From 3cd12006bb6e7c9157f6b0f82a10d0c8cd63e334 Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Wed, 30 May 2018 16:17:22 -0700 Subject: [PATCH] StarlingX open source release updates Signed-off-by: Dean Troyer --- CONTRIBUTORS.wrs | 7 + LICENSE | 202 + README.rst | 5 + base/base-files/base-files/issue | 22 + base/base-files/base-files/issue.net | 21 + base/base-files/base-files/motd | 5 + base/base-files/base-files/nsswitch.conf | 21 + base/centos-release/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 25 + .../centos/meta_patches/PATCH_ORDER | 2 + .../centos-release-include-TiS-changes.patch | 38 + base/centos-release/centos/srpm_path | 1 + base/centos-release/files/issue | 22 + base/centos-release/files/issue.net | 21 + base/expect-lite/centos/build_srpm.data | 2 + base/expect-lite/centos/expect-lite.spec | 28 + base/lshell/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 25 + base/lshell/centos/meta_patches/PATCH_ORDER | 3 + .../spec-include-TiS-changes.patch | 87 + ...spec-update-lshell-conf-allowed-list.patch | 15 + base/lshell/centos/srpm_path | 1 + base/lshell/files/cgcs_cli | 2 + ...ell-newline-escape-character-support.patch | 53 + .../files/lshell-prompt-change-support.patch | 139 + .../files/lshell-shell-escape-check.patch | 121 + base/lshell/files/lshell-source-support.patch | 106 + base/lshell/files/lshell.conf | 94 + base/lshell/files/lshell_cgcs.patch | 54 + base/lshell/files/lshell_env_setup | 100 + base/lshell/files/wrs.sudo | 11 + base/namespace-utils/LICENSE | 202 + base/namespace-utils/centos/build_srpm.data | 2 + .../centos/namespace-utils.spec | 35 + base/namespace-utils/namespace-utils/LICENSE | 202 + base/namespace-utils/namespace-utils/bashns.c | 59 + .../namespace-utils/umount-in-namespace | 25 + base/nss-pam-ldapd/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 25 + .../centos/meta_patches/PATCH_ORDER | 4 + .../remove-custom-nslcd-conf-file.patch | 34 + .../meta_patches/spec-TiS-changes.patch | 45 + .../spec-bind-nslcd-to-rootDN.patch | 27 + base/nss-pam-ldapd/centos/srpm_path | 1 + base/nss-pam-ldapd/files/login | 14 + base/nss-pam-ldapd/files/nslcd.init | 109 + base/setup/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 25 + base/setup/centos/meta_patches/PATCH_ORDER | 14 + ...ports-and-fstab-only-root-accessible.patch | 28 + .../spec-add-TMOUT-variable.patch | 40 + .../spec-add-ironic-uid-gid.patch | 26 + .../spec-add-magnum-uid-gid.patch | 32 + .../spec-add-murano-uid-gid.patch | 32 + .../spec-include-TiS-changes.patch | 35 + ...c-include-add-fm-user-to-snmpd-group.patch | 22 + .../spec-include-snmpd-fm-user-group.patch | 41 + .../spec-include-tis-uid-gid.patch | 1078 + ...move-unused-default-users-and-groups.patch | 33 + .../spec-remove-unused-default-groups.patch | 42 + .../meta_patches/spec-set-custom-prompt.patch | 42 + ...and-uids-to-support-upgrade-from-wrl.patch | 32 + .../patches/add-fm-user-to-snmpd-group.patch | 15 + .../centos/patches/add-ironic-uid-gid.patch | 24 + .../centos/patches/add-magnum-uid-gid.patch | 31 + .../centos/patches/add-murano-uid-gid.patch | 31 + ...move-unused-default-users-and-groups.patch | 66 + .../remove-unused-default-groups.patch | 35 + .../centos/patches/snmpd-fm-user-group.patch | 61 + base/setup/centos/patches/tis-uid-gid.patch | 50 + ...and-uids-to-support-upgrade-from-wrl.patch | 47 + base/setup/centos/srpm_path | 1 + base/setup/files/custom.sh | 1 + base/setup/files/motd | 5 + base/setup/files/nsswitch.conf | 66 + base/setup/files/prompt.sh | 4 + base/tis-extensions/PKG-INFO | 13 + base/tis-extensions/centos/build_srpm.data | 2 + .../tis-extensions/centos/tis-extensions.spec | 69 + base/tis-extensions/files/LICENSE | 202 + .../tis-extensions/files/coredump-sysctl.conf | 4 + base/tis-extensions/files/coredump.conf | 8 + .../files/modules-load-vfio.conf | 1 + base/tis-extensions/files/target | 290 + base/tis-extensions/files/target.service | 14 + connectivity/dhcp/PKG-INFO | 22 + connectivity/dhcp/centos/build_srpm.data | 2 + .../dhclient-dhcp6-wrs-install-uuid.patch | 41 + .../files/dhclient-disable-NSUPDATE.patch | 28 + .../dhcp/centos/files/dhclient-enter-hooks | 32 + .../dhclient-handle-wrs-install-uuid.patch | 42 + .../dhclient-ipv6-bind-to-interface.patch | 48 + ...ient-ipv6-conditionally-set-hostname.patch | 37 + ...-restrict-interfaces-to-command-line.patch | 67 + connectivity/dhcp/centos/files/dhclient.conf | 21 + ...andle-default-classless-static-route.patch | 63 + connectivity/dhcp/centos/files/site.h | 28 + .../files/support-disable-nsupdate.patch | 42 + ...te-package-versioning-for-TIS-format.patch | 27 + .../dhcp/centos/meta_patches/PATCH_ORDER | 7 + .../dhclient-dhcp6-set-hostname.patch | 38 + .../dhclient-disable-NSUPDATE.patch | 48 + .../mark-dhclient.conf-as-config.patch | 25 + ...move-unecessary-dhcp-exit-hooks-file.patch | 43 + .../meta_patches/spec-dhcp-enter-hooks.patch | 41 + .../spec-include-TiS-patches.patch | 79 + connectivity/dhcp/centos/srpm_path | 1 + connectivity/nfs-utils/centos/build_srpm.data | 2 + .../0001-TiS-nfs-utils-spec-add-scripts.patch | 96 + ...te-package-versioning-for-TIS-format.patch | 35 + .../0001-add-rpm-4.14-compatibility.patch | 20 + ...date-nfsmount.conf-with-required-con.patch | 33 + .../nfs-utils/centos/meta_patches/PATCH_ORDER | 5 + ...tils-spec-file-disable-statd-service.patch | 52 + ...s-utils-do-not-pass-CFLAGS-to-native.patch | 38 + ...upport-mountprog-and-nfsprog-options.patch | 46 + ...e-nfsmount.conf-with-required-config.patch | 166 + connectivity/nfs-utils/centos/srpm_path | 1 + .../nfs-utils/files/nfs-mountd.service | 11 + .../nfs-utils/files/nfs-server.service | 18 + .../nfs-utils/files/nfs-statd.service | 12 + ...s-utils-do-not-pass-CFLAGS-to-native.patch | 36 + ...upport-mountprog-and-nfsprog-options.patch | 46 + connectivity/nfs-utils/files/nfs-utils.conf | 35 + connectivity/nfs-utils/files/nfscommon | 147 + .../nfs-utils/files/nfscommon.service | 13 + connectivity/nfs-utils/files/nfsserver | 136 + .../nfs-utils/files/nfsserver.service | 13 + connectivity/openssh/PKG-INFO | 25 + connectivity/openssh/centos/build_srpm.data | 2 + connectivity/openssh/centos/files/ssh_config | 48 + connectivity/openssh/centos/files/sshd_config | 129 + ...01-Further-parallelize-openssh-build.patch | 34 + ...te-package-versioning-for-TIS-format.patch | 34 + .../openssh/centos/meta_patches/PATCH_ORDER | 7 + ...t-script-kill-old-instances-on-start.patch | 32 + .../meta_patches/openssh-service-file.patch | 38 + .../openssh-spec-file-add-init.patch | 35 + .../spec-include-TiS-config-files.patch | 39 + .../sshd-pam-use-common-includes.patch | 58 + connectivity/openssh/centos/srpm_path | 1 + .../add-roaming-no-option-ssh-config.patch | 9 + ...and-disabling-password-based-rootssh.patch | 78 + core/initscripts/PKG-INFO | 19 + core/initscripts/centos/build_srpm.data | 2 + .../0001-Disable-zeroconf-route.patch | 59 + ...intermittenly-do-not-come-up-on-boot.patch | 44 + ...upport-PROMISC-for-interfaces-config.patch | 43 + ...te-package-versioning-for-TIS-format.patch | 28 + .../centos/meta_patches/PATCH_ORDER | 16 + .../add_build_require_on_systemd.patch | 24 + ...-build-failures-due-to-unwanted-sgid.patch | 33 + .../force-delay-check-link-down.patch | 43 + .../ipv6-static-route-support.patch | 33 + .../run-ifdown-on-all-interfaces.patch | 43 + .../spec-add-mountnfs-init-script.patch | 58 + ...-ifup-eth-stop-waiting-if-link-is-up.patch | 32 + .../spec-include-TiS-changes.patch | 61 + ...spec-run-dhclient-as-daemon-for-ipv6.patch | 32 + ...g-affirmative-check-for-link-carrier.patch | 33 + ...g-unsafe-usage-of-linkdelay-variable.patch | 33 + .../stop-creating-shared-dirs.patch | 44 + .../patches/0001-dhclient-remove-1-arg.patch | 26 + .../0001-force-delay-check-link-down.patch | 25 + ...nt-restrict-interfaces-to-those-on-c.patch | 63 + .../ifup-eth-stop-waiting-if-link-is-up.patch | 52 + .../patches/ipv6-static-route-support.patch | 29 + .../relocate-dhclient-leases-to-var-run.patch | 30 + .../run-dhclient-as-daemon-for-ipv6.patch | 34 + .../run-ifdown-on-all-interfaces.patch | 26 + .../patches/support-interface-promisc.patch | 53 + .../support-interface-scriptlets.patch | 91 + ...g-affirmative-check-for-link-carrier.patch | 42 + ...g-unsafe-usage-of-linkdelay-variable.patch | 33 + core/initscripts/centos/srpm_path | 1 + core/initscripts/files/mountnfs.service | 13 + core/initscripts/files/mountnfs.sh | 103 + core/util-linux/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 27 + .../0003-util-linux-login-pamd.patch | 38 + .../centos/meta_patches/PATCH_ORDER | 3 + .../spec-use-su-file-from-shadow.patch | 33 + core/util-linux/centos/srpm_path | 1 + devtools/facter/centos/build_srpm.data | 1 + .../0001-spec-include-TiS-paches.patch | 42 + ...te-package-versioning-for-TIS-format.patch | 27 + .../0003-Add-ipaddress-patch.patch | 48 + .../facter/centos/meta_patches/PATCH_ORDER | 3 + devtools/facter/centos/patches/0001-ps.patch | 30 + .../centos/patches/0002-personality.patch | 93 + ...remove-net-commands-that-can-timeout.patch | 55 + .../patches/0004-centos_fix-ipv6-regex.patch | 15 + ...Hardcode-ipaddress-fact-to-localhost.patch | 188 + devtools/facter/centos/srpm_path | 1 + .../nfscheck/recipes-common/nfscheck/LICENSE | 202 + .../nfscheck/recipes-common/nfscheck/PKG-INFO | 14 + .../nfscheck/centos/build_srpm.data | 2 + .../nfscheck/centos/nfscheck.spec | 43 + .../recipes-common/nfscheck/files/LICENSE | 202 + .../nfscheck/files/nfscheck-init.sh | 79 + .../nfscheck/files/nfscheck.service | 10 + .../recipes-common/nfscheck/files/nfscheck.sh | 53 + devtools/puppet-4.8.2/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0001-Add-WRS-Patches.patch | 47 + .../centos/meta_patches/PATCH_ORDER | 2 + .../patches/1001-Add-timestamps-to-logs.patch | 25 + ...02-Set-hasstatus-to-false-by-default.patch | 49 + .../patches/1003-Update-getpid-function.patch | 31 + .../1004-Block-enabling-of-services.patch | 61 + ...bles-and-basemodulepath-in-puppet.co.patch | 28 + devtools/puppet-4.8.2/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../0002-Add-Rebase-Patches.patch | 33 + ...-meta-fix-ceilometer-puppet-warnings.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + .../patches/0001-Roll-up-TIS-patches.patch | 63 + .../0002-Fix-ceilometer-puppet-warnings.patch | 39 + .../puppet-ceilometer-11.3.0/centos/srpm_path | 1 + .../puppet-ceph-2.2.0/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-patches.patch | 34 + .../meta_patches/0003-Ceph-Jewel-rebase.patch | 32 + ...dd-OSD-support-for-persistent-naming.patch | 32 + .../0005-meta-patch-for-patch5.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 5 + .../patches/0001-Roll-up-TIS-patches.patch | 151 + .../patches/0002-Newton-rebase-fixes.patch | 47 + .../patches/0003-Ceph-Jewel-rebase.patch | 110 + ...dd-OSD-support-for-persistent-naming.patch | 29 + ...e-puppetlabs-apt-as-ceph-requirement.patch | 25 + .../puppet-ceph-2.2.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-patches.patch | 32 + ...volume-cannot-be-deleted-after-swact.patch | 40 + .../centos/meta_patches/PATCH_ORDER | 3 + .../patches/0001-Roll-up-TIS-patches.patch | 213 + ...volume-cannot-be-deleted-after-swact.patch | 46 + .../puppet-cinder-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-patch.patch | 32 + .../0003-Add-region-cache-support.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + .../patches/0001-Roll-up-TIS-patches.patch | 172 + .../0002-Add-region-cache-support.patch | 64 + .../puppet-glance-11.3.0/centos/srpm_path | 1 + .../puppet-heat-11.3.0/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-Patches.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 2 + .../patches/0001-Roll-up-TIS-patches.patch | 152 + .../puppet-heat-11.3.0/centos/srpm_path | 2 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 19 + ...0002-Ironic-dbsync-NeutronGlance-dep.patch | 26 + .../0003-Apply-xinetd-patch.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + ...-dbsync-NeutronGlance-dep-resolution.patch | 78 + ...002-Dont-complain-about-xinetd-2.0.0.patch | 25 + .../puppet-ironic-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...ckage-versioning-for-Titanium-format.patch | 25 + .../0002-squash-titanium-patches.patch | 36 + .../0003-remove-the-keystone-admin-app.patch | 32 + ...ntlet_and_bindhost-from-keystoneconf.patch | 26 + .../centos/meta_patches/PATCH_ORDER | 4 + ...-pike-rebase-squash-titanium-patches.patch | 440 + .../0002-remove-the-Keystone-admin-app.patch | 37 + ...-eventlet_bindhost-from-Keystoneconf.patch | 39 + .../puppet-keystone-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + .../meta_patches/0001-meta-Pike-rebase.patch | 40 + ...eta-fixed-puppet-deprecated-warnings.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 2 + .../centos/patches/0001-Pike-Rebase.patch | 63 + ...002-fixed-puppet-deprecated-warnings.patch | 25 + .../puppet-magnum-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + .../meta_patches/0001-meta-Pike-rebase.patch | 40 + ...eta-fixed-puppet-deprecated-warnings.patch | 32 + ...xpose-heat-and-neutron-endpoint-type.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + .../centos/patches/0001-Pike-Rebase.patch | 153 + ...002-fixed-puppet-deprecated-warnings.patch | 28 + ...xpose-heat-and-neutron-endpoint-type.patch | 35 + .../puppet-murano-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TiS-patches.patch | 46 + .../0003-add-support-for-networking-sfc.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + .../patches/0001-Roll-up-TIS-patches.patch | 586 + ...2-Remove-broken-authtoken-references.patch | 41 + ...ntrol-provider-network-testing-state.patch | 32 + ...04-set-wsgi-pool-size-to-10-from-100.patch | 59 + ...-Add-support-for-neutron-bgp-dragent.patch | 124 + .../0006-Add-parameters-to-classes.patch | 64 + ...e-neutron-bgp-to-use-class-variables.patch | 27 + ...ow-base-mac-address-to-be-configured.patch | 45 + .../0009-add-support-for-networking-sfc.patch | 64 + .../puppet-neutron-11.3.0/centos/srpm_path | 1 + .../puppet-nova-11.4.0/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../0002-Roll-up-TIS-patches.patch | 34 + ...-syntax-error-for-until_complete_rea.patch | 32 + .../meta_patches/0004-Setup-simple-cell.patch | 34 + .../0005-fix-pci-and-compute-pci.patch | 32 + .../0006-Create-Nova-ironic-conf.patch | 26 + ...ve-joshuabaird-ipaclient-requirement.patch | 32 + ..._weight_multiple-to-scheduler-filter.patch | 32 + ...9-Remove-SerialConsole-from-NovaConf.patch | 26 + .../centos/meta_patches/PATCH_ORDER | 9 + .../patches/0001-Roll-up-TIS-patches.patch | 571 + ...-syntax-error-for-until_complete_rea.patch | 24 + .../0003-Create-nova_cell0-database.patch | 32 + ...ngs-in-nova-manage-cell_v2-list_cell.patch | 31 + .../0005-fix-pci-and-compute-pci.patch | 39 + .../0006-Create-Nova-ironic-conf.patch | 1025 + ...rd-ipaclient-from-puppet-nova-requir.patch | 26 + ...ht_multiple-to-nova-scheduler-filter.patch | 60 + ...9-Remove-SerialConsole-from-NovaConf.patch | 39 + .../puppet-nova-11.4.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-patch.patch | 32 + ...on-name-option-for-system-controller.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + .../patches/0001-Roll-up-TIS-patches.patch | 86 + ...on-name-option-for-system-controller.patch | 40 + .../centos/srpm_path | 1 + .../puppet-oslo-11.3.0/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../meta_patches/0002-Add-WRS-patch.patch | 34 + ...003-psycopg2-drivername-for-postgres.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 3 + .../0001-Remove-log_dir-from-conf-files.patch | 36 + ...g2-drivername-to-postgresql-settings.patch | 51 + .../puppet-oslo-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + .../0001-meta-fix-panko-puppet-warning.patch | 42 + .../centos/meta_patches/PATCH_ORDER | 1 + .../0001-Fix-panko-puppet-warning.patch | 25 + .../puppet-panko-11.3.0/centos/srpm_path | 1 + .../centos/build_srpm.data | 16 + .../centos/puppet-boolean.spec | 39 + .../centos/build_srpm.data | 16 + .../centos/puppet-create_resources.spec | 32 + .../puppet-dnsmasq/centos/build_srpm.data | 12 + ...01-puppet-dnsmasq-Kilo-quilt-patches.patch | 116 + ...ismatched-permission-on-dnsmasq-conf.patch | 27 + ...upport-management-of-tftp_max-option.patch | 62 + ...004-Enable-clear-DNS-cache-on-reload.patch | 72 + .../puppet-dnsmasq/centos/puppet-dnsmasq.spec | 43 + .../puppet-drbd-0.3.1/centos/build_srpm.data | 12 + .../centos/files/0001-TIS-Patches.patch | 377 + ...002-Disable-timeout-for-mkfs-command.patch | 24 + ...d-parallel-to-serial-synchronization.patch | 39 + ...-reuse-existing-drbd-cinder-resource.patch | 53 + ...usedSync-states-to-acceptable-cstate.patch | 26 + ...u-mask-to-affine-drbd-kernel-threads.patch | 68 + .../files/0007-Add-disk-by-path-test.patch | 51 + ...-7953-support-for-new-drbd-resources.patch | 40 + .../puppet-drbd-0.3.1/centos/puppet-drbd.spec | 63 + .../puppet-filemapper/centos/build_srpm.data | 16 + .../centos/puppet-filemapper.spec | 31 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../meta_patches/0002-Add-TIS-patch.patch | 32 + ...-disable-config-validation-prechecks.patch | 32 + .../0004-Add-global_options-patch.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 4 + .../patches/0001-Roll-up-TIS-patches.patch | 43 + ...-disable-config-validation-prechecks.patch | 30 + ...Fix-global_options-log-default-value.patch | 25 + .../puppet-haproxy-1.5.0/centos/srpm_path | 1 + .../puppet-ldap/centos/build_srpm.data | 9 + .../puppet-ldap/centos/puppet-ldap.spec | 30 + .../puppet-ldap/puppet_downloader.sh | 11 + .../puppet-lvm/centos/build_srpm.data | 12 + .../0001-puppet-lvm-kilo-quilt-changes.patch | 694 + .../centos/files/0002-UEFI-pvcreate-fix.patch | 46 + .../0003-US94222-Persistent-Dev-Naming.patch | 25 + ...e_fs_on_resize_failure-functionality.patch | 34 + .../puppet-lvm/centos/puppet-lvm.spec | 45 + .../puppet-network/centos/build_srpm.data | 16 + ...nt-to-redhat-route-files-and-test-fo.patch | 71 + .../centos/files/fix-absent-options.patch | 113 + .../files/ipv6-static-route-support.patch | 100 + ...it-inservice-update-of-static-routes.patch | 55 + .../puppet-network-Kilo-quilt-changes.patch | 658 + .../files/puppet-network-support-ipv6.patch | 46 + .../centos/files/route-options-support.patch | 28 + .../puppet-network/centos/puppet-network.spec | 49 + .../puppet-nslcd/centos/build_srpm.data | 16 + .../puppet-nslcd/centos/puppet-nslcd.spec | 31 + .../puppet-ovs_dpdk/centos/build_srpm.data | 2 + .../centos/puppet-ovs_dpdk.spec | 32 + .../src/ovs_dpdk/files/openvswitch_agent.ini | 21 + .../src/ovs_dpdk/files/ovs_dpdk_config_post | 7 + .../src/ovs_dpdk/files/ovs_dpdk_config_pre | 10 + .../files/update_openvswitch_agent_ini | 9 + .../src/ovs_dpdk/files/update_service_config | 33 + .../src/ovs_dpdk/manifests/config.pp | 18 + .../src/ovs_dpdk/manifests/config_files.pp | 41 + .../src/ovs_dpdk/manifests/init.pp | 11 + .../centos/build_srpm.data | 12 + .../files/0001-Roll-up-TIS-patches.patch | 87 + ...move-puppetlabs-apt-as-a-requirement.patch | 24 + .../centos/puppet-postgresql.spec | 52 + .../puppet-puppi/centos/build_srpm.data | 8 + .../puppet-puppi/centos/puppet-puppi.spec | 31 + .../puppet-puppi/puppet_downloader.sh | 11 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-patch.patch | 32 + ...pher-specification-to-openssl-format.patch | 37 + .../0004-Add-deprecation-patch-to-spec.patch | 33 + .../0005-metapatch-for-revert.patch | 32 + .../0006-metapatch-for-fact-removal.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 6 + .../patches/0001-Roll-up-TIS-patches.patch | 143 + ...pher-specification-to-openssl-format.patch | 35 + ...minate-Puppet-4-deprecation-warnings.patch | 182 + ...-upstream-commit-f7c3a4a637d59f3065d.patch | 32 + ...05-Remove-the-rabbitmq_nodename-fact.patch | 87 + .../puppet-rabbitmq-5.5.0/centos/srpm_path | 1 + .../puppet-staging/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../0002-Apply-rename-patch.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 2 + ...ame-nanliu-staging-to-puppet-staging.patch | 28 + .../puppet-staging/centos/srpm_path | 1 + .../centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-Patches.patch | 33 + .../centos/meta_patches/PATCH_ORDER | 2 + .../0001-Filter-password-in-logs.patch | 36 + .../puppet-stdlib-4.12.0/centos/srpm_path | 1 + .../python-setuptools/centos/build_srpm.data | 5 + .../centos/python-setuptools.spec | 629 + devtools/python-setuptools/files/LICENSE | 255 + devtools/python-setuptools/files/LICENSE-2.0 | 202 + devtools/python-setuptools/files/LICENSE.txt | 44 + .../python-django/centos/build_srpm.data | 3 + ...te-package-versioning-for-TIS-format.patch | 25 + .../centos/meta_patches/PATCH_ORDER | 5 + ...-build-failures-due-to-unwanted-sgid.patch | 26 + .../meta-size-number-format.patch | 32 + .../spec-include-TiS-patches.patch | 36 + .../spec-patch-to-remove-SmartyPants.patch | 20 + .../remove-SmartyPantsHTMLTranslator.patch | 50 + .../centos/patches/size-number-format.patch | 25 + .../python/python-django/centos/srpm_path | 1 + .../files/session-filebase-backend-fix.patch | 55 + .../update-session-filebase-backend.patch | 73 + .../throttle_response_logs.patch | 18 + .../enable-logging-realtime.patch | 48 + .../fix-build-error.patch | 15 + .../sqlalchemy_queue_pool_info.patch | 33 + .../fix_pipe_leak_in_subprocess.patch | 97 + .../python/python_2.7.3/syslog_bugfix.patch | 19 + devtools/qemu/.gitignore | 6 + devtools/qemu/PKG-INFO | 19 + devtools/qemu/README | 17 + devtools/qemu/centos/build_srpm.data | 8 + devtools/qemu/centos/files/80-kvm.rules | 1 + devtools/qemu/centos/files/85-kvm.preset | 5 + .../qemu/centos/files/95-kvm-memlock.conf | 10 + .../centos/files/99-qemu-guest-agent.rules | 2 + .../centos/files/README.rhel6-gpxe-source | 9 + devtools/qemu/centos/files/bios-256k.bin | Bin 0 -> 262144 bytes devtools/qemu/centos/files/bridge.conf | 1 + devtools/qemu/centos/files/build_configure.sh | 118 + devtools/qemu/centos/files/ksm.service | 13 + devtools/qemu/centos/files/ksm.sysconfig | 4 + devtools/qemu/centos/files/ksmctl.c | 77 + devtools/qemu/centos/files/ksmtuned | 138 + devtools/qemu/centos/files/ksmtuned.conf | 21 + devtools/qemu/centos/files/ksmtuned.service | 12 + devtools/qemu/centos/files/kvm-setup | 31 + devtools/qemu/centos/files/kvm-setup.service | 14 + devtools/qemu/centos/files/kvm.conf | 12 + devtools/qemu/centos/files/qemu-ga.sysconfig | 19 + .../centos/files/qemu-guest-agent.service | 18 + devtools/qemu/centos/files/qemu.binfmt | 17 + devtools/qemu/centos/files/rhel6-e1000.rom | Bin 0 -> 69120 bytes devtools/qemu/centos/files/rhel6-ne2k_pci.rom | Bin 0 -> 54272 bytes devtools/qemu/centos/files/rhel6-pcnet.rom | Bin 0 -> 54784 bytes devtools/qemu/centos/files/rhel6-rtl8139.rom | Bin 0 -> 54272 bytes devtools/qemu/centos/files/rhel6-virtio.rom | Bin 0 -> 53248 bytes devtools/qemu/centos/files/vhost.conf | 3 + devtools/qemu/centos/qemu-kvm.spec | 5730 +++ devtools/qemu/qemu/qemu-system-x86.conf | 1 + devtools/qemu/qemu/qemu_clean | 41 + devtools/qemu/qemu/qemu_clean.service | 14 + devtools/qemu/scripts/autopatch.sh | 26 + devtools/update-motd/LICENSE | 202 + devtools/update-motd/PKG-INFO | 14 + devtools/update-motd/centos/build_srpm.data | 2 + devtools/update-motd/centos/update-motd.spec | 59 + devtools/update-motd/files/LICENSE | 202 + .../files/apply_banner_customization | 25 + devtools/update-motd/files/customize-banner | 286 + .../files/install_banner_customization | 16 + devtools/update-motd/files/motd-footer | 16 + devtools/update-motd/files/motd-header | 16 + devtools/update-motd/files/motd-update | 15 + devtools/update-motd/files/motd-update.cron | 3 + devtools/vim/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 27 + devtools/vim/centos/meta_patches/PATCH_ORDER | 1 + devtools/vim/centos/srpm_path | 1 + devtools/vim/files/vimrc | 92 + extended/cloud-init/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../centos/meta_patches/PATCH_ORDER | 2 + .../spec-include-tis-changes.patch | 26 + .../cloud-init-interactive-parted.patch | 25 + extended/cloud-init/centos/srpm_path | 1 + .../cloud-init-interactive-parted.patch | 13 + .../cloud-init/find_candidate_devs_fix.patch | 74 + .../cloud-init/cloud-init/first_boot.patch | 35 + extended/e2fsprogs/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../0002-SPEC-tamper-proof-bash-log.patch | 38 + .../e2fsprogs/centos/meta_patches/PATCH_ORDER | 3 + .../meta-e2fsprogs-disable-tests.patch | 32 + .../patches/0100-tamper-proof-bash-log.patch | 78 + .../0101-e2fsprogs-disable-tests.patch | 27 + extended/e2fsprogs/centos/srpm_path | 1 + extended/iproute/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../Add-WRS-ip-maddr-fix-ifname.patch | 40 + .../iproute/centos/meta_patches/PATCH_ORDER | 2 + .../centos/patches/ip-maddr-fix-ifname.patch | 27 + extended/iproute/centos/srpm_path | 1 + extended/irqbalance/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 26 + .../centos/meta_patches/PATCH_ORDER | 2 + .../spec-disable-irqbalance-service.patch | 38 + extended/irqbalance/centos/srpm_path | 1 + extended/libvirt-python/PKG-INFO | 14 + .../libvirt-python/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 28 + .../centos/meta_patches/PATCH_ORDER | 1 + extended/libvirt-python/centos/srpm_path | 1 + extended/libvirt/.gitignore | 6 + extended/libvirt/PKG-INFO | 16 + extended/libvirt/README | 37 + extended/libvirt/centos/build_srpm.data | 8 + extended/libvirt/centos/libvirt.spec | 2146 + .../libvirt/libvirt-2.0.0/libvirt.logrotate | 14 + extended/libvirt/libvirt-2.0.0/libvirt.lxc | 15 + extended/libvirt/libvirt-2.0.0/libvirt.qemu | 15 + extended/libvirt/libvirt-2.0.0/libvirt.uml | 15 + .../libvirt/libvirt-3.5.0/libvirt.logrotate | 14 + extended/libvirt/libvirt-3.5.0/libvirt.lxc | 15 + extended/libvirt/libvirt-3.5.0/libvirt.qemu | 15 + extended/libvirt/libvirt-3.5.0/libvirt.uml | 15 + extended/lighttpd/PKG-INFO | 19 + extended/lighttpd/centos/build_srpm.data | 9 + ...mp-dir-under-lighttpd-chroot-environ.patch | 26 + ...te-package-versioning-for-TIS-format.patch | 27 + .../lighttpd/centos/meta_patches/PATCH_ORDER | 5 + .../meta_add_support_for_tpm.patch | 32 + .../spec-check-content-length.patch | 40 + .../spec-include-TiS-changes.patch | 121 + extended/lighttpd/centos/srpm_path | 1 + .../check-content-length.patch | 86 + .../lighttpd-1.4.35/index.html.lighttpd | 1 + .../lighttpd-1.4.35/lighttpd-csr.conf | 13 + .../lighttpd-1.4.35/lighttpd-inc.conf | 3 + .../lighttpd-tpm-support.patch | 255 + .../lighttpd/lighttpd-1.4.35/lighttpd.conf | 381 + .../lighttpd/lighttpd-1.4.35/lighttpd.init | 124 + .../lighttpd-1.4.35/lighttpd.logrotate | 14 + .../remote-ip-ipv6-support.patch | 117 + extended/lldpd/centos/build_srpm.data | 4 + .../lldpd/centos/files/i40e-lldp-configure.sh | 148 + .../centos/files/lldpd-clear-station.patch | 39 + .../centos/files/lldpd-create-run-dir.patch | 12 + .../centos/files/lldpd-i40e-disable.patch | 12 + extended/lldpd/centos/lldpd.spec | 418 + .../lldpd-0.9.0/lldpd-interface-show.patch | 206 + extended/lldpd/lldpd-0.9.0/lldpd.default | 2 + extended/lldpd/lldpd-0.9.0/lldpd.init | 117 + extended/logrotate/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 27 + .../meta_patches/0002-crond-adjustment.patch | 50 + .../0003-Add-upstream-patches.patch | 36 + .../meta_patches/0004-Add-su-patch.patch | 32 + .../logrotate/centos/meta_patches/PATCH_ORDER | 4 + ...putFile-rename-already-existing-file.patch | 104 + ...File-eliminate-stat-open-TOCTOU-race.patch | 50 + .../0003-Add-su-root-to-logrotate.conf.patch | 26 + extended/logrotate/centos/srpm_path | 1 + extended/logrotate/files/logrotate-cron.d | 4 + extended/nova-utils/centos/build_srpm.data | 2 + extended/nova-utils/centos/nova-utils.spec | 38 + extended/nova-utils/nova-utils/LICENSE | 202 + extended/nova-utils/nova-utils/nova-sriov | 117 + extended/novnc/centos/build_srpm.data | 1 + ...kage-0.6.2-versioning-for-TIS-format.patch | 12 + .../novnc/centos/meta_patches/PATCH_ORDER | 1 + extended/novnc/centos/srpm_path | 1 + extended/ntp/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + extended/ntp/centos/meta_patches/PATCH_ORDER | 3 + ...ntp-spec-add-TiS-custom-config-files.patch | 32 + .../ntpd-started-no-g-option.patch | 20 + extended/ntp/centos/patches/ntp-cgcs.conf | 14 + extended/ntp/centos/srpm_path | 1 + extended/ntp/ntp-4.2.6p5/ntp-cgcs.conf | 14 + extended/ntp/ntp-4.2.6p5/ntpd | 108 + extended/ntp/ntp-4.2.8p6/ntp-cgcs.conf | 14 + extended/ntp/ntp-4.2.8p6/ntpd | 108 + extended/pam/centos/build_srpm.data | 3 + ...te-package-versioning-for-TIS-format.patch | 25 + extended/pam/centos/meta_patches/PATCH_ORDER | 2 + .../pam-spec-add-custome-config-files.patch | 47 + extended/pam/centos/srpm_path | 1 + extended/pam/files/pam.d/common-account | 27 + extended/pam/files/pam.d/common-auth | 22 + extended/pam/files/pam.d/common-password | 38 + extended/pam/files/pam.d/common-session | 21 + .../files/pam.d/common-session-noninteractive | 20 + extended/pam/files/pam.d/system-auth.pamd | 31 + extended/procps/files/sysctl.conf | 86 + .../python-cephclient/centos/build_srpm.data | 6 + .../centos/python-cephclient.spec | 56 + ...eph-Rebase-Update-REST-API-to-0.94.2.patch | 220 + ...eph-Rebase-Update-REST-API-to-0.94.5.patch | 475 + ...eph-Rebase-Update-REST-API-to-10.2.4.patch | 1062 + .../add-osd-get-pool-quota.patch | 15 + .../fix-osd-crush-remove.patch | 25 + .../python-cephclient/fix-osd-tier-add.patch | 19 + .../set-default-endpoint.patch | 20 + .../python-gunicorn/centos/build_srpm.data | 1 + .../0001-TIS-gunicorn-19-upgrade.patch | 118 + .../meta_patches/0001-TIS-packaging.patch | 25 + .../0001-add-worker-abort-patch.patch | 32 + .../centos/meta_patches/PATCH_ORDER | 1 + .../patches/0001-add-worker-abort-hook.patch | 92 + extended/python-gunicorn/centos/srpm_path | 1 + extended/python-ryu/centos/build_srpm.data | 4 + extended/python-ryu/centos/python-ryu.spec | 264 + .../python-smartpm/centos/build_srpm.data | 6 + extended/python-smartpm/centos/centos.info | 6 + .../smart-add-for-rpm-ignoresize-check.patch | 13 + .../centos/patches/smart-attempt.patch | 223 + .../centos/patches/smart-channelsdir.patch | 24 + .../smart-config-ignore-all-recommends.patch | 24 + .../patches/smart-conflict-provider.patch | 196 + .../centos/patches/smart-dflags.patch | 40 + .../patches/smart-filename-NAME_MAX.patch | 35 + .../patches/smart-flag-exclude-packages.patch | 70 + .../smart-flag-ignore-recommends.patch | 60 + .../smart-improve-error-reporting.patch | 253 + .../centos/patches/smart-metadata-match.patch | 28 + .../centos/patches/smart-multilib-fixes.patch | 22 + .../centos/patches/smart-recommends.patch | 1362 + .../patches/smart-rpm-extra-macros.patch | 27 + .../centos/patches/smart-rpm-md-parse.patch | 26 + .../centos/patches/smart-rpm-root.patch | 80 + .../smart-set-noprogress-for-pycurl.patch | 20 + .../centos/patches/smart-support-rpm4.patch | 96 + .../centos/patches/smart-tmpdir.patch | 30 + .../centos/patches/smart-yaml-error.patch | 86 + .../centos/patches/smartpm-rpm5-nodig.patch | 46 + .../python-smartpm/centos/python-smartpm.spec | 82 + .../commit_transaction_error_handling.patch | 37 + extended/sanlock/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../sanlock/centos/meta_patches/PATCH_ORDER | 3 + ...-systemctl-post-enable-preun-disable.patch | 39 + ...-watchdog-enable-and-reboot-on-error.patch | 33 + ...-watchdog-enable-and-reboot-on-error.patch | 35 + extended/sanlock/centos/srpm_path | 2 + extended/shadow/centos/build_srpm.data | 2 + .../centos/files/clear_shadow_locks.service | 11 + extended/shadow/centos/files/login.defs.cgcs | 386 + ...rther-parallelize-shadow-utils-build.patch | 25 + ...te-package-versioning-for-TIS-format.patch | 25 + .../shadow/centos/meta_patches/PATCH_ORDER | 4 + .../add-BuildRequires-systemd.patch | 27 + ...dd-clear-shadow-locs-service-in-spec.patch | 63 + extended/shadow/centos/srpm_path | 1 + extended/shadow/files/clear_shadow_locks | 11 + extended/shadow/files/pam.d/su | 69 + extended/shim-signed/centos/build_srpm.data | 1 + .../0001-Use-presigned-binary.patch | 66 + ...-than-hardcode-shim-unsigned-version.patch | 55 + .../centos/meta_patches/PATCH_ORDER | 2 + extended/shim-signed/centos/srpm_path | 1 + extended/shim-unsigned/centos/build_srpm.data | 2 + .../meta_patches/0001-Embed-TiS-cert.patch | 31 + .../meta_patches/0001-Objcopy-version.patch | 12 + .../centos/meta_patches/PATCH_ORDER | 3 + .../centos/meta_patches/spec.arch.patch | 12 + .../centos/patches/0001-Objcopy-version.patch | 19 + .../centos/patches/0001-Use-TiS-cert.patch | 68 + extended/shim-unsigned/centos/srpm_path | 1 + extended/shim-unsigned/files/tis-shim.crt | 21 + extended/sudo/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../0002-spec-include-TiS-changes.patch | 66 + .../0003-Further-parallelize-sudo-build.patch | 25 + .../meta_patches/0004-remove-make-check.patch | 14 + extended/sudo/centos/meta_patches/PATCH_ORDER | 4 + extended/sudo/centos/srpm_path | 1 + extended/sudo/files/sudo-CVE-2015-5602.patch | 401 + extended/syslog-ng/centos/build_srpm.data | 2 + .../syslog-ng/centos/files/fm_event_syslogger | 78 + .../syslog-ng/centos/files/remotelogging.conf | 129 + .../syslog-ng/centos/files/syslog-ng.conf | 582 + .../centos/files/syslog-ng.logrotate | 173 + ...te-package-versioning-for-TIS-format.patch | 25 + .../meta_patches/0002-Add-TIS-content.patch | 53 + .../0003-add-fm-event-syslogger.patch | 43 + .../syslog-ng/centos/meta_patches/PATCH_ORDER | 3 + .../syslog-ng-service-pid-file-pmond.patch | 19 + extended/syslog-ng/centos/srpm_path | 1 + extended/systemd/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 28 + ...0003-spec-expand-_udevrulesdir-macro.patch | 27 + ...-of-systemd-post-from-running-on-pat.patch | 49 + .../0005-spec-millisec-in-syslog-date.patch | 28 + .../0007-Add-patch-for-journald-config.patch | 24 + ...patch-for-journald-config-rate-limit.patch | 27 + ...Add-patch-to-remove-ID_SAS_PATH-rule.patch | 24 + ...L-warnings-from-systemd-tmpfiles-set.patch | 25 + ...Add-patch-for-moving-vartmp-to-tmpfs.patch | 24 + ...Add-patch-for-restricting-tmpfs-size.patch | 24 + .../systemd/centos/meta_patches/PATCH_ORDER | 10 + .../0501-inject-millisec-in-syslog-date.patch | 79 + ...figure-journald-to-forward-to-syslog.patch | 34 + .../0504-Configure-journald-rate-limit.patch | 29 + .../0505-remove-id-sas-path-symlink.patch | 26 + ...L-warnings-from-systemd-tmpfiles-set.patch | 38 + .../patches/0507-move-vartmp-to-tmpfs.patch | 33 + ...-set-a-1GB-size-restriction-on-tpmfs.patch | 26 + extended/systemd/centos/srpm_path | 1 + extended/tboot/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 32 + .../centos/meta_patches/0002-TiS-tboot.patch | 43 + ...003-security-set-immutable-attribute.patch | 56 + .../tboot/centos/meta_patches/PATCH_ORDER | 3 + .../centos/patches/1000-tboot-for-tis.patch | 188 + extended/tboot/centos/srpm_path | 1 + extended/watchdog/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 25 + .../watchdog/centos/meta_patches/PATCH_ORDER | 2 + .../meta_patches/spec-TiS-changes.patch | 35 + extended/watchdog/centos/srpm_path | 1 + .../watchdog/files/fix-ping-failure.patch | 70 + kernel-rt/centos/build_srpm.data | 4 + ...d-patch-for-missing-ifdef-in-tracing.patch | 36 + ...ix-a-use-after-free-in-sys_mq_notify.patch | 35 + ...ange-name-of-source-tarball-drop-el7.patch | 27 + .../Check-for-oversized-nfs-arguments.patch | 36 + ...p-TIC-patch-list-for-CentOS-7.4-port.patch | 110 + .../Correct-the-source-tarball-name.patch | 29 + .../centos/meta_patches/Disable-debug.patch | 131 + ...lding-kernel-with-CONFIG_BLK_DEV_NBD.patch | 36 + .../centos/meta_patches/Enable-symvers.patch | 44 + ...defs-for-unbuilt-firmware-and-doc-pk.patch | 53 + ...Fix-compile-warnings-in-scsi-drivers.patch | 39 + .../centos/meta_patches/Fix-stack-clash.patch | 51 + kernel-rt/centos/meta_patches/PATCH_ORDER | 37 + ...M-introduce-per-cpu-power-management.patch | 47 + ...orting-Cacheinfo-from-Kernel-4.10.17.patch | 38 + .../Porting-Kernfs-from-Kernel-3.10.patch | 38 + ...-Director-Technology-from-Kernel-4.1.patch | 39 + ...solve-hard-lockup-in-get_kvmclock_ns.patch | 32 + .../Rework-pkg-release-naming.patch | 38 + .../Stricter-decoding-of-NFS-ops.patch | 38 + ...ge-versioning-for-TIS-format-revised.patch | 35 + ...te-package-versioning-for-TIS-format.patch | 28 + ...-building-mpt2sas-mpt3sas-as-builtin.patch | 36 + ...t-module-signing-key-in-kernel-devel.patch | 29 + ...y-turning-off-write-same-in-smartpqi.patch | 35 + ...-high-latency-reported-by-cyclictest.patch | 49 + ...ose-the-memblock-reorder-parms-patch.patch | 42 + .../meta-patch-for-Kernel-IMA-changes.patch | 36 + ...patch-for-Kernel-IMA-keyring-changes.patch | 54 + ...-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch | 36 + .../centos/meta_patches/tis-add-tools.patch | 241 + .../meta_patches/tis-apply-patches.patch | 59 + .../tis-build-unsigned-package.patch | 64 + ...s-debrand-and-add-centos-certificate.patch | 50 + ...tis-handle-tis-config-customizations.patch | 57 + .../meta_patches/tis-remove-signing.patch | 101 + .../meta_patches/tis-remove-trace.patch | 29 + .../x86-dma_alloc_coherent-fix.patch | 38 + ...ng-ifdef-around-max-latency-variable.patch | 50 + ...rqs-and-workqueues-with-kthread_cpus.patch | 73 + ...do-not-cache-fib-route-info-on-local.patch | 58 + ...xpose-pm_qos_resume_latency-for-CPUs.patch | 63 + ...lding-kernel-with-CONFIG_BLK_DEV_NBD.patch | 36 + ...mpt2sas-and-mpt3sas-as-builtin-for-C.patch | 34236 ++++++++++++++++ ...acheinfo-compilation-issues-for-3.10.patch | 114 + ...ntial-preemption-when-get-the-curren.patch | 91 + ...e-kernel-start-eth-devices-at-offset.patch | 37 + ...tion-of-death-of-arbitrary-processes.patch | 539 + ...d-ACS-quirk-for-Intel-Fortville-NICs.patch | 34 + ...orting-Cacheinfo-from-Kernel-4.10.17.patch | 2122 + ...01216-IMA-support-in-Titanium-kernel.patch | 373 + .../US103091-IMA-System-Configuration.patch | 234 + .../affine-compute-kernel-threads.patch | 166 + ...ding-user-settings-if-flash-is-not-f.patch | 52 + ...pci-dma.c-fix-dma_generic_alloc_cohe.patch | 58 + ...t-specifier-for-cma-kernel-parameter.patch | 224 + ...id-taking-spinlock-for-accessing-QoS.patch | 92 + ...-per-CPU-PM-QoS-resume-latency-consi.patch | 71 + ...p-seeking-deeper-idle-if-current-sta.patch | 52 + kernel-rt/centos/patches/cpupower.config | 3 + kernel-rt/centos/patches/cpupower.service | 13 + .../centos/patches/debrand-rh-i686-cpu.patch | 11 + .../centos/patches/debrand-rh_taint.patch | 25 + .../centos/patches/debrand-single-cpu.patch | 25 + .../patches/dpt_i2o-fix-build-warning.patch | 42 + ...w-ignoring-Ethernet-device-RMRR-with.patch | 120 + ...el-3.10.0-x86_64-rt-debug.config.tis_extra | 6 + ...el-3.10.0-x86_64-rt-trace.config.tis_extra | 6 + .../kernel-3.10.0-x86_64-rt.config.tis_extra | 967 + ...block-introduce-memblock_alloc_range.patch | 96 + ...ix-a-use-after-free-in-sys_mq_notify.patch | 51 + ...-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch | 47 + .../timer-Minimize-nohz-off-overhead.patch | 168 + ...timer-migration-overhead-if-disabled.patch | 533 + ...rn-off-write-same-in-smartqpi-driver.patch | 26 + .../x86-enable-DMA-CMA-with-swiotlb.patch | 182 + ...oc_coherent-return-zeroed-memory-if-.patch | 87 + kernel-rt/centos/srpm_path | 1 + kernel-rt/files/centos.cer | Bin 0 -> 1500 bytes kernel-rt/files/ima_signing_key.pub | Bin 0 -> 987 bytes kernel-std/centos/build_srpm.data | 4 + ...thernet-device-RMRR-with-IOMMU-passt.patch | 45 + ...ix-a-use-after-free-in-sys_mq_notify.patch | 35 + ...fix-calltrace-in-megaraid-sas-driver.patch | 49 + .../Check-for-oversized-nfs-arguments.patch | 36 + ...p-TIC-patch-list-for-CentOS-7.4-port.patch | 74 + .../Enable-DMA-CMA-with-swiotlb.patch | 45 + ...lding-kernel-with-CONFIG_BLK_DEV_NBD.patch | 36 + .../Enable-the-rebased-source-patches.patch | 84 + ...ile-issue-with-transparent-hugepages.patch | 36 + ...Fix-compile-warnings-in-scsi-drivers.patch | 39 + .../Further-parallelize-kernel-build.patch | 77 + .../Initial-kernel-build-for-TiS.patch | 110 + ...e-kernel-start-eth-devices-at-offset.patch | 45 + kernel-std/centos/meta_patches/PATCH_ORDER | 31 + ...M-introduce-per-cpu-power-management.patch | 47 + .../Package-unsigned-kernel.patch | 55 + ...orting-Cacheinfo-from-Kernel-4.10.17.patch | 38 + ...-Director-Technology-from-Kernel-4.1.patch | 39 + ...solve-hard-lockup-in-get_kvmclock_ns.patch | 34 + .../Stricter-decoding-of-NFS-ops.patch | 38 + ...-neuter-off-any-TiS-specific-patches.patch | 94 + ...cript-for-patching-add-patch-release.patch | 52 + ...te-package-versioning-for-TIS-format.patch | 39 + ...-building-mpt2sas-mpt3sas-as-builtin.patch | 36 + ...t-module-signing-key-in-kernel-devel.patch | 29 + ...y-turning-off-write-same-in-smartpqi.patch | 35 + .../ixgbe-remove-kernel-builtin-drivers.patch | 29 + .../meta_patches/kernel-build_requires.patch | 28 + .../meta-patch-for-Kernel-IMA-changes.patch | 36 + ...patch-for-Kernel-IMA-keyring-changes.patch | 52 + ...-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch | 36 + .../x86_dma_alloc_coherent-fix.patch | 38 + ...rqs-and-workqueues-with-kthread_cpus.patch | 73 + ...do-not-cache-fib-route-info-on-local.patch | 58 + ...xpose-pm_qos_resume_latency-for-CPUs.patch | 63 + ...lding-kernel-with-CONFIG_BLK_DEV_NBD.patch | 36 + ...mpt2sas-and-mpt3sas-as-builtin-for-C.patch | 34236 ++++++++++++++++ ...ke-thinking-that-Xen-is-always-enabl.patch | 37 + ...acheinfo-compilation-issues-for-3.10.patch | 114 + ...e-when-transparent-hugepages-are-off.patch | 29 + ...ntial-preemption-when-get-the-curren.patch | 91 + ...rq-disablement-around-KVM_SET_CLOCK-.patch | 132 + ...e-kernel-start-eth-devices-at-offset.patch | 37 + ...tion-of-death-of-arbitrary-processes.patch | 537 + ...d-ACS-quirk-for-Intel-Fortville-NICs.patch | 34 + ...orting-Cacheinfo-from-Kernel-4.10.17.patch | 2120 + ...01216-IMA-support-in-Titanium-kernel.patch | 373 + .../US103091-IMA-System-Configuration.patch | 244 + .../affine-compute-kernel-threads.patch | 168 + ...ding-user-settings-if-flash-is-not-f.patch | 52 + ...pci-dma.c-fix-dma_generic_alloc_cohe.patch | 58 + ...t-specifier-for-cma-kernel-parameter.patch | 224 + ...id-taking-spinlock-for-accessing-QoS.patch | 92 + ...-per-CPU-PM-QoS-resume-latency-consi.patch | 71 + ...p-seeking-deeper-idle-if-current-sta.patch | 52 + .../patches/dpt_i2o-fix-build-warning.patch | 42 + ...w-ignoring-Ethernet-device-RMRR-with.patch | 120 + .../kernel-3.10.0-x86_64.config.tis_extra | 826 + ...block-introduce-memblock_alloc_range.patch | 96 + ...ix-a-use-after-free-in-sys_mq_notify.patch | 51 + ...-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch | 47 + ...rn-off-write-same-in-smartqpi-driver.patch | 26 + .../x86-enable-DMA-CMA-with-swiotlb.patch | 182 + ...oc_coherent-return-zeroed-memory-if-.patch | 87 + kernel-std/centos/srpm_path | 2 + kernel-std/files/ima_signing_key.pub | Bin 0 -> 917 bytes mellanox/libibverbs/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 26 + .../centos/meta_patches/PATCH_ORDER | 3 + .../meta_patches/add-build-dependency.patch | 25 + ...-build-failures-due-to-unwanted-sgid.patch | 24 + mellanox/libibverbs/centos/srpm_path | 1 + mellanox/libmlx4/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../libmlx4/centos/meta_patches/PATCH_ORDER | 1 + mellanox/libmlx4/centos/srpm_path | 1 + mellanox/libmlx5/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 26 + .../libmlx5/centos/meta_patches/PATCH_ORDER | 1 + mellanox/libmlx5/centos/srpm_path | 1 + .../mlnx-ofa_kernel/centos/build_srpm.data | 3 + .../0001-Support-TiS-system.patch | 195 + .../centos/meta_patches/PATCH_ORDER | 1 + .../0001-neuter-HAVE_IEEE_GETQCN.patch | 26 + .../0001-neuter-a-bunch-of-ks-stuff.patch | 47 + .../0001-neuter-some-stats-output.patch | 31 + mellanox/mlnx-ofa_kernel/centos/srpm_path | 1 + .../mlnx-ofa_kernel/files/modules-load.conf | 22 + mellanox/rdma-core/centos/build_srpm.data | 1 + ...encies-and-package-versioning-for-Ti.patch | 49 + .../rdma-core/centos/meta_patches/PATCH_ORDER | 1 + mellanox/rdma-core/centos/srpm_path | 1 + mwa-sparta.map | 20 + networking/mlx4-config/centos/build_srpm.data | 4 + .../mlx4-config/centos/mlx4-config.spec | 48 + networking/mlx4-config/files/LICENSE | 202 + .../mlx4-config/files/mlx4-config.service | 12 + .../mlx4-config/files/mlx4-configure.sh | 119 + .../mlx4-config/files/mlx4_core_config.sh | 24 + .../mlx4-config/files/mlx4_core_goenabled.sh | 27 + networking/net-snmp/PKG-INFO | 23 + networking/net-snmp/centos/build_srpm.data | 3 + ...te-package-versioning-for-TIS-format.patch | 27 + .../net-snmp/centos/meta_patches/PATCH_ORDER | 11 + .../meta_patches/fix-snmpd-initscript.patch | 24 + .../fix-snmpd-service-reload.patch | 25 + .../meta_patches/fix-snmpd-service.patch | 28 + .../run-snmpd-as-non-root-user.patch | 50 + .../snmp-spec-add-init-script.patch | 42 + .../snmp-spec-add-snmp-config.patch | 41 + .../snmp-spec-config-file-permission.patch | 27 + .../meta_patches/snmpd-service-OPTIONS.patch | 25 + .../spec-add-rpm-headerGetEntry-fix.patch | 20 + ...configure-without-HOST-RESOURCES-MIB.patch | 21 + .../spec-include-TiS-patches.patch | 59 + networking/net-snmp/centos/srpm_path | 1 + networking/net-snmp/files/snmp.conf.cgcs | 4 + networking/net-snmp/files/snmpd.cgcs | 95 + networking/net-snmp/files/snmpd.conf.cgcs | 24 + .../patches/0001-rpm-headerGetEntry.patch | 148 + networking/openldap/PKG-INFO | 15 + networking/openldap/centos/build_srpm.data | 3 + ...te-package-versioning-for-TIS-format.patch | 27 + .../openldap/centos/meta_patches/PATCH_ORDER | 6 + .../openldap-enable-password-policy.patch | 55 + .../openldap-remove-ldap-conf-cgcs-file.patch | 33 + .../meta_patches/openldap-service-file.patch | 42 + .../meta_patches/openldap-spec-file.patch | 116 + .../openldap-sysconfig-file.patch | 25 + networking/openldap/centos/srpm_path | 1 + networking/openldap/files/initial_config.ldif | 80 + networking/openldap/files/initscript | 116 + .../rootdn-should-not-bypass-ppolicy.patch | 43 + networking/openldap/files/slapd.conf.cgcs | 117 + networking/openvswitch/centos/build_srpm.data | 4 + .../openvswitch/centos/openvswitch.spec | 1009 + .../patches/ovs-vswitchd.system.service.patch | 14 + networking/scapy/centos/build_srpm.data | 1 + ...te-package-versioning-for-tis-format.patch | 28 + ...pv6-fixes-from-2.4-release-candidate.patch | 36 + .../scapy/centos/meta_patches/PATCH_ORDER | 2 + ...socket.pton-socket.ntop-is-available.patch | 64 + networking/scapy/centos/srpm_path | 1 + .../python-3parclient/centos/build_srpm.data | 3 + .../centos/python-3parclient.spec | 35 + ...002-Turn-off-python-crypto-test-step.patch | 26 + python/python-eventlet/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 27 + .../centos/meta_patches/PATCH_ORDER | 2 + .../spec-include-TiS-paches.patch | 34 + ...connection-on-HTTP-413-Request-Entit.patch | 28 + python/python-eventlet/centos/srpm_path | 1 + .../centos/build_srpm.data | 3 + .../centos/python-lefthandclient.spec | 37 + python/python-requests/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../0002-include-patch-for-CGTS-2869.patch | 25 + .../centos/meta_patches/PATCH_ORDER | 2 + ...connection-on-HTTP-413-Request-Entit.patch | 45 + python/python-requests/centos/srpm_path | 1 + .../0002-BuildRequires-pythong-coverage.patch | 25 + restapi-doc/centos/build_srpm | 252 + restapi-doc/centos/build_srpm.data | 7 + restapi-doc/centos/restapi-doc.spec | 32 + restapi-doc/restapi-doc/.gitignore | 21 + restapi-doc/restapi-doc/LICENSE | 202 + restapi-doc/restapi-doc/Makefile | 32 + restapi-doc/restapi-doc/Makefile.cache | 26 + restapi-doc/restapi-doc/README.mvn_cache | 18 + .../restapi-doc/api-ref-guides/pom.xml | 171 + .../bk-api-ref-blockstorage-v2-cgcs-ext.xml | 57 + .../src/bk-api-ref-compute-v2-cgcs-ext.xml | 56 + .../src/bk-api-ref-image-v2-cgcs-ext.xml | 57 + .../src/bk-api-ref-networking-v2-cgcs-ext.xml | 57 + .../src/bk-api-ref-nfv-vim-v1.xml | 57 + .../src/bk-api-ref-patching-v1.xml | 57 + .../src/bk-api-ref-sysinv-v1.xml | 57 + .../src/bk-api-ref-telemetry-v2-cgcs-ext.xml | 57 + .../api-ref-guides/src/bk-api-ref.xml | 51 + .../api-ref-guides/src/preface.xml | 35 + restapi-doc/restapi-doc/api-ref/.htaccess | 0 .../restapi-doc/api-ref/locale/api-ref.pot | 1832 + restapi-doc/restapi-doc/api-ref/locale/fr.po | 2282 + restapi-doc/restapi-doc/api-ref/pom.xml | 174 + .../api-ref-blockstorage-v2-cgcs-ext.xml | 30 + .../docbkx/api-ref-compute-v2-cgcs-ext.xml | 30 + .../src/docbkx/api-ref-image-v2-cgcs-ext.xml | 30 + .../docbkx/api-ref-networking-v2-cgcs-ext.xml | 30 + .../api-ref/src/docbkx/api-ref-nfv-vim-v1.xml | 30 + .../src/docbkx/api-ref-patching-v1.xml | 30 + .../api-ref/src/docbkx/api-ref-sysinv-v1.xml | 30 + .../docbkx/api-ref-telemetry-v2-cgcs-ext.xml | 30 + .../api-ref/src/docbkx/api-ref.xml | 29 + .../ch_blockstorage-api-v2-cgcs-ext.xml | 75 + .../src/docbkx/ch_cgcs-rest-api-intro.xml | 61 + .../src/docbkx/ch_compute-v2-cgcs-ext.xml | 258 + .../src/docbkx/ch_image-v2-cgcs-ext.xml | 63 + .../src/docbkx/ch_networking-v2-cgcs-ext.xml | 409 + .../api-ref/src/docbkx/ch_nfv-vim-api-v1.xml | 116 + .../api-ref/src/docbkx/ch_patching-api-v1.xml | 97 + .../api-ref/src/docbkx/ch_sysinv-api-v1.xml | 1441 + .../src/docbkx/ch_telemetry-v2-cgcs-ext.xml | 97 + .../src/docbkx/itemizedlist-service-list.xml | 49 + .../api-ref/src/docbkx/preface.xml | 26 + .../extension_get-response.json | 49 + .../extension_list-response.json | 39 + .../flavor-extra-specs-create-request.json | 5 + .../flavor-extra-specs-create-response.json | 5 + .../flavor-extra-specs-get-response.json | 3 + .../flavor-extra-specs-list-response.json | 13 + .../hypervisor-get-resp.json | 110 + .../server-groups-get-resp.json | 15 + .../server-groups-list-resp.json | 27 + .../server-groups-post-req.json | 13 + .../server-groups-post-resp.json | 15 + .../compute-v2-cgcs-ext/pci-get-resp.json | 48 + .../compute-v2-cgcs-ext/pci-list-resp.json | 14 + .../providernet-get-resp.json | 10 + .../compute-v2-cgcs-ext/server-get-resp.json | 86 + .../server-interface-attach-request.json | 6 + .../compute-v2-cgcs-ext/server-list-resp.json | 88 + .../server-scale-up-request.json | 6 + .../server_add-request.json | 20 + .../server_add-response.json | 16 + .../v2/cgcs-ext/compute-v2-cgcs-ext.wadl | 1039 + .../src/wadls/compute-api/v2/common.ent | 321 + .../image-v2-cgcs-ext/image_add-request.json | 10 + .../image-v2-cgcs-ext/image_add-response.json | 27 + .../image_list-response.json | 63 + .../image_modify-request.json | 17 + .../image_modify-response.json | 32 + .../image_show-response.json | 32 + .../v2/cgcs-ext/image-v2-cgcs-ext.wadl | 204 + .../api-ref/src/wadls/image-api/v2/common.ent | 240 + .../extension_get-response.json | 62 + .../extension_list-response.json | 47 + .../host-create_admin_request.json | 7 + .../host-create_admin_response.json | 13 + .../host-delete_admin_response.json | 1 + .../host-list_admin_response.json | 52 + .../host-show_admin_response.json | 26 + .../host-update_admin_request.json | 5 + .../host-update_admin_response.json | 26 + .../net-create_admin_request.json | 8 + .../net-create_admin_response.json | 17 + ...et-list-on-providernet_admin_response.json | 32 + .../net-list_admin_response.json | 107 + .../net-show_admin_response.json | 18 + .../port-list_admin_response.json | 268 + .../port-show_admin_response.json | 28 + .../portforwarding-create_admin_request.json | 10 + .../portforwarding-create_admin_response.json | 12 + .../portforwarding-list_admin_response.json | 22 + .../portforwarding-show_admin_response.json | 12 + .../portforwarding-update_admin_request.json | 5 + .../portforwarding-update_admin_response.json | 12 + ...connectivity-test-list_admin_response.json | 28 + ...nectivity-test-schedule_admin_request.json | 7 + ...ectivity-test-schedule_admin_response.json | 5 + .../providernet-create_admin_request.json | 8 + .../providernet-create_admin_response.json | 12 + .../providernet-delete_admin_response.json | 1 + .../providernet-list_admin_response.json | 62 + ...rovidernet-range-create_admin_request.json | 10 + ...ovidernet-range-create_admin_response.json | 13 + ...ovidernet-range-delete_admin_response.json | 1 + ...providernet-range-list_admin_response.json | 59 + ...providernet-range-show_admin_response.json | 13 + ...rovidernet-range-update_admin_request.json | 7 + ...ovidernet-range-update_admin_response.json | 13 + .../providernet-show_admin_response.json | 22 + .../providernet-type-list_admin_response.json | 12 + .../providernet-update_admin_request.json | 5 + .../providernet-update_admin_response.json | 12 + .../qos-create_admin_request.json | 12 + .../qos-create_admin_response.json | 13 + .../qos-delete_admin_response.json | 1 + .../qos-list_admin_response.json | 37 + .../qos-show_admin_response.json | 13 + .../qos-update_admin_request.json | 10 + .../qos-update_admin_response.json | 13 + .../router-list_admin_response.json | 30 + .../router-show_admin_response.json | 15 + .../setting-delete_admin_response.json | 1 + .../setting-list_admin_response.json | 12 + .../setting-show_admin_response.json | 5 + .../setting-update_admin_request.json | 5 + .../setting-update_admin_response.json | 5 + .../subnet-create_admin_request.json | 14 + .../subnet-create_admin_response.json | 20 + .../subnet-list_admin_response.json | 127 + .../subnet-show_admin_response.json | 20 + .../v2/cgcs-ext/networking-v2-cgcs-ext.wadl | 1864 + .../src/wadls/networking-api/v2/common.ent | 590 + .../create-patch-strategy-request.json | 8 + .../create-patch-strategy-response.json | 108 + .../create-upgrade-strategy-request.json | 5 + .../create-upgrade-strategy-response.json | 97 + .../delete-patch-strategy-request.json | 2 + .../delete-upgrade-strategy-request.json | 2 + .../get-patch-strategy-response.json | 725 + .../get-upgrade-strategy-response.json | 356 + .../v1/api_samples/nfv-vim-api-response.json | 18 + .../v1/api_samples/nfv-vim-response.json | 10 + .../api_samples/orchestration-response.json | 17 + .../patch-strategy-action-request.json | 3 + .../patch-strategy-action-response.json | 379 + .../v1/api_samples/sw-patch-response.json | 13 + .../v1/api_samples/sw-upgrade-response.json | 13 + .../upgrade-strategy-action-request.json | 3 + .../upgrade-strategy-action-response.json | 356 + .../src/wadls/nfv-vim-api/v1/common.ent | 61 + .../wadls/nfv-vim-api/v1/nfv-vim-api-v1.wadl | 479 + .../host_install_async-response.json | 5 + .../v1/api_samples/host_list-response.json | 39 + .../v1/api_samples/patch_apply-response.json | 5 + .../v1/api_samples/patch_delete-response.json | 5 + .../v1/api_samples/patch_list-response.json | 26 + .../v1/api_samples/patch_remove-response.json | 5 + .../v1/api_samples/patch_show-response.json | 22 + .../v1/api_samples/patch_upload-response.json | 5 + .../patching-versions-response.json | 1 + .../api_samples/versionv1-get-response.json | 26 + .../src/wadls/patching-api/v1/common.ent | 406 + .../patching-api/v1/patching-api-v1.wadl | 325 + .../v1/api_samples/addrpool_add-request.json | 7 + .../v1/api_samples/addrpool_add-response.json | 11 + .../api_samples/addrpool_list-response.json | 65 + .../api_samples/addrpool_modify-request.json | 10 + .../api_samples/addrpool_modify-response.json | 11 + .../api_samples/addrpool_show-response.json | 12 + .../v1/api_samples/alarm-response.json | 18 + .../v1/api_samples/alarm_list-request.json | 1 + .../v1/api_samples/alarm_list-response.json | 24 + .../api_samples/alarm_summary-response.json | 8 + .../api_samples/ceph_mon_list-response.json | 46 + .../api_samples/ceph_mon_modify-request.json | 13 + .../api_samples/ceph_mon_modify-response.json | 21 + .../api_samples/ceph_mon_show-response.json | 21 + .../api_samples/certconfig_show-response.json | 8 + .../certificate_install-request.json | 1 + .../v1/api_samples/cluster_list-response.json | 20 + .../v1/api_samples/cluster_show-response.json | 46 + .../v1/api_samples/community_add-request.json | 3 + .../api_samples/community_add-response.json | 9 + .../api_samples/community_list-response.json | 16 + .../api_samples/community_modify-request.json | 7 + .../community_modify-response.json | 8 + .../api_samples/community_show-response.json | 8 + .../controller_fs_list-response.json | 71 + .../controller_fs_modify-request.json | 11 + .../controller_fs_modify-response.json | 14 + .../controller_fs_modify_multi-request.json | 18 + .../controller_fs_show-response.json | 72 + .../v1/api_samples/cpu_list-response.json | 57 + .../cpu_modify-request-platform.json | 6 + .../v1/api_samples/cpu_modify-request.json | 6 + .../v1/api_samples/cpu_modify-response.json | 32 + .../v1/api_samples/cpu_show-response.json | 30 + .../v1/api_samples/device_list-response.json | 388 + .../v1/api_samples/device_modify-request.json | 12 + .../api_samples/device_modify-response.json | 33 + .../v1/api_samples/device_show-response.json | 32 + .../v1/api_samples/disk_list-response.json | 67 + .../v1/api_samples/disk_modify-request.json | 7 + .../v1/api_samples/disk_show-response.json | 42 + .../v1/api_samples/dns_modify-request.json | 12 + .../v1/api_samples/dns_modify-response.json | 19 + .../v1/api_samples/dns_show-response.json | 21 + .../api_samples/drbdsync_modify-request.json | 17 + .../api_samples/drbdsync_modify-response.json | 21 + .../api_samples/drbdsync_show-response.json | 23 + .../api_samples/event_log_list-request.json | 1 + .../api_samples/event_log_list-response.json | 23 + .../api_samples/event_log_show-response.json | 18 + .../event_suppression_list-request.json | 1 + .../event_suppression_list-response.json | 57 + .../event_suppression_modify-request.json | 7 + .../event_suppression_modify-response.json | 19 + .../v1/api_samples/extoam_modify-request.json | 12 + .../api_samples/extoam_modify-response.json | 25 + .../v1/api_samples/extoam_show-response.json | 26 + .../firewall_rules_show-response.json | 9 + .../v1/api_samples/host_action-request.json | 7 + .../v1/api_samples/host_action-response.json | 119 + .../v1/api_samples/host_add-request.json | 17 + .../v1/api_samples/host_add-response.json | 162 + .../v1/api_samples/host_addr_add-request.json | 5 + .../api_samples/host_addr_add-response.json | 14 + .../api_samples/host_addr_list-response.json | 82 + .../api_samples/host_addr_show-response.json | 14 + .../api_samples/host_bulk_add-response.json | 4 + .../host_bulk_export-response.json | 1 + .../api_samples/host_downgrade-request.json | 1 + .../api_samples/host_downgrade-response.json | 226 + .../v1/api_samples/host_list-response.json | 206 + .../v1/api_samples/host_modify-request.json | 7 + .../v1/api_samples/host_modify-response.json | 120 + .../api_samples/host_route_add-request.json | 7 + .../api_samples/host_route_add-response.json | 13 + .../api_samples/host_route_list-response.json | 56 + .../api_samples/host_route_show-response.json | 13 + .../v1/api_samples/host_show-response.json | 122 + .../v1/api_samples/host_upgrade-request.json | 1 + .../v1/api_samples/host_upgrade-response.json | 226 + .../v1/api_samples/infra_add-request.json | 7 + .../v1/api_samples/infra_add-response.json | 25 + .../v1/api_samples/infra_apply-request.json | 7 + .../v1/api_samples/infra_apply-response.json | 25 + .../v1/api_samples/infra_modify-request.json | 7 + .../v1/api_samples/infra_modify-response.json | 25 + .../v1/api_samples/infra_show-response.json | 25 + .../v1/api_samples/interface_add-request.json | 12 + .../api_samples/interface_add-response.json | 52 + .../api_samples/interface_list-response.json | 62 + .../api_samples/interface_modify-request.json | 27 + .../interface_modify-response.json | 52 + .../api_samples/interface_show-response.json | 47 + .../istorconfig_summary-response.json | 1 + .../api_samples/license_install-request.json | 1 + .../v1/api_samples/license_list-response.json | 17 + .../api_samples/lldp_agent_list-response.json | 100 + .../api_samples/lldp_agent_show-response.json | 42 + .../lldp_neighbor_list-response.json | 42 + .../lldp_neighbor_show-response.json | 48 + .../v1/api_samples/load_import-request.json | 4 + .../v1/api_samples/load_import-response.json | 10 + .../v1/api_samples/loads_list-response.json | 20 + .../v1/api_samples/loads_show-response.json | 10 + .../v1/api_samples/memory_list-response.json | 62 + .../v1/api_samples/memory_modify-request.json | 17 + .../api_samples/memory_modify-response.json | 29 + .../v1/api_samples/memory_show-response.json | 29 + .../v1/api_samples/network_list-response.json | 29 + .../v1/api_samples/network_show-response.json | 12 + .../v1/api_samples/ntp_modify-request.json | 12 + .../v1/api_samples/ntp_modify-response.json | 18 + .../v1/api_samples/ntp_show-response.json | 21 + .../v1/api_samples/partition_add-request.json | 6 + .../api_samples/partition_add-response.json | 27 + .../api_samples/partition_edit-request.json | 3 + .../api_samples/partition_edit-response.json | 27 + .../api_samples/partition_list-response.json | 59 + .../api_samples/partition_show-response.json | 27 + .../api_samples/physvolume_add-request.json | 5 + .../api_samples/physvolume_add-response.json | 40 + .../api_samples/physvolume_list-response.json | 34 + .../physvolume_modify-request.json | 5 + .../physvolume_modify-response.json | 5 + .../api_samples/physvolume_show-response.json | 50 + .../v1/api_samples/port_list-response.json | 84 + .../v1/api_samples/port_show-response.json | 38 + .../v1/api_samples/profile_add-request.json | 5 + .../v1/api_samples/profile_add-response.json | 106 + .../v1/api_samples/profile_list-response.json | 72 + .../v1/api_samples/profile_show-response.json | 104 + .../remotelogging_modify-request.json | 27 + .../remotelogging_modify-response.json | 22 + .../remotelogging_show-response.json | 24 + .../sdn_controller_add-request.json | 6 + .../sdn_controller_add-response.json | 17 + .../sdn_controller_list-response.json | 18 + .../sdn_controller_modify-request.json | 10 + .../sdn_controller_modify-response.json | 17 + .../sdn_controller_show-response.json | 17 + .../v1/api_samples/sensor_list-response.json | 154 + .../v1/api_samples/sensor_modify-request.json | 7 + .../api_samples/sensor_modify-response.json | 42 + .../v1/api_samples/sensor_show-response.json | 43 + .../sensorgroup_list-response.json | 97 + .../sensorgroup_modify-request.json | 17 + .../sensorgroup_modify-response.json | 51 + .../sensorgroup_show-response.json | 51 + .../service_group_list-response.json | 81 + .../service_group_show-response.json | 11 + .../v1/api_samples/service_list-response.json | 39 + .../api_samples/service_modify-request.json | 7 + .../api_samples/service_modify-response.json | 6 + .../service_node_list-response.json | 20 + .../service_node_show-response.json | 8 + .../service_parameter_add-request.json | 9 + .../service_parameter_add-response.json | 39 + .../service_parameter_apply-request.json | 4 + .../service_parameter_list-response.json | 73 + .../service_parameter_modify-request.json | 13 + .../service_parameter_modify-response.json | 20 + .../service_parameter_show-response.json | 20 + .../v1/api_samples/service_show-response.json | 7 + .../storage_backend_list-response.json | 26 + .../api_samples/storage_ceph_add-request.json | 4 + .../storage_ceph_add-response.json | 33 + .../storage_ceph_list-response.json | 69 + .../storage_ceph_modify-request.json | 5 + .../storage_ceph_modify-response.json | 30 + .../storage_ceph_show-response.json | 33 + .../storage_external_add-request.json | 5 + .../storage_external_add-response.json | 23 + .../storage_external_list-response.json | 26 + .../storage_external_modify-request.json | 7 + .../storage_external_modify-response.json | 0 .../storage_external_show-response.json | 23 + .../api_samples/storage_file_add-request.json | 5 + .../storage_file_add-response.json | 22 + .../storage_file_list-response.json | 26 + .../storage_file_modify-request.json | 7 + .../storage_file_modify-response.json | 3 + .../storage_file_show-response.json | 23 + .../api_samples/storage_lvm_add-request.json | 4 + .../api_samples/storage_lvm_add-response.json | 22 + .../storage_lvm_list-response.json | 26 + .../storage_lvm_modify-request.json | 7 + .../storage_lvm_modify-response.json | 3 + .../storage_lvm_show-response.json | 23 + .../api_samples/storage_tier_add-request.json | 5 + .../storage_tier_add-response.json | 33 + .../storage_tier_list-response.json | 26 + .../storage_tier_modify-request.json | 7 + .../storage_tier_modify-response.json | 33 + .../storage_tier_show-response.json | 32 + .../storage_usage_list-response.json | 16 + .../api_samples/sysinv-versions-response.json | 24 + .../api_samples/system_health-response.json | 1 + .../system_health_upgrade-response.json | 1 + .../v1/api_samples/system_modify-request.json | 37 + .../api_samples/system_modify-response.json | 35 + .../v1/api_samples/system_show-response.json | 35 + .../v1/api_samples/tpmconfig_add-request.json | 5 + .../api_samples/tpmconfig_add-response.json | 19 + .../api_samples/tpmconfig_modify-request.json | 14 + .../tpmconfig_modify-response.json | 19 + .../api_samples/tpmconfig_show-response.json | 20 + .../v1/api_samples/trapdest_add-request.json | 4 + .../v1/api_samples/trapdest_add-response.json | 20 + .../api_samples/trapdest_list-response.json | 37 + .../api_samples/trapdest_modify-request.json | 13 + .../api_samples/trapdest_modify-response.json | 19 + .../api_samples/trapdest_show-response.json | 19 + .../api_samples/upgrade_delete-response.json | 21 + .../v1/api_samples/upgrade_patch-request.json | 1 + .../api_samples/upgrade_patch-response.json | 21 + .../v1/api_samples/upgrade_show-response.json | 20 + .../v1/api_samples/upgrade_start-request.json | 1 + .../api_samples/upgrade_start-response.json | 21 + .../v1/api_samples/version-get-response.json | 24 + .../api_samples/versionv1-get-response.json | 190 + .../v1/api_samples/volume_add-request.json | 7 + .../v1/api_samples/volume_add-response.json | 39 + .../v1/api_samples/volume_edit-request.json | 4 + .../v1/api_samples/volume_edit-response.json | 39 + .../v1/api_samples/volume_list-response.json | 28 + .../v1/api_samples/volume_modify-request.json | 4 + .../api_samples/volume_modify-response.json | 5 + .../v1/api_samples/volume_show-response.json | 28 + .../api_samples/volumegroup_add-request.json | 4 + .../api_samples/volumegroup_add-response.json | 38 + .../volumegroup_list-response.json | 32 + .../volumegroup_modify-request.json | 7 + .../volumegroup_modify-response.json | 40 + .../volumegroup_show-response.json | 38 + .../src/wadls/sysinv-api/v1/common.ent | 4214 ++ .../wadls/sysinv-api/v1/sysinv-api-v1.wadl | 7602 ++++ .../extension_get-response.json | 11 + .../extension_list-response.json | 13 + .../metertype_list-response.json | 7 + .../pipeline_list-response.json | 11 + .../pipeline_modify-request.json | 8 + .../pipeline_modify-response.json | 10 + .../pipeline_show-response.json | 9 + .../v2/cgcs-ext/telemetry-v2-cgcs-ext.wadl | 229 + .../src/wadls/telemetry-api/v2/common.ent | 240 + .../action-snapshot-request.json | 10 + .../action-volume-request.json | 21 + .../extension_get-response.json | 24 + .../extension_list-response.json | 23 + .../snapshot_list_detail_response.json | 30 + .../snapshot_show_response.json | 15 + .../volume_list_detail_response.json | 73 + .../volume_show_response.json | 27 + .../v2/cgcs-ext/volume-v2-cgcs-ext.wadl | 507 + .../src/wadls/volume-api/v2/common.ent | 183 + restapi-doc/restapi-doc/pom.xml | 50 + .../restapi-doc/rest-api-usage-example.pdf | Bin 0 -> 293312 bytes .../restapi-doc/rest-api-usage-example.pptx | Bin 0 -> 418604 bytes security/audit/PKG-INFO | 15 + security/audit/centos/build_srpm.data | 1 + ...te-package-versioning-for-TIS-format.patch | 25 + .../audit/centos/meta_patches/PATCH_ORDER | 2 + .../meta_patches/meta-enable-audispd.patch | 37 + ...001-enable-audispd-and-auth-facility.patch | 31 + security/audit/centos/srpm_path | 1 + security/libtpms/centos/build_srpm.data | 2 + security/libtpms/centos/libtpms.spec | 218 + security/swtpm/centos/build_srpm.data | 2 + security/swtpm/centos/swtpm.spec | 215 + security/swtpm/files/qemu | 82 + security/swtpm/files/setup_vtpm | 93 + security/tpm2-openssl-engine/PKG_INFO | 14 + .../centos/build_srpm.data | 2 + .../centos/tpm2-openssl-engine.spec | 39 + .../tpm2-openssl-engine/LICENSE | 57 + .../tpm2-openssl-engine/Makefile | 54 + .../tpm2-openssl-engine/create_tpm2_key.c | 479 + .../tpm2-openssl-engine/e_tpm2.c | 852 + .../tpm2-openssl-engine/e_tpm2.h | 147 + .../tpm2-openssl-engine/e_tpm2_err.c | 170 + .../tpm2-openssl-engine/tpm2-asn.h | 121 + security/tpm2-tools/PKG-INFO | 14 + security/tpm2-tools/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 35 + .../centos/meta_patches/PATCH_ORDER | 2 + .../disable-socket-mode-TCTI.patch | 25 + security/tpm2-tools/centos/srpm_path | 1 + security/tss2/PKG-INFO | 19 + security/tss2/centos/build_srpm.data | 2 + security/tss2/centos/tss2.spec | 81 + security/wrs-ssl/LICENSE | 202 + security/wrs-ssl/centos/build_srpm.data | 2 + security/wrs-ssl/centos/wrs-ssl.spec | 41 + security/wrs-ssl/files/tpmdevice-setup | 160 + security/wrs-ssl/server-csr.conf | 13 + storage-topology/storage-topology/LICENSE | 202 + storage-topology/storage-topology/setup.py | 19 + .../storage_topology/__init__.py | 5 + .../storage_topology/exec/__init__.py | 5 + .../storage_topology/exec/storage_topology.py | 456 + support/libevent/.gitignore | 7 + support/libevent/PKG-INFO | 19 + support/libevent/centos/build_srpm.data | 2 + ...te-package-versioning-for-TIS-format.patch | 24 + .../libevent/centos/meta_patches/PATCH_ORDER | 2 + .../spec-include-TiS-patches.patch | 22 + support/libevent/centos/srpm_path | 1 + .../files/libevent-disable-tests.patch | 26 + .../files/libevent-ipv6-client-socket.patch | 55 + support/libxslt/libxslt/CVE-2015-7995.patch | 26 + .../Fix-regression-in-for_each_sub_lv.patch | 44 + .../Sync-filesystem-for-thin-snapshots.patch | 48 + .../lvm2/fix_thin_provision_device_name.patch | 37 + support/lvm2/lvm2/lvm2.sh | 36 + .../lvm2/move-thin_check_executable-var.patch | 40 + ...ect-and-report-too-short-crypt-salts.patch | 259 + ...k-overflow-in-json-related-functions.patch | 44 + support/tgt/centos/build_srpm.data | 2 + support/tgt/centos/files/tgtd.init | 156 + support/tgt/centos/files/tgtd.service | 13 + ...te-package-versioning-for-TIS-format.patch | 25 + support/tgt/centos/meta_patches/PATCH_ORDER | 2 + .../spec-to-use-custom-startup-script.patch | 44 + support/tgt/centos/srpm_path | 1 + .../files/0001-usr-Makefile-WARNING-fix.patch | 31 + support/tgt/files/tgtd.init | 156 + vm-topology/centos/build_srpm.data | 4 + vm-topology/centos/vm-topology.spec | 49 + vm-topology/vm-topology/LICENSE | 202 + vm-topology/vm-topology/setup.py | 19 + .../vm-topology/vm_topology/__init__.py | 5 + .../vm-topology/vm_topology/exec/__init__.py | 5 + .../vm_topology/exec/vm_topology.py | 2159 + 1498 files changed, 181275 insertions(+) create mode 100644 CONTRIBUTORS.wrs create mode 100644 LICENSE create mode 100644 README.rst create mode 100644 base/base-files/base-files/issue create mode 100644 base/base-files/base-files/issue.net create mode 100644 base/base-files/base-files/motd create mode 100644 base/base-files/base-files/nsswitch.conf create mode 100644 base/centos-release/centos/build_srpm.data create mode 100644 base/centos-release/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 base/centos-release/centos/meta_patches/PATCH_ORDER create mode 100644 base/centos-release/centos/meta_patches/centos-release-include-TiS-changes.patch create mode 100644 base/centos-release/centos/srpm_path create mode 100644 base/centos-release/files/issue create mode 100644 base/centos-release/files/issue.net create mode 100644 base/expect-lite/centos/build_srpm.data create mode 100644 base/expect-lite/centos/expect-lite.spec create mode 100644 base/lshell/centos/build_srpm.data create mode 100644 base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 base/lshell/centos/meta_patches/PATCH_ORDER create mode 100644 base/lshell/centos/meta_patches/spec-include-TiS-changes.patch create mode 100644 base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch create mode 100644 base/lshell/centos/srpm_path create mode 100755 base/lshell/files/cgcs_cli create mode 100644 base/lshell/files/lshell-newline-escape-character-support.patch create mode 100644 base/lshell/files/lshell-prompt-change-support.patch create mode 100644 base/lshell/files/lshell-shell-escape-check.patch create mode 100644 base/lshell/files/lshell-source-support.patch create mode 100644 base/lshell/files/lshell.conf create mode 100644 base/lshell/files/lshell_cgcs.patch create mode 100755 base/lshell/files/lshell_env_setup create mode 100644 base/lshell/files/wrs.sudo create mode 100644 base/namespace-utils/LICENSE create mode 100644 base/namespace-utils/centos/build_srpm.data create mode 100644 base/namespace-utils/centos/namespace-utils.spec create mode 100644 base/namespace-utils/namespace-utils/LICENSE create mode 100644 base/namespace-utils/namespace-utils/bashns.c create mode 100644 base/namespace-utils/namespace-utils/umount-in-namespace create mode 100644 base/nss-pam-ldapd/centos/build_srpm.data create mode 100644 base/nss-pam-ldapd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 base/nss-pam-ldapd/centos/meta_patches/PATCH_ORDER create mode 100644 base/nss-pam-ldapd/centos/meta_patches/remove-custom-nslcd-conf-file.patch create mode 100644 base/nss-pam-ldapd/centos/meta_patches/spec-TiS-changes.patch create mode 100644 base/nss-pam-ldapd/centos/meta_patches/spec-bind-nslcd-to-rootDN.patch create mode 100644 base/nss-pam-ldapd/centos/srpm_path create mode 100644 base/nss-pam-ldapd/files/login create mode 100755 base/nss-pam-ldapd/files/nslcd.init create mode 100644 base/setup/centos/build_srpm.data create mode 100644 base/setup/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 base/setup/centos/meta_patches/PATCH_ORDER create mode 100644 base/setup/centos/meta_patches/security-make-exports-and-fstab-only-root-accessible.patch create mode 100644 base/setup/centos/meta_patches/spec-add-TMOUT-variable.patch create mode 100644 base/setup/centos/meta_patches/spec-add-ironic-uid-gid.patch create mode 100644 base/setup/centos/meta_patches/spec-add-magnum-uid-gid.patch create mode 100644 base/setup/centos/meta_patches/spec-add-murano-uid-gid.patch create mode 100644 base/setup/centos/meta_patches/spec-include-TiS-changes.patch create mode 100644 base/setup/centos/meta_patches/spec-include-add-fm-user-to-snmpd-group.patch create mode 100644 base/setup/centos/meta_patches/spec-include-snmpd-fm-user-group.patch create mode 100644 base/setup/centos/meta_patches/spec-include-tis-uid-gid.patch create mode 100644 base/setup/centos/meta_patches/spec-passwd-remove-unused-default-users-and-groups.patch create mode 100644 base/setup/centos/meta_patches/spec-remove-unused-default-groups.patch create mode 100644 base/setup/centos/meta_patches/spec-set-custom-prompt.patch create mode 100644 base/setup/centos/meta_patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch create mode 100644 base/setup/centos/patches/add-fm-user-to-snmpd-group.patch create mode 100644 base/setup/centos/patches/add-ironic-uid-gid.patch create mode 100644 base/setup/centos/patches/add-magnum-uid-gid.patch create mode 100644 base/setup/centos/patches/add-murano-uid-gid.patch create mode 100644 base/setup/centos/patches/passwd-remove-unused-default-users-and-groups.patch create mode 100644 base/setup/centos/patches/remove-unused-default-groups.patch create mode 100644 base/setup/centos/patches/snmpd-fm-user-group.patch create mode 100644 base/setup/centos/patches/tis-uid-gid.patch create mode 100644 base/setup/centos/patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch create mode 100644 base/setup/centos/srpm_path create mode 100644 base/setup/files/custom.sh create mode 100644 base/setup/files/motd create mode 100644 base/setup/files/nsswitch.conf create mode 100644 base/setup/files/prompt.sh create mode 100644 base/tis-extensions/PKG-INFO create mode 100644 base/tis-extensions/centos/build_srpm.data create mode 100644 base/tis-extensions/centos/tis-extensions.spec create mode 100644 base/tis-extensions/files/LICENSE create mode 100644 base/tis-extensions/files/coredump-sysctl.conf create mode 100644 base/tis-extensions/files/coredump.conf create mode 100644 base/tis-extensions/files/modules-load-vfio.conf create mode 100644 base/tis-extensions/files/target create mode 100644 base/tis-extensions/files/target.service create mode 100644 connectivity/dhcp/PKG-INFO create mode 100644 connectivity/dhcp/centos/build_srpm.data create mode 100644 connectivity/dhcp/centos/files/dhclient-dhcp6-wrs-install-uuid.patch create mode 100644 connectivity/dhcp/centos/files/dhclient-disable-NSUPDATE.patch create mode 100644 connectivity/dhcp/centos/files/dhclient-enter-hooks create mode 100644 connectivity/dhcp/centos/files/dhclient-handle-wrs-install-uuid.patch create mode 100644 connectivity/dhcp/centos/files/dhclient-ipv6-bind-to-interface.patch create mode 100644 connectivity/dhcp/centos/files/dhclient-ipv6-conditionally-set-hostname.patch create mode 100644 connectivity/dhcp/centos/files/dhclient-restrict-interfaces-to-command-line.patch create mode 100644 connectivity/dhcp/centos/files/dhclient.conf create mode 100644 connectivity/dhcp/centos/files/dhcp-handle-default-classless-static-route.patch create mode 100644 connectivity/dhcp/centos/files/site.h create mode 100644 connectivity/dhcp/centos/files/support-disable-nsupdate.patch create mode 100644 connectivity/dhcp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 connectivity/dhcp/centos/meta_patches/PATCH_ORDER create mode 100644 connectivity/dhcp/centos/meta_patches/dhclient-dhcp6-set-hostname.patch create mode 100644 connectivity/dhcp/centos/meta_patches/dhclient-disable-NSUPDATE.patch create mode 100644 connectivity/dhcp/centos/meta_patches/mark-dhclient.conf-as-config.patch create mode 100644 connectivity/dhcp/centos/meta_patches/remove-unecessary-dhcp-exit-hooks-file.patch create mode 100644 connectivity/dhcp/centos/meta_patches/spec-dhcp-enter-hooks.patch create mode 100644 connectivity/dhcp/centos/meta_patches/spec-include-TiS-patches.patch create mode 100644 connectivity/dhcp/centos/srpm_path create mode 100644 connectivity/nfs-utils/centos/build_srpm.data create mode 100644 connectivity/nfs-utils/centos/meta_patches/0001-TiS-nfs-utils-spec-add-scripts.patch create mode 100644 connectivity/nfs-utils/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 connectivity/nfs-utils/centos/meta_patches/0001-add-rpm-4.14-compatibility.patch create mode 100644 connectivity/nfs-utils/centos/meta_patches/0002-Add-nfs-utils-update-nfsmount.conf-with-required-con.patch create mode 100644 connectivity/nfs-utils/centos/meta_patches/PATCH_ORDER create mode 100644 connectivity/nfs-utils/centos/meta_patches/nfs-utils-spec-file-disable-statd-service.patch create mode 100644 connectivity/nfs-utils/centos/patches/nfs-utils-do-not-pass-CFLAGS-to-native.patch create mode 100644 connectivity/nfs-utils/centos/patches/nfs-utils-support-mountprog-and-nfsprog-options.patch create mode 100644 connectivity/nfs-utils/centos/patches/nfs-utils-update-nfsmount.conf-with-required-config.patch create mode 100644 connectivity/nfs-utils/centos/srpm_path create mode 100644 connectivity/nfs-utils/files/nfs-mountd.service create mode 100644 connectivity/nfs-utils/files/nfs-server.service create mode 100644 connectivity/nfs-utils/files/nfs-statd.service create mode 100644 connectivity/nfs-utils/files/nfs-utils-do-not-pass-CFLAGS-to-native.patch create mode 100644 connectivity/nfs-utils/files/nfs-utils-support-mountprog-and-nfsprog-options.patch create mode 100644 connectivity/nfs-utils/files/nfs-utils.conf create mode 100644 connectivity/nfs-utils/files/nfscommon create mode 100644 connectivity/nfs-utils/files/nfscommon.service create mode 100644 connectivity/nfs-utils/files/nfsserver create mode 100644 connectivity/nfs-utils/files/nfsserver.service create mode 100644 connectivity/openssh/PKG-INFO create mode 100644 connectivity/openssh/centos/build_srpm.data create mode 100644 connectivity/openssh/centos/files/ssh_config create mode 100644 connectivity/openssh/centos/files/sshd_config create mode 100644 connectivity/openssh/centos/meta_patches/0001-Further-parallelize-openssh-build.patch create mode 100644 connectivity/openssh/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 connectivity/openssh/centos/meta_patches/PATCH_ORDER create mode 100644 connectivity/openssh/centos/meta_patches/openssh-init-script-kill-old-instances-on-start.patch create mode 100644 connectivity/openssh/centos/meta_patches/openssh-service-file.patch create mode 100644 connectivity/openssh/centos/meta_patches/openssh-spec-file-add-init.patch create mode 100644 connectivity/openssh/centos/meta_patches/spec-include-TiS-config-files.patch create mode 100644 connectivity/openssh/centos/meta_patches/sshd-pam-use-common-includes.patch create mode 100644 connectivity/openssh/centos/srpm_path create mode 100644 connectivity/openssh/files/add-roaming-no-option-ssh-config.patch create mode 100644 connectivity/openssh/files/sshd-security-hardening-and-disabling-password-based-rootssh.patch create mode 100644 core/initscripts/PKG-INFO create mode 100644 core/initscripts/centos/build_srpm.data create mode 100644 core/initscripts/centos/meta_patches/0001-Disable-zeroconf-route.patch create mode 100644 core/initscripts/centos/meta_patches/0001-Fix-Interfaces-intermittenly-do-not-come-up-on-boot.patch create mode 100644 core/initscripts/centos/meta_patches/0001-Support-PROMISC-for-interfaces-config.patch create mode 100644 core/initscripts/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 core/initscripts/centos/meta_patches/PATCH_ORDER create mode 100644 core/initscripts/centos/meta_patches/add_build_require_on_systemd.patch create mode 100644 core/initscripts/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch create mode 100644 core/initscripts/centos/meta_patches/force-delay-check-link-down.patch create mode 100644 core/initscripts/centos/meta_patches/ipv6-static-route-support.patch create mode 100644 core/initscripts/centos/meta_patches/run-ifdown-on-all-interfaces.patch create mode 100644 core/initscripts/centos/meta_patches/spec-add-mountnfs-init-script.patch create mode 100644 core/initscripts/centos/meta_patches/spec-ifup-eth-stop-waiting-if-link-is-up.patch create mode 100644 core/initscripts/centos/meta_patches/spec-include-TiS-changes.patch create mode 100644 core/initscripts/centos/meta_patches/spec-run-dhclient-as-daemon-for-ipv6.patch create mode 100644 core/initscripts/centos/meta_patches/spec-sysconfig-affirmative-check-for-link-carrier.patch create mode 100644 core/initscripts/centos/meta_patches/spec-sysconfig-unsafe-usage-of-linkdelay-variable.patch create mode 100644 core/initscripts/centos/meta_patches/stop-creating-shared-dirs.patch create mode 100644 core/initscripts/centos/patches/0001-dhclient-remove-1-arg.patch create mode 100644 core/initscripts/centos/patches/0001-force-delay-check-link-down.patch create mode 100644 core/initscripts/centos/patches/dhclient-restrict-interfaces-to-those-on-c.patch create mode 100644 core/initscripts/centos/patches/ifup-eth-stop-waiting-if-link-is-up.patch create mode 100644 core/initscripts/centos/patches/ipv6-static-route-support.patch create mode 100644 core/initscripts/centos/patches/relocate-dhclient-leases-to-var-run.patch create mode 100644 core/initscripts/centos/patches/run-dhclient-as-daemon-for-ipv6.patch create mode 100644 core/initscripts/centos/patches/run-ifdown-on-all-interfaces.patch create mode 100644 core/initscripts/centos/patches/support-interface-promisc.patch create mode 100644 core/initscripts/centos/patches/support-interface-scriptlets.patch create mode 100644 core/initscripts/centos/patches/sysconfig-affirmative-check-for-link-carrier.patch create mode 100644 core/initscripts/centos/patches/sysconfig-unsafe-usage-of-linkdelay-variable.patch create mode 100644 core/initscripts/centos/srpm_path create mode 100644 core/initscripts/files/mountnfs.service create mode 100755 core/initscripts/files/mountnfs.sh create mode 100644 core/util-linux/centos/build_srpm.data create mode 100644 core/util-linux/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 core/util-linux/centos/meta_patches/0003-util-linux-login-pamd.patch create mode 100644 core/util-linux/centos/meta_patches/PATCH_ORDER create mode 100644 core/util-linux/centos/meta_patches/spec-use-su-file-from-shadow.patch create mode 100644 core/util-linux/centos/srpm_path create mode 100644 devtools/facter/centos/build_srpm.data create mode 100644 devtools/facter/centos/meta_patches/0001-spec-include-TiS-paches.patch create mode 100644 devtools/facter/centos/meta_patches/0002-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/facter/centos/meta_patches/0003-Add-ipaddress-patch.patch create mode 100644 devtools/facter/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/facter/centos/patches/0001-ps.patch create mode 100644 devtools/facter/centos/patches/0002-personality.patch create mode 100644 devtools/facter/centos/patches/0003-centos_remove-net-commands-that-can-timeout.patch create mode 100644 devtools/facter/centos/patches/0004-centos_fix-ipv6-regex.patch create mode 100644 devtools/facter/centos/patches/0005-Hardcode-ipaddress-fact-to-localhost.patch create mode 100644 devtools/facter/centos/srpm_path create mode 100644 devtools/nfscheck/recipes-common/nfscheck/LICENSE create mode 100644 devtools/nfscheck/recipes-common/nfscheck/PKG-INFO create mode 100644 devtools/nfscheck/recipes-common/nfscheck/centos/build_srpm.data create mode 100644 devtools/nfscheck/recipes-common/nfscheck/centos/nfscheck.spec create mode 100644 devtools/nfscheck/recipes-common/nfscheck/files/LICENSE create mode 100755 devtools/nfscheck/recipes-common/nfscheck/files/nfscheck-init.sh create mode 100644 devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.service create mode 100644 devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.sh create mode 100644 devtools/puppet-4.8.2/centos/build_srpm.data create mode 100644 devtools/puppet-4.8.2/centos/meta_patches/0000-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-4.8.2/centos/meta_patches/0001-Add-WRS-Patches.patch create mode 100644 devtools/puppet-4.8.2/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-4.8.2/centos/patches/1001-Add-timestamps-to-logs.patch create mode 100644 devtools/puppet-4.8.2/centos/patches/1002-Set-hasstatus-to-false-by-default.patch create mode 100644 devtools/puppet-4.8.2/centos/patches/1003-Update-getpid-function.patch create mode 100644 devtools/puppet-4.8.2/centos/patches/1004-Block-enabling-of-services.patch create mode 100644 devtools/puppet-4.8.2/centos/patches/1005-Set-strict_variables-and-basemodulepath-in-puppet.co.patch create mode 100644 devtools/puppet-4.8.2/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0002-Add-Rebase-Patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0003-meta-fix-ceilometer-puppet-warnings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0002-Fix-ceilometer-puppet-warnings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0002-Add-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0003-Ceph-Jewel-rebase.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0004-Add-OSD-support-for-persistent-naming.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0005-meta-patch-for-patch5.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0002-Newton-rebase-fixes.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0003-Ceph-Jewel-rebase.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0004-US92424-Add-OSD-support-for-persistent-naming.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0005-Remove-puppetlabs-apt-as-ceph-requirement.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0002-Add-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0003-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0002-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch create mode 100644 devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0003-Add-region-cache-support.patch create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0002-Add-region-cache-support.patch create mode 100644 devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0002-Add-TIS-Patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0002-Ironic-dbsync-NeutronGlance-dep.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0003-Apply-xinetd-patch.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0001-Ironic-dbsync-NeutronGlance-dep-resolution.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0002-Dont-complain-about-xinetd-2.0.0.patch create mode 100644 devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-Titanium-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0002-squash-titanium-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0003-remove-the-keystone-admin-app.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0004-remove-eventlet_and_bindhost-from-keystoneconf.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0001-pike-rebase-squash-titanium-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0002-remove-the-Keystone-admin-app.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0003-remove-eventlet_bindhost-from-Keystoneconf.patch create mode 100644 devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0001-Pike-Rebase.patch create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0003-meta-expose-heat-and-neutron-endpoint-type.patch create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0001-Pike-Rebase.patch create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0003-expose-heat-and-neutron-endpoint-type.patch create mode 100644 devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0002-Add-TiS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0003-add-support-for-networking-sfc.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0002-Remove-broken-authtoken-references.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0003-control-provider-network-testing-state.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0004-set-wsgi-pool-size-to-10-from-100.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0005-Add-support-for-neutron-bgp-dragent.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0006-Add-parameters-to-classes.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0007-update-neutron-bgp-to-use-class-variables.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0008-dvr-allow-base-mac-address-to-be-configured.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0009-add-support-for-networking-sfc.patch create mode 100644 devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0002-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0003-upstreamable-fix-syntax-error-for-until_complete_rea.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0004-Setup-simple-cell.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0005-fix-pci-and-compute-pci.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0006-Create-Nova-ironic-conf.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0007-remove-joshuabaird-ipaclient-requirement.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0008-Add-pci_weight_multiple-to-scheduler-filter.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0009-Remove-SerialConsole-from-NovaConf.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0003-Create-nova_cell0-database.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0005-fix-pci-and-compute-pci.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0006-Create-Nova-ironic-conf.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0008-Adding-pci_weight_multiple-to-nova-scheduler-filter.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0009-Remove-SerialConsole-from-NovaConf.patch create mode 100644 devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0003-Add-os-region-name-option-for-system-controller.patch create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0002-Add-os-region-name-option-for-system-controller.patch create mode 100644 devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0002-Add-WRS-patch.patch create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0003-psycopg2-drivername-for-postgres.patch create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0001-Remove-log_dir-from-conf-files.patch create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0002-add-psycopg2-drivername-to-postgresql-settings.patch create mode 100644 devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/0001-meta-fix-panko-puppet-warning.patch create mode 100644 devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/patches/0001-Fix-panko-puppet-warning.patch create mode 100644 devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/srpm_path create mode 100644 devtools/puppet-modules/puppet-boolean-1.0.2/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-boolean-1.0.2/centos/puppet-boolean.spec create mode 100644 devtools/puppet-modules/puppet-create_resources/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-create_resources/centos/puppet-create_resources.spec create mode 100644 devtools/puppet-modules/puppet-dnsmasq/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-dnsmasq/centos/files/0001-puppet-dnsmasq-Kilo-quilt-patches.patch create mode 100644 devtools/puppet-modules/puppet-dnsmasq/centos/files/0002-Fixing-mismatched-permission-on-dnsmasq-conf.patch create mode 100644 devtools/puppet-modules/puppet-dnsmasq/centos/files/0003-Support-management-of-tftp_max-option.patch create mode 100644 devtools/puppet-modules/puppet-dnsmasq/centos/files/0004-Enable-clear-DNS-cache-on-reload.patch create mode 100644 devtools/puppet-modules/puppet-dnsmasq/centos/puppet-dnsmasq.spec create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0001-TIS-Patches.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0002-Disable-timeout-for-mkfs-command.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0003-drbd-parallel-to-serial-synchronization.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0004-US-96914-reuse-existing-drbd-cinder-resource.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0005-Add-PausedSync-states-to-acceptable-cstate.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0006-CGTS-7164-Add-resource-options-cpu-mask-to-affine-drbd-kernel-threads.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0007-Add-disk-by-path-test.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0008-CGTS-7953-support-for-new-drbd-resources.patch create mode 100644 devtools/puppet-modules/puppet-drbd-0.3.1/centos/puppet-drbd.spec create mode 100644 devtools/puppet-modules/puppet-filemapper/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-filemapper/centos/puppet-filemapper.spec create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0002-Add-TIS-patch.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0003-disable-config-validation-prechecks.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0004-Add-global_options-patch.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0002-disable-config-validation-prechecks.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0003-Fix-global_options-log-default-value.patch create mode 100644 devtools/puppet-modules/puppet-haproxy-1.5.0/centos/srpm_path create mode 100644 devtools/puppet-modules/puppet-ldap/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-ldap/centos/puppet-ldap.spec create mode 100755 devtools/puppet-modules/puppet-ldap/puppet_downloader.sh create mode 100644 devtools/puppet-modules/puppet-lvm/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-lvm/centos/files/0001-puppet-lvm-kilo-quilt-changes.patch create mode 100644 devtools/puppet-modules/puppet-lvm/centos/files/0002-UEFI-pvcreate-fix.patch create mode 100644 devtools/puppet-modules/puppet-lvm/centos/files/0003-US94222-Persistent-Dev-Naming.patch create mode 100644 devtools/puppet-modules/puppet-lvm/centos/files/0004-extendind-nuke_fs_on_resize_failure-functionality.patch create mode 100644 devtools/puppet-modules/puppet-lvm/centos/puppet-lvm.spec create mode 100644 devtools/puppet-modules/puppet-network/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-network/centos/files/Don-t-write-absent-to-redhat-route-files-and-test-fo.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/files/fix-absent-options.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/files/ipv6-static-route-support.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/files/permit-inservice-update-of-static-routes.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/files/puppet-network-Kilo-quilt-changes.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/files/puppet-network-support-ipv6.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/files/route-options-support.patch create mode 100644 devtools/puppet-modules/puppet-network/centos/puppet-network.spec create mode 100644 devtools/puppet-modules/puppet-nslcd/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-nslcd/centos/puppet-nslcd.spec create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/centos/puppet-ovs_dpdk.spec create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/openvswitch_agent.ini create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_post create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_pre create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_openvswitch_agent_ini create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_service_config create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config.pp create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config_files.pp create mode 100644 devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/init.pp create mode 100644 devtools/puppet-modules/puppet-postgresql-4.8.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0002-remove-puppetlabs-apt-as-a-requirement.patch create mode 100644 devtools/puppet-modules/puppet-postgresql-4.8.0/centos/puppet-postgresql.spec create mode 100644 devtools/puppet-modules/puppet-puppi/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-puppi/centos/puppet-puppi.spec create mode 100755 devtools/puppet-modules/puppet-puppi/puppet_downloader.sh create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0002-Add-TIS-patch.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0003-meta-Changed-cipher-specification-to-openssl-format.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0004-Add-deprecation-patch-to-spec.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0005-metapatch-for-revert.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0006-metapatch-for-fact-removal.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0001-Roll-up-TIS-patches.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0002-Changed-cipher-specification-to-openssl-format.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0003-Eliminate-Puppet-4-deprecation-warnings.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0004-Partially-revert-upstream-commit-f7c3a4a637d59f3065d.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0005-Remove-the-rabbitmq_nodename-fact.patch create mode 100644 devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/srpm_path create mode 100644 devtools/puppet-modules/puppet-staging/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-staging/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/puppet-staging/centos/meta_patches/0002-Apply-rename-patch.patch create mode 100644 devtools/puppet-modules/puppet-staging/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/puppet-staging/centos/patches/0001-Rename-nanliu-staging-to-puppet-staging.patch create mode 100644 devtools/puppet-modules/puppet-staging/centos/srpm_path create mode 100644 devtools/puppet-modules/puppet-stdlib-4.12.0/centos/build_srpm.data create mode 100644 devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0002-Add-TIS-Patches.patch create mode 100644 devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/puppet-modules/puppet-stdlib-4.12.0/centos/patches/0001-Filter-password-in-logs.patch create mode 100644 devtools/puppet-modules/puppet-stdlib-4.12.0/centos/srpm_path create mode 100644 devtools/python-setuptools/centos/build_srpm.data create mode 100644 devtools/python-setuptools/centos/python-setuptools.spec create mode 100644 devtools/python-setuptools/files/LICENSE create mode 100644 devtools/python-setuptools/files/LICENSE-2.0 create mode 100644 devtools/python-setuptools/files/LICENSE.txt create mode 100644 devtools/python/python-django/centos/build_srpm.data create mode 100644 devtools/python/python-django/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/python/python-django/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/python/python-django/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch create mode 100644 devtools/python/python-django/centos/meta_patches/meta-size-number-format.patch create mode 100644 devtools/python/python-django/centos/meta_patches/spec-include-TiS-patches.patch create mode 100644 devtools/python/python-django/centos/meta_patches/spec-patch-to-remove-SmartyPants.patch create mode 100644 devtools/python/python-django/centos/patches/remove-SmartyPantsHTMLTranslator.patch create mode 100644 devtools/python/python-django/centos/patches/size-number-format.patch create mode 100644 devtools/python/python-django/centos/srpm_path create mode 100644 devtools/python/python-django/files/session-filebase-backend-fix.patch create mode 100644 devtools/python/python-django/update-session-filebase-backend.patch create mode 100644 devtools/python/python-eventlet_0.17.3/throttle_response_logs.patch create mode 100644 devtools/python/python-nose_1.3.0/enable-logging-realtime.patch create mode 100644 devtools/python/python-rtstool-0.1a4/fix-build-error.patch create mode 100644 devtools/python/python-sqlalchemy_0.9.9/sqlalchemy_queue_pool_info.patch create mode 100644 devtools/python/python_2.7.3/fix_pipe_leak_in_subprocess.patch create mode 100644 devtools/python/python_2.7.3/syslog_bugfix.patch create mode 100644 devtools/qemu/.gitignore create mode 100644 devtools/qemu/PKG-INFO create mode 100644 devtools/qemu/README create mode 100644 devtools/qemu/centos/build_srpm.data create mode 100644 devtools/qemu/centos/files/80-kvm.rules create mode 100644 devtools/qemu/centos/files/85-kvm.preset create mode 100644 devtools/qemu/centos/files/95-kvm-memlock.conf create mode 100644 devtools/qemu/centos/files/99-qemu-guest-agent.rules create mode 100644 devtools/qemu/centos/files/README.rhel6-gpxe-source create mode 100644 devtools/qemu/centos/files/bios-256k.bin create mode 100644 devtools/qemu/centos/files/bridge.conf create mode 100755 devtools/qemu/centos/files/build_configure.sh create mode 100644 devtools/qemu/centos/files/ksm.service create mode 100644 devtools/qemu/centos/files/ksm.sysconfig create mode 100644 devtools/qemu/centos/files/ksmctl.c create mode 100644 devtools/qemu/centos/files/ksmtuned create mode 100644 devtools/qemu/centos/files/ksmtuned.conf create mode 100644 devtools/qemu/centos/files/ksmtuned.service create mode 100644 devtools/qemu/centos/files/kvm-setup create mode 100644 devtools/qemu/centos/files/kvm-setup.service create mode 100644 devtools/qemu/centos/files/kvm.conf create mode 100644 devtools/qemu/centos/files/qemu-ga.sysconfig create mode 100644 devtools/qemu/centos/files/qemu-guest-agent.service create mode 100644 devtools/qemu/centos/files/qemu.binfmt create mode 100644 devtools/qemu/centos/files/rhel6-e1000.rom create mode 100644 devtools/qemu/centos/files/rhel6-ne2k_pci.rom create mode 100644 devtools/qemu/centos/files/rhel6-pcnet.rom create mode 100644 devtools/qemu/centos/files/rhel6-rtl8139.rom create mode 100644 devtools/qemu/centos/files/rhel6-virtio.rom create mode 100644 devtools/qemu/centos/files/vhost.conf create mode 100644 devtools/qemu/centos/qemu-kvm.spec create mode 100644 devtools/qemu/qemu/qemu-system-x86.conf create mode 100644 devtools/qemu/qemu/qemu_clean create mode 100644 devtools/qemu/qemu/qemu_clean.service create mode 100755 devtools/qemu/scripts/autopatch.sh create mode 100644 devtools/update-motd/LICENSE create mode 100644 devtools/update-motd/PKG-INFO create mode 100644 devtools/update-motd/centos/build_srpm.data create mode 100644 devtools/update-motd/centos/update-motd.spec create mode 100644 devtools/update-motd/files/LICENSE create mode 100644 devtools/update-motd/files/apply_banner_customization create mode 100644 devtools/update-motd/files/customize-banner create mode 100644 devtools/update-motd/files/install_banner_customization create mode 100644 devtools/update-motd/files/motd-footer create mode 100644 devtools/update-motd/files/motd-header create mode 100644 devtools/update-motd/files/motd-update create mode 100644 devtools/update-motd/files/motd-update.cron create mode 100644 devtools/vim/centos/build_srpm.data create mode 100644 devtools/vim/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 devtools/vim/centos/meta_patches/PATCH_ORDER create mode 100644 devtools/vim/centos/srpm_path create mode 100644 devtools/vim/files/vimrc create mode 100644 extended/cloud-init/centos/build_srpm.data create mode 100644 extended/cloud-init/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/cloud-init/centos/meta_patches/PATCH_ORDER create mode 100644 extended/cloud-init/centos/meta_patches/spec-include-tis-changes.patch create mode 100644 extended/cloud-init/centos/patches/cloud-init-interactive-parted.patch create mode 100644 extended/cloud-init/centos/srpm_path create mode 100644 extended/cloud-init/cloud-init/cloud-init-interactive-parted.patch create mode 100644 extended/cloud-init/cloud-init/find_candidate_devs_fix.patch create mode 100644 extended/cloud-init/cloud-init/first_boot.patch create mode 100644 extended/e2fsprogs/centos/build_srpm.data create mode 100644 extended/e2fsprogs/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/e2fsprogs/centos/meta_patches/0002-SPEC-tamper-proof-bash-log.patch create mode 100644 extended/e2fsprogs/centos/meta_patches/PATCH_ORDER create mode 100644 extended/e2fsprogs/centos/meta_patches/meta-e2fsprogs-disable-tests.patch create mode 100644 extended/e2fsprogs/centos/patches/0100-tamper-proof-bash-log.patch create mode 100644 extended/e2fsprogs/centos/patches/0101-e2fsprogs-disable-tests.patch create mode 100644 extended/e2fsprogs/centos/srpm_path create mode 100644 extended/iproute/centos/build_srpm.data create mode 100644 extended/iproute/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/iproute/centos/meta_patches/Add-WRS-ip-maddr-fix-ifname.patch create mode 100644 extended/iproute/centos/meta_patches/PATCH_ORDER create mode 100644 extended/iproute/centos/patches/ip-maddr-fix-ifname.patch create mode 100644 extended/iproute/centos/srpm_path create mode 100644 extended/irqbalance/centos/build_srpm.data create mode 100644 extended/irqbalance/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/irqbalance/centos/meta_patches/PATCH_ORDER create mode 100644 extended/irqbalance/centos/meta_patches/spec-disable-irqbalance-service.patch create mode 100644 extended/irqbalance/centos/srpm_path create mode 100644 extended/libvirt-python/PKG-INFO create mode 100644 extended/libvirt-python/centos/build_srpm.data create mode 100644 extended/libvirt-python/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/libvirt-python/centos/meta_patches/PATCH_ORDER create mode 100644 extended/libvirt-python/centos/srpm_path create mode 100644 extended/libvirt/.gitignore create mode 100644 extended/libvirt/PKG-INFO create mode 100644 extended/libvirt/README create mode 100644 extended/libvirt/centos/build_srpm.data create mode 100644 extended/libvirt/centos/libvirt.spec create mode 100644 extended/libvirt/libvirt-2.0.0/libvirt.logrotate create mode 100644 extended/libvirt/libvirt-2.0.0/libvirt.lxc create mode 100644 extended/libvirt/libvirt-2.0.0/libvirt.qemu create mode 100644 extended/libvirt/libvirt-2.0.0/libvirt.uml create mode 100644 extended/libvirt/libvirt-3.5.0/libvirt.logrotate create mode 100644 extended/libvirt/libvirt-3.5.0/libvirt.lxc create mode 100644 extended/libvirt/libvirt-3.5.0/libvirt.qemu create mode 100644 extended/libvirt/libvirt-3.5.0/libvirt.uml create mode 100644 extended/lighttpd/PKG-INFO create mode 100755 extended/lighttpd/centos/build_srpm.data create mode 100644 extended/lighttpd/centos/meta_patches/0001-Adding-tmp-dir-under-lighttpd-chroot-environ.patch create mode 100644 extended/lighttpd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/lighttpd/centos/meta_patches/PATCH_ORDER create mode 100644 extended/lighttpd/centos/meta_patches/meta_add_support_for_tpm.patch create mode 100644 extended/lighttpd/centos/meta_patches/spec-check-content-length.patch create mode 100644 extended/lighttpd/centos/meta_patches/spec-include-TiS-changes.patch create mode 100644 extended/lighttpd/centos/srpm_path create mode 100644 extended/lighttpd/lighttpd-1.4.35/check-content-length.patch create mode 100644 extended/lighttpd/lighttpd-1.4.35/index.html.lighttpd create mode 100644 extended/lighttpd/lighttpd-1.4.35/lighttpd-csr.conf create mode 100644 extended/lighttpd/lighttpd-1.4.35/lighttpd-inc.conf create mode 100644 extended/lighttpd/lighttpd-1.4.35/lighttpd-tpm-support.patch create mode 100755 extended/lighttpd/lighttpd-1.4.35/lighttpd.conf create mode 100755 extended/lighttpd/lighttpd-1.4.35/lighttpd.init create mode 100644 extended/lighttpd/lighttpd-1.4.35/lighttpd.logrotate create mode 100644 extended/lighttpd/lighttpd-1.4.35/remote-ip-ipv6-support.patch create mode 100644 extended/lldpd/centos/build_srpm.data create mode 100644 extended/lldpd/centos/files/i40e-lldp-configure.sh create mode 100644 extended/lldpd/centos/files/lldpd-clear-station.patch create mode 100644 extended/lldpd/centos/files/lldpd-create-run-dir.patch create mode 100644 extended/lldpd/centos/files/lldpd-i40e-disable.patch create mode 100644 extended/lldpd/centos/lldpd.spec create mode 100644 extended/lldpd/lldpd-0.9.0/lldpd-interface-show.patch create mode 100644 extended/lldpd/lldpd-0.9.0/lldpd.default create mode 100644 extended/lldpd/lldpd-0.9.0/lldpd.init create mode 100644 extended/logrotate/centos/build_srpm.data create mode 100644 extended/logrotate/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/logrotate/centos/meta_patches/0002-crond-adjustment.patch create mode 100644 extended/logrotate/centos/meta_patches/0003-Add-upstream-patches.patch create mode 100644 extended/logrotate/centos/meta_patches/0004-Add-su-patch.patch create mode 100644 extended/logrotate/centos/meta_patches/PATCH_ORDER create mode 100644 extended/logrotate/centos/patches/0001-createOutputFile-rename-already-existing-file.patch create mode 100644 extended/logrotate/centos/patches/0002-createOutputFile-eliminate-stat-open-TOCTOU-race.patch create mode 100644 extended/logrotate/centos/patches/0003-Add-su-root-to-logrotate.conf.patch create mode 100644 extended/logrotate/centos/srpm_path create mode 100644 extended/logrotate/files/logrotate-cron.d create mode 100644 extended/nova-utils/centos/build_srpm.data create mode 100644 extended/nova-utils/centos/nova-utils.spec create mode 100644 extended/nova-utils/nova-utils/LICENSE create mode 100755 extended/nova-utils/nova-utils/nova-sriov create mode 100644 extended/novnc/centos/build_srpm.data create mode 100644 extended/novnc/centos/meta_patches/0001-Update-package-0.6.2-versioning-for-TIS-format.patch create mode 100644 extended/novnc/centos/meta_patches/PATCH_ORDER create mode 100644 extended/novnc/centos/srpm_path create mode 100644 extended/ntp/centos/build_srpm.data create mode 100644 extended/ntp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/ntp/centos/meta_patches/PATCH_ORDER create mode 100644 extended/ntp/centos/meta_patches/ntp-spec-add-TiS-custom-config-files.patch create mode 100644 extended/ntp/centos/meta_patches/ntpd-started-no-g-option.patch create mode 100644 extended/ntp/centos/patches/ntp-cgcs.conf create mode 100644 extended/ntp/centos/srpm_path create mode 100644 extended/ntp/ntp-4.2.6p5/ntp-cgcs.conf create mode 100755 extended/ntp/ntp-4.2.6p5/ntpd create mode 100644 extended/ntp/ntp-4.2.8p6/ntp-cgcs.conf create mode 100755 extended/ntp/ntp-4.2.8p6/ntpd create mode 100644 extended/pam/centos/build_srpm.data create mode 100644 extended/pam/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/pam/centos/meta_patches/PATCH_ORDER create mode 100644 extended/pam/centos/meta_patches/pam-spec-add-custome-config-files.patch create mode 100644 extended/pam/centos/srpm_path create mode 100755 extended/pam/files/pam.d/common-account create mode 100755 extended/pam/files/pam.d/common-auth create mode 100755 extended/pam/files/pam.d/common-password create mode 100755 extended/pam/files/pam.d/common-session create mode 100755 extended/pam/files/pam.d/common-session-noninteractive create mode 100755 extended/pam/files/pam.d/system-auth.pamd create mode 100644 extended/procps/files/sysctl.conf create mode 100644 extended/python-cephclient/centos/build_srpm.data create mode 100644 extended/python-cephclient/centos/python-cephclient.spec create mode 100644 extended/python-cephclient/python-cephclient/0001-US63903-Ceph-Rebase-Update-REST-API-to-0.94.2.patch create mode 100644 extended/python-cephclient/python-cephclient/0001-US70398-Ceph-Rebase-Update-REST-API-to-0.94.5.patch create mode 100644 extended/python-cephclient/python-cephclient/US92424-Ceph-Rebase-Update-REST-API-to-10.2.4.patch create mode 100644 extended/python-cephclient/python-cephclient/add-osd-get-pool-quota.patch create mode 100644 extended/python-cephclient/python-cephclient/fix-osd-crush-remove.patch create mode 100644 extended/python-cephclient/python-cephclient/fix-osd-tier-add.patch create mode 100644 extended/python-cephclient/python-cephclient/set-default-endpoint.patch create mode 100644 extended/python-gunicorn/centos/build_srpm.data create mode 100644 extended/python-gunicorn/centos/meta_patches/0001-TIS-gunicorn-19-upgrade.patch create mode 100644 extended/python-gunicorn/centos/meta_patches/0001-TIS-packaging.patch create mode 100644 extended/python-gunicorn/centos/meta_patches/0001-add-worker-abort-patch.patch create mode 100644 extended/python-gunicorn/centos/meta_patches/PATCH_ORDER create mode 100644 extended/python-gunicorn/centos/patches/0001-add-worker-abort-hook.patch create mode 100644 extended/python-gunicorn/centos/srpm_path create mode 100644 extended/python-ryu/centos/build_srpm.data create mode 100755 extended/python-ryu/centos/python-ryu.spec create mode 100644 extended/python-smartpm/centos/build_srpm.data create mode 100644 extended/python-smartpm/centos/centos.info create mode 100644 extended/python-smartpm/centos/patches/smart-add-for-rpm-ignoresize-check.patch create mode 100644 extended/python-smartpm/centos/patches/smart-attempt.patch create mode 100644 extended/python-smartpm/centos/patches/smart-channelsdir.patch create mode 100644 extended/python-smartpm/centos/patches/smart-config-ignore-all-recommends.patch create mode 100644 extended/python-smartpm/centos/patches/smart-conflict-provider.patch create mode 100644 extended/python-smartpm/centos/patches/smart-dflags.patch create mode 100644 extended/python-smartpm/centos/patches/smart-filename-NAME_MAX.patch create mode 100644 extended/python-smartpm/centos/patches/smart-flag-exclude-packages.patch create mode 100644 extended/python-smartpm/centos/patches/smart-flag-ignore-recommends.patch create mode 100644 extended/python-smartpm/centos/patches/smart-improve-error-reporting.patch create mode 100644 extended/python-smartpm/centos/patches/smart-metadata-match.patch create mode 100644 extended/python-smartpm/centos/patches/smart-multilib-fixes.patch create mode 100644 extended/python-smartpm/centos/patches/smart-recommends.patch create mode 100644 extended/python-smartpm/centos/patches/smart-rpm-extra-macros.patch create mode 100644 extended/python-smartpm/centos/patches/smart-rpm-md-parse.patch create mode 100644 extended/python-smartpm/centos/patches/smart-rpm-root.patch create mode 100644 extended/python-smartpm/centos/patches/smart-set-noprogress-for-pycurl.patch create mode 100644 extended/python-smartpm/centos/patches/smart-support-rpm4.patch create mode 100644 extended/python-smartpm/centos/patches/smart-tmpdir.patch create mode 100644 extended/python-smartpm/centos/patches/smart-yaml-error.patch create mode 100644 extended/python-smartpm/centos/patches/smartpm-rpm5-nodig.patch create mode 100644 extended/python-smartpm/centos/python-smartpm.spec create mode 100644 extended/python-smartpm/files/commit_transaction_error_handling.patch create mode 100644 extended/sanlock/centos/build_srpm.data create mode 100644 extended/sanlock/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/sanlock/centos/meta_patches/PATCH_ORDER create mode 100644 extended/sanlock/centos/meta_patches/spec-sanlock-systemctl-post-enable-preun-disable.patch create mode 100644 extended/sanlock/centos/meta_patches/spec-wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch create mode 100644 extended/sanlock/centos/patches/wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch create mode 100644 extended/sanlock/centos/srpm_path create mode 100644 extended/shadow/centos/build_srpm.data create mode 100644 extended/shadow/centos/files/clear_shadow_locks.service create mode 100644 extended/shadow/centos/files/login.defs.cgcs create mode 100644 extended/shadow/centos/meta_patches/0001-Further-parallelize-shadow-utils-build.patch create mode 100644 extended/shadow/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/shadow/centos/meta_patches/PATCH_ORDER create mode 100644 extended/shadow/centos/meta_patches/add-BuildRequires-systemd.patch create mode 100644 extended/shadow/centos/meta_patches/add-clear-shadow-locs-service-in-spec.patch create mode 100644 extended/shadow/centos/srpm_path create mode 100644 extended/shadow/files/clear_shadow_locks create mode 100644 extended/shadow/files/pam.d/su create mode 100644 extended/shim-signed/centos/build_srpm.data create mode 100644 extended/shim-signed/centos/meta_patches/0001-Use-presigned-binary.patch create mode 100644 extended/shim-signed/centos/meta_patches/0001-calculate-rather-than-hardcode-shim-unsigned-version.patch create mode 100644 extended/shim-signed/centos/meta_patches/PATCH_ORDER create mode 100644 extended/shim-signed/centos/srpm_path create mode 100644 extended/shim-unsigned/centos/build_srpm.data create mode 100644 extended/shim-unsigned/centos/meta_patches/0001-Embed-TiS-cert.patch create mode 100644 extended/shim-unsigned/centos/meta_patches/0001-Objcopy-version.patch create mode 100644 extended/shim-unsigned/centos/meta_patches/PATCH_ORDER create mode 100644 extended/shim-unsigned/centos/meta_patches/spec.arch.patch create mode 100644 extended/shim-unsigned/centos/patches/0001-Objcopy-version.patch create mode 100644 extended/shim-unsigned/centos/patches/0001-Use-TiS-cert.patch create mode 100644 extended/shim-unsigned/centos/srpm_path create mode 100644 extended/shim-unsigned/files/tis-shim.crt create mode 100644 extended/sudo/centos/build_srpm.data create mode 100644 extended/sudo/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/sudo/centos/meta_patches/0002-spec-include-TiS-changes.patch create mode 100644 extended/sudo/centos/meta_patches/0003-Further-parallelize-sudo-build.patch create mode 100644 extended/sudo/centos/meta_patches/0004-remove-make-check.patch create mode 100644 extended/sudo/centos/meta_patches/PATCH_ORDER create mode 100644 extended/sudo/centos/srpm_path create mode 100644 extended/sudo/files/sudo-CVE-2015-5602.patch create mode 100644 extended/syslog-ng/centos/build_srpm.data create mode 100644 extended/syslog-ng/centos/files/fm_event_syslogger create mode 100644 extended/syslog-ng/centos/files/remotelogging.conf create mode 100644 extended/syslog-ng/centos/files/syslog-ng.conf create mode 100644 extended/syslog-ng/centos/files/syslog-ng.logrotate create mode 100644 extended/syslog-ng/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/syslog-ng/centos/meta_patches/0002-Add-TIS-content.patch create mode 100644 extended/syslog-ng/centos/meta_patches/0003-add-fm-event-syslogger.patch create mode 100644 extended/syslog-ng/centos/meta_patches/PATCH_ORDER create mode 100644 extended/syslog-ng/centos/patches/syslog-ng-service-pid-file-pmond.patch create mode 100644 extended/syslog-ng/centos/srpm_path create mode 100644 extended/systemd/centos/build_srpm.data create mode 100644 extended/systemd/centos/meta_patches/0001-update-package-versioning-for-TIS-format.patch create mode 100644 extended/systemd/centos/meta_patches/0003-spec-expand-_udevrulesdir-macro.patch create mode 100644 extended/systemd/centos/meta_patches/0004-Protect-sections-of-systemd-post-from-running-on-pat.patch create mode 100644 extended/systemd/centos/meta_patches/0005-spec-millisec-in-syslog-date.patch create mode 100644 extended/systemd/centos/meta_patches/0007-Add-patch-for-journald-config.patch create mode 100644 extended/systemd/centos/meta_patches/0008-Add-patch-for-journald-config-rate-limit.patch create mode 100644 extended/systemd/centos/meta_patches/0009-Add-patch-to-remove-ID_SAS_PATH-rule.patch create mode 100644 extended/systemd/centos/meta_patches/0010-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch create mode 100644 extended/systemd/centos/meta_patches/0011-Add-patch-for-moving-vartmp-to-tmpfs.patch create mode 100644 extended/systemd/centos/meta_patches/0012-Add-patch-for-restricting-tmpfs-size.patch create mode 100644 extended/systemd/centos/meta_patches/PATCH_ORDER create mode 100644 extended/systemd/centos/patches/0501-inject-millisec-in-syslog-date.patch create mode 100644 extended/systemd/centos/patches/0503-Configure-journald-to-forward-to-syslog.patch create mode 100644 extended/systemd/centos/patches/0504-Configure-journald-rate-limit.patch create mode 100644 extended/systemd/centos/patches/0505-remove-id-sas-path-symlink.patch create mode 100644 extended/systemd/centos/patches/0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch create mode 100644 extended/systemd/centos/patches/0507-move-vartmp-to-tmpfs.patch create mode 100644 extended/systemd/centos/patches/0508-set-a-1GB-size-restriction-on-tpmfs.patch create mode 100644 extended/systemd/centos/srpm_path create mode 100644 extended/tboot/centos/build_srpm.data create mode 100644 extended/tboot/centos/meta_patches/0001-tboot-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/tboot/centos/meta_patches/0002-TiS-tboot.patch create mode 100644 extended/tboot/centos/meta_patches/0003-security-set-immutable-attribute.patch create mode 100644 extended/tboot/centos/meta_patches/PATCH_ORDER create mode 100644 extended/tboot/centos/patches/1000-tboot-for-tis.patch create mode 100644 extended/tboot/centos/srpm_path create mode 100644 extended/watchdog/centos/build_srpm.data create mode 100644 extended/watchdog/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 extended/watchdog/centos/meta_patches/PATCH_ORDER create mode 100644 extended/watchdog/centos/meta_patches/spec-TiS-changes.patch create mode 100644 extended/watchdog/centos/srpm_path create mode 100644 extended/watchdog/files/fix-ping-failure.patch create mode 100644 kernel-rt/centos/build_srpm.data create mode 100644 kernel-rt/centos/meta_patches/Add-patch-for-missing-ifdef-in-tracing.patch create mode 100644 kernel-rt/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch create mode 100644 kernel-rt/centos/meta_patches/Change-name-of-source-tarball-drop-el7.patch create mode 100644 kernel-rt/centos/meta_patches/Check-for-oversized-nfs-arguments.patch create mode 100644 kernel-rt/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch create mode 100644 kernel-rt/centos/meta_patches/Correct-the-source-tarball-name.patch create mode 100644 kernel-rt/centos/meta_patches/Disable-debug.patch create mode 100644 kernel-rt/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch create mode 100644 kernel-rt/centos/meta_patches/Enable-symvers.patch create mode 100644 kernel-rt/centos/meta_patches/Exclude-package-defs-for-unbuilt-firmware-and-doc-pk.patch create mode 100644 kernel-rt/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch create mode 100644 kernel-rt/centos/meta_patches/Fix-stack-clash.patch create mode 100644 kernel-rt/centos/meta_patches/PATCH_ORDER create mode 100644 kernel-rt/centos/meta_patches/PM-introduce-per-cpu-power-management.patch create mode 100644 kernel-rt/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch create mode 100644 kernel-rt/centos/meta_patches/Porting-Kernfs-from-Kernel-3.10.patch create mode 100644 kernel-rt/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch create mode 100644 kernel-rt/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch create mode 100644 kernel-rt/centos/meta_patches/Rework-pkg-release-naming.patch create mode 100644 kernel-rt/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch create mode 100644 kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format-revised.patch create mode 100644 kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format.patch create mode 100644 kernel-rt/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch create mode 100644 kernel-rt/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch create mode 100644 kernel-rt/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch create mode 100644 kernel-rt/centos/meta_patches/fix-high-latency-reported-by-cyclictest.patch create mode 100644 kernel-rt/centos/meta_patches/lose-the-memblock-reorder-parms-patch.patch create mode 100644 kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch create mode 100644 kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch create mode 100644 kernel-rt/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch create mode 100644 kernel-rt/centos/meta_patches/tis-add-tools.patch create mode 100644 kernel-rt/centos/meta_patches/tis-apply-patches.patch create mode 100644 kernel-rt/centos/meta_patches/tis-build-unsigned-package.patch create mode 100644 kernel-rt/centos/meta_patches/tis-debrand-and-add-centos-certificate.patch create mode 100644 kernel-rt/centos/meta_patches/tis-handle-tis-config-customizations.patch create mode 100644 kernel-rt/centos/meta_patches/tis-remove-signing.patch create mode 100644 kernel-rt/centos/meta_patches/tis-remove-trace.patch create mode 100644 kernel-rt/centos/meta_patches/x86-dma_alloc_coherent-fix.patch create mode 100644 kernel-rt/centos/patches/Add-missing-ifdef-around-max-latency-variable.patch create mode 100644 kernel-rt/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch create mode 100644 kernel-rt/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch create mode 100644 kernel-rt/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch create mode 100644 kernel-rt/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch create mode 100644 kernel-rt/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch create mode 100644 kernel-rt/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch create mode 100644 kernel-rt/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch create mode 100644 kernel-rt/centos/patches/Make-kernel-start-eth-devices-at-offset.patch create mode 100644 kernel-rt/centos/patches/Notification-of-death-of-arbitrary-processes.patch create mode 100644 kernel-rt/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch create mode 100644 kernel-rt/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch create mode 100644 kernel-rt/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch create mode 100644 kernel-rt/centos/patches/US103091-IMA-System-Configuration.patch create mode 100644 kernel-rt/centos/patches/affine-compute-kernel-threads.patch create mode 100644 kernel-rt/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch create mode 100644 kernel-rt/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch create mode 100644 kernel-rt/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch create mode 100644 kernel-rt/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch create mode 100644 kernel-rt/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch create mode 100644 kernel-rt/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch create mode 100644 kernel-rt/centos/patches/cpupower.config create mode 100644 kernel-rt/centos/patches/cpupower.service create mode 100644 kernel-rt/centos/patches/debrand-rh-i686-cpu.patch create mode 100644 kernel-rt/centos/patches/debrand-rh_taint.patch create mode 100644 kernel-rt/centos/patches/debrand-single-cpu.patch create mode 100644 kernel-rt/centos/patches/dpt_i2o-fix-build-warning.patch create mode 100644 kernel-rt/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch create mode 100644 kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-debug.config.tis_extra create mode 100644 kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-trace.config.tis_extra create mode 100644 kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt.config.tis_extra create mode 100644 kernel-rt/centos/patches/memblock-introduce-memblock_alloc_range.patch create mode 100644 kernel-rt/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch create mode 100644 kernel-rt/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch create mode 100644 kernel-rt/centos/patches/timer-Minimize-nohz-off-overhead.patch create mode 100644 kernel-rt/centos/patches/timer-Reduce-timer-migration-overhead-if-disabled.patch create mode 100644 kernel-rt/centos/patches/turn-off-write-same-in-smartqpi-driver.patch create mode 100644 kernel-rt/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch create mode 100644 kernel-rt/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch create mode 100644 kernel-rt/centos/srpm_path create mode 100644 kernel-rt/files/centos.cer create mode 100644 kernel-rt/files/ima_signing_key.pub create mode 100644 kernel-std/centos/build_srpm.data create mode 100644 kernel-std/centos/meta_patches/Allow-ignoring-Ethernet-device-RMRR-with-IOMMU-passt.patch create mode 100644 kernel-std/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch create mode 100644 kernel-std/centos/meta_patches/Centos-fix-calltrace-in-megaraid-sas-driver.patch create mode 100644 kernel-std/centos/meta_patches/Check-for-oversized-nfs-arguments.patch create mode 100644 kernel-std/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch create mode 100644 kernel-std/centos/meta_patches/Enable-DMA-CMA-with-swiotlb.patch create mode 100644 kernel-std/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch create mode 100644 kernel-std/centos/meta_patches/Enable-the-rebased-source-patches.patch create mode 100644 kernel-std/centos/meta_patches/Fix-compile-issue-with-transparent-hugepages.patch create mode 100644 kernel-std/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch create mode 100644 kernel-std/centos/meta_patches/Further-parallelize-kernel-build.patch create mode 100644 kernel-std/centos/meta_patches/Initial-kernel-build-for-TiS.patch create mode 100644 kernel-std/centos/meta_patches/Make-kernel-start-eth-devices-at-offset.patch create mode 100644 kernel-std/centos/meta_patches/PATCH_ORDER create mode 100644 kernel-std/centos/meta_patches/PM-introduce-per-cpu-power-management.patch create mode 100644 kernel-std/centos/meta_patches/Package-unsigned-kernel.patch create mode 100644 kernel-std/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch create mode 100644 kernel-std/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch create mode 100644 kernel-std/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch create mode 100644 kernel-std/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch create mode 100644 kernel-std/centos/meta_patches/Temporarily-neuter-off-any-TiS-specific-patches.patch create mode 100644 kernel-std/centos/meta_patches/Tweak-install-script-for-patching-add-patch-release.patch create mode 100644 kernel-std/centos/meta_patches/Update-package-versioning-for-TIS-format.patch create mode 100644 kernel-std/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch create mode 100644 kernel-std/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch create mode 100644 kernel-std/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch create mode 100644 kernel-std/centos/meta_patches/ixgbe-remove-kernel-builtin-drivers.patch create mode 100644 kernel-std/centos/meta_patches/kernel-build_requires.patch create mode 100644 kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch create mode 100644 kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch create mode 100644 kernel-std/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch create mode 100644 kernel-std/centos/meta_patches/x86_dma_alloc_coherent-fix.patch create mode 100644 kernel-std/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch create mode 100644 kernel-std/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch create mode 100644 kernel-std/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch create mode 100644 kernel-std/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch create mode 100644 kernel-std/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch create mode 100644 kernel-std/centos/patches/Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch create mode 100644 kernel-std/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch create mode 100644 kernel-std/centos/patches/Fix-compile-issue-when-transparent-hugepages-are-off.patch create mode 100644 kernel-std/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch create mode 100644 kernel-std/centos/patches/KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch create mode 100644 kernel-std/centos/patches/Make-kernel-start-eth-devices-at-offset.patch create mode 100644 kernel-std/centos/patches/Notification-of-death-of-arbitrary-processes.patch create mode 100644 kernel-std/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch create mode 100644 kernel-std/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch create mode 100644 kernel-std/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch create mode 100644 kernel-std/centos/patches/US103091-IMA-System-Configuration.patch create mode 100644 kernel-std/centos/patches/affine-compute-kernel-threads.patch create mode 100644 kernel-std/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch create mode 100644 kernel-std/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch create mode 100644 kernel-std/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch create mode 100644 kernel-std/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch create mode 100644 kernel-std/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch create mode 100644 kernel-std/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch create mode 100644 kernel-std/centos/patches/dpt_i2o-fix-build-warning.patch create mode 100644 kernel-std/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch create mode 100644 kernel-std/centos/patches/kernel-3.10.0-x86_64.config.tis_extra create mode 100644 kernel-std/centos/patches/memblock-introduce-memblock_alloc_range.patch create mode 100644 kernel-std/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch create mode 100644 kernel-std/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch create mode 100644 kernel-std/centos/patches/turn-off-write-same-in-smartqpi-driver.patch create mode 100644 kernel-std/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch create mode 100644 kernel-std/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch create mode 100644 kernel-std/centos/srpm_path create mode 100644 kernel-std/files/ima_signing_key.pub create mode 100644 mellanox/libibverbs/centos/build_srpm.data create mode 100644 mellanox/libibverbs/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 mellanox/libibverbs/centos/meta_patches/PATCH_ORDER create mode 100644 mellanox/libibverbs/centos/meta_patches/add-build-dependency.patch create mode 100644 mellanox/libibverbs/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch create mode 100644 mellanox/libibverbs/centos/srpm_path create mode 100644 mellanox/libmlx4/centos/build_srpm.data create mode 100644 mellanox/libmlx4/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 mellanox/libmlx4/centos/meta_patches/PATCH_ORDER create mode 100644 mellanox/libmlx4/centos/srpm_path create mode 100644 mellanox/libmlx5/centos/build_srpm.data create mode 100644 mellanox/libmlx5/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 mellanox/libmlx5/centos/meta_patches/PATCH_ORDER create mode 100644 mellanox/libmlx5/centos/srpm_path create mode 100644 mellanox/mlnx-ofa_kernel/centos/build_srpm.data create mode 100644 mellanox/mlnx-ofa_kernel/centos/meta_patches/0001-Support-TiS-system.patch create mode 100644 mellanox/mlnx-ofa_kernel/centos/meta_patches/PATCH_ORDER create mode 100644 mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-HAVE_IEEE_GETQCN.patch create mode 100644 mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-a-bunch-of-ks-stuff.patch create mode 100644 mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-some-stats-output.patch create mode 100644 mellanox/mlnx-ofa_kernel/centos/srpm_path create mode 100644 mellanox/mlnx-ofa_kernel/files/modules-load.conf create mode 100644 mellanox/rdma-core/centos/build_srpm.data create mode 100644 mellanox/rdma-core/centos/meta_patches/0001-Add-build-dependencies-and-package-versioning-for-Ti.patch create mode 100644 mellanox/rdma-core/centos/meta_patches/PATCH_ORDER create mode 100644 mellanox/rdma-core/centos/srpm_path create mode 100644 mwa-sparta.map create mode 100644 networking/mlx4-config/centos/build_srpm.data create mode 100644 networking/mlx4-config/centos/mlx4-config.spec create mode 100644 networking/mlx4-config/files/LICENSE create mode 100644 networking/mlx4-config/files/mlx4-config.service create mode 100644 networking/mlx4-config/files/mlx4-configure.sh create mode 100644 networking/mlx4-config/files/mlx4_core_config.sh create mode 100644 networking/mlx4-config/files/mlx4_core_goenabled.sh create mode 100644 networking/net-snmp/PKG-INFO create mode 100644 networking/net-snmp/centos/build_srpm.data create mode 100644 networking/net-snmp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 networking/net-snmp/centos/meta_patches/PATCH_ORDER create mode 100644 networking/net-snmp/centos/meta_patches/fix-snmpd-initscript.patch create mode 100644 networking/net-snmp/centos/meta_patches/fix-snmpd-service-reload.patch create mode 100644 networking/net-snmp/centos/meta_patches/fix-snmpd-service.patch create mode 100644 networking/net-snmp/centos/meta_patches/run-snmpd-as-non-root-user.patch create mode 100644 networking/net-snmp/centos/meta_patches/snmp-spec-add-init-script.patch create mode 100644 networking/net-snmp/centos/meta_patches/snmp-spec-add-snmp-config.patch create mode 100644 networking/net-snmp/centos/meta_patches/snmp-spec-config-file-permission.patch create mode 100644 networking/net-snmp/centos/meta_patches/snmpd-service-OPTIONS.patch create mode 100644 networking/net-snmp/centos/meta_patches/spec-add-rpm-headerGetEntry-fix.patch create mode 100644 networking/net-snmp/centos/meta_patches/spec-configure-without-HOST-RESOURCES-MIB.patch create mode 100644 networking/net-snmp/centos/meta_patches/spec-include-TiS-patches.patch create mode 100644 networking/net-snmp/centos/srpm_path create mode 100644 networking/net-snmp/files/snmp.conf.cgcs create mode 100644 networking/net-snmp/files/snmpd.cgcs create mode 100644 networking/net-snmp/files/snmpd.conf.cgcs create mode 100644 networking/net-snmp/patches/0001-rpm-headerGetEntry.patch create mode 100644 networking/openldap/PKG-INFO create mode 100644 networking/openldap/centos/build_srpm.data create mode 100644 networking/openldap/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 networking/openldap/centos/meta_patches/PATCH_ORDER create mode 100644 networking/openldap/centos/meta_patches/openldap-enable-password-policy.patch create mode 100644 networking/openldap/centos/meta_patches/openldap-remove-ldap-conf-cgcs-file.patch create mode 100644 networking/openldap/centos/meta_patches/openldap-service-file.patch create mode 100644 networking/openldap/centos/meta_patches/openldap-spec-file.patch create mode 100644 networking/openldap/centos/meta_patches/openldap-sysconfig-file.patch create mode 100644 networking/openldap/centos/srpm_path create mode 100644 networking/openldap/files/initial_config.ldif create mode 100755 networking/openldap/files/initscript create mode 100644 networking/openldap/files/rootdn-should-not-bypass-ppolicy.patch create mode 100644 networking/openldap/files/slapd.conf.cgcs create mode 100644 networking/openvswitch/centos/build_srpm.data create mode 100644 networking/openvswitch/centos/openvswitch.spec create mode 100644 networking/openvswitch/patches/ovs-vswitchd.system.service.patch create mode 100644 networking/scapy/centos/build_srpm.data create mode 100644 networking/scapy/centos/meta_patches/0001-spec-update-package-versioning-for-tis-format.patch create mode 100644 networking/scapy/centos/meta_patches/0002-spec-include-ipv6-fixes-from-2.4-release-candidate.patch create mode 100644 networking/scapy/centos/meta_patches/PATCH_ORDER create mode 100644 networking/scapy/centos/patches/0001-Use-socket.pton-socket.ntop-is-available.patch create mode 100644 networking/scapy/centos/srpm_path create mode 100644 python/python-3parclient/centos/build_srpm.data create mode 100644 python/python-3parclient/centos/python-3parclient.spec create mode 100644 python/python-cryptography/centos/meta_patches/0002-Turn-off-python-crypto-test-step.patch create mode 100644 python/python-eventlet/centos/build_srpm.data create mode 100644 python/python-eventlet/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 python/python-eventlet/centos/meta_patches/PATCH_ORDER create mode 100644 python/python-eventlet/centos/meta_patches/spec-include-TiS-paches.patch create mode 100644 python/python-eventlet/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch create mode 100644 python/python-eventlet/centos/srpm_path create mode 100644 python/python-lefthandclient/centos/build_srpm.data create mode 100644 python/python-lefthandclient/centos/python-lefthandclient.spec create mode 100644 python/python-requests/centos/build_srpm.data create mode 100644 python/python-requests/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 python/python-requests/centos/meta_patches/0002-include-patch-for-CGTS-2869.patch create mode 100644 python/python-requests/centos/meta_patches/PATCH_ORDER create mode 100644 python/python-requests/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch create mode 100644 python/python-requests/centos/srpm_path create mode 100644 python/python-suds/centos/meta_patches/0002-BuildRequires-pythong-coverage.patch create mode 100755 restapi-doc/centos/build_srpm create mode 100644 restapi-doc/centos/build_srpm.data create mode 100644 restapi-doc/centos/restapi-doc.spec create mode 100644 restapi-doc/restapi-doc/.gitignore create mode 100644 restapi-doc/restapi-doc/LICENSE create mode 100644 restapi-doc/restapi-doc/Makefile create mode 100644 restapi-doc/restapi-doc/Makefile.cache create mode 100644 restapi-doc/restapi-doc/README.mvn_cache create mode 100644 restapi-doc/restapi-doc/api-ref-guides/pom.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-blockstorage-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-compute-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-image-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-networking-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-nfv-vim-v1.xml create mode 100755 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-patching-v1.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-sysinv-v1.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-telemetry-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref.xml create mode 100644 restapi-doc/restapi-doc/api-ref-guides/src/preface.xml create mode 100644 restapi-doc/restapi-doc/api-ref/.htaccess create mode 100644 restapi-doc/restapi-doc/api-ref/locale/api-ref.pot create mode 100644 restapi-doc/restapi-doc/api-ref/locale/fr.po create mode 100644 restapi-doc/restapi-doc/api-ref/pom.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-blockstorage-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-compute-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-image-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-networking-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-nfv-vim-v1.xml create mode 100755 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-patching-v1.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-sysinv-v1.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-telemetry-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_blockstorage-api-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_cgcs-rest-api-intro.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_compute-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_image-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_networking-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_nfv-vim-api-v1.xml create mode 100755 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_patching-api-v1.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_sysinv-api-v1.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/ch_telemetry-v2-cgcs-ext.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/itemizedlist-service-list.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/docbkx/preface.xml create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/hypervisor-get-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-get-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-list-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-req.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-get-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-list-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/providernet-get-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-get-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-interface-attach-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-list-resp.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-scale-up-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/cgcs-ext/compute-v2-cgcs-ext.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/common.ent create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/cgcs-ext/image-v2-cgcs-ext.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/common.ent create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-delete_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list-on-providernet_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-delete_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-delete_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-type-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-delete_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-delete_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-list_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-show_admin_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/cgcs-ext/networking-v2-cgcs-ext.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/common.ent create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-request.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-request.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-patch-strategy-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-upgrade-strategy-request.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-patch-strategy-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-upgrade-strategy-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-api-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/orchestration-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-request.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-patch-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-upgrade-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-request.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/common.ent create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/nfv-vim-api-v1.wadl create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_install_async-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_list-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_apply-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_delete-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_list-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_remove-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_show-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_upload-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patching-versions-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/versionv1-get-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/common.ent create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/patching-api-v1.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_show-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-request.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_summary-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certconfig_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certificate_install-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_show-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify_multi-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request-platform.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/firewall_rules_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_show-response.json create mode 100755 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_export-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/istorconfig_summary-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_install-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_apply-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_backend_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_usage_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sysinv-versions-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health_upgrade-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_delete-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/version-get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/versionv1-get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/common.ent create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/sysinv-api-v1.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/metertype_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_show-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/cgcs-ext/telemetry-v2-cgcs-ext.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/common.ent create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-snapshot-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-volume-request.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_get-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_list-response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_list_detail_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_show_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_list_detail_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_show_response.json create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/cgcs-ext/volume-v2-cgcs-ext.wadl create mode 100644 restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/common.ent create mode 100644 restapi-doc/restapi-doc/pom.xml create mode 100644 restapi-doc/restapi-doc/rest-api-usage-example.pdf create mode 100644 restapi-doc/restapi-doc/rest-api-usage-example.pptx create mode 100644 security/audit/PKG-INFO create mode 100644 security/audit/centos/build_srpm.data create mode 100644 security/audit/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 security/audit/centos/meta_patches/PATCH_ORDER create mode 100644 security/audit/centos/meta_patches/meta-enable-audispd.patch create mode 100644 security/audit/centos/patches/0001-enable-audispd-and-auth-facility.patch create mode 100644 security/audit/centos/srpm_path create mode 100644 security/libtpms/centos/build_srpm.data create mode 100644 security/libtpms/centos/libtpms.spec create mode 100644 security/swtpm/centos/build_srpm.data create mode 100644 security/swtpm/centos/swtpm.spec create mode 100755 security/swtpm/files/qemu create mode 100755 security/swtpm/files/setup_vtpm create mode 100644 security/tpm2-openssl-engine/PKG_INFO create mode 100644 security/tpm2-openssl-engine/centos/build_srpm.data create mode 100644 security/tpm2-openssl-engine/centos/tpm2-openssl-engine.spec create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/LICENSE create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/Makefile create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/create_tpm2_key.c create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.c create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.h create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2_err.c create mode 100644 security/tpm2-openssl-engine/tpm2-openssl-engine/tpm2-asn.h create mode 100644 security/tpm2-tools/PKG-INFO create mode 100644 security/tpm2-tools/centos/build_srpm.data create mode 100644 security/tpm2-tools/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 security/tpm2-tools/centos/meta_patches/PATCH_ORDER create mode 100644 security/tpm2-tools/centos/meta_patches/disable-socket-mode-TCTI.patch create mode 100644 security/tpm2-tools/centos/srpm_path create mode 100644 security/tss2/PKG-INFO create mode 100644 security/tss2/centos/build_srpm.data create mode 100644 security/tss2/centos/tss2.spec create mode 100644 security/wrs-ssl/LICENSE create mode 100644 security/wrs-ssl/centos/build_srpm.data create mode 100644 security/wrs-ssl/centos/wrs-ssl.spec create mode 100644 security/wrs-ssl/files/tpmdevice-setup create mode 100644 security/wrs-ssl/server-csr.conf create mode 100644 storage-topology/storage-topology/LICENSE create mode 100644 storage-topology/storage-topology/setup.py create mode 100644 storage-topology/storage-topology/storage_topology/__init__.py create mode 100644 storage-topology/storage-topology/storage_topology/exec/__init__.py create mode 100644 storage-topology/storage-topology/storage_topology/exec/storage_topology.py create mode 100644 support/libevent/.gitignore create mode 100644 support/libevent/PKG-INFO create mode 100644 support/libevent/centos/build_srpm.data create mode 100644 support/libevent/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 support/libevent/centos/meta_patches/PATCH_ORDER create mode 100644 support/libevent/centos/meta_patches/spec-include-TiS-patches.patch create mode 100644 support/libevent/centos/srpm_path create mode 100644 support/libevent/files/libevent-disable-tests.patch create mode 100644 support/libevent/files/libevent-ipv6-client-socket.patch create mode 100644 support/libxslt/libxslt/CVE-2015-7995.patch create mode 100644 support/lvm2/lvm2/Fix-regression-in-for_each_sub_lv.patch create mode 100644 support/lvm2/lvm2/Sync-filesystem-for-thin-snapshots.patch create mode 100644 support/lvm2/lvm2/fix_thin_provision_device_name.patch create mode 100755 support/lvm2/lvm2/lvm2.sh create mode 100644 support/lvm2/lvm2/move-thin_check_executable-var.patch create mode 100644 support/postgresql/files/0001-pgcrypto-Detect-and-report-too-short-crypt-salts.patch create mode 100644 support/postgresql/files/0002-Prevent-stack-overflow-in-json-related-functions.patch create mode 100644 support/tgt/centos/build_srpm.data create mode 100644 support/tgt/centos/files/tgtd.init create mode 100644 support/tgt/centos/files/tgtd.service create mode 100644 support/tgt/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch create mode 100644 support/tgt/centos/meta_patches/PATCH_ORDER create mode 100644 support/tgt/centos/meta_patches/spec-to-use-custom-startup-script.patch create mode 100644 support/tgt/centos/srpm_path create mode 100644 support/tgt/files/0001-usr-Makefile-WARNING-fix.patch create mode 100644 support/tgt/files/tgtd.init create mode 100644 vm-topology/centos/build_srpm.data create mode 100644 vm-topology/centos/vm-topology.spec create mode 100644 vm-topology/vm-topology/LICENSE create mode 100644 vm-topology/vm-topology/setup.py create mode 100644 vm-topology/vm-topology/vm_topology/__init__.py create mode 100644 vm-topology/vm-topology/vm_topology/exec/__init__.py create mode 100644 vm-topology/vm-topology/vm_topology/exec/vm_topology.py diff --git a/CONTRIBUTORS.wrs b/CONTRIBUTORS.wrs new file mode 100644 index 000000000..68489a05b --- /dev/null +++ b/CONTRIBUTORS.wrs @@ -0,0 +1,7 @@ +The following contributors from Wind River have developed the seed code in this +repository. We look forward to community collaboration and contributions for +additional features, enhancements and refactoring. + +Contributors: +============= +Wind River Titanium Cloud Team diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.rst b/README.rst new file mode 100644 index 000000000..1cabcf9e0 --- /dev/null +++ b/README.rst @@ -0,0 +1,5 @@ +========= +stx-integ +========= + +StarlingX Integration diff --git a/base/base-files/base-files/issue b/base/base-files/base-files/issue new file mode 100644 index 000000000..59f55b8af --- /dev/null +++ b/base/base-files/base-files/issue @@ -0,0 +1,22 @@ + +Release xxxPLATFORM_RELEASExxx \n \l +------------------------------------------------------------------------ +W A R N I N G *** W A R N I N G *** W A R N I N G *** W A R N I N G *** +------------------------------------------------------------------------ +THIS IS A PRIVATE COMPUTER SYSTEM. +This computer system including all related equipment, network devices +(specifically including Internet access), are provided only for authorized use. +All computer systems may be monitored for all lawful purposes, including to +ensure that their use is authorized, for management of the system, to +facilitate protection against unauthorized access, and to verify security +procedures, survivability and operational security. Monitoring includes active +attacks by authorized personnel and their entities to test or verify the +security of the system. During monitoring, information may be examined, +recorded, copied and used for authorized purposes. All information including +personal information, placed on or sent over this system may be monitored. Uses +of this system, authorized or unauthorized, constitutes consent to monitoring +of this system. Unauthorized use may subject you to criminal prosecution. +Evidence of any such unauthorized use collected during monitoring may be used +for administrative, criminal or other adverse action. Use of this system +constitutes consent to monitoring for these purposes. + diff --git a/base/base-files/base-files/issue.net b/base/base-files/base-files/issue.net new file mode 100644 index 000000000..1bce12ff5 --- /dev/null +++ b/base/base-files/base-files/issue.net @@ -0,0 +1,21 @@ +Release xxxPLATFORM_RELEASExxx +------------------------------------------------------------------------ +W A R N I N G *** W A R N I N G *** W A R N I N G *** W A R N I N G *** +------------------------------------------------------------------------ +THIS IS A PRIVATE COMPUTER SYSTEM. +This computer system including all related equipment, network devices +(specifically including Internet access), are provided only for authorized use. +All computer systems may be monitored for all lawful purposes, including to +ensure that their use is authorized, for management of the system, to +facilitate protection against unauthorized access, and to verify security +procedures, survivability and operational security. Monitoring includes active +attacks by authorized personnel and their entities to test or verify the +security of the system. During monitoring, information may be examined, +recorded, copied and used for authorized purposes. All information including +personal information, placed on or sent over this system may be monitored. Uses +of this system, authorized or unauthorized, constitutes consent to monitoring +of this system. Unauthorized use may subject you to criminal prosecution. +Evidence of any such unauthorized use collected during monitoring may be used +for administrative, criminal or other adverse action. Use of this system +constitutes consent to monitoring for these purposes. + diff --git a/base/base-files/base-files/motd b/base/base-files/base-files/motd new file mode 100644 index 000000000..e2c1470e6 --- /dev/null +++ b/base/base-files/base-files/motd @@ -0,0 +1,5 @@ + +WARNING: Unauthorized access to this system is forbidden and will be +prosecuted by law. By accessing this system, you agree that your +actions may be monitored if unauthorized usage is suspected. + diff --git a/base/base-files/base-files/nsswitch.conf b/base/base-files/base-files/nsswitch.conf new file mode 100644 index 000000000..fc7cf2f97 --- /dev/null +++ b/base/base-files/base-files/nsswitch.conf @@ -0,0 +1,21 @@ +# /etc/nsswitch.conf +# +# Example configuration of GNU Name Service Switch functionality. +# If you have the `glibc-doc' and `info' packages installed, try: +# `info libc "Name Service Switch"' for information about this file. + +passwd: files ldap +group: files ldap +shadow: files ldap + +hosts: files dns +networks: files + +protocols: db files +services: db files +ethers: db files +rpc: db files + +netgroup: nis + +sudoers: files diff --git a/base/centos-release/centos/build_srpm.data b/base/centos-release/centos/build_srpm.data new file mode 100644 index 000000000..112ca54f4 --- /dev/null +++ b/base/centos-release/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=2 diff --git a/base/centos-release/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/base/centos-release/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..023e4013d --- /dev/null +++ b/base/centos-release/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From d5890a17f5b07a9d17665c2b4138bb244ab6c680 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:58:59 -0400 +Subject: [PATCH 2/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +--- + SPECS/centos-release.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/centos-release.spec b/SPECS/centos-release.spec +index be95b1b..91dad61 100644 +--- a/SPECS/centos-release.spec ++++ b/SPECS/centos-release.spec +@@ -13,7 +13,7 @@ + + Name: centos-release + Version: %{base_release_version} +-Release: %{centos_rel}%{?dist} ++Release: %{centos_rel}.el7.centos%{?_tis_dist}.%{tis_patch_ver} + Summary: %{product_family} release file + Group: System Environment/Base + License: GPLv2 +-- +1.9.1 + diff --git a/base/centos-release/centos/meta_patches/PATCH_ORDER b/base/centos-release/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..99a95f959 --- /dev/null +++ b/base/centos-release/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +centos-release-include-TiS-changes.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/base/centos-release/centos/meta_patches/centos-release-include-TiS-changes.patch b/base/centos-release/centos/meta_patches/centos-release-include-TiS-changes.patch new file mode 100644 index 000000000..6e0f39d2c --- /dev/null +++ b/base/centos-release/centos/meta_patches/centos-release-include-TiS-changes.patch @@ -0,0 +1,38 @@ +From 4905ace48eb3feae48a02d2bd61e3778f8062532 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:58:59 -0400 +Subject: [PATCH 1/2] WRS: centos-release-include-TiS-changes.patch + +--- + SPECS/centos-release.spec | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SPECS/centos-release.spec b/SPECS/centos-release.spec +index af82c8b..be95b1b 100644 +--- a/SPECS/centos-release.spec ++++ b/SPECS/centos-release.spec +@@ -25,6 +25,8 @@ Provides: system-release(releasever) = %{base_release_version} + Source0: centos-release-%{base_release_version}-%{centos_rel}.tar.gz + Source1: 85-display-manager.preset + Source2: 90-default.preset ++Source3: issue ++Source4: issue.net + + %description + %{product_family} release files +@@ -118,6 +120,12 @@ mkdir -p %{buildroot}%{_prefix}/lib/systemd/system-preset/ + install -m 0644 %{SOURCE1} %{buildroot}%{_prefix}/lib/systemd/system-preset/ + install -m 0644 %{SOURCE2} %{buildroot}%{_prefix}/lib/systemd/system-preset/ + ++# Overwrite default issue files with cgcs related files. ++install -m 0644 %{SOURCE3} %{buildroot}/etc/issue ++install -m 0644 %{SOURCE4} %{buildroot}/etc/issue.net ++sed -i -e "s/xxxPLATFORM_RELEASExxx/%{platform_release}/g" \ ++ %{buildroot}/etc/issue \ ++ %{buildroot}/etc/issue.net + + %clean + rm -rf %{buildroot} +-- +1.9.1 + diff --git a/base/centos-release/centos/srpm_path b/base/centos-release/centos/srpm_path new file mode 100644 index 000000000..7127b6ab7 --- /dev/null +++ b/base/centos-release/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/centos-release-7-4.1708.el7.centos.src.rpm diff --git a/base/centos-release/files/issue b/base/centos-release/files/issue new file mode 100644 index 000000000..59f55b8af --- /dev/null +++ b/base/centos-release/files/issue @@ -0,0 +1,22 @@ + +Release xxxPLATFORM_RELEASExxx \n \l +------------------------------------------------------------------------ +W A R N I N G *** W A R N I N G *** W A R N I N G *** W A R N I N G *** +------------------------------------------------------------------------ +THIS IS A PRIVATE COMPUTER SYSTEM. +This computer system including all related equipment, network devices +(specifically including Internet access), are provided only for authorized use. +All computer systems may be monitored for all lawful purposes, including to +ensure that their use is authorized, for management of the system, to +facilitate protection against unauthorized access, and to verify security +procedures, survivability and operational security. Monitoring includes active +attacks by authorized personnel and their entities to test or verify the +security of the system. During monitoring, information may be examined, +recorded, copied and used for authorized purposes. All information including +personal information, placed on or sent over this system may be monitored. Uses +of this system, authorized or unauthorized, constitutes consent to monitoring +of this system. Unauthorized use may subject you to criminal prosecution. +Evidence of any such unauthorized use collected during monitoring may be used +for administrative, criminal or other adverse action. Use of this system +constitutes consent to monitoring for these purposes. + diff --git a/base/centos-release/files/issue.net b/base/centos-release/files/issue.net new file mode 100644 index 000000000..1bce12ff5 --- /dev/null +++ b/base/centos-release/files/issue.net @@ -0,0 +1,21 @@ +Release xxxPLATFORM_RELEASExxx +------------------------------------------------------------------------ +W A R N I N G *** W A R N I N G *** W A R N I N G *** W A R N I N G *** +------------------------------------------------------------------------ +THIS IS A PRIVATE COMPUTER SYSTEM. +This computer system including all related equipment, network devices +(specifically including Internet access), are provided only for authorized use. +All computer systems may be monitored for all lawful purposes, including to +ensure that their use is authorized, for management of the system, to +facilitate protection against unauthorized access, and to verify security +procedures, survivability and operational security. Monitoring includes active +attacks by authorized personnel and their entities to test or verify the +security of the system. During monitoring, information may be examined, +recorded, copied and used for authorized purposes. All information including +personal information, placed on or sent over this system may be monitored. Uses +of this system, authorized or unauthorized, constitutes consent to monitoring +of this system. Unauthorized use may subject you to criminal prosecution. +Evidence of any such unauthorized use collected during monitoring may be used +for administrative, criminal or other adverse action. Use of this system +constitutes consent to monitoring for these purposes. + diff --git a/base/expect-lite/centos/build_srpm.data b/base/expect-lite/centos/build_srpm.data new file mode 100644 index 000000000..10ed8520d --- /dev/null +++ b/base/expect-lite/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$CGCS_BASE/downloads/expect-lite_4.9.0.tar.gz" +TIS_PATCH_VER=1 diff --git a/base/expect-lite/centos/expect-lite.spec b/base/expect-lite/centos/expect-lite.spec new file mode 100644 index 000000000..8f75063a5 --- /dev/null +++ b/base/expect-lite/centos/expect-lite.spec @@ -0,0 +1,28 @@ +Summary: expect-lite +Name: expect-lite +Version: 4.9.0 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +License: BSD +Group: devel +Packager: Wind River +URL: http://expect-lite.sourceforge.net/ +Requires: expect +Source0: %{name}_%{version}.tar.gz + +%description +Expect based command line automation tool + +%prep +%setup -n %{name}.proj + +%install +mkdir -p $RPM_BUILD_ROOT/usr/local/bin +echo $PWD +install -m 755 expect-lite $RPM_BUILD_ROOT/usr/local/bin/expect-lite + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +/usr/local/bin/expect-lite diff --git a/base/lshell/centos/build_srpm.data b/base/lshell/centos/build_srpm.data new file mode 100644 index 000000000..d6df555cd --- /dev/null +++ b/base/lshell/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=4 diff --git a/base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..39947ee08 --- /dev/null +++ b/base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 30a087a13a78b77537a969db2a30b531246b0bd7 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 26 Sep 2016 17:39:58 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/lshell.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/lshell.spec b/SPECS/lshell.spec +index 0fd4d17..e5f1317 100644 +--- a/SPECS/lshell.spec ++++ b/SPECS/lshell.spec +@@ -2,7 +2,7 @@ + + Name: lshell + Version: 0.9.16 +-Release: 6%{?dist} ++Release: 5.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: A Python-based limited shell + + License: GPLv3+ +-- +1.8.3.1 + diff --git a/base/lshell/centos/meta_patches/PATCH_ORDER b/base/lshell/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..dece91c62 --- /dev/null +++ b/base/lshell/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +spec-include-TiS-changes.patch +spec-update-lshell-conf-allowed-list.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/base/lshell/centos/meta_patches/spec-include-TiS-changes.patch b/base/lshell/centos/meta_patches/spec-include-TiS-changes.patch new file mode 100644 index 000000000..b7de89c61 --- /dev/null +++ b/base/lshell/centos/meta_patches/spec-include-TiS-changes.patch @@ -0,0 +1,87 @@ +lshell.spec: to include Titanium Cloud changes + +To include the Titanium Cloud specific changes from: + +wr-cgcs/layers/cgcs/recipes-base/lshell/files + +diff -u b/SPECS/lshell.spec b/SPECS/lshell.spec +--- b/SPECS/lshell.spec ++++ b/SPECS/lshell.spec +@@ -1,3 +1,5 @@ ++%define WRSROOT_P cBglipPpsKwBQ ++ + Name: lshell + Version: 0.9.16 + Release: 5%{?dist} +@@ -6,6 +8,15 @@ + License: GPLv3+ + URL: https://github.com/ghantoos/lshell + Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz ++Source1: cgcs_cli ++Source2: lshell.conf ++Source3: wrs.sudo ++Source4: lshell_env_setup ++Patch1: lshell_cgcs.patch ++Patch2: lshell-source-support.patch ++Patch3: lshell-prompt-change-support.patch ++Patch4: lshell-newline-escape-character-support.patch ++Patch5: lshell-shell-escape-check.patch + BuildArch: noarch + + BuildRequires: python2-devel +@@ -20,6 +31,11 @@ + %setup -q + #Fix permission + chmod -x CHANGES ++%patch1 -p1 ++%patch2 -p1 ++%patch3 -p1 ++%patch4 -p1 ++%patch5 -p1 + + %build + %{__python2} setup.py build +@@ -27,10 +43,25 @@ + %install + %{__python2} setup.py install -O1 --skip-build --root=%{buildroot} + # Doc files at the wrong place +-rm %{buildroot}%{_defaultdocdir}/lshell/{CHANGES,COPYING,README} ++rm -f %{buildroot}%{_defaultdocdir}/lshell/{CHANGES,COPYING,README} ++mkdir -p ${RPM_BUILD_ROOT}/usr/local/bin ++install -m 755 ${RPM_SOURCE_DIR}/cgcs_cli ${RPM_BUILD_ROOT}/usr/local/bin/cgcs_cli ++install -m 755 ${RPM_SOURCE_DIR}/lshell_env_setup ${RPM_BUILD_ROOT}/usr/local/bin/lshell_env_setup ++install -d ${RPM_BUILD_ROOT}/etc ++install -m 644 ${RPM_SOURCE_DIR}/lshell.conf ${RPM_BUILD_ROOT}/etc/lshell.conf ++install -d ${RPM_BUILD_ROOT}/etc/sudoers.d ++cp ${RPM_SOURCE_DIR}/wrs.sudo wrs.sudo ++echo 'Defaults passprompt="Password: "' >> wrs.sudo ++install -m 440 wrs.sudo ${RPM_BUILD_ROOT}/etc/sudoers.d/wrs + + %pre + getent group lshell >/dev/null || groupadd -r lshell ++getent group wrs >/dev/null || groupadd -r wrs ++getent group wrs_protected >/dev/null || groupadd -f -g 345 wrs_protected ++getent passwd wrsroot > /dev/null || \ ++useradd -m -g wrs -G root,wrs_protected \ ++ -d /home/wrsroot -p %{WRSROOT_P} \ ++ -s /bin/sh wrsroot 2> /dev/null || : + + %post + grep -q '^%{_bindir}/%{name}$' %{_sysconfdir}/shells || \ +@@ -42,13 +73,13 @@ + fi + + %files +-%doc CHANGES COPYING README +-%{_mandir}/man*/*.* + %{_bindir}/%{name} + %config(noreplace) %{_sysconfdir}/%{name}.conf +-%config(noreplace) %{_sysconfdir}/logrotate.d/%{name} ++%config(noreplace) %{_sysconfdir}/sudoers.d/wrs + %{python_sitelib}/lshell/ + %{python_sitelib}/%{name}*.egg-info ++/usr/local/bin/cgcs_cli ++/usr/local/bin/lshell_env_setup + + %changelog + * Wed Jun 17 2015 Fedora Release Engineering - 0.9.16-5 diff --git a/base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch b/base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch new file mode 100644 index 000000000..0e601f9dc --- /dev/null +++ b/base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch @@ -0,0 +1,15 @@ +--- + lshell.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/SPECS/lshell.spec ++++ b/SPECS/lshell.spec +@@ -2,7 +2,7 @@ + + Name: lshell + Version: 0.9.16 +-Release: 5%{?dist} ++Release: 6%{?dist} + Summary: A Python-based limited shell + + License: GPLv3+ diff --git a/base/lshell/centos/srpm_path b/base/lshell/centos/srpm_path new file mode 100644 index 000000000..8e04439b3 --- /dev/null +++ b/base/lshell/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/lshell-0.9.16-5.el7.src.rpm diff --git a/base/lshell/files/cgcs_cli b/base/lshell/files/cgcs_cli new file mode 100755 index 000000000..98f6e6631 --- /dev/null +++ b/base/lshell/files/cgcs_cli @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/bin/lshell diff --git a/base/lshell/files/lshell-newline-escape-character-support.patch b/base/lshell/files/lshell-newline-escape-character-support.patch new file mode 100644 index 000000000..6e1b00b3a --- /dev/null +++ b/base/lshell/files/lshell-newline-escape-character-support.patch @@ -0,0 +1,53 @@ +--- + lshell/shellcmd.py | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +--- a/lshell/shellcmd.py ++++ b/lshell/shellcmd.py +@@ -74,6 +74,7 @@ class ShellCmd(cmd.Cmd, object): + self.promptbase = getuser() + + self.prompt = '%s:~$ ' % self.promptbase ++ self.prompt2 = '> ' # PS2 prompt + + self.intro = self.conf['intro'] + +@@ -670,6 +671,12 @@ class ShellCmd(cmd.Cmd, object): + self.stdout.write("%s\n" % self.intro) + if self.conf['login_script']: + self.loginCmdParse(self.conf['login_script']) ++ ++ # for long commands, a user may escape the new line ++ # by giving a bash like '\' character at the end of ++ # the line. cmdloop() needs to recognize that and ++ # create an appended line before sending it to onecmd() ++ partial_line = "" + stop = None + while not stop: + if self.cmdqueue: +@@ -691,7 +698,24 @@ class ShellCmd(cmd.Cmd, object): + line = 'EOF' + else: + line = line[:-1] # chop \n +- line = self.precmd(line) ++ ++ if len(line) > 1 and line.startswith('\\'): ++ # implying previous partial line ++ line = line[:1].replace('\\', '', 1) ++ if partial_line: ++ line = partial_line + line ++ if line.endswith('\\'): ++ # continuation character. First partial line. ++ # We shall expect the command to continue in ++ # a new line. Change to bash like PS2 prompt to ++ # indicate this continuation to the user ++ partial_line = line.strip('\\') ++ self.prompt = self.prompt2 # switching to PS2 ++ continue ++ partial_line = "" ++ ++ self.updateprompt(os.getcwd()) ++ line = self.precmd(line) + stop = self.onecmd(line) + stop = self.postcmd(stop, line) + self.postloop() diff --git a/base/lshell/files/lshell-prompt-change-support.patch b/base/lshell/files/lshell-prompt-change-support.patch new file mode 100644 index 000000000..5613a0739 --- /dev/null +++ b/base/lshell/files/lshell-prompt-change-support.patch @@ -0,0 +1,139 @@ +--- + lshell/shellcmd.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 71 insertions(+), 6 deletions(-) + +--- a/lshell/shellcmd.py ++++ b/lshell/shellcmd.py +@@ -28,6 +28,7 @@ import readline + import glob + import subprocess + ++from time import gmtime, strftime + from utils import get_aliases + + +@@ -50,6 +51,9 @@ class ShellCmd(cmd.Cmd, object): + else: + self.stderr = stderr + ++ # create a devnull device ++ self.devnull = open(os.devnull, 'w') ++ + self.args = args + self.conf = userconf + self.log = self.conf['logpath'] +@@ -145,13 +149,63 @@ class ShellCmd(cmd.Cmd, object): + self.g_cmd, self.g_arg, self.g_line = ['', '', ''] + return object.__getattribute__(self, attr) + ++ def check_prompt(self, var, value): ++ """ check if user is attempting to ++ modify shell prompt and if so then ++ update the prompt ++ """ ++ if 'PS' in var: ++ if 'PS1' in var: ++ # update prompt ++ self.promptbase = self.setprompt( ++ {'prompt' : value.strip('\n').strip('\r')}) ++ self.updateprompt(os.getcwd()) ++ else: ++ self.log.critical("*** forbidden %s prompt change requested. " ++ "Only PS1 changes permissible" % var) ++ ++ + def setprompt(self, conf): + """ set prompt used by the shell + """ + if conf.has_key('prompt'): + promptbase = conf['prompt'] +- promptbase = promptbase.replace('%u', getuser()) +- promptbase = promptbase.replace('%h', os.uname()[1].split('.')[0]) ++ # Recognize shell name control command ++ promptbase = re.sub(r'\\s', 'lshell', ++ promptbase) ++ # Recognize username control command ++ promptbase = re.sub(r'\\u|%u', getuser(), ++ promptbase) ++ # Recognize hostname control command ++ promptbase = re.sub(r'\\h|%h', os.uname()[1].split('.')[0], ++ promptbase) ++ # Recognize full hostname control command ++ promptbase = re.sub(r'\\H', os.uname()[1], ++ promptbase) ++ # Recognize time control commands ++ promptbase = re.sub(r'\\t', strftime("%H:%M:%S", gmtime()), ++ promptbase) ++ promptbase = re.sub(r'\\T', strftime("%I:%M:%S", gmtime()), ++ promptbase) ++ promptbase = re.sub(r'\\A', strftime("%H:%M", gmtime()), ++ promptbase) ++ promptbase = re.sub(r'\\@', strftime("%I:%M:%S%p", gmtime()), ++ promptbase) ++ promptbase = re.sub(r'\\d', strftime("%a %b %d", gmtime()), ++ promptbase) ++ ######################################################## ++ # The following control commands are not supported: # ++ # v - the shell version # ++ # V - the shell release version # ++ # w - Complete path of current working directory # ++ # W - the basename of the current working directory # ++ # ! - the history number of this command # ++ # # - the command number of this command # ++ # $? - status of the last command # ++ # $() - any command executions # ++ ######################################################## ++ promptbase = re.sub(r'\\v|\\V|\\w|\\W|\\!|\\#|\\\$\?|\\\$\(.*\)|\\\$', '', ++ promptbase) + else: + promptbase = getuser() + +@@ -199,7 +253,7 @@ class ShellCmd(cmd.Cmd, object): + def export(self): + """ export environment variables """ + # if command contains at least 1 space +- if self.g_line.count(' '): ++ if self.g_line.count(' '): + env = self.g_line.split(" ", 1)[1] + # if it conatins the equal sign, consider only the first one + if env.count('='): +@@ -216,6 +270,10 @@ class ShellCmd(cmd.Cmd, object): + cin, cout = os.popen2('`which echo` %s' % value) + value = cout.readlines()[0] + ++ # check if new exported environment ++ # is a prompt change command ++ self.check_prompt(var, value) ++ + os.environ.update({var: value.rstrip()}) + + def source(self): +@@ -485,11 +543,14 @@ class ShellCmd(cmd.Cmd, object): + p = subprocess.Popen( "`which echo` %s" % item, + shell=True, + stdin=subprocess.PIPE, +- stdout=subprocess.PIPE ) ++ stdout=subprocess.PIPE, ++ stderr = self.devnull ) + (cin, cout) = (p.stdin, p.stdout) + except ImportError: +- cin, cout = os.popen2('`which echo` %s' % item) +- item = cout.readlines()[0].split(' ')[0].strip() ++ cin, cout = os.popen2('`which echo` %s 2>/dev/null' % item) ++ shellresponse = cout.readlines() ++ if shellresponse: ++ item = shellresponse[0].split(' ')[0].strip() + item = os.path.expandvars(item) + tomatch = os.path.realpath(item) + if os.path.isdir(tomatch) and tomatch[-1] != '/': tomatch += '/' +@@ -559,6 +620,10 @@ class ShellCmd(cmd.Cmd, object): + if len(env) is not 2: + continue + newenv.update(dict([env])) ++ # check if the new environment includes ++ # any Shell prompt change commands ++ self.check_prompt(env[0], env[1]) ++ + os.environ.update(newenv) + + def loginCmdParse(self, script): diff --git a/base/lshell/files/lshell-shell-escape-check.patch b/base/lshell/files/lshell-shell-escape-check.patch new file mode 100644 index 000000000..d1749f7db --- /dev/null +++ b/base/lshell/files/lshell-shell-escape-check.patch @@ -0,0 +1,121 @@ +--- + lshell/shellcmd.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 77 insertions(+), 3 deletions(-) + +--- a/lshell/shellcmd.py ++++ b/lshell/shellcmd.py +@@ -30,7 +30,7 @@ import subprocess + + from time import gmtime, strftime + from utils import get_aliases +- ++from distutils.spawn import find_executable + + class ShellCmd(cmd.Cmd, object): + """ Main lshell CLI class +@@ -337,6 +337,44 @@ class ShellCmd(cmd.Cmd, object): + # strip all spaces/tabs + line = " ".join(line.split()) + ++ # Expand all variables ++ line = os.path.expandvars(line) ++ ++ # *** AWK HOOK *** # ++ # Before we begin, check if user is trying ++ # to pass an awk script to the awk interpreter ++ # and disallow that option. ++ # ++ # Also disallow inline vars in awk since an attacker ++ # may use that to scramble a forbidden cmd ++ # such as the following shell escape: ++ # (awk -v X=ba -v Y=ash 'BEGIN { system("/bin/"X Y) }' ++ # ++ # In an ideal world we should parse the awk script ++ # and inline vars for forbidden paths and commands ++ # but that will require some gnarly regexes (esp for ++ # the inline vars). Deferring this as TODO ++ if re.match(r'\s*awk.*-f\s*[\w/~]+', line): ++ return self.warn_count('awk script option', oline, strict, ssh) ++ if re.match(r'\s*awk.*-v\s*\w+=', line): ++ return self.warn_count('awk inline variable option', oline, strict, ssh) ++ ++ ++ # process all quoted text seperately ++ # This logic is kept crudely simple on purpose. ++ # At most we might match the same stanza twice ++ # (for e.g. "'a'", 'a') but the converse would ++ # require detecting single quotation stanzas ++ # nested within double quotes and vice versa ++ relist = re.findall(r'[^=]\"(.+)\"',line) ++ relist2 = re.findall(r'[^=]\'(.+)\'',line) ++ relist = relist + relist2 ++ for item in relist: ++ if self.check_secure(item, strict = strict): ++ return 1 ++ if self.check_path(item, strict = strict): ++ return 1 ++ + # ignore quoted text + line = re.sub(r'\"(.+?)\"', '', line) + line = re.sub(r'\'(.+?)\'', '', line) +@@ -438,7 +476,8 @@ class ShellCmd(cmd.Cmd, object): + new_cmd_line = 'export ' + oline + self.g_line = new_cmd_line + self.check_secure(new_cmd_line, strict = strict) +- else: ++ # filter out macros, text or constructs that got picked up as commands ++ elif command.islower() and find_executable(command): + return self.warn_count('command', oline, strict, ssh, command) + return 0 + +@@ -499,6 +538,7 @@ class ShellCmd(cmd.Cmd, object): + %(self.conf['warning_counter'])) + self.stderr.write('This incident has been reported.\n') + ++ + def check_path(self, line, completion=None, ssh=None, strict=None): + """ Check if a path is entered in the line. If so, it checks if user \ + are allowed to see this path. If user is not allowed, it calls \ +@@ -594,7 +634,41 @@ class ShellCmd(cmd.Cmd, object): + detect the new environment and then use that to update the \ + environ of the lshell process. + """ +- pipe = subprocess.Popen("%s; env -0" % script, ++ try: ++ script_path = os.path.expanduser(script.\ ++ strip("source").split()[0]) ++ script_path = os.path.expandvars(script_path) ++ with open (script_path) as fd: ++ content = fd.readlines() ++ content = [line.strip('\n') for line in content] ++ ++ # Although rare in a normal cases, an attacker ++ # may attempt to bypass line validation by ++ # scrambling commands via line continuations ++ partial_line = "" ++ for i,line in enumerate(content): ++ if line.startswith('#'): ++ continue ++ if len(line) > 1 and line.startswith('\\'): ++ # implying previous partial line ++ content[i] = line[:1].replace('\\', '', 1) ++ if partial_line: ++ content[i] = partial_line + line ++ if line.endswith('\\'): ++ # continuation character. First partial line. ++ # We shall expect the command to continue in ++ # a new line. ++ partial_line = content[i].strip('\\') ++ continue ++ partial_line = "" ++ if self.check_secure(content[i]): ++ return ++ if self.check_path(content[i]): ++ return ++ except: ++ pass ++ ++ pipe = subprocess.Popen("%s; env -0" % script, + bufsize=1, + stdout=subprocess.PIPE, + shell=True) diff --git a/base/lshell/files/lshell-source-support.patch b/base/lshell/files/lshell-source-support.patch new file mode 100644 index 000000000..050f62d4d --- /dev/null +++ b/base/lshell/files/lshell-source-support.patch @@ -0,0 +1,106 @@ +--- + lshell/shellcmd.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 64 insertions(+), 1 deletion(-) + +--- a/lshell/shellcmd.py ++++ b/lshell/shellcmd.py +@@ -26,6 +26,7 @@ import re + import signal + import readline + import glob ++import subprocess + + from utils import get_aliases + +@@ -128,6 +129,9 @@ class ShellCmd(cmd.Cmd, object): + # builtin export function + elif self.g_cmd == 'export': + self.export() ++ # builtin source function ++ elif self.g_cmd == 'source': ++ self.source() + # case 'cd' is in an alias e.g. {'toto':'cd /var/tmp'} + elif self.g_line[0:2] == 'cd': + self.g_cmd = self.g_line.split()[0] +@@ -214,6 +218,14 @@ class ShellCmd(cmd.Cmd, object): + + os.environ.update({var: value.rstrip()}) + ++ def source(self): ++ """ implementation of the "source" command ++ """ ++ # ensure if command contains at least 1 space ++ if self.g_line.count(' '): ++ source_script = self.g_line ++ self.sourceShell(source_script) ++ + def cd(self): + """ implementation of the "cd" command + """ +@@ -515,6 +527,57 @@ class ShellCmd(cmd.Cmd, object): + else: + self.prompt = '%s:%s$ ' % (self.promptbase, path) + ++ def sourceShell(self, script): ++ """Source the shell script and call env when done in order to \ ++ detect the new environment and then use that to update the \ ++ environ of the lshell process. ++ """ ++ pipe = subprocess.Popen("%s; env -0" % script, ++ bufsize=1, ++ stdout=subprocess.PIPE, ++ shell=True) ++ ++ iterator = iter(pipe.stdout.readline, b'') ++ outputlist = list(iterator) ++ output = '' ++ for i, line in enumerate(outputlist): ++ if i == (len(outputlist) -1): ++ output = line ++ else: ++ sys.stdout.write(line) ++ ++ # output may pick up some echos at the end of script and merge ++ # with the first line in env. Test for this and echo those to stdout ++ envList = output.split('\0') ++ firstenv = re.findall('^\S+=\S+$', envList[0], re.MULTILINE) ++ if firstenv: ++ print envList[0].strip(firstenv[0]) ++ envList[0] = firstenv[0] ++ newenv = {} ++ for line in envList: ++ env = line.split("=", 1) ++ if len(env) is not 2: ++ continue ++ newenv.update(dict([env])) ++ os.environ.update(newenv) ++ ++ def loginCmdParse(self, script): ++ """Parse the login command specified in login_script. \ ++ If login_script or a sub script sources a bash config \ ++ then call shell_source() ++ """ ++ # if multiple commands are chained together, execute ++ # them individually. We will not support conditional ++ # chaining (&& or ||) since that would required the ++ # additional complexity of checking the retcode of ++ # the previous command ++ cmds = script.split(";") ++ for cmd in cmds: ++ if "source" in cmd: ++ self.sourceShell(cmd) ++ else: ++ os.system(cmd) ++ + def cmdloop(self, intro=None): + """Repeatedly issue a prompt, accept input, parse an initial prefix \ + off the received input, and dispatch to action methods, passing them \ +@@ -541,7 +604,7 @@ class ShellCmd(cmd.Cmd, object): + if self.intro and isinstance(self.intro, str): + self.stdout.write("%s\n" % self.intro) + if self.conf['login_script']: +- os.system(self.conf['login_script']) ++ self.loginCmdParse(self.conf['login_script']) + stop = None + while not stop: + if self.cmdqueue: diff --git a/base/lshell/files/lshell.conf b/base/lshell/files/lshell.conf new file mode 100644 index 000000000..e3e1da037 --- /dev/null +++ b/base/lshell/files/lshell.conf @@ -0,0 +1,94 @@ +# lshell.py configuration file +# +# $Id: lshell.conf,v 1.27 2010-10-18 19:05:17 ghantoos Exp $ + +[global] +## log directory (default /var/log/lshell/ ) +logpath : /var/log/lshell/ +## set log level to 0, 1, 2, 3 or 4 (0: no logs, 1: least verbose, +## 4: log all commands) +loglevel : 2 +## configure log file name (default is %u i.e. username.log) +#logfilename : %y%m%d-%u +#logfilename : syslog + +## in case you are using syslog, you can choose your logname +#syslogname : myapp + +[default] +## a list of the allowed commands or 'all' to allow all commands in user's PATH +allowed : ['source','vim','awk','cut','grep','cat','env','export', 'read', 'pwd','ls','echo','cd','ll','less','cp','scp','sftp','mv','rm','nova','system','neutron','cinder','glance','ceilometer','heat','keystone','passwd','openstack'] + +## a list of forbidden character or commands -- deny vim, as it allows to escape lshell +#forbidden : [';', '&', '|','`','>','<', '$(', '${'] +forbidden : [';', '&', '>','<', '$('] + +## a list of allowed command to use with sudo(8) +#sudo_commands : ['ls', 'more'] + +## number of warnings when user enters a forbidden value before getting +## exited from lshell, set to -1 to disable. +warning_counter : 2 + +## command aliases list (similar to bash’s alias directive) +aliases : {'ll':'ls -l', 'vim':'rvim'} + +## introduction text to print (when entering lshell) +#intro : "== My personal intro ==\nWelcome to lshell\nType '?' or 'help' to get the list of allowed commands" + +## configure your promt using %u or %h (default: username) +prompt : "%u@%h" + +## set sort prompt current directory update (default: 0) +#prompt_short : 0 + +## a value in seconds for the session timer +timer : 900 + +## list of path to restrict the user "geographicaly" +#path : ['/home/bla/','/etc'] + +## set the home folder of your user. If not specified the home_path is set to +## the $HOME environment variable +#home_path : '/home/bla/' + +## update the environment variable $PATH of the user +#env_path : ':/usr/local/bin:/usr/sbin' + +## a list of path; all executable files inside these path will be allowed +#allowed_cmd_path: ['/home/bla/bin','/home/bla/stuff/libexec'] + +## add environment variables +#env_vars : {'foo':1, 'bar':'helloworld'} +env_vars : {'OPENRC_TEMPLATE':'/etc/nova/ldap_openrc_template'} +## allow or forbid the use of scp (set to 1 or 0) +#scp : 1 + +## forbid scp upload +#scp_upload : 0 + +## forbid scp download +#scp_download : 0 + +## allow of forbid the use of sftp (set to 1 or 0) +#sftp : 1 + +## list of command allowed to execute over ssh (e.g. rsync, rdiff-backup, etc.) +#overssh : ['ls', 'rsync'] + +## logging strictness. If set to 1, any unknown command is considered as +## forbidden, and user's warning counter is decreased. If set to 0, command is +## considered as unknown, and user is only warned (i.e. *** unknown synthax) +strict : 0 + +## force files sent through scp to a specific directory +#scpforce : '/home/bla/uploads/' + +## history file maximum size +history_size : 100 + +## set history file name (default is /home/%u/.lhistory) +#history_file : "/home/%u/.lshell_history" + +## define the script to run at user login +login_script : "source /usr/local/bin/lshell_env_setup --mute; install -m 0500 /usr/local/bin/lshell_env_setup ~/" diff --git a/base/lshell/files/lshell_cgcs.patch b/base/lshell/files/lshell_cgcs.patch new file mode 100644 index 000000000..80d35267f --- /dev/null +++ b/base/lshell/files/lshell_cgcs.patch @@ -0,0 +1,54 @@ +Index: lshell-0.9.16/setup.py +=================================================================== +--- lshell-0.9.16.orig/setup.py ++++ lshell-0.9.16/setup.py +@@ -40,10 +40,7 @@ choose a list of allowed commands for ev + scripts = ['bin/lshell'], + package_dir = {'lshell':'lshell'}, + packages = ['lshell'], +- data_files = [('/etc', ['etc/lshell.conf']), +- ('/etc/logrotate.d', ['etc/logrotate.d/lshell']), +- ('share/doc/lshell',['README', 'COPYING', 'CHANGES']), +- ('share/man/man1/', ['man/lshell.1']) ], ++ data_files = [], + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console' +Index: lshell-0.9.16/lshell/shellcmd.py +=================================================================== +--- lshell-0.9.16.orig/lshell/shellcmd.py ++++ lshell-0.9.16/lshell/shellcmd.py +@@ -199,7 +199,7 @@ class ShellCmd(cmd.Cmd, object): + env = self.g_line.split(" ", 1)[1] + # if it conatins the equal sign, consider only the first one + if env.count('='): +- var, value = env.split(' ')[0].split('=')[0:2] ++ var, value = env.split('=', 1) + # expand values, if variable is surcharged by other variables + try: + import subprocess +@@ -212,7 +212,7 @@ class ShellCmd(cmd.Cmd, object): + cin, cout = os.popen2('`which echo` %s' % value) + value = cout.readlines()[0] + +- os.environ.update({var: value}) ++ os.environ.update({var: value.rstrip()}) + + def cd(self): + """ implementation of the "cd" command +@@ -361,7 +361,14 @@ class ShellCmd(cmd.Cmd, object): + + # for all other commands check in allowed list + if command not in self.conf['allowed'] and command: +- return self.warn_count('command', oline, strict, ssh, command) ++ export_pattern = re.compile('^[a-zA-Z0-9\-\_]*=') ++ if export_pattern.match(oline): ++ self.g_cmd = 'export' ++ new_cmd_line = 'export ' + oline ++ self.g_line = new_cmd_line ++ self.check_secure(new_cmd_line, strict = strict) ++ else: ++ return self.warn_count('command', oline, strict, ssh, command) + return 0 + + def warn_count(self, messagetype, line=None, strict=None, ssh=None, command=None): diff --git a/base/lshell/files/lshell_env_setup b/base/lshell/files/lshell_env_setup new file mode 100755 index 000000000..ce0687db8 --- /dev/null +++ b/base/lshell/files/lshell_env_setup @@ -0,0 +1,100 @@ +#!/bin/bash +MAX_OPENRC_LEN=100 +read -p "Pre-store Keystone user credentials for this session? (y/N): " confirm +confirm=${confirm,,} + +if [ "$confirm" == "y" ] || [ "$confirm" = "yes" ]; then + if [ -z "$OPENRC_TEMPLATE" ] || [ ! -f `echo $OPENRC_TEMPLATE` ]; then + read -p "env[OPENRC_TEMPLATE] not set. +Hints will not be available for certain options. Continue anyways? (Y/n): " confirm + confirm=${confirm,,} + ([ "$confirm" == "n" ] || [ "$confirm" == "no" ]) && exit 0 + else + # Check if we are to run Muted + [ "$1" = "--mute" ] && MUTE=1 + + # Load default values for System URL, Region and Keystone URL + defEnv=( $(cat $OPENRC_TEMPLATE) ) + defEnvLen=${#defEnv[@]} + [ "$defEnvLen" -gt "$MAX_OPENRC_LEN" ] && \ + defEnvLen="$MAX_OPENRC_LEN" + for (( i=0; i<$defEnvLen; i++)); + do + if [[ ${defEnv[$i]} =~ OS_AUTH_URL=(.*)$ ]]; then + def_os_auth_url=${BASH_REMATCH[1]} + elif [[ ${defEnv[$i]} =~ OS_REGION_NAME=(.*)$ ]]; then + def_os_region_name=${BASH_REMATCH[1]} + elif [[ ${defEnv[$i]} =~ OS_PROJECT_NAME=(.*)$ ]]; then + def_os_project_name=${BASH_REMATCH[1]} + elif [[ ${defEnv[$i]} =~ OS_USER_DOMAIN_NAME=(.*)$ ]]; then + def_os_user_domain_name=${BASH_REMATCH[1]} + elif [[ ${defEnv[$i]} =~ OS_PROJECT_DOMAIN_NAME=(.*)$ ]]; then + def_os_project_domain_name=${BASH_REMATCH[1]} + fi + done + fi + + read -p "Enter Keystone username [$USER]: " os_user + [ -z "$os_user" ] && os_user="$USER" + + read -p "Enter Keystone user domain name: " os_user_domain_name + [ -z "$os_user_domain_name" ] && os_user_domain_name="$def_os_user_domain_name" + + read -p "Enter Project name: " os_project_name + [ -z "$os_project_name" ] && os_project_name="$def_os_project_name" + + read -p "Enter Project domain name: " os_project_domain_name + [ -z "$os_project_domain_name" ] && os_project_domain_name="$def_os_project_domain_name" + + read -s -p "Enter Keystone password: " os_pass + [ -z "$os_pass" ] && \ + echo -n "Invalid password entry. Aborting!" && exit 1 + + # if we are not in mute mode then ask for these + # from user as input + if [ -z "$MUTE" ]; then + if [ -z "$def_os_region_name" ]; then + read -p "\n\nEnter Keystone Region Name: " os_region + else + read -p "Enter Keystone Region Name [$def_os_region_name]: " os_region + [ -z "$os_region" ] && os_region="$def_os_region_name" + fi + + if [ -z "$def_os_auth_url" ]; then + read -p "Enter Keystone Authentication URL: " os_auth_url + else + read -p "Enter Keystone Authentication URL [$def_os_auth_url]: " os_auth_url + [ -z "$os_auth_url" ] && os_auth_url="$def_os_auth_url" + fi + else + # In MUTE mode + os_region="$def_os_region_name" + echo ""; echo "" + echo "Using default Openstack Region Name: $os_region" + os_auth_url="$def_os_auth_url" + echo "Using default Openstack Authentication URL: $os_auth_url" + echo "To set these to non-default, run \"source ~/$(basename $BASH_SOURCE)\" in your shell" + fi + + + # set user environment which will be valid for + # the duration of this session + # Since lshell is running for internal clients + # move OS ENDPOINT TYPE to internalURL + export OS_ENDPOINT_TYPE="internalURL" + export CINDER_ENDPOINT_TYPE="internalURL" + export OS_INTERFACE="internal" + export OS_USERNAME="$os_user" + export OS_PASSWORD="$os_pass" + export OS_PROJECT_NAME="$os_project_name" + export OS_USER_DOMAIN_NAME="$os_user_domain_name" + export OS_PROJECT_DOMAIN_NAME="$os_project_domain_name" + export OS_AUTH_URL="$os_auth_url" + export OS_IDENTITY_API_VERSION=3 + export OS_REGION_NAME="$os_region" + # modify PS1 prompt + newprompt="[\u@\h \W($os_user)]\$ " + export PS1="$newprompt" + echo "" + echo "Keystone credentials preloaded!" +fi diff --git a/base/lshell/files/wrs.sudo b/base/lshell/files/wrs.sudo new file mode 100644 index 000000000..2924050ef --- /dev/null +++ b/base/lshell/files/wrs.sudo @@ -0,0 +1,11 @@ +## +## User privilege specification +## +wrsroot ALL=(ALL) ALL +wrsroot ALL=(root) NOPASSWD: /usr/bin/config_controller +wrsroot ALL=(root) NOPASSWD: /usr/bin/config_region +wrsroot ALL=(root) NOPASSWD: /usr/bin/config_subcloud +wrsroot ALL=(root) NOPASSWD: /usr/bin/config_management +wrsroot ALL=(root) NOPASSWD: /usr/local/sbin/collect + +Defaults lecture=never, secure_path=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin diff --git a/base/namespace-utils/LICENSE b/base/namespace-utils/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/base/namespace-utils/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/base/namespace-utils/centos/build_srpm.data b/base/namespace-utils/centos/build_srpm.data new file mode 100644 index 000000000..e981e8b5d --- /dev/null +++ b/base/namespace-utils/centos/build_srpm.data @@ -0,0 +1,2 @@ +SRC_DIR="namespace-utils" +TIS_PATCH_VER=0 diff --git a/base/namespace-utils/centos/namespace-utils.spec b/base/namespace-utils/centos/namespace-utils.spec new file mode 100644 index 000000000..601b11ec0 --- /dev/null +++ b/base/namespace-utils/centos/namespace-utils.spec @@ -0,0 +1,35 @@ +%define _CC gcc + +Summary: namespace utils +Name: namespace-utils +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: Wind River +URL: unknown +Source0: %{name}-%{version}.tar.gz + +%description +Titanium Cloud namespace utilities + +%prep +%setup -q + +%build +%{_CC} -o bashns bashns.c + +%install +rm -rf ${RPM_BUILD_ROOT} +install -d -m 755 ${RPM_BUILD_ROOT}%{_sbindir} +install -m 500 bashns ${RPM_BUILD_ROOT}%{_sbindir} +install -m 500 umount-in-namespace ${RPM_BUILD_ROOT}%{_sbindir} + +%clean +rm -rf ${RPM_BUILD_ROOT} + +%files +%license LICENSE +%defattr(-,root,root,-) +%{_sbindir}/umount-in-namespace +%{_sbindir}/bashns diff --git a/base/namespace-utils/namespace-utils/LICENSE b/base/namespace-utils/namespace-utils/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/base/namespace-utils/namespace-utils/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/base/namespace-utils/namespace-utils/bashns.c b/base/namespace-utils/namespace-utils/bashns.c new file mode 100644 index 000000000..2a9c15e5f --- /dev/null +++ b/base/namespace-utils/namespace-utils/bashns.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ + +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include + +void usage(char *name) +{ + printf("usage: %s \n", name); + +} + +int main(int argc, char **argv) { + if (argc < 2) { + printf("usage: %s \n", argv[0]); + return -1; + } + + int pid = atoi(argv[1]); + printf("trying to open filesystem namespace of pid %d\n", pid); + + char buf[100]; + sprintf(buf, "/proc/%d/ns/mnt", pid); + + printf("trying to open %s\n", buf); + + int fd = open(buf, O_RDWR); + if (fd < 1) { + perror("unable to open file"); + return -1; + } + + printf("got fd, trying to set namespace\n"); + + int rc = setns(fd, 0); + if (rc < 0) { + perror("unable to set namespace"); + return -1; + } + + printf("entered namespace successfully, trying to exec bash\n"); + + rc = execvp("bash", 0); + if (rc < 0) { + perror("unable to exec bash"); + return -1; + } +} + diff --git a/base/namespace-utils/namespace-utils/umount-in-namespace b/base/namespace-utils/namespace-utils/umount-in-namespace new file mode 100644 index 000000000..934daeae2 --- /dev/null +++ b/base/namespace-utils/namespace-utils/umount-in-namespace @@ -0,0 +1,25 @@ +#!/bin/bash + +# +# Copyright (c) 2015 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +MNT=$1 + +SELF_NS=$(ls -l /proc/self/ns/mnt 2>/dev/null| sed -r 's/.*\[(.*)\]/\1/') + +ls -l /proc/*/ns/mnt 2>/dev/null| sed -r 's/.*\[(.*)\]/\1/' | sort -u | while read ns +do + if [ "$ns" = "$SELF_NS" ] + then + continue + fi + + ls -l /proc/*/ns/mnt 2>/dev/null | grep $ns |grep '/proc/[0-9]*/' | sed -r 's#.*/proc/([0-9]*)/ns.*#\1#' | while read pid + do + echo "umount -n -l $MNT" | /usr/sbin/bashns $pid + done +done + diff --git a/base/nss-pam-ldapd/centos/build_srpm.data b/base/nss-pam-ldapd/centos/build_srpm.data new file mode 100644 index 000000000..d6df555cd --- /dev/null +++ b/base/nss-pam-ldapd/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=4 diff --git a/base/nss-pam-ldapd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/base/nss-pam-ldapd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..fdd0202a3 --- /dev/null +++ b/base/nss-pam-ldapd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 2fb3bb85ad9c2627f8e7f11a64d6dd2f967fb230 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 26 Sep 2016 17:40:10 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/nss-pam-ldapd.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/nss-pam-ldapd.spec b/SPECS/nss-pam-ldapd.spec +index 72aa77f..e04eb55 100644 +--- a/SPECS/nss-pam-ldapd.spec ++++ b/SPECS/nss-pam-ldapd.spec +@@ -39,7 +39,7 @@ + + Name: nss-pam-ldapd + Version: 0.8.13 +-Release: 8%{?dist} ++Release: 8.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: An nsswitch module which uses directory servers + Group: System Environment/Base + License: LGPLv2+ +-- +1.8.3.1 + diff --git a/base/nss-pam-ldapd/centos/meta_patches/PATCH_ORDER b/base/nss-pam-ldapd/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..ab49c7aec --- /dev/null +++ b/base/nss-pam-ldapd/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,4 @@ +spec-TiS-changes.patch +spec-bind-nslcd-to-rootDN.patch +remove-custom-nslcd-conf-file.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/base/nss-pam-ldapd/centos/meta_patches/remove-custom-nslcd-conf-file.patch b/base/nss-pam-ldapd/centos/meta_patches/remove-custom-nslcd-conf-file.patch new file mode 100644 index 000000000..403d2f172 --- /dev/null +++ b/base/nss-pam-ldapd/centos/meta_patches/remove-custom-nslcd-conf-file.patch @@ -0,0 +1,34 @@ +From a34da1b06ffa8684fdeb89f373921c61a9ac5fbc Mon Sep 17 00:00:00 2001 +From: Saju Oommen +Date: Mon, 15 Jan 2018 14:19:08 -0500 +Subject: [PATCH 1/1] remove-custom-nslcd-conf-file + +--- + SPECS/nss-pam-ldapd.spec | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/SPECS/nss-pam-ldapd.spec b/SPECS/nss-pam-ldapd.spec +index 4390a16..107b4ea 100644 +--- a/SPECS/nss-pam-ldapd.spec ++++ b/SPECS/nss-pam-ldapd.spec +@@ -49,7 +49,6 @@ Source1: http://arthurdejong.org/nss-pam-ldapd/nss-pam-ldapd-%{version}.tar.gz.s + Source2: nslcd.init + Source3: nslcd.tmpfiles + Source4: nslcd.service +-Source5: nslcd.conf + Patch1: nss-pam-ldapd-0.8.12-validname.patch + Patch2: nss-pam-ldapd-0.8.12-In-nslcd-log-EPIPE-only-on-debug-level.patch + Patch3: nss-pam-ldapd-0.8.12-uid-overflow.patch +@@ -167,9 +166,6 @@ mkdir -p -m 0755 $RPM_BUILD_ROOT/etc/tmpfiles.d + install -p -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/tmpfiles.d/%{name}.conf + %endif + +-# WRS +-install -m 644 %{SOURCE5} $RPM_BUILD_ROOT/%{_sysconfdir}/nslcd.conf +- + %clean + rm -rf $RPM_BUILD_ROOT + +-- +1.8.3.1 + diff --git a/base/nss-pam-ldapd/centos/meta_patches/spec-TiS-changes.patch b/base/nss-pam-ldapd/centos/meta_patches/spec-TiS-changes.patch new file mode 100644 index 000000000..8d5991c9f --- /dev/null +++ b/base/nss-pam-ldapd/centos/meta_patches/spec-TiS-changes.patch @@ -0,0 +1,45 @@ +nss-pam-ldapd: include Titanium Cloud changes + +New nss-pam-ldapd uses default ldap group ID, so we set +gid in nslcd.conf to ldap. + +diff --git a/SPECS/nss-pam-ldapd.spec b/SPECS/nss-pam-ldapd.spec +index 72aa77f..20fe844 100644 +--- a/SPECS/nss-pam-ldapd.spec ++++ b/SPECS/nss-pam-ldapd.spec +@@ -49,6 +49,7 @@ Source1: http://arthurdejong.org/nss-pam-ldapd/nss-pam-ldapd-%{version}.tar.gz.s + Source2: nslcd.init + Source3: nslcd.tmpfiles + Source4: nslcd.service ++Source5: nslcd.conf + Patch1: nss-pam-ldapd-0.8.12-validname.patch + Patch2: nss-pam-ldapd-0.8.12-In-nslcd-log-EPIPE-only-on-debug-level.patch + Patch3: nss-pam-ldapd-0.8.12-uid-overflow.patch +@@ -166,6 +167,9 @@ mkdir -p -m 0755 $RPM_BUILD_ROOT/etc/tmpfiles.d + install -p -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/tmpfiles.d/%{name}.conf + %endif + ++# WRS ++install -m 644 %{SOURCE5} $RPM_BUILD_ROOT/%{_sysconfdir}/nslcd.conf ++ + %clean + rm -rf $RPM_BUILD_ROOT + +@@ -249,12 +253,13 @@ if test "$1" -eq "1" && ! grep -q -F "# $comment" $target 2> /dev/null ; then + grep -E '^host[[:blank:]]' $source |\ + sed -r -e "s,^host[[:blank:]](.*),uri ${scheme}://\1/,g" >> $target + fi ++ # WRS: we don't want to change our custom base in nslcd.conf + # Base doesn't require any special logic. +- if grep -E -q '^base[[:blank:]]' $source 2> /dev/null ; then ++ # if grep -E -q '^base[[:blank:]]' $source 2> /dev/null ; then + # Comment out the packaged default base and replace it. +- sed -i -r -e 's,^(base[[:blank:]].*),# \1,g' $target +- grep -E '^base[[:blank:]]' $source >> $target +- fi ++ # sed -i -r -e 's,^(base[[:blank:]].*),# \1,g' $target ++ # grep -E '^base[[:blank:]]' $source >> $target ++ # fi + # Pull in these settings, if they're set, directly. + grep -E '^(binddn|bindpw|port|scope|ssl|pagesize)[[:blank:]]' $source 2> /dev/null >> $target + grep -E '^(tls_)' $source 2> /dev/null >> $target diff --git a/base/nss-pam-ldapd/centos/meta_patches/spec-bind-nslcd-to-rootDN.patch b/base/nss-pam-ldapd/centos/meta_patches/spec-bind-nslcd-to-rootDN.patch new file mode 100644 index 000000000..a66316479 --- /dev/null +++ b/base/nss-pam-ldapd/centos/meta_patches/spec-bind-nslcd-to-rootDN.patch @@ -0,0 +1,27 @@ +From cc70f1c5fb9c2f632a48968cf5eac2cb20210d1e Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Thu, 13 Apr 2017 11:43:59 -0400 +Subject: [PATCH] specify rootDN as bindDN in nslcd to prevent writes over + anonymous binds. + +--- + SPECS/nss-pam-ldapd.spec | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/SPECS/nss-pam-ldapd.spec b/SPECS/nss-pam-ldapd.spec +index 9c0dc91..4390a16 100644 +--- a/SPECS/nss-pam-ldapd.spec ++++ b/SPECS/nss-pam-ldapd.spec +@@ -261,7 +261,8 @@ if test "$1" -eq "1" && ! grep -q -F "# $comment" $target 2> /dev/null ; then + # grep -E '^base[[:blank:]]' $source >> $target + # fi + # Pull in these settings, if they're set, directly. +- grep -E '^(binddn|bindpw|port|scope|ssl|pagesize)[[:blank:]]' $source 2> /dev/null >> $target ++ # WRS: we don't want change our custom binddn and bindpw in nslcd.conf ++ grep -E '^(port|scope|ssl|pagesize)[[:blank:]]' $source 2> /dev/null >> $target + grep -E '^(tls_)' $source 2> /dev/null >> $target + grep -E '^(timelimit|bind_timelimit|idle_timelimit)[[:blank:]]' $source 2> /dev/null >> $target + fi +-- +1.8.3.1 + diff --git a/base/nss-pam-ldapd/centos/srpm_path b/base/nss-pam-ldapd/centos/srpm_path new file mode 100644 index 000000000..a4a9dbeba --- /dev/null +++ b/base/nss-pam-ldapd/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/nss-pam-ldapd-0.8.13-8.el7.src.rpm diff --git a/base/nss-pam-ldapd/files/login b/base/nss-pam-ldapd/files/login new file mode 100644 index 000000000..a8a9977b2 --- /dev/null +++ b/base/nss-pam-ldapd/files/login @@ -0,0 +1,14 @@ +auth sufficient pam_unix.so +auth sufficient pam_ldap.so use_first_pass +auth required pam_deny.so + +account required pam_unix.so +account sufficient pam_ldap.so +account required pam_permit.so + +session required pam_unix.so +session optional pam_ldap.so + +password sufficient pam_unix.so nullok md5 shadow use_authtok +password sufficient pam_ldap.so try_first_pass +password required pam_deny.so diff --git a/base/nss-pam-ldapd/files/nslcd.init b/base/nss-pam-ldapd/files/nslcd.init new file mode 100755 index 000000000..681a91d12 --- /dev/null +++ b/base/nss-pam-ldapd/files/nslcd.init @@ -0,0 +1,109 @@ +#! /bin/sh + +# /etc/init.d/nslcd script for starting and stopping nslcd +# Copyright (C) 2006 West Consulting +# Copyright (C) 2006, 2008, 2009, 2010, 2011, 2012, 2013 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +### BEGIN INIT INFO +# Provides: nslcd +# Required-Start: $remote_fs $syslog $time +# Required-Stop: $remote_fs $syslog +# Should-Start: $named $network slapd +# Should-Stop: $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: LDAP connection daemon +# Description: nslcd is a LDAP connection daemon that is used to +# do LDAP queries for the NSS and PAM modules. +### END INIT INFO + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +NSLCD_NAME=nslcd +NSLCD_BIN=/usr/sbin/$NSLCD_NAME +NSLCD_DESC="LDAP connection daemon" +NSLCD_CFG=/etc/nslcd.conf +NSLCD_STATEDIR=/var/run/nslcd +NSLCD_PIDFILE=$NSLCD_STATEDIR/nslcd.pid + +[ -x "$NSLCD_BIN" ] || exit 0 +[ -f "$NSLCD_CFG" ] || exit 0 + +. /lib/lsb/init-functions + +# read defaults +[ -f /etc/default/$NSLCD_NAME ] && . /etc/default/$NSLCD_NAME + +case "$1" in +start) + # set up state directory + [ -d "$NSLCD_STATEDIR" ] || ( mkdir -m 755 "$NSLCD_STATEDIR" ; \ + chown nslcd:nslcd "$NSLCD_STATEDIR" ) + # start nslcd + log_begin_msg "Starting $NSLCD_DESC" "$NSLCD_NAME" + # THIS IS ONLY TEMPORARY + create-cracklib-dict /usr/share/cracklib/cracklib-small > /dev/null 2>&1 + start-stop-daemon --start --oknodo \ + --pidfile $NSLCD_PIDFILE \ + --startas $NSLCD_BIN + log_end_msg $? + ;; +stop) + # stop nslcd + log_begin_msg "Stopping $NSLCD_DESC" "$NSLCD_NAME" + start-stop-daemon --stop --oknodo \ + --pidfile $NSLCD_PIDFILE \ + --name "$NSLCD_NAME" + log_end_msg $? + [ -n "$NSLCD_PIDFILE" ] && rm -f $NSLCD_PIDFILE + ;; +restart|force-reload) + [ -d "$NSLCD_STATEDIR" ] || ( mkdir -m 755 "$NSLCD_STATEDIR" ; \ + chown nslcd:nslcd "$NSLCD_STATEDIR" ) + log_begin_msg "Restarting $NSLCD_DESC" "$NSLCD_NAME" + start-stop-daemon --stop --quiet --retry 10 \ + --pidfile $NSLCD_PIDFILE \ + --name "$NSLCD_NAME" + [ -n "$NSLCD_PIDFILE" ] && rm -f $NSLCD_PIDFILE + start-stop-daemon --start \ + --pidfile $NSLCD_PIDFILE \ + --startas $NSLCD_BIN + log_end_msg $? + ;; +status) + if [ -f "$NSLCD_PIDFILE" ] + then + if $NSLCD_BIN --check + then + log_success_msg "$NSLCD_NAME running (pid `cat $NSLCD_PIDFILE`)" + exit 0 + else + log_success_msg "$NSLCD_NAME stopped" + exit 1 + fi + else + log_success_msg "$NSLCD_NAME stopped" + exit 3 + fi + ;; +*) + log_success_msg "Usage: $0 {start|stop|restart|force-reload|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/base/setup/centos/build_srpm.data b/base/setup/centos/build_srpm.data new file mode 100644 index 000000000..03540f231 --- /dev/null +++ b/base/setup/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=13 diff --git a/base/setup/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/base/setup/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..543253914 --- /dev/null +++ b/base/setup/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 412fc338e588c92ee0be3bf1b1af0040fac9f500 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 26 Sep 2016 17:40:54 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/setup.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 223bfd5..89a4d2f 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -1,7 +1,7 @@ + Summary: A set of system configuration and setup files + Name: setup + Version: 2.8.71 +-Release: 9%{?dist} ++Release: 7.el7%{?_tis_dist}.%{tis_patch_ver} + License: Public Domain + Group: System Environment/Base + URL: https://fedorahosted.org/setup/ +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/PATCH_ORDER b/base/setup/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..62704c5e4 --- /dev/null +++ b/base/setup/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,14 @@ +spec-include-TiS-changes.patch +spec-include-tis-uid-gid.patch +spec-set-custom-prompt.patch +updating-gids-and-uids-to-support-upgrade-from-wrl.patch +spec-passwd-remove-unused-default-users-and-groups.patch +spec-include-snmpd-fm-user-group.patch +security-make-exports-and-fstab-only-root-accessible.patch +spec-remove-unused-default-groups.patch +0001-Update-package-versioning-for-TIS-format.patch +spec-add-TMOUT-variable.patch +spec-include-add-fm-user-to-snmpd-group.patch +spec-add-magnum-uid-gid.patch +spec-add-ironic-uid-gid.patch +spec-add-murano-uid-gid.patch diff --git a/base/setup/centos/meta_patches/security-make-exports-and-fstab-only-root-accessible.patch b/base/setup/centos/meta_patches/security-make-exports-and-fstab-only-root-accessible.patch new file mode 100644 index 000000000..464f5008a --- /dev/null +++ b/base/setup/centos/meta_patches/security-make-exports-and-fstab-only-root-accessible.patch @@ -0,0 +1,28 @@ +From 2f6906e33b91dc28c7b48ce5604501ce09cfaed6 Mon Sep 17 00:00:00 2001 +Message-Id: <2f6906e33b91dc28c7b48ce5604501ce09cfaed6.1468352966.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 12 Jul 2016 15:43:47 -0400 +Subject: [PATCH 1/1] security make exports and fstab only root accessible + +Apply a chmod of 600 to the two files. + +Signed-off-by: Jim Somerville +--- + SPECS/setup.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index d40113f..6c18614 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -65,6 +65,7 @@ chmod 0644 %{buildroot}/var/log/lastlog + touch %{buildroot}/etc/fstab + touch %{buildroot}/etc/subuid + touch %{buildroot}/etc/subgid ++chmod 0600 %{buildroot}/etc/{exports,fstab} + install -m 644 %{SOURCE1} %{buildroot}/etc/ + install -m 644 %{SOURCE2} %{buildroot}/etc/profile.d/prompt.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-add-TMOUT-variable.patch b/base/setup/centos/meta_patches/spec-add-TMOUT-variable.patch new file mode 100644 index 000000000..458d3f6a7 --- /dev/null +++ b/base/setup/centos/meta_patches/spec-add-TMOUT-variable.patch @@ -0,0 +1,40 @@ +From 13bee9ed7d91fae3d66f91d4e4aa139ca3d05f66 Mon Sep 17 00:00:00 2001 +From: David Balme +Date: Thu, 13 Oct 2016 08:40:27 -0400 +Subject: [PATCH 1/1] add TMOUT variable + +--- + SPECS/setup.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 89a4d2f..1f5c96a 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -8,6 +8,7 @@ URL: https://fedorahosted.org/setup/ + Source0: https://fedorahosted.org/releases/s/e/%{name}/%{name}-%{version}.tar.bz2 + Source1: motd + Source2: prompt.sh ++Source3: custom.sh + BuildArch: noarch + BuildRequires: bash tcsh perl + #require system release for saner dependency order +@@ -70,6 +71,7 @@ touch %{buildroot}/etc/subgid + chmod 0600 %{buildroot}/etc/{exports,fstab} + install -m 644 %{SOURCE1} %{buildroot}/etc/ + install -m 644 %{SOURCE2} %{buildroot}/etc/profile.d/prompt.sh ++install -m 644 %{SOURCE3} %{buildroot}/etc/profile.d/custom.sh + + # remove unpackaged files from the buildroot + rm -f %{buildroot}/etc/Makefile +@@ -125,6 +127,7 @@ end + %config(noreplace) /etc/motd + %dir /etc/profile.d + /etc/profile.d/prompt.sh ++/etc/profile.d/custom.sh + %config(noreplace) %verify(not md5 size mtime) /etc/shells + %ghost %attr(0644,root,root) %verify(not md5 size mtime) /var/log/lastlog + %ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/fstab +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-add-ironic-uid-gid.patch b/base/setup/centos/meta_patches/spec-add-ironic-uid-gid.patch new file mode 100644 index 000000000..7aa40568f --- /dev/null +++ b/base/setup/centos/meta_patches/spec-add-ironic-uid-gid.patch @@ -0,0 +1,26 @@ +commit f944ef677dc090e91b790ac54064d61d071edb5c +Author: Shoaib Nasir +Date: Mon Sep 25 12:20:43 2017 -0400 + + Add ironic-uid-gid.patch to SPECS + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 2ec3541..55dd30b 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -28,6 +28,7 @@ Patch9: snmpd-fm-user-group.patch + Patch10: remove-unused-default-groups.patch + Patch11: add-fm-user-to-snmpd-group.patch + Patch12: add-magnum-uid-gid.patch ++Patch13: add-ironic-uid-gid.patch + + %description + The setup package contains a set of important system configuration and +@@ -48,6 +49,7 @@ setup files, such as passwd, group, and profile. + %patch10 -p1 + %patch11 -p1 + %patch12 -p1 ++%patch13 -p1 + + ./shadowconvert.sh + diff --git a/base/setup/centos/meta_patches/spec-add-magnum-uid-gid.patch b/base/setup/centos/meta_patches/spec-add-magnum-uid-gid.patch new file mode 100644 index 000000000..c689da226 --- /dev/null +++ b/base/setup/centos/meta_patches/spec-add-magnum-uid-gid.patch @@ -0,0 +1,32 @@ +From 11086bd4422e8f24a0b070eb16e53b08f4561c61 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Thu, 3 Aug 2017 16:18:34 -0400 +Subject: [PATCH 1/1] meta add magnum uid and gid + +--- + SPECS/setup.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 9ee24ca..2ec3541 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -27,6 +27,7 @@ Patch8: passwd-remove-unused-default-users-and-groups.patch + Patch9: snmpd-fm-user-group.patch + Patch10: remove-unused-default-groups.patch + Patch11: add-fm-user-to-snmpd-group.patch ++Patch12: add-magnum-uid-gid.patch + + %description + The setup package contains a set of important system configuration and +@@ -46,6 +47,7 @@ setup files, such as passwd, group, and profile. + %patch9 -p1 + %patch10 -p1 + %patch11 -p1 ++%patch12 -p1 + + ./shadowconvert.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-add-murano-uid-gid.patch b/base/setup/centos/meta_patches/spec-add-murano-uid-gid.patch new file mode 100644 index 000000000..e7e7bd4ef --- /dev/null +++ b/base/setup/centos/meta_patches/spec-add-murano-uid-gid.patch @@ -0,0 +1,32 @@ +From bb774f39b779de4e31007fc70bead641820ae74f Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Mon, 8 Jan 2018 12:28:08 -0500 +Subject: [PATCH 1/1] meta add murano uid and gid + +--- + SPECS/setup.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 55dd30b..b652b3c 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -29,6 +29,7 @@ Patch10: remove-unused-default-groups.patch + Patch11: add-fm-user-to-snmpd-group.patch + Patch12: add-magnum-uid-gid.patch + Patch13: add-ironic-uid-gid.patch ++Patch14: add-murano-uid-gid.patch + + %description + The setup package contains a set of important system configuration and +@@ -50,6 +51,7 @@ setup files, such as passwd, group, and profile. + %patch11 -p1 + %patch12 -p1 + %patch13 -p1 ++%patch14 -p1 + + ./shadowconvert.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-include-TiS-changes.patch b/base/setup/centos/meta_patches/spec-include-TiS-changes.patch new file mode 100644 index 000000000..3cbf3b64c --- /dev/null +++ b/base/setup/centos/meta_patches/spec-include-TiS-changes.patch @@ -0,0 +1,35 @@ +setup.spec: to include Titanium Cloud specific changes + +To include files under cgcs/recipes-base/setup/files/* + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 9174b5a..efc52ca 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -6,6 +6,7 @@ License: Public Domain + Group: System Environment/Base + URL: https://fedorahosted.org/setup/ + Source0: https://fedorahosted.org/releases/s/e/%{name}/%{name}-%{version}.tar.bz2 ++Source1: motd + BuildArch: noarch + BuildRequires: bash tcsh perl + #require system release for saner dependency order +@@ -55,6 +56,7 @@ chmod 0644 %{buildroot}/var/log/lastlog + touch %{buildroot}/etc/fstab + touch %{buildroot}/etc/subuid + touch %{buildroot}/etc/subgid ++install -m 644 %{SOURCE1} %{buildroot}/etc/ + + # remove unpackaged files from the buildroot + rm -f %{buildroot}/etc/Makefile +@@ -107,6 +109,7 @@ end + %attr(0600,root,root) %config(noreplace,missingok) /etc/securetty + %config(noreplace) /etc/csh.login + %config(noreplace) /etc/csh.cshrc ++%config(noreplace) /etc/motd + %dir /etc/profile.d + %config(noreplace) %verify(not md5 size mtime) /etc/shells + %ghost %attr(0644,root,root) %verify(not md5 size mtime) /var/log/lastlog +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-include-add-fm-user-to-snmpd-group.patch b/base/setup/centos/meta_patches/spec-include-add-fm-user-to-snmpd-group.patch new file mode 100644 index 000000000..44ea8bdaf --- /dev/null +++ b/base/setup/centos/meta_patches/spec-include-add-fm-user-to-snmpd-group.patch @@ -0,0 +1,22 @@ +--- + SPECS/setup.spec | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -26,6 +26,7 @@ Patch6: updating-gids-and-uids-to-suppor + Patch8: passwd-remove-unused-default-users-and-groups.patch + Patch9: snmpd-fm-user-group.patch + Patch10: remove-unused-default-groups.patch ++Patch11: add-fm-user-to-snmpd-group.patch + + %description + The setup package contains a set of important system configuration and +@@ -44,6 +45,7 @@ setup files, such as passwd, group, and + %patch8 -p1 + %patch9 -p1 + %patch10 -p1 ++%patch11 -p1 + + ./shadowconvert.sh + diff --git a/base/setup/centos/meta_patches/spec-include-snmpd-fm-user-group.patch b/base/setup/centos/meta_patches/spec-include-snmpd-fm-user-group.patch new file mode 100644 index 000000000..3de93e31b --- /dev/null +++ b/base/setup/centos/meta_patches/spec-include-snmpd-fm-user-group.patch @@ -0,0 +1,41 @@ +From 35ebbf2ca7e5e412f55cdaa875845728d203b34d Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 12 Aug 2016 17:35:28 -0400 +Subject: [PATCH] meta patch for snmpd-user-group.patch + +--- + SPECS/setup.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 89ff683..d40113f 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -1,7 +1,7 @@ + Summary: A set of system configuration and setup files + Name: setup + Version: 2.8.71 +-Release: 7%{?dist} ++Release: 8%{?dist} + License: Public Domain + Group: System Environment/Base + URL: https://fedorahosted.org/setup/ +@@ -23,6 +23,7 @@ Patch5: setup-2.8.71-fullpath.patch + Patch6: tis-uid-gid.patch + Patch7: updating-gids-and-uids-to-support-upgrade-from-wrl.patch + Patch8: passwd-remove-unused-default-users-and-groups.patch ++Patch9: snmpd-fm-user-group.patch + + %description + The setup package contains a set of important system configuration and +@@ -39,6 +40,7 @@ setup files, such as passwd, group, and profile. + %patch6 -p1 + %patch7 -p1 + %patch8 -p1 ++%patch9 -p1 + + ./shadowconvert.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-include-tis-uid-gid.patch b/base/setup/centos/meta_patches/spec-include-tis-uid-gid.patch new file mode 100644 index 000000000..665c14258 --- /dev/null +++ b/base/setup/centos/meta_patches/spec-include-tis-uid-gid.patch @@ -0,0 +1,1078 @@ +From ee087f57155f691c416857888a5655f4230becc8 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 25 Apr 2016 13:15:13 -0400 +Subject: [PATCH 1/1] WRS: spec-include-tis-uid-gid.patch + +--- + SPECS/setup.spec | 2 + + SPECS/setup.spec.orig | 1038 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 1040 insertions(+) + create mode 100644 SPECS/setup.spec.orig + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index efc52ca..3f74b90 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -19,6 +19,7 @@ Patch2: setup-2.8.71-bashrc-shellvar.patch + Patch3: setup-2.8.71-uidgidchanges.patch + Patch4: setup-2.8.71-filesystems.patch + Patch5: setup-2.8.71-fullpath.patch ++Patch6: tis-uid-gid.patch + + %description + The setup package contains a set of important system configuration and +@@ -32,6 +33,7 @@ setup files, such as passwd, group, and profile. + %patch3 -p1 + %patch4 -p1 + %patch5 -p1 ++%patch6 -p1 + + ./shadowconvert.sh + +diff --git a/SPECS/setup.spec.orig b/SPECS/setup.spec.orig +new file mode 100644 +index 0000000..3b20861 +--- /dev/null ++++ b/SPECS/setup.spec.orig +@@ -0,0 +1,1038 @@ ++Summary: A set of system configuration and setup files ++Name: setup ++Version: 2.8.71 ++Release: 6%{?dist} ++License: Public Domain ++Group: System Environment/Base ++URL: https://fedorahosted.org/setup/ ++Source0: https://fedorahosted.org/releases/s/e/%{name}/%{name}-%{version}.tar.bz2 ++Source1: motd ++BuildArch: noarch ++BuildRequires: bash tcsh perl ++#require system release for saner dependency order ++Requires: system-release ++Conflicts: filesystem < 3 ++Conflicts: initscripts < 4.26, bash <= 2.0.4-21 ++ ++Patch1: setup-2.8.71-securetty-mainframes.patch ++Patch2: setup-2.8.71-bashrc-shellvar.patch ++Patch3: setup-2.8.71-uidgidchanges.patch ++Patch4: setup-2.8.71-filesystems.patch ++ ++%description ++The setup package contains a set of important system configuration and ++setup files, such as passwd, group, and profile. ++ ++%prep ++%setup -q ++ ++%patch1 -p1 -b .mainframe ++%patch2 -p1 -b .envvar ++%patch3 -p1 ++%patch4 -p1 ++ ++./shadowconvert.sh ++ ++%build ++ ++%check ++# Run any sanity checks. ++make check ++ ++%install ++rm -rf %{buildroot} ++mkdir -p %{buildroot}/etc/profile.d ++cp -ar * %{buildroot}/etc ++rm -f %{buildroot}/etc/uidgid ++rm -f %{buildroot}/etc/COPYING ++mkdir -p %{buildroot}/var/log ++touch %{buildroot}/var/log/lastlog ++touch %{buildroot}/etc/environment ++chmod 0644 %{buildroot}/etc/environment ++chmod 0400 %{buildroot}/etc/{shadow,gshadow} ++chmod 0644 %{buildroot}/var/log/lastlog ++touch %{buildroot}/etc/fstab ++install -m 644 %{SOURCE1} %{buildroot}/etc/ ++ ++# remove unpackaged files from the buildroot ++rm -f %{buildroot}/etc/Makefile ++rm -f %{buildroot}/etc/serviceslint ++rm -f %{buildroot}/etc/uidgidlint ++rm -f %{buildroot}/etc/shadowconvert.sh ++rm -f %{buildroot}/etc/setup.spec ++# remove the "originals" of patched files ++rm -f %{buildroot}/etc/securetty.mainframe ++rm -f %{buildroot}/etc/bashrc.envvar ++rm -f %{buildroot}/etc/*.orig ++ ++%clean ++rm -rf %{buildroot} ++ ++#throw away useless and dangerous update stuff until rpm will be able to ++#handle it ( http://rpm.org/ticket/6 ) ++%post -p ++for i, name in ipairs({"passwd", "shadow", "group", "gshadow"}) do ++ os.remove("/etc/"..name..".rpmnew") ++end ++if posix.access("/usr/bin/newaliases", "x") then ++ os.execute("/usr/bin/newaliases >/dev/null") ++end ++ ++%files ++%defattr(-,root,root,-) ++%doc uidgid COPYING ++%verify(not md5 size mtime) %config(noreplace) /etc/passwd ++%verify(not md5 size mtime) %config(noreplace) /etc/group ++%verify(not md5 size mtime) %attr(0000,root,root) %config(noreplace,missingok) /etc/shadow ++%verify(not md5 size mtime) %attr(0000,root,root) %config(noreplace,missingok) /etc/gshadow ++%config(noreplace) /etc/services ++%verify(not md5 size mtime) %config(noreplace) /etc/exports ++%config(noreplace) /etc/aliases ++%config(noreplace) /etc/environment ++%config(noreplace) /etc/filesystems ++%config(noreplace) /etc/host.conf ++%verify(not md5 size mtime) %config(noreplace) /etc/hosts ++%config(noreplace) /etc/hosts.allow ++%config(noreplace) /etc/hosts.deny ++%verify(not md5 size mtime) %config(noreplace) /etc/motd ++%config(noreplace) /etc/printcap ++%verify(not md5 size mtime) %config(noreplace) /etc/inputrc ++%config(noreplace) /etc/bashrc ++%config(noreplace) /etc/profile ++%config(noreplace) /etc/protocols ++%attr(0600,root,root) %config(noreplace,missingok) /etc/securetty ++%config(noreplace) /etc/csh.login ++%config(noreplace) /etc/csh.cshrc ++%config(noreplace) /etc/motd ++%dir /etc/profile.d ++%config(noreplace) %verify(not md5 size mtime) /etc/shells ++%ghost %attr(0644,root,root) %verify(not md5 size mtime) /var/log/lastlog ++%ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/fstab ++ ++%changelog ++* Fri May 22 2015 Ondrej Vasik - 2.8.71-6 ++- change reservation of 185:185 to jboss user (#1192413) ++- reserve uidgid pair 167:167 for ceph (#1221043) ++- reserve uidgid for systemd-network(192:192) (#1213820) ++- reserve uidgid for systemd-resolve(193:193) (#1213820) ++- mention systemd-jounal-gateway can be dynamic (#1213820) ++ ++ ++* Fri Aug 15 2014 Ondrej Vasik - 2.8.71-5 ++- reserve uidgid pair 142:142 for activemq (#1086923) ++- add xfs to /etc/filesystems, fallback to /proc/filesystems ++ (#1123832) ++ ++* Wed Mar 12 2014 Ondrej Vasik - 2.8.71-4 ++- require system-release for saner dependency order (#1075578) ++ ++* Tue Feb 25 2014 Ondrej Vasik - 2.8.71-3 ++- add more securetty required for mainframes (#1067347) ++- set SHELL envvar to /bin/bash in bashrc (#1063552) ++ ++* Fri Dec 27 2013 Daniel Mach - 2.8.71-2 ++- Mass rebuild 2013-12-27 ++ ++* Fri Jun 07 2013 Ondrej Vasik 2.8.71-1 ++- fix escape codes for screen (#969429) ++- handle vte terminals in bashrc (#924275) ++ ++* Tue May 14 2013 Ondrej Vasik 2.8.70-1 ++- fix typo in cdrom default group (#962486) ++ ++* Thu Apr 18 2013 Ondrej Vasik 2.8.69-1 ++- remove the rpmlib(X-CheckUnifiedSystemdir) requirement ++ hack - no longer required ++ ++* Sun Apr 14 2013 Ondrej Vasik 2.8.68-1 ++- assign gid :135 for mock (#928063) ++- update /etc/services to latest IANA reservations ++ ++* Wed Mar 20 2013 Ondrej Vasik 2.8.67-1 ++- assign 166:166 uidgid pair for ceilometer (#923891) ++- change 187:187 reservation from openstack-heat ++ to just heat(#923858) ++- longer shell names support caused by UsrMove to ++ the /etc/shells (#922527) ++- drop gopher (uid 13, gid 30) from groups created by default ++ -> dropped completely - no gopher server in Fedora (#918206) ++- drop dip (gid 40) from groups created by default ++ -> moved to ppp (#918206) ++- drop uucp (uidgid 14) from groups created by default ++ -> moved to uucp (#918206) ++- create cdrom, tape, dialout, floppy groups in setup(#919285) ++ ++* Tue Mar 05 2013 Ondrej Vasik 2.8.66-1 ++- assign :190 gid for systemd-journal (#918120) ++- assign 191:191 uidgid pair for systemd-journal-gateway (#918120) ++ ++* Wed Jan 23 2013 Ondrej Vasik 2.8.65-1 ++- assign 165:165 uidgid pair for cinder (#902987) ++ ++* Wed Jan 16 2013 Ondrej Vasik 2.8.64-1 ++- correct handling of 256 color terminals in bashrc ++ ++* Mon Dec 02 2012 Ondrej Vasik 2.8.63-1 ++- ovirtagent created by ovirt-guest-agent ++ ++* Mon Dec 02 2012 Ondrej Vasik 2.8.62-1 ++- rename rhevagent uidgid reservation to ovirtagent ++ ++* Fri Nov 02 2012 Ondrej Vasik 2.8.61-1 ++- reserve uid 189 for hacluster (#872208) ++- reserve gid 189 for haclient (#872208) ++ ++* Tue Oct 02 2012 Ondrej Vasik 2.8.60-1 ++- reserve 188:188 for haproxy (#860221) ++ ++* Wed Sep 19 2012 Ondrej Vasik 2.8.59-1 ++- update /etc/services to match with latest IANA ++ assignments ++ ++* Mon Aug 21 2012 Ondrej Vasik 2.8.58-1 ++- reserve 110:110 for jetty (#849927) ++ ++* Mon Aug 06 2012 Ondrej Vasik 2.8.57-1 ++- reserve 187:187 for openstack-heat (#845078) ++ ++* Sat Jul 21 2012 Fedora Release Engineering - 2.8.56-2 ++- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild ++ ++* Fri Jul 13 2012 Ondrej Vasik 2.8.56-1 ++- Turn on parallel history in bash (#815810) ++ ++* Thu Jul 12 2012 Ondrej Vasik 2.8.55-1 ++- reserve 186 uid for jbosson-agent user, reserve 186 gid ++ for jbosson group (#839410) ++ ++* Fri May 11 2012 Ondrej Vasik 2.8.54-1 ++- use unset -f pathmunge in /etc/profile to work more nicely ++ with ksh (#791140) ++ ++* Wed Apr 11 2012 Ondrej Vasik 2.8.53-1 ++- reserve 185:185 for jboss-as (#809398) ++ ++* Fri Mar 23 2012 Ondrej Vasik 2.8.52-1 ++- reserve 184:184 for mongodb (#806052) ++ ++* Thu Mar 22 2012 Ondrej Vasik 2.8.51-1 ++- do not throw away the stderr output of profile.d scripts ++ in noninteractive bash/ksh sessions(#805507) ++ ++* Mon Mar 19 2012 Ondrej Vasik 2.8.50-1 ++- reserve 182:182 for katello (#804204) ++- reserve 183:183 for elasticsearch (#804205) ++ ++* Tue Feb 21 2012 Ondrej Vasik 2.8.49-1 ++- conflict with filesystems before usrmove change ++ ++* Sun Feb 12 2012 Ondrej Vasik 2.8.48-1 ++- remove /bin and /sbin from /etc/profile(#789616) ++- require usrmove ++- add sbin paths in csh.login consistently with bash(#773268) ++ ++* Tue Jan 10 2012 Ondrej Vasik 2.8.47-1 ++- reserve 181:181 uidgid pair for wallaby (#772747) ++ ++* Tue Dec 06 2011 Ondrej Vasik 2.8.46-1 ++- reserve 134:134 uidgid pair for cimsrvr (#760178) ++ ++* Fri Nov 25 2011 Ondrej Vasik 2.8.45-1 ++- reserve :156 groupid for stapusr - #756807 ++- reserve :157 groupid for stapsys - #756807 ++- reserve :158 groupid for stapdev - #756807 ++ ++* Wed Nov 16 2011 Ondrej Vasik 2.8.44-1 ++- reserve 180:180 for aeolus - #754274 ++ ++* Fri Nov 11 2011 Ondrej Vasik 2.8.43-1 ++- gopher home dir in uidgid should be /var/gopher - #752885 ++- reserve 163:163 for keystone (openstack-keystone) - #752842 ++- reserve 164:164 for quantum (openstack-quantum) - #752842 ++- update services to latest IANA ++ ++* Wed Nov 2 2011 Ondrej Vasik 2.8.42-1 ++- add ext4 to /etc/filesystems - #750506 ++ ++* Wed Sep 14 2011 Ondrej Vasik 2.8.41-1 ++- reserve 179:179 for sanlock - #727655 ++ ++* Fri Aug 26 2011 Ondrej Vasik 2.8.40-1 ++- reserve 178:178 for myproxy (myproxy-server) - #733671 ++ ++* Fri Aug 26 2011 Ondrej Vasik 2.8.39-1 ++- reserve 177:177 for dhcpd (dhcp) - #699713 ++ ++* Tue Aug 23 2011 Ondrej Vasik 2.8.38-1 ++- reserve 160:160 for swift (openstack-swift) - #732442 ++- reserve 161:161 for glance (openstack-glance) - #732442 ++- reserve 162:162 for nova (openstack-nova) - #732442 ++- comment out 0/tcp spr-itunes /etc/services entry (#710185) ++- add hvc[01], xvc0, hvsi[012] to /etc/securetty (#728030) ++ ++* Tue Aug 16 2011 Ondrej Vasik 2.8.37-1 ++- dropped all suplemental groups from basic /etc/group file ++ (#722529) ++ ++* Tue Aug 16 2011 Ondrej Vasik 2.8.36-1 ++- dropped suplemental root's groups(#722529) ++ ++* Wed Jun 29 2011 Ondrej Vasik 2.8.35-1 ++- reserve 176:176 for apache traffic server - ats(#715266) ++ ++* Mon Jun 13 2011 Ondrej Vasik 2.8.34-1 ++- update protocols and services to latest IANA ++- reserve 175:175 for rhevagent (#709599) ++ ++* Thu May 19 2011 Ondrej Vasik 2.8.33-1 ++- reflect the reserved username change of amanda ++ to amandabackup (#700807) ++- drop order hosts,bind from setup, no longer used by ++ glibc (#703049) ++- assign 174:174 uidgid for user/group retrace ++ (abrt retrace-server, #706012) ++ ++* Tue Apr 12 2011 Ondrej Vasik 2.8.32-1 ++- do not override already set PROMPT_COMMAND envvar(#691425) ++- do not quit uidgidlint after first error, show all ++- update services to latest IANA ++ ++* Mon Jan 24 2011 Ondrej Vasik 2.8.31-1 ++- drop ownership of /etc/mtab, now owned by util-linux ++ ++* Tue Jan 18 2011 Ondrej Vasik 2.8.30-1 ++- remove explicit buildroot ++- reserve uidgid pair 173:173 for abrt(#670231) ++ ++* Fri Dec 03 2010 Ondrej Vasik 2.8.29-1 ++- run newaliases in the post to prevent sendmail messages ++ about old alias database in the log(#658921) ++ ++* Fri Nov 12 2010 Ondrej Vasik 2.8.28-1 ++- update services and protocols to latest IANA reservations ++- reserve uidgid pair 109:109 for rhevm(#652287) ++ ++* Tue Sep 07 2010 Ondrej Vasik 2.8.27-1 ++- add double quotes arround sourced profile.d scripts - ++ allow special characters in script names ++ ++* Wed Aug 18 2010 Ondrej Vasik 2.8.26-1 ++- fix regression in the change to printf(#624900) ++ ++* Thu Aug 12 2010 Ondrej Vasik 2.8.25-1 ++- use printf instead of echo in bashrc scripts(#620435) ++- update services to latest IANA ++ ++* Wed Jul 28 2010 Ondrej Vasik 2.8.24-1 ++- do show messages from profile.d scripts in interactive ++ login ksh shell(#616418) ++- respect umask settings even with login shell ++ ++* Tue Jun 29 2010 Ondrej Vasik 2.8.23-1 ++- reserve uidgid pair 172:172 for rtkit (#609171) ++ ++* Tue Jun 15 2010 Ondrej Vasik 2.8.22-1 ++- reserve uidgid pair 170:170 for avahi-autoipd ++- reserve uidgid pair 171:171 for pulse (pulseaudio) ++- update reserved homedir for avahi ++ ++* Mon Jun 07 2010 Ondrej Vasik 2.8.21-1 ++- update name of group reserved by cyrus-imapd to saslauth ++ ++* Mon May 24 2010 Ondrej Vasik 2.8.20-1 ++- speedup pathmunge() by using portable case(#544652) ++ ++* Wed May 19 2010 Ondrej Vasik 2.8.19-1 ++- fix syntax error in bashrc pathmunge(since bash 3.2)(#592799) ++ ++* Tue Apr 27 2010 Ondrej Vasik 2.8.18-1 ++- reserve uidgid pair 140:140 for ricci daemon(#585957) ++- reserve uidgid pair 141:141 for luci daemon(#585958) ++ ++* Wed Mar 31 2010 Ondrej Vasik 2.8.17-1 ++- verify md5sum/size/mtime in the case of /etc/hosts.allow ++ and /etc/hosts.deny (#578263) ++- do the same for /etc/services and /etc/protocols, we ++ provide (almost) complete IANA set, so no reason to modify ++ it in most cases outside of setup package ++ ++* Fri Mar 26 2010 Ondrej Vasik 2.8.16-3 ++- bad ugly double-thirteen friday(fix previous badfix) ++ ++* Fri Mar 26 2010 Ondrej Vasik 2.8.16-2 ++- fix not set path for csh shell caused by 2.8.16 update ++ ++* Fri Mar 26 2010 Ondrej Vasik 2.8.16-1 ++- drop X11R6 hierarchy dir from tcsh path (#576940) ++- update services to latest IANA ++- update protocols to latest IANA ++ ++* Thu Jan 21 2010 Ondrej Vasik 2.8.15-1 ++- reserve uidgid pair 155:155 for stap-server(#555813) ++- reserve uidgid pair 113:113 for usbmuxd(#556525) ++ ++* Tue Jan 12 2010 Ondrej Vasik 2.8.14-1 ++- reserve uidgid pair 133:133 for bacula(#554705) ++ ++* Tue Jan 05 2010 Ondrej Vasik 2.8.13-1 ++- update services to latest IANA ++- avoid one /usr/bin/id stat call in /etc/profile(#549056) ++ ++* Thu Dec 17 2009 Ondrej Vasik 2.8.12-1 ++- speed up pathmunge inside bashrc (#544652) ++- do not use deprecated egrep in profile ++ ++* Thu Dec 03 2009 Ondrej Vasik 2.8.11-1 ++- don't have HISTCONTROL ignorespace by default (#520632), ++ but do not override it when it is already set ++- add csync alias for port 2005 / tcp, udp ++ ++* Wed Nov 11 2009 Ondrej Vasik 2.8.10-1 ++- reserve uidgid pair 112:112 for vhostmd (#534110) ++- update /etc/services to latest IANA ++ ++* Tue Sep 08 2009 Ondrej Vasik 2.8.9-1 ++- reserve uidgid pair 108:108 for ovirt from libvirt (#513261) ++- reserve uidgid pair 111:111 for saned from sane-backends ++ (#520634) ++ ++* Mon Aug 17 2009 Ondrej Vasik 2.8.8-1 ++- change permissions on /etc/shadow and /etc/gshadow to 0000 and ++ use capabilities for them(#517577) ++ ++* Sun Jul 26 2009 Fedora Release Engineering - 2.8.7-2 ++- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild ++ ++* Tue Jul 21 2009 Ondrej Vasik 2.8.7-1 ++- increase threshold for uidgid reservations to 200 ++- reserve uidgid pair 107:107 for qemu (libvirt,#511957) ++- reflect threshold in profile and bashrc, do inform about ++ uidgid file existence there ++- remove old remnants about portmap from hosts.deny(#509919) ++ ++* Mon Jun 29 2009 Ondrej Vasik 2.8.6-1 ++- update protocols and services to latest IANA ++- add example for tty in prompt(#503304) ++ ++* Wed May 20 2009 Ondrej Vasik 2.8.5-1 ++- use history-search-backward/forward for pageup/pagedown ++ mapping in inputrc (#500989) ++- add HISTCONTROL="ignoreboth" to /etc/profile to not include ++ duplicities and lines starting with space into the history ++ (#500819) ++ ++* Tue May 12 2009 Ondrej Vasik 2.8.4-1 ++- add oprofile (16:16) to uidgid ++- use os.remove instead of os.execute in lua post ++ - no dependency on /bin/sh (thanks Panu Matilainen) ++ ++* Wed Apr 22 2009 Ondrej Vasik 2.8.3-2 ++- rewrite postun scriptlet to to prevent /bin/sh ++ dependency ++ ++* Fri Apr 10 2009 Ondrej Vasik 2.8.3-1 ++- do not disable coredumps in profile/csh.cshrc scripts, ++ coredumps already disabled in rawhide's RLIMIT_CORE(#495035) ++ ++* Wed Mar 25 2009 Ondrej Vasik 2.8.2-2 ++- reserve uid 65 for nslcd (will share group 55 ldap, #491899) ++ ++* Tue Mar 24 2009 Ondrej Vasik 2.8.2-1 ++- ship COPYING file, update protocols and services ++ to latest IANA ++ ++* Mon Mar 23 2009 Ondrej Vasik 2.8.1-2 ++- fix sources syntax, add sources URL (#226412) ++ ++* Thu Feb 26 2009 Ondrej Vasik 2.8.1-1 ++- do ship/generate /etc/{shadow,gshadow} files(#483251) ++- do ship default /etc/hosts with setup (#483244) ++- activate multi on (required for IPv6 only localhost ++ recognition out-of-the-box) (#486461) ++- added postun section for cleaning of dangerous .rpmnew ++ files after updates ++- make profile and bashrc more portable (ksh, #487419) ++ ++* Wed Feb 25 2009 Fedora Release Engineering - 2.7.7-5 ++- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild ++ ++* Mon Feb 02 2009 Ondrej Vasik 2.7.7-4 ++- drop scriptlet completely(audio/video group ++ temporarily created by packages which use it for ++ updates(#477769)) ++ ++* Fri Jan 30 2009 Ondrej Vasik 2.7.7-3 ++- add support for ctrl+arrow shortcut in rxvt(#474110) ++ ++* Thu Jan 29 2009 Ondrej Vasik 2.7.7-2 ++- reserve 87 gid for polkituser (just uid was reserved), ++ reserve 18 gid for dialout(to prevent conflicts with ++ polkituser gid) ++ ++* Thu Jan 22 2009 Ondrej Vasik 2.7.7-1 ++- synchronize /etc/services with latest IANA, do not use ++ tabs in that file to have consistent output ++- fix indentation in /etc/profile and /etc/bashrc ++ (#481074) ++- assign uid 36 for vdsm, gid 36 for kvm ++ (#346151,#481021) ++ ++* Tue Jan 20 2009 Ondrej Vasik 2.7.6-1 ++- make uidgid file better parsable (synchronize tabs) ++- reserve gid 11 for group cdrom (udev,MAKEDEV) ++- reserve gid 33 for group tape (udev,MAKEDEV) ++- reserve gid 87 for group dialout (udev,MAKEDEV) ++ ++* Tue Jan 06 2009 Ondrej Vasik 2.7.5-4 ++- use lua language in post to prevent additional ++ dependencies ++ ++* Thu Dec 18 2008 Ondrej Vasik 2.7.5-3 ++- add pkiuser (17:17) to uidgid ++- temporarily create video/audio group in post section ++ (#476886) ++ ++* Wed Dec 10 2008 Ondrej Vasik 2.7.5-2 ++- do not export PATH twice(#449286 NOTABUG revert) ++- do not export INPUTRC(to respect just created ~/.inputrc) ++ (#443717) ++ ++* Thu Nov 27 2008 Ondrej Vasik 2.7.5-1 ++- Modified upstream URL, synchronized with upstream git ++ ++* Wed Nov 19 2008 Ondrej Vasik 2.7.4-3 ++- update protocols to latest IANA list (2008-04-18) ++- update services to latest IANA list (2008-11-17) ++- mark /etc/protocols and /etc/inputrc %%config(noreplace) ++- added URL, fixed few rpmlint warnings ++- do own audio and video group (#458843), create it in default ++ /etc/group ++ ++* Tue Nov 18 2008 Ondrej Vasik 2.7.4-2 ++- again process profile.d scripts in noninteractive shells, ++ but do not display stderr/stdout messages(#457243) ++- fix wrong prompt for csh/tcsh (#443854) ++- don't show error message about missing hostname in profile ++ (#301481) ++- reserve rquotad port 875 in /etc/services (#455859) ++- export PATH after processing profile.d scripts (#449286) ++- assign gid's for audio (:63) and video (:39) group(#458843), ++ assign uidgid pair (52:52) for puppet (#471918) ++- fix /etc/services duplicities to pass serviceslint ++ ++* Thu Oct 09 2008 Phil Knirsch 2.7.4-1 ++- Include new serviceslint for speedup (#465642) ++- Cleaned up services due to newly discovered bugs in it with new serviceslint ++ ++* Wed Sep 03 2008 Phil Knirsch 2.7.3-1 ++- Added SBinSanity patch as an approved feature (#458176) ++ ++* Wed Aug 06 2008 Phil Knirsch 2.7.2-1 ++- Added uidgid pair for condor ++- Added uidgid pair for trousers ++ ++* Fri Jul 25 2008 Phil Knirsch 2.7.1-1 ++- Bump to 2.7.1 to avoid version problems with F-9 ++- Removed group news as well (#437462) ++ ++* Tue Jun 17 2008 Phil Knirsch 2.6.16-1 ++- Dropped user news from default /etc/passwd (#437462) ++ ++* Thu Jun 05 2008 Phil Knirsch 2.6.15-1 ++- Added prelude-manager and snortd to uidgid list ++ ++* Mon Apr 07 2008 Phil Knirsch 2.6.14-1 ++- Updated /etc/services to latest IANA version (#315571) ++ ++* Fri Apr 04 2008 Phil Knirsch ++- Fixed a problem with the new prompt for tcsh and screen terminal (#438550) ++ ++* Thu Mar 20 2008 Phil Knirsch 2.6.13-1 ++- Drop the wrong precmd for csh for xterm and screen terminals ++ ++* Tue Feb 26 2008 Phil Knirsch 2.6.12-1 ++- Corrected wrong /etc/profile.d behaviour for non-interactive bash and tcsh ++ ++* Fri Feb 22 2008 Phil Knirsch 2.6.11-1 ++- Fixed problem with /etc/profile.d/* and non-interactive tcsh (#299221) ++- Fixed xterm -title problem (#387581) ++- Fixed problem with /etc/profile.d/*.csh not being executed for none loginshells anymore ++ (#381631, #429838) ++- Corrected missing shell for news user in uidgid and passwd ++ ++* Thu Aug 16 2007 Phil Knirsch 2.6.10-1 ++- License review and update ++ ++* Tue Jul 24 2007 Phil Knirsch 2.6.9-1 ++- Assigned uid 87 for PolicyKit package (#244950) ++- Fixed precmd fix if TERM isn't set (#242732) ++ ++* Wed Jun 06 2007 Phil Knirsch 2.6.7-1 ++- Fixed precmd setting to behave like bash for (t)csh (#242732) ++ ++* Thu May 24 2007 Phil Knirsch 2.6.6-1 ++- Added another set of proposed changes to /etc/csh.cshrc (#199817) ++- Added missing documentation in /etc/hosts.[allow|deny] (#157053) ++ ++* Wed May 23 2007 Phil Knirsch 2.6.5-1 ++- Fixed tcsh behaviour for non login shells (#191233) ++- Fixed umask setting for tcsh to behave identical to bash logins (#199817) ++- Added ipv6-crypt and ipv6-auth for backwards compatibility (#210546) ++ ++* Wed Apr 18 2007 Phil Knirsch 2.6.4-1 ++- Modified the 111/[tcp/udp] entries to work with rpcbind (#236639) ++ ++* Mon Mar 12 2007 Phil Knirsch 2.6.3-1 ++- Changed winbind_auth to wbpriv by request of the samba maintainer ++ ++* Tue Dec 12 2006 Phil Knirsch 2.6.2-1.fc7 ++- Updated uidgid for split of pcap into arpwatcher and tcpdump. ++ ++* Tue Nov 28 2006 Phil Knirsch 2.6.1-1.fc7 ++- Update version and rebuilt ++ ++* Tue Nov 28 2006 Phil Knirsch 2.5.57-1 ++- Revert change for umask in /etc/bashrc (#217523) ++ ++* Thu Nov 16 2006 Phil Knirsch 2.5.56-1 ++- Added an entry for samba and winbind_auth ++ ++* Wed Oct 11 2006 Phil Knirsch 2.5.55-1 ++- Extended the protocols to include the missing hopopt (#209191) ++ ++* Tue Oct 10 2006 Phil Knirsch 2.5.54-1 ++- Update /etc/protocols to latest officiall IANA version (#209191) ++ ++* Thu Jul 27 2006 Phil Knirsch 2.5.53-1 ++- Added utempter gid for new libutempter package (#200240) ++ ++* Mon Jun 19 2006 Phil Knirsch 2.5.52-1 ++- Lock password for root account by default (#182206) ++ ++* Wed May 03 2006 Karsten Hopp ++- remove gkrellmd from the reserved uid/gid list (#186974) ++ ++* Tue Mar 21 2006 Florian La Roche 2.5.50-1 ++- use stricter umask of 022 for all logins ++ ++* Thu Feb 23 2006 Phil Knirsch 2.5.49-1 ++- Really switch to new /etc/services file ++- Added /etc/fstab and /etc/mtab to ownership of setup (#177061) ++ ++* Tue Jan 31 2006 Phil Knirsch 2.5.48-1 ++- Switched to the new large /etc/services file which fixes #112298, #133683, ++ #166443, #168872, #171228. ++- Fixed pathmunge problem with bashrc (#123621) ++- Removed /usr/X11R6/bin from default PATH (#173856) ++ ++* Tue Jan 24 2006 Phil Knirsch ++- Fixed bug with PROMPT_COMMAND being broken for wierd dirs (#142125) ++- Added hfsplus to know filesystems (#172820) ++ ++* Mon Oct 17 2005 Bill Nottingham ++- make motd noreplace (#170539) ++ ++* Tue Sep 6 2005 Bill Nottingham 2.5.47-1 ++- make lastlog 0644 (#167200) ++ ++* Mon Jun 20 2005 Bill Nottingham 2.5.46-1 ++- add buildrequires on bash, tcsh (#161016) ++- move core dump size setting from csh.login to csh.cshrc (#156914) ++ ++* Fri Jun 17 2005 Bill Nottingham 2.5.45-1 ++- ksh doesn't implement EUID/UID. Work around that. (#160731) ++ ++* Thu May 19 2005 Bill Nottingham 2.5.44-1 ++- fix csh.cshrc when -e is used (#158265) ++ ++* Mon Apr 25 2005 Bill Nottingham 2.5.43-1 ++- remove mailman aliases (#155841) ++ ++* Mon Apr 18 2005 Bill Nottingham 2.5.42-1 ++- fix lastlog conflict (#155256) ++ ++* Fri Apr 15 2005 Bill Nottingham 2.5.41-1 ++- get rid of 'id' error messages if there is no /usr (#142707) ++ ++* Mon Jan 31 2005 Bill Nottingham 2.5.40-1 ++- have similar prompt changes for su to root in tcsh as in bash (#143826) ++ ++* Tue Nov 23 2004 Bill Nottingham 2.5.39-1 ++- ghost lastlog (#139539) ++ ++* Thu Nov 18 2004 Bill Nottingham 2.5.38-1 ++- fix bash/tcsh coredump size inconsistency (#139821) ++ ++* Wed Oct 27 2004 Bill Nottingham 2.5.37-1 ++- fix inconsistency in profile.d handling (#136859, ) ++ ++* Fri Oct 8 2004 Bill Nottingham 2.5.36-1 ++- fix duplicate alias ++ ++* Tue Sep 28 2004 Bill Nottingham 2.5.35-1 ++- add /etc/environment ++ ++* Mon Sep 27 2004 Rik van Riel 2.5.34-2 ++- mark /etc/services config(noreplace) (#133683) ++ ++* Thu Sep 23 2004 Bill Nottingham 2.5.34-1 ++- add dict (#107807) ++- add cyrus services (#118832) ++- move delete-char binding for csh (#113682) ++- do the same path munging for csh as for bash (#57708) ++- add postfix aliases (#117661) ++- fix bashrc login shell check (#104491) ++- add odmr to services (#101098) ++- add distcc to services (#91535) ++- add xterm forware/backward word bindings (#80860) ++ ++* Mon May 24 2004 Bill Nottingham ++- make pathmunge available for profile.d scripts (#123621) ++ ++* Wed May 19 2004 Joe Orton 2.5.33-2 ++- add IANA Register Port for svn to /etc/services (#122863) ++ ++* Wed May 5 2004 Nalin Dahyabhai 2.5.33-1 ++- fix syntax error in csh.cshrc ++ ++* Tue May 4 2004 Bill Nottingham 2.5.32-1 ++- set MAIL in csh.cshrc (#115376) ++- fix inputrc check in csh.login (#115073) ++ ++* Mon Jan 26 2004 Bill Nottingham 2.5.31-1 ++- move /etc/aliases here ++ ++* Mon Dec 8 2003 Bill Nottingham 2.5.30-1 ++- remove stty `tput kbs` section (#91357) ++ ++* Tue Sep 2 2003 Bill Nottingham 2.5.27-1 ++- securetty should be noreplace (#103585) ++ ++* Fri Mar 14 2003 Bill Nottingham 2.5.26-1 ++- clean up some typos in /etc/services (#86129) ++ ++* Mon Feb 17 2003 Florian La Roche ++- add "console" to /etc/securetty for mainframe ++ ++* Mon Jan 20 2003 Nalin Dahyabhai 2.5.24-1 ++- allocate uid/gid for mgetty ++ ++* Thu Jan 9 2003 Dan Walsh 2.5.23-1 ++- added PXE to /etc/services ++ ++* Wed Jan 1 2003 Bill Nottingham 2.5.22-1 ++- remove bogus entries from inputrc (#80652) ++ ++* Fri Nov 29 2002 Tim Powers 2.5.21-1 ++- remove unpackaged files from the buildroot ++ ++* Thu Aug 29 2002 Bill Nottingham 2.5.20-1 ++- shopt -s checkwinsize everywhere ++ ++* Wed Aug 28 2002 Preston Brown 2.5.19-1 ++- fix bug #61129 (~ substitution) ++ ++* Wed Aug 15 2002 Jens Petersen 2.5.18-1 ++- bring back the screen case in /etc/bashrc, since /etc/screenrc no ++ longer sets defhstatus (#60596, #60597) ++ ++* Sun Aug 11 2002 Florian La Roche 2.5.17-1 ++- add "set mark-symlinked-directories on" to /etc/inputrc ++ ++* Mon Jul 22 2002 Phil Knirsch 2.5.16-2 ++- Added shopt -s checkwinsize to /etc/bashrc for xterm resizing ++ ++* Fri Jul 19 2002 Jens Petersen 2.5.16-1 ++- dont special case screen in /etc/bashrc, since it overrides the user's ++ screenrc title setting (#60596) ++ ++* Thu Jul 18 2002 Florian La Roche 2.5.14-1 ++- move home dir of "news" to /etc/news ++ ++* Tue May 28 2002 Nalin Dahyabhai 2.5.13-1 ++- allocate uid/gid for privilege-separated sshd ++ ++* Thu May 23 2002 Tim Powers 2.5.12-2 ++- automated rebuild ++ ++* Wed Apr 3 2002 Bill Nottingham 2.5.12-1 ++- fix misformatted comment in /etc/services, allocate uid/gid for ++ frontpage ++ ++* Thu Mar 28 2002 Bill Nottingham 2.5.11-1 ++- add newline in /etc/shells (#62271) ++ ++* Thu Mar 28 2002 Nalin Dahyabhai 2.5.10-1 ++- allocate uid for the vcsa user ++ ++* Tue Mar 12 2002 Bill Nottingham 2.5.9-1 ++- re-add ext3 to /etc/filesystems ++ ++* Mon Mar 11 2002 Bill Nottingham 2.5.8-1 ++- add nologin to /etc/shells (#53963) ++- fix some quoting issues (#59627) ++- fix screen status line (#60596) ++- fix path regexps (#59624) ++- move profile.d stuff to csh.cshrc (#59946) ++ ++* Fri Mar 8 2002 Nalin Dahyabhai ++- add bprd, bpdbm, bpjava-msvc, vnetd, bpcd, and vopied to /etc/services ++ ++* Tue Sep 25 2001 Nalin Dahyabhai ++- change rmtcfg to an alias for bvcontrol, which is a registered name ++ ++* Mon Sep 17 2001 Nalin Dahyabhai 2.5.7-1 ++- add entries to services (ipp, wnn4, and so on) ++- try to remove duplicates in services (remove nameserver as alias for domain, ++ and readnews as alias for netnews) ++ ++* Mon Aug 20 2001 Bill Nottingham ++- change FTP user's home dir to /var/ftp (#52091) ++- %%ghost /etc/shadow, /etc/gshadow ++ ++* Fri Aug 17 2001 Bill Nottingham ++- add /etc/shells to filelist (#51813) ++ ++* Mon Aug 13 2001 Bill Nottingham ++- put lock in /etc/group (#51654) ++ ++* Wed Aug 8 2001 Bill Nottingham ++- lock only needs to be a gid ++- don't set dspmbyte=euc here; do it in lang.csh, and only if necessary (#50318) ++ ++* Mon Aug 6 2001 Jeff Johnson ++- add lock.lock uid/gid 54 to own /var/lock directory. ++ ++* Thu Jul 19 2001 Bill Nottingham ++- add forward/backward-word mappings (#48783) ++- add pgpkeyserver port to /etc/services (#49407) ++ ++* Thu Jul 19 2001 Preston Brown ++- core files disabled by default. Developers can enable them. ++ ++* Fri Jul 13 2001 Bill Nottingham 2.5.1-1 ++- revert news user back to no shell (#48701) ++ ++* Tue Jul 10 2001 Bill Nottingham 2.5.0-1 ++- move profile.d parsing from csh.cshrc to csh.login (#47417) ++ ++* Sat Jul 7 2001 Nalin Dahyabhai 2.4.15-1 ++- reorder /etc/services to match comments again ++- protocol 118 is stp, not st ++- update URLs in /etc/protocols and /etc/services ++ ++* Thu Jul 5 2001 Preston Brown 2.4.14-1 ++- put */sbin in path if user ID is 0. ++ ++* Mon Jun 25 2001 Bill Nottingham ++- add an entry to /etc/services for ssh X11 forwarding (#44944) ++ ++* Wed Jun 13 2001 Bill Nottingham ++- take ttyS0 out of securetty on main tree ++ ++* Tue Jun 12 2001 Philip Copeland ++- added ttyS0 to securetty for serial console usage ++ ++* Tue Jun 12 2001 Bill Nottingham ++- add rndc to /etc/services (#40265) ++- test for read bit, not execute bit, for profile.d (#35714) ++ ++* Sun Jun 03 2001 Florian La Roche ++- add "canna" entry to /etc/services ++ ++* Mon May 21 2001 Bernhard Rosenkraenzer 2.4.10-1 ++- Fix bugs #24159 and #30634 again; whoever moved bashrc from bash ++ to setup used an old version. :(( ++ ++* Wed May 2 2001 Preston Brown 2.4.9-1 ++- bashrc moved here from bash package ++- set umask in bashrc, so it applies for ALL shells. ++ ++* Fri Apr 27 2001 Preston Brown 2.4.8-1 ++- /sbin/nologin for accounts that aren't "real." ++ ++* Sat Apr 7 2001 Preston Brown ++- revert control-arrow forward/backward word (broken) ++ ++* Tue Mar 27 2001 Preston Brown ++- fix japanese input with tcsh (#33211) ++ ++* Tue Mar 6 2001 Bill Nottingham ++- fix some weirdness with rxvt (#30799) ++ ++* Wed Feb 28 2001 Bill Nottingham ++- add SKK input method (#29759) ++ ++* Fri Feb 23 2001 Preston Brown ++ ++* Wed Feb 21 2001 Bill Nottingham ++- fix inputrc, Yet Again. (#28617) ++ ++* Thu Feb 15 2001 Bill Nottingham ++- add in uidgid file, put it in %%doc ++ ++* Wed Feb 7 2001 Adrian Havill ++- bindkey for delete in the case of tcsh ++ ++* Wed Feb 7 2001 Bill Nottingham ++- add some more stuff to /etc/services (#25396, patch from ++ ) ++ ++* Tue Feb 6 2001 Nalin Dahyabhai ++- add gii/tcp = 616 for gated ++ ++* Tue Jan 30 2001 Bill Nottingham ++- wrap some inputrc settings with tests for mode, term (#24117) ++ ++* Mon Jan 29 2001 Bill Nottingham ++- overhaul /etc/protocols (#18530) ++- add port 587 to /etc/services (#25001) ++- add corbaloc (#19581) ++- don't set /usr/X11R6/bin in $PATH if it's already set (#19968) ++ ++* Fri Dec 1 2000 Nalin Dahyabhai ++- Clean up /etc/services, separating registered numbers from unregistered ++ ("squatted") numbers, and adding some. ++ ++* Mon Nov 20 2000 Bernhard Rosenkraenzer ++- Add smtps (465/tcp) and submission (587/tcp) to /etc/services for TLS ++ support (postfix >= 20001030-2) ++ ++* Sun Aug 6 2000 Bill Nottingham ++- /var/log/lastlog is %%config(noreplace) (#15412) ++- some of the various %%verify changes (#14819) ++ ++* Thu Aug 3 2000 Nalin Dahyabhai ++- linuxconf should be 98, not 99 ++ ++* Tue Jul 25 2000 Bill Nottingham ++- fix some of the csh stuff (#14622) ++ ++* Sun Jul 23 2000 Nalin Dahyabhai ++- stop setting "multi on" in /etc/host.conf ++ ++* Wed Jul 12 2000 Prospector ++- automatic rebuild ++ ++* Tue Jun 27 2000 Bill Nottingham ++- add hfs filesystem ++ ++* Wed Jun 21 2000 Preston Brown ++- printcap is a noreplace file now ++ ++* Sun Jun 18 2000 Bill Nottingham ++- fix typo ++ ++* Tue Jun 13 2000 Nalin Dahyabhai ++- add linuxconf/tcp = 99 to /etc/services ++ ++* Sat Jun 10 2000 Bill Nottingham ++- add some stuff to /etc/services ++- tweak ulimit call again ++ ++* Tue Jun 6 2000 Bernhard Rosenkraenzer ++- homedir of ftp is now /var/ftp ++ ++* Sun May 14 2000 Nalin Dahyabhai ++- move profile.d logic in csh.login to csh.cshrc ++ ++* Tue Apr 18 2000 Nalin Dahyabhai ++- redirect ulimit -S -c to /dev/null to avoid clutter ++ ++* Thu Apr 13 2000 Bernhard Rosenkraenzer ++- s/ulimit -c/ulimit -S -c/ - bash 2.x adaption ++ ++* Mon Apr 03 2000 Nalin Dahyabhai ++- Add more of the kerberos-related services from IANA's registry and krb5 ++ ++* Wed Mar 29 2000 Bernhard Rosenkraenzer ++- Add 2.4'ish vc/* devices to securetty ++ ++* Thu Feb 17 2000 Preston Brown ++- add /etc/filesystems with sane defaults ++ ++* Wed Feb 16 2000 Bill Nottingham ++- don't set prompt in /etc/profile (it's done in /etc/bashrc) ++ ++* Fri Feb 5 2000 Bill Nottingham ++- yet more inputrc tweaks from Hans de Goede (hans@highrise.nl) ++ ++* Sun Jan 30 2000 Bill Nottingham ++- yet more inputrc tweaks from Hans de Goede (hans@highrise.nl) ++ ++* Sun Jan 23 2000 Bill Nottingham ++- fix mailq line. (#7140) ++ ++* Fri Jan 21 2000 Bill Nottingham ++- add ldap to /etc/services ++ ++* Tue Jan 18 2000 Bill Nottingham ++- kill HISTFILESIZE, it's broken ++ ++* Tue Jan 18 2000 Preston Brown ++- some inputrc tweaks ++ ++* Wed Jan 12 2000 Bill Nottingham ++- make some more stuff noreplace ++ ++* Fri Nov 19 1999 Bill Nottingham ++- fix mailq line. (#7140) ++ ++* Fri Oct 29 1999 Bill Nottingham ++- split csh.login into csh.login and csh.cshrc (#various) ++- fix pop service names (#6206) ++- fix ipv6 protocols entries (#6219) ++ ++* Thu Sep 2 1999 Jeff Johnson ++- rename /etc/csh.cshrc to /etc/csh.login (#2931). ++- (note: modified /etc/csh.cshrc should end up in /etc/csh.cshrc.rpmsave) ++ ++* Fri Aug 20 1999 Jeff Johnson ++- add defattr. ++- fix limit command in /etc/csh.cshrc (#4582). ++ ++* Thu Jul 8 1999 Bill Nottingham ++- move /etc/inputrc here. ++ ++* Mon Apr 19 1999 Bill Nottingham ++- always use /etc/inputrc ++ ++* Wed Mar 31 1999 Preston Brown ++- added alias pointing to imap from imap2 ++ ++* Tue Mar 23 1999 Preston Brown ++- updated protocols/services from debian to comply with more modern ++- IETF/RFC standards ++ ++* Sun Mar 21 1999 Cristian Gafton ++- auto rebuild in the new build environment (release 4) ++ ++* Thu Feb 18 1999 Jeff Johnson ++- unset variables used in /etc/csh.cshrc (#1212) ++ ++* Mon Jan 18 1999 Jeff Johnson ++- compile for Raw Hide. ++ ++* Tue Oct 13 1998 Cristian Gafton ++- fix the csh.cshrc re: ${PATH} undefined ++ ++* Mon Apr 27 1998 Prospector System ++- translations modified for de, fr, tr ++ ++* Fri Dec 05 1997 Erik Troan ++- /etc/profile uses $i, which needs to be unset ++ ++* Mon Nov 03 1997 Donnie Barnes ++- made /etc/passwd and /etc/group %%config(noreplace) ++ ++* Mon Oct 20 1997 Erik Troan ++- removed /etc/inetd.conf, /etc/rpc ++- flagged /etc/securetty as missingok ++- fixed buildroot stuff in spec file ++ ++* Thu Jul 31 1997 Erik Troan ++- made a noarch package ++ ++* Wed Apr 16 1997 Erik Troan ++- Don't verify md5sum, size, or timestamp of /var/log/lastlog, /etc/passwd, ++ or /etc/group. +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-passwd-remove-unused-default-users-and-groups.patch b/base/setup/centos/meta_patches/spec-passwd-remove-unused-default-users-and-groups.patch new file mode 100644 index 000000000..4e67a50a1 --- /dev/null +++ b/base/setup/centos/meta_patches/spec-passwd-remove-unused-default-users-and-groups.patch @@ -0,0 +1,33 @@ +From f882ce44d7e8574e9affc5e6471265029f9724ca Mon Sep 17 00:00:00 2001 +From: Michel Thebeau +Date: Thu, 21 Jul 2016 11:47:55 -0400 +Subject: [PATCH] spec: add patch to remove unused users and groups + +Signed-off-by: Michel Thebeau +--- + SPECS/setup.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 3debacf..89ff683 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -22,6 +22,7 @@ Patch4: setup-2.8.71-filesystems.patch + Patch5: setup-2.8.71-fullpath.patch + Patch6: tis-uid-gid.patch + Patch7: updating-gids-and-uids-to-support-upgrade-from-wrl.patch ++Patch8: passwd-remove-unused-default-users-and-groups.patch + + %description + The setup package contains a set of important system configuration and +@@ -37,6 +38,7 @@ setup files, such as passwd, group, and profile. + %patch5 -p1 + %patch6 -p1 + %patch7 -p1 ++%patch8 -p1 + + ./shadowconvert.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-remove-unused-default-groups.patch b/base/setup/centos/meta_patches/spec-remove-unused-default-groups.patch new file mode 100644 index 000000000..60998771a --- /dev/null +++ b/base/setup/centos/meta_patches/spec-remove-unused-default-groups.patch @@ -0,0 +1,42 @@ +From e882a5dfad4ad41a256ea3867e1a4c4a08df9a98 Mon Sep 17 00:00:00 2001 +From: Michel Thebeau +Date: Fri, 19 Aug 2016 09:28:43 -0400 +Subject: [PATCH] spec: add patch to remove unused groups + +Signed-off-by: Michel Thebeau +--- + SPECS/setup.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 6c18614..223bfd5 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -1,7 +1,7 @@ + Summary: A set of system configuration and setup files + Name: setup + Version: 2.8.71 +-Release: 8%{?dist} ++Release: 9%{?dist} + License: Public Domain + Group: System Environment/Base + URL: https://fedorahosted.org/setup/ +@@ -24,6 +24,7 @@ Patch6: tis-uid-gid.patch + Patch7: updating-gids-and-uids-to-support-upgrade-from-wrl.patch + Patch8: passwd-remove-unused-default-users-and-groups.patch + Patch9: snmpd-fm-user-group.patch ++Patch10: remove-unused-default-groups.patch + + %description + The setup package contains a set of important system configuration and +@@ -41,6 +42,7 @@ setup files, such as passwd, group, and profile. + %patch7 -p1 + %patch8 -p1 + %patch9 -p1 ++%patch10 -p1 + + ./shadowconvert.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/spec-set-custom-prompt.patch b/base/setup/centos/meta_patches/spec-set-custom-prompt.patch new file mode 100644 index 000000000..b66279409 --- /dev/null +++ b/base/setup/centos/meta_patches/spec-set-custom-prompt.patch @@ -0,0 +1,42 @@ +setup.spec: add custom shell login prompt + +A user can be set to use "sh" (which points to bash) as login prompt. +This makes the login shell to enter "POSIX" mode which will only +read/executes file /etc/profle and files in /etc/profiled.d. So create +custom login prompt in /etc/profiles.d + +--- + SPECS/setup.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 3f74b90..184670f 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -7,6 +7,7 @@ Group: System Environment/Base + URL: https://fedorahosted.org/setup/ + Source0: https://fedorahosted.org/releases/s/e/%{name}/%{name}-%{version}.tar.bz2 + Source1: motd ++Source2: prompt.sh + BuildArch: noarch + BuildRequires: bash tcsh perl + #require system release for saner dependency order +@@ -59,6 +60,7 @@ touch %{buildroot}/etc/fstab + touch %{buildroot}/etc/subuid + touch %{buildroot}/etc/subgid + install -m 644 %{SOURCE1} %{buildroot}/etc/ ++install -m 644 %{SOURCE2} %{buildroot}/etc/profile.d/prompt.sh + + # remove unpackaged files from the buildroot + rm -f %{buildroot}/etc/Makefile +@@ -113,6 +115,7 @@ end + %config(noreplace) /etc/csh.cshrc + %config(noreplace) /etc/motd + %dir /etc/profile.d ++/etc/profile.d/prompt.sh + %config(noreplace) %verify(not md5 size mtime) /etc/shells + %ghost %attr(0644,root,root) %verify(not md5 size mtime) /var/log/lastlog + %ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/fstab +-- +1.8.3.1 + diff --git a/base/setup/centos/meta_patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch b/base/setup/centos/meta_patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch new file mode 100644 index 000000000..c8eaf98a5 --- /dev/null +++ b/base/setup/centos/meta_patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch @@ -0,0 +1,32 @@ +From b4a83aefe522dc1674c4979436398661f3ae4572 Mon Sep 17 00:00:00 2001 +From: Bart Wensley +Date: Mon, 27 Jun 2016 12:28:36 -0400 +Subject: [PATCH 1/1] updating-gids-and-uids-to-support-upgrade-from-wrl.patch + +--- + SPECS/setup.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/setup.spec b/SPECS/setup.spec +index 184670f..3debacf 100644 +--- a/SPECS/setup.spec ++++ b/SPECS/setup.spec +@@ -21,6 +21,7 @@ Patch3: setup-2.8.71-uidgidchanges.patch + Patch4: setup-2.8.71-filesystems.patch + Patch5: setup-2.8.71-fullpath.patch + Patch6: tis-uid-gid.patch ++Patch7: updating-gids-and-uids-to-support-upgrade-from-wrl.patch + + %description + The setup package contains a set of important system configuration and +@@ -35,6 +36,7 @@ setup files, such as passwd, group, and profile. + %patch4 -p1 + %patch5 -p1 + %patch6 -p1 ++%patch7 -p1 + + ./shadowconvert.sh + +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/add-fm-user-to-snmpd-group.patch b/base/setup/centos/patches/add-fm-user-to-snmpd-group.patch new file mode 100644 index 000000000..ebcafea0a --- /dev/null +++ b/base/setup/centos/patches/add-fm-user-to-snmpd-group.patch @@ -0,0 +1,15 @@ +--- + group | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/group ++++ b/group +@@ -21,7 +21,7 @@ neutron:x:164:neutron + cinder:x:165:cinder + ceilometer:x:166:ceilometer + sysinv:x:168:sysinv +-snmpd:x:169:snmpd ++snmpd:x:169:snmpd,fm + heat:x:187:heat + nfv:x:172:nfv + fm:x:195:fm diff --git a/base/setup/centos/patches/add-ironic-uid-gid.patch b/base/setup/centos/patches/add-ironic-uid-gid.patch new file mode 100644 index 000000000..41bc40983 --- /dev/null +++ b/base/setup/centos/patches/add-ironic-uid-gid.patch @@ -0,0 +1,24 @@ +commit 51c505c59a1512c011fcda01d0583a2ddc6f3337 +Author: Shoaib Nasir +Date: Mon Sep 25 11:39:29 2017 -0400 + + add ironic group and passwd + +diff --git a/group b/group +index 7d0244f..9979b99 100644 +--- a/group ++++ b/group +@@ -27,3 +27,4 @@ nfv:x:172:nfv + fm:x:195:fm + libvirt:x:991:nova + magnum:x:1870:magnum ++ironic:x:1874:ironic +diff --git a/passwd b/passwd +index fce82e7..fb49ea3 100644 +--- a/passwd ++++ b/passwd +@@ -17,3 +17,4 @@ postgres:x:120:120:PostgreSQL Server:/var/lib/pgsql:/bin/sh + snmpd:x:169:169:net-snmp:/usr/share/snmp:/sbin/nologin + fm:x:195:195:fm-mgr:/var/lib/fm:/sbin/nologin + magnum:x:1870:1870:OpenStack Magnum Daemons:/var/lib/magnum:/sbin/nologin ++ironic:x:1874:1874:OpenStack Ironic Daemons:/var/lib/ironic:/sbin/nologin diff --git a/base/setup/centos/patches/add-magnum-uid-gid.patch b/base/setup/centos/patches/add-magnum-uid-gid.patch new file mode 100644 index 000000000..e3a2f4ed5 --- /dev/null +++ b/base/setup/centos/patches/add-magnum-uid-gid.patch @@ -0,0 +1,31 @@ +From b7fa16379bf880fb0fe5d36cd2dac9182176d433 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Thu, 3 Aug 2017 16:11:37 -0400 +Subject: [PATCH 1/1] Added magnum uid/gid to the group and passwd files + +--- + group | 1 + + passwd | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/group b/group +index 8924954..7d0244f 100644 +--- a/group ++++ b/group +@@ -26,3 +26,4 @@ heat:x:187:heat + nfv:x:172:nfv + fm:x:195:fm + libvirt:x:991:nova ++magnum:x:1870:magnum +diff --git a/passwd b/passwd +index 2fb16ee..fce82e7 100644 +--- a/passwd ++++ b/passwd +@@ -16,3 +16,4 @@ nfv:x:172:172:nfvi:/var/lib/nfv:/sbin/nologin + postgres:x:120:120:PostgreSQL Server:/var/lib/pgsql:/bin/sh + snmpd:x:169:169:net-snmp:/usr/share/snmp:/sbin/nologin + fm:x:195:195:fm-mgr:/var/lib/fm:/sbin/nologin ++magnum:x:1870:1870:OpenStack Magnum Daemons:/var/lib/magnum:/sbin/nologin +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/add-murano-uid-gid.patch b/base/setup/centos/patches/add-murano-uid-gid.patch new file mode 100644 index 000000000..81a5656ad --- /dev/null +++ b/base/setup/centos/patches/add-murano-uid-gid.patch @@ -0,0 +1,31 @@ +From daeb87a5c097ad17ccbb90c6f15b9042bb991b7a Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Mon, 8 Jan 2018 12:25:06 -0500 +Subject: [PATCH 1/1] Added murano uid/gid to the group and passwd files + +--- + group | 1 + + passwd | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/group b/group +index 9979b99..22fa91d 100644 +--- a/group ++++ b/group +@@ -28,3 +28,4 @@ fm:x:195:fm + libvirt:x:991:nova + magnum:x:1870:magnum + ironic:x:1874:ironic ++murano:x:105:murano +diff --git a/passwd b/passwd +index fb49ea3..dfb96b7 100644 +--- a/passwd ++++ b/passwd +@@ -18,3 +18,4 @@ snmpd:x:169:169:net-snmp:/usr/share/snmp:/sbin/nologin + fm:x:195:195:fm-mgr:/var/lib/fm:/sbin/nologin + magnum:x:1870:1870:OpenStack Magnum Daemons:/var/lib/magnum:/sbin/nologin + ironic:x:1874:1874:OpenStack Ironic Daemons:/var/lib/ironic:/sbin/nologin ++murano:x:105:105:OpenStack Murano Daemons:/home/murano:/sbin/nologin +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/passwd-remove-unused-default-users-and-groups.patch b/base/setup/centos/patches/passwd-remove-unused-default-users-and-groups.patch new file mode 100644 index 000000000..5bdecabb6 --- /dev/null +++ b/base/setup/centos/patches/passwd-remove-unused-default-users-and-groups.patch @@ -0,0 +1,66 @@ +From 737295c6ad990e8e248fef6b378198c3326b90ba Mon Sep 17 00:00:00 2001 +From: Michel Thebeau +Date: Thu, 11 Aug 2016 18:24:25 -0400 +Subject: [PATCH] passwd: remove unused default users and groups + +A customer request to remove unused users and groups. These are default +users/groups on centos which have no bearing on a Titanium Cloud cluster. + +Signed-off-by: Michel Thebeau +--- + group | 8 -------- + passwd | 8 -------- + 2 files changed, 16 deletions(-) + +diff --git a/group b/group +index c21e2de..87a03c1 100644 +--- a/group ++++ b/group +@@ -1,11 +1,7 @@ + root::0: +-bin::1: +-daemon::2: + sys::3: +-adm::4: + tty::5: + disk::6: +-lp::7: + mem::8: + kmem::9: + wheel::10: +@@ -14,12 +10,8 @@ mail::12: + man::15: + dialout::18: + floppy::19: +-games::20: + tape::30: +-video::39: +-ftp::50: + lock::54: +-audio::63: + nobody::99: + users::100: + postgres:x:120: +diff --git a/passwd b/passwd +index 548435f..46a3d52 100644 +--- a/passwd ++++ b/passwd +@@ -1,15 +1,7 @@ + root:*:0:0:root:/root:/bin/bash +-bin:*:1:1:bin:/bin:/sbin/nologin +-daemon:*:2:2:daemon:/sbin:/sbin/nologin +-adm:*:3:4:adm:/var/adm:/sbin/nologin +-lp:*:4:7:lp:/var/spool/lpd:/sbin/nologin + sync:*:5:0:sync:/sbin:/bin/sync + shutdown:*:6:0:shutdown:/sbin:/sbin/shutdown + halt:*:7:0:halt:/sbin:/sbin/halt +-mail:*:8:12:mail:/var/spool/mail:/sbin/nologin +-operator:*:11:0:operator:/root:/sbin/nologin +-games:*:12:100:games:/usr/games:/sbin/nologin +-ftp:*:14:50:FTP User:/var/ftp:/sbin/nologin + nobody:*:99:99:Nobody:/:/sbin/nologin + rabbitmq:x:121:121::/var/lib/rabbitmq:/bin/sh + nova:x:994:162::/var/lib/nova:/bin/false +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/remove-unused-default-groups.patch b/base/setup/centos/patches/remove-unused-default-groups.patch new file mode 100644 index 000000000..8337389db --- /dev/null +++ b/base/setup/centos/patches/remove-unused-default-groups.patch @@ -0,0 +1,35 @@ +From d79451c9a047313fb8da27007ea9d99435e05ff2 Mon Sep 17 00:00:00 2001 +From: Michel Thebeau +Date: Fri, 19 Aug 2016 09:21:44 -0400 +Subject: [PATCH] CGTS-4685: setup: remove unused default groups + +A customer request to remove unused users and groups. These are default +users/groups on centos which have no bearing on a Titanium Cloud cluster. + +Two additional groups are removed: mem, man + +Signed-off-by: Michel Thebeau +--- + group | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/group b/group +index 8794dde..0b93beb 100644 +--- a/group ++++ b/group +@@ -2,12 +2,10 @@ root::0: + sys::3: + tty::5: + disk::6: +-mem::8: + kmem::9: + wheel::10: + cdrom::11: + mail::12: +-man::15: + dialout::18: + floppy::19: + tape::30: +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/snmpd-fm-user-group.patch b/base/setup/centos/patches/snmpd-fm-user-group.patch new file mode 100644 index 000000000..a1ebc971d --- /dev/null +++ b/base/setup/centos/patches/snmpd-fm-user-group.patch @@ -0,0 +1,61 @@ +From 725f6245c1a45973731eb853e9e1b0d388295f92 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 12 Aug 2016 17:40:31 -0400 +Subject: [PATCH] US84147: Security: NON-OPENSTACK Processes: External services + must run as non-root + +Add new snmpd and fm users/groups so that those services may be run as +non-root. +--- + group | 2 ++ + passwd | 2 ++ + uidgid | 3 +++ + 3 files changed, 7 insertions(+) + +diff --git a/group b/group +index 87a03c1..8794dde 100644 +--- a/group ++++ b/group +@@ -23,6 +23,8 @@ neutron:x:164:neutron + cinder:x:165:cinder + ceilometer:x:166:ceilometer + sysinv:x:168:sysinv ++snmpd:x:169:snmpd + heat:x:187:heat + nfv:x:172:nfv ++fm:x:195:fm + libvirt:x:991:nova +diff --git a/passwd b/passwd +index 46a3d52..2fb16ee 100644 +--- a/passwd ++++ b/passwd +@@ -14,3 +14,5 @@ heat:x:992:187::/home/heat:/bin/sh + ceilometer:x:991:166::/home/ceilometer:/bin/sh + nfv:x:172:172:nfvi:/var/lib/nfv:/sbin/nologin + postgres:x:120:120:PostgreSQL Server:/var/lib/pgsql:/bin/sh ++snmpd:x:169:169:net-snmp:/usr/share/snmp:/sbin/nologin ++fm:x:195:195:fm-mgr:/var/lib/fm:/sbin/nologin +diff --git a/uidgid b/uidgid +index c6bbd4b..f779665 100644 +--- a/uidgid ++++ b/uidgid +@@ -134,6 +134,8 @@ quantum 164 164 /var/lib/quantum /sbin/nologin openstack-quantum + cinder 165 165 /var/lib/cinder /sbin/nologin openstack-cinder + ceilometer 166 166 /var/lib/ceilometer /sbin/nologin openstack-ceilometer + ceph 167 167 /var/lib/ceph /sbin/nologin ceph-common ++sysinv 168 168 /var/lib/sysinv /sbin/nologin sysinv ++snmpd 169 169 /usr/share/snmp /sbin/nologin net-snmp + avahi-autoipd 170 170 /var/lib/avahi-autoipd /sbin/nologin avahi + pulse 171 171 /var/run/pulse /sbin/nologin pulseaudio + rtkit 172 172 /proc /sbin/nologin rtkit +@@ -163,6 +165,7 @@ systemd-network 192 192 / /sbin/nologin systemd + systemd-resolve 193 193 / /sbin/nologin systemd + gnats ? ? ? ? gnats, gnats-db + listar ? ? ? ? listar ++fm 195 195 /var/lib/fm /sbin/nologin fm-mgr + nfsnobody 65534 65534 /var/lib/nfs /sbin/nologin nfs-utils + + # Note: nfsnobody is 4294967294 on 64-bit platforms (-2) +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/tis-uid-gid.patch b/base/setup/centos/patches/tis-uid-gid.patch new file mode 100644 index 000000000..b4284babe --- /dev/null +++ b/base/setup/centos/patches/tis-uid-gid.patch @@ -0,0 +1,50 @@ +From fcfa685f89f2dbabf8b73e64cb0941098269856e Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 25 Apr 2016 13:06:49 -0400 +Subject: [PATCH 1/1] WRS: Patch5: tis-uid-gid.patch + +--- + group | 11 +++++++++++ + passwd | 10 ++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/group b/group +index be01f5c..3a0560d 100644 +--- a/group ++++ b/group +@@ -22,3 +22,14 @@ lock::54: + audio::63: + nobody::99: + users::100: ++rabbitmq:x:121: ++glance:x:161:glance ++nova:x:162:nova ++keystone:x:163:keystone ++neutron:x:164:neutron ++cinder:x:165:cinder ++ceilometer:x:166:ceilometer ++sysinv:x:168:sysinv ++heat:x:187:heat ++nfv:x:172:nfv ++libvirt:x:991:nova +diff --git a/passwd b/passwd +index 6c6a8eb..3f28c4e 100644 +--- a/passwd ++++ b/passwd +@@ -11,3 +11,13 @@ operator:*:11:0:operator:/root:/sbin/nologin + games:*:12:100:games:/usr/games:/sbin/nologin + ftp:*:14:50:FTP User:/var/ftp:/sbin/nologin + nobody:*:99:99:Nobody:/:/sbin/nologin ++rabbitmq:x:121:121::/var/lib/rabbitmq:/bin/sh ++nova:x:994:992::/var/lib/nova:/bin/false ++keystone:x:993:991::/home/keystone:/bin/sh ++glance:x:161:161:OpenStack Glance Daemons:/opt/cgcs/glance:/sbin/nologin ++cinder:x:165:165:OpenStack Cinder Daemons:/var/lib/cinder:/sbin/nologin ++sysinv:x:168:168:sysinv Daemons:/var/lib/sysinv:/sbin/nologin ++neutron:x:164:164:OpenStack Neutron Daemons:/var/lib/neutron:/sbin/nologin ++heat:x:992:990::/home/heat:/bin/sh ++ceilometer:x:991:989::/home/ceilometer:/bin/sh ++nfv:x:172:172:nfvi:/var/lib/nfv:/sbin/nologin +-- +1.8.3.1 + diff --git a/base/setup/centos/patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch b/base/setup/centos/patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch new file mode 100644 index 000000000..a23524efa --- /dev/null +++ b/base/setup/centos/patches/updating-gids-and-uids-to-support-upgrade-from-wrl.patch @@ -0,0 +1,47 @@ +From c254a8d2bfdcd4509f84b34ca0d92068a2b28618 Mon Sep 17 00:00:00 2001 +From: Bart Wensley +Date: Wed, 29 Jun 2016 08:15:32 -0400 +Subject: [PATCH 1/1] updating gids and uids to support upgrade from wrl + +--- + group | 1 + + passwd | 9 +++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/group b/group +index 3a0560d..c21e2de 100644 +--- a/group ++++ b/group +@@ -22,6 +22,7 @@ lock::54: + audio::63: + nobody::99: + users::100: ++postgres:x:120: + rabbitmq:x:121: + glance:x:161:glance + nova:x:162:nova +diff --git a/passwd b/passwd +index 3f28c4e..548435f 100644 +--- a/passwd ++++ b/passwd +@@ -12,12 +12,13 @@ games:*:12:100:games:/usr/games:/sbin/nologin + ftp:*:14:50:FTP User:/var/ftp:/sbin/nologin + nobody:*:99:99:Nobody:/:/sbin/nologin + rabbitmq:x:121:121::/var/lib/rabbitmq:/bin/sh +-nova:x:994:992::/var/lib/nova:/bin/false +-keystone:x:993:991::/home/keystone:/bin/sh ++nova:x:994:162::/var/lib/nova:/bin/false ++keystone:x:993:163::/home/keystone:/bin/sh + glance:x:161:161:OpenStack Glance Daemons:/opt/cgcs/glance:/sbin/nologin + cinder:x:165:165:OpenStack Cinder Daemons:/var/lib/cinder:/sbin/nologin + sysinv:x:168:168:sysinv Daemons:/var/lib/sysinv:/sbin/nologin + neutron:x:164:164:OpenStack Neutron Daemons:/var/lib/neutron:/sbin/nologin +-heat:x:992:990::/home/heat:/bin/sh +-ceilometer:x:991:989::/home/ceilometer:/bin/sh ++heat:x:992:187::/home/heat:/bin/sh ++ceilometer:x:991:166::/home/ceilometer:/bin/sh + nfv:x:172:172:nfvi:/var/lib/nfv:/sbin/nologin ++postgres:x:120:120:PostgreSQL Server:/var/lib/pgsql:/bin/sh +-- +1.8.3.1 + diff --git a/base/setup/centos/srpm_path b/base/setup/centos/srpm_path new file mode 100644 index 000000000..62834bcaf --- /dev/null +++ b/base/setup/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/setup-2.8.71-7.el7.src.rpm diff --git a/base/setup/files/custom.sh b/base/setup/files/custom.sh new file mode 100644 index 000000000..d56f37717 --- /dev/null +++ b/base/setup/files/custom.sh @@ -0,0 +1 @@ +export TMOUT=900 \ No newline at end of file diff --git a/base/setup/files/motd b/base/setup/files/motd new file mode 100644 index 000000000..e2c1470e6 --- /dev/null +++ b/base/setup/files/motd @@ -0,0 +1,5 @@ + +WARNING: Unauthorized access to this system is forbidden and will be +prosecuted by law. By accessing this system, you agree that your +actions may be monitored if unauthorized usage is suspected. + diff --git a/base/setup/files/nsswitch.conf b/base/setup/files/nsswitch.conf new file mode 100644 index 000000000..549a44d4e --- /dev/null +++ b/base/setup/files/nsswitch.conf @@ -0,0 +1,66 @@ +# +# /etc/nsswitch.conf +# +# An example Name Service Switch config file. This file should be +# sorted with the most-used services at the beginning. +# +# The entry '[NOTFOUND=return]' means that the search for an +# entry should stop if the search in the previous entry turned +# up nothing. Note that if the search failed due to some other reason +# (like no NIS server responding) then the search continues with the +# next entry. +# +# Valid entries include: +# +# nisplus Use NIS+ (NIS version 3) +# nis Use NIS (NIS version 2), also called YP +# dns Use DNS (Domain Name Service) +# files Use the local files +# db Use the local database (.db) files +# compat Use NIS on compat mode +# hesiod Use Hesiod for user lookups +# [NOTFOUND=return] Stop searching if not found so far +# + +# To use db, put the "db" in front of "files" for entries you want to be +# looked up first in the databases +# +# Example: +#passwd: db files nisplus nis +#shadow: db files nisplus nis +#group: db files nisplus nis + +passwd: files ldap +shadow: files ldap +group: files ldap +initgroups: files + +#hosts: db files nisplus nis dns +hosts: files dns + +# Example - obey only what nisplus tells us... +#services: nisplus [NOTFOUND=return] files +#networks: nisplus [NOTFOUND=return] files +#protocols: nisplus [NOTFOUND=return] files +#rpc: nisplus [NOTFOUND=return] files +#ethers: nisplus [NOTFOUND=return] files +#netmasks: nisplus [NOTFOUND=return] files + +bootparams: nisplus [NOTFOUND=return] files + +ethers: files +netmasks: files +networks: files +protocols: files +rpc: files +services: files sss + +netgroup: nisplus sss + +publickey: nisplus + +automount: files nisplus +aliases: files nisplus + +sudoers: files + diff --git a/base/setup/files/prompt.sh b/base/setup/files/prompt.sh new file mode 100644 index 000000000..44869d392 --- /dev/null +++ b/base/setup/files/prompt.sh @@ -0,0 +1,4 @@ +if [ "$PS1" ]; then + PS1='\h:\w\$ ' +fi +export PS1 diff --git a/base/tis-extensions/PKG-INFO b/base/tis-extensions/PKG-INFO new file mode 100644 index 000000000..80d6c5154 --- /dev/null +++ b/base/tis-extensions/PKG-INFO @@ -0,0 +1,13 @@ +Metadata-Version: 1.1 +Name: tis-extensions +Version: 1.0 +Summary: TIS Extensions to thirdparty pkgs +Home-page: +Author: Windriver +Author-email: info@windriver.com +License: Apache-2.0 + +Description: TIS Extensions to thirdparty pkgs + + +Platform: UNKNOWN diff --git a/base/tis-extensions/centos/build_srpm.data b/base/tis-extensions/centos/build_srpm.data new file mode 100644 index 000000000..75f295c2e --- /dev/null +++ b/base/tis-extensions/centos/build_srpm.data @@ -0,0 +1,2 @@ +SRC_DIR="files" +TIS_PATCH_VER=2 diff --git a/base/tis-extensions/centos/tis-extensions.spec b/base/tis-extensions/centos/tis-extensions.spec new file mode 100644 index 000000000..179b77244 --- /dev/null +++ b/base/tis-extensions/centos/tis-extensions.spec @@ -0,0 +1,69 @@ +# +# The tis-extensions group of packages is intended to allow us to +# add files to "extend" thirdparty packages, such as by packaging +# custom systemd files into /etc/systemd to override the originals +# without modifying or rebuilding the thirdparty package. +# + +Name: tis-extensions +Version: 1.0 +Summary: TIS Extensions to thirdparty pkgs +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: Wind River +URL: unknown +Source0: %{name}-%{version}.tar.gz + +%define debug_package %{nil} + +Requires: systemd + +%description +TIS Extensions to thirdparty pkgs + +%package -n %{name}-controller +Summary: TIS Extensions to thirdparty pkg on controller +Group: base + +%description -n %{name}-controller +TIS Extensions to thirdparty pkgs on controller + +%define local_etc_systemd %{_sysconfdir}/systemd/system/ +%define local_etc_coredump %{_sysconfdir}/systemd/coredump.conf.d +%define local_etc_initd %{_sysconfdir}/init.d +%define local_etc_sysctl %{_sysconfdir}/sysctl.d +%define local_etc_modload %{_sysconfdir}/modules-load.d + +%prep +%setup + +%build + +%install +install -d -m 755 %{buildroot}%{local_etc_initd} +install -p -D -m 555 target %{buildroot}%{local_etc_initd}/target + +install -d -m 755 %{buildroot}%{local_etc_systemd} +install -p -D -m 444 target.service %{buildroot}%{local_etc_systemd}/target.service + +install -d -m 755 %{buildroot}%{local_etc_sysctl} +install -p -D -m 644 coredump-sysctl.conf %{buildroot}%{local_etc_sysctl}/50-coredump.conf + +install -d -m 755 %{buildroot}%{local_etc_coredump} +install -p -D -m 644 coredump.conf %{buildroot}%{local_etc_coredump}/coredump.conf + +install -d -m 755 %{buildroot}%{local_etc_modload} +install -p -D -m 644 modules-load-vfio.conf %{buildroot}%{local_etc_modload}/vfio.conf + +%files +%defattr(-,root,root,-) +%{local_etc_sysctl}/50-coredump.conf +%{local_etc_coredump}/coredump.conf +%{local_etc_modload}/vfio.conf +%doc LICENSE + +%files -n %{name}-controller +%defattr(-,root,root,-) +%{local_etc_initd}/target +%{local_etc_systemd}/target.service diff --git a/base/tis-extensions/files/LICENSE b/base/tis-extensions/files/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/base/tis-extensions/files/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/base/tis-extensions/files/coredump-sysctl.conf b/base/tis-extensions/files/coredump-sysctl.conf new file mode 100644 index 000000000..5a776f7a5 --- /dev/null +++ b/base/tis-extensions/files/coredump-sysctl.conf @@ -0,0 +1,4 @@ +# send coredumps to the systemd coredump utility. +kernel.core_pattern=|/usr/lib/systemd/systemd-coredump %p %u %g %s %t %e +kernel.core_pipe_limit = 4 +kernel.core_uses_pid = 1 diff --git a/base/tis-extensions/files/coredump.conf b/base/tis-extensions/files/coredump.conf new file mode 100644 index 000000000..3b966b28e --- /dev/null +++ b/base/tis-extensions/files/coredump.conf @@ -0,0 +1,8 @@ +[Coredump] +Storage=external +Compress=yes +#ProcessSizeMax=2G +#ExternalSizeMax=2G +#JournalSizeMax=767M +#MaxUse= +#KeepFree= diff --git a/base/tis-extensions/files/modules-load-vfio.conf b/base/tis-extensions/files/modules-load-vfio.conf new file mode 100644 index 000000000..7a497c56a --- /dev/null +++ b/base/tis-extensions/files/modules-load-vfio.conf @@ -0,0 +1 @@ +vfio diff --git a/base/tis-extensions/files/target b/base/tis-extensions/files/target new file mode 100644 index 000000000..259fa012b --- /dev/null +++ b/base/tis-extensions/files/target @@ -0,0 +1,290 @@ +#!/bin/bash +# +# Filename: /etc/init.d/target +# +# Bring up/down iscsi LIO target +# +######################################################################### +# + +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +DESC="target" +STATUS_FILE="/var/run/lio-target.running" + +CINDER_CONF_DIR="/opt/cgcs/cinder" +LIO_CONF_DIR="${CINDER_CONF_DIR}/iscsi-target" +LIO_CONF_FILE="${LIO_CONF_DIR}/saveconfig.json" +TGT_CONF_FILE="${CINDER_CONF_DIR}/data/tgt-initiators-15.12-upgrade.conf" +BASE_TARGET_DIR="/etc/target" + +# Tools +TARGETCLI="/usr/bin/targetcli" +RTSTOOL="/usr/bin/cinder-rtstool" +SM_QUERY="/usr/bin/sm-query" + +# This will log to /var/log/platform.log + +NAME=$(basename $0) + +function log () { + logger -p local1.info "${NAME}: $1" +} + +# Determine whether we are running on the active controller. +# Return value: 0 - controller is active, 1 - not active. + +is_active_controller () { + + # service drbd-cgcs - should be active before iscsi one + local SERVICE="drbd-cgcs" + local ACTIVE=$(${SM_QUERY} service ${SERVICE} | \ + grep enabled-active) + + if [ -z "${ACTIVE}" ] ; then + return 1 + else + return 0 + fi +} + + +# This is a function that migrates 15.12 TGT Target configuration +# to the LIO Target configuration file. The function is called only +# once on the first "swact" to the LIO controller after +# Software Upgrade. + +migrate_tgt () { + + log "Migrating 15.12 TGT iSCSI Target to LIO" + + # TGT configuration directory + TGT_CONF_DIR="/opt/cgcs/cinder/data/volumes" + + # Start the LIO target and enable it for configuration + /usr/bin/targetctl restore + + if [ $? -ne 0 ] ; then + log "ERROR: trying to start the LIO target" + return 1 + fi + + if [ ! -d ${TGT_CONF_DIR} ] ; then + # User does not have attached volumes + log "No volumes to migrate. Migration is done" + return 0 + fi + + if [ ! "$(ls -A ${TGT_CONF_DIR})" ] ; then + # Cinder volumes configuration is empty + log "No volumes to migrate. Migration is done" + return 0 + fi + + PORTAL_IP="" + + if [ -e /etc/hosts ] ; then + PORTAL_IP=$(grep controller-cinder /etc/hosts | awk '{print $1}') + fi + + # If no Portal IP is specified, use default IP address + if [ -z "${PORTAL_IP}" ] ; then + PORTAL_IP="0.0.0.0" + fi + + for volume in `find ${TGT_CONF_DIR} -name "volume-*"` + do + TARGET_NAME=$(grep -n target ${volume} | awk '{ print $2}' | \ + sed 's/>//') + DEVICE=$(grep -n backing-store ${volume} | awk '{print $3}') + + USERID=$(grep -n incominguser ${volume} | awk '{print $3}') + + PASSWORD=$(grep -n incominguser ${volume} | awk '{print $4}') + + INITIATOR=$(grep -n ${TARGET_NAME} ${TGT_CONF_FILE} | \ + awk '{ print $5 }') + + if [ ! "${TARGET_NAME}" -a "${DEVICE}" -a "${USERID}" -a \ + "${PASSWORD}" -a "${INITIATOR}" ] ; then + log "ERROR: volume ${TARGET_NAME} configuration is not complete" + continue + fi + # Add the volume to the LIO configuration + ${RTSTOOL} create ${DEVICE} ${TARGET_NAME} ${USERID} ${PASSWORD} \ + False -a${PORTAL_IP} -p3260 2>/dev/null + + if [ $? -ne 0 ] ; then + log "ERROR: Target creation failed for volume ${TARGET_NAME}" + continue + fi + + log "Created target ${TARGET_NAME}" + + ${RTSTOOL} add-initiator ${TARGET_NAME} ${USERID} ${PASSWORD} \ + ${INITIATOR} 2>/dev/null + + if [ $? -ne 0 ] ; then + log "ERROR: Add Initiator ${INITIATOR} failed for ${TARGET_NAME}" + continue + fi + log "Added Initiator ${INITIATOR} for ${TARGET_NAME}" + + # Create a lun mapping from 1 to 0. Why? Well 15.12 used tgt which + # uses lun 1 as the first volume, but lio uses lun 0. This mapping + # allows iscsi references created in the old tgt realm to continue + # to work. + ${TARGETCLI} "/iscsi/${TARGET_NAME}/tpg1/acls/${INITIATOR} create 1 0" + if [ $? -ne 0 ] ; then + log "ERROR: lun 1 mapping failed: Initiator ${INITIATOR} Target ${TARGET_NAME}" + else + log "Added lun 1 mapping: Initiator ${INITIATOR} Target ${TARGET_NAME}" + fi + done + + # Save and verify the new LIO configuration + ${RTSTOOL} save 2> /dev/null + + if [ $? -ne 0 ] ; then + log "ERROR: Cannot save LIO Target configuration" + return 1 + fi + + ${RTSTOOL} verify 2> /dev/null + + if [ $? -ne 0 ] ; then + log "ERROR: LIO Target verification failed" + return 1 + fi + + log "TGT to LIO migration is done" + return 0 +} + +start () { + + echo -n "Starting ${DESC}..." + + if ! is_active_controller ; then + echo "failed. Controller is not active." + exit 1 + fi + + if [ ! -L ${BASE_TARGET_DIR} ] ; then + rm -rf ${BASE_TARGET_DIR} + ln -s ${LIO_CONF_DIR} ${BASE_TARGET_DIR} + fi + + if [ ! -d ${LIO_CONF_DIR} ] ; then + # Create LIO configuration directory + mkdir -p ${LIO_CONF_DIR} && log "Created ${LIO_CONF_DIR}" + + # Create default LIO configuration file + ${TARGETCLI} saveconfig ${LIO_CONF_FILE} + fi + + if [ -e ${TGT_CONF_FILE} -a -s ${TGT_CONF_FILE} ] ; then + migrate_tgt + + if [ $? -ne 0 ] ; then + echo "tgt migration failed." + exit 1 + fi + mv -f ${TGT_CONF_FILE} ${TGT_CONF_FILE}.bak + else + + /usr/bin/targetctl restore + + if [ $? -ne 0 ] ; then + echo "failed." + exit 1 + fi + fi + + touch ${STATUS_FILE} + + echo "done." +} + +stop () { + + echo -n "Stopping ${DESC}..." + + if [ ! -f ${STATUS_FILE} ] ; then + echo "service has not been started" + exit 0 + fi + + /usr/bin/targetctl clear + + RET=$? + + if [ -f ${STATUS_FILE} ] ; then + rm -f ${STATUS_FILE} + fi + + if [ ${RET} -ne 0 ] ; then + echo "failed." + exit 1 + fi + + echo -n +} + +status() +{ + if [ ! -f ${STATUS_FILE} ] ; then + echo "${DESC} has not been started" + exit 3 + else + echo "${DESC} had been started" + fi +} + +restart () { + stop + start +} + +reload() +{ + if [ ! -f ${STATUS_FILE} ] ; then + echo "${DESC} has not been started" + exit 1 + fi + + /usr/bin/targetctl restore + + if [ $? -ne 0 ] ; then + echo "failed." + exit 1 + fi +} + +case "$1" in + start) + start + ;; + status) + status + ;; + stop|forcedstop) + stop + ;; + reload|force-reload) + reload + ;; + restart|try-restart) + restart + ;; + *) + echo $"Usage: $0 {start|status|stop|forcedstop|restart|try-restart|reload|force-reload}" + exit 1 + ;; +esac + +exit 0 diff --git a/base/tis-extensions/files/target.service b/base/tis-extensions/files/target.service new file mode 100644 index 000000000..7311e0c2e --- /dev/null +++ b/base/tis-extensions/files/target.service @@ -0,0 +1,14 @@ +[Unit] +Description=iscsi LIO target service +After=config.service + +[Service] +Type=oneshot +ExecStart=/etc/init.d/target +ExecStop= +ExecReload= +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/connectivity/dhcp/PKG-INFO b/connectivity/dhcp/PKG-INFO new file mode 100644 index 000000000..c27d5cf6a --- /dev/null +++ b/connectivity/dhcp/PKG-INFO @@ -0,0 +1,22 @@ +Metadata-Version: 1.1 +Name: dhcp +Version: 4.2.5 +Summary: Dynamic host configuration protocol software +Home-page: +Author: +Author-email: +License: ISC + +Description: +DHCP (Dynamic Host Configuration Protocol) is a protocol which allows +individual devices on an IP network to get their own network +configuration information (IP address, subnetmask, broadcast address, +etc.) from a DHCP server. The overall purpose of DHCP is to make it +easier to administer a large network. + +To use DHCP on your network, install a DHCP service (or relay agent), +and on clients run a DHCP client daemon. The dhcp package provides +the ISC DHCP service and relay agent. + + +Platform: UNKNOWN diff --git a/connectivity/dhcp/centos/build_srpm.data b/connectivity/dhcp/centos/build_srpm.data new file mode 100644 index 000000000..b24625715 --- /dev/null +++ b/connectivity/dhcp/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$FILES_BASE/*" +TIS_PATCH_VER=8 diff --git a/connectivity/dhcp/centos/files/dhclient-dhcp6-wrs-install-uuid.patch b/connectivity/dhcp/centos/files/dhclient-dhcp6-wrs-install-uuid.patch new file mode 100644 index 000000000..17bc4a286 --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-dhcp6-wrs-install-uuid.patch @@ -0,0 +1,41 @@ +From 70d970536ec4312be28c7c39b20fe90199c495e0 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:26 -0400 +Subject: [PATCH 6/7] WRS: Patch106: dhclient-dhcp6-wrs-install-uuid.patch + +--- + client/scripts/linux | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/client/scripts/linux b/client/scripts/linux +index ddf50e8..c4ab9a1 100755 +--- a/client/scripts/linux ++++ b/client/scripts/linux +@@ -77,15 +77,22 @@ exit_with_hooks() { + exit $exit_status + } + ++# Select wrs-install-uuid from ipv4 or ipv6 ++if [ -n "$new_dhcp6_wrs_install_uuid" ]; then ++ wrs_install_uuid=$new_dhcp6_wrs_install_uuid ++else ++ wrs_install_uuid=$new_wrs_install_uuid ++fi ++ + # Enforce wrs-install-uuid on management and infrastrucure interfaces + source /etc/platform/platform.conf +-if [ -n "$new_wrs_install_uuid" ]; then ++if [ -n "$wrs_install_uuid" ]; then + if [ "$nodetype" == "controller" ]; then + source /etc/build.info + file="/www/pages/feed/rel-$SW_VERSION/install_uuid" + INSTALL_UUID=$(cat "$file") + fi +- if [ "$INSTALL_UUID" != "$new_wrs_install_uuid" ]; then ++ if [ "$INSTALL_UUID" != "$wrs_install_uuid" ]; then + exit 1 + fi + elif [ "$interface" == "$management_interface" -o \ +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/files/dhclient-disable-NSUPDATE.patch b/connectivity/dhcp/centos/files/dhclient-disable-NSUPDATE.patch new file mode 100644 index 000000000..73764c791 --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-disable-NSUPDATE.patch @@ -0,0 +1,28 @@ +From 4b0c758337d28109ac49f69ac334b4bebf09a0af Mon Sep 17 00:00:00 2001 +From: Hung Pham +Date: Mon, 10 Jul 2017 13:15:39 -0400 +Subject: [PATCH 1/1] dhclient-disable-NSUPDATE + +--- + includes/site.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/includes/site.h b/includes/site.h +index 8ff2834..f7dde00 100644 +--- a/includes/site.h ++++ b/includes/site.h +@@ -115,7 +115,10 @@ + + /* Define this if you want DNS update functionality to be available. */ + +-#define NSUPDATE ++/* WRS: Comment out this define to disable the DDNS feature */ ++/* TiS doesn't use DDNS, and enabling DDNS will cause dhclient to listen on */ ++/* an extra port that may collide with MTCE */ ++/* #define NSUPDATE */ + + /* Define this if you want the dhcpd.pid file to go somewhere other than + the default (which varies from system to system, but is usually either +-- +1.8.3.1 + diff --git a/connectivity/dhcp/centos/files/dhclient-enter-hooks b/connectivity/dhcp/centos/files/dhclient-enter-hooks new file mode 100644 index 000000000..27388e9e6 --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-enter-hooks @@ -0,0 +1,32 @@ +#!/bin/bash +# +# /etc/dhclient-enter-hooks +# +# This file is sourced by /sbin/dhclient-script. +# + +# Select wrs-install-uuid from ipv4 or ipv6 +if [ -n "$new_dhcp6_wrs_install_uuid" ]; then + wrs_install_uuid=$new_dhcp6_wrs_install_uuid +else + wrs_install_uuid=$new_wrs_install_uuid +fi + +# Enforce wrs-install-uuid on management and infrastrucure interfaces +source /etc/platform/platform.conf +if [ -n "$wrs_install_uuid" ]; then + if [ "$nodetype" == "controller" ]; then + source /etc/build.info + file="/www/pages/feed/rel-$SW_VERSION/install_uuid" + INSTALL_UUID=$(cat "$file") + fi + if [ "$INSTALL_UUID" != "$wrs_install_uuid" ]; then + exit_status=1 + fi +elif [ "$interface" == "$management_interface" -o \ + "$interface" == "$infrastructure_interface" ]; then + if [ "$nodetype" != "controller" -o \ + -e "/etc/platform/.initial_config_complete" ]; then + exit_status=1 + fi +fi diff --git a/connectivity/dhcp/centos/files/dhclient-handle-wrs-install-uuid.patch b/connectivity/dhcp/centos/files/dhclient-handle-wrs-install-uuid.patch new file mode 100644 index 000000000..f9db9ac2f --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-handle-wrs-install-uuid.patch @@ -0,0 +1,42 @@ +From d6daacb050008d473b986f574434f9b8ae7139e4 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:23 -0400 +Subject: [PATCH 5/7] WRS: Patch105: dhclient-handle-wrs-install-uuid.patch + +--- + client/scripts/linux | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/client/scripts/linux b/client/scripts/linux +index 59e764f..ddf50e8 100755 +--- a/client/scripts/linux ++++ b/client/scripts/linux +@@ -77,6 +77,25 @@ exit_with_hooks() { + exit $exit_status + } + ++# Enforce wrs-install-uuid on management and infrastrucure interfaces ++source /etc/platform/platform.conf ++if [ -n "$new_wrs_install_uuid" ]; then ++ if [ "$nodetype" == "controller" ]; then ++ source /etc/build.info ++ file="/www/pages/feed/rel-$SW_VERSION/install_uuid" ++ INSTALL_UUID=$(cat "$file") ++ fi ++ if [ "$INSTALL_UUID" != "$new_wrs_install_uuid" ]; then ++ exit 1 ++ fi ++elif [ "$interface" == "$management_interface" -o \ ++ "$interface" == "$infrastructure_interface" ]; then ++ if [ "$nodetype" != "controller" -o \ ++ -e "/etc/platform/.initial_config_complete" ]; then ++ exit 1 ++ fi ++fi ++ + # Invoke the local dhcp client enter hooks, if they exist. + if [ -f /etc/dhclient-enter-hooks ]; then + exit_status=0 +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/files/dhclient-ipv6-bind-to-interface.patch b/connectivity/dhcp/centos/files/dhclient-ipv6-bind-to-interface.patch new file mode 100644 index 000000000..55c8c1e8d --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-ipv6-bind-to-interface.patch @@ -0,0 +1,48 @@ +From f1df67309b435da1d9e02b77100a793ba0165f04 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:18 -0400 +Subject: [PATCH 3/7] WRS: Patch103: dhclient-ipv6-bind-to-interface.patch + +--- + common/socket.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/common/socket.c b/common/socket.c +index f30c171..b236c4a 100644 +--- a/common/socket.c ++++ b/common/socket.c +@@ -236,6 +236,15 @@ if_register_socket(struct interface_info *info, int family, + } + #endif + ++#if defined(SO_BINDTODEVICE) ++ /* Bind this socket to this interface. */ ++ if ((!do_multicast || !*do_multicast) && info->ifp && ++ setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ++ (char *)(info -> ifp), sizeof(*(info -> ifp))) < 0) { ++ log_error("setsockopt: SO_BINDTODEVICE: %m"); ++ } ++#endif ++ + /* Bind the socket to this interface's IP address. */ + if (bind(sock, (struct sockaddr *)&name, name_len) < 0) { + log_error("Can't bind to dhcp address: %m"); +@@ -246,15 +255,6 @@ if_register_socket(struct interface_info *info, int family, + log_fatal("includes a bootp server."); + } + +-#if defined(SO_BINDTODEVICE) +- /* Bind this socket to this interface. */ +- if ((local_family != AF_INET6) && (info->ifp != NULL) && +- setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, +- (char *)(info -> ifp), sizeof(*(info -> ifp))) < 0) { +- log_fatal("setsockopt: SO_BINDTODEVICE: %m"); +- } +-#endif +- + /* IP_BROADCAST_IF instructs the kernel which interface to send + * IP packets whose destination address is 255.255.255.255. These + * will be treated as subnet broadcasts on the interface identified +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/files/dhclient-ipv6-conditionally-set-hostname.patch b/connectivity/dhcp/centos/files/dhclient-ipv6-conditionally-set-hostname.patch new file mode 100644 index 000000000..83464be99 --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-ipv6-conditionally-set-hostname.patch @@ -0,0 +1,37 @@ +From 04e5bef0d9bb0e1b3c8bbecccf11228ae809dfd2 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:21 -0400 +Subject: [PATCH 4/7] WRS: Patch104: + dhclient-ipv6-conditionally-set-hostname.patch + +--- + client/scripts/linux | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/client/scripts/linux b/client/scripts/linux +index 14655f0..59e764f 100755 +--- a/client/scripts/linux ++++ b/client/scripts/linux +@@ -254,6 +254,19 @@ if [ x$reason = xPREINIT6 ] ; then + exit_with_hooks 0 + fi + ++if [ x$reason = xBOUND6 ] || [ x$reason = xRENEW6 ] || \ ++ [ x$reason = xREBIND6 ] || [ x$reason = xREBOOT6 ]; then ++ current_hostname=`hostname` ++ if [ x$current_hostname = x ] || \ ++ [ x$current_hostname = "x(none)" ] || \ ++ [ x$current_hostname = xlocalhost ] || \ ++ [ x$current_hostname = x$old_fqdn_hostname ]; then ++ if [ x$new_fqdn_hostname != x$old_fqdn_hostname ]; then ++ hostname "$new_fqdn_hostname" ++ fi ++ fi ++fi ++ + if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then + echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix} + +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/files/dhclient-restrict-interfaces-to-command-line.patch b/connectivity/dhcp/centos/files/dhclient-restrict-interfaces-to-command-line.patch new file mode 100644 index 000000000..d880ac055 --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient-restrict-interfaces-to-command-line.patch @@ -0,0 +1,67 @@ +From 15b7057f9b9f2b232cf2f9f674c63140e903e379 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:15 -0400 +Subject: [PATCH 2/7] WRS: Patch102: + dhclient-restrict-interfaces-to-command-line.patch + +--- + client/clparse.c | 8 ++++++-- + client/dhclient.c | 3 +++ + includes/dhcpd.h | 1 + + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/client/clparse.c b/client/clparse.c +index b609caf..3ae632a 100644 +--- a/client/clparse.c ++++ b/client/clparse.c +@@ -943,8 +943,12 @@ void parse_interface_declaration (cfile, outer_config, name) + if (!client -> config) + make_client_config (client, outer_config); + +- ip -> flags &= ~INTERFACE_AUTOMATIC; +- interfaces_requested = 1; ++ if (restrict_interfaces != ISC_TRUE) { ++ ip -> flags &= ~INTERFACE_AUTOMATIC; ++ interfaces_requested = 1; ++ } else { ++ log_info("%s not in command line interfaces; ignoring", ip->name); ++ } + + token = next_token (&val, (unsigned *)0, cfile); + if (token != LBRACE) { +diff --git a/client/dhclient.c b/client/dhclient.c +index 0db4703..00b4240 100644 +--- a/client/dhclient.c ++++ b/client/dhclient.c +@@ -71,6 +71,7 @@ isc_boolean_t no_pid_file = ISC_FALSE; + int dhcp_max_agent_option_packet_length = 0; + + int interfaces_requested = 0; ++int restrict_interfaces = ISC_FALSE; + + struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } }; + struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } }; +@@ -240,6 +241,8 @@ main(int argc, char **argv) { + no_dhclient_pid = 1; + } else if (!strcmp(argv[i], "--no-pid")) { + no_pid_file = ISC_TRUE; ++ } else if (!strcmp(argv[i], "--restrict-interfaces")) { ++ restrict_interfaces = ISC_TRUE; + } else if (!strcmp(argv[i], "-cf")) { + if (++i == argc) + usage(); +diff --git a/includes/dhcpd.h b/includes/dhcpd.h +index 1d2bf2c..b1f16bf 100644 +--- a/includes/dhcpd.h ++++ b/includes/dhcpd.h +@@ -2703,6 +2703,7 @@ extern const char *path_dhclient_db; + extern const char *path_dhclient_pid; + extern char *path_dhclient_script; + extern int interfaces_requested; ++extern int restrict_interfaces; + extern struct data_string default_duid; + extern int duid_type; + +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/files/dhclient.conf b/connectivity/dhcp/centos/files/dhclient.conf new file mode 100644 index 000000000..6957e6abd --- /dev/null +++ b/connectivity/dhcp/centos/files/dhclient.conf @@ -0,0 +1,21 @@ +# Default dhclient.conf file +# +option wrs-install-uuid code 224 = string; +option dhcp6.wrs-install-uuid code 224 = string; +request subnet-mask, broadcast-address, time-offset, routers, + domain-name, domain-name-servers, host-name, + interface-mtu, fqdn, dhcp6.fqdn, wrs-install-uuid, + dhcp6.wrs-install-uuid, netbios-name-servers, netbios-scope, + dhcp6.domain-name-servers; + +timeout 30; + +#Changed for CGCS to improve Dead office recovery (DOR behavior) +# retry: every 30 seconds +retry 5; + +# By default, use a hardware address based client-id for both IPv4 and IPv6. +# We change this via puppet to ensure that interfaces that share the same MAC +# are not using the same client-id value. +send dhcp6.client-id = concat(00:03:00, hardware); +send dhcp-client-identifier = concat(00:03:00, hardware); diff --git a/connectivity/dhcp/centos/files/dhcp-handle-default-classless-static-route.patch b/connectivity/dhcp/centos/files/dhcp-handle-default-classless-static-route.patch new file mode 100644 index 000000000..6e8258c7d --- /dev/null +++ b/connectivity/dhcp/centos/files/dhcp-handle-default-classless-static-route.patch @@ -0,0 +1,63 @@ +Index: 4.2.5-P1-r3/dhclient-exit-hooks +=================================================================== +--- 4.2.5-P1-r3.orig/dhclient-exit-hooks ++++ 4.2.5-P1-r3/dhclient-exit-hooks +@@ -4,7 +4,7 @@ + # + # This file is sourced by /sbin/dhclient-script. + # +-# dhcp option 121 is defined in RFC3442. The following is the link. ++# dhcp option 121 is defined in RFC3442. The following is the link. + # http://www.ietf.org/rfc/rfc3442.txt + # + # The code for this option is 121, and its minimum length is 5 bytes. +@@ -52,7 +52,7 @@ function add_routes() { + while [ $# -ne 0 ]; do + mask=$1 + shift +- ++ + # Parse the arguments into a CIDR net/mask string + if [ $mask -eq 32 ]; then + destination="-host $1.$2.$3.$4" +@@ -66,22 +66,31 @@ while [ $# -ne 0 ]; do + elif [ $mask -gt 8 ]; then + destination="-net $1.$2.0.0/$mask" + shift; shift ++ elif [ $mask -gt 0 ]; then ++ destination="-net $1.0.0.0/$mask" ++ shift + else +- destination="-net $1.0.0.0/$mask" +- shift ++ destination="default" + fi +- ++ + # Read the gateway + gateway="$1.$2.$3.$4" + shift; shift; shift; shift + +- # Add route into routing table +- route add $destination gw $gateway +- +- # Print it out if the route is added successfully +- if [ $? = 0 ]; then +- echo "Added route \"$destination gw $gateway\"" ++ if [ $gateway != "0.0.0.0" ]; then ++ # Add route into routing table ++ route add $destination gw $gateway ++ if [ $? = 0 ]; then ++ echo "Added route \"$destination gw $gateway\"" ++ fi ++ else ++ # Add onlink route into routing table ++ route add $destination $interface ++ if [ $? = 0 ]; then ++ echo "Added route \"$destination on $interface\"" ++ fi + fi ++ + done + } + diff --git a/connectivity/dhcp/centos/files/site.h b/connectivity/dhcp/centos/files/site.h new file mode 100644 index 000000000..4c9392039 --- /dev/null +++ b/connectivity/dhcp/centos/files/site.h @@ -0,0 +1,28 @@ +/* + * define config file location in ${S}/includes/site.h + * still need to take care of installation path (${sysconfdir}/dhcpd.conf) + * + * 7/22/2010 - qhe + */ + +/* Define this if you want DNS update functionality to be available. */ + +/* Enabling the DNS update functionality results in the creation of + two UDP sockets with random high port numbers, but these numbers + appear to ignore the configured net.ipv4.ip_local_port_range values. + As a result, there's potential for collision with ports reserved + for platform services. + Given that this functionality is not being used, disable it from + the build. */ +#undef NSUPDATE + +/* Define this if you aren't debugging and you want to save memory + (potentially a _lot_ of memory) by allocating leases in chunks rather + than one at a time. */ + +#define COMPACT_LEASES + + +/* local */ +#define _PATH_DHCPD_CONF "/etc/dhcp/dhcpd.conf" +#define _PATH_DHCLIENT_CONF "/etc/dhcp/dhclient.conf" diff --git a/connectivity/dhcp/centos/files/support-disable-nsupdate.patch b/connectivity/dhcp/centos/files/support-disable-nsupdate.patch new file mode 100644 index 000000000..f42bc8888 --- /dev/null +++ b/connectivity/dhcp/centos/files/support-disable-nsupdate.patch @@ -0,0 +1,42 @@ +From 1a60b6e068a6f6289a48bd8281d116ed6a51f03e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:12 -0400 +Subject: [PATCH 1/7] WRS: Patch101: support-disable-nsupdate.patch + +--- + server/dhcpd.c | 2 ++ + server/failover.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/server/dhcpd.c b/server/dhcpd.c +index 67fec83..7523093 100644 +--- a/server/dhcpd.c ++++ b/server/dhcpd.c +@@ -504,8 +504,10 @@ main(int argc, char **argv) { + trace_srandom = trace_type_register ("random-seed", (void *)0, + trace_seed_input, + trace_seed_stop, MDL); ++#if defined (NSUPDATE) + trace_ddns_init(); + #endif ++#endif + + #if defined (PARANOIA) + /* get user and group info if those options were given */ +diff --git a/server/failover.c b/server/failover.c +index 8944102..d26adfa 100644 +--- a/server/failover.c ++++ b/server/failover.c +@@ -5232,7 +5232,9 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, + */ + if (msg->binding_status == FTS_ACTIVE && + (chaddr_changed || ident_changed)) { ++#if defined (NSUPDATE) + (void) ddns_removals(lease, NULL, NULL, ISC_FALSE); ++#endif + + if (lease->scope != NULL) + binding_scope_dereference(&lease->scope, MDL); +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/connectivity/dhcp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..0c7e019e7 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 80ec3fbb502373b48c54dc075d75b1d13894093e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 5/7] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/dhcp.spec +--- + SPECS/dhcp.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec +index edc4113..29dfbcf 100644 +--- a/SPECS/dhcp.spec ++++ b/SPECS/dhcp.spec +@@ -18,7 +18,7 @@ + Summary: Dynamic host configuration protocol software + Name: dhcp + Version: 4.2.5 +-Release: 58%{?dist} ++Release: 58.el7.centos%{?_tis_dist}.%{tis_patch_ver} + # NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to + # dcantrell maintaining the package) made incorrect use of the epoch and + # that's why it is at 12 now. It should have never been used, but it was. +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/PATCH_ORDER b/connectivity/dhcp/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..378deea32 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,7 @@ +spec-include-TiS-patches.patch +spec-dhcp-enter-hooks.patch +remove-unecessary-dhcp-exit-hooks-file.patch +dhclient-dhcp6-set-hostname.patch +0001-Update-package-versioning-for-TIS-format.patch +mark-dhclient.conf-as-config.patch +dhclient-disable-NSUPDATE.patch diff --git a/connectivity/dhcp/centos/meta_patches/dhclient-dhcp6-set-hostname.patch b/connectivity/dhcp/centos/meta_patches/dhclient-dhcp6-set-hostname.patch new file mode 100644 index 000000000..3a9b55039 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/dhclient-dhcp6-set-hostname.patch @@ -0,0 +1,38 @@ +From 93b0c27355df9fd944ad627413135c1da952c0a9 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 4/7] WRS: dhclient-dhcp6-set-hostname.patch + +--- + SOURCES/dhclient-script | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SOURCES/dhclient-script b/SOURCES/dhclient-script +index 9f725a0..e4dbc20 100644 +--- a/SOURCES/dhclient-script ++++ b/SOURCES/dhclient-script +@@ -598,6 +598,10 @@ dh6config() { + add_ipv6_addr_with_DAD + + make_resolv_conf ++ ++ if [ -n "${new_fqdn_hostname}" ] && need_hostname; then ++ hostname ${new_fqdn_hostname} || echo "See -nc option in dhclient(8) man page." ++ fi + ;; + + RENEW6|REBIND6) +@@ -615,6 +619,10 @@ dh6config() { + [ ! "${new_dhcp6_domain_search}" = "${old_dhcp6_domain_search}" ]; then + make_resolv_conf + fi ++ ++ if [ -n "${new_fqdn_hostname}" ] && need_hostname; then ++ hostname ${new_fqdn_hostname} || echo "See -nc option in dhclient(8) man page." ++ fi + ;; + + DEPREF6) +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/dhclient-disable-NSUPDATE.patch b/connectivity/dhcp/centos/meta_patches/dhclient-disable-NSUPDATE.patch new file mode 100644 index 000000000..19d81d374 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/dhclient-disable-NSUPDATE.patch @@ -0,0 +1,48 @@ +From 49fde785386db1dd3b13b1a3902c0b63aa7ff673 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 7/7] WRS: dhclient-disable-NSUPDATE.patch + +--- + SPECS/dhcp.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec +index 7301e63..92e7b30 100644 +--- a/SPECS/dhcp.spec ++++ b/SPECS/dhcp.spec +@@ -110,6 +110,7 @@ Patch103: dhclient-ipv6-bind-to-interface.patch + Patch104: dhclient-ipv6-conditionally-set-hostname.patch + Patch105: dhclient-handle-wrs-install-uuid.patch + Patch106: dhclient-dhcp6-wrs-install-uuid.patch ++Patch107: dhclient-disable-NSUPDATE.patch + + BuildRequires: autoconf + BuildRequires: automake +@@ -428,6 +429,7 @@ rm -rf includes/isc-dhcp + %patch104 -p1 + %patch105 -p1 + %patch106 -p1 ++%patch107 -p1 + + # Update paths in all man pages + for page in client/dhclient.conf.5 client/dhclient.leases.5 \ +@@ -449,6 +451,7 @@ done + #libtoolize --copy --force + autoreconf --verbose --force --install + ++# WR: failover and tracing need to be disabled in order to disable NSUPDATE + CFLAGS="%{optflags} -fno-strict-aliasing" \ + %configure \ + --with-srv-lease-file=%{_localstatedir}/lib/dhcpd/dhcpd.leases \ +@@ -463,6 +466,7 @@ CFLAGS="%{optflags} -fno-strict-aliasing" \ + --with-ldap \ + --with-ldapcrypto \ + --with-libbind=%{_includedir} --with-libbind-libs=%{_libdir} \ ++ --disable-tracing --disable-failover \ + --disable-static \ + %if %sdt + --enable-systemtap \ +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/mark-dhclient.conf-as-config.patch b/connectivity/dhcp/centos/meta_patches/mark-dhclient.conf-as-config.patch new file mode 100644 index 000000000..526228ea0 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/mark-dhclient.conf-as-config.patch @@ -0,0 +1,25 @@ +From 3fc59f7efbbc18c26261e7fc8b5a4383d874b76c Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 6/7] WRS: mark-dhclient.conf-as-config.patch + +--- + SPECS/dhcp.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec +index 29dfbcf..7301e63 100644 +--- a/SPECS/dhcp.spec ++++ b/SPECS/dhcp.spec +@@ -692,7 +692,7 @@ done + %attr(0644,root,root) %{_mandir}/man8/dhclient-script.8.gz + + # WRS +-%{dhcpconfdir}/dhclient.conf ++%config(noreplace) %{dhcpconfdir}/dhclient.conf + %{dhcpconfdir}/dhclient-enter-hooks + + %files common +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/remove-unecessary-dhcp-exit-hooks-file.patch b/connectivity/dhcp/centos/meta_patches/remove-unecessary-dhcp-exit-hooks-file.patch new file mode 100644 index 000000000..9b750692a --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/remove-unecessary-dhcp-exit-hooks-file.patch @@ -0,0 +1,43 @@ +From 01736403c13648dff7a02366ef994e157ee74970 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 3/7] WRS: remove-unecessary-dhcp-exit-hooks-file.patch + +--- + SPECS/dhcp.spec | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec +index 0150767..edc4113 100644 +--- a/SPECS/dhcp.spec ++++ b/SPECS/dhcp.spec +@@ -40,9 +40,9 @@ Source9: azure-cloud.sh + Source10: README.scripts + + # WRS +-Source20: dhclient-exit-hooks + Source21: dhclient.conf + Source22: dhclient-enter-hooks ++ + + Patch0: dhcp-4.2.0-errwarn-message.patch + Patch1: dhcp-4.2.4-dhclient-options.patch +@@ -573,7 +573,6 @@ EOF + find ${RPM_BUILD_ROOT}/%{_libdir} -name '*.la' -exec '/bin/rm' '-f' '{}' ';'; + + # WRS: Overwrite with our config +-%{__install} -p -m 0755 %{SOURCE20} %{buildroot}%{dhcpconfdir}/dhclient-exit-hooks + %{__install} -p -m 0644 %{SOURCE21} %{buildroot}%{dhcpconfdir}/dhclient.conf + %{__install} -p -m 0755 %{SOURCE22} %{buildroot}%{dhcpconfdir}/dhclient-enter-hooks + +@@ -693,7 +692,6 @@ done + %attr(0644,root,root) %{_mandir}/man8/dhclient-script.8.gz + + # WRS +-%{dhcpconfdir}/dhclient-exit-hooks + %{dhcpconfdir}/dhclient.conf + %{dhcpconfdir}/dhclient-enter-hooks + +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/spec-dhcp-enter-hooks.patch b/connectivity/dhcp/centos/meta_patches/spec-dhcp-enter-hooks.patch new file mode 100644 index 000000000..939c8a409 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/spec-dhcp-enter-hooks.patch @@ -0,0 +1,41 @@ +From 03b852ace37cc26df4462185f51b5eecef808ad2 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 2/7] WRS: spec-dhcp-enter-hooks.patch + +--- + SPECS/dhcp.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec +index 78ee924..0150767 100644 +--- a/SPECS/dhcp.spec ++++ b/SPECS/dhcp.spec +@@ -42,7 +42,7 @@ Source10: README.scripts + # WRS + Source20: dhclient-exit-hooks + Source21: dhclient.conf +- ++Source22: dhclient-enter-hooks + + Patch0: dhcp-4.2.0-errwarn-message.patch + Patch1: dhcp-4.2.4-dhclient-options.patch +@@ -575,6 +575,7 @@ find ${RPM_BUILD_ROOT}/%{_libdir} -name '*.la' -exec '/bin/rm' '-f' '{}' ';'; + # WRS: Overwrite with our config + %{__install} -p -m 0755 %{SOURCE20} %{buildroot}%{dhcpconfdir}/dhclient-exit-hooks + %{__install} -p -m 0644 %{SOURCE21} %{buildroot}%{dhcpconfdir}/dhclient.conf ++%{__install} -p -m 0755 %{SOURCE22} %{buildroot}%{dhcpconfdir}/dhclient-enter-hooks + + %pre + # /usr/share/doc/setup/uidgid +@@ -694,6 +696,7 @@ done + # WRS + %{dhcpconfdir}/dhclient-exit-hooks + %{dhcpconfdir}/dhclient.conf ++%{dhcpconfdir}/dhclient-enter-hooks + + %files common + %doc LICENSE README RELNOTES doc/References.txt +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/meta_patches/spec-include-TiS-patches.patch b/connectivity/dhcp/centos/meta_patches/spec-include-TiS-patches.patch new file mode 100644 index 000000000..1b725d650 --- /dev/null +++ b/connectivity/dhcp/centos/meta_patches/spec-include-TiS-patches.patch @@ -0,0 +1,79 @@ +From 68081498cde44d9b5320e795229865e46a1552ac Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:25:05 -0400 +Subject: [PATCH 1/7] WRS: spec-include-TiS-patches.patch + +--- + SPECS/dhcp.spec | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec +index 9647a5a..78ee924 100644 +--- a/SPECS/dhcp.spec ++++ b/SPECS/dhcp.spec +@@ -39,6 +39,10 @@ Source8: dhcrelay.service + Source9: azure-cloud.sh + Source10: README.scripts + ++# WRS ++Source20: dhclient-exit-hooks ++Source21: dhclient.conf ++ + + Patch0: dhcp-4.2.0-errwarn-message.patch + Patch1: dhcp-4.2.4-dhclient-options.patch +@@ -99,6 +103,14 @@ Patch62: dhcp-max-fd-value.patch + Patch63: dhcp-4.2.5-rh1355827.patch + Patch64: dhcp-4.2.5-centos-branding.patch + ++# WRS ++Patch101: support-disable-nsupdate.patch ++Patch102: dhclient-restrict-interfaces-to-command-line.patch ++Patch103: dhclient-ipv6-bind-to-interface.patch ++Patch104: dhclient-ipv6-conditionally-set-hostname.patch ++Patch105: dhclient-handle-wrs-install-uuid.patch ++Patch106: dhclient-dhcp6-wrs-install-uuid.patch ++ + BuildRequires: autoconf + BuildRequires: automake + BuildRequires: libtool +@@ -409,6 +421,14 @@ rm -rf includes/isc-dhcp + %patch63 -p1 + %patch64 -p1 + ++# WRS ++%patch101 -p1 ++%patch102 -p1 ++%patch103 -p1 ++%patch104 -p1 ++%patch105 -p1 ++%patch106 -p1 ++ + # Update paths in all man pages + for page in client/dhclient.conf.5 client/dhclient.leases.5 \ + client/dhclient-script.8 client/dhclient.8 ; do +@@ -552,6 +572,10 @@ EOF + # Don't package libtool *.la files + find ${RPM_BUILD_ROOT}/%{_libdir} -name '*.la' -exec '/bin/rm' '-f' '{}' ';'; + ++# WRS: Overwrite with our config ++%{__install} -p -m 0755 %{SOURCE20} %{buildroot}%{dhcpconfdir}/dhclient-exit-hooks ++%{__install} -p -m 0644 %{SOURCE21} %{buildroot}%{dhcpconfdir}/dhclient.conf ++ + %pre + # /usr/share/doc/setup/uidgid + %global gid_uid 177 +@@ -667,6 +691,10 @@ done + %attr(0644,root,root) %{_mandir}/man8/dhclient.8.gz + %attr(0644,root,root) %{_mandir}/man8/dhclient-script.8.gz + ++# WRS ++%{dhcpconfdir}/dhclient-exit-hooks ++%{dhcpconfdir}/dhclient.conf ++ + %files common + %doc LICENSE README RELNOTES doc/References.txt + %attr(0644,root,root) %{_mandir}/man5/dhcp-options.5.gz +-- +1.9.1 + diff --git a/connectivity/dhcp/centos/srpm_path b/connectivity/dhcp/centos/srpm_path new file mode 100644 index 000000000..46f6ca503 --- /dev/null +++ b/connectivity/dhcp/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/dhcp-4.2.5-58.el7.centos.src.rpm diff --git a/connectivity/nfs-utils/centos/build_srpm.data b/connectivity/nfs-utils/centos/build_srpm.data new file mode 100644 index 000000000..d6df555cd --- /dev/null +++ b/connectivity/nfs-utils/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=4 diff --git a/connectivity/nfs-utils/centos/meta_patches/0001-TiS-nfs-utils-spec-add-scripts.patch b/connectivity/nfs-utils/centos/meta_patches/0001-TiS-nfs-utils-spec-add-scripts.patch new file mode 100644 index 000000000..87205059f --- /dev/null +++ b/connectivity/nfs-utils/centos/meta_patches/0001-TiS-nfs-utils-spec-add-scripts.patch @@ -0,0 +1,96 @@ +From b7c902072f15c14507ab837f769b6adcf299f2ed Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:19:43 -0400 +Subject: [PATCH 1/4] WRS: 0001-TiS-nfs-utils-spec-add-scripts.patch + +Conflicts: + SPECS/nfs-utils.spec +--- + SPECS/nfs-utils.spec | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/SPECS/nfs-utils.spec b/SPECS/nfs-utils.spec +index a8d651a..583990d 100644 +--- a/SPECS/nfs-utils.spec ++++ b/SPECS/nfs-utils.spec +@@ -15,6 +15,10 @@ Source2: nfs.sysconfig + Source3: nfs-utils_env.sh + Source4: lockd.conf + Source5: 24-nfs-server.conf ++Source10: nfscommon ++Source11: nfsserver ++Source12: nfscommon.service ++Source13: nfsserver.service + + # + # RHEL7.1 +@@ -131,6 +135,10 @@ Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch + Patch102: nfs-utils-1.2.3-sm-notify-res_init.patch + Patch103: nfs-utils-1.2.5-idmap-errmsg.patch + ++# Titanium Cloud Patches ++Patch200: nfs-utils-support-mountprog-and-nfsprog-options.patch ++Patch201: nfs-utils-do-not-pass-CFLAGS-to-native.patch ++ + Group: System Environment/Daemons + Provides: exportfs = %{epoch}:%{version}-%{release} + Provides: nfsstat = %{epoch}:%{version}-%{release} +@@ -382,6 +390,11 @@ This package also contains the mount.nfs and umount.nfs program. + %patch102 -p1 + %patch103 -p1 + ++%patch200 -p1 ++# Titanium Cloud support mountprog and nfsprog options ++%patch201 -p1 ++# Titanium Cloud do not pass CFLAGS to native ++ + # Remove .orig files + find . -name "*.orig" | xargs rm -f + +@@ -443,6 +456,13 @@ install -m 755 %{SOURCE3} $RPM_BUILD_ROOT/usr/lib/systemd/scripts/nfs-utils_env. + install -m 644 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/lockd.conf + install -m 644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/gssproxy + ++mkdir -p $RPM_BUILD_ROOT/etc/init.d ++install -m 755 %{SOURCE10} $RPM_BUILD_ROOT/etc/init.d/nfscommon ++install -m 755 %{SOURCE11} $RPM_BUILD_ROOT/etc/init.d/nfsserver ++ ++install -m 644 %{SOURCE12} $RPM_BUILD_ROOT/%{_unitdir}/nfscommon.service ++install -m 644 %{SOURCE13} $RPM_BUILD_ROOT/%{_unitdir}/nfsserver.service ++ + # + # For backwards compatablity + # +@@ -521,6 +541,9 @@ if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl enable nfs-client.target >/dev/null 2>&1 || : + /bin/systemctl restart nfs-config >/dev/null 2>&1 || : ++ ++ /bin/systemctl enable nfscommon.service >/dev/null 2>&1 || : ++ /bin/systemctl enable nfsserver.service >/dev/null 2>&1 || : + fi + %systemd_post nfs-config + %systemd_post nfs-server +@@ -532,6 +555,9 @@ chown -R rpcuser:rpcuser /var/lib/nfs/statd + if [ $1 -eq 0 ]; then + %systemd_preun nfs-client.target + %systemd_preun nfs-server.server ++ ++ /bin/systemctl disable nfscommon.service >/dev/null 2>&1 || : ++ /bin/systemctl disable nfsserver.service >/dev/null 2>&1 || : + + /usr/sbin/userdel rpcuser 2>/dev/null || : + /usr/sbin/groupdel rpcuser 2>/dev/null || : +@@ -618,6 +644,9 @@ fi + %{_sbindir}/nfsdcltrack + %{_mandir}/*/* + %{_unitdir}/* ++%attr(755,root,root) /etc/init.d/nfscommon ++%attr(755,root,root) /etc/init.d/nfsserver ++ + %attr(755,root,root) /usr/lib/systemd/scripts/nfs-utils_env.sh + %{_prefix}/lib/systemd/system-generators/nfs-server-generator + +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/connectivity/nfs-utils/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..ca2174bb6 --- /dev/null +++ b/connectivity/nfs-utils/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,35 @@ +From c579b798af2fa3b5596bae14d506d1308e8766c6 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:19:43 -0400 +Subject: [PATCH 4/4] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/nfs-utils.spec +--- + SPECS/nfs-utils.spec | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/SPECS/nfs-utils.spec b/SPECS/nfs-utils.spec +index 8585c5d..029e2e3 100644 +--- a/SPECS/nfs-utils.spec ++++ b/SPECS/nfs-utils.spec +@@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser + Name: nfs-utils + URL: http://sourceforge.net/projects/nfs + Version: 1.3.0 +-Release: 0.48%{?dist} ++Release: 0.48.el7%{?_tis_dist}.%{tis_patch_ver} + Epoch: 1 + + # group all 32bit related archs +@@ -150,6 +150,7 @@ Provides: rpc.mountd = %{epoch}:%{version}-%{release} + Provides: rpc.nfsd = %{epoch}:%{version}-%{release} + Provides: rpc.statd = %{epoch}:%{version}-%{release} + Provides: rpc.gssd = %{epoch}:%{version}-%{release} ++Provides: rpc.svcgssd = %{epoch}:%{version}-%{release} + Provides: mount.nfs = %{epoch}:%{version}-%{release} + Provides: mount.nfs4 = %{epoch}:%{version}-%{release} + Provides: umount.nfs = %{epoch}:%{version}-%{release} +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/meta_patches/0001-add-rpm-4.14-compatibility.patch b/connectivity/nfs-utils/centos/meta_patches/0001-add-rpm-4.14-compatibility.patch new file mode 100644 index 000000000..b5bf8a0a2 --- /dev/null +++ b/connectivity/nfs-utils/centos/meta_patches/0001-add-rpm-4.14-compatibility.patch @@ -0,0 +1,20 @@ +diff --git a/SPECS/nfs-utils.spec b/SPECS/nfs-utils.spec +index d43ae40..e7011a2 100644 +--- a/SPECS/nfs-utils.spec ++++ b/SPECS/nfs-utils.spec +@@ -601,14 +601,7 @@ if [ -h /etc/systemd/system/multi-user.target.wants/nfs.target ]; then + fi + fi + +-%triggerun -- nfs-utils < 1:1.2.9-0.5 +-/bin/systemctl stop nfs-secure.service >/dev/null 2>&1 || : +-/bin/systemctl disable nfs-secure.service >/dev/null 2>&1 || : +- +-%triggerun -- nfs-utils < 1:1.2.4-2 +-/bin/systemctl enable nfs-lock.service >/dev/null 2>&1 || : +- +-%triggerin -- nfs-utils > 1:1.3.0-0.39 ++%triggerin -- nfs-utils + # reset configuration files and running daemons + if [ $1 -eq 2 ] ; then + /bin/systemctl enable nfs-client.target >/dev/null 2>&1 || : diff --git a/connectivity/nfs-utils/centos/meta_patches/0002-Add-nfs-utils-update-nfsmount.conf-with-required-con.patch b/connectivity/nfs-utils/centos/meta_patches/0002-Add-nfs-utils-update-nfsmount.conf-with-required-con.patch new file mode 100644 index 000000000..6792c3a1c --- /dev/null +++ b/connectivity/nfs-utils/centos/meta_patches/0002-Add-nfs-utils-update-nfsmount.conf-with-required-con.patch @@ -0,0 +1,33 @@ +From 5a65c9efbbfed7914e3cabc4c68fac87f2a16a1f Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:19:43 -0400 +Subject: [PATCH 2/4] WRS: + 0002-Add-nfs-utils-update-nfsmount.conf-with-required-con.patch + +--- + SPECS/nfs-utils.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/nfs-utils.spec b/SPECS/nfs-utils.spec +index 583990d..1fecdba 100644 +--- a/SPECS/nfs-utils.spec ++++ b/SPECS/nfs-utils.spec +@@ -138,6 +138,7 @@ Patch103: nfs-utils-1.2.5-idmap-errmsg.patch + # Titanium Cloud Patches + Patch200: nfs-utils-support-mountprog-and-nfsprog-options.patch + Patch201: nfs-utils-do-not-pass-CFLAGS-to-native.patch ++Patch202: nfs-utils-update-nfsmount.conf-with-required-config.patch + + Group: System Environment/Daemons + Provides: exportfs = %{epoch}:%{version}-%{release} +@@ -394,6 +395,7 @@ This package also contains the mount.nfs and umount.nfs program. + # Titanium Cloud support mountprog and nfsprog options + %patch201 -p1 + # Titanium Cloud do not pass CFLAGS to native ++%patch202 -p1 + + # Remove .orig files + find . -name "*.orig" | xargs rm -f +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/meta_patches/PATCH_ORDER b/connectivity/nfs-utils/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..82ac2d077 --- /dev/null +++ b/connectivity/nfs-utils/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,5 @@ +0001-TiS-nfs-utils-spec-add-scripts.patch +0002-Add-nfs-utils-update-nfsmount.conf-with-required-con.patch +nfs-utils-spec-file-disable-statd-service.patch +0001-Update-package-versioning-for-TIS-format.patch +0001-add-rpm-4.14-compatibility.patch diff --git a/connectivity/nfs-utils/centos/meta_patches/nfs-utils-spec-file-disable-statd-service.patch b/connectivity/nfs-utils/centos/meta_patches/nfs-utils-spec-file-disable-statd-service.patch new file mode 100644 index 000000000..841376faa --- /dev/null +++ b/connectivity/nfs-utils/centos/meta_patches/nfs-utils-spec-file-disable-statd-service.patch @@ -0,0 +1,52 @@ +From 15f61f1842d76dcf15e506b2b4f755cace7d4b29 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:19:43 -0400 +Subject: [PATCH 3/4] WRS: nfs-utils-spec-file-disable-statd-service.patch + +Conflicts: + SPECS/nfs-utils.spec +--- + SPECS/nfs-utils.spec | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/SPECS/nfs-utils.spec b/SPECS/nfs-utils.spec +index 1fecdba..8585c5d 100644 +--- a/SPECS/nfs-utils.spec ++++ b/SPECS/nfs-utils.spec +@@ -451,6 +451,10 @@ rm $RPM_BUILD_ROOT%{_sbindir}/rpc.svcgssd + rm $RPM_BUILD_ROOT%{_mandir}/man8/rpc.svcgssd.8 + rm $RPM_BUILD_ROOT%{_mandir}/man8/svcgssd.8 + ++# WRS - remove these service files as rpc-statd is started by nfscommon ++rm -f $RPM_BUILD_ROOT%{_unitdir}/rpc-statd.service ++rm -f $RPM_BUILD_ROOT%{_unitdir}/rpc-statd-notify.service ++ + mkdir -p $RPM_BUILD_ROOT/run/sysconfig + mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/scripts + mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/gssproxy +@@ -474,9 +478,6 @@ ln -s rpc-gssd.service nfs-secure.service + ln -s rpc-gssd.service rpcgssd.service + ln -s nfs-idmapd.service nfs-idmap.service + ln -s nfs-idmapd.service rpcidmapd.service +-ln -s rpc-statd.service nfs-lock.service +-ln -s rpc-statd.service nfslock.service +- + + mkdir -p $RPM_BUILD_ROOT%{_sharedstatedir}/nfs/rpc_pipefs + +@@ -541,6 +542,12 @@ fi + %post + if [ $1 -eq 1 ] ; then + # Initial installation ++ if [ -f %{_unitdir}/rpc-statd.service ] ; then ++ rm -f %{_unitdir}/rpc-statd.service ++ fi ++ if [ -f %{_unitdir}/rpc-statd-notify.service ] ; then ++ rm -f %{_unitdir}/rpc-statd-notify.service ++ fi + /bin/systemctl enable nfs-client.target >/dev/null 2>&1 || : + /bin/systemctl restart nfs-config >/dev/null 2>&1 || : + +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/patches/nfs-utils-do-not-pass-CFLAGS-to-native.patch b/connectivity/nfs-utils/centos/patches/nfs-utils-do-not-pass-CFLAGS-to-native.patch new file mode 100644 index 000000000..f3783d6b4 --- /dev/null +++ b/connectivity/nfs-utils/centos/patches/nfs-utils-do-not-pass-CFLAGS-to-native.patch @@ -0,0 +1,38 @@ +Do not pass CFLAGS to gcc while building native tool + +Do not pass CFLAGS/LDFLAGS to gcc while building native tool, The +needed flags has been passed by xxx_CFLAGS=$(CFLAGS_FOR_BUILD). +--- + tools/locktest/Makefile.am | 2 ++ + tools/rpcgen/Makefile.am | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/tools/locktest/Makefile.am b/tools/locktest/Makefile.am +index 3156815..1729fd1 100644 +--- a/tools/locktest/Makefile.am ++++ b/tools/locktest/Makefile.am +@@ -1,6 +1,8 @@ + ## Process this file with automake to produce Makefile.in + + CC=$(CC_FOR_BUILD) ++CFLAGS= ++LDFLAGS= + LIBTOOL = @LIBTOOL@ --tag=CC + + noinst_PROGRAMS = testlk +diff --git a/tools/rpcgen/Makefile.am b/tools/rpcgen/Makefile.am +index 8a9ec89..8bacdaa 100644 +--- a/tools/rpcgen/Makefile.am ++++ b/tools/rpcgen/Makefile.am +@@ -1,6 +1,8 @@ + ## Process this file with automake to produce Makefile.in + + CC=$(CC_FOR_BUILD) ++CFLAGS= ++LDFLAGS= + LIBTOOL = @LIBTOOL@ --tag=CC + + noinst_PROGRAMS = rpcgen +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/patches/nfs-utils-support-mountprog-and-nfsprog-options.patch b/connectivity/nfs-utils/centos/patches/nfs-utils-support-mountprog-and-nfsprog-options.patch new file mode 100644 index 000000000..0184b99b6 --- /dev/null +++ b/connectivity/nfs-utils/centos/patches/nfs-utils-support-mountprog-and-nfsprog-options.patch @@ -0,0 +1,46 @@ +From 10ecc386dc9e8aec697f782473b71fd6702e849c Mon Sep 17 00:00:00 2001 +From: Jackie Huang +Date: Mon, 15 Apr 2013 17:12:26 +0800 +Subject: [PATCH] nfs-utils: support mountprog and nfsprog options + +Add back the support for mountprog and nfsprog options since they +are supported by our kernel NFS client. + +Upstream-status: Inappropriate + +Signed-off-by: Jackie Huang +--- + utils/mount/stropts.c | 10 - + 1 file changed, 10 deletions(-) + +diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c +index 44a941f..e686577 100644 +--- a/utils/mount/stropts.c ++++ b/utils/mount/stropts.c +@@ -451,9 +451,6 @@ static int nfs_construct_new_options(struct mount_options *options, + char new_option[64]; + char *netid; + +- po_remove_all(options, "nfsprog"); +- po_remove_all(options, "mountprog"); +- + po_remove_all(options, "v2"); + po_remove_all(options, "v3"); + po_remove_all(options, "vers"); +@@ -563,13 +560,6 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options, int checkv4) + return 0; + } + +- /* +- * The kernel NFS client doesn't support changing the RPC +- * program number for these services, so force the value of +- * these fields before probing the server's ports. +- */ +- nfs_pmap.pm_prog = NFS_PROGRAM; +- mnt_pmap.pm_prog = MOUNTPROG; + + /* + * If the server's rpcbind service isn't available, we can't +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/patches/nfs-utils-update-nfsmount.conf-with-required-config.patch b/connectivity/nfs-utils/centos/patches/nfs-utils-update-nfsmount.conf-with-required-config.patch new file mode 100644 index 000000000..4cabd901c --- /dev/null +++ b/connectivity/nfs-utils/centos/patches/nfs-utils-update-nfsmount.conf-with-required-config.patch @@ -0,0 +1,166 @@ +From 80e40444247ddfb39efc9a9fa9b6168bd2b5623f Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 13 May 2016 16:34:47 -0400 +Subject: [PATCH 1/1] Update nfsmount.conf with required config + +--- + utils/mount/nfsmount.conf | 134 +++++----------------------------------------- + 1 file changed, 14 insertions(+), 120 deletions(-) + +diff --git a/utils/mount/nfsmount.conf b/utils/mount/nfsmount.conf +index 9b8ff4a..5f92d89 100644 +--- a/utils/mount/nfsmount.conf ++++ b/utils/mount/nfsmount.conf +@@ -1,135 +1,29 @@ + # + # /etc/nfsmount.conf - see nfsmount.conf(5) for details + # +-# This is an NFS mount configuration file. This file can be broken +-# up into three different sections: Mount, Server and Global +-# +-# [ MountPoint "Mount_point" ] +-# This section defines all the mount options that +-# should be used on a particular mount point. The '' +-# string need to be an exact match of the path in the mount +-# command. Example: +-# [ MountPoint "/export/home" ] +-# background=True +-# Would cause all mount to /export/home would be done in +-# the background +-# +-# [ Server "Server_Name" ] +-# This section defines all the mount options that +-# should be used on mounts to a particular NFS server. +-# Example: +-# [ Server "nfsserver.foo.com" ] +-# rsize=32k +-# wsize=32k +-# All reads and writes to the 'nfsserver.foo.com' server +-# will be done with 32k (32768 bytes) block sizes. +-# ++ + [ NFSMount_Global_Options ] +-# This statically named section defines global mount +-# options that can be applied on all NFS mount. +-# ++ + # Protocol Version [2,3,4] + # This defines the default protocol version which will + # be used to start the negotiation with the server. +-# Defaultvers=4 +-# ++Defaultvers=3 ++ + # Setting this option makes it mandatory the server supports the +-# given version. The mount will fail if the given version is +-# not support by the server. +-# Nfsvers=4 +-# ++# given version. The mount will fail if the given version is ++# not support by the server. ++Nfsvers=3 ++ + # Network Protocol [udp,tcp,rdma] (Note: values are case sensitive) + # This defines the default network protocol which will + # be used to start the negotiation with the server. +-# Defaultproto=tcp +-# ++Defaultproto=udp ++ + # Setting this option makes it mandatory the server supports the + # given network protocol. The mount will fail if the given network + # protocol is not supported by the server. +-# Proto=tcp +-# +-# The number of times a request will be retired before +-# generating a timeout +-# Retrans=2 +-# +-# The number of minutes that will retry mount +-# Retry=2 +-# +-# The minimum time (in seconds) file attributes are cached +-# acregmin=30 +-# +-# The Maximum time (in seconds) file attributes are cached +-# acregmin=60 +-# +-# The minimum time (in seconds) directory attributes are cached +-# acregmin=30 +-# +-# The Maximum time (in seconds) directory attributes are cached +-# acregmin=60 +-# +-# Enable Access Control Lists +-# Acl=False +-# +-# Enable Attribute Caching +-# Ac=True +-# +-# Do mounts in background (i.e. asynchronously) +-# Background=False +-# +-# Close-To-Open cache coherence +-# Cto=True +-# +-# Do mounts in foreground (i.e. synchronously) +-# Foreground=True +-# +-# How to handle times out from servers (Hard is STRONGLY suggested) +-# Hard=True +-# Soft=False +-# +-# Enable File Locking +-# Lock=True +-# +-# Enable READDIRPLUS on NFS version 3 mounts +-# Rdirplus=True +-# +-# Maximum Read Size (in Bytes) +-# Rsize=8k +-# +-# Maximum Write Size (in Bytes) +-# Wsize=8k +-# +-# Maximum Server Block Size (in Bytes) +-# Bsize=8k +-# +-# Ignore unknown mount options +-# Sloppy=False +-# +-# Share Data and Attribute Caches +-# Sharecache=True +-# +-# The amount of time, in tenths of a seconds, the client +-# will wait for a response from the server before retransmitting +-# the request. +-# Timeo=600 +-# +-# Sets all attributes times to the same time (in seconds) +-# actimeo=30 +-# +-# Server Mountd port mountport +-# mountport=4001 +-# ++Proto=udp ++ + # Server Mountd Protocol +-# mountproto=tcp +-# +-# Server Mountd Version +-# mounvers=3 +-# +-# Server Mountd Host +-# mounthost=hostname +-# +-# Server Port +-# Port=2049 +-# +-# RPCGSS security flavors +-# [none, sys, krb5, krb5i, krb5p ] +-# Sec=sys ++# mountproto=udp ++ +-- +1.9.1 + diff --git a/connectivity/nfs-utils/centos/srpm_path b/connectivity/nfs-utils/centos/srpm_path new file mode 100644 index 000000000..257b34aff --- /dev/null +++ b/connectivity/nfs-utils/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/nfs-utils-1.3.0-0.48.el7.src.rpm diff --git a/connectivity/nfs-utils/files/nfs-mountd.service b/connectivity/nfs-utils/files/nfs-mountd.service new file mode 100644 index 000000000..613ddc003 --- /dev/null +++ b/connectivity/nfs-utils/files/nfs-mountd.service @@ -0,0 +1,11 @@ +[Unit] +Description=NFS Mount Daemon +After=rpcbind.service nfs-server.service +Requires=rpcbind.service nfs-server.service + +[Service] +EnvironmentFile=-@SYSCONFDIR@/nfs-utils.conf +ExecStart=@SBINDIR@/rpc.mountd -F $MOUNTD_OPTS + +[Install] +WantedBy=multi-user.target diff --git a/connectivity/nfs-utils/files/nfs-server.service b/connectivity/nfs-utils/files/nfs-server.service new file mode 100644 index 000000000..147d7a7b5 --- /dev/null +++ b/connectivity/nfs-utils/files/nfs-server.service @@ -0,0 +1,18 @@ +[Unit] +Description=NFS Server +Requires=rpcbind.service nfs-mountd.service +After=rpcbind.service + +[Service] +Type=oneshot +EnvironmentFile=-@SYSCONFDIR@/nfs-utils.conf +ExecStartPre=@SBINDIR@/exportfs -r +ExecStart=@SBINDIR@/rpc.nfsd $NFSD_OPTS $NFSD_COUNT +ExecStop=@SBINDIR@/rpc.nfsd 0 +ExecStopPost=@SBINDIR@/exportfs -f +ExecReload=@SBINDIR@/exportfs -r +StandardError=syslog +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/connectivity/nfs-utils/files/nfs-statd.service b/connectivity/nfs-utils/files/nfs-statd.service new file mode 100644 index 000000000..746dacf05 --- /dev/null +++ b/connectivity/nfs-utils/files/nfs-statd.service @@ -0,0 +1,12 @@ +[Unit] +Description=NFS file locking service +After=rpcbind.service +Requires=rpcbind.service +Before=remote-fs-pre.target + +[Service] +EnvironmentFile=-@SYSCONFDIR@/nfs-utils.conf +ExecStart=@SBINDIR@/rpc.statd -F $STATD_OPTS + +[Install] +WantedBy=multi-user.target diff --git a/connectivity/nfs-utils/files/nfs-utils-do-not-pass-CFLAGS-to-native.patch b/connectivity/nfs-utils/files/nfs-utils-do-not-pass-CFLAGS-to-native.patch new file mode 100644 index 000000000..f7594e3ee --- /dev/null +++ b/connectivity/nfs-utils/files/nfs-utils-do-not-pass-CFLAGS-to-native.patch @@ -0,0 +1,36 @@ +Do not pass CFLAGS to gcc while building native tool + +Do not pass CFLAGS/LDFLAGS to gcc while building native tool, The +needed flags has been passed by xxx_CFLAGS=$(CFLAGS_FOR_BUILD). +--- + tools/locktest/Makefile.am | 2 ++ + tools/rpcdebug/Makefile.am | 2 ++ + tools/rpcgen/Makefile.am | 2 ++ + 3 files changed, 6 insertions(+), 0 deletions(-) + +Index: nfs-utils-1.2.8/tools/locktest/Makefile.am +=================================================================== +--- nfs-utils-1.2.8.orig/tools/locktest/Makefile.am ++++ nfs-utils-1.2.8/tools/locktest/Makefile.am +@@ -1,6 +1,8 @@ + ## Process this file with automake to produce Makefile.in + + CC=$(CC_FOR_BUILD) ++CFLAGS= ++LDFLAGS= + LIBTOOL = @LIBTOOL@ --tag=CC + + noinst_PROGRAMS = testlk +Index: nfs-utils-1.2.8/tools/rpcgen/Makefile.am +=================================================================== +--- nfs-utils-1.2.8.orig/tools/rpcgen/Makefile.am ++++ nfs-utils-1.2.8/tools/rpcgen/Makefile.am +@@ -1,6 +1,8 @@ + ## Process this file with automake to produce Makefile.in + + CC=$(CC_FOR_BUILD) ++CFLAGS= ++LDFLAGS= + LIBTOOL = @LIBTOOL@ --tag=CC + + noinst_PROGRAMS = rpcgen diff --git a/connectivity/nfs-utils/files/nfs-utils-support-mountprog-and-nfsprog-options.patch b/connectivity/nfs-utils/files/nfs-utils-support-mountprog-and-nfsprog-options.patch new file mode 100644 index 000000000..54b29bd6e --- /dev/null +++ b/connectivity/nfs-utils/files/nfs-utils-support-mountprog-and-nfsprog-options.patch @@ -0,0 +1,46 @@ +From 10ecc386dc9e8aec697f782473b71fd6702e849c Mon Sep 17 00:00:00 2001 +From: Jackie Huang +Date: Mon, 15 Apr 2013 17:12:26 +0800 +Subject: [PATCH] nfs-utils: support mountprog and nfsprog options + +Add back the support for mountprog and nfsprog options since they +are supported by our kernel NFS client. + +Upstream-status: Inappropriate + +Signed-off-by: Jackie Huang +--- + utils/mount/stropts.c | 10 ---------- + 1 files changed, 0 insertions(+), 10 deletions(-) + +diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c +index 50a1a2a..e14a68a 100644 +--- a/utils/mount/stropts.c ++++ b/utils/mount/stropts.c +@@ -444,9 +444,6 @@ static int nfs_construct_new_options(struct mount_options *options, + char new_option[64]; + char *netid; + +- po_remove_all(options, "nfsprog"); +- po_remove_all(options, "mountprog"); +- + po_remove_all(options, "v2"); + po_remove_all(options, "v3"); + po_remove_all(options, "vers"); +@@ -552,13 +549,6 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options) + return 0; + } + +- /* +- * The kernel NFS client doesn't support changing the RPC +- * program number for these services, so force the value of +- * these fields before probing the server's ports. +- */ +- nfs_pmap.pm_prog = NFS_PROGRAM; +- mnt_pmap.pm_prog = MOUNTPROG; + + /* + * If the server's rpcbind service isn't available, we can't +-- +1.7.4.1 + diff --git a/connectivity/nfs-utils/files/nfs-utils.conf b/connectivity/nfs-utils/files/nfs-utils.conf new file mode 100644 index 000000000..a1007a7fb --- /dev/null +++ b/connectivity/nfs-utils/files/nfs-utils.conf @@ -0,0 +1,35 @@ +# Parameters to be passed to nfs-utils (clients & server) service files. +# + +# Options to pass to rpc.nfsd. +NFSD_OPTS="" + +# Number of servers to start up; the default is 8 servers. +NFSD_COUNT="" + +# Where to mount nfsd filesystem; the default is "/proc/fs/nfsd". +PROCNFSD_MOUNTPOINT="" + +# Options used to mount nfsd filesystem; the default is "rw,nodev,noexec,nosuid". +PROCNFSD_MOUNTOPTS="" + +# Options for rpc.mountd. +# If you have a port-based firewall, you might want to set up +# a fixed port here using the --port option. +MOUNTD_OPTS="" + +# Parameters to be passed to nfs-common (nfs clients & server) init script. +# + +# If you do not set values for the NEED_ options, they will be attempted +# autodetected; this should be sufficient for most people. Valid alternatives +# for the NEED_ options are "yes" and "no". + +# Do you want to start the statd daemon? It is not needed for NFSv4. +NEED_STATD="" + +# Options to pass to rpc.statd. +# N.B. statd normally runs on both client and server, and run-time +# options should be specified accordingly. +# STATD_OPTS="-p 32765 -o 32766" +STATD_OPTS="" diff --git a/connectivity/nfs-utils/files/nfscommon b/connectivity/nfs-utils/files/nfscommon new file mode 100644 index 000000000..c5f320766 --- /dev/null +++ b/connectivity/nfs-utils/files/nfscommon @@ -0,0 +1,147 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: nfs-common +# Required-Start: $portmap hwclock +# Required-Stop: $portmap hwclock +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: NFS support for both client and server +# Description: NFS is a popular protocol for file sharing across +# TCP/IP networks. This service provides various +# support functions for NFS mounts. +### END INIT INFO +# +# Startup script for nfs-utils +# +# +# Location of executables: + +# Source function library. +. /etc/init.d/functions + +test -x "$NFS_STATD" || NFS_STATD=/usr/sbin/rpc.statd +test -x "$NFS_IDMAPD" || NFS_IDMAPD=/usr/sbin/rpc.idmapd +test -z "$STATD_PID" && STATD_PID=/var/run/rpc.statd.pid +# +# The default state directory is /var/lib/nfs +test -n "$NFS_STATEDIR" || NFS_STATEDIR=/var/lib/nfs +# +# +#---------------------------------------------------------------------- +# Startup and shutdown functions. +# Actual startup/shutdown is at the end of this file. +#directories +create_directories(){ + echo -n 'creating NFS state directory: ' + mkdir -p "$NFS_STATEDIR" + ( cd "$NFS_STATEDIR" + umask 077 + mkdir -p rpc_pipefs + mkdir -p sm sm.bak statd + chown rpcuser:rpcuser sm sm.bak statd + test -w statd/state || { + rm -f statd/state + :>statd/state + } + umask 022 + for file in xtab etab smtab rmtab + do + test -w "$file" || { + rm -f "$file" + :>"$file" + } + done + ) + chown rpcuser:rpcuser "$NFS_STATEDIR" + echo done +} + +# Parse the fstab and exports file, determine if we need idmapd. +# +NEED_IDMAPD=no + +if [ -f /etc/fstab ]; then + exec 9<&0 /dev/null + echo done +} +#statd +start_statd(){ + echo -n "starting statd: " + start-stop-daemon --start --exec "$NFS_STATD" --pidfile "$STATD_PID" + echo done +} +stop_statd(){ + echo -n 'stopping statd: ' + start-stop-daemon --stop --quiet --signal 1 --pidfile "$STATD_PID" + echo done +} + +#---------------------------------------------------------------------- +# +# supported options: +# start +# stop +# restart: stops and starts mountd +#FIXME: need to create the /var/lib/nfs/... directories +case "$1" in + start) + create_directories + start_statd + start_idmapd;; + stop) stop_idmapd + stop_statd;; + status) + status $NFS_STATD; + RETVAL=$? + if [ "$NEED_IDMAPD" = yes ] + then + status $NFS_IDMAPD + rval=$? + [ $rval -ne 0 ] && exit $rval + fi + exit $RETVAL;; + restart) + $0 stop + $0 start;; + *) + echo "Usage: /etc/init.d/nfscommon {start|stop|status|restart}" + exit 1;; +esac diff --git a/connectivity/nfs-utils/files/nfscommon.service b/connectivity/nfs-utils/files/nfscommon.service new file mode 100644 index 000000000..d1ee13f31 --- /dev/null +++ b/connectivity/nfs-utils/files/nfscommon.service @@ -0,0 +1,13 @@ +[Unit] +Description=Titanium Cloud Filesystem Common +After=network.target rpcbind.service +Before=nfsserver.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/etc/init.d/nfscommon start +ExecStop=/etc/init.d/nfscommon stop + +[Install] +WantedBy=multi-user.target diff --git a/connectivity/nfs-utils/files/nfsserver b/connectivity/nfs-utils/files/nfsserver new file mode 100644 index 000000000..6449537b9 --- /dev/null +++ b/connectivity/nfs-utils/files/nfsserver @@ -0,0 +1,136 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: nfs-kernel-server +# Required-Start: $remote_fs nfs-common $portmap hwclock +# Required-Stop: $remote_fs nfs-common $portmap hwclock +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Kernel NFS server support +# Description: NFS is a popular protocol for file sharing across +# TCP/IP networks. This service provides NFS server +# functionality, which is configured via the +# /etc/exports file. +### END INIT INFO +# +# Startup script for nfs-utils +# +# Source function library. +. /etc/init.d/functions + +# +# The environment variable NFS_SERVERS may be set in /etc/default/nfsd +# Other control variables may be overridden here too +# +# Commented out by 'emacdona' during port to Centos due to change from sysv to systemd +# test -r /etc/default/nfsd && . /etc/default/nfsd + + +# +# Location of executables: +test -x "$NFS_MOUNTD" || NFS_MOUNTD=/usr/sbin/rpc.mountd +test -x "$NFS_NFSD" || NFS_NFSD=/usr/sbin/rpc.nfsd +test -z "$STATD_PID" && STATD_PID=/var/run/rpc.statd.pid +# +# The user mode program must also exist (it just starts the kernel +# threads using the kernel module code). +test -x "$NFS_MOUNTD" || exit 0 +test -x "$NFS_NFSD" || exit 0 +# +# Default is 8 threads, value is settable between 1 and the truely +# ridiculous 99 +test "$NFS_SERVERS" != "" && test "$NFS_SERVERS" -gt 0 && test "$NFS_SERVERS" -lt 100 || NFS_SERVERS=8 +# +#---------------------------------------------------------------------- +# Startup and shutdown functions. +# Actual startup/shutdown is at the end of this file. +#mountd +start_mountd(){ + echo -n 'starting mountd: ' + start-stop-daemon --start --exec "$NFS_MOUNTD" -- "-f /etc/exports $@" + echo done +} +stop_mountd(){ + echo -n 'stopping mountd: ' + start-stop-daemon --stop --quiet --exec "$NFS_MOUNTD" + echo done +} +# +#nfsd +start_nfsd(){ + modprobe -q nfsd + grep -q nfsd /proc/filesystems || { + echo NFS daemon support not enabled in kernel + exit 1 + } + grep -q nfsd /proc/mounts || mount -t nfsd nfsd /proc/fs/nfsd + grep -q nfsd /proc/mounts || { + echo nfsd filesystem could not be mounted at /proc/fs/nfsd + exit 1 + } + + echo -n "starting $1 nfsd kernel threads: " + start-stop-daemon --start --exec "$NFS_NFSD" -- "$@" + echo done +} +delay_nfsd(){ + for delay in 0 1 2 3 4 5 6 7 8 9 + do + if pidof nfsd >/dev/null + then + echo -n . + sleep 1 + else + return 0 + fi + done + return 1 +} +stop_nfsd(){ + # WARNING: this kills any process with the executable + # name 'nfsd'. + echo -n 'stopping nfsd: ' + start-stop-daemon --stop --quiet --signal 1 --name nfsd + if delay_nfsd || { + echo failed + echo ' using signal 9: ' + start-stop-daemon --stop --quiet --signal 9 --name nfsd + delay_nfsd + } + then + echo done + else + echo failed + fi +} + +#---------------------------------------------------------------------- +# +# supported options: +# start +# stop +# reload: reloads the exports file +# restart: stops and starts mountd +#FIXME: need to create the /var/lib/nfs/... directories +case "$1" in + start) exportfs -r + start_nfsd "$NFS_SERVERS" + start_mountd + test -r /etc/exports && exportfs -a;; + stop) exportfs -ua + stop_mountd + stop_nfsd;; + status) + status /usr/sbin/rpc.mountd + RETVAL=$? + status nfsd + rval=$? + [ $RETVAL -eq 0 ] && exit $rval + exit $RETVAL;; + reload) test -r /etc/exports && exportfs -r;; + restart) + $0 stop + $0 start;; + *) echo "Usage: $0 {start|stop|status|reload|restart}" + exit 1;; + +esac diff --git a/connectivity/nfs-utils/files/nfsserver.service b/connectivity/nfs-utils/files/nfsserver.service new file mode 100644 index 000000000..abfc10fad --- /dev/null +++ b/connectivity/nfs-utils/files/nfsserver.service @@ -0,0 +1,13 @@ +[Unit] +Description=Titanium Cloud Filesystem Server +After=network.target nfscommon.service hwclock.service +Before=ntpd.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/etc/init.d/nfsserver start +ExecStop=/etc/init.d/nfsserver stop + +[Install] +WantedBy=multi-user.target diff --git a/connectivity/openssh/PKG-INFO b/connectivity/openssh/PKG-INFO new file mode 100644 index 000000000..842439bb5 --- /dev/null +++ b/connectivity/openssh/PKG-INFO @@ -0,0 +1,25 @@ +Metadata-Version: 1.1 +Name: openssh +Version: 6.6.1p1 +Summary: An open source implementation of SSH protocol versions 1 and 2 +Home-page: +Author: +Author-email: +License: BSD + +Description: +SSH (Secure SHell) is a program for logging into and executing +commands on a remote machine. SSH is intended to replace rlogin and +rsh, and to provide secure encrypted communications between two +untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's version of the last free version of SSH, bringing +it up to date in terms of security and features. + +This package includes the core files necessary for both the OpenSSH +client and server. To make this package useful, you should also +install openssh-clients, openssh-server, or both. + + +Platform: UNKNOWN diff --git a/connectivity/openssh/centos/build_srpm.data b/connectivity/openssh/centos/build_srpm.data new file mode 100644 index 000000000..b24625715 --- /dev/null +++ b/connectivity/openssh/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$FILES_BASE/*" +TIS_PATCH_VER=8 diff --git a/connectivity/openssh/centos/files/ssh_config b/connectivity/openssh/centos/files/ssh_config new file mode 100644 index 000000000..b21f26311 --- /dev/null +++ b/connectivity/openssh/centos/files/ssh_config @@ -0,0 +1,48 @@ +# $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $ + +# This is the ssh client system-wide configuration file. See +# ssh_config(5) for more information. This file provides defaults for +# users, and the values can be changed in per-user configuration files +# or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for some commonly used options. For a comprehensive +# list of available options, their meanings and defaults, please see the +# ssh_config(5) man page. + +Host * + ForwardAgent yes + ForwardX11 yes +# RhostsRSAAuthentication no +# RSAAuthentication yes +# PasswordAuthentication yes +# HostbasedAuthentication no +# GSSAPIAuthentication no +# GSSAPIDelegateCredentials no +# BatchMode no +# CheckHostIP yes +# AddressFamily any +# ConnectTimeout 0 +# StrictHostKeyChecking ask +# IdentityFile ~/.ssh/identity +# IdentityFile ~/.ssh/id_rsa +# IdentityFile ~/.ssh/id_dsa +# Port 22 +# Protocol 2,1 +# Cipher 3des +# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc +# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 +# EscapeChar ~ +# Tunnel no +# TunnelDevice any:any +# PermitLocalCommand no +# VisualHostKey no +KexAlgorithms ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 +UseRoaming no diff --git a/connectivity/openssh/centos/files/sshd_config b/connectivity/openssh/centos/files/sshd_config new file mode 100644 index 000000000..a0fa9fbc0 --- /dev/null +++ b/connectivity/openssh/centos/files/sshd_config @@ -0,0 +1,129 @@ +# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +#Port 22 +#AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +# Disable legacy (protocol version 1) support in the server for new +# installations. In future the default will change to require explicit +# activation of protocol 1 +Protocol 2 + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 1024 + +# Logging +# obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +LogLevel INFO + +# Authentication: + +LoginGraceTime 1m +PermitRootLogin without-password +#StrictModes yes +MaxAuthTries 4 +#MaxSessions 10 + +#RSAAuthentication yes +#PubkeyAuthentication yes +#AuthorizedKeysFile .ssh/authorized_keys + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +#RhostsRSAAuthentication no +# similar for protocol version 2 +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +#PasswordAuthentication yes +PermitEmptyPasswords no + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication no + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM yes + +AllowAgentForwarding no +AllowTcpForwarding no +#GatewayPorts no +X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PrintMotd yes +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +UsePrivilegeSeparation yes +PermitUserEnvironment no +Compression no +ClientAliveInterval 15 +ClientAliveCountMax 4 +# Make SSH connect faster on bootup +UseDNS no +#PidFile /var/run/sshd.pid +#MaxStartups 10 +#PermitTunnel no +#ChrootDirectory none + +# default banner path +Banner /etc/issue.net + +# override default of no subsystems +Subsystem sftp /usr/libexec/openssh/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server +DenyUsers admin secadmin operator +# Filtered cipher, MAC and key exchange algorithm list, defaults can be +# obtained by ssh -Q cipher, ssh -Q mac and ssh -Q kex +# TODO (aning): once openssh is updated to 7.5, an explicit exclusion list +# using "-" should be used for cipher, MAC and kex excluded suites. +Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com +MACs hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com +KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 diff --git a/connectivity/openssh/centos/meta_patches/0001-Further-parallelize-openssh-build.patch b/connectivity/openssh/centos/meta_patches/0001-Further-parallelize-openssh-build.patch new file mode 100644 index 000000000..90534cbec --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/0001-Further-parallelize-openssh-build.patch @@ -0,0 +1,34 @@ +From e9d5aad98db3731eb73837773ab8117b54598196 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:16 -0400 +Subject: [PATCH 7/7] WRS: 0001-Further-parallelize-openssh-build.patch + +--- + SPECS/openssh.spec | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec +index 332152d..52d080a 100644 +--- a/SPECS/openssh.spec ++++ b/SPECS/openssh.spec +@@ -589,7 +589,7 @@ fi + perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile + %endif + +-make ++make -j"%(nproc)" + + # Define a variable to toggle gnome1/gtk2 building. This is necessary + # because RPM doesn't handle nested %if statements. +@@ -615,7 +615,7 @@ popd + pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} + LDFLAGS="$SAVE_LDFLAGS" + %configure --with-selinux --libexecdir=/%{_libdir}/security --with-mantype=man +-make ++make -j"%(nproc)" + popd + %endif + +-- +1.9.1 + diff --git a/connectivity/openssh/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/connectivity/openssh/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..00fe38a87 --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,34 @@ +From 5c046dab0c2f53a7a4ff643011fb367d8f5fbe6e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:16 -0400 +Subject: [PATCH 5/7] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +--- + SPECS/openssh.spec | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec +index 9607a75..332152d 100644 +--- a/SPECS/openssh.spec ++++ b/SPECS/openssh.spec +@@ -71,7 +71,7 @@ + Summary: An open source implementation of SSH protocol versions 1 and 2 + Name: openssh + Version: %{openssh_ver} +-Release: %{openssh_rel}%{?dist}%{?rescue_rel} ++Release: %{openssh_rel}.el7_4%{?_tis_dist}.%{tis_patch_ver} + URL: http://www.openssh.com/portable.html + #URL1: http://pamsshagentauth.sourceforge.net + Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +@@ -339,7 +339,7 @@ Requires: openssh = %{version}-%{release} + Summary: PAM module for authentication with ssh-agent + Group: System Environment/Base + Version: %{pam_ssh_agent_ver} +-Release: %{pam_ssh_agent_rel}.%{openssh_rel}%{?dist}%{?rescue_rel} ++Release: %{pam_ssh_agent_rel}.el7_2%{?_tis_dist}.%{tis_patch_ver} + License: BSD + + %description +-- +1.9.1 + diff --git a/connectivity/openssh/centos/meta_patches/PATCH_ORDER b/connectivity/openssh/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..2add864ec --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,7 @@ +spec-include-TiS-config-files.patch +sshd-pam-use-common-includes.patch +openssh-service-file.patch +openssh-spec-file-add-init.patch +0001-Update-package-versioning-for-TIS-format.patch +openssh-init-script-kill-old-instances-on-start.patch +0001-Further-parallelize-openssh-build.patch diff --git a/connectivity/openssh/centos/meta_patches/openssh-init-script-kill-old-instances-on-start.patch b/connectivity/openssh/centos/meta_patches/openssh-init-script-kill-old-instances-on-start.patch new file mode 100644 index 000000000..aa2b06596 --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/openssh-init-script-kill-old-instances-on-start.patch @@ -0,0 +1,32 @@ +From 7eefd34e4adc9a4c88fc667f99bf76e967270813 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:16 -0400 +Subject: [PATCH 6/7] WRS: + openssh-init-script-kill-old-instances-on-start.patch + +--- + SOURCES/sshd.init | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SOURCES/sshd.init b/SOURCES/sshd.init +index 8901b4f..cd8b4ab 100755 +--- a/SOURCES/sshd.init ++++ b/SOURCES/sshd.init +@@ -60,6 +60,14 @@ start() + # Create keys if necessary + /usr/sbin/sshd-keygen + ++ # In rare instances, sshd may be started but a pid ++ # file is not generated. This is seen usually during ++ # system reboot scenarios. A subsequent attempt to start ++ # sshd here will trigger a port bind error. As a sanity ++ # check attempt a kill call (mostly redundant) to any ++ # previously running sshd instance ++ /bin/kill `/usr/sbin/pidof "$SSHD"` >/dev/null 2>&1 ++ + echo -n $"Starting $prog: " + $SSHD $OPTIONS && success || failure + RETVAL=$? +-- +1.9.1 + diff --git a/connectivity/openssh/centos/meta_patches/openssh-service-file.patch b/connectivity/openssh/centos/meta_patches/openssh-service-file.patch new file mode 100644 index 000000000..e65ef065c --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/openssh-service-file.patch @@ -0,0 +1,38 @@ +From 136246c027dedb5c22c7a50ce8beebdecf85defe Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:15 -0400 +Subject: [PATCH 3/7] WRS: openssh-service-file.patch + +Conflicts: + SOURCES/sshd.service +--- + SOURCES/sshd.service | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/SOURCES/sshd.service b/SOURCES/sshd.service +index af7845c..5cba529 100644 +--- a/SOURCES/sshd.service ++++ b/SOURCES/sshd.service +@@ -5,13 +5,14 @@ After=network.target sshd-keygen.service + Wants=sshd-keygen.service + + [Service] +-Type=notify + EnvironmentFile=/etc/sysconfig/sshd +-ExecStart=/usr/sbin/sshd -D $OPTIONS ++ExecStart=/etc/init.d/sshd start ++ExecStop=/etc/init.d/sshd stop + ExecReload=/bin/kill -HUP $MAINPID +-KillMode=process +-Restart=on-failure +-RestartSec=42s ++PIDFile=/var/run/sshd.pid ++KillMode=none ++#Restart=on-failure ++#RestartSec=42s + + [Install] + WantedBy=multi-user.target +-- +1.9.1 + diff --git a/connectivity/openssh/centos/meta_patches/openssh-spec-file-add-init.patch b/connectivity/openssh/centos/meta_patches/openssh-spec-file-add-init.patch new file mode 100644 index 000000000..dff796d5f --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/openssh-spec-file-add-init.patch @@ -0,0 +1,35 @@ +From 49c227e1ec30dc7b0417f74972cd5414ac68ce46 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:16 -0400 +Subject: [PATCH 4/7] WRS: openssh-spec-file-add-init.patch + +--- + SPECS/openssh.spec | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec +index 2302061..9607a75 100644 +--- a/SPECS/openssh.spec ++++ b/SPECS/openssh.spec +@@ -711,9 +711,6 @@ getent passwd sshd >/dev/null || \ + %preun server + %systemd_preun sshd.service sshd.socket + +-%postun server +-%systemd_postun_with_restart sshd.service +- + %files + %defattr(-,root,root) + %{!?_licensedir:%global license %%doc} +@@ -776,8 +773,6 @@ getent passwd sshd >/dev/null || \ + %attr(0644,root,root) %{_unitdir}/sshd.socket + %attr(0644,root,root) %{_unitdir}/sshd-keygen.service + +-%files server-sysvinit +-%defattr(-,root,root) + %attr(0755,root,root) /etc/rc.d/init.d/sshd + %endif + +-- +1.9.1 + diff --git a/connectivity/openssh/centos/meta_patches/spec-include-TiS-config-files.patch b/connectivity/openssh/centos/meta_patches/spec-include-TiS-config-files.patch new file mode 100644 index 000000000..498a1a5f5 --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/spec-include-TiS-config-files.patch @@ -0,0 +1,39 @@ +From f4b2a7d1f5f139ffd622a5617e63cbdc1fd838bd Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:15 -0400 +Subject: [PATCH 1/7] WRS: spec-include-TiS-config-files.patch + +--- + SPECS/openssh.spec | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec +index 69a8ae4..2302061 100644 +--- a/SPECS/openssh.spec ++++ b/SPECS/openssh.spec +@@ -88,6 +88,10 @@ Source11: sshd.service + Source12: sshd-keygen.service + Source13: sshd-keygen + ++# WRS ++Source14: sshd_config ++Source15: ssh_config ++ + # Internal debug + Patch0: openssh-5.9p1-wIm.patch + +@@ -684,6 +688,11 @@ pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver} + make install DESTDIR=$RPM_BUILD_ROOT + popd + %endif ++ ++# WRS: Overwrite with our config ++install -m 0640 %{SOURCE14} $RPM_BUILD_ROOT/etc/ssh/sshd_config ++install -m 0644 %{SOURCE15} $RPM_BUILD_ROOT/etc/ssh/ssh_config ++ + %clean + rm -rf $RPM_BUILD_ROOT + +-- +1.9.1 + diff --git a/connectivity/openssh/centos/meta_patches/sshd-pam-use-common-includes.patch b/connectivity/openssh/centos/meta_patches/sshd-pam-use-common-includes.patch new file mode 100644 index 000000000..ada8bfc94 --- /dev/null +++ b/connectivity/openssh/centos/meta_patches/sshd-pam-use-common-includes.patch @@ -0,0 +1,58 @@ +From e5e0631b4568821e63cf676c425ed13873e98b0a Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:32:15 -0400 +Subject: [PATCH 2/7] WRS: sshd-pam-use-common-includes.patch + +--- + SOURCES/sshd.pam | 38 +++++++++++++++++++++----------------- + 1 file changed, 21 insertions(+), 17 deletions(-) + +diff --git a/SOURCES/sshd.pam b/SOURCES/sshd.pam +index 0f5c061..72303eb 100644 +--- a/SOURCES/sshd.pam ++++ b/SOURCES/sshd.pam +@@ -1,20 +1,24 @@ + #%PAM-1.0 +-auth required pam_sepermit.so +-auth substack password-auth +-auth include postlogin +-# Used with polkit to reauthorize users in remote sessions +--auth optional pam_reauthorize.so prepare ++ ++auth include common-auth + account required pam_nologin.so +-account include password-auth +-password include password-auth +-# pam_selinux.so close should be the first session rule +-session required pam_selinux.so close +-session required pam_loginuid.so +-# pam_selinux.so open should only be followed by sessions to be executed in the user context +-session required pam_selinux.so open env_params +-session required pam_namespace.so ++ ++# SELinux needs to be the first session rule. This ensures that any ++# lingering context has been cleared. Without out this it is possible ++# that a module could execute code in the wrong domain. ++# When the module is present, "required" would be sufficient (When SELinux ++# is disabled, this returns success.) ++session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close ++ ++account include common-account ++password include common-password + session optional pam_keyinit.so force revoke +-session include password-auth +-session include postlogin +-# Used with polkit to reauthorize users in remote sessions +--session optional pam_reauthorize.so prepare ++session include common-session ++session required pam_loginuid.so ++ ++# SELinux needs to intervene at login time to ensure that the process ++# starts in the proper default security context. Only sessions which are ++# intended to run in the user's context should be run after this. ++# When the module is present, "required" would be sufficient (When SELinux ++# is disabled, this returns success.) ++session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open +-- +1.9.1 + diff --git a/connectivity/openssh/centos/srpm_path b/connectivity/openssh/centos/srpm_path new file mode 100644 index 000000000..7f676b957 --- /dev/null +++ b/connectivity/openssh/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/openssh-7.4p1-12.el7_4.src.rpm diff --git a/connectivity/openssh/files/add-roaming-no-option-ssh-config.patch b/connectivity/openssh/files/add-roaming-no-option-ssh-config.patch new file mode 100644 index 000000000..6bf7f1739 --- /dev/null +++ b/connectivity/openssh/files/add-roaming-no-option-ssh-config.patch @@ -0,0 +1,9 @@ +Index: 6.2p2-r5.5/ssh_config +=================================================================== +--- 6.2p2-r5.5.orig/ssh_config ++++ 6.2p2-r5.5/ssh_config +@@ -45,3 +45,4 @@ Host * + # PermitLocalCommand no + # VisualHostKey no + KexAlgorithms ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 ++UseRoaming no diff --git a/connectivity/openssh/files/sshd-security-hardening-and-disabling-password-based-rootssh.patch b/connectivity/openssh/files/sshd-security-hardening-and-disabling-password-based-rootssh.patch new file mode 100644 index 000000000..03a53eec3 --- /dev/null +++ b/connectivity/openssh/files/sshd-security-hardening-and-disabling-password-based-rootssh.patch @@ -0,0 +1,78 @@ +--- + sshd_config | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +--- a/sshd_config ++++ b/sshd_config +@@ -33,14 +33,14 @@ Protocol 2 + # Logging + # obsoletes QuietMode and FascistLogging + #SyslogFacility AUTH +-#LogLevel INFO ++LogLevel INFO + + # Authentication: + +-#LoginGraceTime 2m +-#PermitRootLogin yes ++LoginGraceTime 1m ++PermitRootLogin without-password + #StrictModes yes +-#MaxAuthTries 6 ++MaxAuthTries 4 + #MaxSessions 10 + + #RSAAuthentication yes +@@ -59,7 +59,7 @@ Protocol 2 + + # To disable tunneled clear text passwords, change to no here! + #PasswordAuthentication yes +-#PermitEmptyPasswords no ++PermitEmptyPasswords no + + # Change to no to disable s/key passwords + ChallengeResponseAuthentication no +@@ -85,10 +85,10 @@ ChallengeResponseAuthentication no + # and ChallengeResponseAuthentication to 'no'. + UsePAM yes + +-#AllowAgentForwarding yes +-#AllowTcpForwarding yes ++AllowAgentForwarding no ++AllowTcpForwarding no + #GatewayPorts no +-#X11Forwarding no ++X11Forwarding no + #X11DisplayOffset 10 + #X11UseLocalhost yes + #PrintMotd yes +@@ -96,18 +96,19 @@ UsePAM yes + #TCPKeepAlive yes + #UseLogin no + UsePrivilegeSeparation yes +-#PermitUserEnvironment no ++PermitUserEnvironment no + Compression no + ClientAliveInterval 15 + ClientAliveCountMax 4 +-#UseDNS yes ++# Make SSH connect faster on bootup ++UseDNS no + #PidFile /var/run/sshd.pid + #MaxStartups 10 + #PermitTunnel no + #ChrootDirectory none + +-# no default banner path +-#Banner none ++# default banner path ++Banner /etc/issue.net + + # override default of no subsystems + Subsystem sftp /usr/libexec/sftp-server +@@ -117,3 +118,5 @@ Subsystem sftp /usr/libexec/sftp-server + # X11Forwarding no + # AllowTcpForwarding no + # ForceCommand cvs server ++DenyUsers admin secadmin operator ++ diff --git a/core/initscripts/PKG-INFO b/core/initscripts/PKG-INFO new file mode 100644 index 000000000..9e63d49ff --- /dev/null +++ b/core/initscripts/PKG-INFO @@ -0,0 +1,19 @@ +Metadata-Version: 1.1 +Name: libevent +Version: 2.0.21 +Summary: Abstract asynchronous event notification library +Home-page: +Author: +Author-email: +License: BSD + +Description: +The libevent API provides a mechanism to execute a callback function +when a specific event occurs on a file descriptor or after a timeout +has been reached. libevent is meant to replace the asynchronous event +loop found in event driven network servers. An application just needs +to call event_dispatch() and can then add or remove events dynamically +without having to change the event loop. + + +Platform: UNKNOWN diff --git a/core/initscripts/centos/build_srpm.data b/core/initscripts/centos/build_srpm.data new file mode 100644 index 000000000..2eb634ca1 --- /dev/null +++ b/core/initscripts/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/* $CGCS_BASE/mwa-sparta/extended/procps/files/sysctl.conf" +TIS_PATCH_VER=16 diff --git a/core/initscripts/centos/meta_patches/0001-Disable-zeroconf-route.patch b/core/initscripts/centos/meta_patches/0001-Disable-zeroconf-route.patch new file mode 100644 index 000000000..45e617711 --- /dev/null +++ b/core/initscripts/centos/meta_patches/0001-Disable-zeroconf-route.patch @@ -0,0 +1,59 @@ +From 21388fc6c11be326dbdae193dd05dce56fdb5b03 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 03/13] WRS: 0001-Disable-zeroconf-route.patch + +Conflicts: + SPECS/initscripts.spec +--- + SOURCES/sysconfig-network.conf | 1 + + SPECS/initscripts.spec | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + create mode 100644 SOURCES/sysconfig-network.conf + +diff --git a/SOURCES/sysconfig-network.conf b/SOURCES/sysconfig-network.conf +new file mode 100644 +index 0000000..5b2803b +--- /dev/null ++++ b/SOURCES/sysconfig-network.conf +@@ -0,0 +1 @@ ++NOZEROCONF=yes +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 5349c54..6a7a76d 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -4,12 +4,13 @@ Version: 9.49.39 + # ppp-watch is GPLv2+, everything else is GPLv2 + License: GPLv2 and GPLv2+ + Group: System Environment/Base +-Release: 1%{?dist} ++Release: 1%{?dist}.4 + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz + + # WRS + Source1: sysctl.conf ++Source2: sysconfig-network.conf + + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + Obsoletes: initscripts-legacy <= 9.39 +@@ -88,6 +89,7 @@ chmod 600 $RPM_BUILD_ROOT/etc/crypttab + + # WRS: Overwrite with our config + install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/etc/sysctl.conf ++install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/etc/sysconfig/network + + %pre + /usr/sbin/groupadd -g 22 -r -f utmp +@@ -220,6 +222,8 @@ rm -rf $RPM_BUILD_ROOT + %dir /usr/libexec/initscripts/legacy-actions + %ghost %{_localstatedir}/log/dmesg + %ghost %{_localstatedir}/log/dmesg.old ++# WRS ++/etc/sysconfig/network + + %files -n debugmode + %defattr(-,root,root) +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/0001-Fix-Interfaces-intermittenly-do-not-come-up-on-boot.patch b/core/initscripts/centos/meta_patches/0001-Fix-Interfaces-intermittenly-do-not-come-up-on-boot.patch new file mode 100644 index 000000000..9db9aa8fa --- /dev/null +++ b/core/initscripts/centos/meta_patches/0001-Fix-Interfaces-intermittenly-do-not-come-up-on-boot.patch @@ -0,0 +1,44 @@ +From 9608ef02519db7648cdede4f113e760e4540c0b9 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 06/13] WRS: + 0001-Fix-Interfaces-intermittenly-do-not-come-up-on-boot.patch + +Conflicts: + SPECS/initscripts.spec +--- + SPECS/initscripts.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 5ba669b..63ad994 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -4,7 +4,7 @@ Version: 9.49.39 + # ppp-watch is GPLv2+, everything else is GPLv2 + License: GPLv2 and GPLv2+ + Group: System Environment/Base +-Release: 1%{?dist}.5 ++Release: 1%{?dist}.6 + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz + +@@ -47,6 +47,7 @@ Patch4: support-interface-scriptlets.patch + Patch5: relocate-dhclient-leases-to-var-run.patch + Patch6: dhclient-restrict-interfaces-to-those-on-c.patch + Patch7: support-interface-promisc.patch ++Patch8: 0001-dhclient-remove-1-arg.patch + + %description + The initscripts package contains basic system scripts used +@@ -71,6 +72,7 @@ Currently, this consists of various memory checking code. + %patch5 -p1 + %patch6 -p1 + %patch7 -p1 ++%patch8 -p1 + + %build + make +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/0001-Support-PROMISC-for-interfaces-config.patch b/core/initscripts/centos/meta_patches/0001-Support-PROMISC-for-interfaces-config.patch new file mode 100644 index 000000000..d4cfbfd9f --- /dev/null +++ b/core/initscripts/centos/meta_patches/0001-Support-PROMISC-for-interfaces-config.patch @@ -0,0 +1,43 @@ +From 47c822a4f51caf9cfc782fbf0e6b670b535fe071 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 04/13] WRS: 0001-Support-PROMISC-for-interfaces-config.patch + +Conflicts: + SPECS/initscripts.spec +--- + SPECS/initscripts.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 6a7a76d..6ec4bea 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -4,7 +4,7 @@ Version: 9.49.39 + # ppp-watch is GPLv2+, everything else is GPLv2 + License: GPLv2 and GPLv2+ + Group: System Environment/Base +-Release: 1%{?dist}.4 ++Release: 1%{?dist}.5 + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz + +@@ -43,6 +43,7 @@ Provides: /sbin/service + Patch4: support-interface-scriptlets.patch + Patch5: relocate-dhclient-leases-to-var-run.patch + Patch6: dhclient-restrict-interfaces-to-those-on-c.patch ++Patch7: support-interface-promisc.patch + + %description + The initscripts package contains basic system scripts used +@@ -66,6 +67,7 @@ Currently, this consists of various memory checking code. + %patch4 -p1 + %patch5 -p1 + %patch6 -p1 ++%patch7 -p1 + + %build + make +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/core/initscripts/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..44c355420 --- /dev/null +++ b/core/initscripts/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,28 @@ +From f77c05868c164eebe1c84eb3fdd920ef3305cebc Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 09/13] WRS: + 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/initscripts.spec +--- + SPECS/initscripts.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index df59412..fd84a75 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -4,7 +4,7 @@ Version: 9.49.39 + # ppp-watch is GPLv2+, everything else is GPLv2 + License: GPLv2 and GPLv2+ + Group: System Environment/Base +-Release: 1%{?dist}.8 ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz + +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/PATCH_ORDER b/core/initscripts/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..db1bb2e48 --- /dev/null +++ b/core/initscripts/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,16 @@ +spec-include-TiS-changes.patch +stop-creating-shared-dirs.patch +0001-Disable-zeroconf-route.patch +0001-Support-PROMISC-for-interfaces-config.patch +spec-add-mountnfs-init-script.patch +0001-Fix-Interfaces-intermittenly-do-not-come-up-on-boot.patch +force-delay-check-link-down.patch +run-ifdown-on-all-interfaces.patch +0001-Update-package-versioning-for-TIS-format.patch +spec-sysconfig-affirmative-check-for-link-carrier.patch +spec-sysconfig-unsafe-usage-of-linkdelay-variable.patch +fix-build-failures-due-to-unwanted-sgid.patch +add_build_require_on_systemd.patch +ipv6-static-route-support.patch +spec-ifup-eth-stop-waiting-if-link-is-up.patch +spec-run-dhclient-as-daemon-for-ipv6.patch diff --git a/core/initscripts/centos/meta_patches/add_build_require_on_systemd.patch b/core/initscripts/centos/meta_patches/add_build_require_on_systemd.patch new file mode 100644 index 000000000..8a7ccab23 --- /dev/null +++ b/core/initscripts/centos/meta_patches/add_build_require_on_systemd.patch @@ -0,0 +1,24 @@ +From 075dd032f651d469e639eb1f25f3d5b7f5ff5485 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 13/13] WRS: add_build_require_on_systemd.patch + +--- + SPECS/initscripts.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 09674a7..cdc282e 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -41,6 +41,7 @@ Requires(pre): /usr/sbin/groupadd + Requires(post): /sbin/chkconfig, coreutils + Requires(preun): /sbin/chkconfig + BuildRequires: glib2-devel popt-devel gettext pkgconfig ++BuildRequires: systemd-devel + Provides: /sbin/service + + Patch4: support-interface-scriptlets.patch +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch b/core/initscripts/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch new file mode 100644 index 000000000..94978afbd --- /dev/null +++ b/core/initscripts/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch @@ -0,0 +1,33 @@ +From 8351b22a5a517ebe779d4bf4904694bd1bd85890 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 12/13] WRS: fix-build-failures-due-to-unwanted-sgid.patch + +--- + SPECS/initscripts.spec | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index f2d0271..09674a7 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -197,6 +197,7 @@ rm -rf $RPM_BUILD_ROOT + %dir /etc/rwtab.d + %dir /etc/statetab.d + /usr/lib/systemd/rhel-* ++%dir %attr(0755,root,root) /usr/lib/systemd/system/*wants + /usr/lib/systemd/system/* + /etc/inittab + /etc/rc[0-9].d +@@ -237,7 +238,7 @@ rm -rf $RPM_BUILD_ROOT + %ghost %attr(0664,root,utmp) /var/run/utmp + %ghost %attr(0644,root,root) /etc/sysconfig/kvm + %ghost %verify(not md5 size mtime) %config(noreplace,missingok) /etc/crypttab +-%dir /usr/lib/tmpfiles.d ++%dir %attr(0755,root,root) /usr/lib/tmpfiles.d + /usr/lib/tmpfiles.d/initscripts.conf + %dir /usr/libexec/initscripts + %dir /usr/libexec/initscripts/legacy-actions +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/force-delay-check-link-down.patch b/core/initscripts/centos/meta_patches/force-delay-check-link-down.patch new file mode 100644 index 000000000..1ae471917 --- /dev/null +++ b/core/initscripts/centos/meta_patches/force-delay-check-link-down.patch @@ -0,0 +1,43 @@ +From 7e75a43284b19d4217d2902adb6f3200bccdf037 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 07/13] WRS: force-delay-check-link-down.patch + +Conflicts: + SPECS/initscripts.spec +--- + SPECS/initscripts.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 63ad994..c806126 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -4,7 +4,7 @@ Version: 9.49.39 + # ppp-watch is GPLv2+, everything else is GPLv2 + License: GPLv2 and GPLv2+ + Group: System Environment/Base +-Release: 1%{?dist}.6 ++Release: 1%{?dist}.7 + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz + +@@ -48,6 +48,7 @@ Patch5: relocate-dhclient-leases-to-var-run.patch + Patch6: dhclient-restrict-interfaces-to-those-on-c.patch + Patch7: support-interface-promisc.patch + Patch8: 0001-dhclient-remove-1-arg.patch ++Patch9: 0001-force-delay-check-link-down.patch + + %description + The initscripts package contains basic system scripts used +@@ -73,6 +74,7 @@ Currently, this consists of various memory checking code. + %patch6 -p1 + %patch7 -p1 + %patch8 -p1 ++%patch9 -p1 + + %build + make +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/ipv6-static-route-support.patch b/core/initscripts/centos/meta_patches/ipv6-static-route-support.patch new file mode 100644 index 000000000..28d0c6991 --- /dev/null +++ b/core/initscripts/centos/meta_patches/ipv6-static-route-support.patch @@ -0,0 +1,33 @@ +From 2055b5d7ac45920a8bfbdaf31ffe5ab586669664 Mon Sep 17 00:00:00 2001 +From: Kevin Smith +Date: Wed, 11 Oct 2017 13:20:07 -0500 +Subject: [PATCH 1/1] ipv6 static route support + +--- + SPECS/initscripts.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 090f75c..d15e196 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -53,6 +53,7 @@ Patch9: 0001-force-delay-check-link-down.patch + Patch10: run-ifdown-on-all-interfaces.patch + Patch11: sysconfig-affirmative-check-for-link-carrier.patch + Patch12: sysconfig-unsafe-usage-of-linkdelay-variable.patch ++Patch13: ipv6-static-route-support.patch + + %description + The initscripts package contains basic system scripts used +@@ -82,6 +83,8 @@ Currently, this consists of various memory checking code. + %patch10 -p1 + %patch11 -p1 + %patch12 -p1 ++%patch13 -p1 ++ + + %build + make +-- +1.8.3.1 + diff --git a/core/initscripts/centos/meta_patches/run-ifdown-on-all-interfaces.patch b/core/initscripts/centos/meta_patches/run-ifdown-on-all-interfaces.patch new file mode 100644 index 000000000..a14d91b2f --- /dev/null +++ b/core/initscripts/centos/meta_patches/run-ifdown-on-all-interfaces.patch @@ -0,0 +1,43 @@ +From 32834cbfb6b7186e49416eef5c442ac6f38fd551 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 08/13] WRS: run-ifdown-on-all-interfaces.patch + +Conflicts: + SPECS/initscripts.spec +--- + SPECS/initscripts.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index c806126..df59412 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -4,7 +4,7 @@ Version: 9.49.39 + # ppp-watch is GPLv2+, everything else is GPLv2 + License: GPLv2 and GPLv2+ + Group: System Environment/Base +-Release: 1%{?dist}.7 ++Release: 1%{?dist}.8 + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz + +@@ -49,6 +49,7 @@ Patch6: dhclient-restrict-interfaces-to-those-on-c.patch + Patch7: support-interface-promisc.patch + Patch8: 0001-dhclient-remove-1-arg.patch + Patch9: 0001-force-delay-check-link-down.patch ++Patch10: run-ifdown-on-all-interfaces.patch + + %description + The initscripts package contains basic system scripts used +@@ -75,6 +76,7 @@ Currently, this consists of various memory checking code. + %patch7 -p1 + %patch8 -p1 + %patch9 -p1 ++%patch10 -p1 + + %build + make +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/spec-add-mountnfs-init-script.patch b/core/initscripts/centos/meta_patches/spec-add-mountnfs-init-script.patch new file mode 100644 index 000000000..9e9588019 --- /dev/null +++ b/core/initscripts/centos/meta_patches/spec-add-mountnfs-init-script.patch @@ -0,0 +1,58 @@ +From 06e0a487c74c650c261bd09e8e9b27e69c3bae89 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 05/13] WRS: spec-add-mountnfs-init-script.patch + +--- + SPECS/initscripts.spec | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 6ec4bea..5ba669b 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -11,9 +11,12 @@ Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{ + # WRS + Source1: sysctl.conf + Source2: sysconfig-network.conf ++Source3: mountnfs.sh ++Source4: mountnfs.service + + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + Obsoletes: initscripts-legacy <= 9.39 ++Requires: /usr/bin/systemctl + Requires: /bin/awk, sed, coreutils + Requires: /sbin/sysctl + Requires: grep +@@ -93,6 +96,11 @@ chmod 600 $RPM_BUILD_ROOT/etc/crypttab + install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/etc/sysctl.conf + install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/etc/sysconfig/network + ++mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d ++install -m 755 %{SOURCE3} $RPM_BUILD_ROOT/etc/rc.d/init.d/mountnfs ++ ++install -m 644 %{SOURCE4} $RPM_BUILD_ROOT/%{_unitdir}/mountnfs.service ++ + %pre + /usr/sbin/groupadd -g 22 -r -f utmp + +@@ -101,6 +109,7 @@ touch /var/log/wtmp /var/run/utmp /var/log/btmp + chown root:utmp /var/log/wtmp /var/run/utmp /var/log/btmp + chmod 664 /var/log/wtmp /var/run/utmp + chmod 600 /var/log/btmp ++/usr/bin/systemctl enable mountnfs.service > /dev/null 2>&1 || : + + /usr/sbin/chkconfig --add network + /usr/sbin/chkconfig --add netconsole +@@ -226,6 +235,8 @@ rm -rf $RPM_BUILD_ROOT + %ghost %{_localstatedir}/log/dmesg.old + # WRS + /etc/sysconfig/network ++/etc/rc.d/init.d/mountnfs ++%{_unitdir}/mountnfs.service + + %files -n debugmode + %defattr(-,root,root) +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/spec-ifup-eth-stop-waiting-if-link-is-up.patch b/core/initscripts/centos/meta_patches/spec-ifup-eth-stop-waiting-if-link-is-up.patch new file mode 100644 index 000000000..b24e578a4 --- /dev/null +++ b/core/initscripts/centos/meta_patches/spec-ifup-eth-stop-waiting-if-link-is-up.patch @@ -0,0 +1,32 @@ +From 2a4fe5935b7d9714752119e2a0b296a2d7202cd3 Mon Sep 17 00:00:00 2001 +From: Denny Khoerniawan +Date: Wed, 15 Nov 2017 14:09:05 -0500 +Subject: [PATCH] spec: ifup-eth stop waiting if link is up + +--- + SPECS/initscripts.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 82c5be0..3adb83f 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -54,6 +54,7 @@ Patch10: run-ifdown-on-all-interfaces.patch + Patch11: sysconfig-affirmative-check-for-link-carrier.patch + Patch12: sysconfig-unsafe-usage-of-linkdelay-variable.patch + Patch13: ipv6-static-route-support.patch ++Patch14: ifup-eth-stop-waiting-if-link-is-up.patch + + %description + The initscripts package contains basic system scripts used +@@ -84,6 +85,7 @@ Currently, this consists of various memory checking code. + %patch11 -p1 + %patch12 -p1 + %patch13 -p1 ++%patch14 -p1 + + + %build +-- +1.8.3.1 + diff --git a/core/initscripts/centos/meta_patches/spec-include-TiS-changes.patch b/core/initscripts/centos/meta_patches/spec-include-TiS-changes.patch new file mode 100644 index 000000000..efb277d31 --- /dev/null +++ b/core/initscripts/centos/meta_patches/spec-include-TiS-changes.patch @@ -0,0 +1,61 @@ +From 9caa7a0860a8adcf38047fb39b6e1577099104d6 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 01/13] WRS: spec-include-TiS-changes.patch + +Conflicts: + SPECS/initscripts.spec +--- + SPECS/initscripts.spec | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 6b81095..7f93a30 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -7,6 +7,10 @@ Group: System Environment/Base + Release: 1%{?dist} + URL: https://github.com/fedora-sysv/initscripts + Source: https://github.com/fedora-sysv/initscripts/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz ++ ++# WRS ++Source1: sysctl.conf ++ + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + Obsoletes: initscripts-legacy <= 9.39 + Requires: /bin/awk, sed, coreutils +@@ -35,6 +39,10 @@ Requires(preun): /sbin/chkconfig + BuildRequires: glib2-devel popt-devel gettext pkgconfig + Provides: /sbin/service + ++Patch4: support-interface-scriptlets.patch ++Patch5: relocate-dhclient-leases-to-var-run.patch ++Patch6: dhclient-restrict-interfaces-to-those-on-c.patch ++ + %description + The initscripts package contains basic system scripts used + during a boot of the system. It also contains scripts which +@@ -54,6 +62,10 @@ Currently, this consists of various memory checking code. + %prep + %setup -q + ++%patch4 -p1 ++%patch5 -p1 ++%patch6 -p1 ++ + %build + make + +@@ -74,6 +86,9 @@ rm -f \ + touch $RPM_BUILD_ROOT/etc/crypttab + chmod 600 $RPM_BUILD_ROOT/etc/crypttab + ++# WRS: Overwrite with our config ++install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/etc/sysctl.conf ++ + %pre + /usr/sbin/groupadd -g 22 -r -f utmp + +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/spec-run-dhclient-as-daemon-for-ipv6.patch b/core/initscripts/centos/meta_patches/spec-run-dhclient-as-daemon-for-ipv6.patch new file mode 100644 index 000000000..e7632452f --- /dev/null +++ b/core/initscripts/centos/meta_patches/spec-run-dhclient-as-daemon-for-ipv6.patch @@ -0,0 +1,32 @@ +From 6c9a61e5ff22f2834dcc5ab91d32b370ef6a878c Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 22 Dec 2017 15:01:11 -0500 +Subject: [PATCH] spec: run dhclient as daemon for ipv6 + +--- + SPECS/initscripts.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 3adb83f..1ab8bb2 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -55,6 +55,7 @@ Patch11: sysconfig-affirmative-check-for-link-carrier.patch + Patch12: sysconfig-unsafe-usage-of-linkdelay-variable.patch + Patch13: ipv6-static-route-support.patch + Patch14: ifup-eth-stop-waiting-if-link-is-up.patch ++Patch15: run-dhclient-as-daemon-for-ipv6.patch + + %description + The initscripts package contains basic system scripts used +@@ -86,6 +87,7 @@ Currently, this consists of various memory checking code. + %patch12 -p1 + %patch13 -p1 + %patch14 -p1 ++%patch15 -p1 + + + %build +-- +1.8.3.1 + diff --git a/core/initscripts/centos/meta_patches/spec-sysconfig-affirmative-check-for-link-carrier.patch b/core/initscripts/centos/meta_patches/spec-sysconfig-affirmative-check-for-link-carrier.patch new file mode 100644 index 000000000..2e151327b --- /dev/null +++ b/core/initscripts/centos/meta_patches/spec-sysconfig-affirmative-check-for-link-carrier.patch @@ -0,0 +1,33 @@ +From 55e24310e0c7c9027d7b3c5d232e28988daebce9 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 10/13] WRS: + spec-sysconfig-affirmative-check-for-link-carrier.patch + +--- + SPECS/initscripts.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index fd84a75..e3748e5 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -50,6 +50,7 @@ Patch7: support-interface-promisc.patch + Patch8: 0001-dhclient-remove-1-arg.patch + Patch9: 0001-force-delay-check-link-down.patch + Patch10: run-ifdown-on-all-interfaces.patch ++Patch11: sysconfig-affirmative-check-for-link-carrier.patch + + %description + The initscripts package contains basic system scripts used +@@ -77,6 +78,7 @@ Currently, this consists of various memory checking code. + %patch8 -p1 + %patch9 -p1 + %patch10 -p1 ++%patch11 -p1 + + %build + make +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/spec-sysconfig-unsafe-usage-of-linkdelay-variable.patch b/core/initscripts/centos/meta_patches/spec-sysconfig-unsafe-usage-of-linkdelay-variable.patch new file mode 100644 index 000000000..9d5f5f509 --- /dev/null +++ b/core/initscripts/centos/meta_patches/spec-sysconfig-unsafe-usage-of-linkdelay-variable.patch @@ -0,0 +1,33 @@ +From 7d7f3dc174164989d47cb103a766e68f818f5f64 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 11/13] WRS: + spec-sysconfig-unsafe-usage-of-linkdelay-variable.patch + +--- + SPECS/initscripts.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index e3748e5..f2d0271 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -51,6 +51,7 @@ Patch8: 0001-dhclient-remove-1-arg.patch + Patch9: 0001-force-delay-check-link-down.patch + Patch10: run-ifdown-on-all-interfaces.patch + Patch11: sysconfig-affirmative-check-for-link-carrier.patch ++Patch12: sysconfig-unsafe-usage-of-linkdelay-variable.patch + + %description + The initscripts package contains basic system scripts used +@@ -79,6 +80,7 @@ Currently, this consists of various memory checking code. + %patch9 -p1 + %patch10 -p1 + %patch11 -p1 ++%patch12 -p1 + + %build + make +-- +1.9.1 + diff --git a/core/initscripts/centos/meta_patches/stop-creating-shared-dirs.patch b/core/initscripts/centos/meta_patches/stop-creating-shared-dirs.patch new file mode 100644 index 000000000..c9c6e16df --- /dev/null +++ b/core/initscripts/centos/meta_patches/stop-creating-shared-dirs.patch @@ -0,0 +1,44 @@ +From f93a873f57cf8134e371668c7514923e6fda80f3 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:49:27 -0400 +Subject: [PATCH 02/13] WRS: stop-creating-shared-dirs.patch + +--- + SPECS/initscripts.spec | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/SPECS/initscripts.spec b/SPECS/initscripts.spec +index 7f93a30..5349c54 100644 +--- a/SPECS/initscripts.spec ++++ b/SPECS/initscripts.spec +@@ -176,10 +176,7 @@ rm -rf $RPM_BUILD_ROOT + /usr/lib/systemd/rhel-* + /usr/lib/systemd/system/* + /etc/inittab +-%dir /etc/rc.d +-%dir /etc/rc.d/rc[0-9].d + /etc/rc[0-9].d +-%dir /etc/rc.d/init.d + /etc/rc.d/init.d/* + %config(noreplace) /etc/sysctl.conf + /usr/lib/sysctl.d/00-system.conf +@@ -201,7 +198,6 @@ rm -rf $RPM_BUILD_ROOT + /usr/sbin/ppp-watch + %{_mandir}/man*/* + %dir %attr(775,root,root) /var/run/netreport +-%dir /etc/ppp + %dir /etc/ppp/peers + /etc/ppp/ip-up + /etc/ppp/ip-down +@@ -209,8 +205,6 @@ rm -rf $RPM_BUILD_ROOT + /etc/ppp/ip-down.ipv6to4 + /etc/ppp/ipv6-up + /etc/ppp/ipv6-down +-%dir /etc/NetworkManager +-%dir /etc/NetworkManager/dispatcher.d + /etc/NetworkManager/dispatcher.d/00-netreport + %doc sysconfig.txt sysvinitfiles static-routes-ipv6 ipv6-tunnel.howto ipv6-6to4.howto changes.ipv6 COPYING + %doc examples +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/0001-dhclient-remove-1-arg.patch b/core/initscripts/centos/patches/0001-dhclient-remove-1-arg.patch new file mode 100644 index 000000000..0f8eb9ec1 --- /dev/null +++ b/core/initscripts/centos/patches/0001-dhclient-remove-1-arg.patch @@ -0,0 +1,26 @@ +From 11bc780fc8c7cfc7bbc59dcd84f3735c1cabfd30 Mon Sep 17 00:00:00 2001 +From: Ludovic Beliveau +Date: Mon, 30 May 2016 10:12:43 -0400 +Subject: [PATCH 1/1] dhclient remove -1 arg + +--- + sysconfig/network-scripts/ifup-eth | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sysconfig/network-scripts/ifup-eth b/sysconfig/network-scripts/ifup-eth +index fdbbf13..439c4c5 100755 +--- a/sysconfig/network-scripts/ifup-eth ++++ b/sysconfig/network-scripts/ifup-eth +@@ -195,7 +195,8 @@ if [ -n "${DYNCONFIG}" ] && [ -x /sbin/dhclient ]; then + generate_lease_file_name + + # Initialize the dhclient args and obtain the hostname options if needed: +- DHCLIENTARGS="${DHCLIENTARGS} ${ONESHOT} -q ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient-${DEVICE}.pid" ++ # DHCLIENTARGS="${DHCLIENTARGS} ${ONESHOT} -q ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient-${DEVICE}.pid" ++ DHCLIENTARGS="${DHCLIENTARGS} ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient-${DEVICE}.pid" + set_hostname_options DHCLIENTARGS + + echo +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/0001-force-delay-check-link-down.patch b/core/initscripts/centos/patches/0001-force-delay-check-link-down.patch new file mode 100644 index 000000000..566f539f7 --- /dev/null +++ b/core/initscripts/centos/patches/0001-force-delay-check-link-down.patch @@ -0,0 +1,25 @@ +From 6afaa4c6e0f4ca0821da986e3e4cc1a0bf56bebb Mon Sep 17 00:00:00 2001 +From: Ludovic Beliveau +Date: Thu, 9 Jun 2016 23:05:17 -0400 +Subject: [PATCH 1/1] force-delay-check-link-down + +--- + sysconfig/network-scripts/network-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysconfig/network-scripts/network-functions b/sysconfig/network-scripts/network-functions +index 080101b..798f28a 100644 +--- a/sysconfig/network-scripts/network-functions ++++ b/sysconfig/network-scripts/network-functions +@@ -460,7 +460,7 @@ check_link_down () + ip link set dev $1 up >/dev/null 2>&1 + fi + timeout=0 +- delay=10 ++ delay=20 + [ -n "$LINKDELAY" ] && delay=$(($LINKDELAY * 2)) + while [ $timeout -le $delay ]; do + [ "$(cat /sys/class/net/$REALDEVICE/carrier 2>/dev/null)" != "0" ] && return 1 +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/dhclient-restrict-interfaces-to-those-on-c.patch b/core/initscripts/centos/patches/dhclient-restrict-interfaces-to-those-on-c.patch new file mode 100644 index 000000000..c7d94866c --- /dev/null +++ b/core/initscripts/centos/patches/dhclient-restrict-interfaces-to-those-on-c.patch @@ -0,0 +1,63 @@ +From bafc4d1f7971edbe7cd411fbe2ee6876ded35c6e Mon Sep 17 00:00:00 2001 +From: Allain Legacy +Date: Thu, 14 Apr 2016 12:04:55 -0400 +Subject: [PATCH] CGTS-3416: dhclient: restrict interfaces to those on command + line only + +By default, the dhclient process does not respect the list of interfaces +supplied at the command line. It configures any interfaces found to be +specified in the config file. Since we customize options for each interface in +our config file and run a separate dhclient process for each interface we end +up with multiple dhclient processes that each service all interfaces. This is +undesirable because it is possible that a request is sent by process A but +received by process B. This leads to lease expiry events even though a valid +request packet was returned by the server. + +This change introduces a "--restrict-interfaces" option to the dhclient process +to force it to ignore all interfaces in config files other than those specified +at the command line. + +To activate this change our version of ifup/ifdown has been modified to +pass the "--restrict-interfaces" to dhclient as well as to request that each +process use its own lease file to avoid file corruption. +--- + sysconfig/network-scripts/ifdown-eth | 2 +- + sysconfig/network-scripts/ifup-eth | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sysconfig/network-scripts/ifdown-eth b/sysconfig/network-scripts/ifdown-eth +index 7ccbddf..5b75162 100755 +--- a/sysconfig/network-scripts/ifdown-eth ++++ b/sysconfig/network-scripts/ifdown-eth +@@ -93,6 +93,6 @@ for VER in "" 6 ; do + generate_lease_file_name $VER + if is_true "$DHCPRELEASE"; then +- /sbin/dhclient -r -lf ${LEASEFILE} -pf /var/run/dhclient$VER-${DEVICE}.pid ${DEVICE} >/dev/null 2>&1 ++ /sbin/dhclient -r -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient$VER-${DEVICE}.pid ${DEVICE} >/dev/null 2>&1 + retcode=$? + else + kill $dhcpid >/dev/null 2>&1 +diff --git a/sysconfig/network-scripts/ifup-eth b/sysconfig/network-scripts/ifup-eth +index 3da5c16..9bcf57f 100755 +--- a/sysconfig/network-scripts/ifup-eth ++++ b/sysconfig/network-scripts/ifup-eth +@@ -187,7 +187,7 @@ if [ -n "${DYNCONFIG}" ] && [ -x /sbin/dhclient ]; then + generate_lease_file_name + + # Initialize the dhclient args and obtain the hostname options if needed: +- DHCLIENTARGS="${DHCLIENTARGS} ${ONESHOT} -q ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient-${DEVICE}.pid" ++ DHCLIENTARGS="${DHCLIENTARGS} ${ONESHOT} -q ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient-${DEVICE}.pid" + set_hostname_options DHCLIENTARGS + + echo +@@ -333,6 +333,6 @@ if is_true "${DHCPV6C}" && [ -x /sbin/dhclient ]; then + + # Initialize the dhclient args for IPv6 and obtain the hostname options if needed: +- DHCLIENTARGS="-6 -1 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} -pf /var/run/dhclient6-${DEVICE}.pid ${DEVICE}" ++ DHCLIENTARGS="-6 -1 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient6-${DEVICE}.pid ${DEVICE}" + set_hostname_options DHCLIENTARGS + + if /sbin/dhclient $DHCLIENTARGS; then +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/ifup-eth-stop-waiting-if-link-is-up.patch b/core/initscripts/centos/patches/ifup-eth-stop-waiting-if-link-is-up.patch new file mode 100644 index 000000000..01059551e --- /dev/null +++ b/core/initscripts/centos/patches/ifup-eth-stop-waiting-if-link-is-up.patch @@ -0,0 +1,52 @@ +From 358cb3c0c8feed5ecfaa8ebfc56b7742b88bb14a Mon Sep 17 00:00:00 2001 +From: Denny Khoerniawan +Date: Wed, 15 Nov 2017 14:02:49 -0500 +Subject: [PATCH] ifup-eth stop waiting if link is up + +--- + sysconfig/network-scripts/ifup-eth | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/sysconfig/network-scripts/ifup-eth b/sysconfig/network-scripts/ifup-eth +index 192ad18..4b8b992 100755 +--- a/sysconfig/network-scripts/ifup-eth ++++ b/sysconfig/network-scripts/ifup-eth +@@ -151,7 +151,7 @@ if [ "$ISALIAS" = no ] && is_bonding_device ${DEVICE} ; then + /sbin/ifup ${device##*/} || net_log "Unable to start slave device ${device##*/} for master ${DEVICE}." warning + done + +- [ -n "${LINKDELAY}" ] && /bin/sleep ${LINKDELAY} ++ check_link_down ${DEVICE} + + # add the bits to setup the needed post enslavement parameters + for arg in $BONDING_OPTS ; do +@@ -171,7 +171,7 @@ if [ -n "${BRIDGE}" ] && [ -x /usr/sbin/brctl ]; then + /sbin/ip addr flush dev ${DEVICE} 2>/dev/null + /sbin/ip link set dev ${DEVICE} up + ethtool_set +- [ -n "${LINKDELAY}" ] && /bin/sleep ${LINKDELAY} ++ check_link_down ${DEVICE} + /usr/sbin/brctl addif -- ${BRIDGE} ${DEVICE} + # add the bits to setup driver parameters here + for arg in $BRIDGING_OPTS ; do +@@ -227,7 +227,7 @@ else + # enable device without IP, useful for e.g. PPPoE + ip link set dev ${REALDEVICE} up + ethtool_set +- [ -n "${LINKDELAY}" ] && /bin/sleep ${LINKDELAY} ++ check_link_down ${REALDEVICE} + else + + expand_config +@@ -242,7 +242,7 @@ else + + ethtool_set + +- [ -n "${LINKDELAY}" ] && /bin/sleep ${LINKDELAY} ++ check_link_down ${REAL_DEVICE} + + if [ "${DEVICE}" = "lo" ]; then + SCOPE="scope host" +-- +1.8.3.1 + diff --git a/core/initscripts/centos/patches/ipv6-static-route-support.patch b/core/initscripts/centos/patches/ipv6-static-route-support.patch new file mode 100644 index 000000000..52473cd87 --- /dev/null +++ b/core/initscripts/centos/patches/ipv6-static-route-support.patch @@ -0,0 +1,29 @@ +From e47e3faa2a3a35018e111dbd061a2e529cf77f9c Mon Sep 17 00:00:00 2001 +From: Kevin Smith +Date: Tue, 17 Oct 2017 10:46:00 -0500 +Subject: [PATCH 1/1] ipv6 static route support + +--- + sysconfig/network-scripts/ifup-routes | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sysconfig/network-scripts/ifup-routes b/sysconfig/network-scripts/ifup-routes +index ff8d5b5..a82d053 100755 +--- a/sysconfig/network-scripts/ifup-routes ++++ b/sysconfig/network-scripts/ifup-routes +@@ -32,9 +32,11 @@ handle_ip_file() { + if [ "$type" != "$t" ]; then + proto="-6" + fi ++ # remove proto input from below so we can keep ++ # ipv6 routes in a route- file as well. + { cat "$file" ; echo ; } | while read line; do + if [[ ! "$line" =~ $MATCH ]]; then +- /sbin/ip $proto $type add $line ++ /sbin/ip $type add $line + fi + done + } +-- +1.8.3.1 + diff --git a/core/initscripts/centos/patches/relocate-dhclient-leases-to-var-run.patch b/core/initscripts/centos/patches/relocate-dhclient-leases-to-var-run.patch new file mode 100644 index 000000000..07899e3cc --- /dev/null +++ b/core/initscripts/centos/patches/relocate-dhclient-leases-to-var-run.patch @@ -0,0 +1,30 @@ +From 6a3a3047ad47570ccdb9b758c8417a66447be697 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Thu, 5 Oct 2017 12:31:18 -0400 +Subject: [PATCH 2/9] WRS: Patch5-relocate-dhclient-leases-to-var-run.patch + +--- + sysconfig/network-scripts/network-functions | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sysconfig/network-scripts/network-functions b/sysconfig/network-scripts/network-functions +index 1867c38..080101b 100644 +--- a/sysconfig/network-scripts/network-functions ++++ b/sysconfig/network-scripts/network-functions +@@ -65,11 +65,11 @@ get_uuid_by_config () + generate_lease_file_name () + { + local ver=$1 +- LEASEFILE="/var/lib/dhclient/dhclient$ver-${DEVICE}.leases" ++ LEASEFILE="/var/run/dhclient$ver-${DEVICE}.leases" + if [ -f $LEASEFILE ]; then + return + fi +- LEASEFILE="/var/lib/dhclient/dhclient$ver-${UUID}-${DEVICE}.lease" ++ LEASEFILE="/var/run/dhclient$ver-${UUID}-${DEVICE}.lease" + } + + generate_config_file_name () +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/run-dhclient-as-daemon-for-ipv6.patch b/core/initscripts/centos/patches/run-dhclient-as-daemon-for-ipv6.patch new file mode 100644 index 000000000..04501c87b --- /dev/null +++ b/core/initscripts/centos/patches/run-dhclient-as-daemon-for-ipv6.patch @@ -0,0 +1,34 @@ +From 580624314b1b93f84264e9d60583dcde4f6b86f3 Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Thu, 11 Jan 2018 11:18:19 -0500 +Subject: [PATCH] run dhclient as daemon for ipv6. + +--- + sysconfig/network-scripts/ifup-eth | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/sysconfig/network-scripts/ifup-eth b/sysconfig/network-scripts/ifup-eth +index 4b8b992..ccb5c75 100755 +--- a/sysconfig/network-scripts/ifup-eth ++++ b/sysconfig/network-scripts/ifup-eth +@@ -341,13 +341,14 @@ if is_true "${DHCPV6C}" && [ -x /sbin/dhclient ]; then + echo -n $"Determining IPv6 information for ${DEVICE}..." + + # Initialize the dhclient args for IPv6 and obtain the hostname options if needed: +- DHCLIENTARGS="-6 -1 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient6-${DEVICE}.pid ${DEVICE}" ++ DHCLIENTARGS="-6 ${DHCPV6C_OPTIONS} ${DHCLIENTCONF} -lf ${LEASEFILE} --restrict-interfaces -pf /var/run/dhclient6-${DEVICE}.pid ${DEVICE}" + set_hostname_options DHCLIENTARGS + +- if /sbin/dhclient $DHCLIENTARGS; then ++ if /sbin/dhclient -1 $DHCLIENTARGS; then + echo $" done." + else +- echo $" failed." ++ /sbin/dhclient $DHCLIENTARGS& ++ echo $" failed. Retrying in background." + if [ "${dhcpipv4}" = "good" -o -n "${IPADDR}" ]; then + net_log "Unable to obtain IPv6 DHCP address ${DEVICE}." warning + else +-- +1.8.3.1 + diff --git a/core/initscripts/centos/patches/run-ifdown-on-all-interfaces.patch b/core/initscripts/centos/patches/run-ifdown-on-all-interfaces.patch new file mode 100644 index 000000000..30f40412a --- /dev/null +++ b/core/initscripts/centos/patches/run-ifdown-on-all-interfaces.patch @@ -0,0 +1,26 @@ +From 76a5f892c132eed05a6cbffbdba3306e50b6a672 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Thu, 5 Oct 2017 12:40:38 -0400 +Subject: [PATCH 7/9] WRS: Patch10-run-ifdown-on-all-interfaces.patch + +--- + rc.d/init.d/network | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rc.d/init.d/network b/rc.d/init.d/network +index a8deed3..852ef94 100755 +--- a/rc.d/init.d/network ++++ b/rc.d/init.d/network +@@ -214,6 +214,9 @@ stop) + if ! check_device_down $DEVICE; then + action $"Shutting down interface $i: " ./ifdown $i boot + [ $? -ne 0 ] && rc=1 ++ else ++ action $"Shutting down non-UP interface $i: " ./ifdown $i boot ++ logger $"Running ifdown on non-UP interface $i" + fi + ) + done +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/support-interface-promisc.patch b/core/initscripts/centos/patches/support-interface-promisc.patch new file mode 100644 index 000000000..336346939 --- /dev/null +++ b/core/initscripts/centos/patches/support-interface-promisc.patch @@ -0,0 +1,53 @@ +From f50fd7a0a9b53ba475d85670a5428876e13dac36 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Thu, 5 Oct 2017 12:37:06 -0400 +Subject: [PATCH 4/9] WRS: Patch7-support-interface-promisc.patch + +--- + sysconfig/network-scripts/ifdown-eth | 5 +++++ + sysconfig/network-scripts/ifup-eth | 8 ++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/sysconfig/network-scripts/ifdown-eth b/sysconfig/network-scripts/ifdown-eth +index 5b75162..60f1ba2 100755 +--- a/sysconfig/network-scripts/ifdown-eth ++++ b/sysconfig/network-scripts/ifdown-eth +@@ -181,4 +181,9 @@ if [ -n "$VLAN" ]; then + fi + fi + ++# WRS: Support PROMISC ++if [ "${PROMISC}" = yes ]; then ++ ip link set dev ${DEVICE} promisc off ++fi ++ + exit $retcode +diff --git a/sysconfig/network-scripts/ifup-eth b/sysconfig/network-scripts/ifup-eth +index 9bcf57f..fdbbf13 100755 +--- a/sysconfig/network-scripts/ifup-eth ++++ b/sysconfig/network-scripts/ifup-eth +@@ -111,6 +111,11 @@ if [ -n "${MTU}" ]; then + ip link set dev ${DEVICE} mtu ${MTU} + fi + ++# WRS: Support PROMISC ++if [ "${PROMISC}" = yes ]; then ++ ip link set dev ${DEVICE} promisc on ++fi ++ + # is the device wireless? If so, configure wireless device specifics + is_wireless_device ${DEVICE} && . ./ifup-wireless + +@@ -130,6 +135,9 @@ if [ "${SLAVE}" = yes -a "${ISALIAS}" = no -a "${MASTER}" != "" ]; then + } + ethtool_set + ++ # WRS: Flush addresses ++ ip addr flush dev ${DEVICE} ++ + exit 0 + fi + +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/support-interface-scriptlets.patch b/core/initscripts/centos/patches/support-interface-scriptlets.patch new file mode 100644 index 000000000..a94fcbafc --- /dev/null +++ b/core/initscripts/centos/patches/support-interface-scriptlets.patch @@ -0,0 +1,91 @@ +From b5fb31139b18385f295debe8acdb25c23b6f8b87 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Thu, 5 Oct 2017 12:30:03 -0400 +Subject: [PATCH 1/9] WRS: Patch4-support-interface-scriptlets.patch + +--- + sysconfig/network-scripts/ifdown | 6 ++++++ + sysconfig/network-scripts/ifdown-post | 12 ++++++++++++ + sysconfig/network-scripts/ifup | 6 ++++++ + sysconfig/network-scripts/ifup-post | 12 ++++++++++++ + 4 files changed, 36 insertions(+) + +diff --git a/sysconfig/network-scripts/ifdown b/sysconfig/network-scripts/ifdown +index 90b1c83..88c1d74 100755 +--- a/sysconfig/network-scripts/ifdown ++++ b/sysconfig/network-scripts/ifdown +@@ -58,6 +58,12 @@ if [ -x /sbin/ifdown-pre-local ]; then + /sbin/ifdown-pre-local ${DEVICE} + fi + ++# WRS: Execute pre-down commands. ++if [ -n "$pre_down" ]; then ++ eval $pre_down ++ [ "$?" != "0" ] && exit 1 ++fi ++ + OTHERSCRIPT="/etc/sysconfig/network-scripts/ifdown-${DEVICETYPE}" + + if [ ! -x ${OTHERSCRIPT} ]; then +diff --git a/sysconfig/network-scripts/ifdown-post b/sysconfig/network-scripts/ifdown-post +index 8b56e14..bd4198a 100755 +--- a/sysconfig/network-scripts/ifdown-post ++++ b/sysconfig/network-scripts/ifdown-post +@@ -61,4 +61,16 @@ if [ -x /sbin/ifdown-local ]; then + /sbin/ifdown-local ${DEVICE} + fi + ++# WRS: Execute down commands. ++if [ -n "$down" ]; then ++ eval $down ++ [ "$?" != "0" ] && exit 1 ++fi ++ ++# WRS: Execute post-down commands. ++if [ -n "$post_down" ]; then ++ eval $post_down ++ [ "$?" != "0" ] && exit 1 ++fi ++ + exit 0 +diff --git a/sysconfig/network-scripts/ifup b/sysconfig/network-scripts/ifup +index d25db5a..07c63a5 100755 +--- a/sysconfig/network-scripts/ifup ++++ b/sysconfig/network-scripts/ifup +@@ -151,6 +151,12 @@ if [ -x /sbin/ifup-pre-local ]; then + /sbin/ifup-pre-local ${CONFIG} $2 + fi + ++# WRS: Execute pre-up commands. ++if [ -n "$pre_up" ]; then ++ eval $pre_up ++ [ "$?" != "0" ] && exit 1 ++fi ++ + OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${DEVICETYPE}" + + if [ ! -x ${OTHERSCRIPT} ]; then +diff --git a/sysconfig/network-scripts/ifup-post b/sysconfig/network-scripts/ifup-post +index ab0710b..3b76492 100755 +--- a/sysconfig/network-scripts/ifup-post ++++ b/sysconfig/network-scripts/ifup-post +@@ -117,4 +117,16 @@ if [ -x /sbin/ifup-local ]; then + /sbin/ifup-local ${DEVICE} + fi + ++# WRS: Execute up commands. ++if [ -n "$up" ]; then ++ eval $up ++ [ "$?" != "0" ] && exit 1 ++fi ++ ++# WRS: Execute post-up commands. ++if [ -n "$post_up" ]; then ++ eval $post_up ++ [ "$?" != "0" ] && exit 1 ++fi ++ + exit 0 +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/sysconfig-affirmative-check-for-link-carrier.patch b/core/initscripts/centos/patches/sysconfig-affirmative-check-for-link-carrier.patch new file mode 100644 index 000000000..6abdacd33 --- /dev/null +++ b/core/initscripts/centos/patches/sysconfig-affirmative-check-for-link-carrier.patch @@ -0,0 +1,42 @@ +From 974b70a23b6a6c579fc4d43efd42e42f26c27310 Mon Sep 17 00:00:00 2001 +From: Allain Legacy +Date: Thu, 17 Nov 2016 08:27:42 -0500 +Subject: [PATCH] sysconfig: affirmative check for link carrier + +The /sys/class/net//carrier attribute is supposed to return 0 or 1 to +indicate whether a link carrier is present or not. This holds true for regular +ethernet devices but for special devices, such as VLAN interfaces, it appears +to be possible that it returns an error on stderr and nothing on stdout in some +scenarios. One such scenario is if the lower interface of a VLAN is +administratively down then checking the carrier status of the VLAN returns +"invalid argument". + +Because of the way the check_link_down() function is currently coded a failure +to produce any output on stdout is interpreted as a sign that the link carrier +is present. That is, the empty string "" is not equal to "0" therefore the +check passes. + +To avoid this scenario we are changing this to a more affirmative check so that +it won't actually pass until stdout returns "1". + +Signed-off-by: Allain Legacy +--- + sysconfig/network-scripts/network-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysconfig/network-scripts/network-functions b/sysconfig/network-scripts/network-functions +index 798f28a..affa8ba 100644 +--- a/sysconfig/network-scripts/network-functions ++++ b/sysconfig/network-scripts/network-functions +@@ -463,7 +463,7 @@ check_link_down () + delay=20 + [ -n "$LINKDELAY" ] && delay=$(($LINKDELAY * 2)) + while [ $timeout -le $delay ]; do +- [ "$(cat /sys/class/net/$REALDEVICE/carrier 2>/dev/null)" != "0" ] && return 1 ++ [ "$(cat /sys/class/net/$REALDEVICE/carrier 2>/dev/null)" == "1" ] && return 1 + usleep 500000 + timeout=$((timeout+1)) + done +-- +1.9.1 + diff --git a/core/initscripts/centos/patches/sysconfig-unsafe-usage-of-linkdelay-variable.patch b/core/initscripts/centos/patches/sysconfig-unsafe-usage-of-linkdelay-variable.patch new file mode 100644 index 000000000..391803810 --- /dev/null +++ b/core/initscripts/centos/patches/sysconfig-unsafe-usage-of-linkdelay-variable.patch @@ -0,0 +1,33 @@ +From d3d109136f6e01ec1d8291ff89f3e00ff64cab31 Mon Sep 17 00:00:00 2001 +From: Allain Legacy +Date: Thu, 17 Nov 2016 11:37:38 -0500 +Subject: [PATCH] sysconfig: unsafe usage of linkdelay variable + +If the LINKDELAY variable is an alphabetic string instead of an integer then +the calculation in check_link_down() causes delay to be set to 0. That causes +the loop to never execute and for the caller to think that the link is always +down. + +This does not address but is related to CGTS-5821 + +Signed-off-by: Allain Legacy +--- + sysconfig/network-scripts/network-functions | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysconfig/network-scripts/network-functions b/sysconfig/network-scripts/network-functions +index affa8ba..a9821f6 100644 +--- a/sysconfig/network-scripts/network-functions ++++ b/sysconfig/network-scripts/network-functions +@@ -461,7 +461,7 @@ check_link_down () + fi + timeout=0 + delay=20 +- [ -n "$LINKDELAY" ] && delay=$(($LINKDELAY * 2)) ++ [[ $LINKDELAY =~ ^[0-9]+$ ]] && delay=$(($LINKDELAY * 2)) + while [ $timeout -le $delay ]; do + [ "$(cat /sys/class/net/$REALDEVICE/carrier 2>/dev/null)" == "1" ] && return 1 + usleep 500000 +-- +1.9.1 + diff --git a/core/initscripts/centos/srpm_path b/core/initscripts/centos/srpm_path new file mode 100644 index 000000000..4559f33fb --- /dev/null +++ b/core/initscripts/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/initscripts-9.49.39-1.el7.src.rpm diff --git a/core/initscripts/files/mountnfs.service b/core/initscripts/files/mountnfs.service new file mode 100644 index 000000000..e7b53d2bb --- /dev/null +++ b/core/initscripts/files/mountnfs.service @@ -0,0 +1,13 @@ +[Unit] +Description=Titanium Cloud Filesystem Auto-mounter +After=network.target +Before=uexportfs.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/etc/init.d/mountnfs start +ExecStop=/etc/init.d/mountnfs stop + +[Install] +WantedBy=multi-user.target diff --git a/core/initscripts/files/mountnfs.sh b/core/initscripts/files/mountnfs.sh new file mode 100755 index 000000000..acc07797b --- /dev/null +++ b/core/initscripts/files/mountnfs.sh @@ -0,0 +1,103 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: mountnfs +# Required-Start: $local_fs $network $rpcbind +# Required-Stop: +# Default-Start: S +# Default-Stop: +### END INIT INFO + +# . /etc/default/rcS + +if [ "$1" = "stop" ]; then + # Avoid mounting if we're shutting down + exit 0 +fi + +# +# Run in a subshell because of I/O redirection. +# +test -f /etc/fstab && ( + +# +# Read through fstab line by line. If it is NFS, set the flag +# for mounting NFS filesystems. If any NFS partition is found and it +# not mounted with the nolock option, we start the rpcbind. +# +rpcbind=no +mount_nfs=no +mount_smb=no +mount_ncp=no +mount_cifs=no +while read device mountpt fstype options +do + case "$device" in + ""|\#*) + continue + ;; + esac + + case "$options" in + *noauto*) + continue + ;; + esac + + if test "$fstype" = nfs + then + mount_nfs=yes + case "$options" in + *nolock*) + ;; + *) + rpcbind=yes + ;; + esac + fi + if test "$fstype" = smbfs + then + mount_smb=yes + fi + if test "$fstype" = ncpfs + then + mount_ncp=yes + fi + if test "$fstype" = cifs + then + mount_cifs=yes + fi +done + +exec 0>&1 + +if test "$rpcbind" = yes +then + # WRL: Centos precheck: Dont start rpcbind in this init script. + # It is started by a systemd service file. + if test "/etc/centos-release" = no + then + if test -x /usr/sbin/rpcbind + then + service rpcbind status > /dev/null + if [ $? != 0 ]; then + echo -n "Starting rpcbind..." + start-stop-daemon --start --quiet --exec /usr/sbin/rpcbind + sleep 2 + fi + fi + fi +fi + +if test "$mount_nfs" = yes || test "$mount_smb" = yes || test "$mount_ncp" = yes || test "$mount_cifs" = yes +then + echo "Mounting remote filesystems..." + test "$mount_nfs" = yes && mount -a -t nfs + test "$mount_smb" = yes && mount -a -t smbfs + test "$mount_ncp" = yes && mount -a -t ncpfs + test "$mount_cifs" = yes && mount -a -t cifs +fi + +) < /etc/fstab + +: exit 0 + diff --git a/core/util-linux/centos/build_srpm.data b/core/util-linux/centos/build_srpm.data new file mode 100644 index 000000000..dc8e77429 --- /dev/null +++ b/core/util-linux/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$CGCS_BASE/mwa-sparta/extended/shadow/files/pam.d/su" +TIS_PATCH_VER=3 diff --git a/core/util-linux/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/core/util-linux/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..68db6d0a3 --- /dev/null +++ b/core/util-linux/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From e665a4b1693745e5c97c14c473e531883225df12 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:55:36 -0400 +Subject: [PATCH 3/3] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/util-linux.spec +--- + SPECS/util-linux.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/util-linux.spec b/SPECS/util-linux.spec +index bed4869..2388f6a 100644 +--- a/SPECS/util-linux.spec ++++ b/SPECS/util-linux.spec +@@ -2,7 +2,7 @@ + Summary: A collection of basic system utilities + Name: util-linux + Version: 2.23.2 +-Release: 43%{?dist} ++Release: 43.el7%{?_tis_dist}.%{tis_patch_ver} + License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain + Group: System Environment/Base + URL: http://en.wikipedia.org/wiki/Util-linux +-- +1.9.1 + diff --git a/core/util-linux/centos/meta_patches/0003-util-linux-login-pamd.patch b/core/util-linux/centos/meta_patches/0003-util-linux-login-pamd.patch new file mode 100644 index 000000000..68d7a5e83 --- /dev/null +++ b/core/util-linux/centos/meta_patches/0003-util-linux-login-pamd.patch @@ -0,0 +1,38 @@ +From 48483baf9bcce5fbf9040f1f400eea9a0fd76c86 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:55:36 -0400 +Subject: [PATCH 2/3] WRS: 0003-util-linux-login-pamd.patch + +--- + SOURCES/util-linux-login.pamd | 1 + + SPECS/util-linux.spec | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/SOURCES/util-linux-login.pamd b/SOURCES/util-linux-login.pamd +index 3c03927..9c57d31 100644 +--- a/SOURCES/util-linux-login.pamd ++++ b/SOURCES/util-linux-login.pamd +@@ -7,6 +7,7 @@ account include system-auth + password include system-auth + # pam_selinux.so close should be the first session rule + session required pam_selinux.so close ++session required pam_mkhomedir.so skel=/etc/skel umask=0022 + session required pam_loginuid.so + session optional pam_console.so + # pam_selinux.so open should only be followed by sessions to be executed in the user context +diff --git a/SPECS/util-linux.spec b/SPECS/util-linux.spec +index 8d4dae6..bed4869 100644 +--- a/SPECS/util-linux.spec ++++ b/SPECS/util-linux.spec +@@ -688,7 +688,7 @@ fi + + %config(noreplace) %{_sysconfdir}/pam.d/chfn + %config(noreplace) %{_sysconfdir}/pam.d/chsh +-%config(noreplace) %{_sysconfdir}/pam.d/login ++%config %{_sysconfdir}/pam.d/login + %config(noreplace) %{_sysconfdir}/pam.d/remote + %config(noreplace) %{_sysconfdir}/pam.d/su + %config(noreplace) %{_sysconfdir}/pam.d/su-l +-- +1.9.1 + diff --git a/core/util-linux/centos/meta_patches/PATCH_ORDER b/core/util-linux/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..c841c9d00 --- /dev/null +++ b/core/util-linux/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +spec-use-su-file-from-shadow.patch +0003-util-linux-login-pamd.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/core/util-linux/centos/meta_patches/spec-use-su-file-from-shadow.patch b/core/util-linux/centos/meta_patches/spec-use-su-file-from-shadow.patch new file mode 100644 index 000000000..a892b782f --- /dev/null +++ b/core/util-linux/centos/meta_patches/spec-use-su-file-from-shadow.patch @@ -0,0 +1,33 @@ +From 8e1cb6a69f144137d23ecaf94d704f35c8c7a9d6 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 14:55:36 -0400 +Subject: [PATCH 1/3] WRS: spec-use-su-file-from-shadow.patch + +--- + SPECS/util-linux.spec | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/SPECS/util-linux.spec b/SPECS/util-linux.spec +index 27d18a9..8d4dae6 100644 +--- a/SPECS/util-linux.spec ++++ b/SPECS/util-linux.spec +@@ -41,6 +41,7 @@ Source12: util-linux-su.pamd + Source13: util-linux-su-l.pamd + Source14: util-linux-runuser.pamd + Source15: util-linux-runuser-l.pamd ++Source16: su + + ### Obsoletes & Conflicts & Provides + Conflicts: bash-completion < 1:2.1-1 +@@ -561,7 +562,7 @@ chmod 755 ${RPM_BUILD_ROOT}%{_bindir}/sunhostid + install -m 644 %{SOURCE2} ./remote + install -m 644 %{SOURCE3} ./chsh + install -m 644 %{SOURCE3} ./chfn +- install -m 644 %{SOURCE12} ./su ++ install -m 644 %{SOURCE16} ./su + install -m 644 %{SOURCE13} ./su-l + install -m 644 %{SOURCE14} ./runuser + install -m 644 %{SOURCE15} ./runuser-l +-- +1.9.1 + diff --git a/core/util-linux/centos/srpm_path b/core/util-linux/centos/srpm_path new file mode 100644 index 000000000..1099936c4 --- /dev/null +++ b/core/util-linux/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/util-linux-2.23.2-43.el7.src.rpm diff --git a/devtools/facter/centos/build_srpm.data b/devtools/facter/centos/build_srpm.data new file mode 100644 index 000000000..0eac83bbb --- /dev/null +++ b/devtools/facter/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=4 diff --git a/devtools/facter/centos/meta_patches/0001-spec-include-TiS-paches.patch b/devtools/facter/centos/meta_patches/0001-spec-include-TiS-paches.patch new file mode 100644 index 000000000..3284b2d7f --- /dev/null +++ b/devtools/facter/centos/meta_patches/0001-spec-include-TiS-paches.patch @@ -0,0 +1,42 @@ +From 0960bacb6c19c7af74cb77d27ae925a7af5d3410 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 09:58:00 -0400 +Subject: [PATCH 1/2] WRS: spec-include-TiS-paches.patch + +--- + SPECS/facter.spec | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/SPECS/facter.spec b/SPECS/facter.spec +index 97ee783..7996d45 100644 +--- a/SPECS/facter.spec ++++ b/SPECS/facter.spec +@@ -31,6 +31,13 @@ Source0: https://downloads.puppetlabs.com/%{name}/%{name}-%{version}.tar. + Source1: https://downloads.puppetlabs.com/%{name}/%{name}-%{version}.tar.gz.asc + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + ++# WRS patches ++Patch0: ps.patch ++Patch1: personality.patch ++Patch2: centos_remove-net-commands-that-can-timeout.patch ++Patch3: centos_fix-ipv6-regex.patch ++ ++ + # Upstream claims to only support 1.8.7 and higher + BuildRequires: ruby >= 1.8.7 + BuildRequires: ruby-devel +@@ -71,6 +78,11 @@ key off the values returned by facts. + + %prep + %setup -q ++# WRS apply patches ++%patch0 -p1 ++%patch1 -p1 ++%patch2 -p2 ++%patch3 -p2 + + %build + # Nothing to build +-- +1.8.3.1 + diff --git a/devtools/facter/centos/meta_patches/0002-Update-package-versioning-for-TIS-format.patch b/devtools/facter/centos/meta_patches/0002-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..37ba76298 --- /dev/null +++ b/devtools/facter/centos/meta_patches/0002-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From fa978faa31b6b3806664f7729d9d190dfdaba862 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 09:58:00 -0400 +Subject: [PATCH 2/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/facter.spec +--- + SPECS/facter.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/facter.spec b/SPECS/facter.spec +index 7996d45..aa4a0db 100644 +--- a/SPECS/facter.spec ++++ b/SPECS/facter.spec +@@ -20,7 +20,7 @@ + + Name: facter + Version: 2.4.4 +-Release: 4%{?dist} ++Release: 4.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Command and ruby library for gathering system information + Epoch: 1 + +-- +1.8.3.1 + diff --git a/devtools/facter/centos/meta_patches/0003-Add-ipaddress-patch.patch b/devtools/facter/centos/meta_patches/0003-Add-ipaddress-patch.patch new file mode 100644 index 000000000..ee5ca6ff3 --- /dev/null +++ b/devtools/facter/centos/meta_patches/0003-Add-ipaddress-patch.patch @@ -0,0 +1,48 @@ +From 26fa177280c21f0c2048c90ae8fdd3ded7a60113 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Thu, 26 Oct 2017 10:44:17 -0400 +Subject: [PATCH] Add ipaddress patch + +--- + SPECS/facter.spec | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/SPECS/facter.spec b/SPECS/facter.spec +index aa4a0db..2829879 100644 +--- a/SPECS/facter.spec ++++ b/SPECS/facter.spec +@@ -32,10 +32,11 @@ Source1: https://downloads.puppetlabs.com/%{name}/%{name}-%{version}.tar. + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + + # WRS patches +-Patch0: ps.patch +-Patch1: personality.patch +-Patch2: centos_remove-net-commands-that-can-timeout.patch +-Patch3: centos_fix-ipv6-regex.patch ++Patch0001: 0001-ps.patch ++Patch0002: 0002-personality.patch ++Patch0003: 0003-centos_remove-net-commands-that-can-timeout.patch ++Patch0004: 0004-centos_fix-ipv6-regex.patch ++Patch0005: 0005-Hardcode-ipaddress-fact-to-localhost.patch + + + # Upstream claims to only support 1.8.7 and higher +@@ -79,10 +80,11 @@ key off the values returned by facts. + %prep + %setup -q + # WRS apply patches +-%patch0 -p1 +-%patch1 -p1 +-%patch2 -p2 +-%patch3 -p2 ++%patch0001 -p1 ++%patch0002 -p1 ++%patch0003 -p2 ++%patch0004 -p2 ++%patch0005 -p1 + + %build + # Nothing to build +-- +1.8.3.1 + diff --git a/devtools/facter/centos/meta_patches/PATCH_ORDER b/devtools/facter/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..00edf2f3a --- /dev/null +++ b/devtools/facter/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-spec-include-TiS-paches.patch +0002-Update-package-versioning-for-TIS-format.patch +0003-Add-ipaddress-patch.patch diff --git a/devtools/facter/centos/patches/0001-ps.patch b/devtools/facter/centos/patches/0001-ps.patch new file mode 100644 index 000000000..b0fa55378 --- /dev/null +++ b/devtools/facter/centos/patches/0001-ps.patch @@ -0,0 +1,30 @@ +--- + lib/facter/ps.rb | 2 +- + spec/unit/ps_spec.rb | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/lib/facter/ps.rb ++++ b/lib/facter/ps.rb +@@ -11,7 +11,7 @@ + # + + Facter.add(:ps) do +- setcode do 'ps -ef' end ++ setcode do 'ps -efww' end + end + + Facter.add(:ps) do +--- a/spec/unit/ps_spec.rb ++++ b/spec/unit/ps_spec.rb +@@ -27,9 +27,9 @@ describe "ps facts" do + 'RedHat', + 'Debian', + ].each do |os| +- it "should return gnu/linux style ps -ef on operatingsystem #{os}" do ++ it "should return gnu/linux style ps -efww on operatingsystem #{os}" do + Facter.fact(:operatingsystem).stubs(:value).returns os +- Facter.fact(:ps).value.should == 'ps -ef' ++ Facter.fact(:ps).value.should == 'ps -efww' + end + end + diff --git a/devtools/facter/centos/patches/0002-personality.patch b/devtools/facter/centos/patches/0002-personality.patch new file mode 100644 index 000000000..0291d6fcd --- /dev/null +++ b/devtools/facter/centos/patches/0002-personality.patch @@ -0,0 +1,93 @@ +--- + lib/facter/personality.rb | 21 ++++++++++++++++++ + lib/facter/subfunction.rb | 61 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 82 insertions(+) + +--- /dev/null ++++ b/lib/facter/personality.rb +@@ -0,0 +1,21 @@ ++# ++# personality.rb ++# ++# This fact gives the personality of this node. ++# ++require 'facter/util/file_read' ++ ++Facter.add('personality') do ++ confine :kernel => :linux ++ ++ setcode do ++ if release = Facter::Util::FileRead.read('/etc/platform/platform.conf') ++ if match = release.match(/^nodetype\=(.*)/) ++ match[1] ++ end ++ end ++ end ++end ++ ++# vim: set ts=2 sw=2 et : ++# encoding: utf-8 +--- /dev/null ++++ b/lib/facter/subfunction.rb +@@ -0,0 +1,61 @@ ++# ++# subfunction.rb ++# ++# This fact gives the subfunction of this node. ++# ++require 'facter/util/file_read' ++ ++Facter.add('subfunction') do ++ confine :kernel => :linux ++ ++ setcode do ++ if release = Facter::Util::FileRead.read('/etc/platform/platform.conf') ++ if match = release.match(/^subfunction\=(.*)/) ++ match[1] ++ end ++ end ++ end ++end ++ ++Facter.add('is_compute_subfunction') do ++ confine :kernel => :linux ++ ++ setcode do ++ if release = Facter::Util::FileRead.read('/etc/platform/platform.conf') ++ match = release.match(/^subfunction\=.*compute/) ? true : false ++ end ++ end ++end ++ ++Facter.add('is_controller_subfunction') do ++ confine :kernel => :linux ++ ++ setcode do ++ if release = Facter::Util::FileRead.read('/etc/platform/platform.conf') ++ match = release.match(/^subfunction\=.*controller/) ? true : false ++ end ++ end ++end ++ ++Facter.add('is_storage_subfunction') do ++ confine :kernel => :linux ++ ++ setcode do ++ if release = Facter::Util::FileRead.read('/etc/platform/platform.conf') ++ match = release.match(/^subfunction\=.*storage/) ? true : false ++ end ++ end ++end ++ ++Facter.add('is_lowlatency_subfunction') do ++ confine :kernel => :linux ++ ++ setcode do ++ if release = Facter::Util::FileRead.read('/etc/platform/platform.conf') ++ match = release.match(/^subfunction\=.*lowlatency/) ? true : false ++ end ++ end ++end ++ ++# vim: set ts=2 sw=2 et : ++# encoding: utf-8 diff --git a/devtools/facter/centos/patches/0003-centos_remove-net-commands-that-can-timeout.patch b/devtools/facter/centos/patches/0003-centos_remove-net-commands-that-can-timeout.patch new file mode 100644 index 000000000..a17672ff1 --- /dev/null +++ b/devtools/facter/centos/patches/0003-centos_remove-net-commands-that-can-timeout.patch @@ -0,0 +1,55 @@ +--- + facter-2.4.4/lib/facter/domain.rb | 24 +++++++++++++----------- + facter-2.4.4/lib/facter/uniqueid.rb | 9 +++++---- + 2 files changed, 18 insertions(+), 15 deletions(-) + +--- a/facter-2.4.4/lib/facter/domain.rb ++++ b/facter-2.4.4/lib/facter/domain.rb +@@ -33,22 +33,24 @@ Facter.add(:domain) do + full_hostname = 'hostname -f 2> /dev/null' + can_do_hostname_f = Regexp.union /Linux/i, /FreeBSD/i, /Darwin/i + +- hostname_command = if Facter.value(:kernel) =~ can_do_hostname_f +- full_hostname +- elsif Facter.value(:kernel) == "windows" +- windows_hostname +- else +- basic_hostname +- end ++ # Because hostname -f doesn't work for IPv6, don't use that flag ++ # hostname_command = if Facter.value(:kernel) =~ can_do_hostname_f ++ # full_hostname ++ # elsif Facter.value(:kernel) == "windows" ++ # windows_hostname ++ # else ++ # basic_hostname ++ # end ++ hostname_command = basic_hostname + + if name = Facter::Core::Execution.exec(hostname_command) \ + and name =~ /.*?\.(.+$)/ + + return_value = $1 +- elsif Facter.value(:kernel) != "windows" and domain = Facter::Core::Execution.exec('dnsdomainname 2> /dev/null') \ +- and domain =~ /.+/ +- +- return_value = domain ++ # elsif Facter.value(:kernel) != "windows" and domain = Facter::Core::Execution.exec('dnsdomainname 2> /dev/null') \ ++ # and domain =~ /.+/ ++ # ++ # return_value = domain + elsif FileTest.exists?("/etc/resolv.conf") + domain = nil + search = nil +--- a/facter-2.4.4/lib/facter/uniqueid.rb ++++ b/facter-2.4.4/lib/facter/uniqueid.rb +@@ -1,4 +1,5 @@ +-Facter.add(:uniqueid) do +- setcode 'hostid' +- confine :kernel => %w{SunOS Linux AIX GNU/kFreeBSD} +-end ++# hostid does not work with IPv6, and is not needed for Titanium cloud, so remove ++# Facter.add(:uniqueid) do ++# setcode 'hostid' ++# confine :kernel => %w{SunOS Linux AIX GNU/kFreeBSD} ++# end diff --git a/devtools/facter/centos/patches/0004-centos_fix-ipv6-regex.patch b/devtools/facter/centos/patches/0004-centos_fix-ipv6-regex.patch new file mode 100644 index 000000000..47012090e --- /dev/null +++ b/devtools/facter/centos/patches/0004-centos_fix-ipv6-regex.patch @@ -0,0 +1,15 @@ +--- + facter-2.4.4/lib/facter/util/ip.rb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/facter-2.4.4/lib/facter/util/ip.rb ++++ b/facter-2.4.4/lib/facter/util/ip.rb +@@ -6,7 +6,7 @@ module Facter::Util::IP + REGEX_MAP = { + :linux => { + :ipaddress => /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/, +- :ipaddress6 => /inet6 (?:addr: )?((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/, ++ :ipaddress6 => /inet6 (?:addr: )?((?!(fe80|\:\:1))(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/, + :macaddress => /(?:ether|HWaddr)\s+((\w{1,2}:){5,}\w{1,2})/, + :netmask => /(?:Mask:|netmask )([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/, + :mtu => /MTU:?\s*(\d+)/i diff --git a/devtools/facter/centos/patches/0005-Hardcode-ipaddress-fact-to-localhost.patch b/devtools/facter/centos/patches/0005-Hardcode-ipaddress-fact-to-localhost.patch new file mode 100644 index 000000000..3af562c09 --- /dev/null +++ b/devtools/facter/centos/patches/0005-Hardcode-ipaddress-fact-to-localhost.patch @@ -0,0 +1,188 @@ +From af1818469ed789bad373e6c0f8d29669acc39669 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Thu, 26 Oct 2017 10:44:20 -0400 +Subject: [PATCH] Hardcode ipaddress fact to localhost + +--- + lib/facter/ipaddress.rb | 163 +----------------------------------------------- + 1 file changed, 2 insertions(+), 161 deletions(-) + +diff --git a/lib/facter/ipaddress.rb b/lib/facter/ipaddress.rb +index 6179a4d..4c54791 100644 +--- a/lib/facter/ipaddress.rb ++++ b/lib/facter/ipaddress.rb +@@ -1,169 +1,10 @@ + # Fact: ipaddress + # +-# Purpose: Return the main IP address for a host. ++# To avoid potential timeouts with this fact, just return 127.0.0.1 always + # +-# Resolution: +-# On the Unixes does an ifconfig, and returns the first non 127.0.0.0/8 +-# subnetted IP it finds. +-# On Windows, it attempts to use the socket library and resolve the machine's +-# hostname via DNS. +-# +-# On LDAP based hosts it tries to use either the win32/resolv library to +-# resolve the hostname to an IP address, or on Unix, it uses the resolv +-# library. +-# +-# As a fall back for undefined systems, it tries to run the "host" command to +-# resolve the machine's hostname using the system DNS. +-# +-# Caveats: +-# DNS resolution relies on working DNS infrastructure and resolvers on the +-# host system. +-# The ifconfig parsing purely takes the first IP address it finds without any +-# checking this is a useful IP address. +-# +- +-require 'facter/util/ip' +- +-Facter.add(:ipaddress) do +- confine :kernel => :linux +- setcode do +- ip = nil +- output = Facter::Util::IP.exec_ifconfig(["2>/dev/null"]) +- if output +- regexp = /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ +- output.split("\n").each do |line| +- match = regexp.match(line) +- if match and not /^127\./.match(match[1]) +- ip = match[1] +- break +- end +- end +- end +- ip +- end +-end +- +-Facter.add(:ipaddress) do +- confine :kernel => %w{FreeBSD OpenBSD Darwin DragonFly} +- setcode do +- ip = nil +- output = Facter::Util::IP.exec_ifconfig +- +- output.split(/^\S/).each do |str| +- if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ +- tmp = $1 +- unless tmp =~ /^127\./ +- ip = tmp +- break +- end +- end +- end +- +- ip +- end +-end + + Facter.add(:ipaddress) do +- confine :kernel => %w{NetBSD SunOS} +- setcode do +- ip = nil +- output = Facter::Util::IP.exec_ifconfig(["-a"]) +- +- output.split(/^\S/).each do |str| +- if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ +- tmp = $1 +- unless tmp =~ /^127\./ or tmp == "0.0.0.0" +- ip = tmp +- break +- end +- end +- end +- +- ip +- end +-end +- +-Facter.add(:ipaddress) do +- confine :kernel => %w{AIX} +- setcode do +- ip = nil +- +- default_interface = Facter::Util::IP.exec_netstat(["-rn | grep default | awk '{ print $6 }'"]) +- output = Facter::Util::IP.exec_ifconfig([default_interface]) +- +- output.split(/^\S/).each do |str| +- if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ +- ip = $1 +- end +- end +- +- ip +- end +-end +- +-Facter.add(:ipaddress) do +- confine :kernel => %w{windows} +- setcode do +- require 'facter/util/ip/windows' +- ipaddr = nil +- +- adapters = Facter::Util::IP::Windows.get_preferred_ipv4_adapters +- adapters.find do |nic| +- nic.IPAddress.any? do |addr| +- ipaddr = addr if Facter::Util::IP::Windows.valid_ipv4_address?(addr) +- ipaddr +- end +- end +- +- ipaddr +- end +-end +- +-Facter.add(:ipaddress, :timeout => 2) do +- setcode do +- if Facter.value(:kernel) == 'windows' +- require 'win32/resolv' +- else +- require 'resolv' +- end +- +- begin +- if hostname = Facter.value(:hostname) +- if Facter.value(:kernel) == 'windows' +- ip = Win32::Resolv.get_resolv_info.last[0] +- else +- ip = Resolv.getaddress(hostname) +- end +- unless ip == "127.0.0.1" +- ip +- end +- else +- nil +- end +- rescue Resolv::ResolvError +- nil +- rescue NoMethodError # i think this is a bug in resolv.rb? +- nil +- end +- end +-end +- +-Facter.add(:ipaddress, :timeout => 2) do + setcode do +- if hostname = Facter.value(:hostname) +- # we need Hostname to exist for this to work +- host = nil +- if host = Facter::Core::Execution.execute("host #{hostname}") +- list = host.chomp.split(/\s/) +- if defined? list[-1] and +- list[-1] =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ +- list[-1] +- end +- else +- nil +- end +- else +- nil +- end ++ "127.0.0.1" + end + end +-- +1.8.3.1 + diff --git a/devtools/facter/centos/srpm_path b/devtools/facter/centos/srpm_path new file mode 100644 index 000000000..91675a53d --- /dev/null +++ b/devtools/facter/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/facter-2.4.4-4.el7.src.rpm diff --git a/devtools/nfscheck/recipes-common/nfscheck/LICENSE b/devtools/nfscheck/recipes-common/nfscheck/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/devtools/nfscheck/recipes-common/nfscheck/PKG-INFO b/devtools/nfscheck/recipes-common/nfscheck/PKG-INFO new file mode 100644 index 000000000..0800a1145 --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/PKG-INFO @@ -0,0 +1,14 @@ +Metadata-Version: 1.1 +Name: nfscheck +Version: 1.0 +Summary: NFS Audit +Home-page: +Author: +Author-email: +License: Apache-2.0 + +Description: +NFS Audit + + +Platform: UNKNOWN diff --git a/devtools/nfscheck/recipes-common/nfscheck/centos/build_srpm.data b/devtools/nfscheck/recipes-common/nfscheck/centos/build_srpm.data new file mode 100644 index 000000000..4498c84d5 --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="LICENSE files/*" +TIS_PATCH_VER=0 diff --git a/devtools/nfscheck/recipes-common/nfscheck/centos/nfscheck.spec b/devtools/nfscheck/recipes-common/nfscheck/centos/nfscheck.spec new file mode 100644 index 000000000..4ba09bd0e --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/centos/nfscheck.spec @@ -0,0 +1,43 @@ +Name: nfscheck +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +Summary: NFS Audit + +Group: base +License: Apache-2.0 +URL: unknown +Source0: nfscheck.sh +Source1: nfscheck.service +Source2: LICENSE + +Requires: systemd +Requires: util-linux + +%description +NFS Audit + + +%prep + + +%build + + +%install +install -d -m 755 %{buildroot}/usr/bin/ +install -m 755 %{SOURCE0} %{buildroot}/usr/bin/nfscheck.sh + +install -d -m 755 %{buildroot}/usr/lib/systemd/system/ +install -m 664 %{SOURCE1} %{buildroot}/usr/lib/systemd/system/nfscheck.service + +%post +/usr/bin/systemctl enable nfscheck.service >/dev/null 2>&1 + +%files +%license ../SOURCES/LICENSE +/usr/bin/* +/usr/lib/systemd/system/* + + +%changelog + diff --git a/devtools/nfscheck/recipes-common/nfscheck/files/LICENSE b/devtools/nfscheck/recipes-common/nfscheck/files/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/files/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck-init.sh b/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck-init.sh new file mode 100755 index 000000000..ac2d86920 --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck-init.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# +# Copyright (c) 2013-2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + + +# chkconfig: 345 99 10 + +### BEGIN INIT INFO +# Provides: nfscheck +# Required-Start: $syslog +# Required-Stop: $syslog +# Default-Start: 2 3 5 +# Default-Stop: 0 1 6 +# Short-Description: nfscheck +# Description: NFS Audit +### END INIT INFO + +DESC="nfscheck" +DAEMON="/usr/bin/nfscheck" +PIDFILE="/var/run/nfscheck.pid" + +start() +{ + if [ -e $PIDFILE ]; then + PIDDIR=/proc/$(cat $PIDFILE) + if [ -d ${PIDDIR} ]; then + echo "$DESC already running." + exit 1 + else + echo "Removing stale PID file $PIDFILE" + rm -f $PIDFILE + fi + fi + + echo -n "Starting $DESC..." + + start-stop-daemon --start --quiet --background \ + --pidfile ${PIDFILE} --make-pidfile --exec ${DAEMON} + + if [ $? -eq 0 ]; then + echo "done." + else + echo "failed." + fi +} + +stop() +{ + echo -n "Stopping $DESC..." + start-stop-daemon --stop --quiet --pidfile $PIDFILE + if [ $? -eq 0 ]; then + echo "done." + else + echo "failed." + fi + rm -f $PIDFILE +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|force-reload) + stop + start + ;; + *) + echo "Usage: $0 {start|stop|force-reload|restart}" + exit 1 + ;; +esac + +exit 0 diff --git a/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.service b/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.service new file mode 100644 index 000000000..e83300e8e --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.service @@ -0,0 +1,10 @@ +[Unit] +Description=nfscheck +After=syslog.target network.target nfs-mountd.service sw-patch.service + +[Service] +Type=simple +ExecStart=/bin/sh /usr/bin/nfscheck.sh + +[Install] +WantedBy=multi-user.target diff --git a/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.sh b/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.sh new file mode 100644 index 000000000..f58ab80ef --- /dev/null +++ b/devtools/nfscheck/recipes-common/nfscheck/files/nfscheck.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# Copyright (c) 2013-2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + + +# The following script tests the NFS mount in order to log when it is hung + +MOUNT=/opt/platform +previous=1 +delay=60 + +while : +do + # First, check that it's actually an NFS mount + mount | grep -q $MOUNT + if [ $? -ne 0 ] + then + logger -t NFSCHECK "$MOUNT is not mounted" + previous=1 + sleep $delay + continue + fi + + ls $MOUNT >/dev/null 2>&1 & + + sleep $delay + + # At this point, jobs will either report no jobs (empty) or Done, + # unless the job is still running/hung + rc=$(jobs) + if [[ -z "$rc" || $rc =~ "Done" ]] + then + # NFS is successful + if [ $previous -ne 0 ] + then + logger -t NFSCHECK "NFS test of $MOUNT is ok" + previous=0 + fi + else + # Keep waiting until the job is done + while ! [[ -z "$rc" || $rc =~ "Done" ]] + do + logger -t NFSCHECK "NFS test of $MOUNT is failed" + previous=1 + sleep $delay + rc=$(jobs) + done + fi +done + diff --git a/devtools/puppet-4.8.2/centos/build_srpm.data b/devtools/puppet-4.8.2/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/devtools/puppet-4.8.2/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/devtools/puppet-4.8.2/centos/meta_patches/0000-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-4.8.2/centos/meta_patches/0000-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..6e157d9c1 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/meta_patches/0000-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 2cc29381484f15cb9e60d94491ebb260402edea1 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 2 Oct 2017 08:29:19 -0500 +Subject: [PATCH 1/1] Update package versioning for TIS format + +--- + SPECS/puppet.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet.spec b/SPECS/puppet.spec +index 777abe2..023f74f 100644 +--- a/SPECS/puppet.spec ++++ b/SPECS/puppet.spec +@@ -19,7 +19,7 @@ + + Name: puppet + Version: 4.8.2 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: A network tool for managing many disparate systems + License: ASL 2.0 + URL: http://puppetlabs.com +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/meta_patches/0001-Add-WRS-Patches.patch b/devtools/puppet-4.8.2/centos/meta_patches/0001-Add-WRS-Patches.patch new file mode 100644 index 000000000..d8a26e558 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/meta_patches/0001-Add-WRS-Patches.patch @@ -0,0 +1,47 @@ +From 56181573a8d619e4685bd0023214724416eac91e Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 2 Oct 2017 09:24:33 -0500 +Subject: [PATCH 1/1] Add WRS Patches + +--- + SPECS/puppet.spec | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/SPECS/puppet.spec b/SPECS/puppet.spec +index 023f74f..284accf 100644 +--- a/SPECS/puppet.spec ++++ b/SPECS/puppet.spec +@@ -32,6 +32,15 @@ Source4: start-puppet-wrapper + # Puppetlabs messed up with default paths + Patch01: 0001-Fix-puppet-paths.patch + Patch02: 0002-Revert-maint-Remove-puppetmaster.service.patch ++ ++# WRS Patches ++Patch1001: 1001-Add-timestamps-to-logs.patch ++Patch1002: 1002-Set-hasstatus-to-false-by-default.patch ++Patch1003: 1003-Update-getpid-function.patch ++Patch1004: 1004-Block-enabling-of-services.patch ++Patch1005: 1005-Set-strict_variables-and-basemodulepath-in-puppet.co.patch ++ ++ + Group: System Environment/Base + + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +@@ -119,6 +128,14 @@ The server can also function as a certificate authority and file server. + %setup -q + %patch01 -p1 -b .paths + %patch02 -p1 -b .server ++ ++%patch1001 -p1 ++%patch1002 -p1 ++%patch1003 -p1 ++%patch1004 -p1 ++%patch1005 -p1 ++ ++ + # Unbundle + #rm -r lib/puppet/vendor/*{pathspec,rgen}* + +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/meta_patches/PATCH_ORDER b/devtools/puppet-4.8.2/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..e520faa1b --- /dev/null +++ b/devtools/puppet-4.8.2/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0000-Update-package-versioning-for-TIS-format.patch +0001-Add-WRS-Patches.patch diff --git a/devtools/puppet-4.8.2/centos/patches/1001-Add-timestamps-to-logs.patch b/devtools/puppet-4.8.2/centos/patches/1001-Add-timestamps-to-logs.patch new file mode 100644 index 000000000..7fa3c0f98 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/patches/1001-Add-timestamps-to-logs.patch @@ -0,0 +1,25 @@ +From 3dad4deb5e1de9be2a6722dc2f1716bb228a7c15 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 30 Dec 2016 11:01:22 -0500 +Subject: [PATCH] Add timestamps to logs + +--- + lib/puppet/util/log/destinations.rb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb +index fb8b6aa..10fff6e 100644 +--- a/lib/puppet/util/log/destinations.rb ++++ b/lib/puppet/util/log/destinations.rb +@@ -165,7 +165,7 @@ Puppet::Util::Log.newdesttype :console do + str = msg.source == "Puppet" ? str : "#{msg.source}: #{str}" + + level = levels[msg.level] +- level[:stream].puts colorize(level[:color], "#{level[:name]}: #{str}") ++ level[:stream].puts colorize(level[:color], "#{level[:name]}: #{msg.time} #{str}") + end + end + +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/patches/1002-Set-hasstatus-to-false-by-default.patch b/devtools/puppet-4.8.2/centos/patches/1002-Set-hasstatus-to-false-by-default.patch new file mode 100644 index 000000000..496847cb5 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/patches/1002-Set-hasstatus-to-false-by-default.patch @@ -0,0 +1,49 @@ +From a0ce82562d75c62fbe7258d0ed4e3ac6d0248ed4 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 30 Dec 2016 10:59:44 -0500 +Subject: [PATCH] Set hasstatus to false by default + +Many of the WR init scripts do not have proper status functions, +so set "hasstatus" to false by default. +--- + lib/puppet/provider/service/init.rb | 9 ++++++++- + lib/puppet/type/service.rb | 3 ++- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/lib/puppet/provider/service/init.rb b/lib/puppet/provider/service/init.rb +index 9f2d030..69940ca 100644 +--- a/lib/puppet/provider/service/init.rb ++++ b/lib/puppet/provider/service/init.rb +@@ -81,7 +81,14 @@ Puppet::Type.type(:service).provide :init, :parent => :base do + next if exclude.include? name + next if not FileTest.executable?(fullpath) + next if not is_init?(fullpath) +- instances << new(:name => name, :path => path, :hasstatus => true) ++ ++ # Try to determine whether the init script has "status" support via grep ++ grepcmd = "grep -q '\\/dev/null && echo true || echo false" ++ if Puppet::Util::Execution.execute(grepcmd) =~ /true/ ++ instances << new(:name => name, :path => path, :hasstatus => true) ++ else ++ instances << new(:name => name, :path => path, :hasstatus => false) ++ end + end + end + instances +diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb +index dc54f1d..2bab7fc 100644 +--- a/lib/puppet/type/service.rb ++++ b/lib/puppet/type/service.rb +@@ -134,7 +134,8 @@ module Puppet + + newvalues(:true, :false) + +- defaultto :true ++ # WRS: Change hasstatus default to false ++ defaultto :false + end + newparam(:name) do + desc <<-EOT +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/patches/1003-Update-getpid-function.patch b/devtools/puppet-4.8.2/centos/patches/1003-Update-getpid-function.patch new file mode 100644 index 000000000..48f816674 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/patches/1003-Update-getpid-function.patch @@ -0,0 +1,31 @@ +From 8ec18087109c7612553ec33d6c87aec1c7a622d1 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 4 Oct 2017 13:04:27 -0500 +Subject: [PATCH] Update getpid function + +Enhance the getpid function to avoid matching with the "puppet apply" command +--- + lib/puppet/provider/service/base.rb | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/puppet/provider/service/base.rb b/lib/puppet/provider/service/base.rb +index d72d408..b8ac2eb 100644 +--- a/lib/puppet/provider/service/base.rb ++++ b/lib/puppet/provider/service/base.rb +@@ -31,11 +31,12 @@ Puppet::Type.type(:service).provide :base, :parent => :service do + def getpid + @resource.fail "Either stop/status commands or a pattern must be specified" unless @resource[:pattern] + regex = Regexp.new(@resource[:pattern]) ++ regex_pa = Regexp.new('puppet apply') + ps = getps + self.debug "Executing '#{ps}'" + IO.popen(ps) { |table| + table.each_line { |line| +- if regex.match(line) ++ if regex.match(line) and not regex_pa.match(line) + self.debug "Process matched: #{line}" + ary = line.sub(/^\s+/, '').split(/\s+/) + return ary[1] +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/patches/1004-Block-enabling-of-services.patch b/devtools/puppet-4.8.2/centos/patches/1004-Block-enabling-of-services.patch new file mode 100644 index 000000000..6748eb6be --- /dev/null +++ b/devtools/puppet-4.8.2/centos/patches/1004-Block-enabling-of-services.patch @@ -0,0 +1,61 @@ +From 9b6966aa6b2b3c3a6876db1e2788d93f90899fa8 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 4 Oct 2017 14:31:23 -0500 +Subject: [PATCH] Block enabling of services + +--- + lib/puppet/provider/service/redhat.rb | 7 ++++--- + lib/puppet/provider/service/systemd.rb | 4 +++- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/lib/puppet/provider/service/redhat.rb b/lib/puppet/provider/service/redhat.rb +index 4f3f9b8..fe3723f 100644 +--- a/lib/puppet/provider/service/redhat.rb ++++ b/lib/puppet/provider/service/redhat.rb +@@ -7,6 +7,7 @@ Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init + " + + commands :chkconfig => "/sbin/chkconfig", :service => "/sbin/service" ++ commands :noop => "/bin/true" + + defaultfor :osfamily => :redhat + defaultfor :osfamily => :suse, :operatingsystemmajrelease => ["10", "11"] +@@ -42,10 +43,10 @@ Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init + # Don't support them specifying runlevels; always use the runlevels + # in the init scripts. + def enable +- chkconfig("--add", @resource[:name]) +- chkconfig(@resource[:name], :on) ++ # Do not enable services ++ noop(@resource[:name]) + rescue Puppet::ExecutionFailure => detail +- raise Puppet::Error, "Could not enable #{self.name}: #{detail}", detail.backtrace ++ raise Puppet::Error, "Could not enable #{self.name}", detail.backtrace + end + + def initscript +diff --git a/lib/puppet/provider/service/systemd.rb b/lib/puppet/provider/service/systemd.rb +index a673550..a4deed4 100644 +--- a/lib/puppet/provider/service/systemd.rb ++++ b/lib/puppet/provider/service/systemd.rb +@@ -8,6 +8,7 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do + providing the proper suffix." + + commands :systemctl => "systemctl" ++ commands :noop => "/bin/true" + + if Facter.value(:osfamily).downcase == 'debian' + # With multiple init systems on Debian, it is possible to have +@@ -118,7 +119,8 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do + + def enable + self.unmask +- systemctl_change_enable(:enable) ++ #systemctl_change_enable(:enable) ++ [command(:noop), @resource[:name]] + end + + def mask +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/patches/1005-Set-strict_variables-and-basemodulepath-in-puppet.co.patch b/devtools/puppet-4.8.2/centos/patches/1005-Set-strict_variables-and-basemodulepath-in-puppet.co.patch new file mode 100644 index 000000000..496035b48 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/patches/1005-Set-strict_variables-and-basemodulepath-in-puppet.co.patch @@ -0,0 +1,28 @@ +From bb145c103c03eabf7adf79d486c7143ebed3ad78 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 10 Oct 2017 09:41:17 -0500 +Subject: [PATCH] WRS: Patch1005: + 1005-Set-strict_variables-and-basemodulepath-in-puppet.co.patch + +Also sets ordering = title-hash so that puppet 4 will run the same as puppet 3 +--- + conf/puppet.conf | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/conf/puppet.conf b/conf/puppet.conf +index bf48823..15674d7 100644 +--- a/conf/puppet.conf ++++ b/conf/puppet.conf +@@ -4,3 +4,9 @@ + # - https://docs.puppetlabs.com/puppet/latest/reference/config_about_settings.html + # - https://docs.puppetlabs.com/puppet/latest/reference/config_file_main.html + # - https://docs.puppetlabs.com/puppet/latest/reference/configuration.html ++[main] ++ # Prevent the use of undefined variables ++ strict_variables = true ++ ordering = title-hash ++ # Set the path to TIS puppet modules ++ basemodulepath = /usr/share/puppet/modules:/usr/share/openstack-puppet/modules +-- +1.8.3.1 + diff --git a/devtools/puppet-4.8.2/centos/srpm_path b/devtools/puppet-4.8.2/centos/srpm_path new file mode 100644 index 000000000..d401ae082 --- /dev/null +++ b/devtools/puppet-4.8.2/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-4.8.2-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..c515061b8 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 6098a4fc06f27ce855fe777afb50b13e23f11e27 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 3 Jan 2017 13:44:33 -0500 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-ceilometer.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-ceilometer.spec b/SPECS/puppet-ceilometer.spec +index 76697c4..6b3a1b4 100644 +--- a/SPECS/puppet-ceilometer.spec ++++ b/SPECS/puppet-ceilometer.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-ceilometer + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Ceilometer + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0002-Add-Rebase-Patches.patch b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0002-Add-Rebase-Patches.patch new file mode 100644 index 000000000..89e7219ea --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0002-Add-Rebase-Patches.patch @@ -0,0 +1,33 @@ +From e2c17352768be4f66a5769876e78d0ba28c8abad Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 14 Nov 2017 09:51:47 -0600 +Subject: [PATCH] Add Rebase Patches + +--- + SPECS/puppet-ceilometer.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/puppet-ceilometer.spec b/SPECS/puppet-ceilometer.spec +index 5f93f86..a869999 100644 +--- a/SPECS/puppet-ceilometer.spec ++++ b/SPECS/puppet-ceilometer.spec +@@ -9,6 +9,8 @@ URL: https://launchpad.net/puppet-ceilometer + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + ++Patch0001: 0001-Roll-up-TIS-patches.patch ++ + BuildArch: noarch + + Requires: puppet-apache +@@ -24,6 +26,7 @@ Puppet module for OpenStack Ceilometer + + %prep + %setup -q -n openstack-ceilometer-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0003-meta-fix-ceilometer-puppet-warnings.patch b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0003-meta-fix-ceilometer-puppet-warnings.patch new file mode 100644 index 000000000..e5a1d825c --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/0003-meta-fix-ceilometer-puppet-warnings.patch @@ -0,0 +1,32 @@ +From 5ecbc776a6fdbd7065b6145c7fd82c03217b8205 Mon Sep 17 00:00:00 2001 +From: Angie Wang +Date: Mon, 29 Jan 2018 14:20:19 -0500 +Subject: [PATCH 1/1] meta fix ceilometer puppet warnings + +--- + SPECS/puppet-ceilometer.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-ceilometer.spec b/SPECS/puppet-ceilometer.spec +index a869999..5356f91 100644 +--- a/SPECS/puppet-ceilometer.spec ++++ b/SPECS/puppet-ceilometer.spec +@@ -10,6 +10,7 @@ URL: https://launchpad.net/puppet-ceilometer + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-Fix-ceilometer-puppet-warnings.patch + + BuildArch: noarch + +@@ -27,6 +28,7 @@ Puppet module for OpenStack Ceilometer + %prep + %setup -q -n openstack-ceilometer-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..12ae5cd53 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-Rebase-Patches.patch +0003-meta-fix-ceilometer-puppet-warnings.patch diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..42e28b28e --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,63 @@ +From ce72dedc948691a25848829798c8a4afd1a380d0 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 14 Nov 2017 09:48:56 -0600 +Subject: [PATCH] Roll up WRS patches to pike + +--- + manifests/db/sync.pp | 3 +++ + manifests/expirer.pp | 2 +- + manifests/params.pp | 4 ++-- + 3 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index db08f6d..7c9ab55 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -29,6 +29,9 @@ class ceilometer::db::sync( + Anchor['ceilometer::config::end'], + Anchor['ceilometer::dbsync::begin'] + ], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "test $::controller_sw_versions_match = true", + notify => Anchor['ceilometer::dbsync::end'], + } + +diff --git a/manifests/expirer.pp b/manifests/expirer.pp +index b69db8a..66847c5 100644 +--- a/manifests/expirer.pp ++++ b/manifests/expirer.pp +@@ -65,7 +65,7 @@ class ceilometer::expirer ( + ensure => $ensure, + command => $ceilometer::params::expirer_command, + environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh', +- user => 'ceilometer', ++ user => 'root', + minute => $minute, + hour => $hour, + monthday => $monthday, +diff --git a/manifests/params.pp b/manifests/params.pp +index 4550dbd..456d8f9 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -7,7 +7,7 @@ class ceilometer::params { + include ::openstacklib::defaults + + $dbsync_command = 'ceilometer-upgrade' +- $expirer_command = 'ceilometer-expirer' ++ $expirer_command = '/usr/bin/ceilometer-expirer-active' + $user = 'ceilometer' + $event_pipeline = '/etc/ceilometer/event_pipeline.yaml' + $pipeline = '/etc/ceilometer/pipeline.yaml' +@@ -33,7 +33,7 @@ class ceilometer::params { + $agent_notification_service_name = 'openstack-ceilometer-notification' + $ceilometer_wsgi_script_path = '/var/www/cgi-bin/ceilometer' + $ceilometer_wsgi_script_source = '/usr/lib/python2.7/site-packages/ceilometer/api/app.wsgi' +- $libvirt_group = undef ++ $libvirt_group = 'libvirt' + } + 'Debian': { + # package names +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0002-Fix-ceilometer-puppet-warnings.patch b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0002-Fix-ceilometer-puppet-warnings.patch new file mode 100644 index 000000000..25068fae2 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/patches/0002-Fix-ceilometer-puppet-warnings.patch @@ -0,0 +1,39 @@ +From c0061b1c127860b0a1a4d4a235094eb6c4fe6160 Mon Sep 17 00:00:00 2001 +From: Angie Wang +Date: Mon, 29 Jan 2018 12:56:00 -0500 +Subject: [PATCH 1/1] Fix ceilometer puppet warnings + +--- + manifests/api.pp | 2 +- + manifests/collector.pp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/manifests/api.pp b/manifests/api.pp +index 7a253c4..189fcfd 100644 +--- a/manifests/api.pp ++++ b/manifests/api.pp +@@ -62,7 +62,7 @@ class ceilometer::api ( + include ::ceilometer::params + include ::ceilometer::policy + +- warning('ceilometer-api has been deprecated in Ocata and will be removed in future. Please use Aodh, Gnocchi and Panko modules instead.') ++ # warning('ceilometer-api has been deprecated in Ocata and will be removed in future. Please use Aodh, Gnocchi and Panko modules instead.') + + if $auth_strategy == 'keystone' { + include ::ceilometer::keystone::authtoken +diff --git a/manifests/collector.pp b/manifests/collector.pp +index eb5b4f7..11cc4ab 100644 +--- a/manifests/collector.pp ++++ b/manifests/collector.pp +@@ -68,7 +68,7 @@ class ceilometer::collector ( + include ::ceilometer::deps + include ::ceilometer::params + +- warning('This class is deprecated. Now the pipeline.yaml can be configured directly to send data eg: gnocchi://') ++ # warning('This class is deprecated. Now the pipeline.yaml can be configured directly to send data eg: gnocchi://') + + # We accept udp_address to be set to empty instead of the usual undef to stay + # close to the "strange" upstream interface. +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/srpm_path new file mode 100644 index 000000000..c2ace8841 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceilometer-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-ceilometer-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/build_srpm.data new file mode 100644 index 000000000..0eac83bbb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=4 diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..3659e7667 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 8f4ade8974fdb044f86ab72533b5ce847875089d Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 3 Jan 2017 13:37:20 -0500 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-ceph.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-ceph.spec b/SPECS/puppet-ceph.spec +index ecde883..7f086c5 100644 +--- a/SPECS/puppet-ceph.spec ++++ b/SPECS/puppet-ceph.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-ceph + Version: 2.2.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Community Developed Ceph Module + License: Apache-2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0002-Add-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0002-Add-TIS-patches.patch new file mode 100644 index 000000000..a96e9cf71 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0002-Add-TIS-patches.patch @@ -0,0 +1,34 @@ +From ff91fc6138685fcaff0222686e83ba7d083e5630 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 7 Feb 2017 14:08:21 -0500 +Subject: [PATCH] Add TIS patches + +--- + SPECS/puppet-ceph.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/puppet-ceph.spec b/SPECS/puppet-ceph.spec +index 7f086c5..771eb26 100644 +--- a/SPECS/puppet-ceph.spec ++++ b/SPECS/puppet-ceph.spec +@@ -8,6 +8,8 @@ License: Apache-2.0 + URL: https://launchpad.net/puppet-ceph + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-Newton-rebase-fixes.patch + + BuildArch: noarch + +@@ -23,6 +25,8 @@ Community Developed Ceph Module + + %prep + %setup -q -n openstack-ceph-%{version} ++%patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0003-Ceph-Jewel-rebase.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0003-Ceph-Jewel-rebase.patch new file mode 100644 index 000000000..be7f031f7 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0003-Ceph-Jewel-rebase.patch @@ -0,0 +1,32 @@ +From 0fadbf6ad0702c390632e687656c91a48a417c99 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Thu, 23 Mar 2017 08:07:56 +0000 +Subject: [PATCH] ceph jewel rebase + +--- + SPECS/puppet-ceph.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-ceph.spec b/SPECS/puppet-ceph.spec +index cd07d2c..90d30d5 100644 +--- a/SPECS/puppet-ceph.spec ++++ b/SPECS/puppet-ceph.spec +@@ -10,6 +10,7 @@ URL: https://launchpad.net/puppet-ceph + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-Newton-rebase-fixes.patch ++Patch0003: 0003-Ceph-Jewel-rebase.patch + + BuildArch: noarch + +@@ -27,6 +28,7 @@ Community Developed Ceph Module + %setup -q -n openstack-ceph-%{version} + %patch0001 -p1 + %patch0002 -p1 ++%patch0003 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0004-Add-OSD-support-for-persistent-naming.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0004-Add-OSD-support-for-persistent-naming.patch new file mode 100644 index 000000000..d5e5a47de --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0004-Add-OSD-support-for-persistent-naming.patch @@ -0,0 +1,32 @@ +From e98b25d0168caa56d72e62e98f3c6701df704db5 Mon Sep 17 00:00:00 2001 +From: Robert Church +Date: Fri, 14 Apr 2017 02:04:43 +0000 +Subject: [PATCH] Add OSD support for persistent naming + +--- + SPECS/puppet-ceph.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-ceph.spec b/SPECS/puppet-ceph.spec +index bb4392d..99e4ac8 100644 +--- a/SPECS/puppet-ceph.spec ++++ b/SPECS/puppet-ceph.spec +@@ -13,6 +13,7 @@ Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_versio + Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-Newton-rebase-fixes.patch + Patch0003: 0003-Ceph-Jewel-rebase.patch ++Patch0004: 0004-US92424-Add-OSD-support-for-persistent-naming.patch + + BuildArch: noarch + +@@ -31,6 +32,7 @@ Community Developed Ceph Module + %patch0001 -p1 + %patch0002 -p1 + %patch0003 -p1 ++%patch0004 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0005-meta-patch-for-patch5.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0005-meta-patch-for-patch5.patch new file mode 100644 index 000000000..83d3374c2 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/0005-meta-patch-for-patch5.patch @@ -0,0 +1,32 @@ +From a6572b58090f2c9bf492d8745ce7cbd0fb8ede33 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 3 Jan 2018 10:42:13 -0600 +Subject: [PATCH] meta patch for patch5 + +--- + SPECS/puppet-ceph.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-ceph.spec b/SPECS/puppet-ceph.spec +index 66fc8ad..c855fc2 100644 +--- a/SPECS/puppet-ceph.spec ++++ b/SPECS/puppet-ceph.spec +@@ -12,6 +12,7 @@ Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-Newton-rebase-fixes.patch + Patch0003: 0003-Ceph-Jewel-rebase.patch + Patch0004: 0004-US92424-Add-OSD-support-for-persistent-naming.patch ++Patch0005: 0005-Remove-puppetlabs-apt-as-ceph-requirement.patch + + BuildArch: noarch + +@@ -31,6 +32,7 @@ Community Developed Ceph Module + %patch0002 -p1 + %patch0003 -p1 + %patch0004 -p1 ++%patch0005 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..4e3db139e --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,5 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-patches.patch +0003-Ceph-Jewel-rebase.patch +0004-Add-OSD-support-for-persistent-naming.patch +0005-meta-patch-for-patch5.patch diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..67d3f2b49 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,151 @@ +From d8e6107a98649475b5151289d6440b41f0397746 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 10 Jan 2017 13:31:17 -0500 +Subject: [PATCH] Roll up TIS patches + +--- + manifests/mon.pp | 15 ++++++++++++--- + manifests/osd.pp | 33 +++++++++++++++++---------------- + manifests/rgw.pp | 7 +++++++ + 3 files changed, 36 insertions(+), 19 deletions(-) + +diff --git a/manifests/mon.pp b/manifests/mon.pp +index a6b5712..54f9909 100644 +--- a/manifests/mon.pp ++++ b/manifests/mon.pp +@@ -65,6 +65,8 @@ define ceph::mon ( + $authentication_type = 'cephx', + $key = undef, + $keyring = undef, ++ $fsid = undef, ++ $service_ensure = 'running', + $exec_timeout = $::ceph::params::exec_timeout, + ) { + +@@ -78,6 +80,7 @@ define ceph::mon ( + $cluster_option = "--cluster ${cluster_name}" + } else { + $cluster_name = 'ceph' ++ $cluster_option = undef + } + + # NOTE(aschultz): this is the service title for the mon service. It may be +@@ -154,6 +157,10 @@ test -e \$mon_data/done + } + } + ++ if $fsid { ++ $fsid_option = "--fsid ${fsid}" ++ } ++ + Ceph_config<||> -> + # prevent automatic creation of the client.admin key by ceph-create-keys + exec { "ceph-mon-${cluster_name}.client.admin.keyring-${id}": +@@ -177,7 +184,8 @@ if [ ! -d \$mon_data ] ; then + --setuser ceph --setgroup ceph \ + --mkfs \ + --id ${id} \ +- --keyring ${keyring_path} ; then ++ --keyring ${keyring_path} \ ++ ${fsid_option} ; then + touch \$mon_data/done \$mon_data/${init} \$mon_data/keyring + chown -h ceph:ceph \$mon_data/done \$mon_data/${init} \$mon_data/keyring + else +@@ -187,7 +195,8 @@ if [ ! -d \$mon_data ] ; then + if ceph-mon ${cluster_option} \ + --mkfs \ + --id ${id} \ +- --keyring ${keyring_path} ; then ++ --keyring ${keyring_path} \ ++ ${fsid_option} ; then + touch \$mon_data/done \$mon_data/${init} \$mon_data/keyring + else + rm -fr \$mon_data +@@ -204,7 +213,7 @@ test -d \$mon_data + timeout => $exec_timeout, + }-> + service { $mon_service: +- ensure => running, ++ ensure => $service_ensure, + } + + # if the service is running before we setup the configs, notify service +diff --git a/manifests/osd.pp b/manifests/osd.pp +index 6c39806..5d3628d 100644 +--- a/manifests/osd.pp ++++ b/manifests/osd.pp +@@ -52,6 +52,8 @@ define ceph::osd ( + $ensure = present, + $journal = undef, + $cluster = undef, ++ $cluster_uuid = undef, ++ $uuid = undef, + $exec_timeout = $::ceph::params::exec_timeout, + $selinux_file_context = 'ceph_var_lib_t', + $fsid = $::ceph::profile::params::fsid, +@@ -66,6 +68,14 @@ define ceph::osd ( + $cluster_name = 'ceph' + } + ++ if $cluster_uuid { ++ $cluster_uuid_option = "--cluster-uuid ${cluster_uuid}" ++ } ++ ++ if $uuid { ++ $uuid_option = "--osd-uuid ${uuid}" ++ } ++ + if $ensure == present { + + $ceph_check_udev = "ceph-osd-check-udev-${name}" +@@ -115,22 +125,13 @@ test -z \$(ceph-disk list ${data} | egrep -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a + Exec[$ceph_check_udev] -> Exec[$ceph_prepare] + # ceph-disk: prepare should be idempotent http://tracker.ceph.com/issues/7475 + exec { $ceph_prepare: +- command => "/bin/true # comment to satisfy puppet syntax requirements +-set -ex +-if ! test -b ${data} ; then +- mkdir -p ${data} +- if getent passwd ceph >/dev/null 2>&1; then +- chown -h ceph:ceph ${data} +- fi +-fi +-ceph-disk prepare ${cluster_option} ${fsid_option} ${data} ${journal} +-udevadm settle +-", +- unless => "/bin/true # comment to satisfy puppet syntax requirements +-set -ex +-ceph-disk list | grep -E ' *${data}1? .*ceph data, (prepared|active)' || +-{ test -f ${data}/fsid && test -f ${data}/ceph_fsid && test -f ${data}/magic ;} +-", ++ command => "/usr/sbin/ceph-disk prepare ${cluster_option} ${cluster_uuid_option} ${uuid_option} --fs-type xfs --zap-disk ${data} ${journal}", ++ # We don't want to erase the disk if: ++ # 1. There is already ceph data on the disk for our cluster AND ++ # 2. The uuid for the OSD we are configuring matches the uuid for the ++ # OSD on the disk. We don't want to attempt to re-use an OSD that ++ # had previously been deleted. ++ unless => "/usr/sbin/ceph-disk list | grep -v 'unknown cluster' | grep ' *${data}.*ceph data' | grep 'osd uuid ${uuid}'", + logoutput => true, + timeout => $exec_timeout, + } +diff --git a/manifests/rgw.pp b/manifests/rgw.pp +index da5557e..2a79c07 100644 +--- a/manifests/rgw.pp ++++ b/manifests/rgw.pp +@@ -177,6 +177,13 @@ define ceph::rgw ( + provider => $::ceph::params::service_provider, + } + # Everything else that is supported by puppet-ceph should run systemd. ++ } elsif $::service_provider == 'systemd' { ++ Service { ++ name => "radosgw-${name}", ++ start => "systemctl start ceph-radosgw", ++ stop => "systemctl stop ceph-radosgw", ++ status => "systemctl status ceph-radosgw", ++ } + } else { + Service { + name => "ceph-radosgw@${name}", +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0002-Newton-rebase-fixes.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0002-Newton-rebase-fixes.patch new file mode 100644 index 000000000..d1f8366df --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0002-Newton-rebase-fixes.patch @@ -0,0 +1,47 @@ +From 89e1781309a8415d65c50c13c18742a92c970362 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 7 Feb 2017 15:49:02 -0500 +Subject: [PATCH] Newton rebase fixes + +--- + manifests/mon.pp | 9 ++++++--- + manifests/osd.pp | 2 +- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/manifests/mon.pp b/manifests/mon.pp +index 54f9909..41fd8df 100644 +--- a/manifests/mon.pp ++++ b/manifests/mon.pp +@@ -100,10 +100,13 @@ define ceph::mon ( + } + # Everything else that is supported by puppet-ceph should run systemd. + } else { +- $init = 'systemd' ++ $init = 'sysvinit' + Service { +- name => "ceph-mon@${id}", +- enable => $mon_enable, ++ name => "ceph-mon-${id}", ++ provider => $::ceph::params::service_provider, ++ start => "service ceph start mon.${id}", ++ stop => "service ceph stop mon.${id}", ++ status => "service ceph status mon.${id}", + } + } + +diff --git a/manifests/osd.pp b/manifests/osd.pp +index 5d3628d..ef171eb 100644 +--- a/manifests/osd.pp ++++ b/manifests/osd.pp +@@ -56,7 +56,7 @@ define ceph::osd ( + $uuid = undef, + $exec_timeout = $::ceph::params::exec_timeout, + $selinux_file_context = 'ceph_var_lib_t', +- $fsid = $::ceph::profile::params::fsid, ++ $fsid = undef, + ) { + + $data = $name +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0003-Ceph-Jewel-rebase.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0003-Ceph-Jewel-rebase.patch new file mode 100644 index 000000000..524b3fb7c --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0003-Ceph-Jewel-rebase.patch @@ -0,0 +1,110 @@ +From b245ba801e8dccffe6df30b448d307b9c332a8bf Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Thu, 23 Mar 2017 08:04:31 +0000 +Subject: [PATCH] ceph jewel rebase + +--- + manifests/mon.pp | 1 + + manifests/rgw.pp | 34 +++++++++++++++++++++++++--------- + manifests/rgw/keystone.pp | 6 +++--- + 3 files changed, 29 insertions(+), 12 deletions(-) + +diff --git a/manifests/mon.pp b/manifests/mon.pp +index 41fd8df..acc112e 100644 +--- a/manifests/mon.pp ++++ b/manifests/mon.pp +@@ -107,6 +107,7 @@ define ceph::mon ( + start => "service ceph start mon.${id}", + stop => "service ceph stop mon.${id}", + status => "service ceph status mon.${id}", ++ enable => $mon_enable, + } + } + +diff --git a/manifests/rgw.pp b/manifests/rgw.pp +index 2a79c07..d7af122 100644 +--- a/manifests/rgw.pp ++++ b/manifests/rgw.pp +@@ -185,23 +185,39 @@ define ceph::rgw ( + status => "systemctl status ceph-radosgw", + } + } else { ++ if $rgw_enable { ++ file { "${rgw_data}/sysvinit": ++ ensure => present, ++ before => Service["radosgw-${name}"], ++ } ++ } + Service { +- name => "ceph-radosgw@${name}", +- enable => $rgw_enable, ++ name => "radosgw-${name}", ++ start => 'service radosgw start', ++ stop => 'service radosgw stop', ++ status => 'service radosgw status', ++ provider => $::ceph::params::service_provider, + } + } + +- service { $rgw_service: +- ensure => $rgw_ensure, +- tag => ['ceph-radosgw'] ++ #for RHEL/CentOS7, systemctl needs to reload to pickup the ceph-radosgw init file ++ if (($::operatingsystem == 'RedHat' or $::operatingsystem == 'CentOS') and (versioncmp($::operatingsystemmajrelease, '7') >= 0)) ++ { ++ exec { 'systemctl-reload-from-rgw': #needed for the new init file ++ command => '/usr/bin/systemctl daemon-reload', ++ } ++ } ++ service { "radosgw-${name}": ++ ensure => $rgw_ensure, ++ tag => ['radosgw'] + } + +- Ceph_config<||> -> Service<| tag == 'ceph-radosgw' |> ++ Ceph_config<||> -> Service["radosgw-${name}"] + Package<| tag == 'ceph' |> -> File['/var/lib/ceph/radosgw'] + Package<| tag == 'ceph' |> -> File[$log_file] + File['/var/lib/ceph/radosgw'] + -> File[$rgw_data] +- -> Service<| tag == 'ceph-radosgw' |> +- File[$log_file] -> Service<| tag == 'ceph-radosgw' |> +- Ceph::Pool<||> -> Service<| tag == 'ceph-radosgw' |> ++ -> Service["radosgw-${name}"] ++ File[$log_file] -> Service["radosgw-${name}"] ++ Ceph::Pool<||> -> Service["radosgw-${name}"] + } +diff --git a/manifests/rgw/keystone.pp b/manifests/rgw/keystone.pp +index e17e4e1..72a0554 100644 +--- a/manifests/rgw/keystone.pp ++++ b/manifests/rgw/keystone.pp +@@ -148,7 +148,7 @@ define ceph::rgw::keystone ( + exec { "${name}-nssdb-ca": + command => "/bin/true # comment to satisfy puppet syntax requirements + set -ex +-wget --no-check-certificate ${rgw_keystone_url}/v2.0/certificates/ca -O - | ++wget --no-check-certificate ${rgw_keystone_url}/${rgw_keystone_version}/certificates/ca -O - | + openssl x509 -pubkey | certutil -A -d ${nss_db_path} -n ca -t \"TCu,Cu,Tuw\" + ", + unless => "/bin/true # comment to satisfy puppet syntax requirements +@@ -161,7 +161,7 @@ certutil -d ${nss_db_path} -L | grep ^ca + exec { "${name}-nssdb-signing": + command => "/bin/true # comment to satisfy puppet syntax requirements + set -ex +-wget --no-check-certificate ${rgw_keystone_url}/v2.0/certificates/signing -O - | ++wget --no-check-certificate ${rgw_keystone_url}/${rgw_keystone_version}/certificates/signing -O - | + openssl x509 -pubkey | certutil -A -d ${nss_db_path} -n signing_cert -t \"P,P,P\" + ", + unless => "/bin/true # comment to satisfy puppet syntax requirements +@@ -176,7 +176,7 @@ certutil -d ${nss_db_path} -L | grep ^signing_cert + -> File[$nss_db_path] + -> Exec["${name}-nssdb-ca"] + -> Exec["${name}-nssdb-signing"] +- ~> Service<| tag == 'ceph-radosgw' |> ++ ~> Service<| tag == 'radosgw' |> + } else { + ceph_config { + "client.${name}/nss_db_path": ensure => absent; +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0004-US92424-Add-OSD-support-for-persistent-naming.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0004-US92424-Add-OSD-support-for-persistent-naming.patch new file mode 100644 index 000000000..1819ad70a --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0004-US92424-Add-OSD-support-for-persistent-naming.patch @@ -0,0 +1,29 @@ +From 7a4c325194885dc43fc87f7094873e0067801652 Mon Sep 17 00:00:00 2001 +From: Robert Church +Date: Thu, 13 Apr 2017 20:31:21 -0500 +Subject: [PATCH] US92424: Add OSD support for persistent naming + +This allows the manifest to provide udev generated /dev/disk/by-* links +to configure the OSDs without requiring any additional changes. The +'readlink -f' will produce the currently enumerated device node +associated with udev link. +--- + manifests/osd.pp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/manifests/osd.pp b/manifests/osd.pp +index ef171eb..b9deea3 100644 +--- a/manifests/osd.pp ++++ b/manifests/osd.pp +@@ -59,7 +59,7 @@ define ceph::osd ( + $fsid = undef, + ) { + +- $data = $name ++ $data = generate('/bin/bash','-c',"/bin/readlink -f ${name}") + + if $cluster { + $cluster_option = "--cluster ${cluster}" +-- +2.9.0 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0005-Remove-puppetlabs-apt-as-ceph-requirement.patch b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0005-Remove-puppetlabs-apt-as-ceph-requirement.patch new file mode 100644 index 000000000..9d903e2dd --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/patches/0005-Remove-puppetlabs-apt-as-ceph-requirement.patch @@ -0,0 +1,25 @@ +From 8ab55c717d5088d8c75b465f5b9196036e0968ce Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 3 Jan 2018 10:39:37 -0600 +Subject: [PATCH] Remove puppetlabs-apt as ceph requirement + +We will never install apt or puppet-apt, so this requirement cannot be fulfilled +--- + metadata.json | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/metadata.json b/metadata.json +index 4175278..39d8c82 100644 +--- a/metadata.json ++++ b/metadata.json +@@ -47,7 +47,6 @@ + ], + "description": "Installs and configures Ceph.", + "dependencies": [ +- {"name":"puppetlabs/apt","version_requirement":">=2.0.0 <3.0.0"}, + {"name":"puppetlabs/apache","version_requirement":">=1.4.1 <2.0.0"}, + {"name":"puppetlabs/concat","version_requirement":">=1.2.1 <3.0.0"}, + {"name":"puppetlabs/inifile","version_requirement":">=1.0.0 <2.0.0"}, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/srpm_path new file mode 100644 index 000000000..3e71fec6e --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ceph-2.2.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-ceph-2.2.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..024e3e138 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=5 diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..ca5b87484 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From a140bd7cdc5bdac336619544141aa64daf54590a Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Tue, 31 Oct 2017 16:00:04 +0200 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-cinder.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-cinder.spec b/SPECS/puppet-cinder.spec +index 6af9d49..f9089b6 100644 +--- a/SPECS/puppet-cinder.spec ++++ b/SPECS/puppet-cinder.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-cinder + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Cinder + License: ASL 2.0 + +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0002-Add-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0002-Add-TIS-patches.patch new file mode 100644 index 000000000..ac18c1468 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0002-Add-TIS-patches.patch @@ -0,0 +1,32 @@ +From b7c5f47cef3c82667014e94f879b6bef943c7e71 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Tue, 31 Oct 2017 16:14:27 +0200 +Subject: [PATCH] Add TIS patches + +--- + SPECS/puppet-cinder.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-cinder.spec b/SPECS/puppet-cinder.spec +index f9089b6..e2e073e 100644 +--- a/SPECS/puppet-cinder.spec ++++ b/SPECS/puppet-cinder.spec +@@ -8,6 +8,7 @@ License: ASL 2.0 + URL: https://launchpad.net/puppet-cinder + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch + + BuildArch: noarch + +@@ -24,6 +25,7 @@ Puppet module for OpenStack Cinder + + %prep + %setup -q -n openstack-cinder-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0003-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0003-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch new file mode 100644 index 000000000..948168074 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/0003-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch @@ -0,0 +1,40 @@ +From 936518067804b9570e4ccbc95bdc519333b68de4 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Wed, 31 Jan 2018 14:10:02 +0000 +Subject: [PATCH] CGTS-8837 cinder volume cannot be deleted after swact + +Using cinder::host causes a deprecation warning in puppet. After +switching to cinder::backend_host and locking/unlocking controller +followed by swact cinder volumes cannot be deleted anymore. This +happens because CONF.host is still used by cinder services (not +entirey replaced with CONF.backend_host). + +Set cinder config DEFAULT/host to cinder::host if defined or +cinder::backend_host otherwise. +--- + SPECS/puppet-cinder.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-cinder.spec b/SPECS/puppet-cinder.spec +index e2e073e..bf848da 100644 +--- a/SPECS/puppet-cinder.spec ++++ b/SPECS/puppet-cinder.spec +@@ -9,6 +9,7 @@ URL: https://launchpad.net/puppet-cinder + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch + + BuildArch: noarch + +@@ -26,6 +27,7 @@ Puppet module for OpenStack Cinder + %prep + %setup -q -n openstack-cinder-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..f89b8db9d --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-patches.patch +0003-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..ecefd87d3 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,213 @@ +From 36e8bf659a3d48ba4eb028ece6f3656e62f358c2 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Mon, 30 Oct 2017 21:50:45 +0200 +Subject: [PATCH] Roll up TIS patches + +--- + lib/puppet/provider/cinder.rb | 5 ++++- + manifests/backend/iscsi.pp | 19 ++++++++++++++++--- + manifests/backend/rbd.pp | 14 +++++++++++--- + manifests/db/sync.pp | 3 +++ + manifests/init.pp | 7 ++++--- + manifests/quota_set.pp | 2 ++ + manifests/volume/rbd.pp | 1 + + spec/classes/cinder_volume_iscsi_spec.rb | 2 +- + 8 files changed, 42 insertions(+), 11 deletions(-) + +diff --git a/lib/puppet/provider/cinder.rb b/lib/puppet/provider/cinder.rb +index 924e8d7..6a0ef2f 100644 +--- a/lib/puppet/provider/cinder.rb ++++ b/lib/puppet/provider/cinder.rb +@@ -36,7 +36,10 @@ class Puppet::Provider::Cinder < Puppet::Provider::Openstack + @credentials.user_domain_name = cinder_credentials['user_domain_name'] + @credentials.project_domain_name = cinder_credentials['project_domain_name'] + end ++ @credentials.region_name = cinder_credentials['region_name'] + raise error unless @credentials.set? ++ # set OS_INTERFACE for cinder requests ++ ENV.store('OS_INTERFACE','internal') + Puppet::Provider::Openstack.request(service, action, properties, @credentials) + end + +@@ -50,7 +53,7 @@ class Puppet::Provider::Cinder < Puppet::Provider::Openstack + + def self.get_cinder_credentials + auth_keys = ['auth_uri', 'project_name', 'username', +- 'password'] ++ 'password', 'region_name'] + conf = cinder_conf + if conf and conf['keystone_authtoken'] and + auth_keys.all?{|k| !conf['keystone_authtoken'][k].nil?} +diff --git a/manifests/backend/iscsi.pp b/manifests/backend/iscsi.pp +index 9530958..1ccc27c 100644 +--- a/manifests/backend/iscsi.pp ++++ b/manifests/backend/iscsi.pp +@@ -103,12 +103,25 @@ define cinder::backend::iscsi ( + } + + 'lioadm': { +- service { 'target': +- ensure => running, +- enable => true, ++ # This service is being managed by Services Manager ++ # and it will be started by SM on an active controller ++ service { 'iscsi': ++ ensure => stopped, ++ name => 'target', ++ enable => false, + tag => 'cinder-support-service', + } + ++ cinder_config { ++ "DEFAULT/iscsi_helper": value => $iscsi_helper; ++ "DEFAULT/num_shell_tries": value => 3; ++ "DEFAULT/num_iscsi_scan_tries": value => 3; ++ "DEFAULT/iscsi_num_targets": value => 10000; ++ "DEFAULT/iscsi_target_prefix": value => 'iqn.2010-10.org.openstack:'; ++ "DEFAULT/iscsi_ip_address": value => '$my_ip'; ++ "DEFAULT/iscsi_port": value => 3260; ++ } ++ + package { 'targetcli': + ensure => present, + name => $::cinder::params::lio_package_name, +diff --git a/manifests/backend/rbd.pp b/manifests/backend/rbd.pp +index b310468..2607c7f 100644 +--- a/manifests/backend/rbd.pp ++++ b/manifests/backend/rbd.pp +@@ -83,7 +83,7 @@ define cinder::backend::rbd ( + $volume_backend_name = $name, + $rbd_ceph_conf = '/etc/ceph/ceph.conf', + $rbd_flatten_volume_from_snapshot = $::os_service_default, +- $rbd_secret_uuid = $::os_service_default, ++ $rbd_secret_uuid = false, + $rbd_max_clone_depth = $::os_service_default, + $rados_connect_timeout = $::os_service_default, + $rados_connection_interval = $::os_service_default, +@@ -102,11 +102,9 @@ define cinder::backend::rbd ( + "${name}/volume_backend_name": value => $volume_backend_name; + "${name}/volume_driver": value => 'cinder.volume.drivers.rbd.RBDDriver'; + "${name}/rbd_ceph_conf": value => $rbd_ceph_conf; +- "${name}/rbd_user": value => $rbd_user; + "${name}/rbd_pool": value => $rbd_pool; + "${name}/rbd_max_clone_depth": value => $rbd_max_clone_depth; + "${name}/rbd_flatten_volume_from_snapshot": value => $rbd_flatten_volume_from_snapshot; +- "${name}/rbd_secret_uuid": value => $rbd_secret_uuid; + "${name}/rados_connect_timeout": value => $rados_connect_timeout; + "${name}/rados_connection_interval": value => $rados_connection_interval; + "${name}/rados_connection_retries": value => $rados_connection_retries; +@@ -130,6 +128,14 @@ define cinder::backend::rbd ( + } + } + ++ if $rbd_secret_uuid { ++ cinder_config {"${name}/rbd_secret_uuid": value => $rbd_secret_uuid;} ++ cinder_config {"${name}/rbd_user": value => $rbd_user;} ++ } else { ++ cinder_config {"${name}/rbd_secret_uuid": ensure => absent;} ++ cinder_config {"${name}/rbd_user": ensure => absent;} ++ } ++ + if $volume_tmp_dir { + cinder_config {"${name}/volume_tmp_dir": value => $volume_tmp_dir;} + warning('The rbd volume_tmp_dir parameter is deprecated. Please use image_conversion_dir in the cinder base class instead.') +@@ -151,6 +157,7 @@ define cinder::backend::rbd ( + } + } + ++ if $override_line { + # Creates an empty file if it doesn't yet exist + ensure_resource('file', $::cinder::params::ceph_init_override, {'ensure' => 'present'}) + +@@ -159,5 +166,6 @@ define cinder::backend::rbd ( + path => $::cinder::params::ceph_init_override, + notify => Anchor['cinder::service::begin'], + } ++ } + + } +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index a37f746..90f910a 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -30,5 +30,8 @@ class cinder::db::sync( + Anchor['cinder::dbsync::begin'] + ], + notify => Anchor['cinder::dbsync::end'], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "test $::controller_sw_versions_match = true", + } + } +diff --git a/manifests/init.pp b/manifests/init.pp +index d58b653..bf23eaa 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -19,8 +19,9 @@ + # Defaults to $::os_service_default + # + # [*rpc_response_timeout*] +-# (optional) Seconds to wait for a response from a call +-# Defaults to $::os_service_default ++# (Optional) rpc_response_timeout for rpc calls ++# Defaults to 60. ++# + # + # [*control_exchange*] + # (Optional) +@@ -318,7 +319,7 @@ class cinder ( + $database_retry_interval = undef, + $database_max_overflow = undef, + $default_transport_url = $::os_service_default, +- $rpc_response_timeout = $::os_service_default, ++ $rpc_response_timeout = '60', + $control_exchange = 'openstack', + $rabbit_ha_queues = $::os_service_default, + $rabbit_heartbeat_timeout_threshold = $::os_service_default, +diff --git a/manifests/quota_set.pp b/manifests/quota_set.pp +index 10c690a..fb4cbe8 100644 +--- a/manifests/quota_set.pp ++++ b/manifests/quota_set.pp +@@ -67,6 +67,7 @@ define cinder::quota_set ( + "OS_PASSWORD=${os_password}", + "OS_AUTH_URL=${os_auth_url}", + "OS_REGION_NAME=${os_region_name}", ++ "CINDER_ENDPOINT_TYPE=internalURL", + ] + } + else { +@@ -75,6 +76,7 @@ define cinder::quota_set ( + "OS_USERNAME=${os_username}", + "OS_PASSWORD=${os_password}", + "OS_AUTH_URL=${os_auth_url}", ++ "CINDER_ENDPOINT_TYPE=internalURL", + ] + } + +diff --git a/manifests/volume/rbd.pp b/manifests/volume/rbd.pp +index accf47b..3971008 100644 +--- a/manifests/volume/rbd.pp ++++ b/manifests/volume/rbd.pp +@@ -93,5 +93,6 @@ cinder::backend::rbd instead.') + rados_connection_retries => $rados_connection_retries, + rbd_store_chunk_size => $rbd_store_chunk_size, + extra_options => $extra_options, ++ backend_host => '$host', + } + } +diff --git a/spec/classes/cinder_volume_iscsi_spec.rb b/spec/classes/cinder_volume_iscsi_spec.rb +index 9fc87a9..4e8585a 100644 +--- a/spec/classes/cinder_volume_iscsi_spec.rb ++++ b/spec/classes/cinder_volume_iscsi_spec.rb +@@ -19,7 +19,7 @@ describe 'cinder::volume::iscsi' do + it { is_expected.to contain_cinder_config('DEFAULT/volume_driver').with( + :value => 'cinder.volume.drivers.lvm.LVMVolumeDriver')} + it { is_expected.to contain_cinder_config('DEFAULT/iscsi_ip_address').with(:value => '127.0.0.2')} +- it { is_expected.to contain_cinder_config('DEFAULT/iscsi_helper').with(:value => 'tgtadm')} ++ it { is_expected.to contain_cinder_config('DEFAULT/iscsi_helper').with(:value => 'lioadm')} + it { is_expected.to contain_cinder_config('DEFAULT/volume_group').with(:value => '')} + it { is_expected.to contain_cinder_config('DEFAULT/volumes_dir').with(:value => '/var/lib/cinder/volumes')} + it { is_expected.to contain_cinder_config('DEFAULT/iscsi_protocol').with(:value => '')} +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0002-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0002-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch new file mode 100644 index 000000000..d4abc3c2a --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/patches/0002-CGTS-8837-cinder-volume-cannot-be-deleted-after-swact.patch @@ -0,0 +1,46 @@ +From 410f15031197e5a252afed9a1c8b85c4cee136b7 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Wed, 31 Jan 2018 13:55:50 +0000 +Subject: [PATCH] CGTS-8837 cinder volume cannot be deleted after swact + +Using cinder::host causes a deprecation warning in puppet. After +switching to cinder::backend_host and locking/unlocking controller +followed by swact cinder volumes cannot be deleted anymore. This +happens because CONF.host is still used by cinder services (not +entirey replaced with CONF.backend_host). + +Set cinder config DEFAULT/host to cinder::host if defined or +cinder::backend_host otherwise. +--- + manifests/init.pp | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index bf23eaa..3ad82e4 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -472,6 +472,12 @@ instead.") + $default_availability_zone_real = $default_availability_zone + } + ++ if is_service_default($host) { ++ $host_real = $backend_host ++ } else { ++ $host_real = $host ++ } ++ + cinder_config { + 'DEFAULT/report_interval': value => $report_interval; + 'DEFAULT/service_down_time': value => $service_down_time; +@@ -480,7 +486,7 @@ instead.") + 'DEFAULT/default_availability_zone': value => $default_availability_zone_real; + 'DEFAULT/allow_availability_zone_fallback': value => $allow_availability_zone_fallback; + 'DEFAULT/image_conversion_dir': value => $image_conversion_dir; +- 'DEFAULT/host': value => $host; ++ 'DEFAULT/host': value => $host_real; + 'DEFAULT/backend_host': value => $backend_host; + } + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/srpm_path new file mode 100644 index 000000000..9f6ca7967 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-cinder-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-cinder-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..0eac83bbb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=4 diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..cca8318ac --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 2f72d134c0c9a4fdc4e83f0aefab1608da644621 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Tue, 31 Oct 2017 15:44:43 +0200 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-glance.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/puppet-glance.spec b/puppet-glance.spec +index 1e9d4b8..64b1dbe 100644 +--- a/SPECS/puppet-glance.spec ++++ b/SPECS/puppet-glance.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-glance + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Glance + License: ASL 2.0 + +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch new file mode 100644 index 000000000..4577c988a --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch @@ -0,0 +1,32 @@ +From 534bf798c41db10847c2035a36e49f2d9d459a00 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Tue, 31 Oct 2017 17:51:50 +0200 +Subject: [PATCH] Add TIS patch + +--- + SPECS/puppet-glance.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/puppet-glance.spec b/puppet-glance.spec +index 64b1dbe..d6b63d1 100644 +--- a/SPECS/puppet-glance.spec ++++ b/SPECS/puppet-glance.spec +@@ -8,6 +8,7 @@ License: ASL 2.0 + URL: https://launchpad.net/puppet-glance + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch + + BuildArch: noarch + +@@ -23,6 +24,7 @@ Puppet module for OpenStack Glance + + %prep + %setup -q -n openstack-glance-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0003-Add-region-cache-support.patch b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0003-Add-region-cache-support.patch new file mode 100644 index 000000000..14fda36a0 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/0003-Add-region-cache-support.patch @@ -0,0 +1,32 @@ +From 56feda10321fb1e5067b78dfeced8c5adcf8748e Mon Sep 17 00:00:00 2001 +From: Stefan Dinescu +Date: Thu, 16 Nov 2017 18:28:36 +0000 +Subject: [PATCH] Add region-cache support + +--- + SPECS/puppet-glance.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-glance.spec b/SPECS/puppet-glance.spec +index d6b63d1..1e49ae0 100644 +--- a/SPECS/puppet-glance.spec ++++ b/SPECS/puppet-glance.spec +@@ -9,6 +9,7 @@ URL: https://launchpad.net/puppet-glance + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-Add-region-cache-support.patch + + BuildArch: noarch + +@@ -25,6 +26,7 @@ Puppet module for OpenStack Glance + %prep + %setup -q -n openstack-glance-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..3b8da08ec --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-patch.patch +0003-Add-region-cache-support.patch diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..326be9ba3 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,172 @@ +From 77f605262cdf55929b230033faafce04399828e6 Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Mon, 30 Oct 2017 14:46:53 +0200 +Subject: [PATCH] Roll up TIS patches + +--- + lib/puppet/provider/glance_image/openstack.rb | 2 +- + manifests/api.pp | 30 ++++++++++++++++++++++ + manifests/db/sync.pp | 3 +++ + manifests/registry.pp | 8 ++++++ + spec/classes/glance_api_spec.rb | 3 +++ + spec/classes/glance_registry_spec.rb | 1 + + 6 files changed, 46 insertions(+), 1 deletion(-) + +diff --git a/lib/puppet/provider/glance_image/openstack.rb b/lib/puppet/provider/glance_image/openstack.rb +index 6e6b4b9..4f30980 100644 +--- a/lib/puppet/provider/glance_image/openstack.rb ++++ b/lib/puppet/provider/glance_image/openstack.rb +@@ -10,7 +10,7 @@ Puppet::Type.type(:glance_image).provide( + Provider to manage glance_image type. + EOT + +- @credentials = Puppet::Provider::Openstack::CredentialsV2_0.new ++ @credentials = Puppet::Provider::Openstack::CredentialsV3.new + + # TODO(flaper87): v2 is now the default. Force the use of v2, + # to avoid supporting both versions and other edge cases. +diff --git a/manifests/api.pp b/manifests/api.pp +index 7e5d3f0..d69059d 100644 +--- a/manifests/api.pp ++++ b/manifests/api.pp +@@ -271,6 +271,25 @@ + # (optional) Maximum number of results that could be returned by a request + # Default: $::os_service_default. + # ++# === WRS parameters: ++# ++# [*cinder_catalog_info*] ++# (optional) Info to match when looking for cinder in the service catalog. ++# Defaults to 'volume:cinder:publicURL'. ++# ++# [*scrubber_datadir*] ++# (optional) Some sort of scrubber datadir. ++# Defaults to '/var/lib/glance/scrubber'. ++# ++# [*cache_raw_conversion_dir*] ++# (optional) Base directory for Ceph RAW Caching feature ++# Defaults to false, not set. RAW Caching will be disabled. ++# ++# [*graceful_shutdown*] ++# (optional) Enable graceful shutdown on SIGUSR2 ++# Defaults to false, not set. ++# ++# + # === deprecated parameters: + # + # [*known_stores*] +@@ -339,6 +358,11 @@ class glance::api( + $validation_options = {}, + $limit_param_default = $::os_service_default, + $api_limit_max = $::os_service_default, ++ # WRS PARAMETERS ++ $cinder_catalog_info = 'volume:cinder:publicURL', ++ $scrubber_datadir = '/var/lib/glance/scrubber', ++ $cache_raw_conversion_dir = '/opt/img-conversions/glance', ++ $graceful_shutdown = false, + # DEPRECATED PARAMETERS + $known_stores = false, + ) inherits glance { +@@ -379,6 +403,10 @@ class glance::api( + 'DEFAULT/enable_v2_api': value => $enable_v2_api; + 'DEFAULT/limit_param_default': value => $limit_param_default; + 'DEFAULT/api_limit_max': value => $api_limit_max; ++ 'DEFAULT/cinder_catalog_info': value => $cinder_catalog_info; ++ 'DEFAULT/scrubber_datadir': value => $scrubber_datadir; ++ 'DEFAULT/cache_raw_conversion_dir': value=> $cache_raw_conversion_dir; ++ 'DEFAULT/graceful_shutdown': value => $graceful_shutdown; + 'glance_store/os_region_name': value => $os_region_name; + } + +@@ -403,6 +431,8 @@ class glance::api( + } + if $default_store { + $default_store_real = $default_store ++ } else { ++ $default_store_real = unset + } + if !empty($stores_real) { + # determine value for glance_store/stores +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index 357be0d..43f6168 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -30,6 +30,9 @@ class glance::db::sync( + Anchor['glance::dbsync::begin'] + ], + notify => Anchor['glance::dbsync::end'], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "test $::controller_sw_versions_match = true", + } + + } +diff --git a/manifests/registry.pp b/manifests/registry.pp +index 258fd01..6adfc09 100644 +--- a/manifests/registry.pp ++++ b/manifests/registry.pp +@@ -121,6 +121,11 @@ + # should be set to False. + # Defaults to $::os_service_default. + # ++# [*graceful_shutdown*] ++# (optional) Enable graceful shutdown on SIGUSR2 ++# Defaults to false, not set. ++# ++# + # DEPRECATED PARAMETERS + # + # [*sync_db*] +@@ -155,6 +160,8 @@ class glance::registry( + $ca_file = $::os_service_default, + $os_region_name = $::os_service_default, + $enable_v1_registry = $::os_service_default, ++ # WRS PARAMETERS ++ $graceful_shutdown = false, + # DEPRECATED + $sync_db = undef, + ) inherits glance { +@@ -181,6 +188,7 @@ class glance::registry( + 'DEFAULT/bind_host': value => $bind_host; + 'DEFAULT/bind_port': value => $bind_port; + 'DEFAULT/enable_v1_registry': value => $enable_v1_registry; ++ 'DEFAULT/graceful_shutdown': value => $graceful_shutdown; + 'glance_store/os_region_name': value => $os_region_name; + } + +diff --git a/spec/classes/glance_api_spec.rb b/spec/classes/glance_api_spec.rb +index 9606b1d..eaf1373 100644 +--- a/spec/classes/glance_api_spec.rb ++++ b/spec/classes/glance_api_spec.rb +@@ -34,6 +34,8 @@ describe 'glance::api' do + :image_cache_dir => '/var/lib/glance/image-cache', + :image_cache_stall_time => '', + :image_cache_max_size => '', ++ :cache_raw_conversion_dir => '/opt/img-conversions/glance', ++ :graceful_shutdown => 'false', + :os_region_name => 'RegionOne', + :pipeline => 'keystone', + :task_time_to_live => '', +@@ -71,6 +73,7 @@ describe 'glance::api' do + :image_cache_dir => '/tmp/glance', + :image_cache_stall_time => '10', + :image_cache_max_size => '10737418240', ++ :cache_raw_conversion_dir => '/opt/img-conversions/glance', + :os_region_name => 'RegionOne2', + :pipeline => 'keystone2', + :sync_db => false, +diff --git a/spec/classes/glance_registry_spec.rb b/spec/classes/glance_registry_spec.rb +index 0d55cf5..4056f11 100644 +--- a/spec/classes/glance_registry_spec.rb ++++ b/spec/classes/glance_registry_spec.rb +@@ -25,6 +25,7 @@ describe 'glance::registry' do + :cert_file => '', + :key_file => '', + :enable_v1_registry => '', ++ :graceful_shutdown => 'false', + } + end + +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0002-Add-region-cache-support.patch b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0002-Add-region-cache-support.patch new file mode 100644 index 000000000..2f5544615 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/patches/0002-Add-region-cache-support.patch @@ -0,0 +1,64 @@ +From be3e4af9cd22d1af7f5df456a6b67188b1cc2c25 Mon Sep 17 00:00:00 2001 +From: Stefan Dinescu +Date: Thu, 16 Nov 2017 18:26:34 +0000 +Subject: [PATCH] Add region cache support + +--- + manifests/api.pp | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/manifests/api.pp b/manifests/api.pp +index d69059d..e563556 100644 +--- a/manifests/api.pp ++++ b/manifests/api.pp +@@ -289,6 +289,13 @@ + # (optional) Enable graceful shutdown on SIGUSR2 + # Defaults to false, not set. + # ++# [*remote_registry_region_name*] ++# (optional) Remote region name for primary region/cloud ++# Defaults to undef, not set ++# ++# [*data_api*] ++# (optional) API for image info retrieval ++# Defaults to glance.db.sqlalchemy.api + # + # === deprecated parameters: + # +@@ -363,6 +370,8 @@ class glance::api( + $scrubber_datadir = '/var/lib/glance/scrubber', + $cache_raw_conversion_dir = '/opt/img-conversions/glance', + $graceful_shutdown = false, ++ $remote_registry_region_name = undef, ++ $data_api = 'glance.db.sqlalchemy.api', + # DEPRECATED PARAMETERS + $known_stores = false, + ) inherits glance { +@@ -408,6 +417,7 @@ class glance::api( + 'DEFAULT/cache_raw_conversion_dir': value=> $cache_raw_conversion_dir; + 'DEFAULT/graceful_shutdown': value => $graceful_shutdown; + 'glance_store/os_region_name': value => $os_region_name; ++ 'DEFAULT/data_api': value => $data_api; + } + + # task/taskflow_executor config. +@@ -507,6 +517,16 @@ class glance::api( + glance_api_config { 'paste_deploy/flavor': ensure => absent } + } + ++ if $remote_registry_region_name { ++ glance_api_config { ++ 'DEFAULT/remote_registry_region_name': ++ ensure => present, ++ value => $remote_registry_region_name, ++ } ++ } else { ++ glance_api_config { 'DEFAULT/remote_registry_region_name': ensure => absent } ++ } ++ + # keystone config + if $auth_strategy == 'keystone' { + include ::glance::api::authtoken +-- +2.7.4 + diff --git a/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/srpm_path new file mode 100644 index 000000000..c83d7c61e --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-glance-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-glance-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..773a32dfb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 83386553c2e10f04d3080fbd9f8b9b8a7aaa1025 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 3 Jan 2017 13:29:01 -0500 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-heat.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-heat.spec b/SPECS/puppet-heat.spec +index ce1d9a5..710e16c 100644 +--- a/SPECS/puppet-heat.spec ++++ b/SPECS/puppet-heat.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-heat + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Heat + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0002-Add-TIS-Patches.patch b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0002-Add-TIS-Patches.patch new file mode 100644 index 000000000..d7969a4d5 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/0002-Add-TIS-Patches.patch @@ -0,0 +1,32 @@ +From e2dc69fb6aef8f45556d2884db02942d84543013 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 24 Jan 2017 11:12:02 -0500 +Subject: [PATCH] Add TIS Patches + +--- + SPECS/puppet-heat.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-heat.spec b/SPECS/puppet-heat.spec +index 4ca652e..5c1ec2f 100644 +--- a/SPECS/puppet-heat.spec ++++ b/SPECS/puppet-heat.spec +@@ -8,6 +8,7 @@ License: ASL 2.0 + URL: https://launchpad.net/puppet-heat + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch + + BuildArch: noarch + +@@ -23,6 +24,7 @@ Puppet module for OpenStack Heat + + %prep + %setup -q -n openstack-heat-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..0403df317 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-Patches.patch diff --git a/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..dca8efd78 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,152 @@ +From 41d3cbbc1a3e359cbed1443327601773fe35cce0 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 6 Nov 2017 15:10:27 -0600 +Subject: [PATCH] WRS: Patch1: 0001-Roll-up-TIS-patches.patch + +--- + manifests/db/sync.pp | 6 +++++- + manifests/engine.pp | 7 +++++++ + manifests/init.pp | 8 ++++++++ + manifests/keystone/domain.pp | 4 +++- + spec/classes/heat_engine_spec.rb | 3 +++ + 5 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index d1a3416..d866595 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -19,7 +19,8 @@ class heat::db::sync( + exec { 'heat-dbsync': + command => "heat-manage ${extra_params} db_sync", + path => '/usr/bin', +- user => 'heat', ++ # For whatever reason, the db_sync doesn't work as heat user ++ #user => 'heat', + refreshonly => true, + try_sleep => 5, + tries => 10, +@@ -30,5 +31,8 @@ class heat::db::sync( + Anchor['heat::dbsync::begin'] + ], + notify => Anchor['heat::dbsync::end'], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "test $::controller_sw_versions_match = true", + } + } +diff --git a/manifests/engine.pp b/manifests/engine.pp +index 6b31316..021662f 100644 +--- a/manifests/engine.pp ++++ b/manifests/engine.pp +@@ -109,6 +109,11 @@ + # (Optional) The directory to search for template files. + # Defaults to $::os_service_default + # ++# [*action_retry_limit*] ++# (optional) Number of times to retry to bring a resource to a non-error ++# state. Set to 0 to disable retries. ++# Defaults to '5' ++# + # [*max_nested_stack_depth*] + # (Optional) Maximum depth allowed when using nested stacks. + # Defaults to $::os_service_default +@@ -135,6 +140,7 @@ class heat::engine ( + $reauthentication_auth_method = $::os_service_default, + $environment_dir = $::os_service_default, + $template_dir = $::os_service_default, ++ $action_retry_limit = $::os_service_default, + $max_nested_stack_depth = $::os_service_default, + ) { + +@@ -194,6 +200,7 @@ class heat::engine ( + 'DEFAULT/reauthentication_auth_method': value => $reauthentication_auth_method; + 'DEFAULT/environment_dir': value => $environment_dir; + 'DEFAULT/template_dir': value => $template_dir; ++ 'DEFAULT/action_retry_limit': value => $action_retry_limit; + 'DEFAULT/max_nested_stack_depth': value => $max_nested_stack_depth; + } + } +diff --git a/manifests/init.pp b/manifests/init.pp +index f268ecd..5d6d445 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -288,6 +288,11 @@ + # take for evaluation. + # Defaults to $::os_service_default. + # ++# === WRS PARAMETERS ++# [*heat_clients_insecure*] ++# (optional) sets the insecure option in the config file under ++# [clients_heat] ++# + # === DEPRECATED PARAMETERS + # + # [*rabbit_host*] +@@ -383,6 +388,8 @@ class heat( + $auth_strategy = 'keystone', + $yaql_memory_quota = $::os_service_default, + $yaql_limit_iterators = $::os_service_default, ++ # WRS PARAMETERS ++ $heat_clients_insecure = false, + # DEPRECATED PARAMETERS + $rabbit_host = $::os_service_default, + $rabbit_port = $::os_service_default, +@@ -480,6 +487,7 @@ instead.") + 'trustee/user_domain_name': value => $keystone_user_domain_name; + 'clients_keystone/auth_uri': value => $auth_url; + 'clients_heat/url': value => $heat_clients_url; ++ 'clients_heat/insecure': value => $heat_clients_insecure; + 'clients/endpoint_type': value => $heat_clients_endpoint_type; + } + +diff --git a/manifests/keystone/domain.pp b/manifests/keystone/domain.pp +index 98c5013..44aa0c5 100644 +--- a/manifests/keystone/domain.pp ++++ b/manifests/keystone/domain.pp +@@ -54,12 +54,14 @@ class heat::keystone::domain ( + 'enabled' => true, + }) + } ++ # fix the user name that has the domain name appended + if $manage_user { +- ensure_resource('keystone_user', "${domain_admin}::${domain_name}", { ++ ensure_resource('keystone_user', $domain_admin, { + 'ensure' => 'present', + 'enabled' => true, + 'email' => $domain_admin_email, + 'password' => $domain_password, ++ 'domain' => $domain_name, + }) + } + if $manage_role { +diff --git a/spec/classes/heat_engine_spec.rb b/spec/classes/heat_engine_spec.rb +index da4ef71..0150edb 100644 +--- a/spec/classes/heat_engine_spec.rb ++++ b/spec/classes/heat_engine_spec.rb +@@ -18,6 +18,7 @@ describe 'heat::engine' do + :reauthentication_auth_method => '', + :environment_dir => '', + :template_dir => '', ++ :action_retry_limit => '', + :max_nested_stack_depth => '', + } + end +@@ -48,6 +49,7 @@ describe 'heat::engine' do + :reauthentication_auth_method => 'trusts', + :environment_dir => '/etc/heat/environment.d', + :template_dir => '/etc/heat/templates', ++ :action_retry_limit => '5', + } + ].each do |new_params| + describe 'when #{param_set == {} ? "using default" : "specifying"} parameters' +@@ -93,6 +95,7 @@ describe 'heat::engine' do + it { is_expected.to contain_heat_config('DEFAULT/reauthentication_auth_method').with_value( expected_params[:reauthentication_auth_method] ) } + it { is_expected.to contain_heat_config('DEFAULT/environment_dir').with_value( expected_params[:environment_dir] ) } + it { is_expected.to contain_heat_config('DEFAULT/template_dir').with_value( expected_params[:template_dir] ) } ++ it { is_expected.to contain_heat_config('DEFAULT/action_retry_limit').with_value('') } + end + + context 'with disabled service managing' do +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/srpm_path new file mode 100644 index 000000000..1e49912f2 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-heat-11.3.0/centos/srpm_path @@ -0,0 +1,2 @@ +mirror:Source/puppet-heat-11.3.0-1.el7.src.rpm + diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..4c262e106 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,19 @@ +commit 4509fa0b8006dd147bb848b5648e334aedd26111 +Author: Shoaib Nasir +Date: Thu Nov 30 15:02:19 2017 -0500 + + Added TIS Versioning to Pike 'puppet-ironic.spec' + +diff --git a/SPECS/puppet-ironic.spec b/SPECS/puppet-ironic.spec +index 0375bd3..ba63c5e 100644 +--- a/SPECS/puppet-ironic.spec ++++ b/SPECS/puppet-ironic.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-ironic + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Ironic + License: ASL 2.0 + diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0002-Ironic-dbsync-NeutronGlance-dep.patch b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0002-Ironic-dbsync-NeutronGlance-dep.patch new file mode 100644 index 000000000..6c25d2033 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0002-Ironic-dbsync-NeutronGlance-dep.patch @@ -0,0 +1,26 @@ +commit 399f1078a0a79d24b0c5fad573fd912eceacefae +Author: Shoaib Nasir +Date: Fri Dec 1 16:16:52 2017 -0500 + + Ironic dbsync with Neutron and Glance dependency resolved + +diff --git a/SPECS/puppet-ironic.spec b/SPECS/puppet-ironic.spec +index ba63c5e..ee83ddc 100644 +--- a/SPECS/puppet-ironic.spec ++++ b/SPECS/puppet-ironic.spec +@@ -8,6 +8,7 @@ License: ASL 2.0 + URL: https://launchpad.net/puppet-ironic + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Ironic-dbsync-NeutronGlance-dep-resolution.patch + + BuildArch: noarch + +@@ -24,6 +25,7 @@ Puppet module for OpenStack Ironic + + %prep + %setup -q -n openstack-ironic-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0003-Apply-xinetd-patch.patch b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0003-Apply-xinetd-patch.patch new file mode 100644 index 000000000..e9f508bd9 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/0003-Apply-xinetd-patch.patch @@ -0,0 +1,32 @@ +From 5727bbd6fa8bd6f75888e3a53d4c50fe13ca5a33 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 09:15:21 -0600 +Subject: [PATCH 2/2] Apply xinetd patch + +--- + SPECS/puppet-ironic.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-ironic.spec b/SPECS/puppet-ironic.spec +index ee83ddc..9199102 100644 +--- a/SPECS/puppet-ironic.spec ++++ b/SPECS/puppet-ironic.spec +@@ -9,6 +9,7 @@ URL: https://launchpad.net/puppet-ironic + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + Patch0001: 0001-Ironic-dbsync-NeutronGlance-dep-resolution.patch ++Patch0002: 0002-Dont-complain-about-xinetd-2.0.0.patch + + BuildArch: noarch + +@@ -26,6 +27,7 @@ Puppet module for OpenStack Ironic + %prep + %setup -q -n openstack-ironic-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..b6c521b44 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Ironic-dbsync-NeutronGlance-dep.patch +0003-Apply-xinetd-patch.patch diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0001-Ironic-dbsync-NeutronGlance-dep-resolution.patch b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0001-Ironic-dbsync-NeutronGlance-dep-resolution.patch new file mode 100644 index 000000000..24adcd557 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0001-Ironic-dbsync-NeutronGlance-dep-resolution.patch @@ -0,0 +1,78 @@ +commit de50acda387041d6810ffbd91cea3bf52b7dbc8d +Author: Shoaib Nasir +Date: Thu Dec 7 17:36:26 2017 -0500 + + WRS Patch1: 0001-Ironic-dbsync-NeutronGlance-dep-resolution.patchng + +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index 9e4e36a..f4e3fa1 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -15,6 +15,17 @@ class ironic::db::sync( + include ::ironic::deps + include ::ironic::params + ++ # NOTE(dtantsur): previous ironic-dbsync was run as root. it will fail to run ++ # as "ironic" user, if there is an old log file owned by root. Let's fix it. ++ # To be removed in Rocky. ++ file { '/var/log/ironic/ironic-dbsync.log': ++ ensure => 'present', ++ owner => 'ironic', ++ group => 'ironic', ++ # /var/log/ironic comes from ironic-common ++ require => Anchor['ironic::install::end'] ++ } ++ + exec { 'ironic-dbsync': + command => "${::ironic::params::dbsync_command} ${extra_params}", + path => '/usr/bin', +@@ -29,5 +40,6 @@ class ironic::db::sync( + Anchor['ironic::dbsync::begin'] + ], + notify => Anchor['ironic::dbsync::end'], ++ require => File['/var/log/ironic/ironic-dbsync.log'], + } + } +diff --git a/manifests/glance.pp b/manifests/glance.pp +index 09a65ce..bad84cd 100644 +--- a/manifests/glance.pp ++++ b/manifests/glance.pp +@@ -93,19 +93,19 @@ class ironic::glance ( + $swift_account_project_name = undef, + ) { + +- $api_servers_real = pick($::ironic::glance_api_servers, $api_servers) ++ $api_servers_real = $api_servers + if is_array($api_servers_real) { + $api_servers_converted = join($api_servers_real, ',') + } else { + $api_servers_converted = $api_servers_real + } + +- $num_retries_real = pick($::ironic::glance_num_retries, $num_retries) +- $api_insecure_real = pick($::ironic::glance_api_insecure, $api_insecure) ++ $num_retries_real = $num_retries ++ $api_insecure_real = $api_insecure + +- $swift_account_real = pick($::ironic::conductor::swift_account, $swift_account) +- $swift_temp_url_key_real = pick($::ironic::conductor::swift_temp_url_key, $swift_temp_url_key) +- $swift_temp_url_duration_real = pick($::ironic::conductor::swift_temp_url_duration, $swift_temp_url_duration) ++ $swift_account_real = $swift_account ++ $swift_temp_url_key_real = $swift_temp_url_key ++ $swift_temp_url_duration_real = $swift_temp_url_duration + + + if ($swift_account_project_name and !is_service_default($swift_account_real)) { +diff --git a/manifests/neutron.pp b/manifests/neutron.pp +index f8cbd5d..35f5e07 100644 +--- a/manifests/neutron.pp ++++ b/manifests/neutron.pp +@@ -55,7 +55,7 @@ class ironic::neutron ( + $project_domain_name = $::os_service_default, + ) { + +- $api_endpoint_real = pick($::ironic::api::neutron_url, $api_endpoint) ++ $api_endpoint_real = $api_endpoint + + ironic_config { + 'neutron/url': value => $api_endpoint_real; diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0002-Dont-complain-about-xinetd-2.0.0.patch b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0002-Dont-complain-about-xinetd-2.0.0.patch new file mode 100644 index 000000000..df52c76a8 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/patches/0002-Dont-complain-about-xinetd-2.0.0.patch @@ -0,0 +1,25 @@ +From 2630b20e0f1063b68e485397ff1479898a70c5d6 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 09:13:41 -0600 +Subject: [PATCH] Dont complain about xinetd 2.0.0 + +--- + metadata.json | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/metadata.json b/metadata.json +index d796045..fdf08c7 100644 +--- a/metadata.json ++++ b/metadata.json +@@ -15,7 +15,7 @@ + {"name":"puppetlabs/vcsrepo","version_requirement":">=1.3.0 <2.0.0"}, + {"name":"openstack/oslo","version_requirement":">=11.3.0 <12.0.0"}, + {"name":"puppetlabs/apache","version_requirement":">=1.8.0 <2.0.0"}, +- {"name":"puppetlabs/xinetd","version_requirement":">=1.5.0 <2.0.0"} ++ {"name":"puppetlabs/xinetd","version_requirement":">=1.5.0 <=2.0.0"} + ], + "data_provider": null, + "description": "Installs and configures OpenStack Ironic (Bare metal).", +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/srpm_path new file mode 100644 index 000000000..020fd80c8 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-ironic-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-ironic-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..024e3e138 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=5 diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-Titanium-format.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-Titanium-format.patch new file mode 100644 index 000000000..4e31a36fb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-Titanium-format.patch @@ -0,0 +1,25 @@ +From dc2d2b15db75503e8b5f1bc639372902ad99333c Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Wed, 25 Oct 2017 16:12:09 -0400 +Subject: [PATCH] Update package versioning for Titanium format + +--- + SPECS/puppet-keystone.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-keystone.spec b/SPECS/puppet-keystone.spec +index 9dc1e0f..956664d 100644 +--- a/SPECS/puppet-keystone.spec ++++ b/SPECS/puppet-keystone.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-keystone + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Keystone + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0002-squash-titanium-patches.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0002-squash-titanium-patches.patch new file mode 100644 index 000000000..6b95d366e --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0002-squash-titanium-patches.patch @@ -0,0 +1,36 @@ +From 0fcc5269a8ee26e7aee8301c13f740dff9c2acee Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Wed, 25 Oct 2017 17:48:23 -0400 +Subject: [PATCH] squash titanium patches + +--- + SPECS/puppet-keystone.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/puppet-keystone.spec b/SPECS/puppet-keystone.spec +index 956664d..f0a18e8 100644 +--- a/SPECS/puppet-keystone.spec ++++ b/SPECS/puppet-keystone.spec +@@ -9,6 +9,9 @@ URL: https://launchpad.net/puppet-keystone + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + ++# WRS Patches ++Patch0001: 0001-pike-rebase-squash-titanium-patches.patch ++ + BuildArch: noarch + + Requires: puppet-apache +@@ -24,6 +27,9 @@ Puppet module for OpenStack Keystone + %prep + %setup -q -n openstack-keystone-%{upstream_version} + ++# WRS Patches ++%patch0001 -p1 ++ + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + + find . \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0003-remove-the-keystone-admin-app.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0003-remove-the-keystone-admin-app.patch new file mode 100644 index 000000000..9f31f9747 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0003-remove-the-keystone-admin-app.patch @@ -0,0 +1,32 @@ +From 145827dcc2c13fa18fbba2455773187dcee9b42e Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Mon, 22 Jan 2018 11:43:27 -0500 +Subject: [PATCH] remove the keystone admin app + +--- + SPECS/puppet-keystone.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-keystone.spec b/SPECS/puppet-keystone.spec +index f0a18e8..42352df 100644 +--- a/SPECS/puppet-keystone.spec ++++ b/SPECS/puppet-keystone.spec +@@ -11,6 +11,7 @@ Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_versio + + # WRS Patches + Patch0001: 0001-pike-rebase-squash-titanium-patches.patch ++Patch0002: 0002-remove-the-Keystone-admin-app.patch + + BuildArch: noarch + +@@ -29,6 +30,7 @@ Puppet module for OpenStack Keystone + + # WRS Patches + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0004-remove-eventlet_and_bindhost-from-keystoneconf.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0004-remove-eventlet_and_bindhost-from-keystoneconf.patch new file mode 100644 index 000000000..df10bab11 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/0004-remove-eventlet_and_bindhost-from-keystoneconf.patch @@ -0,0 +1,26 @@ +commit a1122168b836f9c786c4a6c58c96dde548921a06 +Author: Shoaib Nasir +Date: Thu Feb 15 15:15:33 2018 -0500 + + WRS: 0004-remove-eventlet_and_bindhost-from-keystoneconf.patch + +diff --git a/SPECS/puppet-keystone.spec b/SPECS/puppet-keystone.spec +index 42352df..36cf461 100644 +--- a/SPECS/puppet-keystone.spec ++++ b/SPECS/puppet-keystone.spec +@@ -12,6 +12,7 @@ Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_versio + # WRS Patches + Patch0001: 0001-pike-rebase-squash-titanium-patches.patch + Patch0002: 0002-remove-the-Keystone-admin-app.patch ++Patch0003: 0003-remove-eventlet_bindhost-from-Keystoneconf.patch + + BuildArch: noarch + +@@ -31,6 +32,7 @@ Puppet module for OpenStack Keystone + # WRS Patches + %patch0001 -p1 + %patch0002 -p1 ++%patch0003 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..631c6da41 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,4 @@ +0001-Update-package-versioning-for-Titanium-format.patch +0002-squash-titanium-patches.patch +0003-remove-the-keystone-admin-app.patch +0004-remove-eventlet_and_bindhost-from-keystoneconf.patch diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0001-pike-rebase-squash-titanium-patches.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0001-pike-rebase-squash-titanium-patches.patch new file mode 100644 index 000000000..b41ce9372 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0001-pike-rebase-squash-titanium-patches.patch @@ -0,0 +1,440 @@ +From 08bc7eaaa30f2d893ff357376f0d48875f9d1da5 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 9 Jan 2018 13:37:50 -0600 +Subject: [PATCH 2/3] WRS: Patch1: + 0001-pike-rebase-squash-titanium-patches.patch + +--- + lib/puppet/provider/keystone.rb | 79 ++++++++++++++++++++++- + manifests/db/sync.pp | 3 + + manifests/init.pp | 76 +++++++++++++++++----- + manifests/ldap.pp | 7 ++ + manifests/logging.pp | 2 +- + manifests/resource/service_identity.pp | 7 ++ + manifests/security_compliance.pp | 45 +++++++++++++ + spec/classes/keystone_security_compliance_spec.rb | 19 ++++++ + 8 files changed, 220 insertions(+), 18 deletions(-) + create mode 100644 manifests/security_compliance.pp + create mode 100644 spec/classes/keystone_security_compliance_spec.rb + +diff --git a/lib/puppet/provider/keystone.rb b/lib/puppet/provider/keystone.rb +index 3841418..8eb171d 100644 +--- a/lib/puppet/provider/keystone.rb ++++ b/lib/puppet/provider/keystone.rb +@@ -3,6 +3,7 @@ require 'puppet/provider/openstack' + require 'puppet/provider/openstack/auth' + require 'puppet/provider/openstack/credentials' + require File.join(File.dirname(__FILE__), '..','..', 'puppet/provider/keystone/util') ++require 'hiera_puppet' + + class Puppet::Provider::Keystone < Puppet::Provider::Openstack + +@@ -230,12 +231,88 @@ class Puppet::Provider::Keystone < Puppet::Provider::Openstack + end + end + ++ ### WRS Modifications (Start) ### ++ ++ def self.hiera_lookup(key) ++ HieraPuppet.lookup(key, :undef, self, nil, :priority) ++ end ++ ++ def self.initial_config_primary? ++ return true if ENV['INITIAL_CONFIG_PRIMARY'] == "true" ++ end ++ ++ ++ def self.upgrading? ++ return true if hiera_lookup('platform::params::controller_upgrade') == true ++ end ++ + def self.request(service, action, properties=nil, options={}) + super + rescue Puppet::Error::OpenstackAuthInputError, Puppet::Error::OpenstackUnauthorizedError => error +- request_by_service_token(service, action, error, properties, options=options) ++ if initial_config_primary? ++ # admin user account might not have been created ++ request_by_service_token(service, action, error, properties) ++ else ++ if upgrading? ++ # when running the Keystone manifest during an upgrade ++ # (on controller-1), we need to use an AUTH token and ++ # a bypass URL since using the default AUTL URL will ++ # send the Request to the service catalog URL (internalURL), ++ # running on the non-upgraded controller-0 which cannot ++ # service this request ++ request_by_upgrading_token(service, action, error, properties) ++ else ++ request_by_admin_credential(service, action, error, properties) ++ end ++ end + end + ++ def self.request_by_admin_credential(service, action, error, properties=nil) ++ properties ||= [] ++ @credentials.username = hiera_lookup('openstack::client::params::admin_username') ++ @credentials.password = hiera_lookup('keystone::admin_password') ++ @credentials.project_name = 'admin' ++ @credentials.auth_url = service_url ++ @credentials.identity_api_version = @credentials.version ++ if @credentials.version == '3' ++ @credentials.user_domain_name = hiera_lookup('openstack::client::params::admin_user_domain') ++ @credentials.project_domain_name = hiera_lookup('openstack::client::params::admin_project_domain') ++ end ++ raise error unless @credentials.set? ++ Puppet::Provider::Openstack.request(service, action, properties, @credentials) ++ end ++ ++ def self.get_upgrade_token ++ upgrade_token_file = hiera_lookup('openstack::keystone::upgrade::upgrade_token_file') ++ # the upgrade token file may get refreshed by the same Puppet event ++ # that triggered this call, and therefore may not be available ++ # immediately. Try for timeout before quitting with error ++ timeout = 10 # 10 seconds ++ 1.upto(timeout) do |iter| ++ if File.exists?(upgrade_token_file) ++ upgrade_token = File.read(upgrade_token_file).strip ++ notice("Found #{upgrade_token_file} token file and upgrade token #{upgrade_token}.") ++ return upgrade_token ++ else ++ Puppet.debug("#{upgrade_token_file} not found. Retrying for #{iter} more seconds.") ++ sleep(1) ++ end ++ end ++ raise(Puppet::ExecutionFailure, "Can't retrieve #{upgrade_token_file} in #{timeout}s retry attempts.") ++ end ++ ++ ++ def self.request_by_upgrading_token(service, action, error, properties=nil, options={}) ++ properties ||= [] ++ @credentials.token = get_upgrade_token ++ @credentials.url = hiera_lookup('openstack::keystone::upgrade::url') ++ raise error unless @credentials.service_token_set? ++ Puppet::Provider::Openstack.request(service, action, properties, @credentials, options) ++ end ++ ++ ### WRS Additions (End) ### ++ ++ + def self.request_by_service_token(service, action, error, properties=nil, options={}) + properties ||= [] + @credentials.token = admin_token +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index cee869b..cea217c 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -36,5 +36,8 @@ class keystone::db::sync( + ], + notify => Anchor['keystone::dbsync::end'], + tag => 'keystone-exec', ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "test $::controller_sw_versions_match = true", + } + } +diff --git a/manifests/init.pp b/manifests/init.pp +index 2adc685..4d79d30 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -28,6 +28,15 @@ + # The admin_token has been deprecated by the Keystone service and this + # will be deprecated in a future changeset. Required. + # ++# [*upgrade_token_cmd*] ++# (optional) WRS - if we are in an upgrade scenario, an upgrade token ++# will be required to bypass authentication. ++# Defaults to undef ++# ++# [*upgrade_token_file*] ++# (optional) WRS - the file where the upgrade token will be stowed ++# Defaults to undef ++# + # [*admin_password*] + # Keystone password for the admin user. This is not the admin_token. + # This is the password that the admin user signs into keystone with. +@@ -663,6 +672,8 @@ + # + class keystone( + $admin_token, ++ $upgrade_token_cmd = undef, ++ $upgrade_token_file = undef, + $admin_password = undef, + $package_ensure = 'present', + $client_package_ensure = 'present', +@@ -857,10 +868,13 @@ admin_token will be removed in a later release") + + keystone_config { + 'DEFAULT/admin_token': value => $admin_token, secret => true; ++ # WRS: the following options are deprecated for removal ++ # however public_bind_host and admin_bind_host are still required as long as ++ # keystone is running under eventlet + 'DEFAULT/public_bind_host': value => $public_bind_host; + 'DEFAULT/admin_bind_host': value => $admin_bind_host; +- 'DEFAULT/public_port': value => $public_port; +- 'DEFAULT/admin_port': value => $admin_port; ++ #'DEFAULT/public_port': value => $public_port; ++ #'DEFAULT/admin_port': value => $admin_port; + 'DEFAULT/member_role_id': value => $member_role_id; + 'DEFAULT/member_role_name': value => $member_role_name; + 'paste_deploy/config_file': value => $paste_config; +@@ -897,18 +911,21 @@ admin_token will be removed in a later release") + # ssl config + if ($enable_ssl) { + keystone_config { +- 'ssl/enable': value => true; ++ # WRS ssl/enable is deprecated for removal ++ #'ssl/enable': value => true; + 'ssl/certfile': value => $ssl_certfile; + 'ssl/keyfile': value => $ssl_keyfile; + 'ssl/ca_certs': value => $ssl_ca_certs; + 'ssl/ca_key': value => $ssl_ca_key; + 'ssl/cert_subject': value => $ssl_cert_subject; + } +- } else { +- keystone_config { +- 'ssl/enable': value => false; +- } + } ++ # WRS ssl/enable is deprecated for removal ++ # else { ++ # keystone_config { ++ # 'ssl/enable': value => false; ++ # } ++ #} + + if !is_service_default($memcache_servers) or !is_service_default($cache_memcache_servers) { + Service<| title == 'memcached' |> -> Anchor['keystone::service::begin'] +@@ -1016,14 +1033,15 @@ Fernet or UUID tokens are recommended.") + Fernet or UUID tokens are recommended.") + } + +- keystone_config { +- 'signing/certfile': value => $signing_certfile; +- 'signing/keyfile': value => $signing_keyfile; +- 'signing/ca_certs': value => $signing_ca_certs; +- 'signing/ca_key': value => $signing_ca_key; +- 'signing/cert_subject': value => $signing_cert_subject; +- 'signing/key_size': value => $signing_key_size; +- } ++ # WRS: the following signing options are deprecated for removal ++ #keystone_config { ++ # 'signing/certfile': value => $signing_certfile; ++ # 'signing/keyfile': value => $signing_keyfile; ++ # 'signing/ca_certs': value => $signing_ca_certs; ++ # 'signing/ca_key': value => $signing_ca_key; ++ # 'signing/cert_subject': value => $signing_cert_subject; ++ # 'signing/key_size': value => $signing_key_size; ++ #} + + # Only do pki_setup if we were asked to do so. This is needed + # regardless of the token provider since token revocation lists +@@ -1089,6 +1107,9 @@ Fernet or UUID tokens are recommended.") + heartbeat_rate => $rabbit_heartbeat_rate, + } + ++ # WRS: The following options are deprecated for removal ++ # however they are still required as long as keystone ++ # is running under eventlet + keystone_config { + 'eventlet_server/admin_workers': value => $admin_workers; + 'eventlet_server/public_workers': value => $public_workers; +@@ -1135,7 +1156,8 @@ Fernet or UUID tokens are recommended.") + validate => false, + } + } +- warning("Keystone under Eventlet has been deprecated during the Kilo cycle. \ ++ # Drop this to info. ++ info("Keystone under Eventlet has been deprecated during the Kilo cycle. \ + Support for deploying under eventlet will be dropped as of the M-release of OpenStack.") + } elsif $service_name == 'httpd' { + include ::apache::params +@@ -1280,6 +1302,27 @@ running as a standalone service, or httpd for being run by a httpd server") + } + } + ++ # WRS: Now that the keystone service has started, ++ # check if we are in an Upgrade scenario, and generate ++ # an upgrade token which will be used to bypass Keystone ++ # authentication (specifically the service catalog) for ++ # all operations during upgrades. ++ # This operation is similar to the keystone bootstrap ++ # operation (above) which would generate an admin ++ # token, and therefore also requires the database to ++ # be up and running and configured and is only run once, ++ # so we don't need to notify the service ++ if $upgrade_token_cmd and $upgrade_token_file { ++ exec { 'upgrade token issue': ++ command => "${upgrade_token_cmd} > ${upgrade_token_file}", ++ path => '/usr/bin', ++ creates => $upgrade_token_file, ++ subscribe => Service[$service_name], ++ notify => Anchor['keystone::service::end'], ++ tag => 'keystone-exec', ++ } ++ } ++ + if $using_domain_config { + validate_absolute_path($domain_config_directory) + # Better than ensure resource. We don't want to conflict with any +@@ -1311,4 +1354,5 @@ running as a standalone service, or httpd for being run by a httpd server") + {'value' => $domain_config_directory} + ) + } ++ + } +diff --git a/manifests/ldap.pp b/manifests/ldap.pp +index 11620bf..728ca40 100644 +--- a/manifests/ldap.pp ++++ b/manifests/ldap.pp +@@ -4,6 +4,11 @@ + # + # === parameters: + # ++# [*debug_level*] ++# LDAP debugging level for LDAP calls; a value of zero("0") disables ++# debugging. (integer value) ++# Defaults to 'undef' ++# + # [*url*] + # URL for connecting to the LDAP server. (string value) + # Defaults to 'undef' +@@ -384,6 +389,7 @@ + # Copyright 2012 Puppetlabs Inc, unless otherwise noted. + # + class keystone::ldap( ++ $debug_level = undef, + $url = undef, + $user = undef, + $password = undef, +@@ -494,6 +500,7 @@ class keystone::ldap( + } + + keystone_config { ++ 'ldap/debug_level': value => $debug_level; + 'ldap/url': value => $url; + 'ldap/user': value => $user; + 'ldap/password': value => $password, secret => true; +diff --git a/manifests/logging.pp b/manifests/logging.pp +index e737c4f..3d8df63 100644 +--- a/manifests/logging.pp ++++ b/manifests/logging.pp +@@ -110,7 +110,7 @@ class keystone::logging( + $log_file = $::os_service_default, + $debug = $::os_service_default, + $logging_context_format_string = $::os_service_default, +- $logging_default_format_string = $::os_service_default, ++ $logging_default_format_string = 'keystone:log %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s', + $logging_debug_format_suffix = $::os_service_default, + $logging_exception_prefix = $::os_service_default, + $logging_user_identity_format = $::os_service_default, +diff --git a/manifests/resource/service_identity.pp b/manifests/resource/service_identity.pp +index 09e7d94..243c9ec 100644 +--- a/manifests/resource/service_identity.pp ++++ b/manifests/resource/service_identity.pp +@@ -187,6 +187,8 @@ define keystone::resource::service_identity( + if $service_type { + ensure_resource('keystone_service', "${service_name_real}::${service_type}", { + 'ensure' => $ensure, ++ 'name' => $service_name_real, ++ 'type' => $service_type, + 'description' => $service_description, + }) + } else { +@@ -199,6 +201,9 @@ define keystone::resource::service_identity( + if $public_url and $admin_url and $internal_url { + ensure_resource('keystone_endpoint', "${region}/${service_name_real}::${service_type}", { + 'ensure' => $ensure, ++ 'name' => $service_name_real, ++ 'type' => $service_type, ++ 'region' => $region, + 'public_url' => $public_url, + 'admin_url' => $admin_url, + 'internal_url' => $internal_url, +@@ -210,6 +215,8 @@ define keystone::resource::service_identity( + if $public_url and $admin_url and $internal_url { + ensure_resource('keystone_endpoint', "${region}/${service_name_real}", { + 'ensure' => $ensure, ++ 'name' => $service_name_real, ++ 'region' => $region, + 'public_url' => $public_url, + 'admin_url' => $admin_url, + 'internal_url' => $internal_url, +diff --git a/manifests/security_compliance.pp b/manifests/security_compliance.pp +new file mode 100644 +index 0000000..64830ec +--- /dev/null ++++ b/manifests/security_compliance.pp +@@ -0,0 +1,45 @@ ++# == class: keystone::security_compliance ++# ++# Implements security compliance configuration for keystone. ++# ++# === parameters: ++# ++# [*unique_last_password_count*] ++# This controls the number of previous user password iterations ++# to keep in history, in order to enforce that newly created passwords ++# are unique. Setting the value to 1 (the default) disables this feature. ++# (integer value) ++# Defaults to 'undef' ++# ++# [*password_regex*] ++# The regular expression used to validate password strength ++# requirements. By default, the regular expression will match ++# any password. (string value) ++# Defaults to 'undef' ++# ++# [*password_regex_description*] ++# If a password fails to match the regular expression (*password_regex*), ++# the contents of this configuration will be returned to users to explain ++# why their requested password was insufficient. (string value) ++# Defaults to 'undef' ++# ++# === DEPRECATED group/name ++# ++# == Copyright ++# ++# Copyright 2017 Wind River Systems, unless otherwise noted. ++# ++class keystone::security_compliance( ++ $unique_last_password_count = undef, ++ $password_regex = undef, ++ $password_regex_description = undef, ++) { ++ ++ include ::keystone::deps ++ ++ keystone_config { ++ 'security_compliance/unique_last_password_count': value => $unique_last_password_count; ++ 'security_compliance/password_regex': value => $password_regex; ++ 'security_compliance/password_regex_description': value => $password_regex_description; ++ } ++} +diff --git a/spec/classes/keystone_security_compliance_spec.rb b/spec/classes/keystone_security_compliance_spec.rb +new file mode 100644 +index 0000000..d0d4724 +--- /dev/null ++++ b/spec/classes/keystone_security_compliance_spec.rb +@@ -0,0 +1,19 @@ ++require 'spec_helper' ++ ++describe 'keystone::security_compliance' do ++ describe 'with basic params' do ++ let :params do ++ { ++ :unique_last_password_count => 2, ++ :password_regex => '^(?=.*\d)(?=.*[a-zA-Z]).{7,}$', ++ :password_regex_description => 'password must be at least 7 characters long and contain 1 digit', ++ } ++ end ++ it 'should have basic params' do ++ # basic params ++ is_expected.to contain_keystone_config('security_compliance/unique_last_password_count').with_value('2') ++ is_expected.to contain_keystone_config('security_compliance/password_regex').with_value('^(?=.*\d)(?=.*[a-zA-Z]).{7,}$') ++ is_expected.to contain_keystone_config('security_compliance/password_regex_description').with_value('password must be at least 7 characters long and contain 1 digit') ++ end ++ end ++end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0002-remove-the-Keystone-admin-app.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0002-remove-the-Keystone-admin-app.patch new file mode 100644 index 000000000..7499a8c80 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0002-remove-the-Keystone-admin-app.patch @@ -0,0 +1,37 @@ +From 0fb9013aa056db642457e93a20499fd9b46ba436 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Mon, 22 Jan 2018 11:18:08 -0500 +Subject: [PATCH] CGTS-8701: Remove the Keystone-admin app + +Following the Pike rebase, no services are using Identity V2 and +therefore we can shut off the Keystone admin port / app, as in Identity +V3 the public endpoint and admin endpoints both offer identical services +--- + lib/puppet/provider/keystone.rb | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lib/puppet/provider/keystone.rb b/lib/puppet/provider/keystone.rb +index 8eb171d..3c310dc 100644 +--- a/lib/puppet/provider/keystone.rb ++++ b/lib/puppet/provider/keystone.rb +@@ -171,12 +171,16 @@ class Puppet::Provider::Keystone < Puppet::Provider::Openstack + end + + def self.get_admin_endpoint ++ # NOTE (knasim-wrs): As of the Pike rebase, the public port(5000) ++ # provides the same functionality as the admin port(35357). We ++ # shall therefore not deploy the keystone-admin app and return ++ # the public port + endpoint = nil + if keystone_file + if url = get_section('DEFAULT', 'admin_endpoint') + endpoint = url.chomp('/') + else +- admin_port = get_section('DEFAULT', 'admin_port') || '35357' ++ admin_port = get_section('DEFAULT', 'public_port') || '5000' + host = clean_host(get_section('DEFAULT', 'admin_bind_host')) + protocol = ssl? ? 'https' : 'http' + endpoint = "#{protocol}://#{host}:#{admin_port}" +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0003-remove-eventlet_bindhost-from-Keystoneconf.patch b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0003-remove-eventlet_bindhost-from-Keystoneconf.patch new file mode 100644 index 000000000..905118cdc --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/patches/0003-remove-eventlet_bindhost-from-Keystoneconf.patch @@ -0,0 +1,39 @@ +commit bb91ab26622a5ec695c6564af5a9e5e54fdc903c +Author: Shoaib Nasir +Date: Thu Feb 15 15:04:55 2018 -0500 + + WRS: Patch3: 0003-remove-eventlet_bindhost-from-Keystoneconf.patch + +diff --git a/manifests/init.pp b/manifests/init.pp +index 4d79d30..d64638c 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -871,8 +871,9 @@ admin_token will be removed in a later release") + # WRS: the following options are deprecated for removal + # however public_bind_host and admin_bind_host are still required as long as + # keystone is running under eventlet +- 'DEFAULT/public_bind_host': value => $public_bind_host; +- 'DEFAULT/admin_bind_host': value => $admin_bind_host; ++ # WRS: bind_host options removed from keystone.conf [DEFAULT] ++ #'DEFAULT/public_bind_host': value => $public_bind_host; ++ #'DEFAULT/admin_bind_host': value => $admin_bind_host; + #'DEFAULT/public_port': value => $public_port; + #'DEFAULT/admin_port': value => $admin_port; + 'DEFAULT/member_role_id': value => $member_role_id; +@@ -1110,10 +1111,12 @@ Fernet or UUID tokens are recommended.") + # WRS: The following options are deprecated for removal + # however they are still required as long as keystone + # is running under eventlet +- keystone_config { +- 'eventlet_server/admin_workers': value => $admin_workers; +- 'eventlet_server/public_workers': value => $public_workers; +- } ++ # WRS(snasir): Removing these options from keystone.conf ++ # since they are now populated in keystone-api.conf ++ #keystone_config { ++ # 'eventlet_server/admin_workers': value => $admin_workers; ++ # 'eventlet_server/public_workers': value => $public_workers; ++ #} + + if $manage_service { + if $enabled { diff --git a/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/srpm_path new file mode 100644 index 000000000..875b491b1 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-keystone-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-keystone-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch new file mode 100644 index 000000000..7bce16d4a --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch @@ -0,0 +1,40 @@ +From e3452f7601e328207daa45ec0120907630a9568c Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Wed, 29 Nov 2017 11:04:00 -0500 +Subject: [PATCH 1/1] meta Pike rebase + +--- + SPECS/puppet-magnum.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/puppet-magnum.spec b/SPECS/puppet-magnum.spec +index e1aac22..fd77fec 100644 +--- a/SPECS/puppet-magnum.spec ++++ b/SPECS/puppet-magnum.spec +@@ -2,13 +2,14 @@ + + Name: puppet-magnum + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Magnum + License: ASL 2.0 + + URL: https://launchpad.net/puppet-magnum + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Pike-Rebase.patch + + BuildArch: noarch + +@@ -24,6 +25,7 @@ Installs and configures OpenStack Magnum. + + %prep + %setup -q -n openstack-magnum-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch new file mode 100644 index 000000000..3884a1de7 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch @@ -0,0 +1,32 @@ +From 06305a07fa3028ab15f115a510e9e4a71c8730c4 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Tue, 30 Jan 2018 09:54:26 -0500 +Subject: [PATCH 1/1] meta fixed puppet deprecated warnings + +--- + SPECS/puppet-magnum.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-magnum.spec b/SPECS/puppet-magnum.spec +index fd77fec..207953e 100644 +--- a/SPECS/puppet-magnum.spec ++++ b/SPECS/puppet-magnum.spec +@@ -10,6 +10,7 @@ URL: https://launchpad.net/puppet-magnum + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + Patch0001: 0001-Pike-Rebase.patch ++Patch0002: 0002-fixed-puppet-deprecated-warnings.patch + + BuildArch: noarch + +@@ -26,6 +27,7 @@ Installs and configures OpenStack Magnum. + %prep + %setup -q -n openstack-magnum-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..01447c344 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-meta-Pike-rebase.patch +0002-meta-fixed-puppet-deprecated-warnings.patch diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0001-Pike-Rebase.patch b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0001-Pike-Rebase.patch new file mode 100644 index 000000000..86e9dc89f --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0001-Pike-Rebase.patch @@ -0,0 +1,63 @@ +From 5c591519c2c72827c1480bffb286949e61b649c8 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Wed, 29 Nov 2017 10:53:19 -0500 +Subject: [PATCH 1/1] Pike Rebase + +--- + manifests/init.pp | 7 +++++++ + manifests/keystone/domain.pp | 4 +++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index e9fed95..4f10c2f 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -97,6 +97,10 @@ + # rabbit (for rabbitmq) + # Defaults to 'rabbit' + # ++# WRS ++# [*password_symbols*] ++# (optional) Restrictions on password creation ++# + class magnum( + $package_ensure = 'present', + $notification_transport_url = $::os_service_default, +@@ -119,6 +123,8 @@ class magnum( + $rabbit_virtual_host = $::os_service_default, + $rabbit_password = $::os_service_default, + $rpc_backend = 'rabbit', ++ # WRS ++ $password_symbols = '23456789,ABCDEFGHJKLMNPQRSTUVWXYZ,abcdefghijkmnopqrstuvwxyz', + ) { + + include ::magnum::deps +@@ -176,4 +182,5 @@ instead.") + topics => $notification_topics, + } + ++ magnum_config { 'DEFAULT/password_symbols': value => $password_symbols } + } +diff --git a/manifests/keystone/domain.pp b/manifests/keystone/domain.pp +index 5d9a25d..836fd27 100644 +--- a/manifests/keystone/domain.pp ++++ b/manifests/keystone/domain.pp +@@ -55,12 +55,14 @@ class magnum::keystone::domain ( + ) + } + ++ # fix user name that has the domain name appended + if $manage_user { +- ensure_resource('keystone_user', "${domain_admin}::${domain_name}", { ++ ensure_resource('keystone_user', "${domain_admin}", { + 'ensure' => 'present', + 'enabled' => true, + 'email' => $domain_admin_email, + 'password' => $domain_password, ++ 'domain' => $domain_name, + } + ) + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch new file mode 100644 index 000000000..a577e3fdb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch @@ -0,0 +1,25 @@ +From 772b57dd30d231773bb6e63d06a8d6ba3d37e7d6 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Tue, 30 Jan 2018 09:51:47 -0500 +Subject: [PATCH 1/1] fixed puppet deprecated warnings + +--- + manifests/init.pp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 4f10c2f..a741a54 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -122,7 +122,7 @@ class magnum( + $rabbit_userid = $::os_service_default, + $rabbit_virtual_host = $::os_service_default, + $rabbit_password = $::os_service_default, +- $rpc_backend = 'rabbit', ++ $rpc_backend = undef, + # WRS + $password_symbols = '23456789,ABCDEFGHJKLMNPQRSTUVWXYZ,abcdefghijkmnopqrstuvwxyz', + ) { +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/srpm_path new file mode 100644 index 000000000..1234d1843 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-magnum-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-magnum-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..d3f64f336 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=3 diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch new file mode 100644 index 000000000..ccb4bc419 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0001-meta-Pike-rebase.patch @@ -0,0 +1,40 @@ +From d227bb7cb1ac1320ed92c8541bb20983bfc7b9ec Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Wed, 29 Nov 2017 12:48:33 -0500 +Subject: [PATCH 1/1] meta Pike rebase + +--- + SPECS/puppet-murano.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/puppet-murano.spec b/SPECS/puppet-murano.spec +index d842fd7..6ea0cde 100644 +--- a/SPECS/puppet-murano.spec ++++ b/SPECS/puppet-murano.spec +@@ -2,13 +2,14 @@ + + Name: puppet-murano + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Murano + License: ASL 2.0 + + URL: https://launchpad.net/puppet-murano + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{version}.tar.gz ++Patch0001: 0001-Pike-Rebase.patch + + BuildArch: noarch + +@@ -25,6 +26,7 @@ Installs and configures OpenStack Murano (Application Catalog). + + %prep + %setup -q -n openstack-murano-%{upstream_version} ++%patch0001 -p1 + + + find . -type f -name ".*" -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch new file mode 100644 index 000000000..ea0fb29fd --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0002-meta-fixed-puppet-deprecated-warnings.patch @@ -0,0 +1,32 @@ +From 641d0ba770d605aa63023e08946d10b39763df8f Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Tue, 30 Jan 2018 09:49:25 -0500 +Subject: [PATCH 1/1] meta fixed puppet deprecated warnings + +--- + SPECS/puppet-murano.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-murano.spec b/SPECS/puppet-murano.spec +index 6ea0cde..51b1ef2 100644 +--- a/SPECS/puppet-murano.spec ++++ b/SPECS/puppet-murano.spec +@@ -10,6 +10,7 @@ URL: https://launchpad.net/puppet-murano + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{version}.tar.gz + Patch0001: 0001-Pike-Rebase.patch ++Patch0002: 0002-fixed-puppet-deprecated-warnings.patch + + BuildArch: noarch + +@@ -27,6 +28,7 @@ Installs and configures OpenStack Murano (Application Catalog). + %prep + %setup -q -n openstack-murano-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + + find . -type f -name ".*" -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0003-meta-expose-heat-and-neutron-endpoint-type.patch b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0003-meta-expose-heat-and-neutron-endpoint-type.patch new file mode 100644 index 000000000..ecba13188 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/0003-meta-expose-heat-and-neutron-endpoint-type.patch @@ -0,0 +1,32 @@ +From f2b369cb0f552dcd3461204d95fd36076e3558af Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Mon, 12 Feb 2018 16:03:11 -0500 +Subject: [PATCH 1/1] meta expose heat and neutron endpoint type + +--- + SPECS/puppet-murano.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-murano.spec b/SPECS/puppet-murano.spec +index 51b1ef2..bcf51b2 100644 +--- a/SPECS/puppet-murano.spec ++++ b/SPECS/puppet-murano.spec +@@ -11,6 +11,7 @@ URL: https://launchpad.net/puppet-murano + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{version}.tar.gz + Patch0001: 0001-Pike-Rebase.patch + Patch0002: 0002-fixed-puppet-deprecated-warnings.patch ++Patch0003: 0003-expose-heat-and-neutron-endpoint-type.patch + + BuildArch: noarch + +@@ -29,6 +30,7 @@ Installs and configures OpenStack Murano (Application Catalog). + %setup -q -n openstack-murano-%{upstream_version} + %patch0001 -p1 + %patch0002 -p1 ++%patch0003 -p1 + + + find . -type f -name ".*" -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..4faa35267 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-meta-Pike-rebase.patch +0002-meta-fixed-puppet-deprecated-warnings.patch +0003-meta-expose-heat-and-neutron-endpoint-type.patch diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0001-Pike-Rebase.patch b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0001-Pike-Rebase.patch new file mode 100644 index 000000000..a7a5bafae --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0001-Pike-Rebase.patch @@ -0,0 +1,153 @@ +From 23266d5d4ce487895635fea4e919c9b1490d44d6 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Wed, 29 Nov 2017 12:45:05 -0500 +Subject: [PATCH 1/1] Pike Rebase + +--- + manifests/dashboard.pp | 37 ------------------------------------- + manifests/init.pp | 12 ++++++++++++ + manifests/params.pp | 4 ++-- + 3 files changed, 14 insertions(+), 39 deletions(-) + +diff --git a/manifests/dashboard.pp b/manifests/dashboard.pp +index 8668cec..7c879d9 100644 +--- a/manifests/dashboard.pp ++++ b/manifests/dashboard.pp +@@ -72,26 +72,6 @@ class murano::dashboard( + tag => ['openstack', 'murano-packages'], + } + +- concat { $::murano::params::local_settings_path: } +- +- concat::fragment { 'original_config': +- target => $::murano::params::local_settings_path, +- source => $::murano::params::local_settings_path, +- order => 1, +- } +- +- concat::fragment { 'murano_dashboard_section': +- target => $::murano::params::local_settings_path, +- content => template('murano/local_settings.py.erb'), +- order => 2, +- } +- +- exec { 'clean_horizon_config': +- command => "sed -e '/^## MURANO_CONFIG_BEGIN/,/^## MURANO_CONFIG_END ##/ d' -i ${::murano::params::local_settings_path}", +- onlyif => "grep '^## MURANO_CONFIG_BEGIN' ${::murano::params::local_settings_path}", +- path => [ '/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/' ], +- } +- + if $::os_package_type == 'ubuntu' { + $collect_static_command = "${collect_static_script} collectstatic --noinput" + } else { +@@ -100,29 +80,17 @@ class murano::dashboard( + + exec { 'django_collectstatic': + command => $collect_static_command, +- environment => [ +- "APACHE_USER=${::apache::params::user}", +- "APACHE_GROUP=${::apache::params::group}", +- ], + refreshonly => true, + } + + exec { 'django_compressstatic': + command => "${collect_static_script} compress --force", +- environment => [ +- "APACHE_USER=${::apache::params::user}", +- "APACHE_GROUP=${::apache::params::group}", +- ], + refreshonly => true, + } + + if $sync_db { + exec { 'django_syncdb': + command => "${collect_static_script} migrate --noinput", +- environment => [ +- "APACHE_USER=${::apache::params::user}", +- "APACHE_GROUP=${::apache::params::group}", +- ], + refreshonly => true, + } + +@@ -132,11 +100,6 @@ class murano::dashboard( + } + + Package['murano-dashboard'] +- -> Exec['clean_horizon_config'] +- -> Concat[$::murano::params::local_settings_path] +- -> Service <| title == 'httpd' |> +- +- Package['murano-dashboard'] + ~> Exec['django_collectstatic'] + ~> Exec['django_compressstatic'] + ~> Service <| title == 'httpd' |> +diff --git a/manifests/init.pp b/manifests/init.pp +index 1cc27cc..54ddd50 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -275,6 +275,13 @@ + # (optional) The RabbitMQ virtual host. + # Defaults to $::os_service_default + # ++# === WRS addons ++# [disable_murano_agent] ++# (Optional) disable the use of murano agent ++# ++# [api_workers] ++# number of api workers ++# + class murano( + $admin_password, + $package_ensure = 'present', +@@ -331,6 +338,9 @@ class murano( + $auth_uri = 'http://127.0.0.1:5000', + $memcached_servers = $::os_service_default, + $purge_config = false, ++ # WRS ++ $disable_murano_agent = true, ++ $api_workers = $::os_service_default, + # Deprecated + $identity_uri = 'http://127.0.0.1:35357/', + $rabbit_os_host = $::os_service_default, +@@ -410,6 +420,7 @@ deprecated. Please use murano::default_transport_url instead.") + + murano_config { + 'murano/url' : value => "${service_protocol}://${service_host}:${service_port}"; ++ 'murano/api_workers' : value => $api_workers; + + 'engine/use_trusts' : value => $use_trusts; + +@@ -430,6 +441,7 @@ deprecated. Please use murano::default_transport_url instead.") + + 'networking/default_dns': value => $default_nameservers; + ++ 'engine/disable_murano_agent': value => $disable_murano_agent; + 'engine/packages_service': value => $packages_service, + } + +diff --git a/manifests/params.pp b/manifests/params.pp +index b3eca3f..cf606f0 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -20,7 +20,7 @@ class murano::params { + $common_package_name = 'openstack-murano-common' + $engine_package_name = 'openstack-murano-engine' + $pythonclient_package_name = 'python-muranoclient' +- $dashboard_package_name = 'openstack-murano-dashboard' ++ $dashboard_package_name = 'openstack-murano-ui' + # service names + $cfapi_service_name = 'murano-cf-api' + # dashboard config file +@@ -33,7 +33,7 @@ class murano::params { + $common_package_name = 'murano-common' + $engine_package_name = 'murano-engine' + $pythonclient_package_name = 'python-muranoclient' +- $dashboard_package_name = 'python-murano-dashboard' ++ $dashboard_package_name = 'python-murano-ui' + # service names + $cfapi_service_name = 'murano-cfapi' + # dashboard config file +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch new file mode 100644 index 000000000..458192232 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0002-fixed-puppet-deprecated-warnings.patch @@ -0,0 +1,28 @@ +From 3c0c5fa0443c07f7c092b1d97989f881fc623172 Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Tue, 30 Jan 2018 09:43:42 -0500 +Subject: [PATCH 1/1] removed default values for depricated fields; they were + causing warnings + +--- + manifests/init.pp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 54ddd50..09d3f13 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -347,8 +347,8 @@ class murano( + $rabbit_os_port = $::os_service_default, + $rabbit_os_hosts = $::os_service_default, + $rabbit_os_virtual_host = $::os_service_default, +- $rabbit_os_user = 'guest', +- $rabbit_os_password = 'guest', ++ $rabbit_os_user = $::os_service_default, ++ $rabbit_os_password = $::os_service_default, + ) inherits murano::params { + + include ::murano::deps +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0003-expose-heat-and-neutron-endpoint-type.patch b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0003-expose-heat-and-neutron-endpoint-type.patch new file mode 100644 index 000000000..2349b1546 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/patches/0003-expose-heat-and-neutron-endpoint-type.patch @@ -0,0 +1,35 @@ +From cb98572b4d1b59eaefc1410ae84d67c57714f35e Mon Sep 17 00:00:00 2001 +From: Jerry Sun +Date: Mon, 12 Feb 2018 15:58:37 -0500 +Subject: [PATCH 1/1] Expose heat and neutron endpoint type + +--- + manifests/init.pp | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 09d3f13..45c13c9 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -341,6 +341,8 @@ class murano( + # WRS + $disable_murano_agent = true, + $api_workers = $::os_service_default, ++ $neutron_endpoint_type = 'internalURL', ++ $heat_endpoint_type = 'internalURL', + # Deprecated + $identity_uri = 'http://127.0.0.1:35357/', + $rabbit_os_host = $::os_service_default, +@@ -478,4 +480,9 @@ deprecated. Please use murano::default_transport_url instead.") + if $sync_db { + include ::murano::db::sync + } ++ ++ murano_config { ++ 'neutron/endpoint_type': value => $neutron_endpoint_type; ++ 'heat/endpoint_type': value => $heat_endpoint_type; ++ } + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/srpm_path new file mode 100644 index 000000000..4e792971b --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-murano-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-murano-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..d62463022 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=13 diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..3ef74a9f1 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 4f8a132a691a6c4610424b7a7def4266e1ac5143 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 3 Jan 2017 13:30:12 -0500 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-neutron.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-neutron.spec b/SPECS/puppet-neutron.spec +index 854a666..652d16e 100644 +--- a/SPECS/puppet-neutron.spec ++++ b/SPECS/puppet-neutron.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-neutron + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Neutron + License: Apache-2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0002-Add-TiS-patches.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0002-Add-TiS-patches.patch new file mode 100644 index 000000000..1d9d30863 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0002-Add-TiS-patches.patch @@ -0,0 +1,46 @@ +From 67ee34be8bd3e7829442c97600118148f874ab8d Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Thu, 9 Nov 2017 17:57:50 -0500 +Subject: [PATCH 2/2] Add TiS patches + +--- + SPECS/puppet-neutron.spec | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/SPECS/puppet-neutron.spec b/SPECS/puppet-neutron.spec +index 12252ad..684b3d6 100644 +--- a/SPECS/puppet-neutron.spec ++++ b/SPECS/puppet-neutron.spec +@@ -8,6 +8,14 @@ License: ASL 2.0 + URL: https://launchpad.net/puppet-neutron + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-Remove-broken-authtoken-references.patch ++Patch0003: 0003-control-provider-network-testing-state.patch ++Patch0004: 0004-set-wsgi-pool-size-to-10-from-100.patch ++Patch0005: 0005-Add-support-for-neutron-bgp-dragent.patch ++Patch0006: 0006-Add-parameters-to-classes.patch ++Patch0007: 0007-update-neutron-bgp-to-use-class-variables.patch ++Patch0008: 0008-dvr-allow-base-mac-address-to-be-configured.patch + + BuildArch: noarch + +@@ -26,6 +34,14 @@ Puppet module for OpenStack Neutron + + %prep + %setup -q -n openstack-neutron-%{upstream_version} ++%patch0001 -p1 ++%patch0002 -p1 ++%patch0003 -p1 ++%patch0004 -p1 ++%patch0005 -p1 ++%patch0006 -p1 ++%patch0007 -p1 ++%patch0008 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0003-add-support-for-networking-sfc.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0003-add-support-for-networking-sfc.patch new file mode 100644 index 000000000..d72f27aa7 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/0003-add-support-for-networking-sfc.patch @@ -0,0 +1,32 @@ +From 6239a87b6ea7e24b2a8d612ad443f09de845d6dd Mon Sep 17 00:00:00 2001 +From: Steven Webster +Date: Fri, 5 Jan 2018 12:02:20 -0500 +Subject: [PATCH 1/1] Add support for networking SFC + +--- + SPECS/puppet-neutron.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-neutron.spec b/SPECS/puppet-neutron.spec +index 684b3d6..58bbd24 100644 +--- a/SPECS/puppet-neutron.spec ++++ b/SPECS/puppet-neutron.spec +@@ -16,6 +16,7 @@ Patch0005: 0005-Add-support-for-neutron-bgp-dragent.patch + Patch0006: 0006-Add-parameters-to-classes.patch + Patch0007: 0007-update-neutron-bgp-to-use-class-variables.patch + Patch0008: 0008-dvr-allow-base-mac-address-to-be-configured.patch ++Patch0009: 0009-add-support-for-networking-sfc.patch + + BuildArch: noarch + +@@ -42,6 +43,7 @@ Puppet module for OpenStack Neutron + %patch0006 -p1 + %patch0007 -p1 + %patch0008 -p1 ++%patch0009 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..ada94f815 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TiS-patches.patch +0003-add-support-for-networking-sfc.patch diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..ef8ec492e --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,586 @@ +From ec56923ecaf2081330b8fa6bf8e4616642275a9b Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 16:31:33 -0500 +Subject: [PATCH 1/8] Roll up TIS patches + +--- + .../ini_setting.rb | 22 ++++++ + .../type/neutron_nuage_metadata_agent_config.rb | 42 +++++++++++ + manifests/agents/dhcp.pp | 9 ++- + manifests/agents/l3.pp | 10 ++- + manifests/agents/metadata.pp | 9 ++- + manifests/agents/ml2/sriov.pp | 2 + + manifests/agents/nuage_metadata.pp | 86 ++++++++++++++++++++++ + manifests/db/sync.pp | 3 + + manifests/init.pp | 27 +++++++ + manifests/params.pp | 75 ++++++++++--------- + manifests/plugins/ml2.pp | 5 ++ + manifests/plugins/ml2/type_driver.pp | 5 +- + manifests/server.pp | 4 + + manifests/server/notifications.pp | 10 +++ + 18 files changed, 437 insertions(+), 38 deletions(-) + create mode 100644 lib/puppet/provider/neutron_nuage_metadata_agent_config/ini_setting.rb + create mode 100644 lib/puppet/type/neutron_nuage_metadata_agent_config.rb + create mode 100644 manifests/agents/nuage_metadata.pp + +diff --git a/lib/puppet/provider/neutron_nuage_metadata_agent_config/ini_setting.rb b/lib/puppet/provider/neutron_nuage_metadata_agent_config/ini_setting.rb +new file mode 100644 +index 0000000..d1d9c4e +--- /dev/null ++++ b/lib/puppet/provider/neutron_nuage_metadata_agent_config/ini_setting.rb +@@ -0,0 +1,22 @@ ++Puppet::Type.type(:neutron_nuage_metadata_agent_config).provide( ++ :ini_setting, ++ :parent => Puppet::Type.type(:ini_setting).provider(:ruby) ++) do ++ ++ def section ++ resource[:name].split('/', 2).first ++ end ++ ++ def setting ++ resource[:name].split('/', 2).last ++ end ++ ++ def separator ++ '=' ++ end ++ ++ def file_path ++ '/etc/default/nuage-metadata-agent' ++ end ++ ++end +diff --git a/lib/puppet/type/neutron_nuage_metadata_agent_config.rb b/lib/puppet/type/neutron_nuage_metadata_agent_config.rb +new file mode 100644 +index 0000000..0559841 +--- /dev/null ++++ b/lib/puppet/type/neutron_nuage_metadata_agent_config.rb +@@ -0,0 +1,42 @@ ++Puppet::Type.newtype(:neutron_nuage_metadata_agent_config) do ++ ++ ensurable ++ ++ newparam(:name, :namevar => true) do ++ desc 'Section/setting name to manage from nuage-metadata-agent' ++ newvalues(/\S*\/\S+/) ++ end ++ ++ newproperty(:value) do ++ desc 'The value of the setting to be defined.' ++ munge do |value| ++ value = value.to_s.strip ++ value ++ end ++ ++ def is_to_s( currentvalue ) ++ if resource.secret? ++ return '[old secret redacted]' ++ else ++ return currentvalue ++ end ++ end ++ ++ def should_to_s( newvalue ) ++ if resource.secret? ++ return '[new secret redacted]' ++ else ++ return newvalue ++ end ++ end ++ end ++ ++ newparam(:secret, :boolean => true) do ++ desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' ++ ++ newvalues(:true, :false) ++ ++ defaultto false ++ end ++ ++end +diff --git a/manifests/agents/dhcp.pp b/manifests/agents/dhcp.pp +index 0f5f26f..e8ca41b 100644 +--- a/manifests/agents/dhcp.pp ++++ b/manifests/agents/dhcp.pp +@@ -162,10 +162,17 @@ class neutron::agents::dhcp ( + } + } + ++ # WRS disabling this in CentOS ?? ++ if $::operatingsystem == 'CentOS' { ++ $real_enabled = false ++ } else { ++ $real_enabled = $enabled ++ } ++ + service { 'neutron-dhcp-service': + ensure => $service_ensure, + name => $::neutron::params::dhcp_agent_service, +- enable => $enabled, ++ enable => $real_enabled, + tag => 'neutron-service', + } + } +diff --git a/manifests/agents/l3.pp b/manifests/agents/l3.pp +index 651c750..c02d132 100644 +--- a/manifests/agents/l3.pp ++++ b/manifests/agents/l3.pp +@@ -159,10 +159,18 @@ class neutron::agents::l3 ( + } else { + $service_ensure = 'stopped' + } ++ ++ # WRS. ++ if $::operatingsystem == 'CentOS' { ++ $real_enabled = false ++ } else { ++ $real_enabled = $enabled ++ } ++ + service { 'neutron-l3': + ensure => $service_ensure, + name => $::neutron::params::l3_agent_service, +- enable => $enabled, ++ enable => $real_enabled, + tag => 'neutron-service', + } + } +diff --git a/manifests/agents/metadata.pp b/manifests/agents/metadata.pp +index 0619a59..b0691e2 100644 +--- a/manifests/agents/metadata.pp ++++ b/manifests/agents/metadata.pp +@@ -135,10 +135,17 @@ class neutron::agents::metadata ( + } + } + ++ # WRS ++ if $::operatingsystem == 'CentOS' { ++ $real_enabled = false ++ } else { ++ $real_enabled = $enabled ++ } ++ + service { 'neutron-metadata': + ensure => $service_ensure, + name => $::neutron::params::metadata_agent_service, +- enable => $enabled, ++ enable => $real_enabled, + tag => 'neutron-service', + } + } +diff --git a/manifests/agents/ml2/sriov.pp b/manifests/agents/ml2/sriov.pp +index 9b25b43..736cbee 100644 +--- a/manifests/agents/ml2/sriov.pp ++++ b/manifests/agents/ml2/sriov.pp +@@ -114,6 +114,8 @@ class neutron::agents::ml2::sriov ( + } else { + $service_ensure = 'stopped' + } ++ } else { ++ $service_ensure = 'stopped' + } + + service { 'neutron-sriov-nic-agent-service': +diff --git a/manifests/agents/nuage_metadata.pp b/manifests/agents/nuage_metadata.pp +new file mode 100644 +index 0000000..776a3db +--- /dev/null ++++ b/manifests/agents/nuage_metadata.pp +@@ -0,0 +1,86 @@ ++# == Class: neutron::agents::nuage_metadata ++# ++# Setup and configure Neutron nuage metadata agent. ++# ++# === Parameters ++# ++# [*metadata_port*] ++# The TCP Port used by Nuage metadata agent. Defaults to 9697. ++# ++# [*nova_metadata_ip*] ++# (required) IP address used by Nova metadata server. ++# ++# [*nova_metadata_port*] ++# The TCP Port used by Nova metadata server. Defaults to 8775. ++# ++# [*metadata_proxy_shared_secret*] ++# (required) Used to sign the Instance-ID header. ++# ++# [*nova_client_version*] ++# Version of nova client. Defaults to 2. ++# ++# [*nova_os_username*] ++# (required) Nova username. ++# ++# [*nova_os_password*] ++# (required) Nova password. ++# ++# [*nova_os_tenant_name*] ++# (required) Nova tenant name. ++# ++# [*nova_os_auth_url*] ++# (required) Nova auth URL. Format: http://:5000/v2.0 ++# ++# [*nova_metadata_agent_start_with_ovs*] ++# If nuage-metadata-agent needs to be started with nuage-openvswitch-switch. ++# Defaults to true. ++# ++# [*nova_api_endpoint_type*] ++# Nova API endpoint type (one of publicURL, internalURL, adminURL). ++# Defaults to publicURL. ++# ++# [*nova_region_name*] ++# (required) Nova region name. ++# ++ ++class neutron::agents::nuage_metadata ( ++ $metadata_port = '9697', ++ $nova_metadata_ip = undef, ++ $nova_metadata_port = '8775', ++ $metadata_proxy_shared_secret, ++ $nova_client_version = '2', ++ $nova_os_username = undef, ++ $nova_os_password, ++ $nova_os_tenant_name = undef, ++ $nova_os_auth_url = undef, ++ $nova_metadata_agent_start_with_ovs = 'true', ++ $nova_api_endpoint_type = 'publicURL', ++ $nova_region_name = undef, ++ ) { ++ ++ Neutron_config<||> ~> Service['nuage-metadata-agent'] ++ Neutron_nuage_metadata_agent_config<||> ~> Service['nuage-metadata-agent'] ++ ++ neutron_nuage_metadata_agent_config { ++ '/METADATA_PORT': value => $metadata_port; ++ '/NOVA_METADATA_IP': value => $nova_metadata_ip; ++ '/NOVA_METADATA_PORT': value => $nova_metadata_port; ++ '/METADATA_PROXY_SHARED_SECRET': value => $metadata_proxy_shared_secret; ++ '/NOVA_CLIENT_VERSION': value => $nova_client_version; ++ '/NOVA_OS_USERNAME': value => $nova_os_username; ++ '/NOVA_OS_PASSWORD': value => $nova_os_password; ++ '/NOVA_OS_TENANT_NAME': value => $nova_os_tenant_name; ++ '/NOVA_OS_AUTH_URL': value => $nova_os_auth_url; ++ '/NUAGE_METADATA_AGENT_START_WITH_OVS': value=> $nova_metadata_agent_start_with_ovs; ++ '/NOVA_API_ENDPOINT_TYPE': value => $nova_api_endpoint_type; ++ '/NOVA_REGION_NAME': value => $nova_region_name; ++ } ++ ++ service { 'nuage-metadata-agent': ++ ensure => 'running', ++ enable => false, ++ hasstatus => false, ++ hasrestart => true, ++ require => Class['neutron'], ++ } ++} +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index 6e6a8b9..98679f6 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -37,5 +37,8 @@ class neutron::db::sync( + Anchor['neutron::dbsync::begin'] + ], + notify => Anchor['neutron::dbsync::end'], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "test $::controller_sw_versions_match = true", + } + } +diff --git a/manifests/init.pp b/manifests/init.pp +index 92e49b6..6f611ef 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -329,6 +329,23 @@ + # transport://user:pass@host1:port[,hostN:portN]/virtual_host + # Defaults to $::os_service_default. + # ++# ++# WRS PARAMETERS ++# ++# [*host_driver*] ++# (optional) Sets a specific object class to be used as the host ++# management driver ++# ++# [*fm_driver*] ++# (optional) Sets a specific object class to be used as the fault ++# management driver ++# ++# ++# [*vlan_transparent*] ++# (optional) Allow networks to be created with vlan_transparent attribute ++# ++# ++# + # DEPRECATED PARAMETERS + # + # [*rabbit_password*] +@@ -422,6 +439,10 @@ class neutron ( + $notification_driver = $::os_service_default, + $notification_topics = $::os_service_default, + $notification_transport_url = $::os_service_default, ++ # WRS ++ $host_driver = 'neutron.drivers.host.NoopHostDriver', ++ $fm_driver = 'neutron.drivers.fm.NoopFmDriver', ++ $vlan_transparent = false, + # DEPRECATED PARAMETERS + $rabbit_password = $::os_service_default, + $rabbit_host = $::os_service_default, +@@ -485,6 +506,8 @@ instead.") + purge => $purge_config, + } + ++ $ceilometer_driver = "[ messagingv2 ] " ++ + neutron_config { + 'DEFAULT/bind_host': value => $bind_host; + 'DEFAULT/bind_port': value => $bind_port; +@@ -504,6 +527,10 @@ instead.") + 'agent/root_helper': value => $root_helper; + 'agent/root_helper_daemon': value => $root_helper_daemon; + 'agent/report_interval': value => $report_interval; ++ # WRS ++ 'DEFAULT/host_driver': value => $host_driver; ++ 'DEFAULT/fm_driver': value => $fm_driver; ++ 'DEFAULT/vlan_transparent': value => $vlan_transparent; + } + + oslo::messaging::default { 'neutron_config': +diff --git a/manifests/params.pp b/manifests/params.pp +index fdb0645..aeb5c66 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -7,28 +7,29 @@ class neutron::params { + + $client_package = 'python-neutronclient' + $server_service = 'neutron-server' +- $ovs_agent_service = 'neutron-openvswitch-agent' +- $linuxbridge_agent_service = 'neutron-linuxbridge-agent' +- $cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' ++ #$ovs_agent_service = 'neutron-openvswitch-agent' ++ #$linuxbridge_agent_service = 'neutron-linuxbridge-agent' ++ #$cisco_config_file = '/etc/neutron/plugins/cisco/cisco_plugins.ini' + $opencontrail_plugin_package = 'neutron-plugin-contrail' + $opencontrail_config_file = '/etc/neutron/plugins/opencontrail/ContrailPlugin.ini' +- $midonet_server_package = 'python-networking-midonet' +- $midonet_server_package_ext = 'python-networking-midonet-ext' +- $midonet_config_file = '/etc/neutron/plugins/midonet/midonet.ini' ++ #$midonet_server_package = 'python-networking-midonet' ++ #$midonet_server_package_ext = 'python-networking-midonet-ext' ++ #$midonet_config_file = '/etc/neutron/plugins/midonet/midonet.ini' + $ovn_plugin_package = 'python-networking-ovn' + $vpp_plugin_package = 'python-networking-vpp' + $vpp_agent_service = 'neutron-vpp-agent' +- $plumgrid_plugin_package = 'networking-plumgrid' +- $plumgrid_pythonlib_package = 'plumgrid-pythonlib' +- $plumgrid_config_file = '/etc/neutron/plugins/plumgrid/plumgrid.ini' ++ #$plumgrid_plugin_package = 'networking-plumgrid' ++ #$plumgrid_pythonlib_package = 'plumgrid-pythonlib' ++ #$plumgrid_config_file = '/etc/neutron/plugins/plumgrid/plumgrid.ini' + $nuage_config_file = '/etc/neutron/plugins/nuage/plugin.ini' + $dhcp_agent_service = 'neutron-dhcp-agent' + $lbaasv2_agent_service = 'neutron-lbaasv2-agent' + $haproxy_package = 'haproxy' +- $metering_agent_service = 'neutron-metering-agent' ++ #$metering_agent_service = 'neutron-metering-agent' +- $vpnaas_agent_service = 'neutron-vpn-agent' ++ #$vpnaas_agent_service = 'neutron-vpn-agent' +- $l3_agent_service = 'neutron-l3-agent' ++ $l3_agent_service = 'neutron-l3-agent' + $metadata_agent_service = 'neutron-metadata-agent' ++ $metadata_agent_package = undef + $bagpipe_bgp_package = 'openstack-bagpipe-bgp' + $bgpvpn_bagpipe_package = 'python-networking-bagpipe' + $bgpvpn_bagpipe_service = 'bagpipe-bgp' +@@ -36,41 +37,47 @@ class neutron::params { + $l2gw_agent_service = 'neutron-l2gw-agent' + $nsx_plugin_package = 'vmware-nsx' + $nsx_config_file = '/etc/neutron/plugins/vmware/nsx.ini' ++ $vswitch_agent_service = '' ++ $router_scheduler_driver = 'neutron.scheduler.l3_agent_scheduler.HostBasedScheduler' ++ $network_scheduler_driver = 'neutron.scheduler.dhcp_agent_scheduler.HostBasedScheduler' ++ $router_status_managed = true + ++ # CentOS is in the Redhat osfamily + if($::osfamily == 'Redhat') { + $nobody_user_group = 'nobody' + $package_name = 'openstack-neutron' + $server_package = false +- $ml2_server_package = 'openstack-neutron-ml2' +- $ovs_agent_package = false +- $ovs_server_package = 'openstack-neutron-openvswitch' +- $ovs_cleanup_service = 'neutron-ovs-cleanup' +- $libnl_package = 'libnl' +- $package_provider = 'rpm' +- $linuxbridge_agent_package = false +- $linuxbridge_server_package = 'openstack-neutron-linuxbridge' ++ #$ml2_server_package = 'openstack-neutron-ml2' ++ $ml2_server_package = false ++ #$ovs_agent_package = false ++ #$ovs_server_package = 'openstack-neutron-openvswitch' ++ #$ovs_cleanup_service = 'neutron-ovs-cleanup' ++ #$libnl_package = 'libnl' ++ #$package_provider = 'rpm' ++ #$linuxbridge_agent_package = false ++ #$linuxbridge_server_package = 'openstack-neutron-linuxbridge' + $sriov_nic_agent_service = 'neutron-sriov-nic-agent' + $sriov_nic_agent_package = 'openstack-neutron-sriov-nic-agent' + $bigswitch_lldp_package = 'openstack-neutron-bigswitch-lldp' +- $bigswitch_agent_package = 'openstack-neutron-bigswitch-agent' +- $bigswitch_lldp_service = 'neutron-bsn-lldp' +- $bigswitch_agent_service = 'neutron-bsn-agent' +- $cisco_server_package = 'openstack-neutron-cisco' +- $nvp_server_package = 'openstack-neutron-nicira' ++ #$bigswitch_agent_package = 'openstack-neutron-bigswitch-agent' ++ #$bigswitch_lldp_service = 'neutron-bsn-lldp' ++ #$bigswitch_agent_service = 'neutron-bsn-agent' ++ #$cisco_server_package = 'openstack-neutron-cisco' ++ #$nvp_server_package = 'openstack-neutron-nicira' + $dhcp_agent_package = false +- $lbaasv2_agent_package = 'openstack-neutron-lbaas' +- $metering_agent_package = 'openstack-neutron-metering-agent' +- $vpnaas_agent_package = 'openstack-neutron-vpnaas' ++ #$lbaasv2_agent_package = 'openstack-neutron-lbaas' ++ #$metering_agent_package = 'openstack-neutron-metering-agent' ++ #$vpnaas_agent_package = 'openstack-neutron-vpnaas' + $l2gw_agent_package = 'openstack-neutron-l2gw-agent' + $l2gw_package = 'python2-networking-l2gw' +- if $::operatingsystemrelease =~ /^7.*/ or $::operatingsystem == 'Fedora' { +- $openswan_package = 'libreswan' +- } else { +- $openswan_package = 'openswan' +- } +- $libreswan_package = 'libreswan' ++ #if $::operatingsystemrelease =~ /^7.*/ or $::operatingsystem == 'Fedora' { ++ # $openswan_package = 'libreswan' ++ #} else { ++ # $openswan_package = 'openswan' ++ #} ++ #$libreswan_package = 'libreswan' + $l3_agent_package = false +- $fwaas_package = 'openstack-neutron-fwaas' ++ #$fwaas_package = 'openstack-neutron-fwaas' + $neutron_wsgi_script_path = '/var/www/cgi-bin/neutron' + $neutron_wsgi_script_source = '/usr/bin/neutron-api' + } elsif($::osfamily == 'Debian') { +@@ -99,7 +106,7 @@ class neutron::params { + $vpnaas_agent_package = 'neutron-vpn-agent' + $openswan_package = 'openswan' + $libreswan_package = false +- $metadata_agent_package = 'neutron-metadata-agent' ++ $metadata_agent_package = undef + $l3_agent_package = 'neutron-l3-agent' + $fwaas_package = 'python-neutron-fwaas' + $l2gw_agent_package = 'neutron-l2gateway-agent' +diff --git a/manifests/plugins/ml2.pp b/manifests/plugins/ml2.pp +index b943593..92fb5b4 100644 +--- a/manifests/plugins/ml2.pp ++++ b/manifests/plugins/ml2.pp +@@ -152,6 +152,8 @@ class neutron::plugins::ml2 ( + $purge_config = false, + $max_header_size = $::os_service_default, + $overlay_ip_version = $::os_service_default, ++ $ensure_default_security_group = true, ++ $notify_interval = 0, + # DEPRECATED PARAMETERS + $supported_pci_vendor_devs = undef, + ) { +@@ -230,6 +232,9 @@ class neutron::plugins::ml2 ( + 'ml2/overlay_ip_version': value => $overlay_ip_version; + 'securitygroup/enable_security_group': value => $enable_security_group; + 'securitygroup/firewall_driver': value => $firewall_driver; ++ # WRS ++ 'securitygroup/ensure_default_security_group': value => $ensure_default_security_group; ++ 'securitygroup/notify_interval': value => $notify_interval; + } + + if is_service_default($physical_network_mtus) { +diff --git a/manifests/plugins/ml2/type_driver.pp b/manifests/plugins/ml2/type_driver.pp +index b158695..20141f0 100644 +--- a/manifests/plugins/ml2/type_driver.pp ++++ b/manifests/plugins/ml2/type_driver.pp +@@ -112,6 +112,9 @@ define neutron::plugins::ml2::type_driver ( + elsif ($name == 'local') { + warning('local type_driver is useful only for single-box, because it provides no connectivity between hosts') + } ++ elsif ($name == 'managed_flat' or $name == 'managed_vlan' or $name == 'managed_vxlan') { ++ debug('managed_flat, managed_vlan, and managed_vxlan type_driver requires further runtime configuration') ++ } + elsif ($name == 'nexus_vxlan') { + # Nexus_vxlan type driver has its own class separate from this one + } +@@ -130,6 +133,6 @@ define neutron::plugins::ml2::type_driver ( + } + else { + # detect an invalid type_drivers value +- warning('type_driver unknown.') ++ warning('type_driver (${name}) unknown.') + } + } +diff --git a/manifests/server.pp b/manifests/server.pp +index 785c59c..8a1a3f7 100644 +--- a/manifests/server.pp ++++ b/manifests/server.pp +@@ -256,6 +256,8 @@ class neutron::server ( + $service_providers = $::os_service_default, + $auth_strategy = 'keystone', + $enable_proxy_headers_parsing = $::os_service_default, ++ # WRS ++ $router_status_managed = $neutron::params::router_status_managed, + # DEPRECATED PARAMETERS + $log_dir = undef, + $log_file = undef, +@@ -340,6 +342,8 @@ class neutron::server ( + 'DEFAULT/default_availability_zones': value => join(any2array($default_availability_zones), ','); + 'DEFAULT/network_auto_schedule': value => $network_auto_schedule; + 'service_providers/service_provider': value => $service_providers; ++ # WRS ++ 'DEFAULT/router_status_managed': value => $router_status_managed; + } + + if $state_path { +diff --git a/manifests/server/notifications.pp b/manifests/server/notifications.pp +index d398245..f55751d 100644 +--- a/manifests/server/notifications.pp ++++ b/manifests/server/notifications.pp +@@ -50,6 +50,10 @@ + # (optional) The name of the admin nova tenant + # Defaults to 'services' + # ++# [*project_domain_name*] ++# (optional) Nova project's domain name ++# Defaults to 'Default' ++# + # [*project_domain_id*] + # (optional) Nova project's domain ID + # Defaults to 'default' +@@ -62,6 +66,10 @@ + # (optional) Nova project's name + # Defaults to 'services' + # ++# [*user_domain_name*] ++# (optional) User's domain name for connection to nova in admin context ++# Defaults to 'Default' ++# + # [*user_domain_id*] + # (optional) User's domain ID for connection to nova in admin context + # Defaults to 'default' +@@ -105,6 +113,7 @@ class neutron::server::notifications ( + $user_domain_name = 'Default', + $auth_url = 'http://127.0.0.1:35357', + $region_name = $::os_service_default, ++ $endpoint_type = 'public', + # DEPRECATED PARAMETERS + $auth_plugin = $::os_service_default, + ) { +@@ -121,6 +130,7 @@ class neutron::server::notifications ( + 'nova/password': value => $password, secret => true; + 'nova/project_domain_id': value => $project_domain_id; + 'nova/project_domain_name': value => $project_domain_name; ++ 'nova/endpoint_type': value => $endpoint_type; + 'nova/project_name': value => $project_name; + 'nova/user_domain_id': value => $user_domain_id; + 'nova/user_domain_name': value => $user_domain_name; +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0002-Remove-broken-authtoken-references.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0002-Remove-broken-authtoken-references.patch new file mode 100644 index 000000000..71caa7ef4 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0002-Remove-broken-authtoken-references.patch @@ -0,0 +1,41 @@ +From 90d515932132d54d5a3ce7091dcd16f537f24d59 Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 11:31:49 -0500 +Subject: [PATCH 2/8] Remove broken authtoken references + +--- + manifests/logging.pp | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +diff --git a/manifests/logging.pp b/manifests/logging.pp +index acb376d..d06cbd4 100644 +--- a/manifests/logging.pp ++++ b/manifests/logging.pp +@@ -121,19 +121,13 @@ class neutron::logging ( + + include ::neutron::deps + +- $debug_real = pick($::neutron::debug,$debug) +- $use_syslog_real = pick($::neutron::use_syslog,$use_syslog) +- $use_stderr_real = pick($::neutron::use_stderr,$use_stderr) +- $log_file_real = pick($::neutron::log_file,$log_file) +- $log_dir_real = pick($::neutron::log_dir,$log_dir) +- + oslo::log { 'neutron_config': +- debug => $debug_real, +- use_stderr => $use_stderr_real, +- use_syslog => $use_syslog_real, ++ debug => $debug, ++ use_stderr => $use_stderr, ++ use_syslog => $use_syslog, + syslog_log_facility => $syslog_log_facility, +- log_file => $log_file_real, +- log_dir => $log_dir_real, ++ log_file => $log_file, ++ log_dir => $log_dir, + log_config_append => $log_config_append, + log_date_format => $log_date_format, + watch_log_file => $watch_log_file, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0003-control-provider-network-testing-state.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0003-control-provider-network-testing-state.patch new file mode 100644 index 000000000..73ad213c4 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0003-control-provider-network-testing-state.patch @@ -0,0 +1,32 @@ +From 49c76cf9f9025a94b64fff0bb0746c74f536e620 Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 11:31:49 -0500 +Subject: [PATCH 3/8] control provider network testing state + +--- + manifests/init.pp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 6f611ef..6a223df 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -443,6 +443,7 @@ class neutron ( + $host_driver = 'neutron.drivers.host.NoopHostDriver', + $fm_driver = 'neutron.drivers.fm.NoopFmDriver', + $vlan_transparent = false, ++ $pnet_audit_enabled = true, + # DEPRECATED PARAMETERS + $rabbit_password = $::os_service_default, + $rabbit_host = $::os_service_default, +@@ -531,6 +532,7 @@ instead.") + 'DEFAULT/host_driver': value => $host_driver; + 'DEFAULT/fm_driver': value => $fm_driver; + 'DEFAULT/vlan_transparent': value => $vlan_transparent; ++ 'pnet_connectivity/pnet_audit_enabled': value => $pnet_audit_enabled; + } + + oslo::messaging::default { 'neutron_config': +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0004-set-wsgi-pool-size-to-10-from-100.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0004-set-wsgi-pool-size-to-10-from-100.patch new file mode 100644 index 000000000..26df0ae1f --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0004-set-wsgi-pool-size-to-10-from-100.patch @@ -0,0 +1,59 @@ +From bcdf10df2ba5f68bb61ff2b86f0a6cb813271e7d Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 11:31:50 -0500 +Subject: [PATCH 4/8] set wsgi pool size to 10 from 100 + +--- + manifests/init.pp | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 6a223df..78b994b 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -329,6 +329,10 @@ + # transport://user:pass@host1:port[,hostN:portN]/virtual_host + # Defaults to $::os_service_default. + # ++# [*wsgi_default_pool_size*] ++# (optional) Size of the pool of greenthreads used by wsgi (integer value) ++# Defaults to $::os_service_default. ++# + # + # WRS PARAMETERS + # +@@ -439,6 +443,7 @@ class neutron ( + $notification_driver = $::os_service_default, + $notification_topics = $::os_service_default, + $notification_transport_url = $::os_service_default, ++ $wsgi_default_pool_size = 100, + # WRS + $host_driver = 'neutron.drivers.host.NoopHostDriver', + $fm_driver = 'neutron.drivers.fm.NoopFmDriver', +@@ -549,6 +554,13 @@ instead.") + transport_url => $notification_transport_url, + } + ++ oslo::service { 'neutron_config': ++ wsgi_default_pool_size => $wsgi_default_pool_size, ++ cert_file => $cert_file, ++ key_file => $key_file, ++ ca_file => $ca_file, ++ } ++ + if ! is_service_default ($service_plugins) and ($service_plugins) { + if is_array($service_plugins) { + neutron_config { 'DEFAULT/service_plugins': value => join($service_plugins, ',') } +@@ -602,9 +614,6 @@ instead.") + # SSL Options + neutron_config { + 'DEFAULT/use_ssl': value => $use_ssl; +- 'ssl/cert_file': value => $cert_file; +- 'ssl/key_file': value => $key_file; +- 'ssl/ca_file': value => $ca_file; + } + + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0005-Add-support-for-neutron-bgp-dragent.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0005-Add-support-for-neutron-bgp-dragent.patch new file mode 100644 index 000000000..ac6ea98b7 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0005-Add-support-for-neutron-bgp-dragent.patch @@ -0,0 +1,124 @@ +From 4960835d29eeed60106bb78e0c43de9664c9c0b8 Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 16:31:47 -0500 +Subject: [PATCH 5/8] Add support for neutron bgp dragent + +--- + .../neutron_bgp_dragent_config/ini_setting.rb | 22 +++++++++++++ + lib/puppet/type/neutron_bgp_dragent_config.rb | 18 +++++++++++ + manifests/bgp.pp | 36 ++++++++++++++++++++++ + manifests/params.pp | 1 + + 4 files changed, 77 insertions(+) + create mode 100644 lib/puppet/provider/neutron_bgp_dragent_config/ini_setting.rb + create mode 100644 lib/puppet/type/neutron_bgp_dragent_config.rb + create mode 100644 manifests/bgp.pp + +diff --git a/lib/puppet/provider/neutron_bgp_dragent_config/ini_setting.rb b/lib/puppet/provider/neutron_bgp_dragent_config/ini_setting.rb +new file mode 100644 +index 0000000..aa3e6fb +--- /dev/null ++++ b/lib/puppet/provider/neutron_bgp_dragent_config/ini_setting.rb +@@ -0,0 +1,22 @@ ++Puppet::Type.type(:neutron_bgp_dragent_config).provide( ++ :ini_setting, ++ :parent => Puppet::Type.type(:ini_setting).provider(:ruby) ++) do ++ ++ def section ++ resource[:name].split('/', 2).first ++ end ++ ++ def setting ++ resource[:name].split('/', 2).last ++ end ++ ++ def separator ++ '=' ++ end ++ ++ def file_path ++ '/etc/neutron/bgp_dragent.ini' ++ end ++ ++end +diff --git a/lib/puppet/type/neutron_bgp_dragent_config.rb b/lib/puppet/type/neutron_bgp_dragent_config.rb +new file mode 100644 +index 0000000..2db88d2 +--- /dev/null ++++ b/lib/puppet/type/neutron_bgp_dragent_config.rb +@@ -0,0 +1,18 @@ ++Puppet::Type.newtype(:neutron_bgp_dragent_config) do ++ ++ ensurable ++ ++ newparam(:name, :namevar => true) do ++ desc 'Section/setting name to manage from bgp_dragent.ini' ++ newvalues(/\S+\/\S+/) ++ end ++ ++ newproperty(:value) do ++ desc 'The value of the setting to be defined.' ++ munge do |value| ++ value = value.to_s.strip ++ value.capitalize! if value =~ /^(true|false)$/i ++ value ++ end ++ end ++end +diff --git a/manifests/bgp.pp b/manifests/bgp.pp +new file mode 100644 +index 0000000..d61656c +--- /dev/null ++++ b/manifests/bgp.pp +@@ -0,0 +1,36 @@ ++# == Class: neutron::bgp ++# ++# Sets up bgp dynamic-routing agent. ++# ++# === Parameters ++# ++# [*bgp_router_id*] ++# (required) The BGP router_id ++# ++# [*bgp_speaker_driver*] ++# (required) The BGP speaker driver ++# ++class neutron::bgp ( ++ $bgp_router_id, ++ $bgp_speaker_driver, ++ $service_ensure = 'running', ++ $enable = true, ++) { ++ ++ include neutron::params ++ ++ Neutron_config<||> ~> Service['neutron-bgp-dragent'] ++ Neutron_bgp_dragent_config<||> ~> Service['neutron-bgp-dragent'] ++ ++ neutron_bgp_dragent_config { ++ 'bgp/bgp_router_id': value => $neutron_bgp_router_id; ++ 'bgp/bgp_speaker_driver': value => $neutron_bgp_speaker_driver; ++ } ++ ++ service { 'neutron-bgp-dragent': ++ ensure => $service_ensure, ++ name => $::neutron::params::bgp_dragent_service, ++ enable => $enable, ++ require => Class['neutron'], ++ } ++} +diff --git a/manifests/params.pp b/manifests/params.pp +index aeb5c66..d51a23c 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -41,6 +41,7 @@ class neutron::params { + $router_scheduler_driver = 'neutron.scheduler.l3_agent_scheduler.HostBasedScheduler' + $network_scheduler_driver = 'neutron.scheduler.dhcp_agent_scheduler.HostBasedScheduler' + $router_status_managed = true ++ $bgp_dragent_service = 'neutron-bgp-dragent' + + # CentOS is in the Redhat osfamily + if($::osfamily == 'Redhat') { +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0006-Add-parameters-to-classes.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0006-Add-parameters-to-classes.patch new file mode 100644 index 000000000..ac8883c58 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0006-Add-parameters-to-classes.patch @@ -0,0 +1,64 @@ +From c74cce7e2b7aa268f8f9b2238e662879701fe9d4 Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 11:31:50 -0500 +Subject: [PATCH 6/8] Add parameters to classes + +--- + manifests/init.pp | 2 ++ + manifests/server.pp | 13 +++++++++++++ + 2 files changed, 15 insertions(+) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 78b994b..4e76091 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -449,6 +449,7 @@ class neutron ( + $fm_driver = 'neutron.drivers.fm.NoopFmDriver', + $vlan_transparent = false, + $pnet_audit_enabled = true, ++ $log_format = '[%(name)s] %(message)s', + # DEPRECATED PARAMETERS + $rabbit_password = $::os_service_default, + $rabbit_host = $::os_service_default, +@@ -537,6 +538,7 @@ instead.") + 'DEFAULT/host_driver': value => $host_driver; + 'DEFAULT/fm_driver': value => $fm_driver; + 'DEFAULT/vlan_transparent': value => $vlan_transparent; ++ 'DEFAULT/log_format': value => $log_format; + 'pnet_connectivity/pnet_audit_enabled': value => $pnet_audit_enabled; + } + +diff --git a/manifests/server.pp b/manifests/server.pp +index 8a1a3f7..b2cc64c 100644 +--- a/manifests/server.pp ++++ b/manifests/server.pp +@@ -258,6 +258,7 @@ class neutron::server ( + $enable_proxy_headers_parsing = $::os_service_default, + # WRS + $router_status_managed = $neutron::params::router_status_managed, ++ $vhost_user_enabled = true, + # DEPRECATED PARAMETERS + $log_dir = undef, + $log_file = undef, +@@ -378,6 +379,18 @@ class neutron::server ( + } + } + ++ # WRS ++ if (str2bool($::is_virtual)) { ++ $vhost_user_enabled_real = false ++ } else { ++ $vhost_user_enabled_real = $vhost_user_enabled ++ } ++ ++ neutron_config { ++ # Set to false on virtualbox, true otherwise ++ 'vhost/vhost_user_enabled': value => $vhost_user_enabled_real; ++ } ++ + if ($auth_strategy == 'keystone') { + + include ::neutron::keystone::authtoken +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0007-update-neutron-bgp-to-use-class-variables.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0007-update-neutron-bgp-to-use-class-variables.patch new file mode 100644 index 000000000..bbeb5d83f --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0007-update-neutron-bgp-to-use-class-variables.patch @@ -0,0 +1,27 @@ +From 535eddc2aae95719cf40becca35058f7670ebb4e Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 11:31:51 -0500 +Subject: [PATCH 7/8] update neutron bgp to use class variables + +--- + manifests/bgp.pp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/manifests/bgp.pp b/manifests/bgp.pp +index d61656c..07029f3 100644 +--- a/manifests/bgp.pp ++++ b/manifests/bgp.pp +@@ -23,8 +23,8 @@ class neutron::bgp ( + Neutron_bgp_dragent_config<||> ~> Service['neutron-bgp-dragent'] + + neutron_bgp_dragent_config { +- 'bgp/bgp_router_id': value => $neutron_bgp_router_id; +- 'bgp/bgp_speaker_driver': value => $neutron_bgp_speaker_driver; ++ 'bgp/bgp_router_id': value => $bgp_router_id; ++ 'bgp/bgp_speaker_driver': value => $bgp_speaker_driver; + } + + service { 'neutron-bgp-dragent': +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0008-dvr-allow-base-mac-address-to-be-configured.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0008-dvr-allow-base-mac-address-to-be-configured.patch new file mode 100644 index 000000000..5ab1bd579 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0008-dvr-allow-base-mac-address-to-be-configured.patch @@ -0,0 +1,45 @@ +From b72db6b2d737e48129f06ad63e577a4489b66b77 Mon Sep 17 00:00:00 2001 +From: Joseph Richard +Date: Fri, 10 Nov 2017 11:31:51 -0500 +Subject: [PATCH 8/8] dvr allow base mac address to be configured + +--- + manifests/init.pp | 2 ++ + spec/classes/neutron_init_spec.rb | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 4e76091..23ca45f 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -383,6 +383,7 @@ class neutron ( + $service_plugins = $::os_service_default, + $auth_strategy = 'keystone', + $base_mac = $::os_service_default, ++ $dvr_base_mac = $::os_service_default, + $dhcp_lease_duration = $::os_service_default, + $host = $::os_service_default, + $dns_domain = $::os_service_default, +@@ -521,6 +522,7 @@ instead.") + 'DEFAULT/auth_strategy': value => $auth_strategy; + 'DEFAULT/core_plugin': value => $core_plugin; + 'DEFAULT/base_mac': value => $base_mac; ++ 'DEFAULT/dvr_base_mac': value => $dvr_base_mac; + 'DEFAULT/dhcp_lease_duration': value => $dhcp_lease_duration; + 'DEFAULT/host': value => $host; + 'DEFAULT/dns_domain': value => $dns_domain; +diff --git a/spec/classes/neutron_init_spec.rb b/spec/classes/neutron_init_spec.rb +index 3854313..b4a53fa 100644 +--- a/spec/classes/neutron_init_spec.rb ++++ b/spec/classes/neutron_init_spec.rb +@@ -140,6 +140,7 @@ describe 'neutron' do + is_expected.to contain_neutron_config('DEFAULT/auth_strategy').with_value('keystone') + is_expected.to contain_neutron_config('DEFAULT/core_plugin').with_value( params[:core_plugin] ) + is_expected.to contain_neutron_config('DEFAULT/base_mac').with_value('') ++ is_expected.to contain_neutron_config('DEFAULT/dvr_base_mac').with_value('') + is_expected.to contain_neutron_config('DEFAULT/dhcp_lease_duration').with_value('') + is_expected.to contain_neutron_config('DEFAULT/host').with_value('') + is_expected.to contain_neutron_config('DEFAULT/dns_domain').with_value('') +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0009-add-support-for-networking-sfc.patch b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0009-add-support-for-networking-sfc.patch new file mode 100644 index 000000000..a0f7bb752 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/patches/0009-add-support-for-networking-sfc.patch @@ -0,0 +1,64 @@ +From df39f5643e0b8d1c2e689328f134b4f836aae8e3 Mon Sep 17 00:00:00 2001 +From: Steven Webster +Date: Fri, 5 Jan 2018 11:45:19 -0500 +Subject: [PATCH 1/1] Puppet support for SFC + +--- + manifests/sfc.pp | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + create mode 100644 manifests/sfc.pp + +diff --git a/manifests/sfc.pp b/manifests/sfc.pp +new file mode 100644 +index 0000000..3220e0c +--- /dev/null ++++ b/manifests/sfc.pp +@@ -0,0 +1,45 @@ ++# == Class: neutron::sfc ++# ++# Sets up service function chaining. ++# ++# === Parameters ++# ++# [*sfc_drivers*] ++# (required) The SFC driver ++# ++# [*flowclassifier_drivers*] ++# (required) The flowclassifier driver ++# ++# [*quota_flow_classifier*] ++# (optional) The quota for flow classifiers ++# ++# [*quota_port_chain*] ++# (optional) The quota for port chains ++# ++# [*quota_port_pair_group*] ++# (optional) The quota for port pair groups ++# ++# [*quota_port_pair*] ++# (optional) The quota for port pairs ++# ++class neutron::sfc ( ++ $sfc_drivers, ++ $flowclassifier_drivers, ++ $quota_flow_classifier = $::os_service_default, ++ $quota_port_chain = $::os_service_default, ++ $quota_port_pair_group = $::os_service_default, ++ $quota_port_pair = $::os_service_default, ++) { ++ ++ include neutron::params ++ ++ neutron_config { ++ 'sfc/drivers': value => $sfc_drivers; ++ 'flowclassifier/drivers': value => $flowclassifier_drivers; ++ 'quotas/quota_flow_classifier': value => $quota_flow_classifier; ++ 'quotas/quota_port_chain': value => $quota_port_chain; ++ 'quotas/quota_port_pair_group': value => $quota_port_pair_group; ++ 'quotas/quota_port_pair': value => $quota_port_pair; ++ } ++ ++} +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/srpm_path new file mode 100644 index 000000000..cb39e60a3 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-neutron-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-neutron-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/build_srpm.data new file mode 100644 index 000000000..c66bf348c --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=7 diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..2acec3d13 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 2d2bc32008adca8f1dff6a9539003aaea0615542 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 12:15:00 -0400 +Subject: [PATCH 1/4] Update package versioning for TIS format + +--- + SPECS/puppet-nova.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index 5950895..4dd32c5 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-nova + Version: 11.4.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Nova + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0002-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0002-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..41f0c6d3a --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0002-Roll-up-TIS-patches.patch @@ -0,0 +1,34 @@ +From 6f3c7142899b780c1beeb1634c1265d2fef0e88c Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 12:21:53 -0400 +Subject: [PATCH 2/4] Roll up TIS patches + +--- + SPECS/puppet-nova.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index 4dd32c5..e209d03 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -9,6 +9,8 @@ URL: https://launchpad.net/puppet-nova + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + ++Patch0001: 0001-Roll-up-TIS-patches.patch ++ + BuildArch: noarch + + Requires: puppet-cinder +@@ -28,6 +30,8 @@ Puppet module for OpenStack Nova + %prep + %setup -q -n openstack-nova-%{upstream_version} + ++%patch0001 -p1 ++ + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + + find . \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0003-upstreamable-fix-syntax-error-for-until_complete_rea.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0003-upstreamable-fix-syntax-error-for-until_complete_rea.patch new file mode 100644 index 000000000..fd39f1d29 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0003-upstreamable-fix-syntax-error-for-until_complete_rea.patch @@ -0,0 +1,32 @@ +From f648b2a96fb175766cded083516d4cd73e2207b1 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 12:23:09 -0400 +Subject: [PATCH 3/4] upstreamable: fix syntax error for until_complete_real + +--- + SPECS/puppet-nova.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index e209d03..9bd97b0 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -10,6 +10,7 @@ URL: https://launchpad.net/puppet-nova + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch + + BuildArch: noarch + +@@ -31,6 +32,7 @@ Puppet module for OpenStack Nova + %setup -q -n openstack-nova-%{upstream_version} + + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0004-Setup-simple-cell.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0004-Setup-simple-cell.patch new file mode 100644 index 000000000..9cc667259 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0004-Setup-simple-cell.patch @@ -0,0 +1,34 @@ +From 2909066051cfd5f4813d2d431b0bbea44e8022f0 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 12:24:53 -0400 +Subject: [PATCH 4/4] Setup simple cell + +--- + SPECS/puppet-nova.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index 9bd97b0..f20b9a5 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -11,6 +11,8 @@ Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_versio + + Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch ++Patch0003: 0003-Create-nova_cell0-database.patch ++Patch0004: 0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch + + BuildArch: noarch + +@@ -33,6 +35,8 @@ Puppet module for OpenStack Nova + + %patch0001 -p1 + %patch0002 -p1 ++%patch0003 -p1 ++%patch0004 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0005-fix-pci-and-compute-pci.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0005-fix-pci-and-compute-pci.patch new file mode 100644 index 000000000..fad2fccf7 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0005-fix-pci-and-compute-pci.patch @@ -0,0 +1,32 @@ +From e6242033b356aad8a27599184e98033bf2d2cf1d Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 16:45:06 -0400 +Subject: [PATCH] fix pci and compute::pci + +--- + SPECS/puppet-nova.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index f20b9a5..b7d70b5 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -13,6 +13,7 @@ Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch + Patch0003: 0003-Create-nova_cell0-database.patch + Patch0004: 0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch ++Patch0005: 0005-fix-pci-and-compute-pci.patch + + BuildArch: noarch + +@@ -37,6 +38,7 @@ Puppet module for OpenStack Nova + %patch0002 -p1 + %patch0003 -p1 + %patch0004 -p1 ++%patch0005 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0006-Create-Nova-ironic-conf.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0006-Create-Nova-ironic-conf.patch new file mode 100644 index 000000000..059ecfeed --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0006-Create-Nova-ironic-conf.patch @@ -0,0 +1,26 @@ +commit 0aefcfec6930ed8fe4752c6a3ef2047fb7f0a052 +Author: Shoaib Nasir +Date: Wed Dec 6 19:15:34 2017 -0500 + + Create the nova-ironic.conf patch + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index b7d70b5..2271824 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -14,6 +14,7 @@ Patch0002: 0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch + Patch0003: 0003-Create-nova_cell0-database.patch + Patch0004: 0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch + Patch0005: 0005-fix-pci-and-compute-pci.patch ++Patch0006: 0006-Create-Nova-ironic-conf.patch + + BuildArch: noarch + +@@ -39,6 +40,7 @@ Puppet module for OpenStack Nova + %patch0003 -p1 + %patch0004 -p1 + %patch0005 -p1 ++%patch0006 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0007-remove-joshuabaird-ipaclient-requirement.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0007-remove-joshuabaird-ipaclient-requirement.patch new file mode 100644 index 000000000..ac8265b30 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0007-remove-joshuabaird-ipaclient-requirement.patch @@ -0,0 +1,32 @@ +From d770b08b19314844de13b58f7ec6aba876c55cdc Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 10:10:50 -0600 +Subject: [PATCH] remove joshuabaird-ipaclient requirement + +--- + SPECS/puppet-nova.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index 2271824..88577f3 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -15,6 +15,7 @@ Patch0003: 0003-Create-nova_cell0-database.patch + Patch0004: 0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch + Patch0005: 0005-fix-pci-and-compute-pci.patch + Patch0006: 0006-Create-Nova-ironic-conf.patch ++Patch0007: 0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch + + BuildArch: noarch + +@@ -41,6 +42,7 @@ Puppet module for OpenStack Nova + %patch0004 -p1 + %patch0005 -p1 + %patch0006 -p1 ++%patch0007 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0008-Add-pci_weight_multiple-to-scheduler-filter.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0008-Add-pci_weight_multiple-to-scheduler-filter.patch new file mode 100644 index 000000000..85662ecde --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0008-Add-pci_weight_multiple-to-scheduler-filter.patch @@ -0,0 +1,32 @@ +From dde9c5162827712ad9a5cc1855460e40fffdc3e2 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 14 Mar 2018 10:56:25 -0500 +Subject: [PATCH] Add pci_weight_multiple to scheduler filter + +--- + SPECS/puppet-nova.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index 88577f3..fc7ec1f 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -16,6 +16,7 @@ Patch0004: 0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch + Patch0005: 0005-fix-pci-and-compute-pci.patch + Patch0006: 0006-Create-Nova-ironic-conf.patch + Patch0007: 0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch ++Patch0008: 0008-Adding-pci_weight_multiple-to-nova-scheduler-filter.patch + + BuildArch: noarch + +@@ -43,6 +44,7 @@ Puppet module for OpenStack Nova + %patch0005 -p1 + %patch0006 -p1 + %patch0007 -p1 ++%patch0008 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0009-Remove-SerialConsole-from-NovaConf.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0009-Remove-SerialConsole-from-NovaConf.patch new file mode 100644 index 000000000..fe7dadc34 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/0009-Remove-SerialConsole-from-NovaConf.patch @@ -0,0 +1,26 @@ +commit 9ff6f16a0f440832ef6b52162a717f2c303baace +Author: Shoaib Nasir +Date: Thu Mar 15 15:00:46 2018 -0400 + + WRS: 0009-Remove-SerialConsole-from-NovaConf.patch + +diff --git a/SPECS/puppet-nova.spec b/SPECS/puppet-nova.spec +index fc7ec1f..dea8857 100644 +--- a/SPECS/puppet-nova.spec ++++ b/SPECS/puppet-nova.spec +@@ -17,6 +17,7 @@ Patch0005: 0005-fix-pci-and-compute-pci.patch + Patch0006: 0006-Create-Nova-ironic-conf.patch + Patch0007: 0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch + Patch0008: 0008-Adding-pci_weight_multiple-to-nova-scheduler-filter.patch ++Patch0009: 0009-Remove-SerialConsole-from-NovaConf.patch + + BuildArch: noarch + +@@ -45,6 +46,7 @@ Puppet module for OpenStack Nova + %patch0006 -p1 + %patch0007 -p1 + %patch0008 -p1 ++%patch0009 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..ff285a5f6 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,9 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Roll-up-TIS-patches.patch +0003-upstreamable-fix-syntax-error-for-until_complete_rea.patch +0004-Setup-simple-cell.patch +0005-fix-pci-and-compute-pci.patch +0006-Create-Nova-ironic-conf.patch +0007-remove-joshuabaird-ipaclient-requirement.patch +0008-Add-pci_weight_multiple-to-scheduler-filter.patch +0009-Remove-SerialConsole-from-NovaConf.patch diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..56a06c733 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,571 @@ +From 76096fbf09f43b4bc88bc1e4da38a5ddaee0fbc8 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Wed, 25 Oct 2017 13:30:01 -0400 +Subject: [PATCH 1/4] Roll up TIS patches + +--- + .../compute_reserved_config/ini_setting.rb | 22 +++++ + lib/puppet/type/compute_reserved_config.rb | 19 +++++ + manifests/api.pp | 17 ++++ + manifests/compute.pp | 33 ++++++++ + manifests/compute/libvirt.pp | 95 ++++++++++++++++++++++ + manifests/compute/neutron.pp | 15 ++++ + manifests/db.pp | 3 + + manifests/db/sync.pp | 3 + + manifests/db/sync_api.pp | 3 + + manifests/generic_service.pp | 2 + + manifests/init.pp | 6 ++ + manifests/migration/libvirt.pp | 8 +- + manifests/network/neutron.pp | 5 +- + manifests/params.pp | 2 +- + manifests/vncproxy/common.pp | 68 +++++++++++----- + spec/classes/nova_api_spec.rb | 7 ++ + 16 files changed, 282 insertions(+), 26 deletions(-) + create mode 100644 lib/puppet/provider/compute_reserved_config/ini_setting.rb + create mode 100644 lib/puppet/type/compute_reserved_config.rb + +diff --git a/lib/puppet/provider/compute_reserved_config/ini_setting.rb b/lib/puppet/provider/compute_reserved_config/ini_setting.rb +new file mode 100644 +index 0000000..e7d142f +--- /dev/null ++++ b/lib/puppet/provider/compute_reserved_config/ini_setting.rb +@@ -0,0 +1,22 @@ ++Puppet::Type.type(:compute_reserved_config).provide( ++ :ini_setting, ++ :parent => Puppet::Type.type(:ini_setting).provider(:ruby) ++) do ++ ++ def section ++ resource[:name].split('/', 2).first ++ end ++ ++ def setting ++ resource[:name].split('/', 2).last ++ end ++ ++ def separator ++ '=' ++ end ++ ++ def file_path ++ '/etc/nova/compute_reserved.conf' ++ end ++ ++end +diff --git a/lib/puppet/type/compute_reserved_config.rb b/lib/puppet/type/compute_reserved_config.rb +new file mode 100644 +index 0000000..fa9d441 +--- /dev/null ++++ b/lib/puppet/type/compute_reserved_config.rb +@@ -0,0 +1,19 @@ ++Puppet::Type.newtype(:compute_reserved_config) do ++ ++ ensurable ++ ++ newparam(:name, :namevar => true) do ++ desc 'Section/setting name to manage from compute_reserved.conf' ++ newvalues(/\S*\/\S+/) ++ end ++ ++ newproperty(:value) do ++ desc 'The value of the setting to be defined.' ++ munge do |value| ++ value = value.to_s.strip ++ value.capitalize! if value =~ /^(true|false)$/i ++ value ++ end ++ end ++ ++end +diff --git a/manifests/api.pp b/manifests/api.pp +index 9d187ce..1d809c8 100644 +--- a/manifests/api.pp ++++ b/manifests/api.pp +@@ -238,6 +238,13 @@ + # (optional) User name for the vendordata dynamic plugin credentials. + # Defaults to $::os_service_default + # ++# WRS PARAMETERS ++# [*known_pci_devices*] ++# (optional) Known PCI devices that may get special treatment: ++# Defaults to undef ++# Example ++# "[ {'vendor_id':'8086', 'product_id':'0443', 'name':'Coleto Creek PCIe Co-processor'}, {...} ]" ++# + # DEPRECATED + # + # [*conductor_workers*] +@@ -327,6 +334,9 @@ class nova::api( + $vendordata_dynamic_auth_project_name = $::os_service_default, + $vendordata_dynamic_auth_user_domain_name = $::os_service_default, + $vendordata_dynamic_auth_username = $::os_service_default, ++ # WRS PARAMETER ++ $known_pci_devices = undef, ++ $glance_host = undef, + # DEPRECATED PARAMETER + $conductor_workers = undef, + $osapi_max_limit = undef, +@@ -487,6 +497,7 @@ as a standalone service, or httpd for being run by a httpd server") + 'vendordata_dynamic_auth/project_name': value => $vendordata_dynamic_auth_project_name; + 'vendordata_dynamic_auth/user_domain_name': value => $vendordata_dynamic_auth_user_domain_name; + 'vendordata_dynamic_auth/username': value => $vendordata_dynamic_auth_username; ++ 'DEFAULT/glance_host': value => $glance_host; + } + + oslo::middleware {'nova_config': +@@ -513,6 +524,12 @@ as a standalone service, or httpd for being run by a httpd server") + } + } + ++ if $known_pci_devices { ++ nova_config { ++ 'DEFAULT/known_pci_devices': value => check_array_of_hash($known_pci_devices); ++ } ++ } ++ + # Added arg and if statement prevents this from being run + # where db is not active i.e. the compute + if $sync_db { +diff --git a/manifests/compute.pp b/manifests/compute.pp +index 577cae7..e495f29 100644 +--- a/manifests/compute.pp ++++ b/manifests/compute.pp +@@ -142,6 +142,15 @@ + # will disable itself. + # Defaults to $::os_service_default + # ++# WRS PARAMETERS ++# [*shared_pcpu_map*] ++# (optional) A list or range of physical CPU cores to reserve ++# for shared machine processes ++# Defaults to undef ++# ++# [*compute_reserved_vm_memory_2M*] ++# [*compute_reserved_vm_memory_1G*] ++# + # DEPRECATED + # + # [*pci_passthrough*] +@@ -183,6 +192,10 @@ class nova::compute ( + $barbican_api_version = $::os_service_default, + $max_concurrent_live_migrations = $::os_service_default, + $consecutive_build_service_disable_threshold = $::os_service_default, ++ # WRS PARAMETERS ++ $shared_pcpu_map = undef, ++ $compute_reserved_vm_memory_2M = '()', ++ $compute_reserved_vm_memory_1G = '()', + # DEPRECATED PARAMETERS + $pci_passthrough = undef, + ) { +@@ -222,6 +235,26 @@ class nova::compute ( + 'DEFAULT/max_concurrent_live_migrations': value => $max_concurrent_live_migrations; + 'compute/consecutive_build_service_disable_threshold': + value => $consecutive_build_service_disable_threshold; ++ 'DEFAULT/shared_pcpu_map': value => join(any2array($shared_pcpu_map), ','); ++ } ++ ++ ## Only override build default if value is provided at runtime. ++ ## Setting to () has effect of calculating maximum 2M hugepages. ++ if ($compute_reserved_vm_memory_2M and ($compute_reserved_vm_memory_2M != '()')) { ++ compute_reserved_config { ++ '/COMPUTE_VM_MEMORY_2M' : value => $compute_reserved_vm_memory_2M; ++ } ++ } ++ if ($compute_reserved_vm_memory_1G and ($compute_reserved_vm_memory_1G != '()')) { ++ compute_reserved_config { ++ '/COMPUTE_VM_MEMORY_1G' : value => $compute_reserved_vm_memory_1G; ++ } ++ } ++ ++ Compute_reserved_config<||> ~> ++ exec { 'compute-huge reload': ++ path => [ '/usr/bin', '/usr/sbin', '/bin', '/sbin' ], ++ command => '/etc/init.d/compute-huge.sh reload', + } + + ensure_resource('nova_config', 'DEFAULT/allow_resize_to_same_host', { value => $allow_resize_to_same_host }) +diff --git a/manifests/compute/libvirt.pp b/manifests/compute/libvirt.pp +index 408a5f6..0d89c04 100644 +--- a/manifests/compute/libvirt.pp ++++ b/manifests/compute/libvirt.pp +@@ -126,6 +126,31 @@ + # you actually want to deploy. + # Defaults to true for backward compatibility. + # ++# === WRS PARAMETERS === ++# ++# [*live_migration_downtime*] ++# (optional) Maximum downtime in ms for live migration. ++# Defaults to 500 ++# ++# [*live_migration_downtime_steps*] ++# (optional) Number of incremental steps to reach max ++# downtime value. ++# Defaults to 10 ++# ++# [*live_migration_downtime_delay*] ++# (optional) Time to wait in seconds per GB of RAM ++# between each step increase of the migration downtime. ++# Defaults to 75 ++# ++# [*live_migration_completion_timeout*] ++# (optional) Time to wait in seconds for migration to ++# complete. Set to 0 to disable timeouts. ++# ++# [*live_migration_progress_timeout*] ++# (optional) Time to wait in seconds for migration to make ++# forward progress in transferring data before aborting. ++# Defaults to 150 ++# + class nova::compute::libvirt ( + $ensure_package = 'present', + $libvirt_virt_type = 'kvm', +@@ -150,6 +175,13 @@ class nova::compute::libvirt ( + $compute_driver = 'libvirt.LibvirtDriver', + $preallocate_images = $::os_service_default, + $manage_libvirt_services = true, ++ # WRS PARAMETERS ++ $live_migration_flag = undef, ++ $live_migration_downtime = undef, ++ $live_migration_downtime_steps = undef, ++ $live_migration_downtime_delay = undef, ++ $live_migration_completion_timeout = undef, ++ $live_migration_progress_timeout = undef, + ) inherits nova::params { + + include ::nova::deps +@@ -272,4 +304,67 @@ class nova::compute::libvirt ( + 'DEFAULT/remove_unused_original_minimum_age_seconds': ensure => absent; + } + } ++ ++ ++ # WRS ++ if $live_migration_flag != undef { ++ nova_config { ++ 'libvirt/live_migration_flag': value => $live_migration_flag; ++ } ++ } else { ++ nova_config { ++ 'libvirt/live_migration_flag': ensure => absent; ++ } ++ } ++ ++ if $live_migration_downtime != undef { ++ nova_config { ++ 'libvirt/live_migration_downtime': value => $live_migration_downtime; ++ } ++ } else { ++ nova_config { ++ 'libvirt/live_migration_downtime': ensure => absent; ++ } ++ } ++ ++ if $live_migration_downtime_steps != undef { ++ nova_config { ++ 'libvirt/live_migration_downtime_steps': value => $live_migration_downtime_steps; ++ } ++ } else { ++ nova_config { ++ 'libvirt/live_migration_downtime_steps': ensure => absent; ++ } ++ } ++ ++ if $live_migration_downtime_delay != undef { ++ nova_config { ++ 'libvirt/live_migration_downtime_delay': value => $live_migration_downtime_delay; ++ } ++ } else { ++ nova_config { ++ 'libvirt/live_migration_downtime_delay': ensure => absent; ++ } ++ } ++ ++ if $live_migration_completion_timeout != undef { ++ nova_config { ++ 'libvirt/live_migration_completion_timeout': value => $live_migration_completion_timeout; ++ } ++ } else { ++ nova_config { ++ 'libvirt/live_migration_completion_timeout': ensure => absent; ++ } ++ } ++ ++ if $live_migration_progress_timeout != undef { ++ nova_config { ++ 'libvirt/live_migration_progress_timeout': value => $live_migration_progress_timeout; ++ } ++ } else { ++ nova_config { ++ 'libvirt/live_migration_progress_timeout': ensure => absent; ++ } ++ } ++ + } +diff --git a/manifests/compute/neutron.pp b/manifests/compute/neutron.pp +index 43d6eee..7932792 100644 +--- a/manifests/compute/neutron.pp ++++ b/manifests/compute/neutron.pp +@@ -15,9 +15,14 @@ + # Default to 0.0.0.0/0 + # Due to architecture constraints in nova_config, it's not possible to setup + # more than one SNAT rule though initial parameter is MultiStrOpt ++# ++# === WRS PARAMETERS === ++# [*libvirt_qemu_dpdk_options*] ++# + class nova::compute::neutron ( + $libvirt_vif_driver = 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver', + $force_snat_range = '0.0.0.0/0', ++ $libvirt_qemu_dpdk_options = undef, + ) { + include ::nova::deps + +@@ -45,4 +50,14 @@ class nova::compute::neutron ( + } + } + ++ if $libvirt_qemu_dpdk_options != undef { ++ nova_config { ++ 'libvirt/qemu_dpdk_options': value => $libvirt_qemu_dpdk_options; ++ } ++ } else { ++ nova_config { ++ 'libvirt/qemu_dpdk_options': ensure => absent; ++ } ++ } ++ + } +diff --git a/manifests/db.pp b/manifests/db.pp +index 14d2555..109bd81 100644 +--- a/manifests/db.pp ++++ b/manifests/db.pp +@@ -133,7 +133,10 @@ class nova::db ( + '^(sqlite|mysql(\+pymysql)?|postgresql):\/\/(\S+:\S+@\S+\/\S+)?') + + nova_config { ++ 'api_database/max_overflow': value => $database_max_overflow_real; + 'api_database/connection': value => $api_database_connection_real, secret => true; ++ 'api_database/idle_timeout': value => $database_idle_timeout_real; ++ 'api_database/max_pool_size': value => $database_max_pool_size_real; + 'api_database/slave_connection': value => $api_slave_connection_real, secret => true; + } + +diff --git a/manifests/db/sync.pp b/manifests/db/sync.pp +index 668520f..9116370 100644 +--- a/manifests/db/sync.pp ++++ b/manifests/db/sync.pp +@@ -35,5 +35,8 @@ class nova::db::sync( + Anchor['nova::dbsync::begin'] + ], + notify => Anchor['nova::dbsync::end'], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "/usr/bin/test $::controller_sw_versions_match = true", + } + } +diff --git a/manifests/db/sync_api.pp b/manifests/db/sync_api.pp +index 5f09582..aed359b 100644 +--- a/manifests/db/sync_api.pp ++++ b/manifests/db/sync_api.pp +@@ -44,6 +44,9 @@ class nova::db::sync_api( + Anchor['nova::dbsync_api::begin'] + ], + notify => Anchor['nova::dbsync_api::end'], ++ # Only do the db sync if both controllers are running the same software ++ # version. Avoids impacting mate controller during an upgrade. ++ onlyif => "/usr/bin/test $::controller_sw_versions_match = true", + } + + if $cellv2_setup { +diff --git a/manifests/generic_service.pp b/manifests/generic_service.pp +index 0f3e37d..0fa7ee0 100644 +--- a/manifests/generic_service.pp ++++ b/manifests/generic_service.pp +@@ -62,6 +62,8 @@ define nova::generic_service( + } else { + $service_ensure = 'stopped' + } ++ } else { ++ $service_ensure = 'stopped' + } + + service { $nova_title: +diff --git a/manifests/init.pp b/manifests/init.pp +index ca6a217..66e16a8 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -775,4 +775,10 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + 'upgrade_levels/scheduler': value => $upgrade_level_scheduler; + } + ++ # WRS:extension: ++ nova_config { ++ # WRS extension: default flavor extra-spec hw:mem_page_size ++ 'DEFAULT/default_mempages_size': value => '2048'; ++ } ++ + } +diff --git a/manifests/migration/libvirt.pp b/manifests/migration/libvirt.pp +index 2a1d6e0..6ad3390 100644 +--- a/manifests/migration/libvirt.pp ++++ b/manifests/migration/libvirt.pp +@@ -166,10 +166,12 @@ class nova::migration::libvirt( + } + + nova_config { +- 'libvirt/live_migration_uri': value => $live_migration_uri; + 'libvirt/live_migration_tunnelled': value => $live_migration_tunnelled; +- 'libvirt/live_migration_completion_timeout': value => $live_migration_completion_timeout; +- 'libvirt/live_migration_inbound_addr': value => $live_migration_inbound_addr; ++ # WRS: Currently setting these in nova::compute::libvirt ++ # 'libvirt/live_migration_completion_timeout': value => $live_migration_completion_timeout; ++ # WRS: setting these in WRS puppet modules ++ # 'libvirt/live_migration_uri': value => $live_migration_uri; ++ # 'libvirt/live_migration_inbound_addr': value => $live_migration_inbound_addr; + 'libvirt/live_migration_scheme': value => $live_migration_scheme; + } + } +diff --git a/manifests/network/neutron.pp b/manifests/network/neutron.pp +index e5a310a..8a2c28b 100644 +--- a/manifests/network/neutron.pp ++++ b/manifests/network/neutron.pp +@@ -124,7 +124,7 @@ + # + class nova::network::neutron ( + $neutron_password = false, +- $neutron_auth_type = 'v3password', ++ $neutron_auth_type = 'password', + $neutron_project_name = 'services', + $neutron_project_domain_name = 'Default', + $neutron_username = 'neutron', +@@ -148,7 +148,8 @@ class nova::network::neutron ( + include ::nova::deps + + +- $default_floating_pool_real = pick($::nova::api::default_floating_pool, $default_floating_pool) ++ # WRS: remove dependency on nova::api ++ $default_floating_pool_real = $default_floating_pool + + nova_config { + 'DEFAULT/dhcp_domain': value => $dhcp_domain; +diff --git a/manifests/params.pp b/manifests/params.pp +index 4afa1dd..75ae241 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -32,7 +32,7 @@ class nova::params { + $api_service_name = 'openstack-nova-api' + $cells_service_name = 'openstack-nova-cells' + $cert_service_name = 'openstack-nova-cert' +- $compute_service_name = 'openstack-nova-compute' ++ $compute_service_name = 'nova-compute' + $conductor_service_name = 'openstack-nova-conductor' + $consoleauth_service_name = 'openstack-nova-consoleauth' + $libvirt_service_name = 'libvirtd' +diff --git a/manifests/vncproxy/common.pp b/manifests/vncproxy/common.pp +index 72c12c2..7a6a2ff 100644 +--- a/manifests/vncproxy/common.pp ++++ b/manifests/vncproxy/common.pp +@@ -25,26 +25,54 @@ class nova::vncproxy::common ( + + include ::nova::deps + +- $vncproxy_host_real = normalize_ip_for_uri(pick( +- $vncproxy_host, +- $::nova::compute::vncproxy_host, +- $::nova::vncproxy::host, +- false)) +- $vncproxy_protocol_real = pick( +- $vncproxy_protocol, +- $::nova::compute::vncproxy_protocol, +- $::nova::vncproxy::vncproxy_protocol, +- 'http') +- $vncproxy_port_real = pick( +- $vncproxy_port, +- $::nova::compute::vncproxy_port, +- $::nova::vncproxy::port, +- 6080) +- $vncproxy_path_real = pick( +- $vncproxy_path, +- $::nova::compute::vncproxy_path, +- $::nova::vncproxy::vncproxy_path, +- '/vnc_auto.html') ++ if defined(Class['nova::compute']) { ++ $vncproxy_host_real = normalize_ip_for_uri(pick( ++ $vncproxy_host, ++ $::nova::compute::vncproxy_host, ++ false)) ++ $vncproxy_protocol_real = pick( ++ $vncproxy_protocol, ++ $::nova::compute::vncproxy_protocol, ++ 'http') ++ $vncproxy_port_real = pick( ++ $vncproxy_port, ++ $::nova::compute::vncproxy_port, ++ 6080) ++ $vncproxy_path_real = pick( ++ $vncproxy_path, ++ $::nova::compute::vncproxy_path, ++ '/vnc_auto.html') ++ } elsif defined(Class['nova::vncproxy']) { ++ $vncproxy_host_real = normalize_ip_for_uri(pick( ++ $vncproxy_host, ++ $::nova::vncproxy::host, ++ false)) ++ $vncproxy_protocol_real = pick( ++ $vncproxy_protocol, ++ $::nova::vncproxy::vncproxy_protocol, ++ 'http') ++ $vncproxy_port_real = pick( ++ $vncproxy_port, ++ $::nova::vncproxy::port, ++ 6080) ++ $vncproxy_path_real = pick( ++ $vncproxy_path, ++ $::nova::vncproxy::vncproxy_path, ++ '/vnc_auto.html') ++ } else { ++ $vncproxy_host_real = normalize_ip_for_uri(pick( ++ $vncproxy_host, ++ false)) ++ $vncproxy_protocol_real = pick( ++ $vncproxy_protocol, ++ 'http') ++ $vncproxy_port_real = pick( ++ $vncproxy_port, ++ 6080) ++ $vncproxy_path_real = pick( ++ $vncproxy_path, ++ '/vnc_auto.html') ++ } + + if ($vncproxy_host_real) { + $vncproxy_base_url = "${vncproxy_protocol_real}://${vncproxy_host_real}:${vncproxy_port_real}${vncproxy_path_real}" +diff --git a/spec/classes/nova_api_spec.rb b/spec/classes/nova_api_spec.rb +index 55ae065..fb7e782 100644 +--- a/spec/classes/nova_api_spec.rb ++++ b/spec/classes/nova_api_spec.rb +@@ -131,6 +131,7 @@ describe 'nova::api' do + :vendordata_dynamic_auth_project_name => 'project', + :vendordata_dynamic_auth_user_domain_name => 'Default', + :vendordata_dynamic_auth_username => 'user', ++ :known_pci_devices => "[{\"vendor_id\":\"8086\",\"product_id\":\"0443\",\"name\":\"Coleto Creek PCIe Co-processor\"}]", + }) + end + +@@ -224,6 +225,12 @@ describe 'nova::api' do + 'value' => ['{"vendor_id":"8086","product_id":"0126","name":"graphic_card"}','{"vendor_id":"9096","product_id":"1520","name":"network_card"}'] + ) + end ++ ++ it 'configures nova known_pci_devices entries' do ++ is_expected.to contain_nova_config('DEFAULT/known_pci_devices').with( ++ 'value' => "[{\"vendor_id\":\"8086\",\"product_id\":\"0443\",\"name\":\"Coleto Creek PCIe Co-processor\"}]" ++ ) ++ end + end + + context 'when pci_alias is empty' do +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch new file mode 100644 index 000000000..4c9d94582 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0002-upstreamable-fix-syntax-error-for-until_complete_rea.patch @@ -0,0 +1,24 @@ +From 87b414eb890b8314e79cd41e50d30c560da1c413 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 27 Oct 2017 14:44:17 -0400 +Subject: [PATCH 2/4] upstreamable: fix syntax error for until_complete_real + +--- + manifests/cron/archive_deleted_rows.pp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/manifests/cron/archive_deleted_rows.pp b/manifests/cron/archive_deleted_rows.pp +index 8cd3e45..8446339 100644 +--- a/manifests/cron/archive_deleted_rows.pp ++++ b/manifests/cron/archive_deleted_rows.pp +@@ -67,6 +67,7 @@ class nova::cron::archive_deleted_rows ( + + include ::nova::deps + ++ $until_complete_real = '' + if $until_complete { + $until_complete_real = '--until_complete' + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0003-Create-nova_cell0-database.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0003-Create-nova_cell0-database.patch new file mode 100644 index 000000000..66d197b34 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0003-Create-nova_cell0-database.patch @@ -0,0 +1,32 @@ +From ea31aa96f2b67378a3879af60d1a113482515052 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Wed, 1 Nov 2017 18:38:36 -0400 +Subject: [PATCH 3/4] Create nova_cell0 database + +--- + manifests/db/postgresql.pp | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/manifests/db/postgresql.pp b/manifests/db/postgresql.pp +index c037886..2771074 100644 +--- a/manifests/db/postgresql.pp ++++ b/manifests/db/postgresql.pp +@@ -42,6 +42,15 @@ class nova::db::postgresql( + privileges => $privileges, + } + ++ # WRS: always create nova_cell0 database ++ ::openstacklib::db::postgresql { 'nova_cell0': ++ password_hash => postgresql_password($user, $password), ++ dbname => "${dbname}_cell0", ++ user => $user, ++ encoding => $encoding, ++ privileges => $privileges, ++ } ++ + Anchor['nova::db::begin'] + ~> Class['nova::db::postgresql'] + ~> Anchor['nova::db::end'] +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch new file mode 100644 index 000000000..56b1dbe61 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0004-Filter-out-warnings-in-nova-manage-cell_v2-list_cell.patch @@ -0,0 +1,31 @@ +From 973abbfe0acbec1b8219e3869adf494224ecea7a Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 11:34:45 -0400 +Subject: [PATCH 4/4] Filter out warnings in nova-manage cell_v2 list_cells + +--- + lib/puppet/provider/nova_cell_v2/nova_manage.rb | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/puppet/provider/nova_cell_v2/nova_manage.rb b/lib/puppet/provider/nova_cell_v2/nova_manage.rb +index 5616803..305fe47 100644 +--- a/lib/puppet/provider/nova_cell_v2/nova_manage.rb ++++ b/lib/puppet/provider/nova_cell_v2/nova_manage.rb +@@ -16,9 +16,11 @@ Puppet::Type.type(:nova_cell_v2).provide( + end + + def self.instances +- cells_list = nova_manage_request("cell_v2", "list_cells", "--verbose") +- +- cells_list.split("\n")[3..-2].collect do |cell| ++ cells_list = nova_manage_request("cell_v2", "list_cells", "--verbose") ++ # filer out warning messages ++ cells_list = cells_list.split("\n") ++ cells_list = cells_list.select { |x| x.match(/^\+--|^\| /)} ++ cells_list[3..-2].collect do |cell| + $name, $uuid, $transport_url, $database_connection = cell.split('|')[1..-1].map{ |x| x.strip} + default_transport_url = defaults(is_cell0($uuid))[:transport_url] + default_database_connection = defaults(is_cell0($uuid))[:database_connection] +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0005-fix-pci-and-compute-pci.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0005-fix-pci-and-compute-pci.patch new file mode 100644 index 000000000..eeb060eb1 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0005-fix-pci-and-compute-pci.patch @@ -0,0 +1,39 @@ +From 13cacfc8d404bcfd945fcb3217a023c827fd72b5 Mon Sep 17 00:00:00 2001 +From: Jack Ding +Date: Fri, 3 Nov 2017 16:41:48 -0400 +Subject: [PATCH] fix pci and compute::pci + +--- + manifests/compute.pp | 1 - + manifests/pci.pp | 3 ++- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/manifests/compute.pp b/manifests/compute.pp +index e495f29..4c81d2b 100644 +--- a/manifests/compute.pp ++++ b/manifests/compute.pp +@@ -210,7 +210,6 @@ class nova::compute ( + if $pci_passthrough { + warning('The pci_passthrough parameter is deprecated. Please use nova::compute::pci::passthrough instead.') + } +- include ::nova::compute::pci + + # cryptsetup is required when Barbican is encrypting volumes + if $keymgr_api_class =~ /barbican/ { +diff --git a/manifests/pci.pp b/manifests/pci.pp +index 23b08f8..a41dc01 100644 +--- a/manifests/pci.pp ++++ b/manifests/pci.pp +@@ -16,7 +16,8 @@ class nova::pci( + ) { + include ::nova::deps + +- $picked_aliases = pick_default($::nova::api::pci_alias, $aliases) ++ # WRS: remove dependency on ::nova::api ++ $picked_aliases = $aliases + + if $picked_aliases and + !is_service_default($picked_aliases) and +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0006-Create-Nova-ironic-conf.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0006-Create-Nova-ironic-conf.patch new file mode 100644 index 000000000..61cccbdc0 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0006-Create-Nova-ironic-conf.patch @@ -0,0 +1,1025 @@ +commit 9355e784a0e7ac3ba25eaa6c95a493ebcb12486f +Author: Shoaib Nasir +Date: Fri Dec 8 15:21:58 2017 -0500 + + WRS: 0006-Create-Nova-ironic-conf.patch + +diff --git a/lib/puppet/provider/nova_ironic_config/openstackconfig.rb b/lib/puppet/provider/nova_ironic_config/openstackconfig.rb +new file mode 100644 +index 0000000..d600c13 +--- /dev/null ++++ b/lib/puppet/provider/nova_ironic_config/openstackconfig.rb +@@ -0,0 +1,10 @@ ++Puppet::Type.type(:nova_ironic_config).provide( ++ :openstackconfig, ++ :parent => Puppet::Type.type(:openstack_config).provider(:ruby) ++) do ++ ++ def self.file_path ++ '/etc/nova/nova-ironic.conf' ++ end ++ ++end +diff --git a/lib/puppet/type/nova_ironic_config.rb b/lib/puppet/type/nova_ironic_config.rb +new file mode 100644 +index 0000000..07ffbc1 +--- /dev/null ++++ b/lib/puppet/type/nova_ironic_config.rb +@@ -0,0 +1,61 @@ ++Puppet::Type.newtype(:nova_ironic_config) do ++ ++ ensurable ++ ++ newparam(:name, :namevar => true) do ++ desc 'Section/setting name to manage from nova.conf' ++ newvalues(/\S+\/\S+/) ++ end ++ ++ newproperty(:value, :array_matching => :all) do ++ desc 'The value of the setting to be defined.' ++ def insync?(is) ++ return true if @should.empty? ++ return false unless is.is_a? Array ++ return false unless is.length == @should.length ++ return ( ++ is & @should == is or ++ is & @should.map(&:to_s) == is ++ ) ++ end ++ munge do |value| ++ value = value.to_s.strip ++ value.capitalize! if value =~ /^(true|false)$/i ++ value ++ end ++ ++ def is_to_s( currentvalue ) ++ if resource.secret? ++ return '[old secret redacted]' ++ else ++ return currentvalue ++ end ++ end ++ ++ def should_to_s( newvalue ) ++ if resource.secret? ++ return '[new secret redacted]' ++ else ++ return newvalue ++ end ++ end ++ end ++ ++ newparam(:secret, :boolean => true) do ++ desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' ++ ++ newvalues(:true, :false) ++ ++ defaultto false ++ end ++ ++ newparam(:ensure_absent_val) do ++ desc 'A value that is specified as the value property will behave as if ensure => absent was specified' ++ defaultto('') ++ end ++ ++ autorequire(:package) do ++ 'nova-common' ++ end ++ ++end +diff --git a/manifests/cache.pp b/manifests/cache.pp +index 9befa4f..a55b0de 100644 +--- a/manifests/cache.pp ++++ b/manifests/cache.pp +@@ -114,4 +114,20 @@ class nova::cache ( + memcache_pool_unused_timeout => $memcache_pool_unused_timeout, + memcache_pool_connection_get_timeout => $memcache_pool_connection_get_timeout, + } ++ ++ oslo::cache { 'nova_ironic_config': ++ config_prefix => $config_prefix, ++ expiration_time => $expiration_time, ++ backend => $backend, ++ backend_argument => $backend_argument, ++ proxies => $proxies, ++ enabled => $enabled, ++ debug_cache_backend => $debug_cache_backend, ++ memcache_servers => $memcache_servers, ++ memcache_dead_retry => $memcache_dead_retry, ++ memcache_socket_timeout => $memcache_socket_timeout, ++ memcache_pool_maxsize => $memcache_pool_maxsize, ++ memcache_pool_unused_timeout => $memcache_pool_unused_timeout, ++ memcache_pool_connection_get_timeout => $memcache_pool_connection_get_timeout, ++ } + } +diff --git a/manifests/cells.pp b/manifests/cells.pp +index 5649633..857388e 100644 +--- a/manifests/cells.pp ++++ b/manifests/cells.pp +@@ -169,9 +169,12 @@ class nova::cells ( + 'parent': { + nova_config { 'DEFAULT/compute_api_class': value => 'nova.compute.cells_api.ComputeCellsAPI' } + nova_config { 'cells/cell_type': value => 'api' } ++ nova_ironic_config { 'DEFAULT/compute_api_class': value => 'nova.compute.cells_api.ComputeCellsAPI' } ++ nova_ironic_config { 'cells/cell_type': value => 'api' } + } + 'child': { + nova_config { 'cells/cell_type': value => 'compute' } ++ nova_ironic_config { 'cells/cell_type': value => 'compute' } + } + default: { fail("Unsupported cell_type parameter value: '${cell_type}'. Should be 'parent' or 'child'.") } + } +@@ -198,6 +201,22 @@ class nova::cells ( + 'cells/scheduler': value => $scheduler; + 'cells/scheduler_weight_classes': value => $scheduler_weight_classes; + } ++ nova_ironic_config { ++ 'cells/bandwidth_update_interval': value => $bandwidth_update_interval; ++ 'cells/call_timeout': value => $call_timeout; ++ 'cells/capabilities': value => join($capabilities, ','); ++ 'cells/db_check_interval': value => $db_check_interval; ++ 'cells/enable': value => $enabled; ++ 'cells/instance_updated_at_threshold': value => $instance_updated_at_threshold; ++ 'cells/instance_update_num_instances': value => $instance_update_num_instances; ++ 'cells/max_hop_count': value => $max_hop_count; ++ 'cells/mute_child_interval': value => $mute_child_interval; ++ 'cells/mute_weight_multiplier': value => $mute_weight_multiplier; ++ 'cells/mute_weight_value': value => $mute_weight_value; ++ 'cells/name': value => $cell_name; ++ 'cells/reserve_percent': value => $reserve_percent; ++ 'cells/rpc_driver_queue_base': value => $rpc_driver_queue_base; ++ } + + nova::generic_service { 'cells': + enabled => $enabled, +diff --git a/manifests/compute.pp b/manifests/compute.pp +index 4c81d2b..36d2e7a 100644 +--- a/manifests/compute.pp ++++ b/manifests/compute.pp +@@ -237,6 +237,22 @@ class nova::compute ( + 'DEFAULT/shared_pcpu_map': value => join(any2array($shared_pcpu_map), ','); + } + ++ nova_ironic_config { ++ 'DEFAULT/reserved_host_memory_mb': value => '0'; ++ 'DEFAULT/heal_instance_info_cache_interval': value => $heal_instance_info_cache_interval; ++ 'DEFAULT/resize_confirm_window': value => $resize_confirm_window; ++ 'DEFAULT/vcpu_pin_set': value => $vcpu_pin_set_real; ++ 'DEFAULT/resume_guests_state_on_host_boot': value => $resume_guests_state_on_host_boot; ++ 'key_manager/api_class': value => $keymgr_api_class; ++ 'barbican/auth_endpoint': value => $barbican_auth_endpoint; ++ 'barbican/barbican_endpoint': value => $barbican_endpoint; ++ 'barbican/barbican_api_version': value => $barbican_api_version; ++ 'DEFAULT/max_concurrent_live_migrations': value => $max_concurrent_live_migrations; ++ 'compute/consecutive_build_service_disable_threshold': ++ value => $consecutive_build_service_disable_threshold; ++ 'DEFAULT/shared_pcpu_map': value => join(any2array($shared_pcpu_map), ','); ++ } ++ + ## Only override build default if value is provided at runtime. + ## Setting to () has effect of calculating maximum 2M hugepages. + if ($compute_reserved_vm_memory_2M and ($compute_reserved_vm_memory_2M != '()')) { +@@ -266,15 +282,27 @@ class nova::compute ( + $vncserver_proxyclient_address; + 'vnc/keymap': value => $vnc_keymap; + } ++ nova_ironic_config { ++ 'vnc/vncserver_proxyclient_address': value => ++ $vncserver_proxyclient_address; ++ 'vnc/keymap': value => $vnc_keymap; ++ } + } else { + nova_config { + 'vnc/vncserver_proxyclient_address': ensure => absent; + 'vnc/keymap': ensure => absent; + } ++ nova_ironic_config { ++ 'vnc/vncserver_proxyclient_address': ensure => absent; ++ 'vnc/keymap': ensure => absent; ++ } + } + nova_config { + 'vnc/enabled': value => $vnc_enabled; + } ++ nova_ironic_config { ++ 'vnc/enabled': value => $vnc_enabled; ++ } + + if $neutron_enabled != true and $install_bridge_utils { + # Install bridge-utils if we use nova-network +@@ -295,13 +323,16 @@ class nova::compute ( + + if $force_config_drive { + nova_config { 'DEFAULT/force_config_drive': value => true } ++ nova_ironic_config { 'DEFAULT/force_config_drive': value => true } + } else { + nova_config { 'DEFAULT/force_config_drive': ensure => absent } ++ nova_ironic_config { 'DEFAULT/force_config_drive': ensure => absent } + } + + if $virtio_nic { + # Enable the virtio network card for instances + nova_config { 'DEFAULT/libvirt_use_virtio_for_bridges': value => true } ++ nova_ironic_config { 'DEFAULT/libvirt_use_virtio_for_bridges': value => true } + } + + if $instance_usage_audit and $instance_usage_audit_period in ['hour', 'day', 'month', 'year'] { +@@ -309,16 +340,27 @@ class nova::compute ( + 'DEFAULT/instance_usage_audit': value => $instance_usage_audit; + 'DEFAULT/instance_usage_audit_period': value => $instance_usage_audit_period; + } ++ nova_ironic_config { ++ 'DEFAULT/instance_usage_audit': value => $instance_usage_audit; ++ 'DEFAULT/instance_usage_audit_period': value => $instance_usage_audit_period; ++ } + } else { + nova_config { + 'DEFAULT/instance_usage_audit': ensure => absent; + 'DEFAULT/instance_usage_audit_period': ensure => absent; + } ++ nova_ironic_config { ++ 'DEFAULT/instance_usage_audit': ensure => absent; ++ 'DEFAULT/instance_usage_audit_period': ensure => absent; ++ } + } + + nova_config { + 'DEFAULT/force_raw_images': value => $force_raw_images; + } ++ nova_ironic_config { ++ 'DEFAULT/force_raw_images': value => $force_raw_images; ++ } + + if is_service_default($config_drive_format) or $config_drive_format == 'iso9660' { + ensure_packages($::nova::params::genisoimage_package_name, { +@@ -329,5 +371,8 @@ class nova::compute ( + nova_config { + 'DEFAULT/config_drive_format': value => $config_drive_format; + } ++ nova_ironic_config { ++ 'DEFAULT/config_drive_format': value => $config_drive_format; ++ } + + } +diff --git a/manifests/compute/ironic.pp b/manifests/compute/ironic.pp +index 747436e..8f856d5 100644 +--- a/manifests/compute/ironic.pp ++++ b/manifests/compute/ironic.pp +@@ -25,4 +25,10 @@ class nova::compute::ironic ( + 'DEFAULT/compute_driver': value => $compute_driver; + 'DEFAULT/max_concurrent_builds': value => $max_concurrent_builds; + } ++ ++ nova_ironic_config { ++ 'DEFAULT/compute_driver': value => $compute_driver; ++ 'DEFAULT/max_concurrent_builds': value => $max_concurrent_builds; ++ 'DEFAULT/reserved_host_memory_mb': value => '0'; ++ } + } +diff --git a/manifests/compute/neutron.pp b/manifests/compute/neutron.pp +index 7932792..c135dbc 100644 +--- a/manifests/compute/neutron.pp ++++ b/manifests/compute/neutron.pp +@@ -33,6 +33,9 @@ class nova::compute::neutron ( + nova_config { + 'libvirt/vif_driver': value => $libvirt_vif_driver; + } ++ nova_ironic_config { ++ 'libvirt/vif_driver': value => $libvirt_vif_driver; ++ } + + if $libvirt_vif_driver == 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver' and $force_snat_range { + # Validate ip and mask for force_snat_range +@@ -41,6 +44,9 @@ class nova::compute::neutron ( + nova_config { + 'DEFAULT/force_snat_range': value => $force_snat_range; + } ++ nova_ironic_config { ++ 'DEFAULT/force_snat_range': value => $force_snat_range; ++ } + } else { + fail('force_snat_range should be IPv4 or IPv6 CIDR notation') + } +@@ -48,16 +54,25 @@ class nova::compute::neutron ( + nova_config { + 'DEFAULT/force_snat_range': ensure => absent; + } ++ nova_ironic_config { ++ 'DEFAULT/force_snat_range': ensure => absent; ++ } + } + + if $libvirt_qemu_dpdk_options != undef { + nova_config { + 'libvirt/qemu_dpdk_options': value => $libvirt_qemu_dpdk_options; + } ++ nova_ironic_config { ++ 'libvirt/qemu_dpdk_options': value => $libvirt_qemu_dpdk_options; ++ } + } else { + nova_config { + 'libvirt/qemu_dpdk_options': ensure => absent; + } ++ nova_ironic_config { ++ 'libvirt/qemu_dpdk_options': ensure => absent; ++ } + } + + } +diff --git a/manifests/compute/pci.pp b/manifests/compute/pci.pp +index c0c62d4..30b4dba 100644 +--- a/manifests/compute/pci.pp ++++ b/manifests/compute/pci.pp +@@ -28,4 +28,8 @@ class nova::compute::pci( + nova_config { + 'pci/passthrough_whitelist': value => $passthrough_real; + } +-} +\ No newline at end of file ++ ++ nova_ironic_config { ++ 'pci/passthrough_whitelist': value => $passthrough_real; ++ } ++} +diff --git a/manifests/compute/rbd.pp b/manifests/compute/rbd.pp +index 6ad9907..6743cb6 100644 +--- a/manifests/compute/rbd.pp ++++ b/manifests/compute/rbd.pp +@@ -89,12 +89,19 @@ class nova::compute::rbd ( + nova_config { + 'libvirt/rbd_user': value => $libvirt_rbd_user; + } ++ nova_ironic_config { ++ 'libvirt/rbd_user': value => $libvirt_rbd_user; ++ } + + if $libvirt_rbd_secret_uuid { + nova_config { + 'libvirt/rbd_secret_uuid': value => $libvirt_rbd_secret_uuid; + } + ++ nova_ironic_config { ++ 'libvirt/rbd_secret_uuid': value => $libvirt_rbd_secret_uuid; ++ } ++ + file { '/etc/nova/secret.xml': + content => template('nova/secret.xml-compute.erb'), + require => Anchor['nova::config::begin'], +@@ -131,11 +138,20 @@ class nova::compute::rbd ( + 'libvirt/images_rbd_pool': value => $libvirt_images_rbd_pool; + 'libvirt/images_rbd_ceph_conf': value => $libvirt_images_rbd_ceph_conf; + } ++ nova_ironic_config { ++ 'libvirt/images_type': value => 'rbd'; ++ 'libvirt/images_rbd_pool': value => $libvirt_images_rbd_pool; ++ 'libvirt/images_rbd_ceph_conf': value => $libvirt_images_rbd_ceph_conf; ++ } + } else { + nova_config { + 'libvirt/images_rbd_pool': ensure => absent; + 'libvirt/images_rbd_ceph_conf': ensure => absent; + } ++ nova_ironic_config { ++ 'libvirt/images_rbd_pool': ensure => absent; ++ 'libvirt/images_rbd_ceph_conf': ensure => absent; ++ } + } + + } +diff --git a/manifests/compute/serial.pp b/manifests/compute/serial.pp +index 422c0af..83d1526 100644 +--- a/manifests/compute/serial.pp ++++ b/manifests/compute/serial.pp +@@ -31,4 +31,11 @@ class nova::compute::serial( + 'serial_console/base_url': value => $base_url; + 'serial_console/proxyclient_address': value => $proxyclient_address; + } ++ ++ nova_ironic_config { ++ 'serial_console/enabled': value => true; ++ 'serial_console/port_range': value => $port_range; ++ 'serial_console/base_url': value => $base_url; ++ 'serial_console/proxyclient_address': value => $proxyclient_address; ++ } + } +diff --git a/manifests/compute/spice.pp b/manifests/compute/spice.pp +index cdfc739..06746b3 100644 +--- a/manifests/compute/spice.pp ++++ b/manifests/compute/spice.pp +@@ -55,6 +55,9 @@ class nova::compute::spice( + nova_config { + 'spice/html5proxy_base_url': value => $html5proxy_base_url; + } ++ nova_ironic_config { ++ 'spice/html5proxy_base_url': value => $html5proxy_base_url; ++ } + } + + nova_config { +@@ -64,4 +67,12 @@ class nova::compute::spice( + 'spice/server_proxyclient_address': value => $server_proxyclient_address; + 'spice/keymap': value => $keymap; + } ++ ++ nova_ironic_config { ++ 'spice/enabled': value => true; ++ 'spice/agent_enabled': value => $agent_enabled; ++ 'spice/server_listen': value => $server_listen; ++ 'spice/server_proxyclient_address': value => $server_proxyclient_address; ++ 'spice/keymap': value => $keymap; ++ } + } +diff --git a/manifests/compute/vmware.pp b/manifests/compute/vmware.pp +index 53586d2..31289e9 100644 +--- a/manifests/compute/vmware.pp ++++ b/manifests/compute/vmware.pp +@@ -102,6 +102,21 @@ class nova::compute::vmware( + 'vmware/datastore_regex': value => $datastore_regex; + } + ++ nova_ironic_config { ++ 'DEFAULT/compute_driver': value => $compute_driver; ++ 'vmware/host_ip': value => $host_ip; ++ 'vmware/host_username': value => $host_username; ++ 'vmware/host_password': value => $host_password; ++ 'vmware/cluster_name': value => $cluster_name; ++ 'vmware/api_retry_count': value => $api_retry_count; ++ 'vmware/maximum_objects': value => $maximum_objects; ++ 'vmware/task_poll_interval': value => $task_poll_interval; ++ 'vmware/use_linked_clone': value => $use_linked_clone; ++ 'vmware/insecure': value => $insecure; ++ 'vmware/ca_file': value => $ca_file; ++ 'vmware/datastore_regex': value => $datastore_regex; ++ } ++ + package { 'python-suds': + ensure => present, + tag => ['openstack', 'nova-support-package'], +diff --git a/manifests/config.pp b/manifests/config.pp +index d138b33..806b474 100644 +--- a/manifests/config.pp ++++ b/manifests/config.pp +@@ -30,13 +30,16 @@ + class nova::config ( + $nova_config = {}, + $nova_paste_api_ini = {}, ++ $nova_ironic_config = {}, + ) { + + include ::nova::deps + + validate_hash($nova_config) ++ validate_hash($nova_ironic_config) + validate_hash($nova_paste_api_ini) + + create_resources('nova_config', $nova_config) ++ create_resources('nova_ironic_config', $nova_ironic_config) + create_resources('nova_paste_api_ini', $nova_paste_api_ini) + } +diff --git a/manifests/init.pp b/manifests/init.pp +index 66e16a8..0154fe1 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -642,10 +642,14 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + resources { 'nova_config': + purge => $purge_config, + } ++ resources { 'nova_ironic_config': ++ purge => $purge_config, ++ } + + if $image_service == 'nova.image.glance.GlanceImageService' { + if $glance_api_servers { + nova_config { 'glance/api_servers': value => $glance_api_servers } ++ nova_ironic_config { 'glance/api_servers': value => $glance_api_servers } + } + } + +@@ -658,6 +662,15 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + 'DEFAULT/disk_allocation_ratio': value => $disk_allocation_ratio; + } + ++ nova_ironic_config { ++ 'api/auth_strategy': value => $auth_strategy; ++ 'DEFAULT/image_service': value => $image_service; ++ 'DEFAULT/host': value => 'controller'; ++ 'DEFAULT/cpu_allocation_ratio': value => $cpu_allocation_ratio; ++ 'DEFAULT/ram_allocation_ratio': value => $ram_allocation_ratio; ++ 'DEFAULT/disk_allocation_ratio': value => $disk_allocation_ratio; ++ } ++ + oslo::messaging::rabbit {'nova_config': + rabbit_password => $rabbit_password, + rabbit_userid => $rabbit_userid, +@@ -678,6 +691,26 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + rabbit_ha_queues => $rabbit_ha_queues, + } + ++ oslo::messaging::rabbit {'nova_ironic_config': ++ rabbit_password => $rabbit_password, ++ rabbit_userid => $rabbit_userid, ++ rabbit_virtual_host => $rabbit_virtual_host, ++ rabbit_use_ssl => $rabbit_use_ssl, ++ heartbeat_timeout_threshold => $rabbit_heartbeat_timeout_threshold, ++ heartbeat_rate => $rabbit_heartbeat_rate, ++ kombu_reconnect_delay => $kombu_reconnect_delay, ++ amqp_durable_queues => $amqp_durable_queues, ++ kombu_compression => $kombu_compression, ++ kombu_ssl_ca_certs => $kombu_ssl_ca_certs, ++ kombu_ssl_certfile => $kombu_ssl_certfile, ++ kombu_ssl_keyfile => $kombu_ssl_keyfile, ++ kombu_ssl_version => $kombu_ssl_version, ++ rabbit_hosts => $rabbit_hosts, ++ rabbit_host => $rabbit_host, ++ rabbit_port => $rabbit_port, ++ rabbit_ha_queues => $rabbit_ha_queues, ++ } ++ + oslo::messaging::amqp { 'nova_config': + server_request_prefix => $amqp_server_request_prefix, + broadcast_prefix => $amqp_broadcast_prefix, +@@ -697,6 +730,25 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + password => $amqp_password, + } + ++ oslo::messaging::amqp { 'nova_ironic_config': ++ server_request_prefix => $amqp_server_request_prefix, ++ broadcast_prefix => $amqp_broadcast_prefix, ++ group_request_prefix => $amqp_group_request_prefix, ++ container_name => $amqp_container_name, ++ idle_timeout => $amqp_idle_timeout, ++ trace => $amqp_trace, ++ ssl_ca_file => $amqp_ssl_ca_file, ++ ssl_cert_file => $amqp_ssl_cert_file, ++ ssl_key_file => $amqp_ssl_key_file, ++ ssl_key_password => $amqp_ssl_key_password, ++ allow_insecure_clients => $amqp_allow_insecure_clients, ++ sasl_mechanisms => $amqp_sasl_mechanisms, ++ sasl_config_dir => $amqp_sasl_config_dir, ++ sasl_config_name => $amqp_sasl_config_name, ++ username => $amqp_username, ++ password => $amqp_password, ++ } ++ + # SSL Options + if $use_ssl { + nova_config { +@@ -706,6 +758,14 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + 'wsgi/ssl_cert_file' : value => $cert_file; + 'wsgi/ssl_key_file' : value => $key_file; + } ++ nova_ironic_config { ++ 'DEFAULT/enabled_ssl_apis' : value => join($enabled_ssl_apis, ','); ++ 'ssl/cert_file' : value => $cert_file; ++ 'ssl/key_file' : value => $key_file; ++ 'wsgi/ssl_cert_file' : value => $cert_file; ++ 'wsgi/ssl_key_file' : value => $key_file; ++ } ++ + if $ca_file { + nova_config { 'ssl/ca_file' : + value => $ca_file, +@@ -713,10 +773,20 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + nova_config { 'wsgi/ssl_ca_file' : + value => $ca_file, + } ++ ++ nova_ironic_config { 'ssl/ca_file' : ++ value => $ca_file, ++ } ++ nova_ironic_config { 'wsgi/ssl_ca_file' : ++ value => $ca_file, ++ } + } else { + nova_config { 'ssl/ca_file' : + ensure => absent, + } ++ nova_ironic_config { 'ssl/ca_file' : ++ ensure => absent, ++ } + } + } else { + nova_config { +@@ -725,6 +795,12 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + 'ssl/key_file' : ensure => absent; + 'ssl/ca_file' : ensure => absent; + } ++ nova_ironic_config { ++ 'DEFAULT/enabled_ssl_apis' : ensure => absent; ++ 'ssl/cert_file' : ensure => absent; ++ 'ssl/key_file' : ensure => absent; ++ 'ssl/ca_file' : ensure => absent; ++ } + } + + oslo::messaging::default { 'nova_config': +@@ -732,12 +808,22 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + rpc_response_timeout => $rpc_response_timeout, + control_exchange => $control_exchange, + } ++ oslo::messaging::default { 'nova_ironic_config': ++ transport_url => $default_transport_url, ++ rpc_response_timeout => $rpc_response_timeout, ++ control_exchange => $control_exchange, ++ } + + oslo::messaging::notifications { 'nova_config': + transport_url => $notification_transport_url, + driver => $notification_driver, + topics => $notification_topics, + } ++ oslo::messaging::notifications { 'nova_ironic_config': ++ transport_url => $notification_transport_url, ++ driver => $notification_driver, ++ topics => $notification_topics, ++ } + + nova_config { + 'cinder/catalog_info': value => $cinder_catalog_info; +@@ -751,15 +837,32 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + 'DEFAULT/block_device_allocate_retries': value => $block_device_allocate_retries; + 'DEFAULT/block_device_allocate_retries_interval': value => $block_device_allocate_retries_interval; + } ++ nova_ironic_config { ++ 'cinder/catalog_info': value => $cinder_catalog_info; ++ 'os_vif_linux_bridge/use_ipv6': value => $use_ipv6; ++ 'notifications/notify_api_faults': value => $notify_api_faults; ++ # Following may need to be broken out to different nova services ++ 'DEFAULT/state_path': value => $state_path; ++ 'DEFAULT/service_down_time': value => $service_down_time; ++ 'DEFAULT/rootwrap_config': value => $rootwrap_config; ++ 'DEFAULT/report_interval': value => $report_interval; ++ 'DEFAULT/block_device_allocate_retries': value => $block_device_allocate_retries; ++ 'DEFAULT/block_device_allocate_retries_interval': value => $block_device_allocate_retries_interval; ++ } + + oslo::concurrency { 'nova_config': lock_path => $lock_path } ++ oslo::concurrency { 'nova_ironic_config': lock_path => $lock_path } + + if $notify_on_state_change and $notify_on_state_change in ['vm_state', 'vm_and_task_state'] { + nova_config { + 'notifications/notify_on_state_change': value => $notify_on_state_change; + } ++ nova_ironic_config { ++ 'notifications/notify_on_state_change': value => $notify_on_state_change; ++ } + } else { + nova_config { 'notifications/notify_on_state_change': ensure => absent; } ++ nova_ironic_config { 'notifications/notify_on_state_change': ensure => absent; } + } + + nova_config { +@@ -774,11 +877,27 @@ but should be one of: ssh-rsa, ssh-dsa, ssh-ecdsa.") + 'upgrade_levels/network': value => $upgrade_level_network; + 'upgrade_levels/scheduler': value => $upgrade_level_scheduler; + } ++ nova_ironic_config { ++ 'cinder/os_region_name': value => $os_region_name; ++ 'upgrade_levels/cells': value => $upgrade_level_cells; ++ 'upgrade_levels/cert': value => $upgrade_level_cert; ++ 'upgrade_levels/compute': value => $upgrade_level_compute; ++ 'upgrade_levels/conductor': value => $upgrade_level_conductor; ++ 'upgrade_levels/console': value => $upgrade_level_console; ++ 'upgrade_levels/consoleauth': value => $upgrade_level_consoleauth; ++ 'upgrade_levels/intercell': value => $upgrade_level_intercell; ++ 'upgrade_levels/network': value => $upgrade_level_network; ++ 'upgrade_levels/scheduler': value => $upgrade_level_scheduler; ++ } + + # WRS:extension: + nova_config { + # WRS extension: default flavor extra-spec hw:mem_page_size + 'DEFAULT/default_mempages_size': value => '2048'; + } ++ nova_ironic_config { ++ # WRS extension: default flavor extra-spec hw:mem_page_size ++ 'DEFAULT/default_mempages_size': value => '2048'; ++ } + + } +diff --git a/manifests/ironic/common.pp b/manifests/ironic/common.pp +index f38393a..e2d53f8 100644 +--- a/manifests/ironic/common.pp ++++ b/manifests/ironic/common.pp +@@ -62,7 +62,7 @@ class nova::ironic::common ( + include ::nova::deps + + +- nova_config { ++ nova_ironic_config { + 'ironic/auth_plugin': value => $auth_plugin; + 'ironic/username': value => $username; + 'ironic/password': value => $password; +diff --git a/manifests/keystone/authtoken.pp b/manifests/keystone/authtoken.pp +index e2db1a0..fcf65d4 100644 +--- a/manifests/keystone/authtoken.pp ++++ b/manifests/keystone/authtoken.pp +@@ -266,4 +266,42 @@ class nova::keystone::authtoken( + revocation_cache_time => $revocation_cache_time, + token_cache_time => $token_cache_time, + } ++ ++ keystone::resource::authtoken { 'nova_ironic_config': ++ username => $username, ++ password => $password, ++ project_name => $project_name, ++ auth_url => $auth_url, ++ auth_uri => $auth_uri, ++ auth_version => $auth_version, ++ auth_type => $auth_type, ++ auth_section => $auth_section, ++ user_domain_name => $user_domain_name, ++ project_domain_name => $project_domain_name, ++ insecure => $insecure, ++ cache => $cache, ++ cafile => $cafile, ++ certfile => $certfile, ++ check_revocations_for_cached => $check_revocations_for_cached, ++ delay_auth_decision => $delay_auth_decision, ++ enforce_token_bind => $enforce_token_bind, ++ hash_algorithms => $hash_algorithms, ++ http_connect_timeout => $http_connect_timeout, ++ http_request_max_retries => $http_request_max_retries, ++ include_service_catalog => $include_service_catalog, ++ keyfile => $keyfile, ++ memcache_pool_conn_get_timeout => $memcache_pool_conn_get_timeout, ++ memcache_pool_dead_retry => $memcache_pool_dead_retry, ++ memcache_pool_maxsize => $memcache_pool_maxsize, ++ memcache_pool_socket_timeout => $memcache_pool_socket_timeout, ++ memcache_secret_key => $memcache_secret_key, ++ memcache_security_strategy => $memcache_security_strategy, ++ memcache_use_advanced_pool => $memcache_use_advanced_pool, ++ memcache_pool_unused_timeout => $memcache_pool_unused_timeout, ++ memcached_servers => $memcached_servers, ++ manage_memcache_package => $manage_memcache_package, ++ region_name => $region_name, ++ revocation_cache_time => $revocation_cache_time, ++ token_cache_time => $token_cache_time, ++ } + } +diff --git a/manifests/logging.pp b/manifests/logging.pp +index 4bdaef5..75703e2 100644 +--- a/manifests/logging.pp ++++ b/manifests/logging.pp +@@ -133,4 +133,23 @@ class nova::logging( + log_date_format => $log_date_format, + } + ++ oslo::log { 'nova_ironic_config': ++ debug => $debug_real, ++ use_stderr => $use_stderr_real, ++ use_syslog => $use_syslog_real, ++ log_dir => $log_dir_real, ++ syslog_log_facility => $log_facility_real, ++ logging_context_format_string => $logging_context_format_string, ++ logging_default_format_string => $logging_default_format_string, ++ logging_debug_format_suffix => $logging_debug_format_suffix, ++ logging_exception_prefix => $logging_exception_prefix, ++ log_config_append => $log_config_append, ++ default_log_levels => $default_log_levels, ++ publish_errors => $publish_errors, ++ fatal_deprecations => $fatal_deprecations, ++ instance_format => $instance_format, ++ instance_uuid_format => $instance_uuid_format, ++ log_date_format => $log_date_format, ++ } ++ + } +diff --git a/manifests/network.pp b/manifests/network.pp +index 64c696f..a00d481 100644 +--- a/manifests/network.pp ++++ b/manifests/network.pp +@@ -124,11 +124,18 @@ class nova::network( + 'DEFAULT/floating_range': value => $floating_range; + 'DEFAULT/auto_assign_floating_ip': value => $auto_assign_floating_ip; + } ++ nova_ironic_config { ++ 'DEFAULT/floating_range': value => $floating_range; ++ 'DEFAULT/auto_assign_floating_ip': value => $auto_assign_floating_ip; ++ } + } + + nova_config { + 'DEFAULT/multi_host': value => $multi_host; + } ++ nova_ironic_config { ++ 'DEFAULT/multi_host': value => $multi_host; ++ } + + if has_key($config_overrides, 'vlan_start') { + $vlan_start = $config_overrides['vlan_start'] +diff --git a/manifests/network/flat.pp b/manifests/network/flat.pp +index ad2870e..ca50dd7 100644 +--- a/manifests/network/flat.pp ++++ b/manifests/network/flat.pp +@@ -30,9 +30,19 @@ class nova::network::flat ( + + if $public_interface { + nova_config { 'DEFAULT/public_interface': value => $public_interface } ++ nova_ironic_config { 'DEFAULT/public_interface': value => $public_interface } + } + + nova_config { ++ rk/flat.pp ++ 'DEFAULT/network_manager': value => 'nova.network.manager.FlatManager'; ++ 'DEFAULT/fixed_range': value => $fixed_range; ++ 'DEFAULT/flat_interface': value => $flat_interface; ++ 'DEFAULT/flat_network_bridge': value => $flat_network_bridge; ++ } ++ ++ nova_ironic_config { ++ rk/flat.pp + 'DEFAULT/network_manager': value => 'nova.network.manager.FlatManager'; + 'DEFAULT/fixed_range': value => $fixed_range; + 'DEFAULT/flat_interface': value => $flat_interface; +diff --git a/manifests/network/flatdhcp.pp b/manifests/network/flatdhcp.pp +index 73d89d7..794e2be 100644 +--- a/manifests/network/flatdhcp.pp ++++ b/manifests/network/flatdhcp.pp +@@ -62,6 +62,7 @@ class nova::network::flatdhcp ( + + if $public_interface { + nova_config { 'DEFAULT/public_interface': value => $public_interface } ++ nova_ironic_config { 'DEFAULT/public_interface': value => $public_interface } + } + + nova_config { +@@ -76,4 +77,16 @@ class nova::network::flatdhcp ( + 'DEFAULT/dhcpbridge_flagfile': value => $dhcpbridge_flagfile; + } + ++ nova_ironic_config { ++ 'DEFAULT/network_manager': value => 'nova.network.manager.FlatDHCPManager'; ++ 'DEFAULT/fixed_range': value => $fixed_range; ++ 'DEFAULT/flat_interface': value => $flat_interface; ++ 'DEFAULT/flat_network_bridge': value => $flat_network_bridge; ++ 'DEFAULT/force_dhcp_release': value => $force_dhcp_release; ++ 'DEFAULT/flat_injected': value => $flat_injected; ++ 'DEFAULT/dhcp_domain': value => $dhcp_domain; ++ 'DEFAULT/dhcpbridge': value => $dhcpbridge; ++ 'DEFAULT/dhcpbridge_flagfile': value => $dhcpbridge_flagfile; ++ } ++ + } +diff --git a/manifests/network/neutron.pp b/manifests/network/neutron.pp +index 8a2c28b..20b0c00 100644 +--- a/manifests/network/neutron.pp ++++ b/manifests/network/neutron.pp +@@ -171,4 +171,24 @@ class nova::network::neutron ( + 'neutron/auth_type': value => $neutron_auth_type; + } + ++ nova_ironic_config { ++ 'DEFAULT/dhcp_domain': value => $dhcp_domain; ++ 'DEFAULT/firewall_driver': value => $firewall_driver; ++ 'DEFAULT/vif_plugging_is_fatal': value => false; ++ 'DEFAULT/vif_plugging_timeout': value => $vif_plugging_timeout; ++ 'neutron/default_floating_pool': value => $default_floating_pool_real; ++ 'neutron/url': value => $neutron_url; ++ 'neutron/timeout': value => $neutron_url_timeout; ++ 'neutron/project_name': value => $neutron_project_name; ++ 'neutron/project_domain_name': value => $neutron_project_domain_name; ++ 'neutron/region_name': value => $neutron_region_name; ++ 'neutron/username': value => $neutron_username; ++ 'neutron/user_domain_name': value => $neutron_user_domain_name; ++ 'neutron/password': value => $neutron_password, secret => true; ++ 'neutron/auth_url': value => $neutron_auth_url; ++ 'neutron/ovs_bridge': value => $neutron_ovs_bridge; ++ 'neutron/extension_sync_interval': value => $neutron_extension_sync_interval; ++ 'neutron/auth_type': value => $neutron_auth_type; ++ } ++ + } +diff --git a/manifests/network/vlan.pp b/manifests/network/vlan.pp +index f3261b8..aa76196 100644 +--- a/manifests/network/vlan.pp ++++ b/manifests/network/vlan.pp +@@ -56,6 +56,7 @@ class nova::network::vlan ( + + if $public_interface { + nova_config { 'DEFAULT/public_interface': value => $public_interface } ++ nova_ironic_config { 'DEFAULT/public_interface': value => $public_interface } + } + + nova_config { +@@ -69,4 +70,15 @@ class nova::network::vlan ( + 'DEFAULT/dhcpbridge_flagfile': value => $dhcpbridge_flagfile; + } + ++ nova_ironic_config { ++ 'DEFAULT/network_manager': value => 'nova.network.manager.VlanManager'; ++ 'DEFAULT/fixed_range': value => $fixed_range; ++ 'DEFAULT/vlan_interface': value => $vlan_interface; ++ 'DEFAULT/vlan_start': value => $vlan_start; ++ 'DEFAULT/force_dhcp_release': value => $force_dhcp_release; ++ 'DEFAULT/dhcp_domain': value => $dhcp_domain; ++ 'DEFAULT/dhcpbridge': value => $dhcpbridge; ++ 'DEFAULT/dhcpbridge_flagfile': value => $dhcpbridge_flagfile; ++ } ++ + } +diff --git a/manifests/placement.pp b/manifests/placement.pp +index 1ed8ec0..7903dc7 100644 +--- a/manifests/placement.pp ++++ b/manifests/placement.pp +@@ -73,4 +73,16 @@ class nova::placement( + 'placement/os_interface': value => $os_interface; + } + ++ nova_ironic_config { ++ 'placement/auth_type': value => $auth_type; ++ 'placement/auth_url': value => $auth_url; ++ 'placement/password': value => $password, secret => true; ++ 'placement/project_domain_name': value => $project_domain_name; ++ 'placement/project_name': value => $project_name; ++ 'placement/user_domain_name': value => $user_domain_name; ++ 'placement/username': value => $username; ++ 'placement/os_region_name': value => $os_region_name; ++ 'placement/os_interface': value => $os_interface; ++ } ++ + } +diff --git a/manifests/policy.pp b/manifests/policy.pp +index 238ca04..2ab9530 100644 +--- a/manifests/policy.pp ++++ b/manifests/policy.pp +@@ -41,5 +41,6 @@ class nova::policy ( + create_resources('openstacklib::policy::base', $policies, $policy_defaults) + + oslo::policy { 'nova_config': policy_file => $policy_path } ++ oslo::policy { 'nova_ironic_config': policy_file => $policy_path } + + } +diff --git a/manifests/quota.pp b/manifests/quota.pp +index f4b1682..f71895d 100644 +--- a/manifests/quota.pp ++++ b/manifests/quota.pp +@@ -116,4 +116,24 @@ class nova::quota( + 'DEFAULT/max_age': value => $max_age; + } + ++ nova_ironic_config { ++ 'DEFAULT/quota_instances': value => $quota_instances; ++ 'DEFAULT/quota_cores': value => $quota_cores; ++ 'DEFAULT/quota_ram': value => $quota_ram; ++ 'DEFAULT/quota_floating_ips': value => $quota_floating_ips; ++ 'DEFAULT/quota_fixed_ips': value => $quota_fixed_ips; ++ 'DEFAULT/quota_metadata_items': value => $quota_metadata_items; ++ 'DEFAULT/quota_injected_files': value => $quota_injected_files; ++ 'DEFAULT/quota_injected_file_content_bytes': value => $quota_injected_file_content_bytes; ++ 'DEFAULT/quota_injected_file_path_length': value => $quota_injected_file_path_length; ++ 'DEFAULT/quota_security_groups': value => $quota_security_groups; ++ 'DEFAULT/quota_security_group_rules': value => $quota_security_group_rules; ++ 'DEFAULT/quota_key_pairs': value => $quota_key_pairs; ++ 'DEFAULT/quota_server_groups': value => $quota_server_groups; ++ 'DEFAULT/quota_server_group_members': value => $quota_server_group_members; ++ 'DEFAULT/reservation_expire': value => $reservation_expire; ++ 'DEFAULT/until_refresh': value => $until_refresh; ++ 'DEFAULT/max_age': value => $max_age; ++ } ++ + } +diff --git a/manifests/serialproxy.pp b/manifests/serialproxy.pp +index fe1b617..f52b128 100644 +--- a/manifests/serialproxy.pp ++++ b/manifests/serialproxy.pp +@@ -39,6 +39,10 @@ class nova::serialproxy( + 'serial_console/serialproxy_port': value => $serialproxy_port; + 'serial_console/serialproxy_host': value => $serialproxy_host; + } ++ nova_ironic_config { ++ 'serial_console/serialproxy_port': value => $serialproxy_port; ++ 'serial_console/serialproxy_host': value => $serialproxy_host; ++ } + + nova::generic_service { 'serialproxy': + enabled => $enabled, +diff --git a/manifests/vncproxy.pp b/manifests/vncproxy.pp +index 23b102f..507e522 100644 +--- a/manifests/vncproxy.pp ++++ b/manifests/vncproxy.pp +@@ -51,6 +51,11 @@ class nova::vncproxy( + 'vnc/novncproxy_port': value => $port; + } + ++ nova_ironic_config { ++ 'vnc/novncproxy_host': value => $host; ++ 'vnc/novncproxy_port': value => $port; ++ } ++ + nova::generic_service { 'vncproxy': + enabled => $enabled, + manage_service => $manage_service, +diff --git a/manifests/vncproxy/common.pp b/manifests/vncproxy/common.pp +index 7a6a2ff..d6e26d8 100644 +--- a/manifests/vncproxy/common.pp ++++ b/manifests/vncproxy/common.pp +@@ -80,5 +80,8 @@ class nova::vncproxy::common ( + nova_config { + 'vnc/novncproxy_base_url': value => $vncproxy_base_url; + } ++ nova_ironic_config { ++ 'vnc/novncproxy_base_url': value => $vncproxy_base_url; ++ } + } + } diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch new file mode 100644 index 000000000..1bdc0df92 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0007-Remove-joshuabaird-ipaclient-from-puppet-nova-requir.patch @@ -0,0 +1,26 @@ +From 6a25305dcd4bb2c42a4802b23f045719a9d7d027 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 10:08:36 -0600 +Subject: [PATCH] Remove joshuabaird-ipaclient from puppet-nova requirements + +We are not using novajoin in our manifests so we do not need to package and include an additional +puppet module not provided by centos +--- + metadata.json | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/metadata.json b/metadata.json +index 26a2c3a..e505b71 100644 +--- a/metadata.json ++++ b/metadata.json +@@ -10,7 +10,6 @@ + "dependencies": [ + {"name":"puppetlabs/apache","version_requirement":">=1.0.0 <2.0.0"}, + {"name":"duritong/sysctl","version_requirement":">=0.0.1 <1.0.0"}, +- {"name":"joshuabaird/ipaclient","version_requirement":">=2.5.1"}, + {"name":"openstack/cinder","version_requirement":">=11.3.0 <12.0.0"}, + {"name":"openstack/glance","version_requirement":">=11.3.0 <12.0.0"}, + {"name":"puppetlabs/inifile","version_requirement":">=1.0.0 <2.0.0"}, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0008-Adding-pci_weight_multiple-to-nova-scheduler-filter.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0008-Adding-pci_weight_multiple-to-nova-scheduler-filter.patch new file mode 100644 index 000000000..3ba0e884c --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0008-Adding-pci_weight_multiple-to-nova-scheduler-filter.patch @@ -0,0 +1,60 @@ +From 4d2ea36762a73b3dcf86bef0e100342b02667a03 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 14 Mar 2018 10:52:29 -0500 +Subject: [PATCH] Adding pci_weight_multiple to nova scheduler filter + +Only adding to scheduler filter and not the cell filter +Also updated the ruby spec to expect the new value +--- + manifests/scheduler/filter.pp | 8 ++++++++ + spec/classes/nova_scheduler_filter_spec.rb | 1 + + 2 files changed, 9 insertions(+) + +diff --git a/manifests/scheduler/filter.pp b/manifests/scheduler/filter.pp +index 52179a7..c27de8a 100644 +--- a/manifests/scheduler/filter.pp ++++ b/manifests/scheduler/filter.pp +@@ -99,6 +99,11 @@ + # (optional) Separator character(s) for image property namespace and name + # Defaults to $::os_service_default + # ++# WRS ++# [*pci_weight_multiplier*] ++# (optional) Multiplier for weighing hosts based on pci ++# Defaults to $::os_service_default ++# + class nova::scheduler::filter ( + $scheduler_host_manager = 'host_manager', + $scheduler_max_attempts = '3', +@@ -122,6 +127,7 @@ class nova::scheduler::filter ( + $restrict_isolated_hosts_to_isolated_images = $::os_service_default, + $aggregate_image_properties_isolation_namespace = $::os_service_default, + $aggregate_image_properties_isolation_separator = $::os_service_default, ++ $pci_weight_multiplier = $::os_service_default, + ) { + + include ::nova::deps +@@ -213,6 +219,8 @@ class nova::scheduler::filter ( + value => $aggregate_image_properties_isolation_namespace; + 'filter_scheduler/aggregate_image_properties_isolation_separator': + value => $aggregate_image_properties_isolation_separator; ++ 'filter_scheduler/pci_weight_multiplier': ++ value => $pci_weight_multiplier; + } + + } +diff --git a/spec/classes/nova_scheduler_filter_spec.rb b/spec/classes/nova_scheduler_filter_spec.rb +index 1ae0b10..037b506 100644 +--- a/spec/classes/nova_scheduler_filter_spec.rb ++++ b/spec/classes/nova_scheduler_filter_spec.rb +@@ -31,6 +31,7 @@ describe 'nova::scheduler::filter' do + it { is_expected.to contain_nova_config('filter_scheduler/restrict_isolated_hosts_to_isolated_images').with_value('') } + it { is_expected.to contain_nova_config('filter_scheduler/aggregate_image_properties_isolation_namespace').with_value('') } + it { is_expected.to contain_nova_config('filter_scheduler/aggregate_image_properties_isolation_separator').with_value('') } ++ it { is_expected.to contain_nova_config('filter_scheduler/pci_weight_multiplier').with_value('') } + + end + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0009-Remove-SerialConsole-from-NovaConf.patch b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0009-Remove-SerialConsole-from-NovaConf.patch new file mode 100644 index 000000000..cb1c77241 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/patches/0009-Remove-SerialConsole-from-NovaConf.patch @@ -0,0 +1,39 @@ +commit 10632d76afeaf052f604bb7e983e07c631bbb387 +Author: Shoaib Nasir +Date: Thu Mar 15 14:54:50 2018 -0400 + + WRS: Patch9 - Remove-SerialConsole-from-novaconf.patch + +diff --git a/manifests/compute/serial.pp b/manifests/compute/serial.pp +index 83d1526..6a34abb 100644 +--- a/manifests/compute/serial.pp ++++ b/manifests/compute/serial.pp +@@ -25,13 +25,6 @@ class nova::compute::serial( + + include ::nova::deps + +- nova_config { +- 'serial_console/enabled': value => true; +- 'serial_console/port_range': value => $port_range; +- 'serial_console/base_url': value => $base_url; +- 'serial_console/proxyclient_address': value => $proxyclient_address; +- } +- + nova_ironic_config { + 'serial_console/enabled': value => true; + 'serial_console/port_range': value => $port_range; +diff --git a/manifests/serialproxy.pp b/manifests/serialproxy.pp +index f52b128..5ea2cb4 100644 +--- a/manifests/serialproxy.pp ++++ b/manifests/serialproxy.pp +@@ -35,10 +35,6 @@ class nova::serialproxy( + include ::nova::deps + include ::nova::params + +- nova_config { +- 'serial_console/serialproxy_port': value => $serialproxy_port; +- 'serial_console/serialproxy_host': value => $serialproxy_host; +- } + nova_ironic_config { + 'serial_console/serialproxy_port': value => $serialproxy_port; + 'serial_console/serialproxy_host': value => $serialproxy_host; diff --git a/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/srpm_path new file mode 100644 index 000000000..7efb1101b --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-nova-11.4.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-nova-11.4.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..0eac83bbb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=4 diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..350bed51d --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 2a3ff36dc325a09ae8601575a0699bdcedcf463b Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 16 Oct 2017 12:06:28 -0500 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-openstacklib.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-openstacklib.spec b/SPECS/puppet-openstacklib.spec +index 7f3bbd8..8bf2c1b 100644 +--- a/SPECS/puppet-openstacklib.spec ++++ b/SPECS/puppet-openstacklib.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-openstacklib + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet OpenStack Libraries + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch new file mode 100644 index 000000000..5fea85474 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0002-Add-TIS-patch.patch @@ -0,0 +1,32 @@ +From 0eea2c3205d9d38e6118e8c97bebae0a87674054 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Wed, 11 Jan 2017 12:30:10 -0500 +Subject: [PATCH] Add TIS patch + +--- + SPECS/puppet-openstacklib.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-openstacklib.spec b/SPECS/puppet-openstacklib.spec +index 0ed0c1d..38faf85 100644 +--- a/SPECS/puppet-openstacklib.spec ++++ b/SPECS/puppet-openstacklib.spec +@@ -8,6 +8,7 @@ License: Apache-2.0 + URL: https://launchpad.net/puppet-openstacklib + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch + + BuildArch: noarch + +@@ -24,6 +25,7 @@ Puppet OpenStack Libraries + + %prep + %setup -q -n openstack-openstacklib-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0003-Add-os-region-name-option-for-system-controller.patch b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0003-Add-os-region-name-option-for-system-controller.patch new file mode 100644 index 000000000..9117762a9 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/0003-Add-os-region-name-option-for-system-controller.patch @@ -0,0 +1,32 @@ +From d41dc6c9dcf6e0fbf5ef82f0aaf4e951699aa13c Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Wed, 21 Feb 2018 13:42:58 -0600 +Subject: [PATCH 1/1] Add os region name option for system controller + +--- + SPECS/puppet-openstacklib.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-openstacklib.spec b/SPECS/puppet-openstacklib.spec +index 9622492..1a42722 100644 +--- a/SPECS/puppet-openstacklib.spec ++++ b/SPECS/puppet-openstacklib.spec +@@ -9,6 +9,7 @@ URL: https://launchpad.net/puppet-openstacklib + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-Add-os-region-name-option-for-system-controller.patch + + BuildArch: noarch + +@@ -26,6 +27,7 @@ Puppet OpenStack Libraries + %prep + %setup -q -n openstack-openstacklib-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..3b044fba8 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-patch.patch +0003-Add-os-region-name-option-for-system-controller.patch diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..5030d2a2b --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,86 @@ +From d73f9ea44ec91944af0bc4faa743b0df2570f200 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 16 Oct 2017 13:12:14 -0500 +Subject: [PATCH] Roll up TIS patches + +Includes CGTS-6741 puppet openstack use internal url +--- + lib/puppet/provider/openstack.rb | 1 + + lib/puppet/provider/openstack/auth.rb | 16 ++++++++++++++-- + lib/puppet/provider/openstack/credentials.rb | 2 -- + 3 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/lib/puppet/provider/openstack.rb b/lib/puppet/provider/openstack.rb +index 0240ce4..8b8e564 100644 +--- a/lib/puppet/provider/openstack.rb ++++ b/lib/puppet/provider/openstack.rb +@@ -45,6 +45,7 @@ class Puppet::Provider::Openstack < Puppet::Provider + begin + action = args[1] + Timeout.timeout(command_timeout(action)) do ++ args.unshift('--os-interface', 'internal') + openstack_command *args + end + rescue Timeout::Error +diff --git a/lib/puppet/provider/openstack/auth.rb b/lib/puppet/provider/openstack/auth.rb +index 743071d..73abeb3 100644 +--- a/lib/puppet/provider/openstack/auth.rb ++++ b/lib/puppet/provider/openstack/auth.rb +@@ -1,9 +1,19 @@ + #require 'puppet/provider/openstack/credentials' + require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/openstack/credentials') ++require 'hiera_puppet' + + module Puppet::Provider::Openstack::Auth + +- RCFILENAME = "#{ENV['HOME']}/openrc" ++ RCFILENAME = "/etc/nova/openrc" ++ ++ def lookup_hiera(key) ++ HieraPuppet.lookup(key, :undef, self, nil, :priority) ++ end ++ ++ def get_admin_password ++ value=lookup_hiera('keystone::admin_password') ++ return value ++ end + + def get_os_vars_from_env + env = {} +@@ -17,7 +27,7 @@ module Puppet::Provider::Openstack::Auth + unless rcfile.nil? + File.open(rcfile).readlines.delete_if{|l| l=~ /^#|^$/ }.each do |line| + # we only care about the OS_ vars from the file LP#1699950 +- if line =~ /OS_/ ++ if line =~ /OS_/ and line.include?('=') + key, value = line.split('=') + key = key.split(' ').last + value = value.chomp.gsub(/'/, '') +@@ -38,6 +48,8 @@ module Puppet::Provider::Openstack::Auth + unless @credentials.set? + @credentials.unset + set_credentials(@credentials, get_os_vars_from_rcfile(rc_filename)) ++ # retrieves the password from hiera data since keyring is not yet available ++ @credentials.password = get_admin_password + end + unless @credentials.set? + raise(Puppet::Error::OpenstackAuthInputError, 'Insufficient credentials to authenticate') +diff --git a/lib/puppet/provider/openstack/credentials.rb b/lib/puppet/provider/openstack/credentials.rb +index 2765b2b..9c831e3 100644 +--- a/lib/puppet/provider/openstack/credentials.rb ++++ b/lib/puppet/provider/openstack/credentials.rb +@@ -70,11 +70,9 @@ class Puppet::Provider::Openstack::CredentialsV3 < Puppet::Provider::Openstack:: + :domain_id, + :domain_name, + :key, +- :project_domain_id, + :project_domain_name, + :project_id, + :trust_id, +- :user_domain_id, + :user_domain_name, + :user_id + ] +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0002-Add-os-region-name-option-for-system-controller.patch b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0002-Add-os-region-name-option-for-system-controller.patch new file mode 100644 index 000000000..bd3b5f2fb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/patches/0002-Add-os-region-name-option-for-system-controller.patch @@ -0,0 +1,40 @@ +From 17142ba33ae9cdf10bcc36a1329e97a5dfd7d7d6 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Wed, 21 Feb 2018 13:35:59 -0600 +Subject: [PATCH 1/1] Add os region name option for system controller + +--- + lib/puppet/provider/openstack.rb | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/lib/puppet/provider/openstack.rb b/lib/puppet/provider/openstack.rb +index 8b8e564..53f2366 100644 +--- a/lib/puppet/provider/openstack.rb ++++ b/lib/puppet/provider/openstack.rb +@@ -40,12 +40,23 @@ class Puppet::Provider::Openstack < Puppet::Provider + self.class_variable_get("@@command_timeout") + end + ++ def self.hiera_lookup(key) ++ HieraPuppet.lookup(key, :undef, self, nil, :priority) ++ end ++ ++ def self.systemcontroller? ++ return true if hiera_lookup('platform::params::distributed_cloud_role') == 'systemcontroller' ++ end ++ + # with command_timeout + def self.openstack(*args) + begin + action = args[1] + Timeout.timeout(command_timeout(action)) do + args.unshift('--os-interface', 'internal') ++ if systemcontroller? ++ args.unshift('--os-region-name', 'SystemController') ++ end + openstack_command *args + end + rescue Timeout::Error +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/srpm_path new file mode 100644 index 000000000..609c1cc18 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-openstacklib-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-openstacklib-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..7a88f3d5c --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 3f11515f1f5c95bba34be6148d21b4a31d413a05 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 11:44:56 -0400 +Subject: [PATCH 1/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/puppet-oslo.spec +--- + SPECS/puppet-oslo.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-oslo.spec b/SPECS/puppet-oslo.spec +index 2c7bdad..2b89be7 100644 +--- a/SPECS/puppet-oslo.spec ++++ b/SPECS/puppet-oslo.spec +@@ -1,7 +1,7 @@ + %{!?upstream_version: %global upstream_version %{version}%{?milestone}} + Name: puppet-oslo + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for managing Oslo.* library + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0002-Add-WRS-patch.patch b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0002-Add-WRS-patch.patch new file mode 100644 index 000000000..adfdd8bde --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0002-Add-WRS-patch.patch @@ -0,0 +1,34 @@ +From c1099550e41a13e84ed2822a0826bae2e9bcb9d9 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 11:44:56 -0400 +Subject: [PATCH 2/2] WRS: 0002-Add-WRS-patch.patch + +--- + SPECS/puppet-oslo.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/puppet-oslo.spec b/SPECS/puppet-oslo.spec +index 2b89be7..d2d6331 100644 +--- a/SPECS/puppet-oslo.spec ++++ b/SPECS/puppet-oslo.spec +@@ -9,6 +9,8 @@ URL: https://launchpad.net/puppet-oslo + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + ++Patch0001: 0001-Remove-log_dir-from-conf-files.patch ++ + BuildArch: noarch + + Requires: puppet-inifile +@@ -22,6 +24,8 @@ Puppet module for managing Oslo.* library + %prep + %setup -q -n openstack-oslo-%{upstream_version} + ++%patch0001 -p1 ++ + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + + find . \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0003-psycopg2-drivername-for-postgres.patch b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0003-psycopg2-drivername-for-postgres.patch new file mode 100644 index 000000000..930f4670c --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/0003-psycopg2-drivername-for-postgres.patch @@ -0,0 +1,32 @@ +From 4291fe6a18127e1169f4364b1f2e934ab06dc86b Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 14 Dec 2017 11:10:05 -0600 +Subject: [PATCH] psycopg2 drivername for postgres + +--- + SPECS/puppet-oslo.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-oslo.spec b/SPECS/puppet-oslo.spec +index 65bd995..9802ecc 100644 +--- a/SPECS/puppet-oslo.spec ++++ b/SPECS/puppet-oslo.spec +@@ -10,6 +10,7 @@ URL: https://launchpad.net/puppet-oslo + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + + Patch0001: 0001-Remove-log_dir-from-conf-files.patch ++Patch0002: 0002-add-psycopg2-drivername-to-postgresql-settings.patch + + BuildArch: noarch + +@@ -25,6 +26,7 @@ Puppet module for managing Oslo.* library + %setup -q -n openstack-oslo-%{upstream_version} + + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..4030bb1ca --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-WRS-patch.patch +0003-psycopg2-drivername-for-postgres.patch diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0001-Remove-log_dir-from-conf-files.patch b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0001-Remove-log_dir-from-conf-files.patch new file mode 100644 index 000000000..3443b2e12 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0001-Remove-log_dir-from-conf-files.patch @@ -0,0 +1,36 @@ +From b8dee2da527c3d3010e2b5b4e49f87f430afa826 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Fri, 3 Nov 2017 17:48:38 -0500 +Subject: [PATCH] Remove log_dir from conf files + +--- + manifests/log.pp | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/manifests/log.pp b/manifests/log.pp +index 8778d46..771a674 100644 +--- a/manifests/log.pp ++++ b/manifests/log.pp +@@ -27,9 +27,7 @@ + # Defaults to $::os_service_default + # + # [*log_dir*] +-# (Optional) Directory where logs should be stored. +-# If set to $::os_service_default, it will not log to any directory. +-# Defaults to $::os_service_default ++# WRS: Remove log_dir to ensure services log via syslog + # + # [*watch_log_file*] + # (Optional) Uses logging handler designed to watch file system (boolean value). +@@ -136,7 +134,7 @@ define oslo::log( + 'DEFAULT/log_config_append' => { value => $log_config_append }, + 'DEFAULT/log_date_format' => { value => $log_date_format }, + 'DEFAULT/log_file' => { value => $log_file }, +- 'DEFAULT/log_dir' => { value => $log_dir }, ++ 'DEFAULT/log_dir' => { ensure => absent }, + 'DEFAULT/watch_log_file' => { value => $watch_log_file }, + 'DEFAULT/use_syslog' => { value => $use_syslog }, + 'DEFAULT/syslog_log_facility' => { value => $syslog_log_facility }, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0002-add-psycopg2-drivername-to-postgresql-settings.patch b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0002-add-psycopg2-drivername-to-postgresql-settings.patch new file mode 100644 index 000000000..7340a067b --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/patches/0002-add-psycopg2-drivername-to-postgresql-settings.patch @@ -0,0 +1,51 @@ +From 1823423c329675a72ea5b3497c31f8c407dcdf27 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 14 Dec 2017 11:08:30 -0600 +Subject: [PATCH] add psycopg2 drivername to postgresql settings + +--- + manifests/db.pp | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/manifests/db.pp b/manifests/db.pp +index 172c8ae..4b918bc 100644 +--- a/manifests/db.pp ++++ b/manifests/db.pp +@@ -132,10 +132,13 @@ define oslo::db( + + if !is_service_default($connection) { + +- validate_re($connection, +- '^(sqlite|mysql(\+pymysql)?|postgresql|mongodb):\/\/(\S+:\S+@\S+\/\S+)?') ++ if $connection !~ '^(sqlite|mysql(\+pymysql)?|postgresql(\+psycopg2)?|mongodb):\/\/(\S+:\S+@\S+\/\S+)?' { ++ err{'invalid database connection parameter: $connection':} ++ } ++ # add psycopg2 drivername to postgresql if using driverless postgres setting ++ $real_connection = regsubst($connection,'^postgresql:','postgresql+psycopg2:') + +- case $connection { ++ case $real_connection { + /^mysql(\+pymysql)?:\/\//: { + require '::mysql::bindings' + require '::mysql::bindings::python' +@@ -145,7 +148,7 @@ define oslo::db( + $backend_package = false + } + } +- /^postgresql:\/\//: { ++ /^postgresql(\+psycopg2)?:\/\//: { + $backend_package = false + require '::postgresql::lib::python' + } +@@ -178,7 +181,7 @@ to connect to the database.") + $database_options = { + 'database/sqlite_synchronous' => { value => $sqlite_synchronous }, + 'database/backend' => { value => $backend }, +- 'database/connection' => { value => $connection, secret => true }, ++ 'database/connection' => { value => $real_connection, secret => true }, + 'database/slave_connection' => { value => $slave_connection, secret => true }, + 'database/mysql_sql_mode' => { value => $mysql_sql_mode }, + 'database/idle_timeout' => { value => $idle_timeout }, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/srpm_path new file mode 100644 index 000000000..825811329 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-oslo-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-oslo-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/build_srpm.data b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/0001-meta-fix-panko-puppet-warning.patch b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/0001-meta-fix-panko-puppet-warning.patch new file mode 100644 index 000000000..664eae41b --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/0001-meta-fix-panko-puppet-warning.patch @@ -0,0 +1,42 @@ +From b16235e006dff73c7d90a5c4362ec45d976c8411 Mon Sep 17 00:00:00 2001 +From: Angie Wang +Date: Mon, 29 Jan 2018 13:32:42 -0500 +Subject: [PATCH 1/1] meta fix panko puppet warning + +--- + SPECS/puppet-panko.spec | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/SPECS/puppet-panko.spec b/SPECS/puppet-panko.spec +index f19cd32..a235ee2 100644 +--- a/SPECS/puppet-panko.spec ++++ b/SPECS/puppet-panko.spec +@@ -4,7 +4,7 @@ + + Name: puppet-panko + Version: 11.3.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Puppet module for OpenStack Panko Service + License: ASL 2.0 + +@@ -12,6 +12,8 @@ URL: https://launchpad.net/puppet-panko + + Source0: https://tarballs.openstack.org/%{name}/%{name}-%{upstream_version}.tar.gz + ++Patch0001: 0001-Fix-panko-puppet-warning.patch ++ + BuildArch: noarch + + Requires: puppet-inifile +@@ -26,6 +28,7 @@ Installs and configures OpenStack Panko Events Service. + + %prep + %setup -q -n %{upstream_name}-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..f2b82c2f2 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-meta-fix-panko-puppet-warning.patch diff --git a/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/patches/0001-Fix-panko-puppet-warning.patch b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/patches/0001-Fix-panko-puppet-warning.patch new file mode 100644 index 000000000..c3f97720d --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/patches/0001-Fix-panko-puppet-warning.patch @@ -0,0 +1,25 @@ +From 02fb08dbc67712c70f65f0098f73a72820a7182d Mon Sep 17 00:00:00 2001 +From: Angie Wang +Date: Mon, 29 Jan 2018 13:24:18 -0500 +Subject: [PATCH 1/1] Fix panko puppet warning + +--- + manifests/api.pp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/manifests/api.pp b/manifests/api.pp +index bd72fea..7f6620c 100644 +--- a/manifests/api.pp ++++ b/manifests/api.pp +@@ -89,7 +89,7 @@ class panko::api ( + $es_index_name = $::os_service_default, + ) inherits panko::params { + +- warning('This Class is deprecated and will be removed in future releases.') ++ # warning('This Class is deprecated and will be removed in future releases.') + + include ::panko::deps + include ::panko::policy +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/srpm_path b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/srpm_path new file mode 100644 index 000000000..6e579ba47 --- /dev/null +++ b/devtools/puppet-modules/openstack/puppet-panko-11.3.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-panko-11.3.0-1.el7.src.rpm diff --git a/devtools/puppet-modules/puppet-boolean-1.0.2/centos/build_srpm.data b/devtools/puppet-modules/puppet-boolean-1.0.2/centos/build_srpm.data new file mode 100644 index 000000000..abed3a7b1 --- /dev/null +++ b/devtools/puppet-modules/puppet-boolean-1.0.2/centos/build_srpm.data @@ -0,0 +1,16 @@ +PREFIX=puppet +MODULE=boolean +VERSION=1.0.2 + +GIT_SHA=22b726dd78b0a60a224cc7054aebbf28e9306f62 + +# Generic Copy routine +# Un-patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz" + +#Patched +#COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=1 diff --git a/devtools/puppet-modules/puppet-boolean-1.0.2/centos/puppet-boolean.spec b/devtools/puppet-modules/puppet-boolean-1.0.2/centos/puppet-boolean.spec new file mode 100644 index 000000000..666211252 --- /dev/null +++ b/devtools/puppet-modules/puppet-boolean-1.0.2/centos/puppet-boolean.spec @@ -0,0 +1,39 @@ +%global git_sha 22b726dd78b0a60a224cc7054aebbf28e9306f62 +%global module_dir boolean + +Name: puppet-boolean +Version: 1.0.2 +Release: 1%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet Boolean module +License: Apache + +URL: https://github.com/adrienthebo/puppet-boolean + +Source0: %{name}-%{git_sha}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A Puppet module to provide boolean parameters + +%prep +%setup -n %{name} + +find . -type f -name ".*" -exec rm {} + +find . -size 0 -exec rm {} + +find . \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} + +find . \( -name "*.pp" -o -name "*.py" \) -exec chmod -x {} + +find . \( -name "*.rb" -o -name "*.erb" \) -exec chmod -x {} + +find . \( -name spec -o -name ext \) | xargs rm -rf + +%install +rm -rf %{buildroot} +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -rp * %{buildroot}/%{_datadir}/puppet/modules/%{module_dir}/ + +%files +%license %{_datadir}/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-create_resources/centos/build_srpm.data b/devtools/puppet-modules/puppet-create_resources/centos/build_srpm.data new file mode 100644 index 000000000..b7700f318 --- /dev/null +++ b/devtools/puppet-modules/puppet-create_resources/centos/build_srpm.data @@ -0,0 +1,16 @@ +PREFIX=puppetlabs +MODULE=create_resources +VERSION=0.0.1 + +GIT_SHA=4639819a7f3a4fa9310d2ba583c63e467df7e2c3 + +# Generic Copy routine +# Un-patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz" + +#Patched +#COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/puppet-create_resources/centos/puppet-create_resources.spec b/devtools/puppet-modules/puppet-create_resources/centos/puppet-create_resources.spec new file mode 100644 index 000000000..9ad58ff3d --- /dev/null +++ b/devtools/puppet-modules/puppet-create_resources/centos/puppet-create_resources.spec @@ -0,0 +1,32 @@ +%global git_sha 4639819a7f3a4fa9310d2ba583c63e467df7e2c3 +%global prefix puppetlabs +%global module_dir create_resources + +Name: puppet-%{module_dir} +Version: 0.0.1 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet %{module_dir} module +License: Apache + +URL: https://github.com/puppetlabs/puppetlabs-create_resources + +Source0: %{prefix}-%{module_dir}-%{git_sha}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A Puppet module to dynamically add resources to the catalog + +%prep +%autosetup -c %{module_dir} + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R packstack/puppet/modules/%{module_dir} %{buildroot}/%{_datadir}/puppet/modules + +%files +%license packstack/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-dnsmasq/centos/build_srpm.data b/devtools/puppet-modules/puppet-dnsmasq/centos/build_srpm.data new file mode 100644 index 000000000..09d2ebb68 --- /dev/null +++ b/devtools/puppet-modules/puppet-dnsmasq/centos/build_srpm.data @@ -0,0 +1,12 @@ +PREFIX=puppet +MODULE=dnsmasq +VERSION=1.1.0 + +GIT_SHA=cff07e90890662972c97684a2baee964f68ff3ed + +#Patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=3 diff --git a/devtools/puppet-modules/puppet-dnsmasq/centos/files/0001-puppet-dnsmasq-Kilo-quilt-patches.patch b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0001-puppet-dnsmasq-Kilo-quilt-patches.patch new file mode 100644 index 000000000..ff631ec66 --- /dev/null +++ b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0001-puppet-dnsmasq-Kilo-quilt-patches.patch @@ -0,0 +1,116 @@ +From 7430149d3a7f1ab9f93ec863e55cdf6d96cd4f06 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 7 Jun 2016 10:22:23 -0400 +Subject: [PATCH] puppet-dnsmasq Kilo quilt patches + +--- + packstack/puppet/modules/dnsmasq/manifests/init.pp | 8 ++++++++ + packstack/puppet/modules/dnsmasq/manifests/params.pp | 7 +++++-- + packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb | 9 ++++++--- + 3 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/packstack/puppet/modules/dnsmasq/manifests/init.pp b/packstack/puppet/modules/dnsmasq/manifests/init.pp +index 176bec7..c61fd94 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/init.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/init.pp +@@ -258,6 +258,13 @@ + # If you don't want dnsmasq to read /etc/hosts, set this to true. + # Default: false + # ++# [*dhcp_hostsfile*] ++# Read DHCP host information from the specified file. The file contains ++# information about one host per line. The format of a line is the same ++# as text to the right of '=' in --dhcp-host. The advantage of storing ++# DHCP host information in this file is that it can be changed without ++# re-starting dnsmasq: the file will be re-read when dnsmasq receives SIGHUP. ++# + # [*addn_hosts*] + # If you want dnsmasq to read another file/s, as well as /etc/hosts, use this. + # It can be an array of files to read. See next option to manage these files with +@@ -457,6 +464,7 @@ class dnsmasq ( + $no_poll = params_lookup( 'no_poll' ), + $bind_interfaces = params_lookup( 'bind_interfaces' ), + $no_hosts = params_lookup( 'no_hosts' ), ++ $dhcp_hostsfile = params_lookup( 'dhcp_hostsfile' ), + $addn_hosts = params_lookup( 'addn_hosts' ), + $addn_hosts_dir = params_lookup( 'addn_hosts_dir' ), + $expand_hosts = params_lookup( 'expand_hosts' ), +diff --git a/packstack/puppet/modules/dnsmasq/manifests/params.pp b/packstack/puppet/modules/dnsmasq/manifests/params.pp +index 5b8f02d..6dd5b96 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/params.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/params.pp +@@ -38,6 +38,7 @@ class dnsmasq::params { + + $process_user = $::operatingsystem ? { + /(?i:Debian|Ubuntu|Mint)/ => 'dnsmasq', ++ /(?i:wrlinux)/ => 'root', + default => 'nobody', + } + +@@ -62,7 +63,7 @@ class dnsmasq::params { + } + + $config_file_init = $::operatingsystem ? { +- /(?i:Debian|Ubuntu|Mint)/ => '/etc/default/dnsmasq', ++ /(?i:Debian|Ubuntu|Mint|wrlinux)/ => '/etc/default/dnsmasq', + default => '/etc/sysconfig/dnsmasq', + } + +@@ -90,6 +91,7 @@ class dnsmasq::params { + $no_poll = false + $bind_interfaces = false + $no_hosts = false ++ $dhcp_hostsfile = '' + $addn_hosts = '' + $addn_hosts_dir = '' + $expand_hosts = false +@@ -115,6 +117,7 @@ class dnsmasq::params { + } + $mx_target = '' + $localmx = false ++ $selfmx = false + $server = '' + $local = '' + $address = '' +@@ -151,7 +154,7 @@ class dnsmasq::params { + $version = 'present' + $absent = false + $disable = false +- $disableboot = false ++ $disableboot = true + + ### General module variables that can have a site or per module default + $monitor = false +diff --git a/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb b/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb +index 7bc4a03..ea5aa01 100644 +--- a/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb ++++ b/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb +@@ -3,12 +3,12 @@ + <% if scope.lookupvar('dnsmasq::port') != '' -%> + port=<%= scope.lookupvar('dnsmasq::port') %> + <% end -%> +-<% if scope.lookupvar('dnsmasq::bool_domain_need') -%> +-domain-needed +-<% end -%> + <% if scope.lookupvar('dnsmasq::bool_bogus_priv') -%> + bogus-priv + <% end -%> ++<% if scope.lookupvar('dnsmasq::bool_domain_needed') -%> ++domain-needed ++<% end -%> + <% if scope.lookupvar('dnsmasq::bool_filterwin2k') -%> + filterwin2k + <% end -%> +@@ -33,6 +33,9 @@ bind-interfaces + <% if scope.lookupvar('dnsmasq::bool_no_hosts') -%> + no-hosts + <% end -%> ++<% if scope.lookupvar('dnsmasq::dhcp_hostsfile') != '' -%> ++dhcp-hostsfile=<%= scope.lookupvar('dnsmasq::dhcp_hostsfile') %> ++<% end -%> + <% if scope.lookupvar('dnsmasq::bool_expand_hosts') -%> + expand-hosts + <% end -%> +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-dnsmasq/centos/files/0002-Fixing-mismatched-permission-on-dnsmasq-conf.patch b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0002-Fixing-mismatched-permission-on-dnsmasq-conf.patch new file mode 100644 index 000000000..40d422ea1 --- /dev/null +++ b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0002-Fixing-mismatched-permission-on-dnsmasq-conf.patch @@ -0,0 +1,27 @@ +From b8308a495f853d066c5c0e5d2257a070b033f626 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Tue, 5 Jul 2016 16:46:28 -0400 +Subject: [PATCH] CGTS-4280: Fixing mismatched permission on dnsmasq.conf which + was set to 0640 when created from config_controller (controller-0) but was at + 0644 on controller-1 through application of this manifest. + +--- + packstack/puppet/modules/dnsmasq/manifests/params.pp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/packstack/puppet/modules/dnsmasq/manifests/params.pp b/packstack/puppet/modules/dnsmasq/manifests/params.pp +index 6dd5b96..6129b57 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/params.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/params.pp +@@ -51,7 +51,7 @@ class dnsmasq::params { + } + + $config_file_mode = $::operatingsystem ? { +- default => '0644', ++ default => '0640', + } + + $config_file_owner = $::operatingsystem ? { +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-dnsmasq/centos/files/0003-Support-management-of-tftp_max-option.patch b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0003-Support-management-of-tftp_max-option.patch new file mode 100644 index 000000000..08341e813 --- /dev/null +++ b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0003-Support-management-of-tftp_max-option.patch @@ -0,0 +1,62 @@ +From 017e2ed0c664fb8689f6a9c4352db740c2c39725 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Thu, 15 Sep 2016 16:49:48 -0400 +Subject: [PATCH] Support management of tftp_max option + +--- + packstack/puppet/modules/dnsmasq/manifests/init.pp | 4 ++++ + packstack/puppet/modules/dnsmasq/manifests/params.pp | 1 + + packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb | 3 +++ + 3 files changed, 8 insertions(+) + +diff --git a/packstack/puppet/modules/dnsmasq/manifests/init.pp b/packstack/puppet/modules/dnsmasq/manifests/init.pp +index c61fd94..b66ac17 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/init.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/init.pp +@@ -328,6 +328,9 @@ + # Enable dnsmasq's built-in TFTP server + # Default: false + # ++# [*tftp_max*] ++# Max tftp connections ++# + # [*tftp_secure*] + # Make the TFTP server more secure: with this set, only files owned by + # the user dnsmasq is running as will be send over the net. +@@ -476,6 +479,7 @@ class dnsmasq ( + $pxe_prompt_timeout = params_lookup( 'pxe_prompt_timeout' ), + $pxe_service = params_lookup( 'pxe_service' ), + $enable_tftp = params_lookup( 'enable_tftp' ), ++ $tftp_max = params_lookup( 'tftp_max' ), + $tftp_secure = params_lookup( 'tftp_secure' ), + $tftp_root = params_lookup( 'tftp_root' ), + $dhcp_lease_max = params_lookup( 'dhcp_lease_max' ), +diff --git a/packstack/puppet/modules/dnsmasq/manifests/params.pp b/packstack/puppet/modules/dnsmasq/manifests/params.pp +index 6129b57..845e91e 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/params.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/params.pp +@@ -103,6 +103,7 @@ class dnsmasq::params { + $pxe_prompt_timeout = '60' + $pxe_service = '' + $enable_tftp = false ++ $tftp_max = '' + $tftp_secure = false + $tftp_root = '' + $dhcp_lease_max = '' +diff --git a/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb b/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb +index ea5aa01..6a6cbdf 100644 +--- a/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb ++++ b/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb +@@ -60,6 +60,9 @@ pxe-service=<%= scope.lookupvar('dnsmasq::pxe_service') %> + <% if scope.lookupvar('dnsmasq::bool_enable_tftp') -%> + enable-tftp + <% end -%> ++<% if scope.lookupvar('dnsmasq::tftp_max') != '' -%> ++tftp-max=<%= scope.lookupvar('dnsmasq::tftp_max') %> ++<% end -%> + <% if scope.lookupvar('dnsmasq::bool_tftp_secure') -%> + tftp-secure + <% end -%> +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-dnsmasq/centos/files/0004-Enable-clear-DNS-cache-on-reload.patch b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0004-Enable-clear-DNS-cache-on-reload.patch new file mode 100644 index 000000000..65b677108 --- /dev/null +++ b/devtools/puppet-modules/puppet-dnsmasq/centos/files/0004-Enable-clear-DNS-cache-on-reload.patch @@ -0,0 +1,72 @@ +From 35fa3c673307db2ebed20c952817608fadd26fa6 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Thu, 22 Jun 2017 16:33:29 -0400 +Subject: [PATCH 1/1] Enable clear the DNS cache on reload + +--- + packstack/puppet/modules/dnsmasq/manifests/init.pp | 7 +++++++ + packstack/puppet/modules/dnsmasq/manifests/params.pp | 1 + + packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb | 3 +++ + 3 files changed, 11 insertions(+) + +diff --git a/packstack/puppet/modules/dnsmasq/manifests/init.pp b/packstack/puppet/modules/dnsmasq/manifests/init.pp +index b66ac17..93276bb 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/init.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/init.pp +@@ -211,6 +211,11 @@ + # bringing up the link unnecessarily. + # Default: true + # ++# [*clear_on_reload*] ++# Whenever /etc/resolv.conf is re-read or the upstream servers are set via ++# DBus, clear the DNS cache. ++# Default: true ++# + # [*filterwin2k*] + # Uncomment this to filter useless windows-originated DNS requests + # which can trigger dial-on-demand links needlessly. +@@ -460,6 +465,7 @@ class dnsmasq ( + $protocol = params_lookup( 'protocol' ), + $domain_needed = params_lookup( 'domain_needed' ), + $bogus_priv = params_lookup( 'bogus_priv' ), ++ $clear_on_reload = params_lookup( 'clear_on_reload' ), + $filterwin2k = params_lookup( 'filterwin2k' ), + $resolv_file = params_lookup( 'resolv_file' ), + $strict_order = params_lookup( 'strict_order' ), +@@ -531,6 +537,7 @@ class dnsmasq ( + + $bool_domain_needed=any2bool($domain_needed) + $bool_bogus_priv=any2bool($bogus_priv) ++ $bool_clear_on_reload=any2bool($clear_on_reload) + $bool_filterwin2k=any2bool($filterwin2k) + $bool_strict_order=any2bool($strict_order) + $bool_no_resolv=any2bool($no_resolv) +diff --git a/packstack/puppet/modules/dnsmasq/manifests/params.pp b/packstack/puppet/modules/dnsmasq/manifests/params.pp +index 845e91e..4d8e70a 100644 +--- a/packstack/puppet/modules/dnsmasq/manifests/params.pp ++++ b/packstack/puppet/modules/dnsmasq/manifests/params.pp +@@ -84,6 +84,7 @@ class dnsmasq::params { + + $domain_needed = true + $bogus_priv = true ++ $clear_on_reload = true + $filterwin2k = false + $resolv_file = '' + $strict_order = false +diff --git a/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb b/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb +index bb8d941..109b768 100644 +--- a/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb ++++ b/packstack/puppet/modules/dnsmasq/templates/dnsmasq.conf.erb +@@ -9,6 +9,9 @@ bogus-priv + <% if scope.lookupvar('dnsmasq::bool_domain_needed') -%> + domain-needed + <% end -%> ++<% if scope.lookupvar('dnsmasq::bool_clear_on_reload') -%> ++clear-on-reload ++<% end -%> + <% if scope.lookupvar('dnsmasq::bool_filterwin2k') -%> + filterwin2k + <% end -%> +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-dnsmasq/centos/puppet-dnsmasq.spec b/devtools/puppet-modules/puppet-dnsmasq/centos/puppet-dnsmasq.spec new file mode 100644 index 000000000..fc1b2e414 --- /dev/null +++ b/devtools/puppet-modules/puppet-dnsmasq/centos/puppet-dnsmasq.spec @@ -0,0 +1,43 @@ +%global git_sha cff07e90890662972c97684a2baee964f68ff3ed +%global module_dir dnsmasq + +Name: puppet-dnsmasq +Version: 1.1.0 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet dnsmasq module +License: Apache + +URL: github.com/netmanagers/puppet-dnsmasq + +Source0: %{name}-%{git_sha}.tar.gz + +Patch0: 0001-puppet-dnsmasq-Kilo-quilt-patches.patch +Patch1: 0002-Fixing-mismatched-permission-on-dnsmasq-conf.patch +Patch2: 0003-Support-management-of-tftp_max-option.patch +Patch3: 0004-Enable-clear-DNS-cache-on-reload.patch + +BuildArch: noarch + +BuildRequires: python2-devel + +Requires: puppet-concat +Requires: puppet-puppi + +%description +A Puppet module for dnsmasq + +%prep +%setup -c %{module_dir} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R packstack/puppet/modules/%{module_dir} %{buildroot}/%{_datadir}/puppet/modules + +%files +#%license packstack/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/build_srpm.data b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/build_srpm.data new file mode 100644 index 000000000..520a2f7fd --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/build_srpm.data @@ -0,0 +1,12 @@ +PREFIX=puppetlabs +MODULE=drbd +VERSION=0.3.1 + +GIT_SHA=496b3ba9cd74a2d12636f9e90a718739a5451169 + +#DRBD has quilt patches (stored as git patches) +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=9 diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0001-TIS-Patches.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0001-TIS-Patches.patch new file mode 100644 index 000000000..a27d0f353 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0001-TIS-Patches.patch @@ -0,0 +1,377 @@ +From 95c0ec5cb26efbe2c5dbf45df21518d8d1776be0 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Wed, 4 Jan 2017 12:15:53 -0500 +Subject: [PATCH] TIS Patches + +This patch rolls up the previous TIS patches, which includes: +1. CGTS-4787 Set DRBD service ensure parameter + +2. Updates to fix DRBD resync-rate and engineered parameters: + +There are several DRBD performance related parameters that must be set to +get reasonable resync performance, otherwise default resync throughput +is limited to 40MB/s. Note that user community has noted this limit +when they use default settings, or up-rev DRBD from 8.3, etc. Eg. they +realize they hit this limit despite having 10G link or better and faster +disks. + +The following parameters were added to puppet-drbd module for resource +file generation, in addition to: c-plan-ahead, c-fill-target, c-min-rate, +c-max-rate, currently engineered for dynamic resync-rates. + +disk section: +- 'resync-rate' (aka 'rate') was missed in the CentOS port from Kilo +- 'al-extents' set to 3389, set to a prime number. Increasing this improves + random write throughput. Could set a bit higher, but would need a study. + +net section: +- 'max-buffers' engineered to scale with supported MBps, setting too low + (eg., default setting) is a bottleneck on 10G link. Set this to + maximum settable value of 20000. Note this parm may be settable to + larger values in more current DRBD rev. If we need to support faster + disks, likely need to increase this proportionately. +- 'max-epoch-size' also set to 20000. DRBD tuning recommendation page + sets this the same as max-buffers. +- 'unplug-watermark' set to 16 based on DRBD tuning recommendations page +- 'sndbuf-size' set to 0 to auto-tune; historically default was too small +- 'rcvbuf-size' set to 0 to auto-tune +--- + manifests/init.pp | 11 ++-- + manifests/resource.pp | 93 +++++++++++++++++++++++++--- + manifests/resource/up.pp | 2 +- + manifests/service.pp | 2 +- + templates/header.res.erb | 53 ++++++++++++++-- + templates/primary-resource.res.erb | 2 +- + templates/primary-stacked-resource.res.erb | 2 +- + templates/resource.res.erb | 2 +- + templates/secondary-resource.res.erb | 2 +- + templates/secondary-stacked-resource.res.erb | 2 +- + 10 files changed, 148 insertions(+), 23 deletions(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 09f7d48..76ce9c9 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -6,7 +6,8 @@ + # + class drbd( + $service_enable = true, +- $package_name = 'drbd8-utils', ++ $service_ensure = 'running', ++ $package_name = 'drbd-utils', + ) { + include ::drbd::service + +@@ -22,7 +23,7 @@ class drbd( + } + + File { +- mode => '0644', ++ mode => '0640', + owner => 'root', + group => 'root', + require => Package['drbd'], +@@ -45,8 +46,10 @@ class drbd( + # only allow files managed by puppet in this directory. + file { '/etc/drbd.d': + ensure => directory, +- mode => '0644', +- purge => true, ++ mode => '0640', ++ # Set purge to false so that it does not clear the dir ++ # when the 2nd drbd resource is added. ++ purge => false, + recurse => true, + force => true, + require => Package['drbd'], +diff --git a/manifests/resource.pp b/manifests/resource.pp +index af2ff77..10edc1a 100644 +--- a/manifests/resource.pp ++++ b/manifests/resource.pp +@@ -22,6 +22,10 @@ + # [ha_primary] If the resource is being applied on the primary host. + # [initial_setup] If this run is associated with the initial setup. Allows a user + # to only perform dangerous setup on the initial run. ++# [link_util] replication link network utilization percent ++# [link_speed] replication link network speed mbps ++# [num_parallel] number of parallel drbd filesystems to sync ++# [rtt_ms] round-trip-time milliseconds (i.e., ping between replication nodes) + define drbd::resource ( + $host1 = undef, + $host2 = undef, +@@ -39,7 +43,10 @@ define drbd::resource ( + $group = 'root', + $protocol = 'C', + $verify_alg = 'crc32c', +- $rate = false, ++ $link_util = false, ++ $link_speed = false, ++ $num_parallel = false, ++ $rtt_ms = false, + $net_parameters = false, + $manage = true, + $ha_primary = false, +@@ -47,6 +54,7 @@ define drbd::resource ( + $fs_type = 'ext4', + $mkfs_opts = '', + $disk = undef, ++ $handlers = false, + ) { + include ::drbd + +@@ -67,6 +75,75 @@ define drbd::resource ( + group => $group, + } + ++ if $link_util and $link_speed and $num_parallel and $rtt_ms { ++ # Engineer drbd variable sync rate parameters based on the following: ++ # https://blogs.linbit.com/p/128/drbd-sync-rate-controller/ ++ # https://blogs.linbit.com/p/443/drbd-sync-rate-controller-2/ ++ # Methodology adapted to account for replication link speed and parallelism. ++ ++ # Since there is no aggregate bandwidth control, prorate the drbd ++ # replication bandwidth based on parallelism. ++ # Based on experimentation, it seems generally better to set num_parallel ++ # to 1 and let DRBD auto-regulate its throughput. The end result is that ++ # multiple competing filesystems (i.e., on same disk device) already have ++ # their sync throughput reduced. ++ $mbps = $link_speed / $num_parallel ++ ++ # bandwidth delay product ++ $bdp_k = $mbps * $rtt_ms ++ ++ # engineer initial sync rate as percent of link bandwidth ++ $rate_M = floor($link_util * $mbps / 8 / 100) ++ $rate = "${rate_M}M" ++ ++ # engineer c_plan_ahead to default value (tenths) ++ # Documentation indicates this value OK even for 200 ms RTT. ++ $c_plan_ahead = 20 ++ ++ # engineer c_fill_target as 1*BDP (tune within 1x to 3x BDP; ++ # choose minimum value that saturates bandwidth) ++ $fill_target_k = floor(1 * $bdp_k) ++ $c_fill_target = "${fill_target_k}k" ++ ++ # engineer c_min_rate -- experimentally determined so DRBD is not ++ # throttled to a crawl even when there is minimal application IO. ++ # DRBD default is way too small. ++ $min_rate_M = 15 + floor($link_util * $mbps / 8 / 100 / 25) ++ $c_min_rate = "${min_rate_M}M" ++ ++ # engineer c_max_rate as percent of link bandwidth ++ $max_rate_M = floor($link_util * $mbps / 8 / 100) ++ $c_max_rate = "${max_rate_M}M" ++ ++ # various tuning settings to enable larger link bandwidth (eg, 10G) ++ # max_buffers should scale with MBps; set to maximum settable ++ $max_buffers = 20000 ++ $max_epoch_size = 20000 ++ $unplug_watermark = 16 ++ # sndbuf_size and rcvbuf_size should scale with mbps; set 0 to auto-tune ++ $sndbuf_size = 0 ++ $rcvbuf_size = 0 ++ # increase al_extents to improve random write throughput; set to prime number ++ $al_extents = 3389 ++ } else { ++ # disable variable sync rate ++ $c_plan_ahead = 0 ++ $c_fill_target = false ++ $c_min_rate = false ++ $c_max_rate = false ++ ++ # engineer fixed sync rate at 40 percent of 1G ++ $rate_M = floor(40 * 1000 / 8 / 100) ++ $rate = "${rate_M}M" ++ ++ $max_buffers = false ++ $max_epoch_size = false ++ $unplug_watermark = false ++ $sndbuf_size = false ++ $rcvbuf_size = false ++ $al_extents = false ++ } ++ + concat { "/etc/drbd.d/${name}.res": + mode => '0600', + require => [ +@@ -94,13 +171,13 @@ define drbd::resource ( + } + # Export our fragment for the clustered node + if $ha_primary and $cluster { +- @@concat::fragment { "${name} ${cluster} primary resource": ++ concat::fragment { "${name} ${cluster} primary resource": + target => "/etc/drbd.d/${name}.res", + content => template('drbd/resource.res.erb'), + order => '10', + } + } elsif $cluster { +- @@concat::fragment { "${name} ${cluster} secondary resource": ++ concat::fragment { "${name} ${cluster} secondary resource": + target => "/etc/drbd.d/${name}.res", + content => template('drbd/resource.res.erb'), + order => '20', +@@ -137,11 +214,11 @@ define drbd::resource ( + order => '99', + } + +- if $cluster { +- # Import cluster nodes +- Concat::Fragment <<| title == "${name} ${cluster} primary resource" |>> +- Concat::Fragment <<| title == "${name} ${cluster} secondary resource" |>> +- } ++# if $cluster { ++# # Import cluster nodes ++# Concat::Fragment <<| title == "${name} ${cluster} primary resource" |>> ++# Concat::Fragment <<| title == "${name} ${cluster} secondary resource" |>> ++# } + + # Due to a bug in puppet, defined() conditionals must be in a defined + # resource to be evaluated *after* the collector instead of before. +diff --git a/manifests/resource/up.pp b/manifests/resource/up.pp +index 7668792..b626f55 100644 +--- a/manifests/resource/up.pp ++++ b/manifests/resource/up.pp +@@ -70,7 +70,7 @@ define drbd::resource::up ( + # ensure that the device is mounted + mount { $mountpoint: + ensure => mounted, +- atboot => false, ++ atboot => yes, + device => $device, + fstype => 'auto', + options => 'defaults,noauto', +diff --git a/manifests/service.pp b/manifests/service.pp +index de56b34..f9b217a 100644 +--- a/manifests/service.pp ++++ b/manifests/service.pp +@@ -1,6 +1,6 @@ + class drbd::service { + @service { 'drbd': +- ensure => running, ++ ensure => $drbd::service_ensure, + enable => $drbd::service_enable, + require => Package['drbd'], + restart => 'service drbd reload', +diff --git a/templates/header.res.erb b/templates/header.res.erb +index 2d785c4..a3256a3 100644 +--- a/templates/header.res.erb ++++ b/templates/header.res.erb +@@ -5,7 +5,32 @@ resource <%= @name %> { + disk <%= @disk %>; + meta-disk internal; + ++ disk { ++<% if @rate -%> ++ resync-rate <%= @rate %>; ++<% end -%> ++<% if @c_plan_ahead -%> ++ c-plan-ahead <%= @c_plan_ahead %>; ++<% end -%> ++<% if @c_fill_target -%> ++ c-fill-target <%= @c_fill_target %>; ++<% end -%> ++<% if @c_min_rate -%> ++ c-min-rate <%= @c_min_rate %>; ++<% end -%> ++<% if @c_max_rate -%> ++ c-max-rate <%= @c_max_rate %>; ++<% end -%> ++<% if @al_extents -%> ++ al-extents <%= @al_extents %>; ++<% end -%> ++ } ++ + net { ++ after-sb-0pri discard-zero-changes; ++ after-sb-1pri discard-secondary; ++ after-sb-2pri disconnect; ++ + cram-hmac-alg sha1; + <% if @secret -%> + shared-secret "<%= @secret %>"; +@@ -16,12 +41,32 @@ resource <%= @name %> { + <%= k %> <%= v %>; + <% end -%> + <% end -%> +- } + +- syncer { ++<% if @max_buffers -%> ++ max-buffers <%= @max_buffers %>; ++<% end -%> ++<% if @max_epoch_size -%> ++ max-epoch-size <%= @max_epoch_size %>; ++<% end -%> ++<% if @unplug_watermark -%> ++ unplug-watermark <%= @unplug_watermark %>; ++<% end -%> ++<% if @sndbuf_size -%> ++ sndbuf-size <%= @sndbuf_size %>; ++<% end -%> ++<% if @rcvbuf_size -%> ++ rcvbuf-size <%= @rcvbuf_size %>; ++<% end -%> ++<% if @verify_alg -%> + verify-alg <%= @verify_alg %>; +-<% if @rate -%> +- rate <%= @rate %>; + <% end -%> + } + ++<% if @handlers -%> ++ handlers { ++<% @handlers.sort_by {|k, v| k}.each do |k, v| -%> ++ <%= k %> "<%= v %>"; ++<% end -%> ++ } ++<% end -%> ++ +diff --git a/templates/primary-resource.res.erb b/templates/primary-resource.res.erb +index f8af77e..6032fd2 100644 +--- a/templates/primary-resource.res.erb ++++ b/templates/primary-resource.res.erb +@@ -1,3 +1,3 @@ + on <%= @host1 %> { +- address <%= @ip1 %>:<%= @port %>; ++ address <%= IPAddr.new(@ip1).ipv6?() ? "ipv6 ["+@ip1+"]:"+@port : "ipv4 "+@ip1+":"+@port %>; + } +diff --git a/templates/primary-stacked-resource.res.erb b/templates/primary-stacked-resource.res.erb +index 7eb4dad..a22d8b3 100644 +--- a/templates/primary-stacked-resource.res.erb ++++ b/templates/primary-stacked-resource.res.erb +@@ -1,3 +1,3 @@ + stacked-on-top-of <%= @res1 %> { +- address <%= @ip1 %>:<%= @port %>; ++ address <%= IPAddr.new(ip1).ipv6?() ? "ipv6 ["+ip1+"]:"+port : "ipv4 "+ip1+":"+port %>; + } +diff --git a/templates/resource.res.erb b/templates/resource.res.erb +index 047877e..9dd4c4d 100644 +--- a/templates/resource.res.erb ++++ b/templates/resource.res.erb +@@ -1,3 +1,3 @@ + on <%= @hostname %> { +- address <%= @ipaddress %>:<%= @port %>; ++ address <%= IPAddr.new(ipaddress).ipv6?() ? "ipv6 ["+ipaddress+"]:"+@port : "ipv4 "+ipaddress+":"+port %>; + } +diff --git a/templates/secondary-resource.res.erb b/templates/secondary-resource.res.erb +index 678640a..cf2fd96 100644 +--- a/templates/secondary-resource.res.erb ++++ b/templates/secondary-resource.res.erb +@@ -1,3 +1,3 @@ + on <%= @host2 %> { +- address <%= @ip2 %>:<%= @port %>; ++ address <%= IPAddr.new(@ip2).ipv6?() ? "ipv6 ["+@ip2+"]:"+@port : "ipv4 "+@ip2+":"+@port %>; + } +diff --git a/templates/secondary-stacked-resource.res.erb b/templates/secondary-stacked-resource.res.erb +index 409a705..87d28f5 100644 +--- a/templates/secondary-stacked-resource.res.erb ++++ b/templates/secondary-stacked-resource.res.erb +@@ -1,3 +1,3 @@ + stacked-on-top-of <%= @res2 %> { +- address <%= @ip2 %>:<%= @port %>; ++ address <%= IPAddr.new(ip2).ipv6?() ? "ipv6 ["+ip2+"]:"+port : "ipv4 "+ip2+":"+port %>; + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0002-Disable-timeout-for-mkfs-command.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0002-Disable-timeout-for-mkfs-command.patch new file mode 100644 index 000000000..e578dbed3 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0002-Disable-timeout-for-mkfs-command.patch @@ -0,0 +1,24 @@ +From 0c36ecaef39328e85f41ebe8164dc7da5949542a Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 11 Apr 2017 11:14:25 -0400 +Subject: [PATCH] Disable timeout for mkfs command + +--- + manifests/resource/up.pp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/manifests/resource/up.pp b/manifests/resource/up.pp +index b626f55..f9de8ab 100644 +--- a/manifests/resource/up.pp ++++ b/manifests/resource/up.pp +@@ -54,6 +54,7 @@ define drbd::resource::up ( + } + exec { "drbd_format_volume_${name}": + command => "mkfs.${fs_type} ${mkfs_opts} ${device}", ++ timeout => 0, + refreshonly => true, + require => Exec["drbd_make_primary_${name}"], + before => $before, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0003-drbd-parallel-to-serial-synchronization.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0003-drbd-parallel-to-serial-synchronization.patch new file mode 100644 index 000000000..49ad45a96 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0003-drbd-parallel-to-serial-synchronization.patch @@ -0,0 +1,39 @@ +From a1186e3f68a338c575acdcf5cf41728a1b9ba2c1 Mon Sep 17 00:00:00 2001 +From: Angie Wang +Date: Mon, 29 May 2017 10:20:13 -0400 +Subject: [PATCH 1/1] drbd-parallel-to-serial-synchronization + +--- + manifests/resource.pp | 1 + + templates/header.res.erb | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/manifests/resource.pp b/manifests/resource.pp +index 10edc1a..d19ad8b 100644 +--- a/manifests/resource.pp ++++ b/manifests/resource.pp +@@ -47,6 +47,7 @@ define drbd::resource ( + $link_speed = false, + $num_parallel = false, + $rtt_ms = false, ++ $resync_after = undef, + $net_parameters = false, + $manage = true, + $ha_primary = false, +diff --git a/templates/header.res.erb b/templates/header.res.erb +index a3256a3..be53761 100644 +--- a/templates/header.res.erb ++++ b/templates/header.res.erb +@@ -9,6 +9,9 @@ resource <%= @name %> { + <% if @rate -%> + resync-rate <%= @rate %>; + <% end -%> ++<% if @resync_after -%> ++ resync-after <%= @resync_after %>; ++<% end -%> + <% if @c_plan_ahead -%> + c-plan-ahead <%= @c_plan_ahead %>; + <% end -%> +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0004-US-96914-reuse-existing-drbd-cinder-resource.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0004-US-96914-reuse-existing-drbd-cinder-resource.patch new file mode 100644 index 000000000..017387d21 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0004-US-96914-reuse-existing-drbd-cinder-resource.patch @@ -0,0 +1,53 @@ +From 132fc324c633ee95ca9ac8d00fb27fe5c4df6a3a Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Tue, 30 May 2017 21:52:52 +0000 +Subject: [PATCH] US-96914 reuse existing drbd-cinder resource + +Trying to initialize and enable DRBD resource fails in "drbdadm +create-md" when the disk already contains meta data. In this case +"drbdadm adjust" should be called. +--- + manifests/resource/up.pp | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/manifests/resource/up.pp b/manifests/resource/up.pp +index f9de8ab..160c8c2 100644 +--- a/manifests/resource/up.pp ++++ b/manifests/resource/up.pp +@@ -14,7 +14,7 @@ define drbd::resource::up ( + exec { "initialize DRBD metadata for ${name}": + command => "yes yes | drbdadm create-md ${name}", + onlyif => "test -e ${disk}", +- unless => "drbdadm dump-md ${name} || (drbdadm cstate ${name} | egrep -q '^(Sync|Connected|WFConnection|StandAlone|Verify)')", ++ unless => "drbdadm dump-md ${name} || (drbdadm cstate ${name} | egrep -q '^(Sync|Connected|WFConnection|StandAlone|Verify)') || (drbdadm show-gi ${name} | grep 'meta-data: need apply-al')", + before => Service['drbd'], + require => [ + Exec['modprobe drbd'], +@@ -26,6 +26,7 @@ define drbd::resource::up ( + exec { "enable DRBD resource ${name}": + command => "drbdadm up ${name}", + onlyif => "drbdadm dstate ${name} | egrep -q '^(Diskless/|Unconfigured|Consistent)'", ++ unless => "drbdadm show-gi ${name} | grep 'meta-data: need apply-al'", + before => Service['drbd'], + require => [ + Exec["initialize DRBD metadata for ${name}"], +@@ -34,6 +35,16 @@ define drbd::resource::up ( + notify => Service['drbd'], + } + ++ exec { "reuse existing DRBD resoure ${name}": ++ command => "drbdadm adjust ${name}", ++ onlyif => "test -e ${disk} && (drbdadm show-gi ${name} | grep 'meta-data: need apply-al')", ++ before => Service['drbd'], ++ require => [ ++ Exec['modprobe drbd'], ++ Concat["/etc/drbd.d/${name}.res"], ++ ], ++ notify => Service['drbd'], ++ } + + # these resources should only be applied if we are configuring the + # primary node in our HA setup +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0005-Add-PausedSync-states-to-acceptable-cstate.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0005-Add-PausedSync-states-to-acceptable-cstate.patch new file mode 100644 index 000000000..453d46a10 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0005-Add-PausedSync-states-to-acceptable-cstate.patch @@ -0,0 +1,26 @@ +From b575f4c50e8726c5f9b3227b37a4517c0bbde85c Mon Sep 17 00:00:00 2001 +From: Robert Church +Date: Fri, 2 Jun 2017 02:15:19 +0000 +Subject: [PATCH] Add PausedSync states to acceptable cstate to avoid metdata + creation + +--- + manifests/resource/up.pp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/manifests/resource/up.pp b/manifests/resource/up.pp +index 160c8c2..3e2fdac 100644 +--- a/manifests/resource/up.pp ++++ b/manifests/resource/up.pp +@@ -14,7 +14,7 @@ define drbd::resource::up ( + exec { "initialize DRBD metadata for ${name}": + command => "yes yes | drbdadm create-md ${name}", + onlyif => "test -e ${disk}", +- unless => "drbdadm dump-md ${name} || (drbdadm cstate ${name} | egrep -q '^(Sync|Connected|WFConnection|StandAlone|Verify)') || (drbdadm show-gi ${name} | grep 'meta-data: need apply-al')", ++ unless => "drbdadm dump-md ${name} || (drbdadm cstate ${name} | egrep -q '^(PausedSync|Sync|Connected|WFConnection|StandAlone|Verify)') || (drbdadm show-gi ${name} | grep 'meta-data: need apply-al')", + before => Service['drbd'], + require => [ + Exec['modprobe drbd'], +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0006-CGTS-7164-Add-resource-options-cpu-mask-to-affine-drbd-kernel-threads.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0006-CGTS-7164-Add-resource-options-cpu-mask-to-affine-drbd-kernel-threads.patch new file mode 100644 index 000000000..5c6aec170 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0006-CGTS-7164-Add-resource-options-cpu-mask-to-affine-drbd-kernel-threads.patch @@ -0,0 +1,68 @@ +From 0e264e7ac2b311aa9b42b183660a07b7e4e36b11 Mon Sep 17 00:00:00 2001 +From: Jim Gauld +Date: Fri, 9 Jun 2017 14:58:23 -0400 +Subject: [PATCH 1/1] CGTS-7164: Add resource options cpu-mask to affine drbd + kernel threads + +This adds "options { cpu-mask ; }" section to DRBD resource +configuration if 'cpumask' hexstring is defined. This governs kernel +threads: drbd_w_, drbd_r_, drbd_a_. + +Related notes: +- if cpumask is not specified, the kernel threads drbd_w_, drbd_r_, + drbd_a_, and drbd_as_ are affined to individual cores, each + on a different core. + +- the remainder of the kernel threads are governed by kernel boot + argument kthread_cpus=. i.e., drbd-reissue, drbd_submit, + jbd2/drbd-8, drbd_as_. + +- the drbd_a_ and drbd_as_ show up when DRBD is duplex. + +- the drbd_a_ threads have SCHED_RR scheduling policy. +--- + manifests/resource.pp | 3 +++ + templates/header.res.erb | 6 ++++++ + 2 files changed, 9 insertions(+) + +diff --git a/manifests/resource.pp b/manifests/resource.pp +index d19ad8b..17e6142 100644 +--- a/manifests/resource.pp ++++ b/manifests/resource.pp +@@ -26,6 +26,8 @@ + # [link_speed] replication link network speed mbps + # [num_parallel] number of parallel drbd filesystems to sync + # [rtt_ms] round-trip-time milliseconds (i.e., ping between replication nodes) ++# [cpumask] cpu-affinity-mask for DRBD kernel threads (hexidecimal notation). ++# 0 means spread over all CPUs of the machine. + define drbd::resource ( + $host1 = undef, + $host2 = undef, +@@ -48,6 +50,7 @@ define drbd::resource ( + $num_parallel = false, + $rtt_ms = false, + $resync_after = undef, ++ $cpumask = false, + $net_parameters = false, + $manage = true, + $ha_primary = false, +diff --git a/templates/header.res.erb b/templates/header.res.erb +index be53761..df52544 100644 +--- a/templates/header.res.erb ++++ b/templates/header.res.erb +@@ -29,6 +29,12 @@ resource <%= @name %> { + <% end -%> + } + ++<% if @cpumask -%> ++ options { ++ cpu-mask <%= @cpumask %>; ++ } ++<% end -%> ++ + net { + after-sb-0pri discard-zero-changes; + after-sb-1pri discard-secondary; +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0007-Add-disk-by-path-test.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0007-Add-disk-by-path-test.patch new file mode 100644 index 000000000..1eb12f5fd --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0007-Add-disk-by-path-test.patch @@ -0,0 +1,51 @@ +From 30ae8c86d9471980a0058823d6593e7548e19506 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Thu, 15 Jun 2017 17:34:30 -0400 +Subject: [PATCH] Add disk by-path test + +--- + manifests/resource/up.pp | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/manifests/resource/up.pp b/manifests/resource/up.pp +index 3e2fdac..ea379a8 100644 +--- a/manifests/resource/up.pp ++++ b/manifests/resource/up.pp +@@ -8,6 +8,17 @@ define drbd::resource::up ( + $mountpoint, + $automount, + ) { ++ ++ # Ensure disk by-path link exists ++ exec { "test disk by-path for ${name}": ++ command => "udevadm settle", ++ unless => "test -e ${disk}", ++ before => Service['drbd'], ++ require => [ ++ Exec['modprobe drbd'] ++ ], ++ } ++ + # create metadata on device, except if resource seems already initalized. + # drbd is very tenacious about asking for aproval if there is data on the + # volume already. +@@ -18,6 +29,7 @@ define drbd::resource::up ( + before => Service['drbd'], + require => [ + Exec['modprobe drbd'], ++ Exec["test disk by-path for ${name}"], + Concat["/etc/drbd.d/${name}.res"], + ], + notify => Service['drbd'], +@@ -35,7 +47,7 @@ define drbd::resource::up ( + notify => Service['drbd'], + } + +- exec { "reuse existing DRBD resoure ${name}": ++ exec { "reuse existing DRBD resource ${name}": + command => "drbdadm adjust ${name}", + onlyif => "test -e ${disk} && (drbdadm show-gi ${name} | grep 'meta-data: need apply-al')", + before => Service['drbd'], +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0008-CGTS-7953-support-for-new-drbd-resources.patch b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0008-CGTS-7953-support-for-new-drbd-resources.patch new file mode 100644 index 000000000..83067296a --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/files/0008-CGTS-7953-support-for-new-drbd-resources.patch @@ -0,0 +1,40 @@ +From a29598365183c10e4650088675a6e3181b340187 Mon Sep 17 00:00:00 2001 +From: Kristine Bujold +Date: Wed, 17 Jan 2018 18:18:15 -0500 +Subject: [PATCH 1/1] foo bar + +--- + manifests/init.pp | 2 ++ + templates/global_common.conf.erb | 5 +++++ + 2 files changed, 7 insertions(+) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 76ce9c9..5e6bdc0 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -8,6 +8,8 @@ class drbd( + $service_enable = true, + $service_ensure = 'running', + $package_name = 'drbd-utils', ++ $wfc_timeout = 0, ++ $degr_wfc_timeout = 0, + ) { + include ::drbd::service + +diff --git a/templates/global_common.conf.erb b/templates/global_common.conf.erb +index 921a637..0253ef3 100644 +--- a/templates/global_common.conf.erb ++++ b/templates/global_common.conf.erb +@@ -3,4 +3,9 @@ global { + } + common { + protocol C; ++ ++ startup { ++ wfc-timeout <%= @wfc_timeout %>; ++ degr-wfc-timeout <%= @degr_wfc_timeout %>; ++ } + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-drbd-0.3.1/centos/puppet-drbd.spec b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/puppet-drbd.spec new file mode 100644 index 000000000..8d2574731 --- /dev/null +++ b/devtools/puppet-modules/puppet-drbd-0.3.1/centos/puppet-drbd.spec @@ -0,0 +1,63 @@ +%global git_sha 496b3ba9cd74a2d12636f9e90a718739a5451169 +%global prefix puppetlabs +%global module_dir drbd + +Name: puppet-%{module_dir} +Version: 0.3.1 +Release: rc0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet %{module_dir} module +License: Apache + +URL: https://github.com/puppetlabs/puppetlabs-drbd + +Source0: %{prefix}-%{module_dir}-%{git_sha}.tar.gz + +Patch0001: 0001-TIS-Patches.patch +Patch0002: 0002-Disable-timeout-for-mkfs-command.patch +Patch0003: 0003-drbd-parallel-to-serial-synchronization.patch +Patch0004: 0004-US-96914-reuse-existing-drbd-cinder-resource.patch +Patch0005: 0005-Add-PausedSync-states-to-acceptable-cstate.patch +Patch0006: 0006-CGTS-7164-Add-resource-options-cpu-mask-to-affine-drbd-kernel-threads.patch +Patch0007: 0007-Add-disk-by-path-test.patch +Patch0008: 0008-CGTS-7953-support-for-new-drbd-resources.patch + +BuildArch: noarch + +BuildRequires: python2-devel + +# According to .fixtures.yml the following puppet modules are required +Requires: puppet-concat +Requires: puppet-stdlib + + +%description +A Puppet module for configuring drbd + +%prep +%setup -n puppetlabs-drbd + +find . -type f -name ".*" -exec rm {} + +find . -size 0 -exec rm {} + +find . \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} + +find . \( -name "*.pp" -o -name "*.py" \) -exec chmod -x {} + +find . \( -name "*.rb" -o -name "*.erb" \) -exec chmod -x {} + +find . \( -name spec -o -name ext \) | xargs rm -rf + +%patch0001 -p1 +%patch0002 -p1 +%patch0003 -p1 +%patch0004 -p1 +%patch0005 -p1 +%patch0006 -p1 +%patch0007 -p1 +%patch0008 -p1 + +%install +rm -rf %{buildroot} +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -rp * %{buildroot}/%{_datadir}/puppet/modules/%{module_dir}/ + +%files +%license %{_datadir}/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-filemapper/centos/build_srpm.data b/devtools/puppet-modules/puppet-filemapper/centos/build_srpm.data new file mode 100644 index 000000000..69ab8a223 --- /dev/null +++ b/devtools/puppet-modules/puppet-filemapper/centos/build_srpm.data @@ -0,0 +1,16 @@ +PREFIX=puppet +MODULE=filemapper +VERSION=1.1.3 + +GIT_SHA=9b53310278e76827bbe12a36cc6470d77071abb2 + +# Generic Copy routine +# Un-patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz" + +#Patched +#COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/puppet-filemapper/centos/puppet-filemapper.spec b/devtools/puppet-modules/puppet-filemapper/centos/puppet-filemapper.spec new file mode 100644 index 000000000..7becd5084 --- /dev/null +++ b/devtools/puppet-modules/puppet-filemapper/centos/puppet-filemapper.spec @@ -0,0 +1,31 @@ +%global git_sha 9b53310278e76827bbe12a36cc6470d77071abb2 +%global module_dir filemapper + +Name: puppet-filemapper +Version: 1.1.3 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet FileMapper module +License: Apache + +URL: https://github.com/voxpupuli/puppet-filemapper + +Source0: %{name}-%{git_sha}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +Puppet module to map files to resources and back + +%prep +%autosetup -c %{module_dir} + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R packstack/puppet/modules/%{module_dir} %{buildroot}/%{_datadir}/puppet/modules + +%files +%license packstack/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/build_srpm.data b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/build_srpm.data new file mode 100644 index 000000000..0eac83bbb --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=4 diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..bf72c73f5 --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 60166c6f060244ec2d1416d8a05d22fd6353424f Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 11:10:38 -0400 +Subject: [PATCH 1/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/puppet-haproxy.spec +--- + SPECS/puppet-haproxy.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-haproxy.spec b/SPECS/puppet-haproxy.spec +index 6944e73..a975f60 100644 +--- a/SPECS/puppet-haproxy.spec ++++ b/SPECS/puppet-haproxy.spec +@@ -8,7 +8,7 @@ + + Name: puppet-haproxy + Version: 1.5.0 +-Release: 2%{?alphatag}%{?dist} ++Release: 2.6ee8180git.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Configures HAProxy servers and manages the configuration of backend member servers. + License: Apache-2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0002-Add-TIS-patch.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0002-Add-TIS-patch.patch new file mode 100644 index 000000000..98a8119ed --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0002-Add-TIS-patch.patch @@ -0,0 +1,32 @@ +From 38e3d487daef2cfc9b820091cdb1290a8ffe0d2f Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 11:10:38 -0400 +Subject: [PATCH 2/2] WRS: 0002-Add-TIS-patch.patch + +--- + SPECS/puppet-haproxy.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-haproxy.spec b/SPECS/puppet-haproxy.spec +index a975f60..a843f00 100644 +--- a/SPECS/puppet-haproxy.spec ++++ b/SPECS/puppet-haproxy.spec +@@ -15,6 +15,7 @@ License: Apache-2.0 + URL: https://github.com/puppetlabs/puppetlabs-haproxy + + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch + + BuildArch: noarch + +@@ -27,6 +28,7 @@ Configures HAProxy servers and manages the configuration of backend member serve + + %prep + %setup -q -n %{upstream_name}-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0003-disable-config-validation-prechecks.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0003-disable-config-validation-prechecks.patch new file mode 100644 index 000000000..45843fcd7 --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0003-disable-config-validation-prechecks.patch @@ -0,0 +1,32 @@ +From 8a01ac3f649282ade4c136a2c1cb1b8bbbab28de Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 26 May 2017 17:18:23 -0400 +Subject: [PATCH] 0003-disable-config-validation-prechecks + +--- + SPECS/puppet-haproxy.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-haproxy.spec b/SPECS/puppet-haproxy.spec +index a843f00..a0a9be1 100644 +--- a/SPECS/puppet-haproxy.spec ++++ b/SPECS/puppet-haproxy.spec +@@ -16,6 +16,7 @@ URL: https://github.com/puppetlabs/puppetlabs-haproxy + + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-disable-config-validation-prechecks.patch + + BuildArch: noarch + +@@ -29,6 +30,7 @@ Configures HAProxy servers and manages the configuration of backend member serve + %prep + %setup -q -n %{upstream_name}-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0004-Add-global_options-patch.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0004-Add-global_options-patch.patch new file mode 100644 index 000000000..003253db9 --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/0004-Add-global_options-patch.patch @@ -0,0 +1,32 @@ +From 62ba2a5aa0e9e254f65976a26f9b1b5751cddb47 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Sun, 24 Sep 2017 00:15:51 -0400 +Subject: [PATCH] Add global_options patch + +--- + SPECS/puppet-haproxy.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-haproxy.spec b/SPECS/puppet-haproxy.spec +index a0a9be1..a446384 100644 +--- a/SPECS/puppet-haproxy.spec ++++ b/SPECS/puppet-haproxy.spec +@@ -17,6 +17,7 @@ URL: https://github.com/puppetlabs/puppetlabs-haproxy + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-disable-config-validation-prechecks.patch ++Patch0003: 0003-Fix-global_options-log-default-value.patch + + BuildArch: noarch + +@@ -31,6 +32,7 @@ Configures HAProxy servers and manages the configuration of backend member serve + %setup -q -n %{upstream_name}-%{upstream_version} + %patch0001 -p1 + %patch0002 -p1 ++%patch0003 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..893476741 --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,4 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-patch.patch +0003-disable-config-validation-prechecks.patch +0004-Add-global_options-patch.patch diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..e2a87934d --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,43 @@ +From 4485b6cbf5a8bf1d3830b0406685aba3ece4e413 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Wed, 11 Jan 2017 13:05:12 -0500 +Subject: [PATCH] Roll up TIS patches + +--- + manifests/config.pp | 4 ++-- + manifests/init.pp | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/manifests/config.pp b/manifests/config.pp +index 781b6fa..785740d 100644 +--- a/manifests/config.pp ++++ b/manifests/config.pp +@@ -68,8 +68,8 @@ define haproxy::config ( + if $_global_options['chroot'] { + file { $_global_options['chroot']: + ensure => directory, +- owner => $_global_options['user'], +- group => $_global_options['group'], ++ owner => 'root', ++ group => 'root', + } + } + } +diff --git a/manifests/init.pp b/manifests/init.pp +index e2d3d92..b0369f7 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -101,8 +101,8 @@ + class haproxy ( + $package_ensure = 'present', + $package_name = $haproxy::params::package_name, +- $service_ensure = 'running', +- $service_manage = true, ++ $service_ensure = false, ++ $service_manage = false, + $service_options = $haproxy::params::service_options, + $sysconfig_options = $haproxy::params::sysconfig_options, + $global_options = $haproxy::params::global_options, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0002-disable-config-validation-prechecks.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0002-disable-config-validation-prechecks.patch new file mode 100644 index 000000000..0f99586c3 --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0002-disable-config-validation-prechecks.patch @@ -0,0 +1,30 @@ +From 73b4a43227e36aa32103e7d8a69bcb35678f7e6c Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 26 May 2017 17:04:32 -0400 +Subject: [PATCH] disable configuration validation during haproxy manifest + apply since some files/options referenced in the configuration (such as for + TPM) may still be in flight while the haproxy manifest applies. This + validation option is a bit of an overkill anyways since it doesn't cause + Packstack to fail the manifest application, and is a soft error log but with + the added disadvantage of not applying any haproxy configuration (even the + sane bits) on a validation failure + +--- + manifests/config.pp | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/manifests/config.pp b/manifests/config.pp +index 785740d..4d084fa 100644 +--- a/manifests/config.pp ++++ b/manifests/config.pp +@@ -47,7 +47,6 @@ define haproxy::config ( + owner => '0', + group => '0', + mode => '0644', +- validate_cmd => '/usr/sbin/haproxy -f % -c', + } + + # Simple Header +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0003-Fix-global_options-log-default-value.patch b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0003-Fix-global_options-log-default-value.patch new file mode 100644 index 000000000..44a6ec0cd --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/patches/0003-Fix-global_options-log-default-value.patch @@ -0,0 +1,25 @@ +From 872a041122b1e443e23a16e5816c3d8aa18714f8 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Sun, 24 Sep 2017 00:14:25 -0400 +Subject: [PATCH] Fix global_options log default value + +--- + manifests/params.pp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/manifests/params.pp b/manifests/params.pp +index 21e6bb0..b29e427 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -15,7 +15,7 @@ class haproxy::params { + 'Archlinux', 'Debian', 'Redhat', 'Gentoo', 'Suse' : { + $package_name = 'haproxy' + $global_options = { +- 'log' => "${::ipaddress} local0", ++ 'log' => 'global', + 'chroot' => '/var/lib/haproxy', + 'pidfile' => '/var/run/haproxy.pid', + 'maxconn' => '4000', +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/srpm_path b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/srpm_path new file mode 100644 index 000000000..c4e216add --- /dev/null +++ b/devtools/puppet-modules/puppet-haproxy-1.5.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-haproxy-1.5.0-2.6ee8180git.el7.src.rpm diff --git a/devtools/puppet-modules/puppet-ldap/centos/build_srpm.data b/devtools/puppet-modules/puppet-ldap/centos/build_srpm.data new file mode 100644 index 000000000..1bd3398fc --- /dev/null +++ b/devtools/puppet-modules/puppet-ldap/centos/build_srpm.data @@ -0,0 +1,9 @@ +PREFIX=puppet +MODULE=ldap +VERSION=0.2.4 + +GIT_SHA=480f13af6d17d1d3fcf0dc7b4bd04b49fa4099e1 + +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz" + +TIS_PATCH_VER=3 diff --git a/devtools/puppet-modules/puppet-ldap/centos/puppet-ldap.spec b/devtools/puppet-modules/puppet-ldap/centos/puppet-ldap.spec new file mode 100644 index 000000000..0c6e39e91 --- /dev/null +++ b/devtools/puppet-modules/puppet-ldap/centos/puppet-ldap.spec @@ -0,0 +1,30 @@ +%global git_sha 480f13af6d17d1d3fcf0dc7b4bd04b49fa4099e1 +%global module_dir ldap + +Name: puppet-ldap +Version: 0.2.4 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet LDAP module +License: GPLv2 + +URL: https://github.com/torian/puppet-ldap + +Source0: %{name}-%{git_sha}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A Puppet module to manage client and server configuration for OpenLdap + +%prep +%setup -n puppet-ldap-master + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R ../puppet-ldap-master/* %{buildroot}/%{_datadir}/puppet/modules/%{module_dir}/. + +%files +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-ldap/puppet_downloader.sh b/devtools/puppet-modules/puppet-ldap/puppet_downloader.sh new file mode 100755 index 000000000..5ce2e29fd --- /dev/null +++ b/devtools/puppet-modules/puppet-ldap/puppet_downloader.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +BRANCH="master" +repo="https://github.com/torian" +module="puppet-ldap" +git ls-remote $repo/$module $BRANCH +SHA=`git ls-remote $repo/$module $BRANCH | awk '{print $1}'` +echo $SHA +wget $repo/$module/archive/$BRANCH.tar.gz -O "$module"-"$SHA".tar.gz + + diff --git a/devtools/puppet-modules/puppet-lvm/centos/build_srpm.data b/devtools/puppet-modules/puppet-lvm/centos/build_srpm.data new file mode 100644 index 000000000..9bfbdd412 --- /dev/null +++ b/devtools/puppet-modules/puppet-lvm/centos/build_srpm.data @@ -0,0 +1,12 @@ +PREFIX=puppetlabs +MODULE=lvm +VERSION=0.5.0 + +GIT_SHA=d0283da637ae24550fb4ba109a48ef8d5d8c8b84 + +#Patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=4 diff --git a/devtools/puppet-modules/puppet-lvm/centos/files/0001-puppet-lvm-kilo-quilt-changes.patch b/devtools/puppet-modules/puppet-lvm/centos/files/0001-puppet-lvm-kilo-quilt-changes.patch new file mode 100644 index 000000000..eaaa9a169 --- /dev/null +++ b/devtools/puppet-modules/puppet-lvm/centos/files/0001-puppet-lvm-kilo-quilt-changes.patch @@ -0,0 +1,694 @@ +From b80e106ace391d88de683c3da5e03878ce1ffa1d Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 7 Jun 2016 10:36:17 -0400 +Subject: [PATCH] puppet-lvm kilo quilt changes + +--- + .../lvm/lib/puppet/provider/logical_volume/lvm.rb | 194 ++++++++++++++------- + .../lvm/lib/puppet/provider/physical_volume/lvm.rb | 2 +- + .../lvm/lib/puppet/provider/volume_group/lvm.rb | 60 ++++++- + .../modules/lvm/lib/puppet/type/logical_volume.rb | 32 +++- + .../puppet/modules/lvm/manifests/logical_volume.pp | 6 + + packstack/puppet/modules/lvm/manifests/volume.pp | 11 +- + .../puppet/provider/logical_volume/lvm_spec.rb | 55 +++--- + 7 files changed, 267 insertions(+), 93 deletions(-) + +diff --git a/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb b/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb +index e813193..2f41695 100755 +--- a/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb +@@ -3,24 +3,56 @@ Puppet::Type.type(:logical_volume).provide :lvm do + + commands :lvcreate => 'lvcreate', + :lvremove => 'lvremove', ++ :lvresize => 'lvresize', + :lvextend => 'lvextend', + :lvs => 'lvs', +- :resize2fs => 'resize2fs', ++ :vgs => 'vgs', + :umount => 'umount', + :blkid => 'blkid', + :dmsetup => 'dmsetup', ++ :dd => 'dd', + :lvconvert => 'lvconvert', +- :lvdisplay => 'lvdisplay' +- +- optional_commands :xfs_growfs => 'xfs_growfs', +- :resize4fs => 'resize4fs' ++ :lvdisplay => 'lvdisplay', ++ :fsadm => 'fsadm', ++ :dd => 'dd' ++ ++ def round_to_extent(size) ++ lvm_size_units = { ++ "K" => 1**0, "M" => 1024**1, "G" => 1024**2, "T" => 1024**3, "P" => 1024**4, "E" => 1025**5, ++ } ++ ++ if @resource[:size] =~ /^([0-9]+(\.[0-9]+)?)([KMGTPE])/i ++ size_value = $1.to_f ++ size_unit = $3.upcase ++ size_kibi = (size_value * lvm_size_units[size_unit]).to_i ++ if vgs('--noheading', '-o', 'vg_extent_size', '--units', 'k', "#{@resource[:volume_group]}") =~ /\s+(\d+)\.\d+k/i ++ vg_extent_size_kibi = $1.to_i ++ end ++ new_size_kibi = ((size_kibi + vg_extent_size_kibi - 1) / vg_extent_size_kibi) * vg_extent_size_kibi ++ "#{new_size_kibi}k" ++ else ++ size ++ end ++ end + + def create + args = ['-n', @resource[:name]] + if @resource[:size] +- args.push('--size', @resource[:size]) ++ size = @resource[:size] ++ if size == 'max' ++ size = vgs('--noheading', '-o', 'vg_size', '--units', 'k', "#{@resource[:volume_group]}").strip ++ elsif @resource[:round_to_extent] then ++ size = round_to_extent(size) ++ end ++ args.push('--size', size) + elsif @resource[:initial_size] +- args.push('--size', @resource[:initial_size]) ++ args.push( ++ '--size', ++ if @resource[:round_to_extent] then ++ round_to_extent(@resource[:initial_size]) ++ else ++ @resource[:initial_size] ++ end) + end + if @resource[:extents] + args.push('--extents', @resource[:extents]) +@@ -63,6 +95,7 @@ Puppet::Type.type(:logical_volume).provide :lvm do + + args << @resource[:volume_group] + lvcreate(*args) ++ lvzero + end + + def destroy +@@ -75,9 +108,16 @@ Puppet::Type.type(:logical_volume).provide :lvm do + lvs(@resource[:volume_group]) =~ lvs_pattern + end + ++ def exec_cmd(*cmd) ++ output = Puppet::Util::Execution.execute(cmd, :failonfail => false, :combine => true) ++ {:out => output, :exit => $CHILD_STATUS.exitstatus} ++ end ++ + def size + if @resource[:size] =~ /^\d+\.?\d{0,2}([KMGTPE])/i + unit = $1.downcase ++ else ++ unit = 'k' + end + + raw = lvs('--noheading', '--unit', unit, path) +@@ -92,64 +132,87 @@ Puppet::Type.type(:logical_volume).provide :lvm do + end + + def size=(new_size) +- lvm_size_units = { "K" => 1, "M" => 1024, "G" => 1048576, "T" => 1073741824, "P" => 1099511627776, "E" => 1125899906842624 } +- lvm_size_units_match = lvm_size_units.keys().join('|') ++ lvm_size_units = { ++ "K" => 1**0, "M" => 1024**1, "G" => 1024**2, "T" => 1024**3, "P" => 1024**4, "E" => 1025**5, ++ } + +- resizeable = false +- current_size = size() ++ current_size = size() + +- if current_size =~ /(\d+\.{0,1}\d{0,2})(#{lvm_size_units_match})/i +- current_size_bytes = $1.to_i +- current_size_unit = $2.upcase +- end ++ if current_size =~ /^([0-9]+(\.[0-9]+)?)([KMGTPE])/i ++ current_size_value = $1.to_f ++ current_size_unit = $3.upcase ++ current_size = (current_size_value * lvm_size_units[current_size_unit]).to_i ++ end + +- if new_size =~ /(\d+)(#{lvm_size_units_match})/i +- new_size_bytes = $1.to_i +- new_size_unit = $2.upcase +- end ++ info( "Current: value=#{current_size_value}, unit=#{current_size_unit}, kibi=#{current_size}" ) + +- ## Get the extend size +- if lvs('--noheading', '-o', 'vg_extent_size', '--units', 'k', path) =~ /\s+(\d+)\.\d+k/i +- vg_extent_size = $1.to_i +- end ++ if new_size == 'max' ++ new_size = vgs('--noheading', '-o', 'vg_size', '--units', 'k', "#{@resource[:volume_group]}").strip ++ end + +- ## Verify that it's a extension: Reduce is potentially dangerous and should be done manually +- if lvm_size_units[current_size_unit] < lvm_size_units[new_size_unit] +- resizeable = true +- elsif lvm_size_units[current_size_unit] > lvm_size_units[new_size_unit] +- if (current_size_bytes * lvm_size_units[current_size_unit]) < (new_size_bytes * lvm_size_units[new_size_unit]) +- resizeable = true +- end +- elsif lvm_size_units[current_size_unit] == lvm_size_units[new_size_unit] +- if new_size_bytes > current_size_bytes +- resizeable = true +- end +- end ++ if new_size =~ /^([0-9]+(\.[0-9]+)?)([KMGTPE])/i ++ new_size_value = $1.to_f ++ new_size_unit = $3.upcase ++ new_size = (new_size_value * lvm_size_units[new_size_unit]).to_i ++ end + +- if not resizeable +- if @resource[:size_is_minsize] == :true or @resource[:size_is_minsize] == true or @resource[:size_is_minsize] == 'true' +- info( "Logical volume already has minimum size of #{new_size} (currently #{current_size})" ) +- else +- fail( "Decreasing the size requires manual intervention (#{new_size} < #{current_size})" ) +- end +- else +- ## Check if new size fits the extend blocks +- if new_size_bytes * lvm_size_units[new_size_unit] % vg_extent_size != 0 +- fail( "Cannot extend to size #{new_size} because VG extent size is #{vg_extent_size} KB" ) +- end ++ info( "New: value=#{new_size_value}, unit=#{new_size_unit}, kibi=#{new_size}" ) + +- lvextend( '-L', new_size, path) || fail( "Cannot extend to size #{new_size} because lvextend failed." ) ++ ## Get the extend size ++ if lvs('--noheading', '-o', 'vg_extent_size', '--units', 'k', path) =~ /\s+(\d+)\.\d+k/i ++ vg_extent_size = $1.to_i ++ end + +- blkid_type = blkid(path) +- if command(:resize4fs) and blkid_type =~ /\bTYPE=\"(ext4)\"/ +- resize4fs( path) || fail( "Cannot resize file system to size #{new_size} because resize2fs failed." ) +- elsif blkid_type =~ /\bTYPE=\"(ext[34])\"/ +- resize2fs( path) || fail( "Cannot resize file system to size #{new_size} because resize2fs failed." ) +- elsif blkid_type =~ /\bTYPE=\"(xfs)\"/ +- xfs_growfs( path) || fail( "Cannot resize filesystem to size #{new_size} because xfs_growfs failed." ) ++ if new_size < current_size ++ if @resource[:size_is_minsize] == :true or @resource[:size_is_minsize] == true or @resource[:size_is_minsize] == 'true' ++ info( "Logical volume already has minimum size of #{new_size} (currently #{current_size})" ) ++ else ++ if not @resource[:allow_reduce] ++ fail( "Decreasing the size requires manual intervention (#{new_size} < #{current_size})" ) ++ end ++ if new_size % vg_extent_size != 0 ++ if @resource[:round_to_extent] ++ new_size = ((new_size + vg_extent_size - 1) / vg_extent_size) * vg_extent_size ++ if new_size >= current_size ++ info( "Logical volume already has a size of #{current_size}" ) ++ return ++ end ++ else ++ fail( "Cannot reduce to size #{new_size} because VG extent size is #{vg_extent_size} KB" ) + end +- ++ end ++ exec_cmd('umount', path) ++ exec_cmd('fsadm', '-y', 'check', path ) ++ r = exec_cmd('fsadm', '-y', 'resize', path, "#{new_size}k") ++ if r[:exit] != 0 and @resource[:nuke_fs_on_resize_failure] ++ exec_cmd('dd', 'if=/dev/zero', "of=#{path}", "bs=512", "count=16", "conv=notrunc") ++ blkid('-g') ++ end ++ lvresize( '-f', '-L', "#{new_size}k", path) || fail( "Cannot reduce to size #{new_size} because lvresize failed." ) ++ end ++ elsif new_size > current_size ++ if new_size % vg_extent_size != 0 ++ if @resource[:round_to_extent] ++ new_size = ((new_size + vg_extent_size - 1) / vg_extent_size) * vg_extent_size ++ if new_size <= current_size ++ info( "Logical volume already has a size of #{current_size}" ) ++ return ++ end ++ else ++ fail( "Cannot extend to size #{new_size} because VG extent size is #{vg_extent_size} KB" ) ++ end ++ end ++ lvextend( '-L', "#{new_size}k", path) || fail( "Cannot extend to size #{new_size} because lvextend failed." ) ++ exec_cmd('umount', path) ++ exec_cmd('fsadm', '-y', 'check', path ) ++ r = exec_cmd('fsadm', '-y', 'resize', path, "#{new_size}k") ++ if r[:exit] != 0 and @resource[:nuke_fs_on_resize_failure] ++ exec_cmd('dd', 'if=/dev/zero', "of=#{path}", "bs=512", "count=16", "conv=notrunc") ++ blkid('-g') + end ++ else ++ info( "Logical volume already has a size of #{current_size}" ) ++ end + end + + +@@ -161,7 +224,7 @@ Puppet::Type.type(:logical_volume).provide :lvm do + # Minus one because it says "2" when there is only one spare. And so on. + n = ($1.to_i)-1 + #puts " current mirrors: #{n}" +- return n.to_s ++ return n.to_s + end + return 0.to_s + end +@@ -176,7 +239,7 @@ Puppet::Type.type(:logical_volume).provide :lvm do + end + + # Region size cannot be changed on an existing mirror (not even when changing to zero mirrors). +- ++ + if @resource[:alloc] + args.push( '--alloc', @resource[:alloc] ) + end +@@ -222,9 +285,6 @@ Puppet::Type.type(:logical_volume).provide :lvm do + end + end + +- +- +- + private + + def lvs_pattern +@@ -240,4 +300,18 @@ Puppet::Type.type(:logical_volume).provide :lvm do + "/dev/#{@resource[:volume_group]}" + end + ++ def lvzero ++ if lvs('--noheading', '-o', 'lv_size', '--units', 'm', path) =~ /\s+(\d+)\.\d+m/i ++ lv_size = $1.to_i ++ lv_size = lv_size - 2 ++ begin ++ dd('if=/dev/zero', 'of=' + path, 'bs=1M', "seek=#{lv_size}") ++ rescue ++ end ++ begin ++ dd('if=/dev/zero', 'of=' + path, 'bs=1M', 'count=100') ++ rescue ++ end ++ end ++ end + end +diff --git a/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb b/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb +index eaefc92..6ac6e0a 100644 +--- a/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb +@@ -4,7 +4,7 @@ Puppet::Type.type(:physical_volume).provide(:lvm) do + commands :pvcreate => 'pvcreate', :pvremove => 'pvremove', :pvs => 'pvs', :vgs => 'vgs' + + def create +- pvcreate(@resource[:name]) ++ pvcreate('-y', @resource[:name]) + end + + def destroy +diff --git a/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb b/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb +index c8de071..3d54dba 100644 +--- a/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb +@@ -1,12 +1,18 @@ ++require 'csv' ++ + Puppet::Type.type(:volume_group).provide :lvm do + desc "Manages LVM volume groups" + + commands :vgcreate => 'vgcreate', + :vgremove => 'vgremove', ++ :pvremove => 'pvremove', + :vgs => 'vgs', + :vgextend => 'vgextend', + :vgreduce => 'vgreduce', +- :pvs => 'pvs' ++ :vgscan => 'vgscan', ++ :pvs => 'pvs', ++ :lvremove => 'lvremove', ++ :umount => 'umount' + + def create + vgcreate(@resource[:name], *@resource.should(:physical_volumes)) +@@ -22,17 +28,55 @@ Puppet::Type.type(:volume_group).provide :lvm do + false + end + ++ def exec_cmd(*cmd) ++ output = Puppet::Util::Execution.execute(cmd, :failonfail => false, :combine => true) ++ {:out => output, :exit => $CHILD_STATUS.exitstatus} ++ end ++ + def physical_volumes=(new_volumes = []) +- # Only take action if createonly is false just to be safe +- # this is really only here to enforce the createonly setting +- # if something goes wrong in physical_volumes +- if @resource[:createonly].to_s == "false" +- existing_volumes = physical_volumes +- extraneous = existing_volumes - new_volumes +- extraneous.each { |volume| reduce_with(volume) } ++ # Only take action if createonly is false just to be safe ++ # this is really only here to enforce the createonly setting ++ # if something goes wrong in physical_volumes ++ if @resource[:createonly].to_s == "false" ++ vgreduce('--removemissing', '--force', @resource[:name]) ++ existing_volumes = physical_volumes ++ extraneous = existing_volumes - new_volumes ++ pv_to_lv={} ++ pv_to_dev={} ++ csv = CSV.new(pvs('-o', 'pv_name,vg_name,lv_name', '--separator', ','), ++ :headers => true, :header_converters => :symbol) ++ csv.to_a.map {|row| row.to_hash}.each do |m| ++ unless m[:lv].nil? ++ pv_to_lv[m[:_pv].strip] = "#{m[:vg]}/#{m[:lv]}" ++ pv_to_dev[m[:_pv].strip] = "#{m[:vg].gsub('-','--')}-#{m[:lv].gsub('-','--')}" ++ end ++ end ++ ++ if extraneous == existing_volumes ++ extraneous.each do |volume| ++ if pv_to_lv.has_key?(volume) ++ exec_cmd('/bin/umount', "/dev/mapper/#{pv_to_dev[volume]}") ++ lvremove('-f', pv_to_lv[volume]) ++ end ++ end ++ vgremove(@resource[:name], '--force') ++ extraneous.each do |volume| ++ pvremove(volume) ++ end ++ vgcreate(@resource[:name], *new_volumes) ++ else ++ extraneous.each do |volume| ++ if pv_to_lv.has_key?(volume) ++ exec_cmd('/bin/umount', "/dev/mapper/#{pv_to_dev[volume]}") ++ lvremove('-f', pv_to_lv[volume]) ++ end ++ reduce_with(volume) ++ pvremove(volume) ++ end + missing = new_volumes - existing_volumes + missing.each { |volume| extend_with(volume) } + end ++ end + end + + def physical_volumes +diff --git a/packstack/puppet/modules/lvm/lib/puppet/type/logical_volume.rb b/packstack/puppet/modules/lvm/lib/puppet/type/logical_volume.rb +index f907e08..3081650 100644 +--- a/packstack/puppet/modules/lvm/lib/puppet/type/logical_volume.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/type/logical_volume.rb +@@ -31,7 +31,7 @@ Puppet::Type.newtype(:logical_volume) do + newproperty(:size) do + desc "The size of the logical volume. Set to undef to use all available space" + validate do |value| +- unless value =~ /^[0-9]+(\.[0-9]+)?[KMGTPE]/i ++ unless value =~ /(^[0-9]+(\.[0-9]+)?[KMGTPE]|max)/i + raise ArgumentError , "#{value} is not a valid logical volume size" + end + end +@@ -50,6 +50,36 @@ Puppet::Type.newtype(:logical_volume) do + desc "Configures the logical volume type. AIX only" + end + ++ newparam(:allow_reduce) do ++ desc "Allow reducing logical volume size." ++ validate do |value| ++ unless [:true, true, "true", :false, false, "false"].include?(value) ++ raise ArgumentError , "allow_reduce must either be true or false" ++ end ++ end ++ defaultto :false ++ end ++ ++ newparam(:round_to_extent) do ++ desc "Allow rounding of logical volume size to extent size." ++ validate do |value| ++ unless [:true, true, "true", :false, false, "false"].include?(value) ++ raise ArgumentError , "round_to_extent must either be true or false" ++ end ++ end ++ defaultto :false ++ end ++ ++ newparam(:nuke_fs_on_resize_failure) do ++ desc "Remove filesystem on logical volume resize failure." ++ defaultto :false ++ validate do |value| ++ unless [:true, true, "true", :false, false, "false"].include?(value) ++ raise ArgumentError , "nuke_fs_on_resize_failure must either be true or false" ++ end ++ end ++ end ++ + newparam(:range) do + desc "Sets the inter-physical volume allocation policy. AIX only" + validate do |value| +diff --git a/packstack/puppet/modules/lvm/manifests/logical_volume.pp b/packstack/puppet/modules/lvm/manifests/logical_volume.pp +index e6e5e78..4888b5d 100644 +--- a/packstack/puppet/modules/lvm/manifests/logical_volume.pp ++++ b/packstack/puppet/modules/lvm/manifests/logical_volume.pp +@@ -3,7 +3,9 @@ + define lvm::logical_volume ( + $volume_group, + $size = undef, ++ $size_is_minsize = false, + $initial_size = undef, ++ $round_to_extent = false, + $ensure = present, + $options = 'defaults', + $pass = '2', +@@ -12,6 +14,7 @@ define lvm::logical_volume ( + $mkfs_options = undef, + $mountpath = "/${name}", + $mountpath_require = false, ++ $remounts = true, + $createfs = true, + $extents = undef, + $stripes = undef, +@@ -21,6 +24,7 @@ define lvm::logical_volume ( + ) { + + validate_bool($mountpath_require) ++ validate_bool($size_is_minsize) + + if ($name == undef) { + fail("lvm::logical_volume \$name can't be undefined") +@@ -51,6 +55,7 @@ define lvm::logical_volume ( + ensure => $ensure, + volume_group => $volume_group, + size => $size, ++ size_is_minsize => $size_is_minsize, + initial_size => $initial_size, + stripes => $stripes, + stripesize => $stripesize, +@@ -81,6 +86,7 @@ define lvm::logical_volume ( + pass => $pass, + dump => $dump, + atboot => true, ++ remounts => $remounts, + } + } + } +diff --git a/packstack/puppet/modules/lvm/manifests/volume.pp b/packstack/puppet/modules/lvm/manifests/volume.pp +index a8bc3c8..bdfc937 100644 +--- a/packstack/puppet/modules/lvm/manifests/volume.pp ++++ b/packstack/puppet/modules/lvm/manifests/volume.pp +@@ -59,7 +59,10 @@ define lvm::volume ( + $fstype = undef, + $size = undef, + $extents = undef, +- $initial_size = undef ++ $initial_size = undef, ++ $allow_reduce = false, ++ $round_to_extent = false, ++ $nuke_fs_on_resize_failure = false + ) { + + if ($name == undef) { +@@ -88,6 +91,9 @@ define lvm::volume ( + volume_group => $vg, + size => $size, + initial_size => $initial_size, ++ allow_reduce => $allow_reduce, ++ round_to_extent => $round_to_extent, ++ nuke_fs_on_resize_failure => $nuke_fs_on_resize_failure, + before => Volume_group[$vg] + } + } +@@ -124,6 +130,9 @@ define lvm::volume ( + volume_group => $vg, + size => $size, + extents => $extents, ++ allow_reduce => $allow_reduce, ++ round_to_extent => $round_to_extent, ++ nuke_fs_on_resize_failure => $nuke_fs_on_resize_failure, + require => Volume_group[$vg] + } + +diff --git a/packstack/puppet/modules/lvm/spec/unit/puppet/provider/logical_volume/lvm_spec.rb b/packstack/puppet/modules/lvm/spec/unit/puppet/provider/logical_volume/lvm_spec.rb +index 56c32a5..a465a7f 100644 +--- a/packstack/puppet/modules/lvm/spec/unit/puppet/provider/logical_volume/lvm_spec.rb ++++ b/packstack/puppet/modules/lvm/spec/unit/puppet/provider/logical_volume/lvm_spec.rb +@@ -12,23 +12,24 @@ describe provider_class do + describe 'when creating' do + context 'with size' do + it "should execute 'lvcreate' with a '--size' option" do +- @resource.expects(:[]).with(:name).returns('mylv') +- @resource.expects(:[]).with(:volume_group).returns('myvg') ++ @resource.expects(:[]).with(:name).returns('mylv').at_least_once ++ @resource.expects(:[]).with(:volume_group).returns('myvg').at_least_once + @resource.expects(:[]).with(:size).returns('1g').at_least_once + @resource.expects(:[]).with(:extents).returns(nil).at_least_once + @resource.expects(:[]).with(:stripes).returns(nil).at_least_once + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + end + end + context 'with initial_size' do + it "should execute 'lvcreate' with a '--size' option" do +- @resource.expects(:[]).with(:name).returns('mylv') +- @resource.expects(:[]).with(:volume_group).returns('myvg') ++ @resource.expects(:[]).with(:name).returns('mylv').at_least_once ++ @resource.expects(:[]).with(:volume_group).returns('myvg').at_least_once + @resource.expects(:[]).with(:initial_size).returns('1g').at_least_once + @resource.expects(:[]).with(:size).returns(nil).at_least_once + @resource.expects(:[]).with(:extents).returns(nil).at_least_once +@@ -36,15 +37,16 @@ describe provider_class do + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + end + end + context 'without size and without extents' do + it "should execute 'lvcreate' without a '--size' option or a '--extents' option" do +- @resource.expects(:[]).with(:name).returns('mylv') +- @resource.expects(:[]).with(:volume_group).returns('myvg') ++ @resource.expects(:[]).with(:name).returns('mylv').at_least_once ++ @resource.expects(:[]).with(:volume_group).returns('myvg').at_least_once + @resource.expects(:[]).with(:size).returns(nil).at_least_once + @resource.expects(:[]).with(:initial_size).returns(nil).at_least_once + @resource.expects(:[]).with(:extents).returns(nil).at_least_once +@@ -52,45 +54,47 @@ describe provider_class do + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--extents', '100%FREE', 'myvg') + @provider.create + end + end + context 'with extents' do + it "should execute 'lvcreate' with a '--extents' option" do +- @resource.expects(:[]).with(:name).returns('mylv') +- @resource.expects(:[]).with(:volume_group).returns('myvg') ++ @resource.expects(:[]).with(:name).returns('mylv').at_least_once ++ @resource.expects(:[]).with(:volume_group).returns('myvg').at_least_once + @resource.expects(:[]).with(:size).returns('1g').at_least_once + @resource.expects(:[]).with(:extents).returns('80%vg').at_least_once + @resource.expects(:[]).with(:stripes).returns(nil).at_least_once + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', '--extents', '80%vg', 'myvg') + @provider.create + end + end + context 'without extents' do + it "should execute 'lvcreate' without a '--extents' option" do +- @resource.expects(:[]).with(:name).returns('mylv') +- @resource.expects(:[]).with(:volume_group).returns('myvg') ++ @resource.expects(:[]).with(:name).returns('mylv').at_least_once ++ @resource.expects(:[]).with(:volume_group).returns('myvg').at_least_once + @resource.expects(:[]).with(:size).returns('1g').at_least_once + @resource.expects(:[]).with(:extents).returns(nil).at_least_once + @resource.expects(:[]).with(:stripes).returns(nil).at_least_once + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + end + end + context 'with initial_size and mirroring' do + it "should execute 'lvcreate' with '--size' and '--mirrors' and '--mirrorlog' options" do +- @resource.expects(:[]).with(:name).returns('mylv') +- @resource.expects(:[]).with(:volume_group).returns('myvg') ++ @resource.expects(:[]).with(:name).returns('mylv').at_least_once ++ @resource.expects(:[]).with(:volume_group).returns('myvg').at_least_once + @resource.expects(:[]).with(:initial_size).returns('1g').at_least_once + @resource.expects(:[]).with(:size).returns(nil).at_least_once + @resource.expects(:[]).with(:extents).returns(nil).at_least_once +@@ -102,6 +106,7 @@ describe provider_class do + @resource.expects(:[]).with(:region_size).returns(nil).at_least_once + @resource.expects(:[]).with(:no_sync).returns(nil).at_least_once + @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', '--mirrors', '1', '--mirrorlog', 'core', 'myvg') + @provider.create + end +@@ -120,13 +125,15 @@ describe provider_class do + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once ++ @resource.expects(:[]).with(:nuke_fs_on_resize_failure).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + @provider.expects(:lvs).with('--noheading', '--unit', 'g', '/dev/myvg/mylv').returns(' 1.00g').at_least_once + @provider.expects(:lvs).with('--noheading', '-o', 'vg_extent_size', '--units', 'k', '/dev/myvg/mylv').returns(' 1000.00k') + @provider.expects(:lvextend).with('-L', '2000000k', '/dev/myvg/mylv').returns(true) +- @provider.expects(:blkid).with('/dev/myvg/mylv') ++ #@provider.expects(:blkid).with('/dev/myvg/mylv') + @provider.size = '2000000k' + end + end +@@ -140,7 +147,8 @@ describe provider_class do + @resource.expects(:[]).with(:stripesize).returns(nil).at_least_once + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + @provider.expects(:lvs).with('--noheading', '--unit', 'g', '/dev/myvg/mylv').returns(' 1.00g').at_least_once +@@ -161,7 +169,9 @@ describe provider_class do + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:size_is_minsize).returns(:false).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once ++ @resource.expects(:[]).with(:allow_reduce).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + @provider.expects(:lvs).with('--noheading', '--unit', 'g', '/dev/myvg/mylv').returns(' 1.00g').at_least_once +@@ -182,7 +192,8 @@ describe provider_class do + @resource.expects(:[]).with(:readahead).returns(nil).at_least_once + @resource.expects(:[]).with(:size_is_minsize).returns(:true).at_least_once + @resource.expects(:[]).with(:mirror).returns(nil).at_least_once +- @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:alloc).returns(nil).at_least_once ++ @resource.expects(:[]).with(:round_to_extent).returns(false).at_least_once + @provider.expects(:lvcreate).with('-n', 'mylv', '--size', '1g', 'myvg') + @provider.create + @provider.expects(:lvs).with('--noheading', '--unit', 'g', '/dev/myvg/mylv').returns(' 1.00g').at_least_once +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-lvm/centos/files/0002-UEFI-pvcreate-fix.patch b/devtools/puppet-modules/puppet-lvm/centos/files/0002-UEFI-pvcreate-fix.patch new file mode 100644 index 000000000..3ac7b91d8 --- /dev/null +++ b/devtools/puppet-modules/puppet-lvm/centos/files/0002-UEFI-pvcreate-fix.patch @@ -0,0 +1,46 @@ +From ac6a60e4d65e33017f8db0eca499f8dd898acb3c Mon Sep 17 00:00:00 2001 +From: Kristine Bujold +Date: Fri, 15 Jul 2016 16:55:16 -0400 +Subject: [PATCH] US80802 - PXE Installation changes for UEFI support. Fixing + pvcreate issue. + +--- + .../lvm/lib/puppet/provider/physical_volume/lvm.rb | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb b/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb +index 6ac6e0a..18183ae 100644 +--- a/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/provider/physical_volume/lvm.rb +@@ -1,12 +1,27 @@ + Puppet::Type.type(:physical_volume).provide(:lvm) do + desc "Manages LVM physical volumes" + +- commands :pvcreate => 'pvcreate', :pvremove => 'pvremove', :pvs => 'pvs', :vgs => 'vgs' ++ ++ commands :pvcreate => 'pvcreate', ++ :pvremove => 'pvremove', ++ :pvs => 'pvs', ++ :vgs => 'vgs', ++ :dd => 'dd' + + def create ++ # Delete the first few bytes at the start and end of the partition. This is required with ++ # GPT partitions, they save partition info at the start and the end of the block. ++ exec_cmd('dd', 'if=/dev/zero', "of=#{@resource[:name]}", "bs=512", "count=34") ++ exec_cmd('dd', 'if=/dev/zero', "of=#{@resource[:name]}", "bs=512", "count=34", "seek=$((`blockdev --getsz #{@resource[:name]}` - 34))") ++ + pvcreate('-y', @resource[:name]) + end + ++ def exec_cmd(*cmd) ++ output = Puppet::Util::Execution.execute(cmd, :failonfail => false, :combine => true) ++ {:out => output, :exit => $CHILD_STATUS.exitstatus} ++ end ++ + def destroy + pvremove(@resource[:name]) + end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-lvm/centos/files/0003-US94222-Persistent-Dev-Naming.patch b/devtools/puppet-modules/puppet-lvm/centos/files/0003-US94222-Persistent-Dev-Naming.patch new file mode 100644 index 000000000..a1ddc0d8f --- /dev/null +++ b/devtools/puppet-modules/puppet-lvm/centos/files/0003-US94222-Persistent-Dev-Naming.patch @@ -0,0 +1,25 @@ +From b05de190832bba08ce410c267c4b2f8a74916f7a Mon Sep 17 00:00:00 2001 +From: Robert Church +Date: Wed, 1 Mar 2017 09:12:34 +0000 +Subject: [PATCH] US94222: Persistent Dev Naming + +--- + packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb b/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb +index 3d54dba..04dea64 100644 +--- a/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/provider/volume_group/lvm.rb +@@ -81,7 +81,7 @@ Puppet::Type.type(:volume_group).provide :lvm do + + def physical_volumes + if @resource[:createonly].to_s == "false" || ! vgs(@resource[:name]) +- lines = pvs('-o', 'pv_name,vg_name', '--separator', ',') ++ lines = `pvs -o pv_name,vg_name --separator ',' | awk -F ',' 'NR>1{cmd="find -L /dev/disk/by-path/ -samefile" $1; cmd | getline $1;print $1 "," $2; next};{print}'` + lines.split(/\n/).grep(/,#{@resource[:name]}$/).map { |s| + s.split(/,/)[0].strip + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-lvm/centos/files/0004-extendind-nuke_fs_on_resize_failure-functionality.patch b/devtools/puppet-modules/puppet-lvm/centos/files/0004-extendind-nuke_fs_on_resize_failure-functionality.patch new file mode 100644 index 000000000..a0115a786 --- /dev/null +++ b/devtools/puppet-modules/puppet-lvm/centos/files/0004-extendind-nuke_fs_on_resize_failure-functionality.patch @@ -0,0 +1,34 @@ +From f2676c5ac0e17a18726815b72ef449c804e07135 Mon Sep 17 00:00:00 2001 +From: Stefan Dinescu +Date: Wed, 6 Dec 2017 12:50:14 +0000 +Subject: [PATCH 1/1] extendind nuke_fs_on_resize_failure functionality + +--- + .../modules/lvm/lib/puppet/provider/logical_volume/lvm.rb | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb b/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb +index 2f41695..2abfea3 100755 +--- a/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb ++++ b/packstack/puppet/modules/lvm/lib/puppet/provider/logical_volume/lvm.rb +@@ -188,7 +188,16 @@ Puppet::Type.type(:logical_volume).provide :lvm do + exec_cmd('dd', 'if=/dev/zero', "of=#{path}", "bs=512", "count=16", "conv=notrunc") + blkid('-g') + end +- lvresize( '-f', '-L', "#{new_size}k", path) || fail( "Cannot reduce to size #{new_size} because lvresize failed." ) ++ r = exec_cmd('lvresize', '-r', '-f', '-L', "#{new_size}k", path) ++ if r[:exit] != 0 ++ if @resource[:nuke_fs_on_resize_failure] ++ exec_cmd('dd', 'if=/dev/zero', "of=#{path}", "bs=512", "count=16", "conv=notrunc") ++ blkid('-g') ++ lvresize( '-f', '-L', "#{new_size}k", path) || fail( "Cannot reduce to size #{new_size} because lvresize failed." ) ++ else ++ fail( "Cannot reduce to size #{new_size} because lvresize failed." ) ++ end ++ end + end + elsif new_size > current_size + if new_size % vg_extent_size != 0 +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-lvm/centos/puppet-lvm.spec b/devtools/puppet-modules/puppet-lvm/centos/puppet-lvm.spec new file mode 100644 index 000000000..8f7252092 --- /dev/null +++ b/devtools/puppet-modules/puppet-lvm/centos/puppet-lvm.spec @@ -0,0 +1,45 @@ +%global git_sha d0283da637ae24550fb4ba109a48ef8d5d8c8b84 +%global prefix puppetlabs +%global module_dir lvm + +Name: puppet-%{module_dir} +Version: 0.5.0 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet %{module_dir} module +License: Apache + +URL: https://github.com/puppetlabs/puppetlabs-lvm + +Source0: %{prefix}-%{module_dir}-%{git_sha}.tar.gz + +Patch0: 0001-puppet-lvm-kilo-quilt-changes.patch +Patch1: 0002-UEFI-pvcreate-fix.patch +Patch2: 0003-US94222-Persistent-Dev-Naming.patch +Patch3: 0004-extendind-nuke_fs_on_resize_failure-functionality.patch + +BuildArch: noarch + +BuildRequires: python2-devel + +# According to .fixtures.yml the following puppet modules are also required +Requires: puppet-stdlib + + +%description +A Puppet module for Logical Resource Management (LVM) + +%prep +%setup -c %{module_dir} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R packstack/puppet/modules/%{module_dir} %{buildroot}/%{_datadir}/puppet/modules + +%files +%license packstack/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-network/centos/build_srpm.data b/devtools/puppet-modules/puppet-network/centos/build_srpm.data new file mode 100644 index 000000000..acc6c8f17 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/build_srpm.data @@ -0,0 +1,16 @@ +PREFIX=puppet +MODULE=network +VERSION=1.0.2 + +GIT_SHA=7deacd5fdc22c0543455878a8d1872f2f5417c1d + +# Generic Copy routine +# Un-patched +#COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz" + +#Patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=7 diff --git a/devtools/puppet-modules/puppet-network/centos/files/Don-t-write-absent-to-redhat-route-files-and-test-fo.patch b/devtools/puppet-modules/puppet-network/centos/files/Don-t-write-absent-to-redhat-route-files-and-test-fo.patch new file mode 100644 index 000000000..efc544618 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/Don-t-write-absent-to-redhat-route-files-and-test-fo.patch @@ -0,0 +1,71 @@ +From 49e103bbeb4d6efe1ca75f581d41ee6a8ed7caf5 Mon Sep 17 00:00:00 2001 +From: Romanos Skiadas +Date: Wed, 2 Nov 2016 14:51:47 -0400 +Subject: [PATCH] Don't write absent to redhat route files and test for this + +Signed-off-by: Allain Legacy +--- + .../network/lib/puppet/provider/network_route/redhat.rb | 9 +++++++-- + .../spec/unit/provider/network_route/redhat_spec.rb | 17 ++++++++++++++++- + 2 files changed, 23 insertions(+), 3 deletions(-) + +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +index f45eab5..9841c8e 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +@@ -84,10 +84,15 @@ Puppet::Type.type(:network_route).provide(:redhat) do + raise Puppet::Error, "#{provider.name} does not have a #{prop}." if provider.send(prop).nil? + end + if provider.network == "default" +- contents << "#{provider.network} via #{provider.gateway} dev #{provider.interface} #{provider.options}\n" ++ contents << "#{provider.network} via #{provider.gateway} dev #{provider.interface}\n" + else +- contents << "#{provider.network}/#{provider.netmask} via #{provider.gateway} dev #{provider.interface} #{provider.options}\n" ++ contents << "#{provider.network}/#{provider.netmask} via #{provider.gateway} dev #{provider.interface}\n" + end ++ contents << if provider.options == :absent ++ "\n" ++ else ++ " #{provider.options}\n" ++ end + end + contents.join + end +diff --git a/packstack/puppet/modules/network/spec/unit/provider/network_route/redhat_spec.rb b/packstack/puppet/modules/network/spec/unit/provider/network_route/redhat_spec.rb +index dfc9d6b..1ad2128 100644 +--- a/packstack/puppet/modules/network/spec/unit/provider/network_route/redhat_spec.rb ++++ b/packstack/puppet/modules/network/spec/unit/provider/network_route/redhat_spec.rb +@@ -91,7 +91,18 @@ describe Puppet::Type.type(:network_route).provider(:redhat) do + ) + end + +- let(:content) { described_class.format_file('', [route1_provider, route2_provider, defaultroute_provider]) } ++ let(:nooptions_provider) do ++ stub('nooptions_provider', ++ name: 'default', ++ network: 'default', ++ netmask: '', ++ gateway: '10.0.0.1', ++ interface: 'eth2', ++ options: :absent ++ ) ++ end ++ ++ let(:content) { described_class.format_file('', [route1_provider, route2_provider, defaultroute_provider, nooptions_provider]) } + + describe "writing the route line" do + describe "For standard (non-default) routes" do +@@ -122,6 +133,10 @@ describe Puppet::Type.type(:network_route).provider(:redhat) do + it "should have the correct fields appended" do + content.scan(/^default .*$/).first.should be_include("default via 10.0.0.1 dev eth1") + end ++ ++ it 'should not contain the word absent when no options are defined' do ++ expect(content).to_not match(/absent/) ++ end + end + end + end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-network/centos/files/fix-absent-options.patch b/devtools/puppet-modules/puppet-network/centos/files/fix-absent-options.patch new file mode 100644 index 000000000..23c738f02 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/fix-absent-options.patch @@ -0,0 +1,113 @@ +From f22d4c9d24939afb8f29323adffe3eb570f14804 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=3D=3FUTF-8=3Fq=3FIgor=3D20Gali=3DC4=3D87=3F=3D?= + +Date: Wed, 2 Nov 2016 14:54:28 -0400 +Subject: [PATCH] fix "absent" options + +analogous to redhat, we check if options are absent, before appending +them to the file. This fixes #160 + +Signed-off-by: Allain Legacy +--- + .../lib/puppet/provider/network_route/redhat.rb | 10 ++--- + .../lib/puppet/provider/network_route/routes.rb | 3 +- + .../unit/provider/network_route/routes_spec.rb | 48 ++++++++++++++++++++++ + 3 files changed, 53 insertions(+), 8 deletions(-) + +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +index 9841c8e..7123d44 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +@@ -84,15 +84,11 @@ Puppet::Type.type(:network_route).provide(:redhat) do + raise Puppet::Error, "#{provider.name} does not have a #{prop}." if provider.send(prop).nil? + end + if provider.network == "default" +- contents << "#{provider.network} via #{provider.gateway} dev #{provider.interface}\n" ++ contents << "#{provider.network} via #{provider.gateway} dev #{provider.interface}" + else +- contents << "#{provider.network}/#{provider.netmask} via #{provider.gateway} dev #{provider.interface}\n" ++ contents << "#{provider.network}/#{provider.netmask} via #{provider.gateway} dev #{provider.interface}" + end +- contents << if provider.options == :absent +- "\n" +- else +- " #{provider.options}\n" +- end ++ contents << (provider.options == :absent ? "\n" : " #{provider.options}\n") + end + contents.join + end +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/routes.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/routes.rb +index 2dd579f..ca7066d 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_route/routes.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/routes.rb +@@ -93,7 +93,8 @@ Puppet::Type.type(:network_route).provide(:routes) do + raise Puppet::Error, "#{provider.name} is missing the required parameter 'gateway'." if provider.gateway.nil? + raise Puppet::Error, "#{provider.name} is missing the required parameter 'interface'." if provider.interface.nil? + +- contents << "#{provider.network} #{provider.netmask} #{provider.gateway} #{provider.interface} #{provider.options}\n" ++ contents << "#{provider.network} #{provider.netmask} #{provider.gateway} #{provider.interface}" ++ contents << (provider.options == :absent ? "\n" : " #{provider.options}\n") + end + + contents.join +diff --git a/packstack/puppet/modules/network/spec/unit/provider/network_route/routes_spec.rb b/packstack/puppet/modules/network/spec/unit/provider/network_route/routes_spec.rb +index 2e55eba..9376739 100644 +--- a/packstack/puppet/modules/network/spec/unit/provider/network_route/routes_spec.rb ++++ b/packstack/puppet/modules/network/spec/unit/provider/network_route/routes_spec.rb +@@ -93,4 +93,52 @@ describe Puppet::Type.type(:network_route).provider(:routes) do + end + end + end ++ describe 'when formatting simple files' do ++ let(:route1_provider) do ++ stub('route1_provider', ++ name: '172.17.67.0', ++ network: '172.17.67.0', ++ netmask: '255.255.255.0', ++ gateway: '172.18.6.2', ++ interface: 'vlan200', ++ options: :absent, ++ ) ++ end ++ ++ let(:route2_provider) do ++ stub('lo_provider', ++ name: '172.28.45.0', ++ network: '172.28.45.0', ++ netmask: '255.255.255.0', ++ gateway: '172.18.6.2', ++ interface: 'eth0', ++ options: :absent, ++ ) ++ end ++ ++ let(:content) { described_class.format_file('', [route1_provider, route2_provider]) } ++ ++ describe 'writing the route line' do ++ it 'should write only fields' do ++ expect(content.scan(/^172.17.67.0 .*$/).length).to eq(1) ++ expect(content.scan(/^172.17.67.0 .*$/).first.split(/\s/, 5).length).to eq(4) ++ end ++ ++ it 'should have the correct fields appended' do ++ expect(content.scan(/^172.17.67.0 .*$/).first).to include('172.17.67.0 255.255.255.0 172.18.6.2 vlan200') ++ end ++ ++ it 'should fail if the netmask property is not defined' do ++ route2_provider.unstub(:netmask) ++ route2_provider.stubs(:netmask).returns nil ++ expect { content }.to raise_exception ++ end ++ ++ it 'should fail if the gateway property is not defined' do ++ route2_provider.unstub(:gateway) ++ route2_provider.stubs(:gateway).returns nil ++ expect { content }.to raise_exception ++ end ++ end ++ end + end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-network/centos/files/ipv6-static-route-support.patch b/devtools/puppet-modules/puppet-network/centos/files/ipv6-static-route-support.patch new file mode 100644 index 000000000..10456b1f7 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/ipv6-static-route-support.patch @@ -0,0 +1,100 @@ +From 49820add1d1e5f63343615ead9b551b8679f466d Mon Sep 17 00:00:00 2001 +From: Kevin Smith +Date: Mon, 16 Oct 2017 15:06:37 -0500 +Subject: [PATCH 1/1] ipv6 static route support + +--- + .../lib/puppet/provider/network_route/redhat.rb | 3 ++- + .../network/lib/puppet/type/network_route.rb | 26 ++++++++++++++-------- + .../network/spec/unit/type/network_route_spec.rb | 5 +++++ + 3 files changed, 24 insertions(+), 10 deletions(-) + +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +index 5073519..c289f5f 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +@@ -93,7 +93,8 @@ Puppet::Type.type(:network_route).provide(:redhat) do + if provider.network == "default" + contents << "#{provider.network} via #{provider.gateway} dev #{provider.interface}" + else +- contents << "#{provider.network}/#{provider.netmask} via #{provider.gateway} dev #{provider.interface}" ++ # provider.name will have cidr notation ++ contents << "#{provider.name} via #{provider.gateway} dev #{provider.interface}" + end + contents << (provider.options == :absent ? "\n" : " #{provider.options}\n") + end +diff --git a/packstack/puppet/modules/network/lib/puppet/type/network_route.rb b/packstack/puppet/modules/network/lib/puppet/type/network_route.rb +index 7ab67dd..fd52c58 100644 +--- a/packstack/puppet/modules/network/lib/puppet/type/network_route.rb ++++ b/packstack/puppet/modules/network/lib/puppet/type/network_route.rb +@@ -5,8 +5,6 @@ Puppet::Type.newtype(:network_route) do + + ensurable + +- IPV4_ADDRESS_REGEX = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ +- + newparam(:name) do + isnamevar + desc "The name of the network route" +@@ -18,7 +16,7 @@ Puppet::Type.newtype(:network_route) do + validate do |value| + begin + t = IPAddr.new(value) unless value == "default" +- rescue ArgumentError ++ rescue + fail("Invalid value for network: #{value}") + end + end +@@ -29,17 +27,27 @@ Puppet::Type.newtype(:network_route) do + desc "The subnet mask to apply to the route" + + validate do |value| +- unless (value.length <= 2 or value =~ IPV4_ADDRESS_REGEX) ++ unless value.length <= 3 || (IPAddr.new(value) rescue false) + fail("Invalid value for argument netmask: #{value}") + end + end + + munge do |value| +- case value +- when IPV4_ADDRESS_REGEX +- value +- when /^\d+$/ +- IPAddr.new('255.255.255.255').mask(value.strip.to_i).to_s ++ # '255.255.255.255'.to_i will return 255, so we try to convert it back: ++ if value.to_i.to_s == value ++ if value.to_i <= 32 ++ IPAddr.new('255.255.255.255').mask(value.strip.to_i).to_s ++ else ++ IPAddr.new('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff').mask(value.strip.to_i).to_s ++ end ++ else ++ if (IPAddr.new(value).ipv6? rescue false) ++ IPAddr.new('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff').mask(value).to_s ++ elsif (IPAddr.new(value).ipv4? rescue false) ++ IPAddr.new('255.255.255.255').mask(value).to_s ++ else ++ raise("Invalid value for argument netmask: #{value}") ++ end + end + end + end +diff --git a/packstack/puppet/modules/network/spec/unit/type/network_route_spec.rb b/packstack/puppet/modules/network/spec/unit/type/network_route_spec.rb +index 24e9da3..6e6f3e4 100644 +--- a/packstack/puppet/modules/network/spec/unit/type/network_route_spec.rb ++++ b/packstack/puppet/modules/network/spec/unit/type/network_route_spec.rb +@@ -55,6 +55,11 @@ describe Puppet::Type.type(:network_route) do + r[:netmask].should == '255.255.255.0' + end + ++ it 'should convert IPv6 netmasks of the CIDR form' do ++ r = Puppet::Type.type(:network_route).new(name: 'lxd bridge', network: 'fd58:281b:6eef:eb3d::', netmask: '64', gateway: 'fd58:281b:6eef:eb3d::1', interface: 'lxdbr0') ++ expect(r[:netmask]).to eq('ffff:ffff:ffff:ffff::') ++ end ++ + it "should convert netmasks of the expanded netmask form" do + r = described_class.new(:name => '192.168.1.0/24', :network => '192.168.1.0', :netmask => '255.255.128.0', :gateway => '23.23.23.42', :interface => 'eth0') + r[:netmask].should == '255.255.128.0' +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-network/centos/files/permit-inservice-update-of-static-routes.patch b/devtools/puppet-modules/puppet-network/centos/files/permit-inservice-update-of-static-routes.patch new file mode 100644 index 000000000..66e76230b --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/permit-inservice-update-of-static-routes.patch @@ -0,0 +1,55 @@ +From 46ec08e58419bb73bf49b44cf32fa3d304236615 Mon Sep 17 00:00:00 2001 +From: Kevin Smith +Date: Thu, 5 Oct 2017 13:33:12 -0500 +Subject: [PATCH 1/1] permit inservice update of static routes + +--- + .../network/lib/puppet/provider/network_route/redhat.rb | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +index 7123d44..5073519 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/redhat.rb +@@ -18,12 +18,18 @@ Puppet::Type.type(:network_route).provide(:redhat) do + + has_feature :provider_options + ++ # WRS: Generate temporary copies. It will get compared to files under ++ # /etc/sysconfig/network-scripts afterward. Only config that have changed ++ # will get replaced. Don't let puppet directly manage them, else it will ++ # trigger un-wanted networking actions (like up/down). ++ RSCRIPT_DIRECTORY = "/var/run/network-scripts.puppet" ++ + def select_file +- "/etc/sysconfig/network-scripts/route-#{@resource[:interface]}" ++ "#{RSCRIPT_DIRECTORY}/route-#{@resource[:interface]}" + end + + def self.target_files +- Dir["/etc/sysconfig/network-scripts/route-*"] ++ Dir["#{RSCRIPT_DIRECTORY}/route-*"] + end + + def self.parse_file(filename, contents) +@@ -76,6 +82,7 @@ Puppet::Type.type(:network_route).provide(:redhat) do + + # Generate an array of sections + def self.format_file(filename, providers) ++ Dir.mkdir(RSCRIPT_DIRECTORY) unless File.exists?(RSCRIPT_DIRECTORY) + contents = [] + contents << header + # Build routes +@@ -103,4 +110,9 @@ Puppet::Type.type(:network_route).provide(:redhat) do + HEADER + str + end ++ ++ def self.post_flush_hook(filename) ++ File.chmod(0644, filename) ++ end ++ + end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-network/centos/files/puppet-network-Kilo-quilt-changes.patch b/devtools/puppet-modules/puppet-network/centos/files/puppet-network-Kilo-quilt-changes.patch new file mode 100644 index 000000000..841198fb6 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/puppet-network-Kilo-quilt-changes.patch @@ -0,0 +1,658 @@ +From 8e14e2e258a8f2f7189ed37c6337c41fbff0362a Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 6 Jun 2016 17:13:09 -0400 +Subject: [PATCH] puppet-network Kilo quilt changes + +--- + .../lib/puppet/provider/network_config/redhat.rb | 39 ++- + .../lib/puppet/provider/network_config/wrlinux.rb | 296 +++++++++++++++++++++ + .../lib/puppet/provider/network_route/wrlinux.rb | 109 ++++++++ + .../network/lib/puppet/type/network_config.rb | 4 + + packstack/puppet/modules/network/manifests/bond.pp | 22 ++ + .../puppet/modules/network/manifests/bond/setup.pp | 2 + + .../modules/network/manifests/bond/wrlinux.pp | 56 ++++ + 7 files changed, 521 insertions(+), 7 deletions(-) + create mode 100644 packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb + create mode 100644 packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb + create mode 100644 packstack/puppet/modules/network/manifests/bond/wrlinux.pp + +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb +index 4b6de7e..758f387 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb +@@ -19,7 +19,12 @@ Puppet::Type.type(:network_config).provide(:redhat) do + has_feature :provider_options + + # @return [String] The path to network-script directory on redhat systems +- SCRIPT_DIRECTORY = "/etc/sysconfig/network-scripts" ++ # SCRIPT_DIRECTORY = "/etc/sysconfig/network-scripts" ++ # WRS: Generate temporary copies. It will get compared to files under ++ # /etc/sysconfig/network-scripts afterward. Only config that have changed ++ # will get replaced. Don't let puppet directly manage them, else it will ++ # trigger un-wanted networking actions (like up/down). ++ SCRIPT_DIRECTORY = "/var/run/network-scripts.puppet" + + # The valid vlan ID range is 0-4095; 4096 is out of range + VLAN_RANGE_REGEX = %r[\d{1,3}|40[0-9][0-5]] +@@ -35,6 +40,7 @@ Puppet::Type.type(:network_config).provide(:redhat) do + :name => 'DEVICE', + :hotplug => 'HOTPLUG', + :mtu => 'MTU', ++ :gateway => 'GATEWAY', + } + + # Map provider instances to files based on their name +@@ -60,8 +66,14 @@ Puppet::Type.type(:network_config).provide(:redhat) do + # RedhatProvider.target_files + # # => ['/etc/sysconfig/network-scripts/ifcfg-eth0', '/etc/sysconfig/network-scripts/ifcfg-eth1'] + def self.target_files(script_dir = SCRIPT_DIRECTORY) +- entries = Dir.entries(script_dir).select {|entry| entry.match SCRIPT_REGEX} +- entries.map {|entry| File.join(SCRIPT_DIRECTORY, entry)} ++ entries = [] ++ if Dir.exists?(SCRIPT_DIRECTORY) ++ Dir.foreach(SCRIPT_DIRECTORY) do |item| ++ next if not item.match SCRIPT_REGEX ++ entries << item ++ end ++ end ++ entries + end + + # Convert a redhat network script into a hash +@@ -184,6 +196,8 @@ Puppet::Type.type(:network_config).provide(:redhat) do + end + + def self.format_file(filename, providers) ++ Dir.mkdir(SCRIPT_DIRECTORY) unless File.exists?(SCRIPT_DIRECTORY) ++ + if providers.length == 0 + return "" + elsif providers.length > 1 +@@ -193,11 +207,11 @@ Puppet::Type.type(:network_config).provide(:redhat) do + provider = providers[0] + props = {} + +- # Map everything to a flat hash +- props = (provider.options || {}) ++ props = provider.options if provider.options && provider.options != :absent + ++ # Map everything to a flat hash + NAME_MAPPINGS.keys.each do |type_name| +- if (val = provider.send(type_name)) ++ if (val = provider.send(type_name)) && val != :absent + props[type_name] = val + end + end +@@ -214,11 +228,11 @@ Puppet::Type.type(:network_config).provide(:redhat) do + str << %{#{key}=#{val}\n} + end + ++ content.prepend(header) + content + end + + def self.unmunge(props) +- + pairs = {} + + [:onboot, :hotplug].each do |bool_property| +@@ -245,6 +259,17 @@ Puppet::Type.type(:network_config).provide(:redhat) do + pairs + end + ++ def self.header ++ str = <<-HEADER ++# HEADER: This file is is being managed by puppet. Changes to ++# HEADER: interfaces that are not being managed by puppet will persist; ++# HEADER: however changes to interfaces that are being managed by puppet will ++# HEADER: be overwritten. In addition, file order is NOT guaranteed. ++# HEADER: Last generated at: #{Time.now} ++HEADER ++ str ++ end ++ + def self.post_flush_hook(filename) + File.chmod(0644, filename) + end +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb +new file mode 100644 +index 0000000..44c645a +--- /dev/null ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb +@@ -0,0 +1,296 @@ ++require 'puppetx/filemapper' ++ ++Puppet::Type.type(:network_config).provide(:wrlinux) do ++ # Wind River Linux network_config interfaces provider. ++ # ++ # This provider uses the filemapper mixin to map the interfaces file to a ++ # collection of network_config providers, and back. ++ # ++ include PuppetX::FileMapper ++ ++ desc "Wind River interfaces style provider" ++ ++ confine :osfamily => :wrlinux ++ defaultfor :osfamily => :wrlinux ++ ++ has_feature :provider_options ++ has_feature :hotpluggable ++ ++ def select_file ++ '/var/run/interfaces.puppet' ++ end ++ ++ def self.target_files ++ ['/var/run/interfaces.puppet'] ++ end ++ ++ class MalformedInterfacesError < Puppet::Error ++ def initialize(msg = nil) ++ msg = 'Malformed wrlinux interfaces file; cannot instantiate network_config resources' if msg.nil? ++ super ++ end ++ end ++ ++ def self.raise_malformed ++ @failed = true ++ raise MalformedInterfacesError ++ end ++ ++ class Instance ++ ++ attr_reader :name ++ ++ # Booleans ++ attr_accessor :onboot, :hotplug ++ ++ ++ # These fields are going to get rearranged to resolve issue 16 ++ # https://github.com/adrienthebo/puppet-network/issues/16 ++ attr_accessor :ipaddress, :netmask, :family, :method, :mtu ++ ++ # Options hash ++ attr_reader :options ++ ++ def initialize(name) ++ @name = name ++ ++ @options = Hash.new {|hash, key| hash[key] = []} ++ end ++ ++ def to_hash ++ h = { ++ :name => @name, ++ :onboot => @onboot, ++ :hotplug => @hotplug, ++ :ipaddress => @ipaddress, ++ :netmask => @netmask, ++ :family => @family, ++ :method => @method, ++ :mtu => @mtu, ++ :options => squeeze_options ++ } ++ ++ h.inject({}) do |hash, (key, val)| ++ hash[key] = val unless val.nil? ++ hash ++ end ++ end ++ ++ def squeeze_options ++ @options.inject({}) do |hash, (key, value)| ++ if value.size <= 1 ++ hash[key] = value.pop ++ else ++ hash[key] = value ++ end ++ ++ hash ++ end ++ end ++ ++ class << self ++ ++ def reset! ++ @interfaces = {} ++ end ++ ++ # @return [Array] All class instances ++ def all_instances ++ @interfaces ||= {} ++ @interfaces ++ end ++ ++ def [](name) ++ if all_instances[name] ++ obj = all_instances[name] ++ else ++ obj = self.new(name) ++ all_instances[name] = obj ++ end ++ ++ obj ++ end ++ end ++ end ++ ++ def self.parse_file(filename, contents) ++ # Debian has a very irregular format for the interfaces file. The ++ # parse_file method is somewhat derived from the ifup executable ++ # supplied in the debian ifupdown package. The source can be found at ++ # http://packages.debian.org/squeeze/ifupdown ++ ++ ++ # The debian interfaces implementation requires global state while parsing ++ # the file; namely, the stanza being parsed as well as the interface being ++ # parsed. ++ status = :none ++ current_interface = nil ++ ++ lines = contents.split("\n") ++ # TODO Join lines that end with a backslash ++ ++ # Iterate over all lines and determine what attributes they create ++ lines.each do |line| ++ ++ # Strip off any trailing comments ++ line.sub!(/#.*$/, '') ++ ++ case line ++ when /^\s*#|^\s*$/ ++ # Ignore comments and blank lines ++ next ++ ++ when /^auto|^allow-auto/ ++ # Parse out any auto sections ++ interfaces = line.split(' ') ++ interfaces.delete_at(0) ++ ++ interfaces.each do |name| ++ Instance[name].onboot = true ++ end ++ ++ # Reset the current parse state ++ current_interface = nil ++ ++ when /^allow-hotplug/ ++ # parse out allow-hotplug lines ++ ++ interfaces = line.split(' ') ++ interfaces.delete_at(0) ++ ++ interfaces.each do |name| ++ Instance[name].hotplug = true ++ end ++ ++ # Don't reset Reset the current parse state ++ when /^iface/ ++ ++ # Format of the iface line: ++ # ++ # iface ++ # zero or more options for ++ ++ if match = line.match(/^iface\s+(\S+)\s+(\S+)\s+(\S+)/) ++ name = match[1] ++ family = match[2] ++ method = match[3] ++ ++ # If an iface block for this interface has been seen, the file is ++ # malformed. ++ raise_malformed if Instance[name] and Instance[name].family ++ ++ status = :iface ++ current_interface = name ++ ++ # This is done automatically ++ #Instance[name].name = name ++ Instance[name].family = family ++ Instance[name].method = method ++ ++ else ++ # If we match on a string with a leading iface, but it isn't in the ++ # expected format, malformed blar blar ++ raise_malformed ++ end ++ ++ when /^mapping/ ++ ++ # XXX dox ++ raise Puppet::DevError, "Debian interfaces mapping parsing not implemented." ++ status = :mapping ++ ++ else ++ # We're currently examining a line that is within a mapping or iface ++ # stanza, so we need to validate the line and add the options it ++ # specifies to the known state of the interface. ++ ++ case status ++ when :iface ++ if match = line.match(/(\S+)\s+(\S.*)/) ++ # If we're parsing an iface stanza, then we should receive a set of ++ # lines that contain two or more space delimited strings. Append ++ # them as options to the iface in an array. ++ ++ key = match[1] ++ val = match[2] ++ ++ name = current_interface ++ ++ case key ++ when 'address'; Instance[name].ipaddress = val ++ when 'netmask'; Instance[name].netmask = val ++ when 'mtu'; Instance[name].mtu = val ++ else Instance[name].options[key] << val ++ end ++ else ++ raise_malformed ++ end ++ when :mapping ++ raise Puppet::DevError, "Debian interfaces mapping parsing not implemented." ++ when :none ++ raise_malformed ++ end ++ end ++ end ++ ++ Instance.all_instances.map {|name, instance| instance.to_hash } ++ end ++ ++ # Generate an array of sections ++ def self.format_file(filename, providers) ++ contents = [] ++ contents << header ++ ++ # Add onboot interfaces ++ if (auto_interfaces = providers.select {|provider| provider.onboot == true }) ++ stanza = [] ++ stanza << "auto " + auto_interfaces.map(&:name).sort.join(" ") ++ contents << stanza.join("\n") ++ end ++ ++ # Build iface stanzas ++ providers.sort_by(&:name).each do |provider| ++ # TODO add validation method ++ raise Puppet::Error, "#{provider.name} does not have a method." if provider.method.nil? ++ raise Puppet::Error, "#{provider.name} does not have a family." if provider.family.nil? ++ ++ stanza = [] ++ stanza << %{iface #{provider.name} #{provider.family} #{provider.method}} ++ ++ [ ++ [:ipaddress, 'address'], ++ [:netmask, 'netmask'], ++ [:mtu, 'mtu'], ++ ].each do |(property, section)| ++ stanza << " #{section} #{provider.send property}" if provider.send(property) and provider.send(property) != :absent ++ end ++ ++ if provider.options and provider.options != :absent ++ provider.options.each_pair do |key, val| ++ if val.is_a? String ++ stanza << " #{key} #{val}" ++ elsif val.is_a? Array ++ val.each { |entry| stanza << " #{key} #{entry}" } ++ else ++ raise Puppet::Error, "#{self} options key #{key} expects a String or Array, got #{val.class}" ++ end ++ end ++ end ++ ++ contents << stanza.join("\n") ++ end ++ ++ contents.map {|line| line + "\n\n"}.join ++ end ++ ++ def self.header ++ str = <<-HEADER ++# HEADER: This file is is being managed by puppet. Changes to ++# HEADER: interfaces that are not being managed by puppet will persist; ++# HEADER: however changes to interfaces that are being managed by puppet will ++# HEADER: be overwritten. In addition, file order is NOT guaranteed. ++# HEADER: Last generated at: #{Time.now} ++HEADER ++ str ++ end ++end +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb +new file mode 100644 +index 0000000..d3fa7b5 +--- /dev/null ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb +@@ -0,0 +1,109 @@ ++require 'ipaddr' ++require 'puppetx/filemapper' ++ ++Puppet::Type.type(:network_route).provide(:wrlinux) do ++ # Wind River Linux network_route routes provider. ++ # ++ # This provider uses the filemapper mixin to map the routes file to a ++ # collection of network_route providers, and back. ++ # ++ include PuppetX::FileMapper ++ ++ desc "Wind River routes style provider" ++ ++ confine :osfamily => :wrlinux ++ ++ # $ dpkg -S /etc/network/if-up.d/20static-routes ++ # ifupdown-extra: /etc/network/if-up.d/20static-routes ++ confine :exists => '/etc/network/if-up.d/20static-routes' ++ ++ defaultfor :osfamily => :wrlinux ++ ++ has_feature :provider_options ++ ++ def select_file ++ '/etc/network/routes' ++ end ++ ++ def self.target_files ++ ['/etc/network/routes'] ++ end ++ ++ class MalformedRoutesError < Puppet::Error ++ def initialize(msg = nil) ++ msg = 'Malformed wrlinux routes file; cannot instantiate network_route resources' if msg.nil? ++ super ++ end ++ end ++ ++ def self.raise_malformed ++ @failed = true ++ raise MalformedRoutesError ++ end ++ ++ def self.parse_file(filename, contents) ++ # Build out an empty hash for new routes for storing their configs. ++ route_hash = Hash.new do |hash, key| ++ hash[key] = {} ++ hash[key][:name] = key ++ hash[key] ++ end ++ ++ lines = contents.split("\n") ++ lines.each do |line| ++ # Strip off any trailing comments ++ line.sub!(/#.*$/, '') ++ ++ if line =~ /^\s*#|^\s*$/ ++ # Ignore comments and blank lines ++ next ++ end ++ ++ route = line.split(' ', 5) ++ ++ if route.length < 4 ++ raise_malformed ++ end ++ ++ # use the CIDR version of the target as :name ++ cidr_target = "#{route[0]}/#{IPAddr.new(route[1]).to_i.to_s(2).count('1')}" ++ ++ route_hash[cidr_target][:network] = route[0] ++ route_hash[cidr_target][:netmask] = route[1] ++ route_hash[cidr_target][:gateway] = route[2] ++ route_hash[cidr_target][:interface] = route[3] ++ route_hash[cidr_target][:options] = route[4] if route[4] ++ end ++ ++ route_hash.values ++ end ++ ++ # Generate an array of sections ++ def self.format_file(filename, providers) ++ contents = [] ++ contents << header ++ ++ # Build routes ++ providers.sort_by(&:name).each do |provider| ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'network'." if provider.network.nil? ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'netmask'." if provider.netmask.nil? ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'gateway'." if provider.gateway.nil? ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'interface'." if provider.interface.nil? ++ ++ contents << "#{provider.network} #{provider.netmask} #{provider.gateway} #{provider.interface} #{provider.options}\n" ++ end ++ ++ contents.join ++ end ++ ++ def self.header ++ str = <<-HEADER ++# HEADER: This file is is being managed by puppet. Changes to ++# HEADER: routes that are not being managed by puppet will persist; ++# HEADER: however changes to routes that are being managed by puppet will ++# HEADER: be overwritten. In addition, file order is NOT guaranteed. ++# HEADER: Last generated at: #{Time.now} ++HEADER ++ str ++ end ++end +diff --git a/packstack/puppet/modules/network/lib/puppet/type/network_config.rb b/packstack/puppet/modules/network/lib/puppet/type/network_config.rb +index a50a0df..1297ad7 100644 +--- a/packstack/puppet/modules/network/lib/puppet/type/network_config.rb ++++ b/packstack/puppet/modules/network/lib/puppet/type/network_config.rb +@@ -95,6 +95,10 @@ Puppet::Type.newtype(:network_config) do + defaultto :raw + end + ++ newproperty(:gateway) do ++ desc 'The IP address of the network router or gateway device (if any)' ++ end ++ + # `:options` provides an arbitrary passthrough for provider properties, so + # that provider specific behavior doesn't clutter up the main type but still + # allows for more powerful actions to be taken. +diff --git a/packstack/puppet/modules/network/manifests/bond.pp b/packstack/puppet/modules/network/manifests/bond.pp +index d6d98ce..26ca104 100644 +--- a/packstack/puppet/modules/network/manifests/bond.pp ++++ b/packstack/puppet/modules/network/manifests/bond.pp +@@ -188,6 +188,28 @@ define network::bond( + require => Kmod::Alias[$name], + } + } ++ WRLinux: { ++ network::bond::wrlinux { $name: ++ slaves => $slaves, ++ ensure => $ensure, ++ ipaddress => $ipaddress, ++ netmask => $netmask, ++ method => $method, ++ family => $family, ++ onboot => $onboot, ++ ++ mode => $mode, ++ miimon => $miimon, ++ downdelay => $downdelay, ++ updelay => $updelay, ++ lacp_rate => $lacp_rate, ++ primary => $primary, ++ primary_reselect => $primary_reselect, ++ xmit_hash_policy => $xmit_hash_policy, ++ ++ require => Kmod::Alias[$name], ++ } ++ } + RedHat: { + network::bond::redhat { $name: + ensure => $ensure, +diff --git a/packstack/puppet/modules/network/manifests/bond/setup.pp b/packstack/puppet/modules/network/manifests/bond/setup.pp +index abe1252..0a30767 100644 +--- a/packstack/puppet/modules/network/manifests/bond/setup.pp ++++ b/packstack/puppet/modules/network/manifests/bond/setup.pp +@@ -10,5 +10,7 @@ class network::bond::setup { + ensure => present, + } + } ++ WRLinux: { ++ } + } + } +diff --git a/packstack/puppet/modules/network/manifests/bond/wrlinux.pp b/packstack/puppet/modules/network/manifests/bond/wrlinux.pp +new file mode 100644 +index 0000000..e240341 +--- /dev/null ++++ b/packstack/puppet/modules/network/manifests/bond/wrlinux.pp +@@ -0,0 +1,56 @@ ++# = Define: network::bond::wrlinux ++# ++# Instantiate bonded interfaces on Debian based systems. ++# ++# == See also ++# ++# * Debian Network Bonding http://wiki.wrlinux.org/Bonding ++define network::bond::wrlinux( ++ $slaves, ++ $ensure = present, ++ $ipaddress = undef, ++ $netmask = undef, ++ $method = undef, ++ $family = undef, ++ $onboot = undef, ++ ++ $mode = undef, ++ $miimon = undef, ++ $downdelay = undef, ++ $updelay = undef, ++ $lacp_rate = undef, ++ $primary = undef, ++ $primary_reselect = undef, ++ $xmit_hash_policy = undef, ++) { ++ ++ $raw = { ++ 'bond-slaves' => join($slaves, ' '), ++ 'bond-mode' => $mode, ++ 'bond-miimon' => $miimon, ++ 'bond-downdelay' => $downdelay, ++ 'bond-updelay' => $updelay, ++ 'bond-lacp-rate' => $lacp_rate, ++ 'bond-primary' => $primary, ++ 'bond-primary-reselect' => $primary_reselect, ++ 'bond-xmit-hash-policy' => $xmit_hash_policy, ++ } ++ ++ $opts = compact_hash($raw) ++ ++ network_config { $name: ++ ensure => $ensure, ++ ipaddress => $ipaddress, ++ netmask => $netmask, ++ family => $family, ++ method => $method, ++ onboot => $onboot, ++ options => $opts, ++ } ++ ++ network_config { $slaves: ++ ensure => absent, ++ reconfigure => true, ++ before => Network_config[$name], ++ } ++} +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-network/centos/files/puppet-network-support-ipv6.patch b/devtools/puppet-modules/puppet-network/centos/files/puppet-network-support-ipv6.patch new file mode 100644 index 000000000..b6d2f3c91 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/puppet-network-support-ipv6.patch @@ -0,0 +1,46 @@ +Index: packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb +@@ -224,6 +224,11 @@ + + pairs = self.unmunge props + ++ ip_version = provider.send(:family) ++ if (ip_version.to_s == "inet6") ++ pairs = self.ipv6_fixup pairs ++ end ++ + content = pairs.inject('') do |str, (key, val)| + str << %{#{key}=#{val}\n} + end +@@ -259,6 +264,30 @@ + pairs + end + ++ def self.ipv6_fixup(pairs) ++ pairs['IPV6INIT'] = 'yes' ++ ++ if (pairs.include? 'NETMASK' and pairs.include? 'IPADDR') ++ pairs['IPV6ADDR'] = pairs['IPADDR'].to_s + "/" + pairs['NETMASK'].to_s ++ pairs.delete('NETMASK') ++ pairs.delete('IPADDR') ++ elsif (pairs.include? 'IPADDR') ++ pairs['IPV6ADDR'] = pairs['IPADDR'].to_s ++ pairs.delete('IPADDR') ++ end ++ ++ if (pairs.include? 'GATEWAY') ++ pairs['IPV6_DEFAULTGW'] = pairs['GATEWAY'] ++ pairs.delete('GATEWAY') ++ end ++ ++ if (pairs['BOOTPROTO'].to_s == 'dhcp') ++ pairs['DHCPV6C'] = 'yes' ++ pairs['DHCLIENTARGS'] = '-1' ++ end ++ pairs ++ end ++ + def self.header + str = <<-HEADER + # HEADER: This file is is being managed by puppet. Changes to diff --git a/devtools/puppet-modules/puppet-network/centos/files/route-options-support.patch b/devtools/puppet-modules/puppet-network/centos/files/route-options-support.patch new file mode 100644 index 000000000..37bf13867 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/files/route-options-support.patch @@ -0,0 +1,28 @@ +From c26a70ab9d5839f90148c578edc5d15133355194 Mon Sep 17 00:00:00 2001 +From: Kevin Smith +Date: Wed, 25 Oct 2017 07:37:52 -0500 +Subject: [PATCH 1/1] route options support + +--- + packstack/puppet/modules/network/lib/puppet/type/network_route.rb | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/packstack/puppet/modules/network/lib/puppet/type/network_route.rb b/packstack/puppet/modules/network/lib/puppet/type/network_route.rb +index fd52c58..13ca06a 100644 +--- a/packstack/puppet/modules/network/lib/puppet/type/network_route.rb ++++ b/packstack/puppet/modules/network/lib/puppet/type/network_route.rb +@@ -3,6 +3,11 @@ require 'ipaddr' + Puppet::Type.newtype(:network_route) do + @doc = "Manage non-volatile route configuration information" + ++ feature :provider_options, <<-EOD ++ The provider can accept an arbitrary options string. The semantics of ++ these options will depend on the provider. ++ EOD ++ + ensurable + + newparam(:name) do +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-network/centos/puppet-network.spec b/devtools/puppet-modules/puppet-network/centos/puppet-network.spec new file mode 100644 index 000000000..7b53bdb74 --- /dev/null +++ b/devtools/puppet-modules/puppet-network/centos/puppet-network.spec @@ -0,0 +1,49 @@ +%global git_sha 7deacd5fdc22c0543455878a8d1872f2f5417c1d +%global module_dir network + +Name: puppet-network +Version: 1.0.2 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet Network module +License: Apache + +URL: https://github.com/voxpupuli/puppet-network + +Source0: %{name}-%{git_sha}.tar.gz + +Patch0: puppet-network-Kilo-quilt-changes.patch +Patch1: puppet-network-support-ipv6.patch +Patch2: Don-t-write-absent-to-redhat-route-files-and-test-fo.patch +Patch3: fix-absent-options.patch +Patch4: permit-inservice-update-of-static-routes.patch +Patch5: ipv6-static-route-support.patch +Patch6: route-options-support.patch + + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A Puppet module to manage non volatile network and route configuration + +%prep +%setup -c %{module_dir} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 + + + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R packstack/puppet/modules/%{module_dir} %{buildroot}/%{_datadir}/puppet/modules + +%files +%license packstack/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-nslcd/centos/build_srpm.data b/devtools/puppet-modules/puppet-nslcd/centos/build_srpm.data new file mode 100644 index 000000000..f16d30827 --- /dev/null +++ b/devtools/puppet-modules/puppet-nslcd/centos/build_srpm.data @@ -0,0 +1,16 @@ +PREFIX=puppet +MODULE=nslcd +VERSION=0.0.1 + +GIT_SHA=b8c19b1ada89865f2e50758e054583798ad8011a + +# Generic Copy routine +# Un-patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz" + +#Patched +#COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/puppet-nslcd/centos/puppet-nslcd.spec b/devtools/puppet-modules/puppet-nslcd/centos/puppet-nslcd.spec new file mode 100644 index 000000000..ffcafccc0 --- /dev/null +++ b/devtools/puppet-modules/puppet-nslcd/centos/puppet-nslcd.spec @@ -0,0 +1,31 @@ +%global git_sha b8c19b1ada89865f2e50758e054583798ad8011a +%global module_dir nslcd + +Name: puppet-nslcd +Version: 0.0.1 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet nslcd module +License: Apache + +URL: https://github.com/jlyheden/puppet-nslcd + +Source0: %{name}-%{git_sha}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A Puppet module for nslcd - local LDAP name service daemon + +%prep +%autosetup -c %{module_dir} + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R packstack/puppet/modules/%{module_dir} %{buildroot}/%{_datadir}/puppet/modules + +%files +#%license packstack/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/centos/build_srpm.data b/devtools/puppet-modules/puppet-ovs_dpdk/centos/build_srpm.data new file mode 100644 index 000000000..aeb2ddf69 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/centos/build_srpm.data @@ -0,0 +1,2 @@ +SRC_DIR="src" +TIS_PATCH_VER=0 diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/centos/puppet-ovs_dpdk.spec b/devtools/puppet-modules/puppet-ovs_dpdk/centos/puppet-ovs_dpdk.spec new file mode 100644 index 000000000..5db71e38f --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/centos/puppet-ovs_dpdk.spec @@ -0,0 +1,32 @@ +%global module_dir ovs_dpdk + +Name: puppet-%{module_dir} +Version: 1.0.0 +Release: %{tis_patch_ver}%{?_tis_dist} +Summary: Puppet ovs_dpdk module +License: Apache + +URL: unknown + +Source0: %{name}-%{version}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A puppet module for ovs dpdk + +%prep +%autosetup -c %{module_dir} + +# +# The src for this puppet module needs to be staged to puppet/modules +# +%install +install -d -m 0755 %{buildroot}%{_datadir}/puppet/modules/%{module_dir} +cp -R %{name}-%{version}/%{module_dir} %{buildroot}%{_datadir}/puppet/modules + +%files +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/openvswitch_agent.ini b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/openvswitch_agent.ini new file mode 100644 index 000000000..8b6bb05b7 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/openvswitch_agent.ini @@ -0,0 +1,21 @@ +[DEFAULT] +log_file = neutron-ovs.log +log_dir = /tmp + +[ml2_type_flat] +flat_networks = providernet-a, +[ml2_type_geneve] +vni_ranges = 1:1000 +[ml2_type_gre] +tunnel_id_ranges = 1:1000 +[ml2_type_vlan] +network_vlan_ranges = providernet-a +[ml2_type_vxlan] +vni_ranges = 1:1000 + +[ovs] +datapath_type = netdev +vhostuser_socket_dir = /var/run/openvswitch/ +bridge_mappings = providernet-a:br-ex +tunnel_bridge = br-tun +local_ip = 192.168.204.242 diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_post b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_post new file mode 100644 index 000000000..def333577 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_post @@ -0,0 +1,7 @@ +#! /bin/bash + +ovs-vsctl --no-wait --may-exist add-br br-ex -- set bridge br-ex datapath_type=netdev +modprobe uio_pci_generic +/usr/share/openvswitch/dpdk-usertools/dpdk-devbind.py --bind=uio_pci_generic 0000:00:08.0 + +ovs-vsctl --no-wait --may-exist add-port br-ex dpdk0 -- set Interface dpdk0 type=dpdk options:dpdk-devargs=0000:00:08.0 diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_pre b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_pre new file mode 100644 index 000000000..3aa7ebda8 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/ovs_dpdk_config_pre @@ -0,0 +1,10 @@ +#! /bin/bash + +sysctl -w vm.nr_hugepages=1024 +mkdir -p /dev/hugepages +mount -t hugetlbfs -o pagesize=2M none /dev/hugepages + +ovs-vsctl --no-wait set Open_vSwitch . "other_config:dpdk-init=true" +ovs-vsctl --no-wait set Open_vSwitch . "other_config:dpdk-lcore-mask=1" +ovs-vsctl --no-wait set Open_vSwitch . "other_config:dpdk-alloc-mem=512" + diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_openvswitch_agent_ini b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_openvswitch_agent_ini new file mode 100644 index 000000000..82e651d31 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_openvswitch_agent_ini @@ -0,0 +1,9 @@ +#! /bin/sh + +IP=`ifconfig | grep "192.168" | sed -e "s/.*inet //" -e "s/ netmask.*//"` + +if [ "x$IP" = "x" ]; then + IP="127.0.0.1" +fi + +sed -i "s/local_ip.*/local_ip =$IP/" /etc/neutron/openvswitch_agent.ini diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_service_config b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_service_config new file mode 100644 index 000000000..c25162ad3 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/files/update_service_config @@ -0,0 +1,33 @@ +#! /bin/bash + +# update ovs-vswitchd.service + +sed -i "/ExecStartPre=\/usr\/bin\/ovs_dpdk_config_pre/d" /usr/lib/systemd/system/ovs-vswitchd.service +sed -i "/\[Service\]/a ExecStartPre=/usr/bin/ovs_dpdk_config_pre" /usr/lib/systemd/system/ovs-vswitchd.service + +sed -i "/ExecStartPost=\/usr\/bin\/ovs_dpdk_config_post/d" /usr/lib/systemd/system/ovs-vswitchd.service +sed -i "/\[Service\]/a ExecStartPost=/usr/bin/ovs_dpdk_config_post" /usr/lib/systemd/system/ovs-vswitchd.service + +# update neutron-openvswitch-agent.servic +sed -i "s#ExecStart=.*#ExecStart=/usr/bin/neutron-openvswitch-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/openvswitch_agent.ini --log-file /var/log/neutron/openvswitch-agent.log#" /usr/lib/systemd/system/neutron-openvswitch-agent.service + +sed -i "s#User=.*#User=root#" /usr/lib/systemd/system/neutron-openvswitch-agent.service + +sed -i "/Requires=ovs-vswitchd.service/d" /usr/lib/systemd/system/neutron-openvswitch-agent.service +sed -i "/\[Unit\]/a Requires=ovs-vswitchd.service" /usr/lib/systemd/system/neutron-openvswitch-agent.service + +sed -i "s#After=syslog.target#After=ovs-vswitchd.service syslog.target#" /usr/lib/systemd/system/neutron-openvswitch-agent.service + +#sed -i "/ExecStartPre=\/usr\/bin\/ovs_dpdk_config_post/d" /usr/lib/systemd/system/neutron-openvswitch-agent.service +#sed -i "/\[Service\]/a ExecStartPre=/usr/bin/ovs_dpdk_config_post" /usr/lib/systemd/system/neutron-openvswitch-agent.service + +#work around +sed -i "/Requires=openvswitch.service neutron-openvswitch-agent.service neutron-l3-agent.service/d" /usr/lib/systemd/system/nova-compute.service +sed -i "/\[Unit\]/a Requires=openvswitch.service neutron-openvswitch-agent.service neutron-l3-agent.service" /usr/lib/systemd/system/nova-compute.service + +# update neutron-l3-agent.service +sed -i "s#ExecStart=.*#ExecStart=/usr/bin/neutron-l3-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/l3_agent.ini --log-file /var/log/neutron/l3-agent.log#" /usr/lib/systemd/system/neutron-l3-agent.service + +sed -i "s#User=.*#User=root#" /usr/lib/systemd/system/neutron-l3-agent.service +sed -i "s#After=syslog.target#After=neutron-openvswitch-agent.service syslog.target#" /usr/lib/systemd/system/neutron-l3-agent.service + diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config.pp b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config.pp new file mode 100644 index 000000000..663744f85 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config.pp @@ -0,0 +1,18 @@ +class ovs_dpdk::config { + exec { 'setup_ovsdpdk_1_1': + path => [ '/usr/bin', '/usr/sbin', '/bin', '/sbin' ], + command => 'update_openvswitch_agent_ini', + } ~> + exec { 'setup_ovsdpdk_1_2': + path => [ '/usr/bin', '/usr/sbin', '/bin', '/sbin' ], + command => 'update_service_config', + } ~> + exec { 'setup_ovsdpdk_1_3': + path => [ '/usr/bin', '/usr/sbin', '/bin', '/sbin' ], + command => 'systemctl enable neutron-openvswitch-agent', + } ~> + exec { 'setup_ovsdpdk_1_4': + path => [ '/usr/bin', '/usr/sbin', '/bin', '/sbin' ], + command => 'systemctl enable neutron-l3-agent', + } +} diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config_files.pp b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config_files.pp new file mode 100644 index 000000000..d88d61bcb --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/config_files.pp @@ -0,0 +1,41 @@ +class ovs_dpdk::config_files { + file { '/etc/neutron/openvswitch_agent.ini': + ensure => file, + mode =>"0640", + owner => 'root', + group => 'neutron', + source => 'puppet:///modules/ovs_dpdk/openvswitch_agent.ini', + } + + file { '/usr/bin/update_openvswitch_agent_ini': + ensure => file, + mode =>"0755", + owner => 'root', + group => 'root', + source => 'puppet:///modules/ovs_dpdk/update_openvswitch_agent_ini' + } + + file { '/usr/bin/update_service_config': + ensure => file, + mode =>"0755", + owner => 'root', + group => 'root', + source => 'puppet:///modules/ovs_dpdk/update_service_config' + } + + file { '/usr/bin/ovs_dpdk_config_pre': + ensure => file, + mode =>"0755", + owner => 'root', + group => 'root', + source => 'puppet:///modules/ovs_dpdk/ovs_dpdk_config_pre', + } + + file { '/usr/bin/ovs_dpdk_config_post': + ensure => file, + mode =>"0755", + owner => 'root', + group => 'root', + source => 'puppet:///modules/ovs_dpdk/ovs_dpdk_config_post', + } +} diff --git a/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/init.pp b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/init.pp new file mode 100644 index 000000000..9d7cc7094 --- /dev/null +++ b/devtools/puppet-modules/puppet-ovs_dpdk/src/ovs_dpdk/manifests/init.pp @@ -0,0 +1,11 @@ +# Class ovs_dpdk +# +# ovs_dpdk configuration +# +# == parameters +# + +class ovs_dpdk { + class { ovs_dpdk::config_files: } ~> + class { ovs_dpdk::config: } +} diff --git a/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/build_srpm.data b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/build_srpm.data new file mode 100644 index 000000000..9bbf7e928 --- /dev/null +++ b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/build_srpm.data @@ -0,0 +1,12 @@ +PREFIX=puppetlabs +MODULE=postgresql +VERSION=4.8.0 + +GIT_SHA=d022a56b28b2174456fc0f6adc51a4b54493afad + +#Patched +COPY_LIST="$CGCS_BASE/downloads/puppet/$PREFIX-$MODULE-$GIT_SHA.tar.gz $FILES_BASE/*" + + + +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..ed917cd8d --- /dev/null +++ b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,87 @@ +From 94cc61ad7f76d94791fee4f596d3c8c3124c0526 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Wed, 11 Jan 2017 14:25:20 -0500 +Subject: [PATCH] Roll up TIS patches + +--- + manifests/params.pp | 2 +- + manifests/server/config.pp | 8 ++++++-- + manifests/server/initdb.pp | 9 +++++++++ + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/manifests/params.pp b/manifests/params.pp +index d40a1eb..45be360 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -74,7 +74,7 @@ class postgresql::params inherits postgresql::globals { + } + $psql_path = pick($psql_path, "${bindir}/psql") + +- $service_status = $service_status ++ $service_status = "systemctl is-active postgresql" + $service_reload = "service ${service_name} reload" + $perl_package_name = pick($perl_package_name, 'perl-DBD-Pg') + $python_package_name = pick($python_package_name, 'python-psycopg2') +diff --git a/manifests/server/config.pp b/manifests/server/config.pp +index 205dd22..2ecad4b 100644 +--- a/manifests/server/config.pp ++++ b/manifests/server/config.pp +@@ -111,6 +111,12 @@ class postgresql::server::config { + postgresql::server::config_entry { 'data_directory': + value => $datadir, + } ++ postgresql::server::config_entry { 'hba_file': ++ value => $pg_hba_conf_path, ++ } ++ postgresql::server::config_entry { 'ident_file': ++ value => $pg_ident_conf_path, ++ } + if $timezone { + postgresql::server::config_entry { 'timezone': + value => $timezone, +@@ -154,7 +160,6 @@ class postgresql::server::config { + concat { $pg_ident_conf_path: + owner => $user, + group => $group, +- force => true, # do not crash if there is no pg_ident_rules + mode => '0640', + warn => true, + notify => Class['postgresql::server::reload'], +@@ -165,7 +170,6 @@ class postgresql::server::config { + concat { $recovery_conf_path: + owner => $user, + group => $group, +- force => true, # do not crash if there is no recovery conf file + mode => '0640', + warn => true, + notify => Class['postgresql::server::reload'], +diff --git a/manifests/server/initdb.pp b/manifests/server/initdb.pp +index 2252a19..5e263e3 100644 +--- a/manifests/server/initdb.pp ++++ b/manifests/server/initdb.pp +@@ -3,6 +3,7 @@ class postgresql::server::initdb { + $needs_initdb = $postgresql::server::needs_initdb + $initdb_path = $postgresql::server::initdb_path + $datadir = $postgresql::server::datadir ++ $confdir = $postgresql::server::confdir + $xlogdir = $postgresql::server::xlogdir + $logdir = $postgresql::server::logdir + $encoding = $postgresql::server::encoding +@@ -41,6 +42,14 @@ class postgresql::server::initdb { + seltype => $seltype, + } + ++ # Make sure the conf directory exists, and has the correct permissions. ++ file { $confdir: ++ ensure => directory, ++ owner => $user, ++ group => $group, ++ mode => '0700', ++ } ++ + if($xlogdir) { + # Make sure the xlog directory exists, and has the correct permissions. + file { $xlogdir: +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0002-remove-puppetlabs-apt-as-a-requirement.patch b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0002-remove-puppetlabs-apt-as-a-requirement.patch new file mode 100644 index 000000000..d19b49c6a --- /dev/null +++ b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/files/0002-remove-puppetlabs-apt-as-a-requirement.patch @@ -0,0 +1,24 @@ +From dd019f3e222c799afff53cb00447c130839f7d39 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 3 Jan 2018 14:11:08 -0600 +Subject: [PATCH] remove puppetlabs-apt as a requirement + +--- + metadata.json | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/metadata.json b/metadata.json +index 2a59dc9..b1de7f0 100644 +--- a/metadata.json ++++ b/metadata.json +@@ -9,7 +9,6 @@ + "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "dependencies": [ + {"name":"puppetlabs/stdlib","version_requirement":"4.x"}, +- {"name":"puppetlabs/apt","version_requirement":">=1.8.0 <3.0.0"}, + {"name":"puppetlabs/concat","version_requirement":">= 1.1.0 <3.0.0"} + ], + "data_provider": null, +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/puppet-postgresql.spec b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/puppet-postgresql.spec new file mode 100644 index 000000000..e794318c7 --- /dev/null +++ b/devtools/puppet-modules/puppet-postgresql-4.8.0/centos/puppet-postgresql.spec @@ -0,0 +1,52 @@ +%global git_sha d022a56b28b2174456fc0f6adc51a4b54493afad +%global prefix puppetlabs +%global module_dir postgresql + +Name: puppet-%{module_dir} +Version: 4.8.0 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet %{module_dir} module +License: Apache + +URL: https://github.com/puppetlabs/puppetlabs-postgresql + +Source0: %{prefix}-%{module_dir}-%{git_sha}.tar.gz + +Patch0001: 0001-Roll-up-TIS-patches.patch +Patch0002: 0002-remove-puppetlabs-apt-as-a-requirement.patch + +BuildArch: noarch + +BuildRequires: python2-devel + +# According to .fixtures.yml the following puppet modules are also needed +#Requires: puppet-apt +Requires: puppet-stdlib +Requires: puppet-firewall +Requires: puppet-concat + + +%description +A Puppet module for managing PostgreSQL databases + +%prep +%setup -n %{prefix}-%{module_dir} +%patch0001 -p1 +%patch0002 -p1 + +find . -type f -name ".*" -exec rm {} + +find . -size 0 -exec rm {} + +find . \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} + +find . \( -name "*.pp" -o -name "*.py" \) -exec chmod -x {} + +find . \( -name "*.rb" -o -name "*.erb" \) -exec chmod -x {} + +find . \( -name spec -o -name ext \) | xargs rm -rf + +%install +rm -rf %{buildroot} +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -rp * %{buildroot}/%{_datadir}/puppet/modules/%{module_dir}/ + +%files +%license %{_datadir}/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-puppi/centos/build_srpm.data b/devtools/puppet-modules/puppet-puppi/centos/build_srpm.data new file mode 100644 index 000000000..677603382 --- /dev/null +++ b/devtools/puppet-modules/puppet-puppi/centos/build_srpm.data @@ -0,0 +1,8 @@ +MODULE=puppi +VERSION=2.2.3 + +GIT_SHA=c1c47f4edfd761d1bbde32a75da0c3fa7cc93a81 + +COPY_LIST="$CGCS_BASE/downloads/puppet/$MODULE-$GIT_SHA.tar.gz" + +TIS_PATCH_VER=0 diff --git a/devtools/puppet-modules/puppet-puppi/centos/puppet-puppi.spec b/devtools/puppet-modules/puppet-puppi/centos/puppet-puppi.spec new file mode 100644 index 000000000..bcb340a10 --- /dev/null +++ b/devtools/puppet-modules/puppet-puppi/centos/puppet-puppi.spec @@ -0,0 +1,31 @@ +%global git_sha c1c47f4edfd761d1bbde32a75da0c3fa7cc93a81 +%global module_dir puppi + +Name: puppet-puppi +Version: 2.2.3 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Puppet Puppi module +License: Apache + +URL: https://github.com/example42/puppi + +Source0: %{module_dir}-%{git_sha}.tar.gz + +BuildArch: noarch + +BuildRequires: python2-devel + +%description +A Puppet module to provide puppet knowledge to CLI + +%prep +%setup -n puppi-master + +%install +install -d -m 0755 %{buildroot}/%{_datadir}/puppet/modules/%{module_dir} +cp -R ../puppi-master/* %{buildroot}/%{_datadir}/puppet/modules/%{module_dir}/. + +%files +%license %{_datadir}/puppet/modules/%{module_dir}/LICENSE +%{_datadir}/puppet/modules/%{module_dir} + diff --git a/devtools/puppet-modules/puppet-puppi/puppet_downloader.sh b/devtools/puppet-modules/puppet-puppi/puppet_downloader.sh new file mode 100755 index 000000000..60587fd03 --- /dev/null +++ b/devtools/puppet-modules/puppet-puppi/puppet_downloader.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +BRANCH="master" +repo=" https://github.com/example42" +module="puppi" +git ls-remote $repo/$module $BRANCH +SHA=`git ls-remote $repo/$module $BRANCH | awk '{print $1}'` +echo $SHA +wget $repo/$module/archive/$BRANCH.tar.gz -O "$module"-"$SHA".tar.gz + + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/build_srpm.data b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/build_srpm.data new file mode 100644 index 000000000..8429863c3 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=6 diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..49da59414 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From a1d4efe436a005962d677a146a261ac175b6b55f Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 1 Nov 2017 14:35:36 -0500 +Subject: [PATCH] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +--- + SPECS/puppet-rabbitmq.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-rabbitmq.spec b/SPECS/puppet-rabbitmq.spec +index 987ba3b..dc2c81b 100644 +--- a/SPECS/puppet-rabbitmq.spec ++++ b/SPECS/puppet-rabbitmq.spec +@@ -14,7 +14,7 @@ + + Name: puppet-rabbitmq + Version: 5.6.0 +-Release: 4%{?alphatag}%{?dist} ++Release: 4.5ac45degit.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Installs, configures, and manages RabbitMQ. + License: ASL 2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0002-Add-TIS-patch.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0002-Add-TIS-patch.patch new file mode 100644 index 000000000..75f3a87a9 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0002-Add-TIS-patch.patch @@ -0,0 +1,32 @@ +From 287fb29ea7d1bb31af50701bd7ac0e12c1524197 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 1 Nov 2017 14:44:13 -0500 +Subject: [PATCH 2/2] Add-TIS-patch + +--- + SPECS/puppet-rabbitmq.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-rabbitmq.spec b/SPECS/puppet-rabbitmq.spec +index dc2c81b..c96099b 100644 +--- a/SPECS/puppet-rabbitmq.spec ++++ b/SPECS/puppet-rabbitmq.spec +@@ -21,6 +21,7 @@ License: ASL 2.0 + URL: https://github.com/puppetlabs/puppetlabs-rabbitmq + + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz ++Patch0001: 0001-Roll-up-TIS-patches.patch + + BuildArch: noarch + +@@ -33,6 +34,7 @@ Installs, configures, and manages RabbitMQ. + + %prep + %setup -q -n %{tarsources}-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0003-meta-Changed-cipher-specification-to-openssl-format.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0003-meta-Changed-cipher-specification-to-openssl-format.patch new file mode 100644 index 000000000..885da3030 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0003-meta-Changed-cipher-specification-to-openssl-format.patch @@ -0,0 +1,37 @@ +From 95d7ce5d66e9a583045ce2789813a49e738b20eb Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 1 Nov 2017 14:49:05 -0500 +Subject: [PATCH 3/3] Changed cipher specification to openssl format + +By default, the config file is set up to accept ciphers in erlang format. +Our existing services (haproxy, lighttpd) both uses openssl format. +This change makes the config file generated by packstack assume the ciphers +given is in openssl format. Specifying ciphers in the same format makes it +easier to maintain. +--- + SPECS/puppet-rabbitmq.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-rabbitmq.spec b/SPECS/puppet-rabbitmq.spec +index c96099b..6541bc7 100644 +--- a/SPECS/puppet-rabbitmq.spec ++++ b/SPECS/puppet-rabbitmq.spec +@@ -22,6 +22,7 @@ URL: https://github.com/puppetlabs/puppetlabs-rabbitmq + + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch ++Patch0002: 0002-Changed-cipher-specification-to-openssl-format.patch + + BuildArch: noarch + +@@ -35,6 +36,7 @@ Installs, configures, and manages RabbitMQ. + %prep + %setup -q -n %{tarsources}-%{upstream_version} + %patch0001 -p1 ++%patch0002 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0004-Add-deprecation-patch-to-spec.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0004-Add-deprecation-patch-to-spec.patch new file mode 100644 index 000000000..7910474bf --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0004-Add-deprecation-patch-to-spec.patch @@ -0,0 +1,33 @@ +From 0e807a7738ff0455da4a54b5e4176bc13985f19f Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 19 Dec 2017 09:50:00 -0600 +Subject: [PATCH] Add deprecation patch to spec + +--- + SPECS/puppet-rabbitmq.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/puppet-rabbitmq.spec b/SPECS/puppet-rabbitmq.spec +index 6541bc7..e2a29cb 100644 +--- a/SPECS/puppet-rabbitmq.spec ++++ b/SPECS/puppet-rabbitmq.spec +@@ -23,6 +23,7 @@ URL: https://github.com/puppetlabs/puppetlabs-rabbitmq + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz + Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-Changed-cipher-specification-to-openssl-format.patch ++Patch0003: 0003-Eliminate-Puppet-4-deprecation-warnings.patch + + BuildArch: noarch + +@@ -37,6 +38,8 @@ Installs, configures, and manages RabbitMQ. + %setup -q -n %{tarsources}-%{upstream_version} + %patch0001 -p1 + %patch0002 -p1 ++%patch0003 -p1 ++ + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0005-metapatch-for-revert.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0005-metapatch-for-revert.patch new file mode 100644 index 000000000..c045588a2 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0005-metapatch-for-revert.patch @@ -0,0 +1,32 @@ +From fbb9b6275c4c199643d51bf6d192ae7623dcef99 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 24 Jan 2018 16:04:04 -0600 +Subject: [PATCH 4/4] metapatch for revert patch + +--- + SPECS/puppet-rabbitmq.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-rabbitmq.spec b/SPECS/puppet-rabbitmq.spec +index e2a29cb..17a12bc 100644 +--- a/SPECS/puppet-rabbitmq.spec ++++ b/SPECS/puppet-rabbitmq.spec +@@ -24,6 +24,7 @@ Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit} + Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-Changed-cipher-specification-to-openssl-format.patch + Patch0003: 0003-Eliminate-Puppet-4-deprecation-warnings.patch ++Patch0004: 0004-Partially-revert-upstream-commit-f7c3a4a637d59f3065d.patch + + BuildArch: noarch + +@@ -39,6 +40,7 @@ Installs, configures, and manages RabbitMQ. + %patch0001 -p1 + %patch0002 -p1 + %patch0003 -p1 ++%patch0004 -p1 + + + find . -type f -name ".*" -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0006-metapatch-for-fact-removal.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0006-metapatch-for-fact-removal.patch new file mode 100644 index 000000000..43fd42e9e --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/0006-metapatch-for-fact-removal.patch @@ -0,0 +1,32 @@ +From 35277432f8da1569fdb472b4459b687695807ece Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Fri, 2 Feb 2018 12:32:19 -0600 +Subject: [PATCH] metapatch for fact removal + +--- + SPECS/puppet-rabbitmq.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-rabbitmq.spec b/SPECS/puppet-rabbitmq.spec +index 17a12bc..7f3a412 100644 +--- a/SPECS/puppet-rabbitmq.spec ++++ b/SPECS/puppet-rabbitmq.spec +@@ -25,6 +25,7 @@ Patch0001: 0001-Roll-up-TIS-patches.patch + Patch0002: 0002-Changed-cipher-specification-to-openssl-format.patch + Patch0003: 0003-Eliminate-Puppet-4-deprecation-warnings.patch + Patch0004: 0004-Partially-revert-upstream-commit-f7c3a4a637d59f3065d.patch ++Patch0005: 0005-Remove-the-rabbitmq_nodename-fact.patch + + BuildArch: noarch + +@@ -41,6 +42,7 @@ Installs, configures, and manages RabbitMQ. + %patch0002 -p1 + %patch0003 -p1 + %patch0004 -p1 ++%patch0005 -p1 + + + find . -type f -name ".*" -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..4a294d514 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,6 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-patch.patch +0003-meta-Changed-cipher-specification-to-openssl-format.patch +0004-Add-deprecation-patch-to-spec.patch +0005-metapatch-for-revert.patch +0006-metapatch-for-fact-removal.patch diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0001-Roll-up-TIS-patches.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0001-Roll-up-TIS-patches.patch new file mode 100644 index 000000000..a8fda4854 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0001-Roll-up-TIS-patches.patch @@ -0,0 +1,143 @@ +From 6170b01db0dea2b58fc0f150704205f7aac82ab4 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 2 Nov 2017 09:22:58 -0500 +Subject: [PATCH 1/2] WRS: Patch1: 0001-Roll-up-TIS-patches.patch + +--- + lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb | 6 ++++++ + manifests/config.pp | 6 +++--- + manifests/init.pp | 5 +++-- + manifests/install.pp | 4 +++- + manifests/install/rabbitmqadmin.pp | 3 ++- + manifests/params.pp | 1 + + 6 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb b/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb +index 7e73295..438d9cc 100644 +--- a/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb ++++ b/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb +@@ -95,6 +95,12 @@ Puppet::Type.type(:rabbitmq_policy).provide(:rabbitmqctl, :parent => Puppet::Pro + resource[:definition] ||= definition + resource[:pattern] ||= pattern + resource[:priority] ||= priority ++ # WRS. Values passed in from packstack are in string format. These need ++ # to be converted back to integer for certain parameters (e.g. max-length, ++ # expires) ++ if (resource[:definition].keys & ["max-length", "expires"]).any? ++ resource[:definition].each {|k,v| resource[:definition][k] = v.to_i} ++ end + # rabbitmq>=3.2.0 + if Puppet::Util::Package.versioncmp(self.class.rabbitmq_version, '3.2.0') >= 0 + rabbitmqctl('set_policy', +diff --git a/manifests/config.pp b/manifests/config.pp +index 6e1f7f5..66a8b08 100644 +--- a/manifests/config.pp ++++ b/manifests/config.pp +@@ -116,7 +116,7 @@ class rabbitmq::config { + ensure => directory, + owner => '0', + group => '0', +- mode => '0644', ++ mode => '0640', + } + + file { '/etc/rabbitmq/ssl': +@@ -132,7 +132,7 @@ class rabbitmq::config { + content => template($config), + owner => '0', + group => '0', +- mode => '0644', ++ mode => '0640', + notify => Class['rabbitmq::service'], + } + +@@ -142,7 +142,7 @@ class rabbitmq::config { + content => template($env_config), + owner => '0', + group => '0', +- mode => '0644', ++ mode => '0640', + notify => Class['rabbitmq::service'], + } + +diff --git a/manifests/init.pp b/manifests/init.pp +index 363c70d..3451599 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -11,6 +11,7 @@ class rabbitmq( + Hash $config_shovel_statics = $rabbitmq::params::config_shovel_statics, + String $default_user = $rabbitmq::params::default_user, + String $default_pass = $rabbitmq::params::default_pass, ++ String $default_host = $rabbitmq::params::default_host, + Boolean $delete_guest_user = $rabbitmq::params::delete_guest_user, + String $env_config = $rabbitmq::params::env_config, + Stdlib::Absolutepath $env_config_path = $rabbitmq::params::env_config_path, +@@ -186,7 +187,7 @@ class rabbitmq( + + rabbitmq_plugin { 'rabbitmq_management': + ensure => present, +- require => Class['rabbitmq::install'], ++ require => [ File['/etc/rabbitmq'], Class['rabbitmq::install'] ], + notify => Class['rabbitmq::service'], + provider => 'rabbitmqplugins', + } +@@ -206,7 +207,7 @@ class rabbitmq( + if ($ldap_auth) { + rabbitmq_plugin { 'rabbitmq_auth_backend_ldap': + ensure => present, +- require => Class['rabbitmq::install'], ++ require => [ File['/etc/rabbitmq'], Class['rabbitmq::install'] ], + notify => Class['rabbitmq::service'], + } + } +diff --git a/manifests/install.pp b/manifests/install.pp +index 20ca090..45072c4 100644 +--- a/manifests/install.pp ++++ b/manifests/install.pp +@@ -11,7 +11,9 @@ class rabbitmq::install { + package { 'rabbitmq-server': + ensure => $package_ensure, + name => $package_name, +- provider => $package_provider, ++ # DPENNEY: For some reason, package_provider is coming out as yum. ++ # Hardcode as rpm for now. ++ provider => 'rpm', + notify => Class['rabbitmq::service'], + require => $package_require, + } +diff --git a/manifests/install/rabbitmqadmin.pp b/manifests/install/rabbitmqadmin.pp +index e0ab7c7..9a3a8dd 100644 +--- a/manifests/install/rabbitmqadmin.pp ++++ b/manifests/install/rabbitmqadmin.pp +@@ -11,6 +11,7 @@ class rabbitmq::install::rabbitmqadmin { + + $default_user = $rabbitmq::default_user + $default_pass = $rabbitmq::default_pass ++ $default_host = $rabbitmq::default_host + $node_ip_address = $rabbitmq::node_ip_address + + if $rabbitmq::node_ip_address == 'UNSET' { +@@ -27,7 +28,7 @@ class rabbitmq::install::rabbitmqadmin { + + staging::file { 'rabbitmqadmin': + target => "${rabbitmq::rabbitmq_home}/rabbitmqadmin", +- source => "${protocol}://${default_user}:${default_pass}@${sanitized_ip}:${management_port}/cli/rabbitmqadmin", ++ source => "${protocol}://${default_user}:${default_pass}@${default_host}:${management_port}/cli/rabbitmqadmin", + curl_option => "-k ${curl_prefix} --retry 30 --retry-delay 6", + timeout => '180', + wget_option => '--no-proxy', +diff --git a/manifests/params.pp b/manifests/params.pp +index ffface9..da0d2b4 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -87,6 +87,7 @@ class rabbitmq::params { + $config_shovel_statics = {} + $default_user = 'guest' + $default_pass = 'guest' ++ $default_host = 'localhost' + $delete_guest_user = false + $env_config = 'rabbitmq/rabbitmq-env.conf.erb' + $env_config_path = '/etc/rabbitmq/rabbitmq-env.conf' +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0002-Changed-cipher-specification-to-openssl-format.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0002-Changed-cipher-specification-to-openssl-format.patch new file mode 100644 index 000000000..a58966d86 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0002-Changed-cipher-specification-to-openssl-format.patch @@ -0,0 +1,35 @@ +From c6a94f3bbc69d82c74cc597b6b7b1fe5813b0537 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 2 Nov 2017 09:22:58 -0500 +Subject: [PATCH 2/2] WRS: Patch2: + 0002-Changed-cipher-specification-to-openssl-format.patch + +--- + templates/rabbitmq.config.erb | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/templates/rabbitmq.config.erb b/templates/rabbitmq.config.erb +index cf2a388..b9612f3 100644 +--- a/templates/rabbitmq.config.erb ++++ b/templates/rabbitmq.config.erb +@@ -72,7 +72,7 @@ + <%- end -%> + <%- if @ssl_ciphers and @ssl_ciphers.size > 0 -%> + ,{ciphers,[ +- <%= @ssl_ciphers.sort.map{|k| "{#{k}}"}.join(",\n ") %> ++ <%= @ssl_ciphers.sort.map{|k| "\"#{k}\""}.join(",\n ") %> + ]} + <%- end -%> + ]}, +@@ -111,7 +111,7 @@ + <%- end -%> + <%- if @ssl_ciphers and @ssl_ciphers.size > 0 -%> + ,{ciphers,[ +- <%= @ssl_ciphers.sort.map{|k| "{#{k}}"}.join(",\n ") %> ++ <%= @ssl_ciphers.sort.map{|k| "\"#{k}\""}.join(",\n ") %> + ]} + <%- end -%> + ]} +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0003-Eliminate-Puppet-4-deprecation-warnings.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0003-Eliminate-Puppet-4-deprecation-warnings.patch new file mode 100644 index 000000000..cea267f9f --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0003-Eliminate-Puppet-4-deprecation-warnings.patch @@ -0,0 +1,182 @@ +From 1d09cd4cc048a8a1958f3bf7bc5ee8a9e4617455 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 19 Dec 2017 10:26:17 -0600 +Subject: [PATCH] WRS: Patch3: + 0003-Eliminate-Puppet-4-deprecation-warnings.patch + +--- + manifests/init.pp | 49 ++++++++++--------------------------------------- + manifests/params.pp | 16 ++++++++-------- + metadata.json | 1 - + 3 files changed, 18 insertions(+), 48 deletions(-) + +diff --git a/manifests/init.pp b/manifests/init.pp +index 3451599..7808464 100644 +--- a/manifests/init.pp ++++ b/manifests/init.pp +@@ -17,11 +17,11 @@ class rabbitmq( + Stdlib::Absolutepath $env_config_path = $rabbitmq::params::env_config_path, + Optional[String] $erlang_cookie = $rabbitmq::params::erlang_cookie, + $interface = $rabbitmq::params::interface, +- $management_port = $rabbitmq::params::management_port, ++ Integer[1, 65535] $management_port = $rabbitmq::params::management_port, + $management_ssl = $rabbitmq::params::management_ssl, + Optional[String] $management_hostname = $rabbitmq::params::management_hostname, + String $node_ip_address = $rabbitmq::params::node_ip_address, +- $package_apt_pin = $rabbitmq::params::package_apt_pin, ++ Optional[Variant[Numeric, String]] $package_apt_pin = $rabbitmq::params::package_apt_pin, + String $package_ensure = $rabbitmq::params::package_ensure, + String $package_gpg_key = $rabbitmq::params::package_gpg_key, + String $package_name = $rabbitmq::params::package_name, +@@ -33,7 +33,7 @@ class rabbitmq( + $rabbitmq_user = $rabbitmq::params::rabbitmq_user, + $rabbitmq_group = $rabbitmq::params::rabbitmq_group, + $rabbitmq_home = $rabbitmq::params::rabbitmq_home, +- $port = $rabbitmq::params::port, ++ Integer $port = $rabbitmq::params::port, + Boolean $tcp_keepalive = $rabbitmq::params::tcp_keepalive, + Integer $tcp_backlog = $rabbitmq::params::tcp_backlog, + Optional[Integer] $tcp_sndbuf = $rabbitmq::params::tcp_sndbuf, +@@ -49,10 +49,10 @@ class rabbitmq( + String $ssl_key = $rabbitmq::params::ssl_key, + Optional[Integer] $ssl_depth = $rabbitmq::params::ssl_depth, + Optional[String] $ssl_cert_password = $rabbitmq::params::ssl_cert_password, +- $ssl_port = $rabbitmq::params::ssl_port, ++ Integer[1, 65535] $ssl_port = $rabbitmq::params::ssl_port, + $ssl_interface = $rabbitmq::params::ssl_interface, +- $ssl_management_port = $rabbitmq::params::ssl_management_port, +- $ssl_stomp_port = $rabbitmq::params::ssl_stomp_port, ++ Integer[1, 65535] $ssl_management_port = $rabbitmq::params::ssl_management_port, ++ Integer[1, 65535] $ssl_stomp_port = $rabbitmq::params::ssl_stomp_port, + $ssl_verify = $rabbitmq::params::ssl_verify, + $ssl_fail_if_no_peer_cert = $rabbitmq::params::ssl_fail_if_no_peer_cert, + Optional[Array] $ssl_versions = $rabbitmq::params::ssl_versions, +@@ -63,15 +63,15 @@ class rabbitmq( + String $ldap_user_dn_pattern = $rabbitmq::params::ldap_user_dn_pattern, + String $ldap_other_bind = $rabbitmq::params::ldap_other_bind, + Boolean $ldap_use_ssl = $rabbitmq::params::ldap_use_ssl, +- $ldap_port = $rabbitmq::params::ldap_port, ++ Integer[1, 65535] $ldap_port = $rabbitmq::params::ldap_port, + Boolean $ldap_log = $rabbitmq::params::ldap_log, + Hash $ldap_config_variables = $rabbitmq::params::ldap_config_variables, +- $stomp_port = $rabbitmq::params::stomp_port, ++ Integer[1, 65535] $stomp_port = $rabbitmq::params::stomp_port, + Boolean $stomp_ssl_only = $rabbitmq::params::stomp_ssl_only, +- $version = $rabbitmq::params::version, ++ Optional[String] $version = $rabbitmq::params::version, + Boolean $wipe_db_on_cookie_change = $rabbitmq::params::wipe_db_on_cookie_change, + $cluster_partition_handling = $rabbitmq::params::cluster_partition_handling, +- $file_limit = $rabbitmq::params::file_limit, ++ Variant[Integer[-1,], Enum['unlimited', 'infinity']] $file_limit = $rabbitmq::params::file_limit, + Hash $environment_variables = $rabbitmq::params::environment_variables, + Hash $config_variables = $rabbitmq::params::config_variables, + Hash $config_kernel_variables = $rabbitmq::params::config_kernel_variables, +@@ -85,35 +85,6 @@ class rabbitmq( + Stdlib::Absolutepath $inetrc_config_path = $rabbitmq::params::inetrc_config_path, + ) inherits rabbitmq::params { + +- # Validate install parameters. +- validate_re($package_apt_pin, '^(|\d+)$') +- validate_re($version, '^\d+\.\d+\.\d+(-\d+)*$') # Allow 3 digits and optional -n postfix. +- # Validate config parameters. +- if ! is_integer($management_port) { +- validate_re($management_port, '\d+') +- } +- if ! is_integer($port) { +- validate_re($port, ['\d+','UNSET']) +- } +- if ! is_integer($stomp_port) { +- validate_re($stomp_port, '\d+') +- } +- +- # using sprintf for conversion to string, because "${file_limit}" doesn't +- # pass lint, despite being nicer +- validate_re(sprintf('%s', $file_limit), +- '^(\d+|-1|unlimited|infinity)$', '$file_limit must be a positive integer, \'-1\', \'unlimited\', or \'infinity\'.') +- if ! is_integer($ssl_port) { +- validate_re($ssl_port, '\d+') +- } +- if ! is_integer($ssl_management_port) { +- validate_re($ssl_management_port, '\d+') +- } +- if ! is_integer($ssl_stomp_port) { +- validate_re($ssl_stomp_port, '\d+') +- } +- validate_re($ldap_port, '\d+') +- + if $ssl_only and ! $ssl { + fail('$ssl_only => true requires that $ssl => true') + } +diff --git a/manifests/params.pp b/manifests/params.pp +index da0d2b4..d5ef906 100644 +--- a/manifests/params.pp ++++ b/manifests/params.pp +@@ -68,7 +68,7 @@ class rabbitmq::params { + #install + $admin_enable = true + $management_hostname = undef +- $management_port = '15672' ++ $management_port = 15672 + $management_ssl = true + $package_apt_pin = '' + $package_gpg_key = 'https://www.rabbitmq.com/rabbitmq-release-signing-key.asc' +@@ -94,7 +94,7 @@ class rabbitmq::params { + $erlang_cookie = undef + $interface = 'UNSET' + $node_ip_address = 'UNSET' +- $port = '5672' ++ $port = 5672 + $tcp_keepalive = false + $tcp_backlog = 128 + $tcp_sndbuf = undef +@@ -107,10 +107,10 @@ class rabbitmq::params { + $ssl_key = 'UNSET' + $ssl_depth = undef + $ssl_cert_password = undef +- $ssl_port = '5671' ++ $ssl_port = 5671 + $ssl_interface = 'UNSET' +- $ssl_management_port = '15671' +- $ssl_stomp_port = '6164' ++ $ssl_management_port = 15671 ++ $ssl_stomp_port = 6164 + $ssl_verify = 'verify_none' + $ssl_fail_if_no_peer_cert = false + $ssl_versions = undef +@@ -121,10 +121,10 @@ class rabbitmq::params { + $ldap_user_dn_pattern = 'cn=username,ou=People,dc=example,dc=com' + $ldap_other_bind = 'anon' + $ldap_use_ssl = false +- $ldap_port = '389' ++ $ldap_port = 389 + $ldap_log = false + $ldap_config_variables = {} +- $stomp_port = '6163' ++ $stomp_port = 6163 + $stomp_ssl_only = false + $wipe_db_on_cookie_change = false + $cluster_partition_handling = 'ignore' +@@ -134,7 +134,7 @@ class rabbitmq::params { + $config_management_variables = {} + $config_additional_variables = {} + $auth_backends = undef +- $file_limit = '16384' ++ $file_limit = 16384 + $collect_statistics_interval = undef + $ipv6 = false + $inetrc_config = 'rabbitmq/inetrc.erb' +diff --git a/metadata.json b/metadata.json +index 5803cf5..b3426f6 100644 +--- a/metadata.json ++++ b/metadata.json +@@ -48,7 +48,6 @@ + ], + "dependencies": [ + {"name":"puppetlabs/stdlib","version_requirement":">= 3.13.1 < 5.0.0"}, +- {"name":"puppetlabs/apt","version_requirement":">= 1.8.0 < 5.0.0"}, + {"name":"puppet/staging","version_requirement":">= 0.3.1 < 2.0.0"} + ] + } +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0004-Partially-revert-upstream-commit-f7c3a4a637d59f3065d.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0004-Partially-revert-upstream-commit-f7c3a4a637d59f3065d.patch new file mode 100644 index 000000000..4575722f6 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0004-Partially-revert-upstream-commit-f7c3a4a637d59f3065d.patch @@ -0,0 +1,32 @@ +From 5c8fa2301ee9fa92267ff351e3fa3e59f2b2df79 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Wed, 24 Jan 2018 16:01:48 -0600 +Subject: [PATCH] Partially revert upstream commit + f7c3a4a637d59f3065d8129e9ebacba992dfc469 + +Upstream converted the code based on rabbitmqctl 3.6.10 changes +We are using 3.6.5 but hopefully this expression will match both + +Status of node rabbit@localhost ... +or +Status of node rabbit@localhost +--- + lib/facter/rabbitmq_nodename.rb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/facter/rabbitmq_nodename.rb b/lib/facter/rabbitmq_nodename.rb +index 301e3c1..d5c6352 100644 +--- a/lib/facter/rabbitmq_nodename.rb ++++ b/lib/facter/rabbitmq_nodename.rb +@@ -2,7 +2,7 @@ Facter.add(:rabbitmq_nodename) do + setcode do + if Facter::Core::Execution.which('rabbitmqctl') + rabbitmq_nodename = Facter::Core::Execution.execute('rabbitmqctl status 2>&1') +- %r{^Status of node '?([\w\.]+@[\w\.\-]+)'?}.match(rabbitmq_nodename)[1] ++ %r{^Status of node '?([\w\.]+@[\w\.\-]+)'?( \.+)?$}.match(rabbitmq_nodename)[1] + end + end + end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0005-Remove-the-rabbitmq_nodename-fact.patch b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0005-Remove-the-rabbitmq_nodename-fact.patch new file mode 100644 index 000000000..dbe7ce4de --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/patches/0005-Remove-the-rabbitmq_nodename-fact.patch @@ -0,0 +1,87 @@ +From 02c56be5340b079797fdb9944e1e048f1c3a18b7 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Fri, 2 Feb 2018 12:30:22 -0600 +Subject: [PATCH] Remove the rabbitmq_nodename fact + +This fact will not work on a standby node. it requires a drbd folder in order +for rabbitmqctl status to work. +--- + lib/facter/rabbitmq_nodename.rb | 8 ------ + spec/unit/rabbitmq_nodename_spec.rb | 50 ------------------------------------- + 2 files changed, 58 deletions(-) + delete mode 100644 lib/facter/rabbitmq_nodename.rb + delete mode 100644 spec/unit/rabbitmq_nodename_spec.rb + +diff --git a/lib/facter/rabbitmq_nodename.rb b/lib/facter/rabbitmq_nodename.rb +deleted file mode 100644 +index 2ee7926..0000000 +--- a/lib/facter/rabbitmq_nodename.rb ++++ /dev/null +@@ -1,8 +0,0 @@ +-Facter.add(:rabbitmq_nodename) do +- setcode do +- if Facter::Core::Execution.which('rabbitmqctl') +- rabbitmq_nodename = Facter::Core::Execution.execute('rabbitmqctl status 2>&1') +- %r{^Status of node '?([\w\.]+@[\w\.\-]+)'?( \.+)?$}.match(rabbitmq_nodename)[1] +- end +- end +-end +diff --git a/spec/unit/rabbitmq_nodename_spec.rb b/spec/unit/rabbitmq_nodename_spec.rb +deleted file mode 100644 +index 621d7eb..0000000 +--- a/spec/unit/rabbitmq_nodename_spec.rb ++++ /dev/null +@@ -1,50 +0,0 @@ +-require "spec_helper" +- +-describe Facter::Util::Fact do +- before { +- Facter.clear +- } +- +- describe "rabbitmq_nodename" do +- context 'with value' do +- before :each do +- Facter::Core::Execution.stubs(:which).with('rabbitmqctl').returns(true) +- Facter::Core::Execution.stubs(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty@rabbit1 ...') +- end +- it { +- expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit1') +- } +- end +- +- context 'with dashes in hostname' do +- before :each do +- Facter::Core::Execution.stubs(:which).with('rabbitmqctl').returns(true) +- Facter::Core::Execution.stubs(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty@rabbit-1 ...') +- end +- it { +- expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1') +- } +- end +- +- context 'with quotes around node name' do +- before :each do +- Facter::Core::Execution.stubs(:which).with('rabbitmqctl').returns(true) +- Facter::Core::Execution.stubs(:execute).with('rabbitmqctl status 2>&1').returns('Status of node \'monty@rabbit-1\' ...') +- end +- it { +- expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1') +- } +- end +- +- context 'without trailing points' do +- before :each do +- Facter::Core::Execution.stubs(:which).with('rabbitmqctl').returns(true) +- Facter::Core::Execution.stubs(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty@rabbit-1') +- end +- it { +- expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1') +- } +- end +- +- end +-end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/srpm_path b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/srpm_path new file mode 100644 index 000000000..4ff2a8cd5 --- /dev/null +++ b/devtools/puppet-modules/puppet-rabbitmq-5.5.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-rabbitmq-5.6.0-4.5ac45degit.el7.src.rpm diff --git a/devtools/puppet-modules/puppet-staging/centos/build_srpm.data b/devtools/puppet-modules/puppet-staging/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/devtools/puppet-modules/puppet-staging/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/devtools/puppet-modules/puppet-staging/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/puppet-staging/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..879b3f0af --- /dev/null +++ b/devtools/puppet-modules/puppet-staging/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From a211d6907fdef7106b32acf70e36b6795a155c5b Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 12:53:29 -0600 +Subject: [PATCH 1/2] Update package versioning for TIS format + +--- + SPECS/puppet-staging.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-staging.spec b/SPECS/puppet-staging.spec +index 0848033..0dd5d59 100644 +--- a/SPECS/puppet-staging.spec ++++ b/SPECS/puppet-staging.spec +@@ -8,7 +8,7 @@ + + Name: puppet-staging + Version: 1.0.4 +-Release: 1%{?alphatag}%{?dist} ++Release: 1.b466d93git.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Compressed file staging and deployment + License: Apache-2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-staging/centos/meta_patches/0002-Apply-rename-patch.patch b/devtools/puppet-modules/puppet-staging/centos/meta_patches/0002-Apply-rename-patch.patch new file mode 100644 index 000000000..f7b0120fd --- /dev/null +++ b/devtools/puppet-modules/puppet-staging/centos/meta_patches/0002-Apply-rename-patch.patch @@ -0,0 +1,32 @@ +From 2f7d1d4fd969e529e8efcdcf8ea6c0040e3392e3 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 12:54:34 -0600 +Subject: [PATCH 2/2] Apply rename patch + +--- + SPECS/puppet-staging.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/puppet-staging.spec b/SPECS/puppet-staging.spec +index 0dd5d59..b6c93ce 100644 +--- a/SPECS/puppet-staging.spec ++++ b/SPECS/puppet-staging.spec +@@ -15,6 +15,7 @@ License: Apache-2.0 + URL: https://github.com/nanliu/puppet-staging + + Source0: https://github.com/nanliu/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz ++Patch0001: 0001-Rename-nanliu-staging-to-puppet-staging.patch + + BuildArch: noarch + +@@ -25,6 +26,7 @@ Compressed file staging and deployment + + %prep + %setup -q -n %{name}-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-staging/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/puppet-staging/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..a9ac01563 --- /dev/null +++ b/devtools/puppet-modules/puppet-staging/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Apply-rename-patch.patch diff --git a/devtools/puppet-modules/puppet-staging/centos/patches/0001-Rename-nanliu-staging-to-puppet-staging.patch b/devtools/puppet-modules/puppet-staging/centos/patches/0001-Rename-nanliu-staging-to-puppet-staging.patch new file mode 100644 index 000000000..76f3231cf --- /dev/null +++ b/devtools/puppet-modules/puppet-staging/centos/patches/0001-Rename-nanliu-staging-to-puppet-staging.patch @@ -0,0 +1,28 @@ +From dca28ab0ee1e31d8850ead8f055a53a7ae629cfa Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 4 Jan 2018 12:47:59 -0600 +Subject: [PATCH] Rename nanliu-staging to puppet-staging + +This is the version of puppet-staging shipped with Centos and renaming +this will fix the ModuleLoader warnings in the puppet logs +for puppet-mysql and puppet-postgresql +--- + metadata.json | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/metadata.json b/metadata.json +index a889487..d7b4a81 100644 +--- a/metadata.json ++++ b/metadata.json +@@ -95,7 +95,7 @@ + "version_requirement": ">=2.7.0" + } + ], +- "name": "nanliu-staging", ++ "name": "puppet-staging", + "version": "1.0.4", + "source": "git://github.com/nanliu/puppet-staging", + "author": "Nan Liu", +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-staging/centos/srpm_path b/devtools/puppet-modules/puppet-staging/centos/srpm_path new file mode 100644 index 000000000..da2c9b598 --- /dev/null +++ b/devtools/puppet-modules/puppet-staging/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-staging-1.0.4-1.b466d93git.el7.src.rpm diff --git a/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/build_srpm.data b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..8d667c260 --- /dev/null +++ b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 3b29074ca269b8246a7f9bd5ad8468c1b7e54dc5 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 3 Jan 2017 13:45:43 -0500 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/puppet-stdlib.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/puppet-stdlib.spec b/SPECS/puppet-stdlib.spec +index baab15b..0261e5d 100644 +--- a/SPECS/puppet-stdlib.spec ++++ b/SPECS/puppet-stdlib.spec +@@ -8,7 +8,7 @@ + + Name: puppet-stdlib + Version: 4.13.1 +-Release: 2%{?alphatag}%{?dist} ++Release: 2.dcef77agit.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Standard library of resources for Puppet modules. + License: Apache-2.0 + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0002-Add-TIS-Patches.patch b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0002-Add-TIS-Patches.patch new file mode 100644 index 000000000..234cea67a --- /dev/null +++ b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/0002-Add-TIS-Patches.patch @@ -0,0 +1,33 @@ +From 36f161731c1041805d4d3de98a0f280917692757 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 1 May 2017 14:39:38 -0400 +Subject: [PATCH] Add TIS Patches + +--- + SPECS/puppet-stdlib.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/puppet-stdlib.spec b/SPECS/puppet-stdlib.spec +index 769c0ef..7304088 100644 +--- a/SPECS/puppet-stdlib.spec ++++ b/SPECS/puppet-stdlib.spec +@@ -15,6 +15,8 @@ URL: https://github.com/puppetlabs/puppetlabs-stdlib + + Source0: https://github.com/puppetlabs/%{upstream_name}/archive/%{commit}.tar.gz#/%{upstream_name}-%{shortcommit}.tar.gz + ++Patch0001: 0001-Filter-password-in-logs.patch ++ + BuildArch: noarch + + Requires: puppet >= 2.7.0 +@@ -24,6 +26,7 @@ Standard library of resources for Puppet modules. + + %prep + %setup -q -n %{upstream_name}-%{upstream_version} ++%patch0001 -p1 + + find . -type f -name ".*" -exec rm {} + + find . -size 0 -exec rm {} + +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/PATCH_ORDER b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..0403df317 --- /dev/null +++ b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-Patches.patch diff --git a/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/patches/0001-Filter-password-in-logs.patch b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/patches/0001-Filter-password-in-logs.patch new file mode 100644 index 000000000..73f7267bf --- /dev/null +++ b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/patches/0001-Filter-password-in-logs.patch @@ -0,0 +1,36 @@ +From d95ec2abaa68a1da308c3c8b01c700fcc544a788 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 1 May 2017 14:37:22 -0400 +Subject: [PATCH] Filter password in logs + +--- + lib/puppet/parser/functions/ensure_resource.rb | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/lib/puppet/parser/functions/ensure_resource.rb b/lib/puppet/parser/functions/ensure_resource.rb +index 1ba6a44..b9c3242 100644 +--- a/lib/puppet/parser/functions/ensure_resource.rb ++++ b/lib/puppet/parser/functions/ensure_resource.rb +@@ -30,15 +30,17 @@ ENDOFDOC + raise(ArgumentError, 'Must specify a type') unless type + raise(ArgumentError, 'Must specify a title') unless title + params ||= {} ++ filtered_params = Marshal.load(Marshal.dump(params)) # deep copy ++ filtered_params.delete("password") + + items = [title].flatten + + items.each do |item| + Puppet::Parser::Functions.function(:defined_with_params) + if function_defined_with_params(["#{type}[#{item}]", params]) +- Puppet.debug("Resource #{type}[#{item}] with params #{params} not created because it already exists") ++ Puppet.debug("Resource #{type}[#{item}] with params #{filtered_params} not created because it already exists") + else +- Puppet.debug("Create new resource #{type}[#{item}] with params #{params}") ++ Puppet.debug("Create new resource #{type}[#{item}] with params #{filtered_params}") + Puppet::Parser::Functions.function(:create_resources) + function_create_resources([type.capitalize, { item => params }]) + end +-- +1.8.3.1 + diff --git a/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/srpm_path b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/srpm_path new file mode 100644 index 000000000..993db8eb6 --- /dev/null +++ b/devtools/puppet-modules/puppet-stdlib-4.12.0/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/puppet-stdlib-4.13.1-2.dcef77agit.el7.src.rpm diff --git a/devtools/python-setuptools/centos/build_srpm.data b/devtools/python-setuptools/centos/build_srpm.data new file mode 100644 index 000000000..5ec8a3649 --- /dev/null +++ b/devtools/python-setuptools/centos/build_srpm.data @@ -0,0 +1,5 @@ +#python-setuptools-v38.5.1.tar.gz + +COPY_LIST="$CGCS_BASE/downloads/python-setuptools-v38.5.1.tar.gz $PKG_BASE/files/*" + +TIS_PATCH_VER=0 diff --git a/devtools/python-setuptools/centos/python-setuptools.spec b/devtools/python-setuptools/centos/python-setuptools.spec new file mode 100644 index 000000000..630f078a2 --- /dev/null +++ b/devtools/python-setuptools/centos/python-setuptools.spec @@ -0,0 +1,629 @@ +# Dependencies for check and wheel introduce circular dependencies +# Set this to 0 after we've bootstrapped. + +%global with_check 0 +%global build_wheel 0 + +# define some macros for RHEL 6 +%global __python2 %__python +%global python2_sitelib %python_sitelib + +%global srcname setuptools +%if 0%{?build_wheel} +%global python2_wheelname %{srcname}-%{version}-py2.py3-none-any.whl +%global python2_record %{python2_sitelib}/%{srcname}-%{version}.dist-info/RECORD +%if 0%{?with_python3} +%global python3_wheelname %python2_wheelname +%global python3_record %{python3_sitelib}/%{srcname}-%{version}.dist-info/RECORD +%endif +%endif + +Name: python-setuptools +Version: 38.5.1 +Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} +Summary: Easily build and distribute Python packages + +Group: Applications/System +# LIcensing is in flux, see https://bitbucket.org/pypa/setuptools/issues/132/missing-license +License: (Python or ZPLv2.0) and ASL 2.0 +URL: https://pypi.python.org/pypi/%{srcname} +#Source0: https://files.pythonhosted.org/packages/source/s/%{srcname}/%{srcname}-%{version}.tar.gz +Source0: python-setuptools-v38.5.1.tar.gz +# PSFL +#Source1: https://hg.python.org/cpython/raw-file/tip/LICENSE +Source1: LICENSE +# ZPL +#Source2: https://raw.githubusercontent.com/zopefoundation/Zope/master/LICENSE.txt +Source2: LICENSE.txt +# ASL 2.0 +#Source3: http://www.apache.org/licenses/LICENSE-2.0 +Source3: LICENSE-2.0 + +BuildArch: noarch +BuildRequires: python2-devel +%if 0%{?build_wheel} +BuildRequires: python-pip +BuildRequires: python-wheel +%endif +%if 0%{?with_check} +BuildRequires: pytest +BuildRequires: python-mock +%endif # with_check + +%if 0%{?with_python3} +BuildRequires: python3-devel +%if 0%{?with_check} +BuildRequires: python3-pytest +BuildRequires: python3-mock +%endif # with_check +%if 0%{?build_wheel} +BuildRequires: python3-pip +BuildRequires: python3-wheel +%endif # build_wheel +%endif # with_python3 + +# We're now back to setuptools as the package. +# Keep the python-distribute name active for a few releases. Eventually we'll +# want to get rid of the Provides and just keep the Obsoletes +Provides: python-distribute = %{version}-%{release} +Obsoletes: python-distribute < 0.6.36-2 + + +%description +Setuptools is a collection of enhancements to the Python distutils that allow +you to more easily build and distribute Python packages, especially ones that +have dependencies on other packages. + +This package also contains the runtime components of setuptools, necessary to +execute the software that requires pkg_resources.py. + +%package -n python2-setuptools +Summary: Easily build and distribute Python packages +%{?python_provide:%python_provide python2-setuptools} +%description -n python2-setuptools +Setuptools is a collection of enhancements to the Python distutils that allow +you to more easily build and distribute Python packages, especially ones that +have dependencies on other packages. + +This package also contains the runtime components of setuptools, necessary to +execute the software that requires pkg_resources.py. + +%if 0%{?with_python3} +%package -n python3-setuptools +Summary: Easily build and distribute Python 3 packages +Group: Applications/System +%{?python_provide:%python_provide python3-setuptools} + +# Note: Do not need to Require python3-backports-ssl_match_hostname because it +# has been present since python3-3.2. We do not ship python3-3.0 or +# python3-3.1 anywhere + +%description -n python3-setuptools +Setuptools is a collection of enhancements to the Python 3 distutils that allow +you to more easily build and distribute Python 3 packages, especially ones that +have dependencies on other packages. + +This package also contains the runtime components of setuptools, necessary to +execute the software that requires pkg_resources.py. + +%endif # with_python3 + +%prep +%setup -q -n %{srcname}-%{version} + +# We can't remove .egg-info (but it doesn't matter, since it'll be rebuilt): +# The problem is that to properly execute setuptools' setup.py, +# it is needed for setuptools to be loaded as a Distribution +# (with egg-info or .dist-info dir), it's not sufficient +# to just have them on PYTHONPATH +# Running "setup.py install" without having setuptools installed +# as a distribution gives warnings such as +# ... distutils/dist.py:267: UserWarning: Unknown distribution option: 'entry_points' +# and doesn't create "easy_install" and .egg-info directory +# Note: this is only a problem if bootstrapping wheel or building on RHEL, +# otherwise setuptools are installed as dependency into buildroot + +# Strip shbang +find setuptools -name \*.py | xargs sed -i -e '1 {/^#!\//d}' +# Remove bundled exes +rm -f setuptools/*.exe +# These tests require internet connection +rm setuptools/tests/test_integration.py + +%build +%if 0%{?build_wheel} +%{__python} setup.py bdist_wheel +%else +export PBR_VERSION=%{version} +%{__python} bootstrap.py +%{__python} setup.py build +%endif + +%if 0%{?with_python3} +%if 0%{?build_wheel} +%{__python3} setup.py bdist_wheel +%else +%{__python3} setup.py build +%endif +%endif # with_python3 + +%install +# Must do the python3 install first because the scripts in /usr/bin are +# overwritten with every setup.py install (and we want the python2 version +# to be the default for now). +%if 0%{?with_python3} +%if 0%{?build_wheel} +pip3 install -I dist/%{python3_wheelname} --root %{buildroot} --strip-file-prefix %{buildroot} + +# TODO: we have to remove this by hand now, but it'd be nice if we wouldn't have to +# (pip install wheel doesn't overwrite) +rm %{buildroot}%{_bindir}/easy_install + +sed -i '/\/usr\/bin\/easy_install,/d' %{buildroot}%{python3_record} +%else +%{__python3} setup.py install --skip-build --root %{buildroot} +%endif + +rm -rf %{buildroot}%{python3_sitelib}/setuptools/tests +%if 0%{?build_wheel} +sed -i '/^setuptools\/tests\//d' %{buildroot}%{python3_record} +%endif + +find %{buildroot}%{python3_sitelib} -name '*.exe' | xargs rm -f +%endif # with_python3 + +%if 0%{?build_wheel} +pip2 install -I dist/%{python2_wheelname} --root %{buildroot} --strip-file-prefix %{buildroot} +%else +%{__python2} setup.py install --skip-build --root %{buildroot} +%endif + +rm -rf %{buildroot}%{python2_sitelib}/setuptools/tests +%if 0%{?build_wheel} +sed -i '/^setuptools\/tests\//d' %{buildroot}%{python2_record} +%endif + +install -p -m 0644 %{SOURCE1} psfl.txt +install -p -m 0644 %{SOURCE2} zpl.txt +install -p -m 0644 %{SOURCE3} asl.txt +find %{buildroot}%{python2_sitelib} -name '*.exe' | xargs rm -f + +# Don't ship these +rm -r docs/{Makefile,conf.py,_*} + +%if 0%{?with_check} +%check +LANG=en_US.utf8 PYTHONPATH=$(pwd) py.test + +%if 0%{?with_python3} +LANG=en_US.utf8 PYTHONPATH=$(pwd) py.test-%{python3_version} +%endif # with_python3 +%endif # with_check + +%files -n python2-setuptools +%license psfl.txt zpl.txt asl.txt +%doc docs/* +%{python2_sitelib}/* +%{_bindir}/easy_install +%{_bindir}/easy_install-2.* + +%if 0%{?with_python3} +%files -n python3-setuptools +%license psfl.txt zpl.txt asl.txt +%doc docs/* +%{python3_sitelib}/easy_install.py +%{python3_sitelib}/pkg_resources/ +%{python3_sitelib}/setuptools*/ +%{python3_sitelib}/__pycache__/* +%{_bindir}/easy_install-3.* +%endif # with_python3 + +%changelog +* Tue Jun 07 2016 Kevin Fenzi - 22.0.5-1 +- Update to 22.0.5. Fixes bug #1342706 + +* Thu Jun 02 2016 Kevin Fenzi - 20.0.0-1 +- Upgrade to 22.0.0 + +* Tue May 31 2016 Nils Philippsen +- fix source URL + +* Sun May 29 2016 Kevin Fenzi - 21.2.2-1 +- Update to 21.2.2. Fixes bug #1332357 + +* Thu Apr 28 2016 Kevin Fenzi - 20.10.1-1 +- Update to 20.10.1. Fixes bug #1330375 + +* Sat Apr 16 2016 Kevin Fenzi - 20.9.0-1 +- Update to 20.9.0. Fixes bug #1327827 + +* Fri Apr 15 2016 Kevin Fenzi - 20.8.1-1 +- Update to 20.8.1. Fixes bug #1325910 + +* Thu Mar 31 2016 Kevin Fenzi - 20.6.7-1 +- Update to 20.6.7. Fixes bug #1322836 + +* Wed Mar 30 2016 Kevin Fenzi - 20.4-1 +- Update to 20.4. Fixes bug #1319366 + +* Wed Mar 16 2016 Kevin Fenzi - 20.3-1 +- Update to 20.3. Fixes bug #1311967 + +* Sat Feb 27 2016 Kevin Fenzi - 20.2.2-1 +- Update to 20.2.2. Fixes bug #1311967 + +* Sat Feb 13 2016 Kevin Fenzi - 20.1.1-1 +- Update to 20.1.1. Fixes bug #130719 + +* Fri Feb 12 2016 Kevin Fenzi - 20.1-1 +- Update to 20.1. Fixes bug #1307000 + +* Mon Feb 08 2016 Kevin Fenzi - 20.0-1 +- Update to 20.0. Fixes bug #1305394 + +* Sat Feb 06 2016 Kevin Fenzi - 19.7-1 +- Update to 19.7. Fixes bug #1304563 + +* Wed Feb 3 2016 Orion Poplawski - 19.6.2-2 +- Fix python3 package file ownership + +* Sun Jan 31 2016 Kevin Fenzi - 19.6.2-1 +- Update to 19.6.2. Fixes bug #1303397 + +* Mon Jan 25 2016 Kevin Fenzi - 19.6-1 +- Update to 19.6. + +* Mon Jan 25 2016 Kevin Fenzi - 19.5-1 +- Update to 19.5. Fixes bug #1301313 + +* Mon Jan 18 2016 Kevin Fenzi - 19.4-1 +- Update to 19.4. Fixes bug #1299288 + +* Tue Jan 12 2016 Orion Poplawski - 19.2-2 +- Cleanup spec from python3-setuptools review + +* Fri Jan 08 2016 Kevin Fenzi - 19.2-1 +- Update to 19.2. Fixes bug #1296755 + +* Fri Dec 18 2015 Kevin Fenzi - 19.1.1-1 +- Update to 19.1.1. Fixes bug #1292658 + +* Tue Dec 15 2015 Kevin Fenzi - 18.8.1-1 +- Update to 18.8.1. Fixes bug #1291678 + +* Sat Dec 12 2015 Kevin Fenzi - 18.8-1 +- Update to 18.8. Fixes bug #1290942 + +* Fri Dec 04 2015 Kevin Fenzi - 18.7.1-1 +- Update to 18.7.1. Fixes bug #1287372 + +* Wed Nov 25 2015 Kevin Fenzi - 18.6.1-1 +- Update to 18.6.1. Fixes bug #1270578 + +* Sun Nov 15 2015 Thomas Spura - 18.5-3 +- Try to disable zip_safe bug #1271776 +- Add python2 subpackage + +* Fri Nov 06 2015 Robert Kuska - 18.5-2 +- Add patch so it is possible to set test_args variable + +* Tue Nov 03 2015 Robert Kuska - 18.5-1 +- Update to 18.5. Fixes bug #1270578 + +* Tue Oct 13 2015 Robert Kuska - 18.4-1 +- Update to 18.4. Fixes bug #1270578 +- Build with wheel and check phase + +* Wed Sep 23 2015 Robert Kuska - 18.3.2-2 +- Python3.5 rebuild: rebuild without wheel and check phase + +* Tue Sep 22 2015 Kevin Fenzi 18.3.2-1 +- Update to 18.3.2. Fixes bug #1264902 + +* Mon Sep 07 2015 Kevin Fenzi 18.3.1-1 +- Update to 18.3.1. Fixes bug #1256188 + +* Wed Aug 05 2015 Kevin Fenzi 18.1-1 +- Update to 18.1. Fixes bug #1249436 + +* Mon Jun 29 2015 Pierre-Yves Chibon - 18.0.1-2 +- Explicitely provide python2-setuptools + +* Thu Jun 25 2015 Kevin Fenzi 18.0.1-1 +- Update to 18.0.1 + +* Sat Jun 20 2015 Kevin Fenzi 17.1.1-3 +- Drop no longer needed Requires/BuildRequires on python-backports-ssl_match_hostname +- Fixes bug #1231325 + +* Thu Jun 18 2015 Fedora Release Engineering - 17.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Jun 10 2015 Kevin Fenzi 17.1.1-1 +- Update to 17.1.1. Fixes bug 1229507 + +* Sun Jun 07 2015 Kevin Fenzi 17.1-1 +- Update to 17.1. Fixes bug 1229066 + +* Sat May 30 2015 Kevin Fenzi 17.0-1 +- Update to 17 + +* Mon May 18 2015 Kevin Fenzi 16.0-1 +- Update to 16 + +* Mon Apr 27 2015 Ralph Bean - 15.2-1 +- new version + +* Sat Apr 04 2015 Ralph Bean - 15.0-1 +- new version + +* Sun Mar 22 2015 Ralph Bean - 14.3.1-1 +- new version + +* Sat Mar 21 2015 Ralph Bean - 14.3.1-1 +- new version + +* Mon Mar 16 2015 Ralph Bean - 14.3-1 +- new version + +* Sun Mar 15 2015 Ralph Bean - 14.2-1 +- new version + +* Sun Mar 15 2015 Ralph Bean - 14.1.1-1 +- new version + +* Fri Mar 06 2015 Ralph Bean - 13.0.2-1 +- new version + +* Thu Mar 05 2015 Ralph Bean - 12.4-1 +- new version + +* Fri Feb 27 2015 Ralph Bean - 12.3-1 +- new version + +* Tue Jan 20 2015 Kevin Fenzi 12.0.3-1 +- Update to 12.0.3 + +* Fri Jan 09 2015 Slavek Kabrda - 11.3.1-2 +- Huge spec cleanup +- Make spec buildable on all Fedoras and RHEL 6 and 7 +- Make tests actually run + +* Wed Jan 07 2015 Kevin Fenzi 11.3.1-1 +- Update to 11.3.1. Fixes bugs: #1179393 and #1178817 + +* Sun Jan 04 2015 Kevin Fenzi 11.0-1 +- Update to 11.0. Fixes bug #1178421 + +* Fri Dec 26 2014 Kevin Fenzi 8.2.1-1 +- Update to 8.2.1. Fixes bug #1175229 + +* Thu Oct 23 2014 Ralph Bean - 7.0-1 +- Latest upstream. Fixes bug #1154590. + +* Mon Oct 13 2014 Ralph Bean - 6.1-1 +- Latest upstream. Fixes bug #1152130. + +* Sat Oct 11 2014 Ralph Bean - 6.0.2-2 +- Modernized python2 macros. +- Inlined locale environment variables in the %%check section. +- Remove bundled egg-info and .exes. + +* Fri Oct 03 2014 Kevin Fenzi 6.0.2-1 +- Update to 6.0.2 + +* Sat Sep 27 2014 Kevin Fenzi 6.0.1-1 +- Update to 6.0.1. Fixes bug #1044444 + +* Mon Jun 30 2014 Toshio Kuratomi - 2.0-8 +- Remove the python-setuptools-devel Virtual Provides as per this Fedora 21 + Change: http://fedoraproject.org/wiki/Changes/Remove_Python-setuptools-devel + +* Mon Jun 30 2014 Toshio Kuratomi - 2.0-7 +- And another bug in sdist + +* Mon Jun 30 2014 Toshio Kuratomi - 2.0-6 +- Fix a bug in the sdist command + +* Sat Jun 07 2014 Fedora Release Engineering - 2.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri Apr 25 2014 Matej Stuchlik - 2.0-4 +- Rebuild as wheel for Python 3.4 + +* Thu Apr 24 2014 Tomas Radej - 2.0-3 +- Rebuilt for tag f21-python + +* Wed Apr 23 2014 Matej Stuchlik - 2.0-2 +- Add a switch to build setuptools as wheel + +* Mon Dec 9 2013 Toshio Kuratomi - 2.0-1 +- Update to new upstream release with a few things removed from the API: + Changelog: https://pypi.python.org/pypi/setuptools#id139 + +* Mon Nov 18 2013 Toshio Kuratomi - 1.4-1 +- Update to 1.4 that gives easy_install pypi credential handling + +* Thu Nov 7 2013 Toshio Kuratomi - 1.3.1-1 +- Minor upstream update to reign in overzealous warnings + +* Mon Nov 4 2013 Toshio Kuratomi - 1.3-1 +- Upstream update that pulls in our security patches + +* Mon Oct 28 2013 Toshio Kuratomi - 1.1.7-1 +- Update to newer upstream release that has our patch to the unittests +- Fix for http://bugs.python.org/issue17997#msg194950 which affects us since + setuptools copies that code. Changed to use + python-backports-ssl_match_hostname so that future issues can be fixed in + that package. + +* Sat Oct 26 2013 Toshio Kuratomi - 1.1.6-1 +- Update to newer upstream release. Some minor incompatibilities listed but + they should affect few, if any consumers. + +* Sun Aug 04 2013 Fedora Release Engineering - 0.9.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 23 2013 Toshio Kuratomi - 0.9.6-1 +- Upstream update -- just fixes python-2.4 compat + +* Tue Jul 16 2013 Toshio Kuratomi - 0.9.5-1 +- Update to 0.9.5 + - package_index can handle hashes other than md5 + - Fix security vulnerability in SSL certificate validation + - https://bugzilla.redhat.com/show_bug.cgi?id=963260 + +* Fri Jul 5 2013 Toshio Kuratomi - 0.8-1 +- Update to upstream 0.8 release. Codebase now runs on anything from + python-2.4 to python-3.3 without having to be translated by 2to3. + +* Wed Jul 3 2013 Toshio Kuratomi - 0.7.7-1 +- Update to 0.7.7 upstream release + +* Mon Jun 10 2013 Toshio Kuratomi - 0.7.2-2 +- Update to the setuptools-0.7 branch that merges distribute and setuptools + +* Thu Apr 11 2013 Toshio Kuratomi - 0.6.36-1 +- Update to upstream 0.6.36. Many bugfixes + +* Thu Feb 14 2013 Fedora Release Engineering - 0.6.28-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Aug 03 2012 David Malcolm - 0.6.28-3 +- rebuild for https://fedoraproject.org/wiki/Features/Python_3.3 + +* Fri Aug 3 2012 David Malcolm - 0.6.28-2 +- remove rhel logic from with_python3 conditional + +* Mon Jul 23 2012 Toshio Kuratomi - 0.6.28-1 +- New upstream release: + - python-3.3 fixes + - honor umask when setuptools is used to install other modules + +* Sat Jul 21 2012 Fedora Release Engineering - 0.6.27-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jun 11 2012 Toshio Kuratomi - 0.6.27-2 +- Fix easy_install.py having a python3 shebang in the python2 package + +* Thu Jun 7 2012 Toshio Kuratomi - 0.6.27-1 +- Upstream bugfix + +* Tue May 15 2012 Toshio Kuratomi - 0.6.24-2 +- Upstream bugfix + +* Sat Jan 14 2012 Fedora Release Engineering - 0.6.24-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Oct 17 2011 Toshio Kuratomi - 0.6.24-1 +- Upstream bugfix +- Compile the win32 launcher binary using mingw + +* Sun Aug 21 2011 Toshio Kuratomi - 0.6.21-1 +- Upstream bugfix release + +* Thu Jul 14 2011 Toshio Kuratomi - 0.6.19-1 +- Upstream bugfix release + +* Tue Feb 22 2011 Toshio Kuratomi - 0.6.14-7 +- Switch to patch that I got in to upstream + +* Tue Feb 22 2011 Toshio Kuratomi - 0.6.14-6 +- Fix build on python-3.2 + +* Wed Feb 09 2011 Fedora Release Engineering - 0.6.14-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sun Aug 22 2010 Thomas Spura - 0.6.14-4 +- rebuild with python3.2 + http://lists.fedoraproject.org/pipermail/devel/2010-August/141368.html + +* Tue Aug 10 2010 Toshio Kuratomi - 0.6.14-3 +- Update description to mention this is distribute + +* Thu Jul 22 2010 Thomas Spura - 0.6.14-2 +- bump for building against python 2.7 + +* Thu Jul 22 2010 Thomas Spura - 0.6.14-1 +- update to new version +- all patches are upsteam + +* Wed Jul 21 2010 David Malcolm - 0.6.13-7 +- generalize path of easy_install-2.6 and -3.1 to -2.* and -3.* + +* Wed Jul 21 2010 David Malcolm - 0.6.13-6 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Sat Jul 3 2010 Toshio Kuratomi - 0.6.13-5 +- Upstream patch for compatibility problem with setuptools +- Minor spec cleanups +- Provide python-distribute for those who see an import distribute and need + to get the proper package. + +* Thu Jun 10 2010 Toshio Kuratomi - 0.6.13-4 +- Fix race condition in unittests under the python-2.6.x on F-14. + +* Thu Jun 10 2010 Toshio Kuratomi - 0.6.13-3 +- Fix few more buildroot macros + +* Thu Jun 10 2010 Toshio Kuratomi - 0.6.13-2 +- Include data that's needed for running tests + +* Thu Jun 10 2010 Toshio Kuratomi - 0.6.13-1 +- Update to upstream 0.6.13 +- Minor specfile formatting fixes + +* Thu Feb 04 2010 Toshio Kuratomi - 0.6.10-3 +- First build with python3 support enabled. + +* Fri Jan 29 2010 Toshio Kuratomi - 0.6.10-2 +- Really disable the python3 portion + +* Fri Jan 29 2010 Toshio Kuratomi - 0.6.10-1 +- Update the python3 portions but disable for now. +- Update to 0.6.10 +- Remove %%pre scriptlet as the file has a different name than the old + package's directory + +* Tue Jan 26 2010 Toshio Kuratomi - 0.6.9-4 +- Fix install to make /usr/bin/easy_install the py2 version +- Don't need python3-tools since the library is now in the python3 package +- Few other changes to cleanup style + +* Fri Jan 22 2010 David Malcolm - 0.6.9-2 +- add python3 subpackage + +* Mon Dec 14 2009 Toshio Kuratomi - 0.6.9-1 +- New upstream bugfix release. + +* Sun Dec 13 2009 Toshio Kuratomi - 0.6.8-2 +- Test rebuild + +* Mon Nov 16 2009 Toshio Kuratomi - 0.6.8-1 +- Update to 0.6.8. +- Fix directory => file transition when updating from setuptools-0.6c9. + +* Tue Nov 3 2009 Toshio Kuratomi - 0.6.7-2 +- Fix duplicate inclusion of files. +- Only Obsolete old versions of python-setuptools-devel + +* Tue Nov 3 2009 Toshio Kuratomi - 0.6.7-1 +- Move easy_install back into the main package as the needed files have been + moved from python-devel to the main python package. +- Update to 0.6.7 bugfix. + +* Fri Oct 16 2009 Toshio Kuratomi - 0.6.6-1 +- Upstream bugfix release. + +* Mon Oct 12 2009 Toshio Kuratomi - 0.6.4-1 +- First build from the distribute codebase -- distribute-0.6.4. +- Remove svn patch as upstream has chosen to go with an easier change for now. + +* Sun Jul 26 2009 Fedora Release Engineering - 0.6c9-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 14 2009 Konstantin Ryabitsev - 0.6c9-4 +- Apply SVN-1.6 versioning patch (rhbz #511021) + +* Thu Feb 26 2009 Fedora Release Engineering - 0.6c9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild diff --git a/devtools/python-setuptools/files/LICENSE b/devtools/python-setuptools/files/LICENSE new file mode 100644 index 000000000..84a3337c2 --- /dev/null +++ b/devtools/python-setuptools/files/LICENSE @@ -0,0 +1,255 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations (now Zope +Corporation, see http://www.zope.com). In 2001, the Python Software +Foundation (PSF, see http://www.python.org/psf/) was formed, a +non-profit organization created specifically to own Python-related +Intellectual Property. Zope Corporation is a sponsoring member of +the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016 Python Software Foundation; All Rights +Reserved" are retained in Python alone or in any derivative version prepared by +Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/devtools/python-setuptools/files/LICENSE-2.0 b/devtools/python-setuptools/files/LICENSE-2.0 new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/devtools/python-setuptools/files/LICENSE-2.0 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/devtools/python-setuptools/files/LICENSE.txt b/devtools/python-setuptools/files/LICENSE.txt new file mode 100644 index 000000000..e1f9ad7b3 --- /dev/null +++ b/devtools/python-setuptools/files/LICENSE.txt @@ -0,0 +1,44 @@ +Zope Public License (ZPL) Version 2.1 + +A copyright notice accompanies this license document that identifies the +copyright holders. + +This license has been certified as open source. It has also been designated as +GPL compatible by the Free Software Foundation (FSF). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions in source code must retain the accompanying copyright +notice, this list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the accompanying copyright +notice, this list of conditions, and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. Names of the copyright holders must not be used to endorse or promote +products derived from this software without prior written permission from the +copyright holders. + +4. The right to distribute this software or to use it for any purpose does not +give you the right to use Servicemarks (sm) or Trademarks (tm) of the +copyright +holders. Use of them is covered by separate agreement with the copyright +holders. + +5. If any files are modified, you must cause the modified files to carry +prominent notices stating that you changed the files and the date of any +change. + +Disclaimer + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/devtools/python/python-django/centos/build_srpm.data b/devtools/python/python-django/centos/build_srpm.data new file mode 100644 index 000000000..e9b2ca7d7 --- /dev/null +++ b/devtools/python/python-django/centos/build_srpm.data @@ -0,0 +1,3 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=4 +BUILD_IS_SLOW=2 diff --git a/devtools/python/python-django/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/python/python-django/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..9650530af --- /dev/null +++ b/devtools/python/python-django/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 487be212ccf9debb2c15dcc360ee4c429779b6d0 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 26 Sep 2016 17:50:11 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/python-django.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/python-django.spec b/SPECS/python-django.spec +index d0e54bb..5cf8579 100644 +--- a/SPECS/python-django.spec ++++ b/SPECS/python-django.spec +@@ -29,7 +29,7 @@ + Name: python-django + + Version: 1.8.14 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: A high-level Python Web framework + + Group: Development/Languages +-- +1.8.3.1 + diff --git a/devtools/python/python-django/centos/meta_patches/PATCH_ORDER b/devtools/python/python-django/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..8d18985c6 --- /dev/null +++ b/devtools/python/python-django/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,5 @@ +spec-include-TiS-patches.patch +0001-Update-package-versioning-for-TIS-format.patch +fix-build-failures-due-to-unwanted-sgid.patch +meta-size-number-format.patch +spec-patch-to-remove-SmartyPants.patch \ No newline at end of file diff --git a/devtools/python/python-django/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch b/devtools/python/python-django/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch new file mode 100644 index 000000000..412bb9b66 --- /dev/null +++ b/devtools/python/python-django/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch @@ -0,0 +1,26 @@ +From 8b52d5a27b4c288aa2167968b1d570e3caba6245 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Fri, 18 Nov 2016 14:02:39 -0500 +Subject: [PATCH 1/1] python-django-bash-completion: fix build failures due to + unwanted sgid bit + +--- + SPECS/python-django.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/python-django.spec b/SPECS/python-django.spec +index 5cf8579..79557de 100644 +--- a/SPECS/python-django.spec ++++ b/SPECS/python-django.spec +@@ -421,6 +421,8 @@ popd + %doc docs/_build/html/* + + %files bash-completion ++%dir %attr(0755,root,root) %{_datadir}/bash-completion ++%dir %attr(0755,root,root) %{_datadir}/bash-completion/completions + %{_datadir}/bash-completion + + %if 0%{?with_python3} +-- +1.8.3.1 + diff --git a/devtools/python/python-django/centos/meta_patches/meta-size-number-format.patch b/devtools/python/python-django/centos/meta_patches/meta-size-number-format.patch new file mode 100644 index 000000000..20b00cf38 --- /dev/null +++ b/devtools/python/python-django/centos/meta_patches/meta-size-number-format.patch @@ -0,0 +1,32 @@ +From 8145058f9ee3042cbc2214751333b25a9eafedf0 Mon Sep 17 00:00:00 2001 +From: Wei Zhou +Date: Wed, 11 Oct 2017 22:23:10 -0500 +Subject: [PATCH 1/1] meta size number format + +--- + SPECS/python-django.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/python-django.spec b/SPECS/python-django.spec +index 79557de..5bef0ec 100644 +--- a/SPECS/python-django.spec ++++ b/SPECS/python-django.spec +@@ -41,6 +41,7 @@ Patch0: python-django-1.8.3-shell-completion.patch + + # WRS + Patch1: session-filebase-backend-fix.patch ++Patch2: size-number-format.patch + + BuildArch: noarch + BuildRequires: python2-devel +@@ -154,6 +155,7 @@ rm -rf Django.egg-info + + # WRS + %patch1 -p1 ++%patch2 -p1 + + # empty files + for f in \ +-- +1.8.3.1 + diff --git a/devtools/python/python-django/centos/meta_patches/spec-include-TiS-patches.patch b/devtools/python/python-django/centos/meta_patches/spec-include-TiS-patches.patch new file mode 100644 index 000000000..b93bbfe15 --- /dev/null +++ b/devtools/python/python-django/centos/meta_patches/spec-include-TiS-patches.patch @@ -0,0 +1,36 @@ +From 6cee1f687c1148254fcddc34a7f7de334a26dba1 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Fri, 26 Aug 2016 15:10:15 -0400 +Subject: [PATCH 1/1] WRS: spec-include-TiS-patches.patch + +--- + SPECS/python-django.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/python-django.spec b/SPECS/python-django.spec +index 269991d..d0e54bb 100644 +--- a/SPECS/python-django.spec ++++ b/SPECS/python-django.spec +@@ -39,6 +39,9 @@ Source0: https://files.pythonhosted.org/packages/source/D/Django/Django-% + + Patch0: python-django-1.8.3-shell-completion.patch + ++# WRS ++Patch1: session-filebase-backend-fix.patch ++ + BuildArch: noarch + BuildRequires: python2-devel + +@@ -149,6 +152,9 @@ rm -rf Django.egg-info + + %patch0 + ++# WRS ++%patch1 -p1 ++ + # empty files + for f in \ + django/contrib/staticfiles/models.py \ +-- +1.9.1 + diff --git a/devtools/python/python-django/centos/meta_patches/spec-patch-to-remove-SmartyPants.patch b/devtools/python/python-django/centos/meta_patches/spec-patch-to-remove-SmartyPants.patch new file mode 100644 index 000000000..e98189aa1 --- /dev/null +++ b/devtools/python/python-django/centos/meta_patches/spec-patch-to-remove-SmartyPants.patch @@ -0,0 +1,20 @@ +diff --git a/SPECS/python-django.spec b/SPECS/python-django.spec +index 5bef0ec..827d08f 100644 +--- a/SPECS/python-django.spec ++++ b/SPECS/python-django.spec +@@ -42,6 +42,7 @@ Patch0: python-django-1.8.3-shell-completion.patch + # WRS + Patch1: session-filebase-backend-fix.patch + Patch2: size-number-format.patch ++Patch3: remove-SmartyPantsHTMLTranslator.patch + + BuildArch: noarch + BuildRequires: python2-devel +@@ -156,6 +157,7 @@ rm -rf Django.egg-info + # WRS + %patch1 -p1 + %patch2 -p1 ++%patch3 -p1 + + # empty files + for f in \ diff --git a/devtools/python/python-django/centos/patches/remove-SmartyPantsHTMLTranslator.patch b/devtools/python/python-django/centos/patches/remove-SmartyPantsHTMLTranslator.patch new file mode 100644 index 000000000..fac77b181 --- /dev/null +++ b/devtools/python/python-django/centos/patches/remove-SmartyPantsHTMLTranslator.patch @@ -0,0 +1,50 @@ +From 3624581259cecf7ca2d695fbebc27fed2a4d941c Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 5 Oct 2017 16:38:20 -0400 +Subject: [PATCH] No smartypants + + +diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py +index fd93194..aa3afbb 100644 +--- a/docs/_ext/djangodocs.py ++++ b/docs/_ext/djangodocs.py +@@ -12,7 +12,7 @@ from sphinx.builders.html import StandaloneHTMLBuilder + from sphinx.util.compat import Directive + from sphinx.util.console import bold + from sphinx.util.nodes import set_source_info +-from sphinx.writers.html import SmartyPantsHTMLTranslator ++from sphinx.writers.html import HTMLTranslator + + # RE for option descriptions without a '--' prefix + simple_option_desc_re = re.compile( +@@ -227,7 +227,7 @@ class VersionDirective(Directive): + return ret + + +-class DjangoHTMLTranslator(SmartyPantsHTMLTranslator): ++class DjangoHTMLTranslator(HTMLTranslator): + """ + Django-specific reST to HTML tweaks. + """ +@@ -260,10 +260,10 @@ class DjangoHTMLTranslator(SmartyPantsHTMLTranslator): + # + def visit_literal_block(self, node): + self.no_smarty += 1 +- SmartyPantsHTMLTranslator.visit_literal_block(self, node) ++ HTMLTranslator.visit_literal_block(self, node) + + def depart_literal_block(self, node): +- SmartyPantsHTMLTranslator.depart_literal_block(self, node) ++ HTMLTranslator.depart_literal_block(self, node) + self.no_smarty -= 1 + + # +@@ -300,7 +300,7 @@ class DjangoHTMLTranslator(SmartyPantsHTMLTranslator): + old_ids = node.get('ids', []) + node['ids'] = ['s-' + i for i in old_ids] + node['ids'].extend(old_ids) +- SmartyPantsHTMLTranslator.visit_section(self, node) ++ HTMLTranslator.visit_section(self, node) + node['ids'] = old_ids + + diff --git a/devtools/python/python-django/centos/patches/size-number-format.patch b/devtools/python/python-django/centos/patches/size-number-format.patch new file mode 100644 index 000000000..67d2cd3ab --- /dev/null +++ b/devtools/python/python-django/centos/patches/size-number-format.patch @@ -0,0 +1,25 @@ +diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py +index cd2457d..dc10ea3 100644 +--- a/django/template/defaultfilters.py ++++ b/django/template/defaultfilters.py +@@ -905,15 +905,15 @@ def filesizeformat(bytes): + if bytes < KB: + value = ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes} + elif bytes < MB: +- value = ugettext("%s KB") % filesize_number_format(bytes / KB) ++ value = ugettext("%s KiB") % filesize_number_format(bytes / KB) + elif bytes < GB: +- value = ugettext("%s MB") % filesize_number_format(bytes / MB) ++ value = ugettext("%s MiB") % filesize_number_format(bytes / MB) + elif bytes < TB: +- value = ugettext("%s GB") % filesize_number_format(bytes / GB) ++ value = ugettext("%s GiB") % filesize_number_format(bytes / GB) + elif bytes < PB: +- value = ugettext("%s TB") % filesize_number_format(bytes / TB) ++ value = ugettext("%s TiB") % filesize_number_format(bytes / TB) + else: +- value = ugettext("%s PB") % filesize_number_format(bytes / PB) ++ value = ugettext("%s PiB") % filesize_number_format(bytes / PB) + + return avoid_wrapping(value) + diff --git a/devtools/python/python-django/centos/srpm_path b/devtools/python/python-django/centos/srpm_path new file mode 100644 index 000000000..1b60de931 --- /dev/null +++ b/devtools/python/python-django/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/python-django-1.8.14-1.el7.src.rpm diff --git a/devtools/python/python-django/files/session-filebase-backend-fix.patch b/devtools/python/python-django/files/session-filebase-backend-fix.patch new file mode 100644 index 000000000..993d2fb42 --- /dev/null +++ b/devtools/python/python-django/files/session-filebase-backend-fix.patch @@ -0,0 +1,55 @@ +From 1ab6e8cd0031813aa2b70847d6b54f294d8f90f5 Mon Sep 17 00:00:00 2001 +From: Giao Le +Date: Mon, 11 Jul 2016 16:20:13 -0400 +Subject: [PATCH 1/1] session-filebase-backend-fix + +--- + Django-1.8.7 | 1 + + django/contrib/sessions/backends/file.py | 15 ++++++++++++--- + 2 files changed, 13 insertions(+), 3 deletions(-) + create mode 120000 Django-1.8.7 + +diff --git a/Django-1.8.7 b/Django-1.8.7 +new file mode 120000 +index 0000000..2fa6e7c +--- /dev/null ++++ b/Django-1.8.7 +@@ -0,0 +1 @@ ++Django-1.8.7 +\ No newline at end of file +diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py +index 41469c4..2b10b3e 100644 +--- a/django/contrib/sessions/backends/file.py ++++ b/django/contrib/sessions/backends/file.py +@@ -71,6 +71,17 @@ class SessionStore(SessionBase): + modification = datetime.datetime.fromtimestamp(modification) + return modification + ++ def _expiry_date(self, session_data): ++ """ ++ Return the expiry time of the file storing the session's content. ++ """ ++ expiry = session_data.get('_session_expiry') ++ if not expiry: ++ expiry = self._last_modification() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE) ++ elif not isinstance(expiry, datetime.datetime): ++ expiry = self._last_modification() + datetime.timedelta(seconds=expiry) ++ return expiry ++ + def load(self): + session_data = {} + try: +@@ -89,9 +100,7 @@ class SessionStore(SessionBase): + self.create() + + # Remove expired sessions. +- expiry_age = self.get_expiry_age( +- modification=self._last_modification(), +- expiry=session_data.get('_session_expiry')) ++ expiry_age = self.get_expiry_age(expiry=self._expiry_date(session_data)) + if expiry_age < 0: + session_data = {} + self.delete() +-- +1.9.1 + diff --git a/devtools/python/python-django/update-session-filebase-backend.patch b/devtools/python/python-django/update-session-filebase-backend.patch new file mode 100644 index 000000000..ac0dc8434 --- /dev/null +++ b/devtools/python/python-django/update-session-filebase-backend.patch @@ -0,0 +1,73 @@ +--- + django/contrib/sessions/backends/file.py | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +--- a/django/contrib/sessions/backends/file.py ++++ b/django/contrib/sessions/backends/file.py +@@ -6,13 +6,14 @@ import shutil + import tempfile + + from django.conf import settings +-from django.contrib.sessions.backends.base import SessionBase, CreateError, VALID_KEY_CHARS +-from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured ++from django.contrib.sessions.backends.base import ( ++ VALID_KEY_CHARS, CreateError, SessionBase, ++) ++from django.contrib.sessions.exceptions import InvalidSessionKey ++from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation + from django.utils import timezone + from django.utils.encoding import force_text + +-from django.contrib.sessions.exceptions import InvalidSessionKey +- + + class SessionStore(SessionBase): + """ +@@ -70,6 +71,15 @@ class SessionStore(SessionBase): + modification = datetime.datetime.fromtimestamp(modification) + return modification + ++ def _expiry_date(self, session_data): ++ """ ++ Return the expiry time of the file storing the session's content. ++ """ ++ expiry = session_data.get('_session_expiry') ++ if not expiry: ++ expiry = self._last_modification() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE) ++ return expiry ++ + def load(self): + session_data = {} + try: +@@ -88,15 +98,13 @@ class SessionStore(SessionBase): + self.create() + + # Remove expired sessions. +- expiry_age = self.get_expiry_age( +- modification=self._last_modification(), +- expiry=session_data.get('_session_expiry')) +- if expiry_age < 0: ++ expiry_age = self.get_expiry_age(expiry=self._expiry_date(session_data)) ++ if expiry_age <= 0: + session_data = {} + self.delete() + self.create() + except (IOError, SuspiciousOperation): +- self.create() ++ self._session_key = None + return session_data + + def create(self): +@@ -107,10 +115,11 @@ class SessionStore(SessionBase): + except CreateError: + continue + self.modified = True +- self._session_cache = {} + return + + def save(self, must_create=False): ++ if self.session_key is None: ++ return self.create() + # Get the session data now, before we start messing + # with the file it is stored within. + session_data = self._get_session(no_load=must_create) diff --git a/devtools/python/python-eventlet_0.17.3/throttle_response_logs.patch b/devtools/python/python-eventlet_0.17.3/throttle_response_logs.patch new file mode 100644 index 000000000..8788f951d --- /dev/null +++ b/devtools/python/python-eventlet_0.17.3/throttle_response_logs.patch @@ -0,0 +1,18 @@ +diff --git a/eventlet/wsgi.py b/eventlet/wsgi.py +index 7258277..057ef64 100644 +--- a/eventlet/wsgi.py ++++ b/eventlet/wsgi.py +@@ -512,7 +512,12 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler): + hook(self.environ, *args, **kwargs) + + if self.server.log_output: +- self.server.log.info(self.server.log_format % { ++ if (self.requestline.startswith('GET') and ++ (status_code[0] == '200')): ++ logger = self.server.log.debug ++ else: ++ logger = self.server.log.info ++ logger(self.server.log_format % { + 'client_ip': self.get_client_ip(), + 'client_port': self.client_address[1], + 'date_time': self.log_date_time_string(), diff --git a/devtools/python/python-nose_1.3.0/enable-logging-realtime.patch b/devtools/python/python-nose_1.3.0/enable-logging-realtime.patch new file mode 100644 index 000000000..3e502ab1a --- /dev/null +++ b/devtools/python/python-nose_1.3.0/enable-logging-realtime.patch @@ -0,0 +1,48 @@ +--- + nose/plugins/logcapture.py | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/nose/plugins/logcapture.py ++++ b/nose/plugins/logcapture.py +@@ -110,6 +110,8 @@ class LogCapture(Plugin): + logdatefmt = None + clear = False + filters = ['-nose'] ++ realtime = False ++ + + def options(self, parser, env): + """Register commandline options. +@@ -156,6 +158,10 @@ class LogCapture(Plugin): + "--logging-level", action="store", + default='NOTSET', dest="logcapture_level", + help="Set the log level to capture") ++ parser.add_option( ++ "--logging-realtime", action="store_true", ++ default=False, dest="logcapture_realtime", ++ help="Set to display log in realtime") + + def configure(self, options, conf): + """Configure plugin. +@@ -171,6 +177,7 @@ class LogCapture(Plugin): + self.loglevel = options.logcapture_level + if options.logcapture_filters: + self.filters = options.logcapture_filters.split(',') ++ self.logrealtime = options.logcapture_realtime + + def setupLoghandler(self): + # setup our handler with root logger +@@ -193,6 +200,12 @@ class LogCapture(Plugin): + if isinstance(handler, MyMemoryHandler): + root_logger.handlers.remove(handler) + root_logger.addHandler(self.handler) ++ ++ # added to see realtime logging - 31 Oct 2014 ++ # add stderr output ++ if self.logrealtime: ++ root_logger.addHandler(logging.StreamHandler()) ++ + # to make sure everything gets captured + loglevel = getattr(self, "loglevel", "NOTSET") + root_logger.setLevel(getattr(logging, loglevel)) + diff --git a/devtools/python/python-rtstool-0.1a4/fix-build-error.patch b/devtools/python/python-rtstool-0.1a4/fix-build-error.patch new file mode 100644 index 000000000..c9315cb61 --- /dev/null +++ b/devtools/python/python-rtstool-0.1a4/fix-build-error.patch @@ -0,0 +1,15 @@ +--- + setup.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/setup.py ++++ b/setup.py +@@ -15,7 +15,7 @@ + # under the License. + + +-from distutils.core import setup ++from setuptools import setup + + setup(name='rtstool', + version='0.1a4', diff --git a/devtools/python/python-sqlalchemy_0.9.9/sqlalchemy_queue_pool_info.patch b/devtools/python/python-sqlalchemy_0.9.9/sqlalchemy_queue_pool_info.patch new file mode 100644 index 000000000..9ab977ab7 --- /dev/null +++ b/devtools/python/python-sqlalchemy_0.9.9/sqlalchemy_queue_pool_info.patch @@ -0,0 +1,33 @@ +--- + lib/sqlalchemy/pool.py | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/lib/sqlalchemy/pool.py ++++ b/lib/sqlalchemy/pool.py +@@ -435,6 +435,17 @@ class _ConnectionRecord(object): + """ + return {} + ++ @property ++ def pool_info(self): ++ """The ``.pool_info`` dictionary associated with the DBAPI connection. ++ """ ++ pool_info = dict() ++ pool_info['Pool size'] = self.__pool.size() ++ pool_info['Connections'] = self.__pool.checkedin() ++ pool_info['Overflow'] = self.__pool.overflow() ++ pool_info['Checkedout'] = self.__pool.checkedout() ++ return pool_info ++ + @classmethod + def checkout(cls, pool): + rec = pool._do_get() +@@ -540,7 +551,7 @@ class _ConnectionRecord(object): + self.__pool.logger.debug("Created new connection %r", connection) + return connection + except Exception as e: +- self.__pool.logger.debug("Error on connect(): %s", e) ++ self.__pool.logger.error("Error on connect(): %s, %s", self.__pool.status(), e) + raise + + diff --git a/devtools/python/python_2.7.3/fix_pipe_leak_in_subprocess.patch b/devtools/python/python_2.7.3/fix_pipe_leak_in_subprocess.patch new file mode 100644 index 000000000..3f84fc46e --- /dev/null +++ b/devtools/python/python_2.7.3/fix_pipe_leak_in_subprocess.patch @@ -0,0 +1,97 @@ +--- + Lib/subprocess.py | 33 +++++++++++++++++++++++++++------ + Lib/test/test_subprocess.py | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+), 6 deletions(-) + +--- a/Lib/subprocess.py ++++ b/Lib/subprocess.py +@@ -671,12 +671,33 @@ class Popen(object): + c2pread, c2pwrite, + errread, errwrite) = self._get_handles(stdin, stdout, stderr) + +- self._execute_child(args, executable, preexec_fn, close_fds, +- cwd, env, universal_newlines, +- startupinfo, creationflags, shell, +- p2cread, p2cwrite, +- c2pread, c2pwrite, +- errread, errwrite) ++ try: ++ self._execute_child(args, executable, preexec_fn, close_fds, ++ cwd, env, universal_newlines, ++ startupinfo, creationflags, shell, ++ p2cread, p2cwrite, ++ c2pread, c2pwrite, ++ errread, errwrite) ++ except Exception: ++ # preserve original exception in case os.close raises ++ exc_type, exc_value, exc_trace = sys.exc_info() ++ ++ to_close = [] ++ # only close the pipes we created ++ if stdin == PIPE: ++ to_close.extend([p2cread, p2cwrite]) ++ if stdout == PIPE: ++ to_close.extend([c2pread, c2pwrite]) ++ if stderr == PIPE: ++ to_close.extend([errread, errwrite]) ++ ++ for fd in to_close: ++ try: ++ os.close(fd) ++ except OSError: ++ pass ++ ++ raise exc_type, exc_value, exc_trace + + if mswindows: + if p2cwrite is not None: +--- a/Lib/test/test_subprocess.py ++++ b/Lib/test/test_subprocess.py +@@ -58,6 +58,23 @@ class BaseTestCase(unittest.TestCase): + self.assertEqual(actual, expected, msg) + + ++class PopenTestException(Exception): ++ pass ++ ++class PopenExecuteChildRaises(subprocess.Popen): ++ """ POpen subclass for testing cleanup of subprocess.PIPE filehandles when ++ _execute_child fails ++ """ ++ def _execute_child(self, args, executable, preexec_fn, close_fds, ++ cwd, env, universal_newlines, ++ startupinfo, creationflags, shell, ++ p2cread, p2cwrite, ++ c2pread, c2pwrite, ++ errread, errwrite): ++ ++ raise PopenTestException("Forced Exception for Test") ++ ++ + class ProcessTestCase(BaseTestCase): + + def test_call_seq(self): +@@ -631,6 +648,23 @@ class ProcessTestCase(BaseTestCase): + time.sleep(2) + p.communicate("x" * 2**20) + ++ # This test is Linux specific for simplicity to at least have ++ # some coverage. It is not a platform specific bug. ++ @unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()), ++ "Linux specific") ++ # Test for the fd leak reported in http://bugs.python.org/issue16327 ++ def test_failed_child_execute_fd_leak(self): ++ fd_directory = '/proc/%d/fd' % os.getpid() ++ num_fds_before_popen = len(os.listdir(fd_directory)) ++ with self.assertRaises(PopenTestException): ++ PopenExecuteChildRaises( ++ [sys.executable, "-c", "print()"], stdin=subprocess.PIPE, ++ stdout=subprocess.PIPE, stderr=subprocess.PIPE) ++ ++ num_fds_after_exception = len(os.listdir(fd_directory)) ++ self.assertEqual(num_fds_before_popen, num_fds_after_exception) ++ ++ + # context manager + class _SuppressCoreFiles(object): + """Try to prevent core files from being created.""" diff --git a/devtools/python/python_2.7.3/syslog_bugfix.patch b/devtools/python/python_2.7.3/syslog_bugfix.patch new file mode 100644 index 000000000..18f41ad95 --- /dev/null +++ b/devtools/python/python_2.7.3/syslog_bugfix.patch @@ -0,0 +1,19 @@ +--- + Lib/logging/handlers.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/Lib/logging/handlers.py ++++ b/Lib/logging/handlers.py +@@ -742,7 +742,11 @@ class SysLogHandler(logging.Handler): + except socket.error: + self.socket.close() + self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) +- self.socket.connect(address) ++ try: ++ self.socket.connect(address) ++ except socket.error: ++ self.socket.close() ++ raise + + # curious: when talking to the unix-domain '/dev/log' socket, a + # zero-terminator seems to be required. this string is placed diff --git a/devtools/qemu/.gitignore b/devtools/qemu/.gitignore new file mode 100644 index 000000000..1878aa832 --- /dev/null +++ b/devtools/qemu/.gitignore @@ -0,0 +1,6 @@ +!.distro +.distro/centos7/rpmbuild/RPMS +.distro/centos7/rpmbuild/SRPMS +.distro/centos7/rpmbuild/BUILD +.distro/centos7/rpmbuild/BUILDROOT +.distro/centos7/rpmbuild/SOURCES/qemu*tar.gz diff --git a/devtools/qemu/PKG-INFO b/devtools/qemu/PKG-INFO new file mode 100644 index 000000000..be89f193d --- /dev/null +++ b/devtools/qemu/PKG-INFO @@ -0,0 +1,19 @@ +Metadata-Version: 1.1 +Name: qemu +Version: 2.3.0 +Summary: QEMU is a FAST! processor emulator +Home-page: +Author: Windriver +Author-email: info@windriver.com +License: Apache-2.0 + +Description: +qemu-kvm is an open source virtualizer that provides hardware emulation for +the KVM hypervisor. qemu-kvm acts as a virtual machine monitor together with +the KVM kernel modules, and emulates the hardware for a full system such as +a PC and its assocated peripherals. + +As qemu-kvm requires no host kernel patches to run, it is safe and easy to use. + + +Platform: UNKNOWN diff --git a/devtools/qemu/README b/devtools/qemu/README new file mode 100644 index 000000000..687cb34fd --- /dev/null +++ b/devtools/qemu/README @@ -0,0 +1,17 @@ +Get the RedHat source rpm from: +$ wget wget http://cbs.centos.org/kojifiles/packages/qemu-kvm-ev/2.3.0/31.el7_2.7.1/src/qemu-kvm-ev-2.3.0-31.el7_2.7.1.src.rpm + +Uncompress the source rpm: +$ rpm2cpio qemu-kvm-ev-2.3.0-31.el7_2.7.1.src.rpm | cpio -idmv + +All the patches from the redhat source rpm have been applied in git/qemu using +scripts/autopatch.sh. + +Some of these patches can't be applied cleanly with 'git am'. So this script +attempd to execute 'git am' on each of them, if it fails it tries to patch +the files manually with 'git apply --index'. + +A git tag 'qemu-kvm-ev-2.3.0-31.el7_2.7.1' has been added to the last patch +applied. + +The Titanium Cloud specific patches will be added after this tag. diff --git a/devtools/qemu/centos/build_srpm.data b/devtools/qemu/centos/build_srpm.data new file mode 100644 index 000000000..39d6f4be1 --- /dev/null +++ b/devtools/qemu/centos/build_srpm.data @@ -0,0 +1,8 @@ +SRC_DIR="$CGCS_BASE/git/qemu" +COPY_LIST="$CGCS_BASE/downloads/kvm-unit-tests.git-4ea7633.tar.bz2 \ + $FILES_BASE/* \ + $PKG_BASE/qemu/qemu_clean \ + $PKG_BASE/qemu/qemu_clean.service \ + $PKG_BASE/qemu/qemu-system-x86.conf" +TIS_BASE_SRCREV=46f69965dbb07f479887ace50654ecc8879299bc +TIS_PATCH_VER=GITREVCOUNT diff --git a/devtools/qemu/centos/files/80-kvm.rules b/devtools/qemu/centos/files/80-kvm.rules new file mode 100644 index 000000000..e61b48ff3 --- /dev/null +++ b/devtools/qemu/centos/files/80-kvm.rules @@ -0,0 +1 @@ +KERNEL=="kvm", GROUP="kvm", MODE="0666" diff --git a/devtools/qemu/centos/files/85-kvm.preset b/devtools/qemu/centos/files/85-kvm.preset new file mode 100644 index 000000000..8024052ec --- /dev/null +++ b/devtools/qemu/centos/files/85-kvm.preset @@ -0,0 +1,5 @@ +# Enable kvm-setup by default. This can have odd side effects on +# PowerNV systems that aren't intended as KVM hosts, but at present we +# only support RHEL on PowerNV for the purpose of being a RHEV host. + +enable kvm-setup.service diff --git a/devtools/qemu/centos/files/95-kvm-memlock.conf b/devtools/qemu/centos/files/95-kvm-memlock.conf new file mode 100644 index 000000000..fc59dbe05 --- /dev/null +++ b/devtools/qemu/centos/files/95-kvm-memlock.conf @@ -0,0 +1,10 @@ +# The KVM HV implementation on Power can require a significant amount +# of unswappable memory (about half of which also needs to be host +# physically contiguous) to hold the guest's Hash Page Table (HPT) - +# roughly 1/64th of the guest's RAM size, minimum 16MiB. +# +# These limits allow unprivileged users to start smallish VMs, such as +# those used by libguestfs. +# +* hard memlock 65536 +* soft memlock 65536 diff --git a/devtools/qemu/centos/files/99-qemu-guest-agent.rules b/devtools/qemu/centos/files/99-qemu-guest-agent.rules new file mode 100644 index 000000000..8a290abbd --- /dev/null +++ b/devtools/qemu/centos/files/99-qemu-guest-agent.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="virtio-ports", ATTR{name}=="org.qemu.guest_agent.0", \ + TAG+="systemd" ENV{SYSTEMD_WANTS}="qemu-guest-agent.service" diff --git a/devtools/qemu/centos/files/README.rhel6-gpxe-source b/devtools/qemu/centos/files/README.rhel6-gpxe-source new file mode 100644 index 000000000..bff3160c4 --- /dev/null +++ b/devtools/qemu/centos/files/README.rhel6-gpxe-source @@ -0,0 +1,9 @@ +The ROM images on /usr/share/qemu-kvm/rhel6-*.rom come from the +Red Hat Enterprise Linux 6.4 package gpxe-roms-qemu-0.9.7-6.9.el6.noarch.rpm. + +The source code for those images can be downloaded from: +http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/gpxe-0.9.7-6.9.el6.src.rpm + +For more information on how to obtain source code for Red Hat Enterprise Linux +software, you can refer to Chapter 1. Obtaining Red Hat Enterprise Linux of the +Red Hat Enterprise Linux Installation Guide. diff --git a/devtools/qemu/centos/files/bios-256k.bin b/devtools/qemu/centos/files/bios-256k.bin new file mode 100644 index 0000000000000000000000000000000000000000..07f2a309c5be4685f1dccdc621874b4d9d3034a1 GIT binary patch literal 262144 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

URR|ZeW5B5|-+m-X;oG187ce?5G*upM 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 literal 0 HcmV?d00001 diff --git a/devtools/qemu/centos/files/bridge.conf b/devtools/qemu/centos/files/bridge.conf new file mode 100644 index 000000000..a573665d3 --- /dev/null +++ b/devtools/qemu/centos/files/bridge.conf @@ -0,0 +1 @@ +allow virbr0 diff --git a/devtools/qemu/centos/files/build_configure.sh b/devtools/qemu/centos/files/build_configure.sh new file mode 100755 index 000000000..31d78a19c --- /dev/null +++ b/devtools/qemu/centos/files/build_configure.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +_prefix=$1 +shift +_libdir=$1 +shift +_sysconfdir=$1 +shift +_localstatedir=$1 +shift +_libexecdir=$1 +shift +pkgname=$1 +shift +arch=$1 +shift +nvr=$1 +shift +optflags=$1 +shift +have_fdt=$1 +shift +have_gluster=$1 +shift +have_guest_agent=$1 +shift +have_numa=$1 +shift +have_rbd=$1 +shift +have_rdma=$1 +shift +have_seccomp=$1 +shift +have_spice=$1 +shift +have_usbredir=$1 +shift +have_tcmalloc=$1 +shift + + +if [ "$have_rbd" == "enable" ]; then + rbd_driver=rbd, +fi + +if [ "$have_gluster" == "enable" ]; then + gluster_driver=gluster, +fi + +./configure \ + --prefix=${_prefix} \ + --libdir=${_libdir} \ + --sysconfdir=${_sysconfdir} \ + --interp-prefix=${_prefix}/qemu-%M \ + --localstatedir=${_localstatedir} \ + --libexecdir=${_libexecdir} \ + --extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \ + --extra-cflags="${optflags} -fPIE -DPIE -O2" \ + --with-pkgversion=${nvr} \ + --with-confsuffix=/${pkgname} \ + --with-coroutine=ucontext \ + --with-system-pixman \ + --disable-bluez \ + --disable-brlapi \ + --enable-cap-ng \ + --enable-coroutine-pool \ + --disable-curl \ + --enable-curses \ + --disable-debug-tcg \ + --enable-docs \ + --disable-gtk \ + --enable-kvm \ + --disable-libiscsi \ + --disable-libnfs \ + --disable-libssh2 \ + --disable-libusb \ + --disable-bzip2 \ + --enable-linux-aio \ + --enable-live-block-migration \ + --disable-lzo \ + --disable-opengl \ + --enable-pie \ + --disable-qom-cast-debug \ + --disable-sdl \ + --enable-snappy \ + --disable-sparse \ + --disable-strip \ + --enable-tpm \ + --enable-trace-backend=nop \ + --disable-uuid \ + --disable-vde \ + --disable-vhdx \ + --disable-vhost-scsi \ + --enable-vhost-net \ + --enable-virtfs \ + --disable-vnc-jpeg \ + --disable-vnc-png \ + --disable-vnc-sasl \ + --disable-vte \ + --enable-werror \ + --disable-xen \ + --disable-xfsctl \ + --enable-attr \ + --${have_fdt}-fdt \ + --${have_gluster}-glusterfs \ + --${have_guest_agent}-guest-agent \ + --${have_numa}-numa \ + --${have_rbd}-rbd \ + --${have_rdma}-rdma \ + --${have_seccomp}-seccomp \ + --${have_spice}-spice \ + --${have_usbredir}-usb-redir \ + --${have_tcmalloc}-tcmalloc \ + --audio-drv-list=pa,alsa \ + --block-drv-rw-whitelist=qcow2,raw,file,host_device,nbd,iscsi,${gluster_driver}${rbd_driver}blkdebug \ + --block-drv-ro-whitelist=vmdk,vhdx,vpc,https,ssh \ + "$@" diff --git a/devtools/qemu/centos/files/ksm.service b/devtools/qemu/centos/files/ksm.service new file mode 100644 index 000000000..35c6f1de8 --- /dev/null +++ b/devtools/qemu/centos/files/ksm.service @@ -0,0 +1,13 @@ +[Unit] +Description=Kernel Samepage Merging +ConditionPathExists=/sys/kernel/mm/ksm + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=-/etc/sysconfig/ksm +ExecStart=/usr/libexec/ksmctl start +ExecStop=/usr/libexec/ksmctl stop + +[Install] +WantedBy=multi-user.target diff --git a/devtools/qemu/centos/files/ksm.sysconfig b/devtools/qemu/centos/files/ksm.sysconfig new file mode 100644 index 000000000..d99656d70 --- /dev/null +++ b/devtools/qemu/centos/files/ksm.sysconfig @@ -0,0 +1,4 @@ +# The maximum number of unswappable kernel pages +# which may be allocated by ksm (0 for unlimited) +# If unset, defaults to half of total memory +# KSM_MAX_KERNEL_PAGES= diff --git a/devtools/qemu/centos/files/ksmctl.c b/devtools/qemu/centos/files/ksmctl.c new file mode 100644 index 000000000..af3959102 --- /dev/null +++ b/devtools/qemu/centos/files/ksmctl.c @@ -0,0 +1,77 @@ +/* Start/stop KSM, for systemd. + * Copyright (C) 2009, 2011 Red Hat, Inc. + * Written by Paolo Bonzini . + * Based on the original sysvinit script by Dan Kenigsberg + * This file is distributed under the GNU General Public License, version 2 + * or later. */ + +#include +#include +#include +#include +#include +#include + +#define KSM_MAX_KERNEL_PAGES_FILE "/sys/kernel/mm/ksm/max_kernel_pages" +#define KSM_RUN_FILE "/sys/kernel/mm/ksm/run" + +char *program_name; + +int usage(void) +{ + fprintf(stderr, "Usage: %s {start|stop}\n", program_name); + return 1; +} + +int write_value(uint64_t value, char *filename) +{ + FILE *fp; + if (!(fp = fopen(filename, "w")) || + fprintf(fp, "%llu\n", (unsigned long long) value) == EOF || + fflush(fp) == EOF || + fclose(fp) == EOF) + return 1; + + return 0; +} + +uint64_t ksm_max_kernel_pages() +{ + char *var = getenv("KSM_MAX_KERNEL_PAGES"); + char *endptr; + uint64_t value; + if (var && *var) { + value = strtoll(var, &endptr, 0); + if (value < LLONG_MAX && !*endptr) + return value; + } + /* Unless KSM_MAX_KERNEL_PAGES is set, let KSM munch up to half of + * total memory. */ + return sysconf(_SC_PHYS_PAGES) / 2; +} + +int start(void) +{ + if (access(KSM_MAX_KERNEL_PAGES_FILE, R_OK) >= 0) + write_value(ksm_max_kernel_pages(), KSM_MAX_KERNEL_PAGES_FILE); + return write_value(1, KSM_RUN_FILE); +} + +int stop(void) +{ + return write_value(0, KSM_RUN_FILE); +} + +int main(int argc, char **argv) +{ + program_name = argv[0]; + if (argc < 2) { + return usage(); + } else if (!strcmp(argv[1], "start")) { + return start(); + } else if (!strcmp(argv[1], "stop")) { + return stop(); + } else { + return usage(); + } +} diff --git a/devtools/qemu/centos/files/ksmtuned b/devtools/qemu/centos/files/ksmtuned new file mode 100644 index 000000000..320ce7405 --- /dev/null +++ b/devtools/qemu/centos/files/ksmtuned @@ -0,0 +1,138 @@ +#!/bin/bash +# +# Copyright 2009 Red Hat, Inc. and/or its affiliates. +# Released under the GPL +# +# Author: Dan Kenigsberg +# +# ksmtuned - a simple script that controls whether (and with what vigor) ksm +# should search for duplicated pages. +# +# starts ksm when memory commited to qemu processes exceeds a threshold, and +# make ksm work harder and harder untill memory load falls below that +# threshold. +# +# send SIGUSR1 to this process right after a new qemu process is started, or +# following its death, to retune ksm accordingly +# +# needs testing and ironing. contact danken@redhat.com if something breaks. + +if [ -f /etc/ksmtuned.conf ]; then + . /etc/ksmtuned.conf +fi + +debug() { + if [ -n "$DEBUG" ]; then + s="`/bin/date`: $*" + [ -n "$LOGFILE" ] && echo "$s" >> "$LOGFILE" || echo "$s" + fi +} + + +KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60} +KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300} +KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50} + +KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64} +KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250} +# millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep +# more, bigger sleep less. +KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10} + +KSM_THRES_COEF=${KSM_THRES_COEF:-20} +KSM_THRES_CONST=${KSM_THRES_CONST:-2048} + +total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo` +debug total $total + +npages=0 +sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total] +[ $sleep -le 10 ] && sleep=10 +debug sleep $sleep +thres=$[total * KSM_THRES_COEF / 100] +if [ $KSM_THRES_CONST -gt $thres ]; then + thres=$KSM_THRES_CONST +fi +debug thres $thres + +KSMCTL () { + case x$1 in + xstop) + echo 0 > /sys/kernel/mm/ksm/run + ;; + xstart) + echo $2 > /sys/kernel/mm/ksm/pages_to_scan + echo $3 > /sys/kernel/mm/ksm/sleep_millisecs + echo 1 > /sys/kernel/mm/ksm/run + ;; + esac +} + +committed_memory () { + local pidlist + pidlist=$(pgrep -d ' ' -- '^qemu(-kvm|:.{1,11})$') + if [ -n "$pidlist" ]; then + ps -p "$pidlist" -o rsz= + fi | awk '{ sum += $1 }; END { print 0+sum }' +} + +free_memory () { + awk '/^(MemFree|Buffers|Cached):/ {free += $2}; END {print free}' \ + /proc/meminfo +} + +increase_npages() { + local delta + delta=${1:-0} + npages=$[npages + delta] + if [ $npages -lt $KSM_NPAGES_MIN ]; then + npages=$KSM_NPAGES_MIN + elif [ $npages -gt $KSM_NPAGES_MAX ]; then + npages=$KSM_NPAGES_MAX + fi + echo $npages +} + + +adjust () { + local free committed + free=`free_memory` + committed=`committed_memory` + debug committed $committed free $free + if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then + KSMCTL stop + debug "$[committed + thres] < $total and free > $thres, stop ksm" + return 1 + fi + debug "$[committed + thres] > $total, start ksm" + if [ $free -lt $thres ]; then + npages=`increase_npages $KSM_NPAGES_BOOST` + debug "$free < $thres, boost" + else + npages=`increase_npages $KSM_NPAGES_DECAY` + debug "$free > $thres, decay" + fi + KSMCTL start $npages $sleep + debug "KSMCTL start $npages $sleep" + return 0 +} + +function nothing () { + : +} + +loop () { + trap nothing SIGUSR1 + while true + do + sleep $KSM_MONITOR_INTERVAL & + wait $! + adjust + done +} + +PIDFILE=${PIDFILE-/var/run/ksmtune.pid} +if touch "$PIDFILE"; then + loop & + echo $! > "$PIDFILE" +fi diff --git a/devtools/qemu/centos/files/ksmtuned.conf b/devtools/qemu/centos/files/ksmtuned.conf new file mode 100644 index 000000000..fc4518cf9 --- /dev/null +++ b/devtools/qemu/centos/files/ksmtuned.conf @@ -0,0 +1,21 @@ +# Configuration file for ksmtuned. + +# How long ksmtuned should sleep between tuning adjustments +# KSM_MONITOR_INTERVAL=60 + +# Millisecond sleep between ksm scans for 16Gb server. +# Smaller servers sleep more, bigger sleep less. +# KSM_SLEEP_MSEC=10 + +# KSM_NPAGES_BOOST=300 +# KSM_NPAGES_DECAY=-50 +# KSM_NPAGES_MIN=64 +# KSM_NPAGES_MAX=1250 + +# KSM_THRES_COEF=20 +# KSM_THRES_CONST=2048 + +# uncomment the following if you want ksmtuned debug info + +# LOGFILE=/var/log/ksmtuned +# DEBUG=1 diff --git a/devtools/qemu/centos/files/ksmtuned.service b/devtools/qemu/centos/files/ksmtuned.service new file mode 100644 index 000000000..39febcca7 --- /dev/null +++ b/devtools/qemu/centos/files/ksmtuned.service @@ -0,0 +1,12 @@ +[Unit] +Description=Kernel Samepage Merging (KSM) Tuning Daemon +After=ksm.service +Requires=ksm.service + +[Service] +ExecStart=/usr/sbin/ksmtuned +ExecReload=/bin/kill -USR1 $MAINPID +Type=forking + +[Install] +WantedBy=multi-user.target diff --git a/devtools/qemu/centos/files/kvm-setup b/devtools/qemu/centos/files/kvm-setup new file mode 100644 index 000000000..14721bdcd --- /dev/null +++ b/devtools/qemu/centos/files/kvm-setup @@ -0,0 +1,31 @@ +#! /bin/bash + +kvm_setup_powerpc () { + if grep '^platform[[:space:]]*:[[:space:]]*PowerNV' /proc/cpuinfo > /dev/null; then + # PowerNV platform, which is KVM HV capable + + if [ -z "$SUBCORES" ]; then + SUBCORES=1 + fi + + # Step 1. Load the KVM HVmodule + if ! modprobe -b kvm_hv; then + return + fi + + # Step 2. Configure subcore mode + # FIXME: Should we check for POWER8 first? + /usr/sbin/ppc64_cpu --subcores-per-core=$SUBCORES + + # Step 3. Disable SMT (multithreading) + /usr/sbin/ppc64_cpu --smt=off + fi +} + +case $(uname -m) in + ppc64|ppc64le) + kvm_setup_powerpc + ;; +esac + +exit 0 diff --git a/devtools/qemu/centos/files/kvm-setup.service b/devtools/qemu/centos/files/kvm-setup.service new file mode 100644 index 000000000..9c4bf9723 --- /dev/null +++ b/devtools/qemu/centos/files/kvm-setup.service @@ -0,0 +1,14 @@ +[Unit] +Description=Perform system configuration to prepare system to run KVM guests +# Offlining CPUs can cause irqbalance to throw warnings if it's running +Before=irqbalance.service +# libvirtd reads CPU topology at startup, so change it before +Before=libvirtd.service + +[Service] +Type=oneshot +EnvironmentFile=-/etc/sysconfig/kvm +ExecStart=/usr/lib/systemd/kvm-setup + +[Install] +WantedBy=multi-user.target diff --git a/devtools/qemu/centos/files/kvm.conf b/devtools/qemu/centos/files/kvm.conf new file mode 100644 index 000000000..3f7842a13 --- /dev/null +++ b/devtools/qemu/centos/files/kvm.conf @@ -0,0 +1,12 @@ +# Setting modprobe kvm_intel/kvm_amd nested = 1 +# only enables Nested Virtualization until the next reboot or +# module reload. Uncomment the option applicable +# to your system below to enable the feature permanently. +# +# User changes in this file are preserved across upgrades. +# +# For Intel +#options kvm_intel nested=1 +# +# For AMD +#options kvm_amd nested=1 diff --git a/devtools/qemu/centos/files/qemu-ga.sysconfig b/devtools/qemu/centos/files/qemu-ga.sysconfig new file mode 100644 index 000000000..f54018e53 --- /dev/null +++ b/devtools/qemu/centos/files/qemu-ga.sysconfig @@ -0,0 +1,19 @@ +# This is a systemd environment file, not a shell script. +# It provides settings for "/lib/systemd/system/qemu-guest-agent.service". + +# Comma-separated blacklist of RPCs to disable, or empty list to enable all. +# +# You can get the list of RPC commands using "qemu-ga --blacklist='?'". +# There should be no spaces between commas and commands in the blacklist. +BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush + +# Fsfreeze hook script specification. +# +# FSFREEZE_HOOK_PATHNAME=/dev/null : disables the feature. +# +# FSFREEZE_HOOK_PATHNAME=/path/to/executable : enables the feature with the +# specified binary or shell script. +# +# FSFREEZE_HOOK_PATHNAME= : enables the feature with the +# default value (invoke "qemu-ga --help" to interrogate). +FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook diff --git a/devtools/qemu/centos/files/qemu-guest-agent.service b/devtools/qemu/centos/files/qemu-guest-agent.service new file mode 100644 index 000000000..44b11cda9 --- /dev/null +++ b/devtools/qemu/centos/files/qemu-guest-agent.service @@ -0,0 +1,18 @@ +[Unit] +Description=QEMU Guest Agent +BindsTo=dev-virtio\x2dports-org.qemu.guest_agent.0.device +After=dev-virtio\x2dports-org.qemu.guest_agent.0.device + +[Service] +UMask=0077 +EnvironmentFile=/etc/sysconfig/qemu-ga +ExecStart=/usr/bin/qemu-ga \ + --method=virtio-serial \ + --path=/dev/virtio-ports/org.qemu.guest_agent.0 \ + --blacklist=${BLACKLIST_RPC} \ + -F${FSFREEZE_HOOK_PATHNAME} +StandardError=syslog +Restart=always +RestartSec=0 + +[Install] diff --git a/devtools/qemu/centos/files/qemu.binfmt b/devtools/qemu/centos/files/qemu.binfmt new file mode 100644 index 000000000..63a58f473 --- /dev/null +++ b/devtools/qemu/centos/files/qemu.binfmt @@ -0,0 +1,17 @@ +:qemu-i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386: +:qemu-i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386: +:qemu-alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha: +:qemu-arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm: +:qemu-armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb: +:qemu-sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc: +:qemu-ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc: +:qemu-m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k: +:qemu-mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips: +:qemu-mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel: +:qemu-mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32: +:qemu-mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el: +:qemu-mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64: +:qemu-mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el: +:qemu-sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4: +:qemu-sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb: +:qemu-s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x: diff --git a/devtools/qemu/centos/files/rhel6-e1000.rom b/devtools/qemu/centos/files/rhel6-e1000.rom new file mode 100644 index 0000000000000000000000000000000000000000..078d26087f8c74bfb5ecf4275cd715d7a807abea GIT binary patch literal 69120 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 literal 0 HcmV?d00001 diff --git a/devtools/qemu/centos/files/rhel6-pcnet.rom b/devtools/qemu/centos/files/rhel6-pcnet.rom new file mode 100644 index 0000000000000000000000000000000000000000..2805a0f93aef14fb0e88bb9f86d8ad29762eadb1 GIT binary patch literal 54784 zcmZs?2RvKh_c(mBBMAwD*fC3OHH(T(RT~tsDUH-F32JLlX+(AJmg=6m%+@Zt(H0eI zbX|?rWs`sU{r-Oc&-=cg_vVwE=bY!<=bU@y^E|oN?`GU&IWPwNzmI%C39tgFP98q$ z1b_^PAQ%(?;s6K$_3nOBmg4d&%d?`?BAKeWF~JmGTO~#>`vL0 zl*BYlN{Ints5BQqM>H%sBV%($hGB*-;J4k`L-sEKK%m30LH$AftEhimBUF(13jFm| z3Dq(IXQk;e)IqkjjbN6_&# zNGL#W9TTG?2&piD-7Tc!pLVk+@l6om-M3gIJywLM?G#bq=+sz1Td0Bp*d4f{KIV>v zHUhwu^oa#xq5p$MLgodpII^-ZPLF7OF0`5g?tpUUz!K;`>FL}pL>S#=;$kId3gb3kL^26tN{!)Wp`>S*@>AFZ{SE~CXu6( z66t$lSSh>7fT5uwfWiE8U(rDkeI>wH;H89WQw&Tb&o0P6IYS^#MKI7G(ztyT90UHz zSpjL{z(8lnd8SCt&43}jG73f)*&bmiG>n41CjA@izf8CP&B=#i6km)H& z3ICU`h*1I{8gL0{>Vkp40Xk!wkIT-|KF(K>{(GJP*>tXj$OK%G%0W65JO?d%_he9? z%Ge5fNls-(ru=8b-5I;1Sj;_1i5P(HPY+N*`bwyBK3j0}q%6wZhymK%P@Fc`MdJT4 z)J|wPoxzM2-7P}~PGx+7z6=fyMyZONJ?y17^%3N?EE8$c@>*8#r`{d#$dCbLfd3%> zkQc4mnaFeh`p(k=+v!w%MI8kw8;hn_#slY8{+y4d+aTis<{x||o!0(O4I)MO`V|S8 zh!TXG0N;oL9!c0@Sn$_`YVp^E&|q3S^>(31ap0g(Fi&fzw{{aixX9JI3B?^C6e#X! z>4t+aKy;>R;%zZXdyK%lLeWK{-Y>%H&0wXlWUK{*fdfKOpdS+fnkex7KLYP+aj;NW zO|IVofZ4){6%oi128uY8tNvFkKqwS7&I14aJ^H`DZ~vzk0Q@*#3#N1c_Ln*OIsA2e z1yV&;g7F;T?H?eEY61|vra@u74j}UB@UTEUq3GPAK_Q;pf`j1ITYg+Zpn*C9P}WmN z0?G!Q`+;tkcd=sT}1j)P8Ef(6s0K903zn+Ia8tStu1hl6OgtgN}Iee8~ zG|xhozM;2%gVPH-^HBgGQVPCyk>2_pPOrcE59Yi8lmF$YmH*;?iK+*^VNf3cz(65A zyo^t;r`bS6sDJ4VbQM-zf(cbBU{zOPbcPZE0ti(u!$e6rfLb?$00Y-)^zeV(BJYh9 z`J<>Tc+>q>=_b>3F99m%G9AKa!N7PR<&VfRbP5;>&?Q^I03h`*oejcLq(r7d#~eh` zUFqyOA=8`Ac}6#R4qA$+o`WX;&MZl~1GwQou-dNLTAsc(k1!r^iX;rJ^25|!awIqkFFL@#=wA;*M#MExa_$gq;Qs> zXG=~&)kAZN1`J5Kc-)w7YfUIIPbkhS*e{SK`k39Yb)zB`6A)N03aqUHMOIk z^h}ThWSYEEUT%RDCN+;JqL%!nS5jbfvbIRkD(g9@c0bPOx={F)>VpH8=!~H7 zf2qzNnv6VWC{*c29CAhG3x(;zT%in8>Y)EB8qE?@iKVC>lw|>`BF}nT)`}F4=B@;+ zoB^`U*&Xn93)4c`|Csz=*`^DH)56MZS-RE$jttPN#4I@4C9+R;%KkTn(<2jNOcv

ZfhG$MZFyCWnj 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 S-ji?iQ)ClDQVo5lPo&R~n_8tWxF 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�%q022-8eRre#u=J;dPJL{@>rR#V;pKVG?F$ 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 literal 0 HcmV?d00001 diff --git a/devtools/qemu/centos/files/rhel6-rtl8139.rom b/devtools/qemu/centos/files/rhel6-rtl8139.rom new file mode 100644 index 0000000000000000000000000000000000000000..a5273e8d6a1d83670ba0363007d73614a8e5a66d GIT binary patch literal 54272 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

*@9cCZ;*#@v49^G^?1gYluDgeHz?yUXuvJe|21| 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

^ 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

onkC|f+0g4BuhLRdmE1f8?vi|$f(e|ZG# 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

;N6H z49HRBYDnUYyl=hL3o%uG)WyC3JWFjoq7^bJ@NdJd8@N^IAK$j;^Qcy`8b=xj5D5*(cdVxd*gt7w~ z{MXt80x+1#$qD~a=m~s;b}j6In$n_+?aG_F@X#d=#zqiYnQhDhRa>(_U_MkXg%o%p zn6MckTYMmB)-;)5t(N<8tt|pQ)jqCfgC%!I{5|<@8JRp)E>z7l9^ID|=nP_nPI<$O z22w%%%3t3Xcd(Xi`gRl@-y;8=q-S9!%T2$HcHx-Q(s?p-B=IKf`E-Z`oj121lcymm zn%j5%&_Eo9n|!3>u(V|%u(bQIh4o8Nqn|8{@Eu2*g!X0I`+<+Z83u6mj|JdN@h*!j z{M28%g8{&6S;1D6Hn$^*pdfZ40I$W0tqkM`V3@ls@OYn)rY)e~0c7o`IJoL;H58SE zv`;`;g9ncF6(kyP_03p|er|O6{c@Gb@9aFX3|6*nLmjS|=mMc6H$)ybQo#Q7>Pf%q z{2OKOv>I21C1tgtj5&_XKJaeD8fZ6PK%zsAR=Lu+-*!jTE)JojTEzr}v%2aIPfNaP zgPMY=--OZB%JNoRJ*zka_z^e~Acn<6k7frkzh|i_Vc43=95)02Y0t5@?a6<_ujN`M z9rlM^LT&`8g+;Lb+3oSu*I8xdR*>J(|C+sn9N)X0#|rr+SS52Svs*?Q?R+!f0-RVn zyY>B1|L&sj4q^ZaZD|~8*&oe@Gk*f#3ym*(v<5ksUkJKbnnZ z+gacu19aU-|Q!U)ae>}gc zb&PLZ$bU|}c@i)cP#*2uJBjje{Q1OTT1!kR$8CNv&^5swu%P}|XL)UhM)XqInlS$) zB$26@P4-$6WvkKPmuRerKXf?8q~_KZATvR<+Rw{0>MN=v+k8)Xr}NS_u#{i;Mf$Et zHS3WW<9zA&uvt^og)rQd-#fiMwi~jb0)&yxW@;5nth$1Sv~jP|`9Mb(0Y!z2=&si} zpjr)ct)dJ-N^rgZ(cDpYO|mcUdGZB_X>BQ4`b)M_-J8+CqE^vh(Ic7v*xP#EUSI6p zT&Xb55KikH+IcPU5Mq!FA@qzkHIHW8!{3lW%>bGG4BsdA%s+~X6B=B$@r*79J4kZk zm#Crl27>LkFWsr-gvsSL7-GveADAsu*j@ScN;#ALU$x8y!Y{`Q*nW}d#I*eMHFDpw zR>ycbfkIR1jah#OjQP?%`}t(m4wD!Lire^3v7=w{0?B+wOkz#TkOY*2Mr)MG1F=P0B3rfRx#8qTNnRyY> z-sV}xdN)!Hj}rjdJ;@7#7b`KVoWzN%vD z*=vUTdL}TX`oigFZJ}b|T&B4-7@!yR3=m^U#1Z2GT2=Sni_0h>hIds4(!0QqWcdw? z3p)95JryR@1LJ$Dkl-@qNNZt-_>bqk-I77d8r+eIkTS4Og(~sDPbLs4j`glW49j@olHD)@Z#oir$aZ@;1703 zX{r1nHIcf!gTl0H2bzD&e>*C^ml!XOK(7S-|1i9f_g^ked|k_{RE-U|(??O)`E^00>vT)wY@JQ{ znGLxoeWKod!Lg@bpibof!ViZQm$cNRibRT=(_i(sa8C9WSoofzBfhH^E4Gh2-i+y< zD%|MWdV5qThQi8%q2iJ_*b4YB1c{M@A<#0pth?%uc4}+I7=rlDSI~gnv@G+7X<`da zA`u}nCMG>LWBWUg%}kEWNW^8(qtILP+(rV1q8mw1LhX;tjLnWb)VUnIN_4jMclGn5 z8O6~v<5SZ=rc6v6IIMgiHATkJ^gy)YE`SSFB;v375wtRZ1fq$du>`_DBR1WDygxQ2 zb7!I`QRj-0v7wEjl^oGEHN*eT!>@8;Xkch^M{H#@W~!8R-}qYeg$GkEV1wW&)y; z60aSOmFxm%24x^$AT*Pwnp$$}Gd_++1N@xncF8j2A4eZY)NlVFC?*!gHg@j@P{`+> z7?}S?q`}fNldRorCgxjSi<#L()yBnIm|3eNN6VVzO<4XgF)$Iw$J$0}0M-mgElV@g zzatGTZHzN>{!GjV?1!5g1F~{dl9CR@#wcGI9N!g}l5J*bY^EY^ZEPH!R8rENVjF9a z3fLbRQxV!aV~ZeoAP{6qZ1UM-Q?iJH%v3^DYU)!;?BJn{?H*pYOx(B(&U8LFSBPB9Yll=AsR3s06Fp7>RSQ6C9>e5Zq zmaC3ZF@%()fUM+wxybrFv&R|XN-o@bhlU#jd*$Ql@y+=?1JSW}?W4mp5AE6c#6rnx zk|r0COfU?kr>OmT;;SM!kOn_w8Ta&jA!R=&=6PHy<{rTvcgc`n97)0v`FzK~2CbX_ zopNffPbQ0vMY_JvzLp4HUwD3)K+l*XP+Xm8NrH&L`_X1$C!-p~J9wR;Nofay6AT}S zD~3uK0?s0|o~5)%pU!w4eZV_5rf|Y_Z8A7I1t&{Mt~!^poR-uhm!5eO9bAdwRY)$?_Bpd0+!uKcZL`*beEKNKP zW*VrZG`bM%ajlWbu~bGw&wxd&!|J*!av-@wibzj6aPWWao#|Io>9U7+*hzNC4kXMo z1OkRB1B6LNLl}h+WR`#oNgzN5Bw-S183Z|kHZ3BE*v^PoK@bQCwoI*J(}+q#Kt$W& zwh9qEtp~L6w1@L|+*_aOYt>p+tLj~E{hoY*9g&(DX1Kn^9jo0X(3tecysa!vV%7XN|+9NcK}G9B%CWyNMSZHJJqN z`SNl{BZf$*uo==w$jx}c6Yf1);GnR|B)pXJE%k(=K5XK}#++T#W(iLUL=(bnQqm^X33=%{B>D^{DmIn|Ng7P0pH(*KlPc$1*J14O2#P~R02d7>!cNVmJ_onmSRSp@5wm@7jx>4!owL?a6`(Ma`OegMIJsr z@H{vck|p8CMI25}zvhFHQ40Y%8~fPbzV+EtEAOr^`E+78BTw3|UuR>)(dJQd(~zd{ z9$|!j2BoiJsLX^J!KiB1uv{oVoNl2sttNJbO8#}JIC!w>P9=$8 zBQrjD*RoD8{y~1m2TIUhOb#VKm(Z&}bTa6mM5;SlaZW6DFj3>vOmmQC-QyYOSuKA7 z)xKkHW|~WPD8KS}e1{rK(0xRc?;+?SKX?OU1)PHQX`oI{LA{SX3lQcJ?fEs>sDD{saI%kYQY~Ukh-v zE9QnHJXQTSpTmyCm;_HRR3JJk0Yyl9^9&cF2jDVzp+$tm3~1k~gRaCdy*RM;P%^6T z%;Iu5hj~3f{Rm(Wcx@!KtJhQG_Wy(-_AZFKFvnkUl6{MfnFYssR(cKY}0!p8-|GW=SA2A6)&rCI*0A~2~eWB_><4ckahVu;$ z8&&NWa_H|3Ub5M~~ z^v|s5Eq>F~jTkqWJiUz(W7{>-5|=zjj-Hv9xX#L@ZE;|O1I8!RZnuiAq#SV&m{9!m z6U7&)OP&uBV*b_03;j9M$&cxHk9f!@;_~os1{G&#Z0H^$J?j#n6nIMD#U*(u#c7hn z917;lxO!Q}mNXLTdw{c4oN*BBza#L@syi;ROlw%iTI%MQKPkXWNTkxF%>DLzG0h$h zRzI4gH3Z)EjU%50ug$P>o0Id6vgx(A!Fe`5i(lh{_csY!^@C6*H-mOFA6 zqgV2H0^cBRU;okpabbzT)H+05DyNSLLEIX7P$BkCa&%K=WKsmXgqvC{9u1VWqXNkR5 zPTBRxz$#JQrgF4pa2Z%&-pIHm35ur0ZeB^F*LJ&hht4s<#Nu*tBt|f6hS`{s6`lI0 zP|aJfrk8={$nfxkA^ykp?1f!x{qaU7%&16T zV4EirXS%b_IfCd!$_73XM=zQ2W&)A5t2u^&&xe#U~(vf;c*kLJ3^D54ZxN~0Jc)O2Q zjE$xOY|xAju#0hUW!8@PL|EuNVV63_O(gzh6_LX9ab38Veh3?(kB#!77wH;L6DLFY ztdIby4#n+i-qRJiPwlj}LTnmPlSVi#ilRogZ#u{L>=s0^58!wO!4)&>jx!T25Y9O}S3oa(1}H$1t!D8mP*8;Q$atAX?o>8z0F1!-_CgpA>|00+tAbANMkM`T+MQ76{dMIw02Q z1)Ot4)X7jnZR%g!Ej#bH*PXdSv9EKy(jD4>B{~gQj_xi8+8*xvzKR|~irm<>_m~9I z*JOp7Qf(q9db{Yc6#=;IXvI&)J>P|}aUasTCtd%+3xpEv4xMs1;5UfAkPr82$EDlJ zP>-&Kf91A{`K|z#Sz!1H?yX>|A?RD%xgt8$1p7(q-7+$gYUFF!Xl1M^u0v$38D%@~H-rZF{*^02WHAm|sKnH+5mny*z9 zADQ>JKgW8avEl|@vdA!ygwxU%-}@xx=91)hQ-tEQ;oLvu@?VgukhGs0h-M~efTcQKw={qPVsR?q3W&5ho2NGQGdpww;hSsU5D0g;cpVdFawbXt zhp9dDN!=VjlQRZOYV-+rt&{64qe0P(9GbLvXp-6NGF5Q(-y4>oBEg|KV+g3|wgBsj z3c)$xhaF9HKNZ35x%Z#*X1yUchzfaC-Y9Vtqg{MBgmc5XR%o* zgg7rCoeCM{w%a0`ng_u-`w~SvCAywcsT|)%yXgK~4r>mqUygJ{khen5sP8e@6bD<& z%c?#s5Dz#cgn+UP&+$u)cU76tqwm*l_CT!%gS-4dhy0%9`@4?*>^KZP6by}5fI6?C z-eV4`iPJAij}L>N9TDj#GS_8f+WHB@>tOH6q52Vi3Xy_%&ZjlibgXP|scZ#LjMlbI z+wjztJTLI8WmxF3- ztgGWhwCT99Z{fPyy;omZ;J0eEg=xfVG9Uc(ptAS5sPH-L_kc#mxmv`|GIkj+YCOix z`L)7N&zk<%BVB|Y+grE3%qU6C@QD{kL7FNmlfCq&>9MRwW$I%qfMK7W6-Uh2U2*#1KS)E=< z`fWA=$Q#o2!cgkp7_*hs|JZ+O1D1_DGwIJ}mFw?FIpq(Y)TFAH6JwTk&uP0+Q7 zT?U6+bHL9ZrK*Lve}BB(XLFy6OqJ!SzS0mNl1|{SW6;TO*1%ijgpUlD?kns0pBY~` zP_puLSIq|g2MC2}fxrWC;EvUet82GAp4FfKXTeeRFi`Ef-@M_)9E|}Itn05bNZx2l zHXyMqfHIh=j17Eu690tiRk*kjK!zgp8lXfgo^7%+AoBJA{xvk!i8A~jy9Ygx8C%ry z@yZv&Lh7`U%M>vaQYV-jwBwjFj%H*@k4jN&1HE^kT(_U@d^gx*4!PoEA)in2Smpb{ z9?080+*nCF(6*A)FTF*L$LB(2N&W8z_Zw^pG%i|@tAo8?7^%p&H>C-imDruHjhppc zhnK(;f(7bMgn^o#A<0T{M6lb)lAx)L(vr~U=haqh)P?OFTiLro?`Pf6S$KRwvk*k# zm5{&bTl~2&#H!gBsLB@i3jOigIj?LYM4{d2q1r#C`ayaJ*mBQa+ouZ0gyfY%)Mhr`}}I6_v7WsnduJ( z7$AmJg4dR89oU=Tz_L#sc6d#P(4;73iq!#&SFcqA)CZbHFodb?YpT34Aa_v=k$6s*pigJ;@Qj?Rd~uO>4z!0m93JPpu<4gl4c*|= zm0R`X(?}yRP@5I`uqz4nCiQCteuP;wPmjRLhxzQ_FS2joO#B?Ecg-tngrR)31*l^) z5;pM2Z(s4?iI&clmWHi12wwu*@hcVYTkv0ClrD{vxT44z?Bs#J;xXYRv6i%{)MOcs z52xT+;w=((K3s^`+TB!(dz@d1zwLJf-#A>oDpLLkU$#s^;Q1T;LbV|wsOz#srFmNq zjt;I);&;L6_z{|XPK;iGtMH?rtle#f7dkD|uj;}UHWnS7UN6{ymk3WxA$$~9r7m&z z!rxgq;%gK7P3PbSJnAfb8Snh{@IDCPj??ac$wv)c|9kps(L})XXZCgY!8F7EH1q6Y z(wf#C5czv%O5xZ8?IxyU%E~CCY-|Zr2>ag$8fsv03h-kpAJU7yf7Sd6dXqJHFUWay k8v1w_`*yJNphM{KIw%|ffJguc0f7HLKK;M_AIQLe0D@LEk^lez literal 0 HcmV?d00001 diff --git a/devtools/qemu/centos/files/rhel6-virtio.rom b/devtools/qemu/centos/files/rhel6-virtio.rom new file mode 100644 index 0000000000000000000000000000000000000000..fa24faee741da179812b13a38c10cad14b7083ef GIT binary patch literal 53248 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 1.7.5-1 +Requires: sgabios-bin +%endif +%ifnarch aarch64 +Requires: seavgabios-bin >= 1.9.1-4 +Requires: ipxe-roms-qemu >= 20160127-4 +%endif +%ifarch %{power64} +Requires: SLOF >= %{SLOF_gittagdate}-1.git%{SLOF_gittagcommit} +%endif +Requires: %{pkgname}-common%{?pkgsuffix} = %{epoch}:%{version}-%{release} +%if %{have_seccomp} +Requires: libseccomp >= 1.0.0 +%endif +# For compressed guest memory dumps +Requires: lzo snappy +%if %{have_gluster} +Requires: glusterfs-api >= 3.6.0 +%endif +%if %{have_kvm_setup} +Requires(post): systemd-units + %ifarch %{power64} +Requires: powerpc-utils + %endif +%endif +Requires: libusbx >= 1.0.19 +%if %{have_usbredir} +Requires: usbredir >= 0.7.1 +%endif + +# OOM killer breaks builds with parallel make on s390(x) +%ifarch s390 s390x + %define _smp_mflags %{nil} +%endif + +Source0: qemu-kvm-ev-%{version}.tar.gz + +Source1: qemu.binfmt +# Creates /dev/kvm +Source3: 80-kvm.rules +# KSM control scripts +# Source4: ksm.service +# Source5: ksm.sysconfig +# Source6: ksmctl.c +# Source7: ksmtuned.service +# Source8: ksmtuned +# Source9: ksmtuned.conf +Source10: qemu-guest-agent.service +Source11: 99-qemu-guest-agent.rules +Source12: bridge.conf +Source13: qemu-ga.sysconfig +Source14: rhel6-virtio.rom +Source15: rhel6-pcnet.rom +Source16: rhel6-rtl8139.rom +Source17: rhel6-ne2k_pci.rom +Source18: bios-256k.bin +Source19: README.rhel6-gpxe-source +Source20: rhel6-e1000.rom +Source21: kvm-setup +Source22: kvm-setup.service +Source23: 85-kvm.preset +Source24: build_configure.sh +Source25: kvm-unit-tests.git-4ea7633.tar.bz2 +Source26: vhost.conf +Source27: kvm.conf +Source28: 95-kvm-memlock.conf + +#WRS +Source127: qemu_clean +Source128: qemu_clean.service +Source129: qemu-system-x86.conf + + +BuildRequires: zlib-devel +BuildRequires: SDL-devel +BuildRequires: which +BuildRequires: texi2html +BuildRequires: gnutls-devel +BuildRequires: cyrus-sasl-devel +BuildRequires: libtool +BuildRequires: libaio-devel +BuildRequires: rsync +BuildRequires: python +BuildRequires: pciutils-devel +BuildRequires: pulseaudio-libs-devel +BuildRequires: libiscsi-devel +BuildRequires: ncurses-devel +BuildRequires: libattr-devel +BuildRequires: libusbx-devel >= 1.0.19 +BuildRequires: systemd-devel +%if %{have_usbredir} +BuildRequires: usbredir-devel >= 0.7.1 +%endif +BuildRequires: texinfo +%if %{have_spice} +BuildRequires: spice-protocol >= 0.12.2 +BuildRequires: spice-server-devel >= 0.12.0 +BuildRequires: libcacard-devel +# For smartcard NSS support +BuildRequires: nss-devel +%endif +%if %{have_seccomp} +BuildRequires: libseccomp-devel >= 1.0.0 +%endif +# For network block driver +BuildRequires: libcurl-devel +BuildRequires: libssh2-devel +%ifarch x86_64 +BuildRequires: librados2-devel +BuildRequires: librbd1-devel +%endif +%if %{have_gluster} +# For gluster block driver +BuildRequires: glusterfs-api-devel >= 3.6.0 +BuildRequires: glusterfs-devel +%endif +# We need both because the 'stap' binary is probed for by configure +BuildRequires: systemtap +BuildRequires: systemtap-sdt-devel +# For XFS discard support in raw-posix.c +# For VNC JPEG support +BuildRequires: libjpeg-devel +# For VNC PNG support +BuildRequires: libpng-devel +# For uuid generation +BuildRequires: libuuid-devel +# For BlueZ device support +BuildRequires: bluez-libs-devel +# For Braille device support +BuildRequires: brlapi-devel +# For test suite +BuildRequires: check-devel +# For virtfs +BuildRequires: libcap-devel +# Hard requirement for version >= 1.3 +BuildRequires: pixman-devel +# Documentation requirement +BuildRequires: perl-podlators +BuildRequires: texinfo +# For rdma +%if 0%{?have_librdma} +BuildRequires: librdmacm-devel +%endif +%if 0%{?have_tcmalloc} +BuildRequires: gperftools-devel +%endif +%if %{have_fdt} +BuildRequires: libfdt-devel >= 1.4.2 +%endif +# iasl and cpp for acpi generation (not a hard requirement as we can use +# pre-compiled files, but it's better to use this) +%ifarch %{ix86} x86_64 +BuildRequires: iasl +BuildRequires: cpp +%endif +# For compressed guest memory dumps +BuildRequires: lzo-devel snappy-devel +# For NUMA memory binding +BuildRequires: numactl-devel +BuildRequires: libgcrypt-devel + +# For kvm-unit-tests +%ifarch x86_64 +BuildRequires: binutils +BuildRequires: kernel-devel +%endif + +# WRS: build_configure.sh enables libcap-ng +BuildRequires: libcap-ng-devel + +Requires: qemu-img%{?pkgsuffix} = %{epoch}:%{version}-%{release} + +# RHEV-specific changes: +# We provide special suffix for qemu-kvm so the conflit is easy +# In addition, RHEV version should obsolete all RHEL version in case both +# RHEL and RHEV channels are used +%rhel_rhev_conflicts qemu-kvm + + +%define qemudocdir %{_docdir}/%{pkgname} + +%description +qemu-kvm is an open source virtualizer that provides hardware emulation for +the KVM hypervisor. qemu-kvm acts as a virtual machine monitor together with +the KVM kernel modules, and emulates the hardware for a full system such as +a PC and its assocated peripherals. + +As qemu-kvm requires no host kernel patches to run, it is safe and easy to use. + +%package -n qemu-img%{?pkgsuffix} +Summary: QEMU command line tool for manipulating disk images +Group: Development/Tools + +%rhel_rhev_conflicts qemu-img + +%description -n qemu-img%{?pkgsuffix} +This package provides a command line tool for manipulating disk images. + +%package -n qemu-kvm-common%{?pkgsuffix} +Summary: QEMU common files needed by all QEMU targets +Group: Development/Tools +Requires(post): /usr/bin/getent +Requires(post): /usr/sbin/groupadd +Requires(post): /usr/sbin/useradd +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +%rhel_rhev_conflicts qemu-kvm-common + +%description -n qemu-kvm-common%{?pkgsuffix} +qemu-kvm is an open source virtualizer that provides hardware emulation for +the KVM hypervisor. + +This package provides documentation and auxiliary programs used with qemu-kvm. + +%package -n qemu-kvm-tools%{?pkgsuffix} +Summary: KVM debugging and diagnostics tools +Group: Development/Tools + +%rhel_rhev_conflicts qemu-kvm-tools + +%description -n qemu-kvm-tools%{?pkgsuffix} +This package contains some diagnostics and debugging tools for KVM, +such as kvm_stat. + +%if 0 +%package -n libcacard%{?pkgsuffix} +Summary: Common Access Card (CAC) Emulation +Group: Development/Libraries + +%rhel_rhev_conflicts libcacard + +%description -n libcacard%{?pkgsuffix} +Common Access Card (CAC) emulation library. + +%package -n libcacard-tools%{?pkgsuffix} +Summary: CAC Emulation tools +Group: Development/Libraries +Requires: libcacard%{?pkgsuffix} = %{epoch}:%{version}-%{release} +# older qemu-img has vscclient which is now in libcacard-tools +Requires: qemu-img%{?pkgsuffix} >= 3:1.3.0-5 + +%rhel_rhev_conflicts libcacard-tools + +%description -n libcacard-tools%{?pkgsuffix} +CAC emulation tools. + +%package -n libcacard-devel%{?pkgsuffix} +Summary: CAC Emulation devel +Group: Development/Libraries +Requires: libcacard%{?pkgsuffix} = %{epoch}:%{version}-%{release} + +%rhel_rhev_conflicts libcacard-devel + +%description -n libcacard-devel%{?pkgsuffix} +CAC emulation development files. +%endif + +%prep +%setup -q -n qemu-kvm-ev-%{version} + +# Copy bios files to allow 'make check' pass +cp %{SOURCE14} pc-bios +cp %{SOURCE15} pc-bios +cp %{SOURCE16} pc-bios +cp %{SOURCE17} pc-bios +cp %{SOURCE18} pc-bios +cp %{SOURCE20} pc-bios + +# if patch fuzzy patch applying will be forbidden +%define with_fuzzy_patches 0 +%if %{with_fuzzy_patches} + patch_command='patch -p1 -s' +%else + patch_command='patch -p1 -F1 -s' +%endif + +ApplyPatch() +{ + local patch=$1 + shift + if [ ! -f $RPM_SOURCE_DIR/$patch ]; then + exit 1 + fi + case "$patch" in + *.bz2) bunzip2 < "$RPM_SOURCE_DIR/$patch" | $patch_command ${1+"$@"} ;; + *.gz) gunzip < "$RPM_SOURCE_DIR/$patch" | $patch_command ${1+"$@"} ;; + *) $patch_command ${1+"$@"} < "$RPM_SOURCE_DIR/$patch" ;; + esac +} + +# don't apply patch if it's empty or does not exist +ApplyOptionalPatch() +{ + local patch=$1 + shift + if [ ! -f $RPM_SOURCE_DIR/$patch ]; then + return 0 + fi + local C=$(wc -l $RPM_SOURCE_DIR/$patch | awk '{print $1}') + if [ "$C" -gt 9 ]; then + ApplyPatch $patch ${1+"$@"} + fi +} + + +ApplyOptionalPatch qemu-kvm-test.patch + +# for tscdeadline_latency.flat +%ifarch x86_64 + tar -xf %{SOURCE25} +%endif + +%build +buildarch="%{kvm_target}-softmmu" + +# --build-id option is used for giving info to the debug packages. +extraldflags="-Wl,--build-id"; +buildldflags="VL_LDFLAGS=-Wl,--build-id" + +# QEMU already knows how to set _FORTIFY_SOURCE +%global optflags %(echo %{optflags} | sed 's/-Wp,-D_FORTIFY_SOURCE=2//') + +%ifarch s390 + # drop -g flag to prevent memory exhaustion by linker + %global optflags %(echo %{optflags} | sed 's/-g//') + sed -i.debug 's/"-g $CFLAGS"/"$CFLAGS"/g' configure +%endif + +cp %{SOURCE24} build_configure.sh + +./build_configure.sh \ + "%{_prefix}" \ + "%{_libdir}" \ + "%{_sysconfdir}" \ + "%{_localstatedir}" \ + "%{_libexecdir}" \ + "%{pkgname}" \ + "%{kvm_target}" \ + "%{name}-%{version}-%{release}" \ + "%{optflags}" \ +%if 0%{have_fdt} + enable \ +%else + disable \ +%endif +%if 0%{have_gluster} + enable \ +%else + disable \ +%endif + disable \ + enable \ +%ifarch x86_64 + enable \ +%else + disable \ +%endif + enable \ +%if 0%{have_seccomp} + enable \ +%else + disable \ +%endif +%if 0%{have_spice} + enable \ +%else + disable \ +%endif +%if 0%{have_usbredir} + enable \ +%else + disable \ +%endif +%if 0%{have_tcmalloc} + enable \ +%else + disable \ +%endif + --target-list="$buildarch" + +echo "config-host.mak contents:" +echo "===" +cat config-host.mak +echo "===" + +make V=1 %{?_smp_mflags} $buildldflags + +# WRS: Disable - we are not using traces +# Setup back compat qemu-kvm binary +# ./scripts/tracetool.py --backend dtrace --format stap \ +# --binary %{_libexecdir}/qemu-kvm --target-name %{kvm_target} \ +# --target-type system --probe-prefix \ +# qemu.kvm < ./trace-events > qemu-kvm.stp + +# ./scripts/tracetool.py --backend dtrace --format simpletrace-stap \ +# --binary %{_libexecdir}/qemu-kvm --target-name %{kvm_target} \ +# --target-type system --probe-prefix \ +# qemu.kvm < ./trace-events > qemu-kvm-simpletrace.stp + +cp -a %{kvm_target}-softmmu/qemu-system-%{kvm_target} qemu-kvm + + +# gcc %{SOURCE6} -O2 -g -o ksmctl + +# build tscdeadline_latency.flat +%ifarch x86_64 + (cd kvm-unit-tests && ./configure) + make -C kvm-unit-tests +%endif + +%install +%define _udevdir %(pkg-config --variable=udevdir udev)/rules.d + +# install -D -p -m 0644 %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/ksm.service +# install -D -p -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ksm +# install -D -p -m 0755 ksmctl $RPM_BUILD_ROOT%{_libexecdir}/ksmctl + +# install -D -p -m 0644 %{SOURCE7} $RPM_BUILD_ROOT%{_unitdir}/ksmtuned.service +# install -D -p -m 0755 %{SOURCE8} $RPM_BUILD_ROOT%{_sbindir}/ksmtuned +# install -D -p -m 0644 %{SOURCE9} $RPM_BUILD_ROOT%{_sysconfdir}/ksmtuned.conf +install -D -p -m 0644 %{SOURCE26} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/vhost.conf +install -D -p -m 0644 %{SOURCE129} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/qemu-system-x86.conf + +mkdir -p $RPM_BUILD_ROOT%{_bindir}/ +mkdir -p $RPM_BUILD_ROOT%{_udevdir} + +install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_udevdir} + +mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname} +install -m 0644 scripts/dump-guest-memory.py \ + $RPM_BUILD_ROOT%{_datadir}/%{pkgname} +%ifarch x86_64 + install -m 0644 kvm-unit-tests/x86/tscdeadline_latency.flat \ + $RPM_BUILD_ROOT%{_datadir}/%{pkgname} +%endif + +make DESTDIR=$RPM_BUILD_ROOT \ + sharedir="%{_datadir}/%{pkgname}" \ + datadir="%{_datadir}/%{pkgname}" \ + install + +mkdir -p $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset + +# Install compatibility roms +install %{SOURCE14} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/ +install %{SOURCE15} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/ +install %{SOURCE16} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/ +install %{SOURCE17} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/ +install %{SOURCE20} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/ + +install -m 0755 qemu-kvm $RPM_BUILD_ROOT%{_libexecdir}/ +# WRS: Disable traces +# install -m 0644 qemu-kvm.stp $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/ +# install -m 0644 qemu-kvm-simpletrace.stp $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/ + +# WRS: Add kvm softlink +ln -sf %{_libexecdir}/qemu-kvm $RPM_BUILD_ROOT/usr/bin/kvm + +rm $RPM_BUILD_ROOT%{_bindir}/qemu-system-%{kvm_target} +# WRS: Disable traces +# rm $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/qemu-system-%{kvm_target}.stp +# rm $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/qemu-system-%{kvm_target}-simpletrace.stp + +# Install simpletrace +# install -m 0755 scripts/simpletrace.py $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/simpletrace.py +# mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool +# install -m 0644 -t $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool scripts/tracetool/*.py +# mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/backend +# install -m 0644 -t $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/backend scripts/tracetool/backend/*.py +# mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/format +# install -m 0644 -t $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/format scripts/tracetool/format/*.py + +mkdir -p $RPM_BUILD_ROOT%{qemudocdir} +install -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README README.systemtap COPYING COPYING.LIB LICENSE %{SOURCE19} docs/interop/qmp-spec.txt +mv ${RPM_BUILD_ROOT}%{_docdir}/qemu/qemu-doc.html $RPM_BUILD_ROOT%{qemudocdir} +mv ${RPM_BUILD_ROOT}%{_docdir}/qemu/qemu-doc.txt $RPM_BUILD_ROOT%{qemudocdir} +mv ${RPM_BUILD_ROOT}%{_docdir}/qemu/qemu-qmp-ref.html $RPM_BUILD_ROOT%{qemudocdir} +mv ${RPM_BUILD_ROOT}%{_docdir}/qemu/qemu-qmp-ref.txt $RPM_BUILD_ROOT%{qemudocdir} +chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/* +chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man8/* + +install -D -p -m 0644 qemu.sasl $RPM_BUILD_ROOT%{_sysconfdir}/sasl2/%{pkgname}.conf + +# Provided by package openbios +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/openbios-ppc +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/openbios-sparc32 +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/openbios-sparc64 +# Provided by package SLOF +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/slof.bin + +# Remove unpackaged files. +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/palcode-clipper +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/petalogix*.dtb +rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/bamboo.dtb +rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/ppc_rom.bin +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/s390-zipl.rom +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/s390-ccw.img +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/s390-netboot.img +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/u-boot.e500 + +%ifnarch %{power64} + rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/spapr-rtas.bin + rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/skiboot.lid + rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/qemu_vga.ndrv +%endif + +%ifnarch x86_64 + rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/acpi-dsdt.aml + rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/kvmvapic.bin + rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/linuxboot.bin + rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/multiboot.bin +%endif + +# Remove sparc files +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/QEMU,tcx.bin +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/QEMU,cgthree.bin + +# Remove efi roms +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/efi*.rom + +# Remove ivshmem example programs +rm -rf ${RPM_BUILD_ROOT}%{_bindir}/ivshmem-client +rm -rf ${RPM_BUILD_ROOT}%{_bindir}/ivshmem-server + +# Provided by package ipxe +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/pxe*rom +# Provided by package vgabios +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/vgabios*bin +# Provided by package seabios +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/bios*.bin +# Provided by package sgabios +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/sgabios.bin + +# Remove tracing stuff +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/trace-events-all + +# the pxe gpxe images will be symlinks to the images on +# /usr/share/ipxe, as QEMU doesn't know how to look +# for other paths, yet. +pxe_link() { + ln -s ../ipxe/$2.rom %{buildroot}%{_datadir}/%{pkgname}/pxe-$1.rom +} + +%ifnarch aarch64 +pxe_link e1000 8086100e +pxe_link ne2k_pci 10ec8029 +pxe_link pcnet 10222000 +pxe_link rtl8139 10ec8139 +pxe_link virtio 1af41000 +pxe_link e1000e 808610d3 +%endif + +rom_link() { + ln -s $1 %{buildroot}%{_datadir}/%{pkgname}/$2 +} + +%ifnarch aarch64 + rom_link ../seavgabios/vgabios-isavga.bin vgabios.bin + rom_link ../seavgabios/vgabios-cirrus.bin vgabios-cirrus.bin + rom_link ../seavgabios/vgabios-qxl.bin vgabios-qxl.bin + rom_link ../seavgabios/vgabios-stdvga.bin vgabios-stdvga.bin + rom_link ../seavgabios/vgabios-vmware.bin vgabios-vmware.bin + rom_link ../seavgabios/vgabios-virtio.bin vgabios-virtio.bin +%endif +%ifarch x86_64 + rom_link ../seabios/bios.bin bios.bin + rom_link ../seabios/bios-256k.bin bios-256k.bin + rom_link ../sgabios/sgabios.bin sgabios.bin +%endif + +%if 0%{have_kvm_setup} + install -D -p -m 755 %{SOURCE21} $RPM_BUILD_ROOT%{_prefix}/lib/systemd/kvm-setup + install -D -p -m 644 %{SOURCE22} $RPM_BUILD_ROOT%{_unitdir}/kvm-setup.service + install -D -p -m 644 %{SOURCE23} $RPM_BUILD_ROOT%{_presetdir}/85-kvm.preset +%endif + +%if 0%{have_memlock_limits} + install -D -p -m 644 %{SOURCE28} $RPM_BUILD_ROOT%{_sysconfdir}/security/limits.d/95-kvm-memlock.conf +%endif + +# Install rules to use the bridge helper with libvirt's virbr0 +install -D -m 0644 %{SOURCE12} $RPM_BUILD_ROOT%{_sysconfdir}/%{pkgname}/bridge.conf + +%if 0 +make %{?_smp_mflags} $buildldflags DESTDIR=$RPM_BUILD_ROOT install-libcacard + +find $RPM_BUILD_ROOT -name "libcacard.so*" -exec chmod +x \{\} \; +%endif + +find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f + +# WRS +install -d %{buildroot}/etc/init.d +install -m 700 %{SOURCE127} %{buildroot}/etc/init.d/qemu_clean +install -d %{buildroot}/etc/systemd/system/ +install -m 664 %{SOURCE128} %{buildroot}/etc/systemd/system/qemu_clean.service + +%check +# WRS: Disable unit tests +# make check V=1 + +%post +# load kvm modules now, so we can make sure no reboot is needed. +# If there's already a kvm module installed, we don't mess with it +%udev_rules_update +sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : + udevadm trigger --subsystem-match=misc --sysname-match=kvm --action=add || : +%if %{have_kvm_setup} + systemctl daemon-reload # Make sure it sees the new presets and unitfile + %systemd_post kvm-setup.service + if systemctl is-enabled kvm-setup.service > /dev/null; then + systemctl start kvm-setup.service + fi +%endif + +%post -n qemu-kvm-common%{?pkgsuffix} +# %systemd_post ksm.service +# %systemd_post ksmtuned.service + +getent group kvm >/dev/null || groupadd -g 36 -r kvm +getent group qemu >/dev/null || groupadd -g 107 -r qemu +getent passwd qemu >/dev/null || \ +useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ + -c "qemu user" qemu + +# WRS +if [ $1 -eq 1 ] ; then + ln -s /usr/libexec/qemu-kvm /usr/bin/qemu-system-x86_64 +fi +exit 0 + +%systemd_post qemu_clean.service + +%preun -n qemu-kvm-common%{?pkgsuffix} +# %systemd_preun ksm.service +# %systemd_preun ksmtuned.service + +# WRS +%systemd_preun qemu_clean.service + +%postun -n qemu-kvm-common%{?pkgsuffix} +# %systemd_postun_with_restart ksm.service +# %systemd_postun_with_restart ksmtuned.service + +# WRS +%systemd_postun_with_restart qemu_clean.service + +%global kvm_files \ +%{_udevdir}/80-kvm.rules + +%global qemu_kvm_files \ +%{_libexecdir}/qemu-kvm \ +%{_datadir}/%{pkgname}/systemtap/conf.d/qemu_kvm.conf \ +%{_datadir}/%{pkgname}/systemtap/script.d/qemu_kvm.stp + +# WRS: Disable traces +# %{_datadir}/systemtap/tapset/qemu-kvm.stp +# %{_datadir}/systemtap/tapset/qemu-kvm-simpletrace.stp + +%files -n qemu-kvm-common%{?pkgsuffix} +%defattr(-,root,root) +%dir %{qemudocdir} +%doc %{qemudocdir}/Changelog +%doc %{qemudocdir}/README +%doc %{qemudocdir}/qemu-doc.html +%doc %{qemudocdir}/qemu-doc.txt +%doc %{qemudocdir}/COPYING +%doc %{qemudocdir}/COPYING.LIB +%doc %{qemudocdir}/LICENSE +%doc %{qemudocdir}/README.rhel6-gpxe-source +%doc %{qemudocdir}/README.systemtap +%doc %{qemudocdir}/qmp-spec.txt +%doc %{qemudocdir}/qemu-qmp-ref.html +%doc %{qemudocdir}/qemu-qmp-ref.txt + +%dir %{_datadir}/%{pkgname}/ +%{_datadir}/%{pkgname}/keymaps/ +%{_mandir}/man1/%{pkgname}.1* +%{_mandir}/man7/qemu-qmp-ref* +%attr(4755, -, -) %{_libexecdir}/qemu-bridge-helper +%config(noreplace) %{_sysconfdir}/sasl2/%{pkgname}.conf +# %{_unitdir}/ksm.service +# %{_libexecdir}/ksmctl +# %config(noreplace) %{_sysconfdir}/sysconfig/ksm +# %{_unitdir}/ksmtuned.service +# %{_sbindir}/ksmtuned +# %config(noreplace) %{_sysconfdir}/ksmtuned.conf +%dir %{_sysconfdir}/%{pkgname} +%config(noreplace) %{_sysconfdir}/%{pkgname}/bridge.conf +%config(noreplace) %{_sysconfdir}/modprobe.d/vhost.conf +%{_sysconfdir}/modprobe.d/qemu-system-x86.conf +# WRS: Disable traces +# %{_datadir}/%{pkgname}/simpletrace.py* +# %{_datadir}/%{pkgname}/tracetool/*.py* +# %{_datadir}/%{pkgname}/tracetool/backend/*.py* +# %{_datadir}/%{pkgname}/tracetool/format/*.py* + +%files +%defattr(-,root,root) +%ifarch x86_64 + %{_datadir}/%{pkgname}/acpi-dsdt.aml + %{_datadir}/%{pkgname}/bios.bin + %{_datadir}/%{pkgname}/bios-256k.bin + %{_datadir}/%{pkgname}/linuxboot.bin + %{_datadir}/%{pkgname}/linuxboot_dma.bin + %{_datadir}/%{pkgname}/multiboot.bin + %{_datadir}/%{pkgname}/kvmvapic.bin + %{_datadir}/%{pkgname}/sgabios.bin +%endif +%ifnarch aarch64 + %{_datadir}/%{pkgname}/vgabios.bin + %{_datadir}/%{pkgname}/vgabios-cirrus.bin + %{_datadir}/%{pkgname}/vgabios-qxl.bin + %{_datadir}/%{pkgname}/vgabios-stdvga.bin + %{_datadir}/%{pkgname}/vgabios-vmware.bin + %{_datadir}/%{pkgname}/vgabios-virtio.bin + %{_datadir}/%{pkgname}/pxe-e1000.rom + %{_datadir}/%{pkgname}/pxe-e1000e.rom + %{_datadir}/%{pkgname}/pxe-virtio.rom + %{_datadir}/%{pkgname}/pxe-pcnet.rom + %{_datadir}/%{pkgname}/pxe-rtl8139.rom + %{_datadir}/%{pkgname}/pxe-ne2k_pci.rom +%endif +%{_datadir}/%{pkgname}/qemu-icon.bmp +%{_datadir}/%{pkgname}/qemu_logo_no_text.svg +%{_datadir}/%{pkgname}/rhel6-virtio.rom +%{_datadir}/%{pkgname}/rhel6-pcnet.rom +%{_datadir}/%{pkgname}/rhel6-rtl8139.rom +%{_datadir}/%{pkgname}/rhel6-ne2k_pci.rom +%{_datadir}/%{pkgname}/rhel6-e1000.rom +%{_datadir}/%{pkgname}/dump-guest-memory.py* +%ifarch %{power64} + %{_datadir}/%{pkgname}/spapr-rtas.bin +%endif +%{?kvm_files:} +%{?qemu_kvm_files:} +%if %{have_kvm_setup} + %{_prefix}/lib/systemd/kvm-setup + %{_unitdir}/kvm-setup.service + %{_presetdir}/85-kvm.preset +%endif +%if 0%{have_memlock_limits} + %{_sysconfdir}/security/limits.d/95-kvm-memlock.conf +%endif + +# WRS +/etc/init.d/qemu_clean +/etc/systemd/system/qemu_clean.service +/usr/bin/virtfs-proxy-helper +/usr/bin/kvm + +%files -n qemu-kvm-tools%{?pkgsuffix} +%defattr(-,root,root,-) +%ifarch x86_64 +%{_datadir}/%{pkgname}/tscdeadline_latency.flat +%endif + +%files -n qemu-img%{?pkgsuffix} +%defattr(-,root,root) +%{_bindir}/qemu-img +%{_bindir}/qemu-io +%{_bindir}/qemu-nbd +%{_mandir}/man1/qemu-img.1* +%{_mandir}/man8/qemu-nbd.8* +# WRS: virtfs +%{_mandir}/man1/virtfs-proxy-helper.1* + +%if 0 +%files -n libcacard%{?pkgsuffix} +%defattr(-,root,root,-) +%{_libdir}/libcacard.so.* + +%files -n libcacard-tools%{?pkgsuffix} +%defattr(-,root,root,-) +%{_bindir}/vscclient + +%files -n libcacard-devel%{?pkgsuffix} +%defattr(-,root,root,-) +%{_includedir}/cacard +%{_libdir}/libcacard.so +%{_libdir}/pkgconfig/libcacard.pc +%endif + +%changelog +* Thu Apr 20 2017 Sandro Bonazzola - ev-2.6.0-28.el7_3.9.1 +- Removing RH branding from package name + +* Fri Mar 24 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.9 +- kvm-block-gluster-memory-usage-use-one-glfs-instance-per.patch [bz#1413044] +- kvm-gluster-Fix-use-after-free-in-glfs_clear_preopened.patch [bz#1413044] +- kvm-fix-cirrus_vga-fix-OOB-read-case-qemu-Segmentation-f.patch [bz#1430061] +- kvm-cirrus-vnc-zap-bitblit-support-from-console-code.patch [bz#1430061] +- kvm-cirrus-add-option-to-disable-blitter.patch [bz#1430061] +- kvm-cirrus-fix-cirrus_invalidate_region.patch [bz#1430061] +- kvm-cirrus-stop-passing-around-dst-pointers-in-the-blitt.patch [bz#1430061] +- kvm-cirrus-stop-passing-around-src-pointers-in-the-blitt.patch [bz#1430061] +- kvm-cirrus-fix-off-by-one-in-cirrus_bitblt_rop_bkwd_tran.patch [bz#1430061] +- kvm-file-posix-Consider-max_segments-for-BlockLimits.max.patch [bz#1431149] +- kvm-file-posix-clean-up-max_segments-buffer-termination.patch [bz#1431149] +- kvm-file-posix-Don-t-leak-fd-in-hdev_get_max_segments.patch [bz#1431149] +- Resolves: bz#1413044 + (block-gluster: use one glfs instance per volume) +- Resolves: bz#1430061 + (CVE-2016-9603 qemu-kvm-rhev: Qemu: cirrus: heap buffer overflow via vnc connection [rhel-7.3.z]) +- Resolves: bz#1431149 + (VMs pause when writing to Virtio-SCSI direct lun with scsi passthrough enabled via an Emulex HBA) + +* Tue Mar 21 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.8 +- kvm-target-i386-present-virtual-L3-cache-info-for-vcpus.patch [bz#1430802] +- Resolves: bz#1430802 + (Enhance qemu to present virtual L3 cache info for vcpus) + +* Wed Mar 15 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.7 +- kvm-block-check-full-backing-filename-when-searching-pro.patch [bz#1425125] +- kvm-qemu-iotests-Don-t-create-fifos-pidfiles-with-protoc.patch [bz#1425125] +- kvm-qemu-iotest-test-to-lookup-protocol-based-image-with.patch [bz#1425125] +- kvm-target-i386-Don-t-use-cpu-migratable-when-filtering-.patch [bz#1413897] +- Resolves: bz#1413897 + (cpu flag nonstop_tsc is not present in guest with host-passthrough and feature policy require invtsc) +- Resolves: bz#1425125 + (qemu fails to recognize gluster URIs in backing chain for block-commit operation) + +* Mon Feb 13 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.6 +- kvm-cirrus-fix-patterncopy-checks.patch [bz#1420493] +- kvm-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch [bz#1420493] +- kvm-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch [bz#1420493] +- Resolves: bz#1420493 + (EMBARGOED CVE-2017-2620 qemu-kvm-rhev: Qemu: display: cirrus: potential arbitrary code execution via cirrus_bitblt_cputovideo [rhel-7.3.z]) + +* Fri Feb 10 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.5 +- kvm-memory-Provide-memory_region_init_rom.patch [bz#1420456] +- kvm-pci-mark-ROMs-read-only.patch [bz#1420456] +- kvm-vhost-skip-ROM-sections.patch [bz#1420456] +- kvm-display-cirrus-check-vga-bits-per-pixel-bpp-value.patch [bz#1418234] +- kvm-display-cirrus-ignore-source-pitch-value-as-needed-i.patch [bz#1418234] +- kvm-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch [bz#1418234] +- kvm-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch [bz#1418234] +- kvm-cirrus-fix-blit-address-mask-handling.patch [bz#1418234] +- kvm-cirrus-fix-oob-access-issue-CVE-2017-2615.patch [bz#1418234] +- Resolves: bz#1418234 + (CVE-2017-2615 qemu-kvm-rhev: Qemu: display: cirrus: oob access while doing bitblt copy backward mode [rhel-7.3.z]) +- Resolves: bz#1420456 + ([ppc64le]reset vm when do migration, HMP in src host promp "tcmalloc: large alloc 1073872896 bytes...") + +* Wed Feb 08 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.4 +- kvm-Disable-usbredir-and-libcacard-for-unsupported-archi.patch [bz#1420428] +- Resolves: bz#1420428 + (Remove dependencies required by spice on ppc64le) + +* Wed Jan 04 2017 Miroslav Rezanina - rhev-2.6.0-28.el7_3.3 +- kvm-pc_piix-fix-compat-props-typo-for-RHEL6-machine-type.patch [bz#1408122] +- kvm-net-don-t-poke-at-chardev-internal-QemuOpts.patch [bz#1410200] +- Resolves: bz#1408122 + (Opteron_G4 CPU model broken in QEMU 2.6 with RHEL 6 machine type) +- Resolves: bz#1410200 + (qemu gets SIGSEGV when hot-plug a vhostuser network) + +* Fri Dec 09 2016 Miroslav Rezanina - rhev-2.6.0-28.el7_3.2 +- kvm-numa-do-not-leak-NumaOptions.patch [bz#1397745] +- kvm-char-free-the-tcp-connection-data-when-closing.patch [bz#1397745] +- kvm-char-free-MuxDriver-when-closing.patch [bz#1397745] +- kvm-ahci-free-irqs-array.patch [bz#1397745] +- kvm-virtio-input-free-config-list.patch [bz#1397745] +- kvm-usb-free-USBDevice.strings.patch [bz#1397745] +- kvm-usb-free-leaking-path.patch [bz#1397745] +- kvm-ahci-fix-sglist-leak-on-retry.patch [bz#1397745] +- kvm-virtio-add-virtqueue_rewind.patch [bz#1402509] +- kvm-virtio-balloon-fix-stats-vq-migration.patch [bz#1402509] +- kvm-virtio-blk-Release-s-rq-queue-at-system_reset.patch [bz#1393041] +- kvm-virtio-blk-Remove-stale-comment-about-draining.patch [bz#1393041] +- Resolves: bz#1393041 + (system_reset should clear pending request for error (virtio-blk)) +- Resolves: bz#1397745 + (Backport memory leak fixes from QEMU 2.7) +- Resolves: bz#1402509 + (virtio-balloon stats virtqueue does not migrate properly) + +* Wed Nov 30 2016 Miroslav Rezanina - rhev-2.6.0-28.el7_3.1 +- kvm-ide-fix-halted-IO-segfault-at-reset.patch [bz#1393043] +- kvm-atapi-fix-halted-DMA-reset.patch [bz#1393043] +- kvm-ahci-clear-aiocb-in-ncq_cb.patch [bz#1393736] +- kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch [bz#1392876] +- kvm-Postcopy-vs-xbzrle-Don-t-send-xbzrle-pages-once-in-p.patch [bz#1395360] +- kvm-ui-fix-refresh-of-VNC-server-surface.patch [bz#1392881] +- Resolves: bz#1392876 + (windows guests migration from rhel6.8-z to rhel7.3 with virtio-net-pci fail) +- Resolves: bz#1392881 + (Graphic can't be showed out quickly if guest graphic mode is vnc) +- Resolves: bz#1393043 + (system_reset should clear pending request for error (IDE)) +- Resolves: bz#1393736 + (qemu core dump when there is an I/O error on AHCI) +- Resolves: bz#1395360 + (Post-copy migration fails with XBZRLE compression) + +* Tue Sep 27 2016 Miroslav Rezanina - rhev-2.6.0-28.el7 +- kvm-ARM-ACPI-fix-the-AML-ID-format-for-CPU-devices.patch [bz#1373733] +- Resolves: bz#1373733 + (failed to run a guest VM with >= 12 vcpu under ACPI mode) + +* Fri Sep 23 2016 Miroslav Rezanina - rhev-2.6.0-27.el7 +- kvm-char-fix-waiting-for-TLS-and-telnet-connection.patch [bz#1300773] +- kvm-target-i386-introduce-kvm_put_one_msr.patch [bz#1377920] +- kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch [bz#1377920] +- Resolves: bz#1300773 + (RFE: add support for native TLS encryption on chardev TCP transports) +- Resolves: bz#1377920 + (Guest fails reboot and causes kernel-panic) + +* Tue Sep 20 2016 Miroslav Rezanina - rhev-2.6.0-26.el7 +- kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch [bz#1372455] +- kvm-iothread-Stop-threads-before-main-quits.patch [bz#1343021] +- kvm-virtio-pci-error-out-when-both-legacy-and-modern-mod.patch [bz#1370005] +- kvm-virtio-bus-Plug-devices-after-features-are-negotiate.patch [bz#1370005] +- kvm-virtio-pci-reduce-modern_mem_bar-size.patch [bz#1365613] +- kvm-virtio-vga-adapt-to-page-per-vq-off.patch [bz#1365613] +- kvm-virtio-gpu-pci-tag-as-not-hotpluggable.patch [bz#1368032] +- kvm-scsi-disk-Cleaning-up-around-tray-open-state.patch [bz#1374251] +- kvm-virtio-scsi-Don-t-abort-when-media-is-ejected.patch [bz#1374251] +- kvm-io-remove-mistaken-call-to-object_ref-on-QTask.patch [bz#1375677] +- kvm-block-Invalidate-all-children.patch [bz#1355927] +- kvm-block-Drop-superfluous-invalidating-bs-file-from-dri.patch [bz#1355927] +- kvm-block-Inactivate-all-children.patch [bz#1355927] +- kvm-vfio-pci-Fix-regression-in-MSI-routing-configuration.patch [bz#1373802] +- kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch [bz#1363998] +- kvm-blockdev-ignore-cache-options-for-empty-CDROM-drives.patch [bz#1342999] +- kvm-block-reintroduce-bdrv_flush_all.patch [bz#1338638] +- kvm-qemu-use-bdrv_flush_all-for-vm_stop-et-al.patch [bz#1338638] +- Resolves: bz#1338638 + (Migration fails after ejecting the cdrom in the guest) +- Resolves: bz#1342999 + ('cache=x' cannot work with empty cdrom) +- Resolves: bz#1343021 + (Core dump when quit from HMP after migration finished) +- Resolves: bz#1355927 + (qemu SIGABRT when doing inactive blockcommit with external system checkpoint snapshot) +- Resolves: bz#1363998 + (Live migration via a compressed file causes the guest desktop to freeze) +- Resolves: bz#1365613 + ([PCI] The default MMIO range reserved by firmware for PCI bridges is not enough to hotplug virtio-1 devices) +- Resolves: bz#1368032 + (kernel crash after hot remove virtio-gpu device) +- Resolves: bz#1370005 + (Fail to get network device info(eth0) in guest with virtio-net-pci/vhostforce) +- Resolves: bz#1372455 + ([Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl)(qemu-kvm-rhev)) +- Resolves: bz#1373802 + (Network can't recover when trigger EEH one time) +- Resolves: bz#1374251 + (qemu-kvm-rhev core dumped when enabling virtio-scsi "data plane" and executing "eject") +- Resolves: bz#1375677 + (Crash when performing VNC websockets handshake) + +* Tue Sep 13 2016 Miroslav Rezanina - rhev-2.6.0-25.el7 +- kvm-virtio-recalculate-vq-inuse-after-migration.patch [bz#1372763] +- kvm-virtio-decrement-vq-inuse-in-virtqueue_discard.patch [bz#1372763] +- kvm-virtio-balloon-discard-virtqueue-element-on-reset.patch [bz#1370703] +- kvm-virtio-zero-vq-inuse-in-virtio_reset.patch [bz#1370703 bz#1374623] +- Resolves: bz#1370703 + ([Balloon] Whql Job "Commom scenario stress with IO" failed on 2008-32/64) +- Resolves: bz#1372763 + (RHSA-2016-1756 breaks migration of instances) +- Resolves: bz#1374623 + (RHSA-2016-1756 breaks migration of instances) + +* Fri Sep 09 2016 Miroslav Rezanina - rhev-2.6.0-24.el7 +- kvm-Fix-configure-test-for-PBKDF2-in-nettle.patch [bz#1301019] +- kvm-redhat-switch-from-gcrypt-to-nettle-for-crypto.patch [bz#1301019] +- kvm-crypto-assert-that-qcrypto_hash_digest_len-is-in-ran.patch [bz#1301019] +- kvm-crypto-fix-handling-of-iv-generator-hash-defaults.patch [bz#1301019] +- kvm-crypto-ensure-XTS-is-only-used-with-ciphers-with-16-.patch [bz#1301019] +- kvm-vhost-user-test-Use-libqos-instead-of-pxe-virtio.rom.patch [bz#1371211] +- kvm-vl-Delay-initialization-of-memory-backends.patch [bz#1371211] +- kvm-spapr-implement-H_CHANGE_LOGICAL_LAN_MAC-h_call.patch [bz#1371419] +- Resolves: bz#1301019 + (RFE: add support for LUKS disk encryption format driver w/ RBD, iSCSI, and qcow2) +- Resolves: bz#1371211 + (Qemu 2.6 won't boot guest with 2 meg hugepages) +- Resolves: bz#1371419 + ([ppc64le] Can't modify mac address for spapr-vlan device in rhel6.8 guest) + +* Tue Sep 06 2016 Miroslav Rezanina - rhev-2.6.0-23.el7 +- kvm-vhost-user-disconnect-on-HUP.patch [bz#1355902] +- kvm-vhost-don-t-assume-opaque-is-a-fd-use-backend-cleanu.patch [bz#1355902] +- kvm-vhost-make-vhost_log_put-idempotent.patch [bz#1355902] +- kvm-vhost-assert-the-log-was-cleaned-up.patch [bz#1355902] +- kvm-vhost-fix-cleanup-on-not-fully-initialized-device.patch [bz#1355902] +- kvm-vhost-make-vhost_dev_cleanup-idempotent.patch [bz#1355902] +- kvm-vhost-net-always-call-vhost_dev_cleanup-on-failure.patch [bz#1355902] +- kvm-vhost-fix-calling-vhost_dev_cleanup-after-vhost_dev_.patch [bz#1355902] +- kvm-vhost-do-not-assert-on-vhost_ops-failure.patch [bz#1355902] +- kvm-vhost-add-missing-VHOST_OPS_DEBUG.patch [bz#1355902] +- kvm-vhost-use-error_report-instead-of-fprintf-stderr.patch [bz#1355902] +- kvm-qemu-char-fix-qemu_chr_fe_set_msgfds-crash-when-disc.patch [bz#1355902] +- kvm-vhost-user-call-set_msgfds-unconditionally.patch [bz#1355902] +- kvm-vhost-user-check-qemu_chr_fe_set_msgfds-return-value.patch [bz#1355902] +- kvm-vhost-user-check-vhost_user_-read-write-return-value.patch [bz#1355902] +- kvm-vhost-user-keep-vhost_net-after-a-disconnection.patch [bz#1355902] +- kvm-vhost-user-add-get_vhost_net-assertions.patch [bz#1355902] +- kvm-Revert-vhost-net-do-not-crash-if-backend-is-not-pres.patch [bz#1355902] +- kvm-vhost-net-vhost_migration_done-is-vhost-user-specifi.patch [bz#1355902] +- kvm-vhost-add-assert-to-check-runtime-behaviour.patch [bz#1355902] +- kvm-char-add-chr_wait_connected-callback.patch [bz#1355902] +- kvm-char-add-and-use-tcp_chr_wait_connected.patch [bz#1355902] +- kvm-vhost-user-wait-until-backend-init-is-completed.patch [bz#1355902] +- kvm-vhost-user-add-error-report-in-vhost_user_write.patch [bz#1355902] +- kvm-vhost-add-vhost_net_set_backend.patch [bz#1355902] +- kvm-vhost-do-not-update-last-avail-idx-on-get_vring_base.patch [bz#1355902] +- kvm-vhost-check-for-vhost_ops-before-using.patch [bz#1355902] +- kvm-vhost-user-Introduce-a-new-protocol-feature-REPLY_AC.patch [bz#1355902] +- kvm-linux-aio-Handle-io_submit-failure-gracefully.patch [bz#1285928] +- kvm-Revert-acpi-pc-add-fw_cfg-device-node-to-dsdt.patch [bz#1368153] +- Resolves: bz#1285928 + (linux-aio aborts on io_submit() failure) +- Resolves: bz#1355902 + (vhost-user reconnect misc fixes and improvements) +- Resolves: bz#1368153 + (Please hide fw_cfg device in windows guest in order to make svvp test pass) + +* Mon Aug 22 2016 Miroslav Rezanina - rhev-2.6.0-22.el7 +- kvm-target-i386-kvm-Report-kvm_pv_unhalt-as-unsupported-.patch [bz#1363679] +- kvm-ioapic-keep-RO-bits-for-IOAPIC-entry.patch [bz#1358653] +- kvm-ioapic-clear-remote-irr-bit-for-edge-triggered-inter.patch [bz#1358653] +- kvm-x86-iommu-introduce-parent-class.patch [bz#1358653] +- kvm-intel_iommu-rename-VTD_PCI_DEVFN_MAX-to-x86-iommu.patch [bz#1358653] +- kvm-x86-iommu-provide-x86_iommu_get_default.patch [bz#1358653] +- kvm-x86-iommu-introduce-intremap-property.patch [bz#1358653] +- kvm-acpi-enable-INTR-for-DMAR-report-structure.patch [bz#1358653] +- kvm-intel_iommu-allow-queued-invalidation-for-IR.patch [bz#1358653] +- kvm-intel_iommu-set-IR-bit-for-ECAP-register.patch [bz#1358653] +- kvm-acpi-add-DMAR-scope-definition-for-root-IOAPIC.patch [bz#1358653] +- kvm-intel_iommu-define-interrupt-remap-table-addr-regist.patch [bz#1358653] +- kvm-intel_iommu-handle-interrupt-remap-enable.patch [bz#1358653] +- kvm-intel_iommu-define-several-structs-for-IOMMU-IR.patch [bz#1358653] +- kvm-intel_iommu-add-IR-translation-faults-defines.patch [bz#1358653] +- kvm-intel_iommu-Add-support-for-PCI-MSI-remap.patch [bz#1358653] +- kvm-intel_iommu-get-rid-of-0-initializers.patch [bz#1358653] +- kvm-q35-ioapic-add-support-for-emulated-IOAPIC-IR.patch [bz#1358653] +- kvm-ioapic-introduce-ioapic_entry_parse-helper.patch [bz#1358653] +- kvm-intel_iommu-add-support-for-split-irqchip.patch [bz#1358653] +- kvm-x86-iommu-introduce-IEC-notifiers.patch [bz#1358653] +- kvm-ioapic-register-IOMMU-IEC-notifier-for-ioapic.patch [bz#1358653] +- kvm-intel_iommu-Add-support-for-Extended-Interrupt-Mode.patch [bz#1358653] +- kvm-intel_iommu-add-SID-validation-for-IR.patch [bz#1358653] +- kvm-irqchip-simplify-kvm_irqchip_add_msi_route.patch [bz#1358653] +- kvm-irqchip-i386-add-hook-for-add-remove-virq.patch [bz#1358653] +- kvm-irqchip-x86-add-msi-route-notify-fn.patch [bz#1358653] +- kvm-irqchip-do-explicit-commit-when-update-irq.patch [bz#1358653] +- kvm-intel_iommu-support-all-masks-in-interrupt-entry-cac.patch [bz#1358653] +- kvm-all-add-trace-events-for-kvm-irqchip-ops.patch [bz#1358653] +- kvm-intel_iommu-disallow-kernel-irqchip-on-with-IR.patch [bz#1358653] +- kvm-intel_iommu-avoid-unnamed-fields.patch [bz#1358653] +- kvm-irqchip-only-commit-route-when-irqchip-is-used.patch [bz#1358653] +- kvm-x86-ioapic-ignore-level-irq-during-processing.patch [bz#1358653] +- kvm-x86-ioapic-add-support-for-explicit-EOI.patch [bz#1358653] +- kvm-memory-Fix-IOMMU-replay-base-address.patch [bz#1364035] +- kvm-Add-luks-to-block-driver-whitelist.patch [bz#1301019] +- Resolves: bz#1301019 + (RFE: add support for LUKS disk encryption format driver w/ RBD, iSCSI, and qcow2) +- Resolves: bz#1358653 + ([RFE] Interrupt remapping support for Intel vIOMMUs) +- Resolves: bz#1363679 + (RHEL guest hangs with kernel-irqchip=off and smp>1) +- Resolves: bz#1364035 + ([ppc64le][VFIO]Qemu complains:vfio_dma_map(0x10033d3a980, 0x1f34f0000, 0x10000, 0x3fff9a6d0000) = -6 (No such device or address)) + +* Tue Aug 16 2016 Miroslav Rezanina - rhev-2.6.0-21.el7 +- kvm-fix-qemu-exit-on-memory-hotplug-when-allocation-fail.patch [bz#1351409] +- kvm-spapr-remove-extra-type-variable.patch [bz#1363812] +- kvm-ppc-Introduce-a-function-to-look-up-CPU-alias-string.patch [bz#1363812] +- kvm-hw-ppc-spapr-Look-up-CPU-alias-names-instead-of-hard.patch [bz#1363812] +- kvm-ppc-kvm-Do-not-mess-up-the-generic-CPU-family-regist.patch [bz#1363812] +- kvm-ppc-kvm-Register-also-a-generic-spapr-CPU-core-famil.patch [bz#1363812] +- kvm-ppc64-fix-compressed-dump-with-pseries-kernel.patch [bz#1240497] +- kvm-monitor-fix-crash-when-leaving-qemu-with-spice-audio.patch [bz#1355704] +- kvm-audio-clean-up-before-monitor-clean-up.patch [bz#1355704] +- kvm-vnc-don-t-crash-getting-server-info-if-lsock-is-NULL.patch [bz#1359655] +- kvm-vnc-fix-crash-when-vnc_server_info_get-has-an-error.patch [bz#1359655] +- kvm-vnc-ensure-connection-sharing-limits-is-always-confi.patch [bz#1359655] +- kvm-vnc-make-sure-we-finish-disconnect.patch [bz#1352799] +- kvm-virtio-net-allow-increasing-rx-queue-size.patch [bz#1358962] +- kvm-input-add-trace-events-for-full-queues.patch [bz#1366471] +- kvm-virtio-set-low-features-early-on-load.patch [bz#1365747] +- kvm-Revert-virtio-net-unbreak-self-announcement-and-gues.patch [bz#1365747] +- Resolves: bz#1240497 + (qemu-kvm-rhev: dump-guest-memory creates invalid header with format kdump-{zlib,lzo,snappy} on ppc64) +- Resolves: bz#1351409 + (When hotplug memory, guest will shutdown as Insufficient free host memory pages available to allocate) +- Resolves: bz#1352799 + (Client information from hmp doesn't vanish after client disconnect when using vnc display) +- Resolves: bz#1355704 + (spice: core dump when 'quit') +- Resolves: bz#1358962 + (Increase the queue size to the max allowed, 1024.) +- Resolves: bz#1359655 + (Qemu crashes when connecting to a guest started with "-vnc none" by virt-viewer) +- Resolves: bz#1363812 + (qemu-kvm-rhev: -cpu POWER8 no longer works) +- Resolves: bz#1365747 + (Migrate guest(win10) after hot plug/unplug memory balloon device [Missing section footer for 0000:00:07.0/virtio-net]) +- Resolves: bz#1366471 + (QEMU prints "usb-kbd: warning: key event queue full" when pressing keys during SLOF boot) + +* Wed Aug 10 2016 Miroslav Rezanina - rhev-2.6.0-20.el7 +- kvm-block-gluster-rename-server-volname-image-host-volum.patch [bz#1247933] +- kvm-block-gluster-code-cleanup.patch [bz#1247933] +- kvm-block-gluster-deprecate-rdma-support.patch [bz#1247933] +- kvm-block-gluster-using-new-qapi-schema.patch [bz#1247933] +- kvm-block-gluster-add-support-for-multiple-gluster-serve.patch [bz#1247933] +- kvm-block-gluster-fix-doc-in-the-qapi-schema-and-member-.patch [bz#1247933] +- kvm-throttle-Don-t-allow-burst-limits-to-be-lower-than-t.patch [bz#1355665] +- kvm-throttle-Test-burst-limits-lower-than-the-normal-lim.patch [bz#1355665] +- kvm-spapr-Error-out-when-CPU-hotplug-is-attempted-on-old.patch [bz#1362019] +- kvm-spapr-Correctly-set-query_hotpluggable_cpus-hook-bas.patch [bz#1362019] +- Resolves: bz#1247933 + (RFE: qemu-kvm-rhev: support multiple volume hosts for gluster volumes) +- Resolves: bz#1355665 + (Suggest to limit the burst value to be not less than the throttle value) +- Resolves: bz#1362019 + (Crashes when using query-hotpluggable-cpus with pseries-rhel7.2.0 machine type) + +* Fri Aug 05 2016 Miroslav Rezanina - rhev-2.6.0-19.el7 +- kvm-hw-pcie-root-port-Fix-PCIe-root-port-initialization.patch [bz#1323976] +- kvm-hw-pxb-declare-pxb-devices-as-not-hot-pluggable.patch [bz#1323976] +- kvm-hw-acpi-fix-a-DSDT-table-issue-when-a-pxb-is-present.patch [bz#1323976] +- kvm-acpi-refactor-pxb-crs-computation.patch [bz#1323976] +- kvm-hw-apci-handle-64-bit-MMIO-regions-correctly.patch [bz#1323976] +- kvm-target-i386-Move-TCG-initialization-check-to-tcg_x86.patch [bz#1087672] +- kvm-target-i386-Move-TCG-initialization-to-realize-time.patch [bz#1087672] +- kvm-target-i386-Call-cpu_exec_init-on-realize.patch [bz#1087672] +- kvm-tests-acpi-report-names-of-expected-files-in-verbose.patch [bz#1087672] +- kvm-acpi-add-aml_debug.patch [bz#1087672] +- kvm-acpi-add-aml_refof.patch [bz#1087672] +- kvm-pc-acpi-remove-AML-for-empty-not-used-GPE-handlers.patch [bz#1087672] +- kvm-pc-acpi-consolidate-CPU-hotplug-AML.patch [bz#1087672] +- kvm-pc-acpi-consolidate-GPE._E02-with-the-rest-of-CPU-ho.patch [bz#1087672] +- kvm-pc-acpi-cpu-hotplug-make-AML-CPU_foo-defines-local-t.patch [bz#1087672] +- kvm-pc-acpi-mark-current-CPU-hotplug-functions-as-legacy.patch [bz#1087672] +- kvm-pc-acpi-consolidate-legacy-CPU-hotplug-in-one-file.patch [bz#1087672] +- kvm-pc-acpi-simplify-build_legacy_cpu_hotplug_aml-signat.patch [bz#1087672] +- kvm-pc-acpi-cpuhp-legacy-switch-ProcessorID-to-possible_.patch [bz#1087672] +- kvm-acpi-extend-ACPI-interface-to-provide-send_event-hoo.patch [bz#1087672] +- kvm-pc-use-AcpiDeviceIfClass.send_event-to-issue-GPE-eve.patch [bz#1087672] +- kvm-target-i386-Remove-xlevel-hv-spinlocks-option-fixups.patch [bz#1087672] +- kvm-target-i386-Move-features-logic-that-requires-CPUSta.patch [bz#1087672] +- kvm-target-i386-Remove-assert-kvm_enabled-from-host_x86_.patch [bz#1087672] +- kvm-target-i386-Move-xcc-kvm_required-check-to-realize-t.patch [bz#1087672] +- kvm-target-i386-Use-cpu_generic_init-in-cpu_x86_init.patch [bz#1087672] +- kvm-target-i386-Consolidate-calls-of-object_property_par.patch [bz#1087672] +- kvm-docs-update-ACPI-CPU-hotplug-spec-with-new-protocol.patch [bz#1087672] +- kvm-pc-piix4-ich9-add-cpu-hotplug-legacy-property.patch [bz#1087672] +- kvm-acpi-cpuhp-add-CPU-devices-AML-with-_STA-method.patch [bz#1087672] +- kvm-pc-acpi-introduce-AcpiDeviceIfClass.madt_cpu-hook.patch [bz#1087672] +- kvm-acpi-cpuhp-implement-hot-add-parts-of-CPU-hotplug-in.patch [bz#1087672] +- kvm-acpi-cpuhp-implement-hot-remove-parts-of-CPU-hotplug.patch [bz#1087672] +- kvm-acpi-cpuhp-add-cpu._OST-handling.patch [bz#1087672] +- kvm-pc-use-new-CPU-hotplug-interface-since-2.7-machine-t.patch [bz#1087672] +- kvm-pc-acpi-drop-intermediate-PCMachineState.node_cpu.patch [bz#1087672] +- kvm-qmp-fix-spapr-example-of-query-hotpluggable-cpus.patch [bz#1087672] +- kvm-qdev-Don-t-stop-applying-globals-on-first-error.patch [bz#1087672] +- kvm-qdev-Eliminate-qemu_add_globals-function.patch [bz#1087672] +- kvm-qdev-Use-GList-for-global-properties.patch [bz#1087672] +- kvm-qdev-GlobalProperty.errp-field.patch [bz#1087672] +- kvm-vl-Simplify-global-property-registration.patch [bz#1087672] +- kvm-machine-add-properties-to-compat_props-incrementaly.patch [bz#1087672] +- kvm-machine-Add-machine_register_compat_props-function.patch [bz#1087672] +- kvm-vl-Set-errp-to-error_abort-on-machine-compat_props.patch [bz#1087672] +- kvm-target-sparc-Use-sparc_cpu_parse_features-directly.patch [bz#1087672] +- kvm-target-i386-Avoid-using-locals-outside-their-scope.patch [bz#1087672] +- kvm-cpu-Use-CPUClass-parse_features-as-convertor-to-glob.patch [bz#1087672] +- kvm-arm-virt-Parse-cpu_model-only-once.patch [bz#1087672] +- kvm-cpu-make-cpu-qom.h-only-include-able-from-cpu.h.patch [bz#1087672] +- kvm-target-i386-make-cpu-qom.h-not-target-specific.patch [bz#1087672] +- kvm-target-Don-t-redefine-cpu_exec.patch [bz#1087672] +- kvm-pc-Parse-CPU-features-only-once.patch [bz#1087672] +- kvm-target-i386-Use-uint32_t-for-X86CPU.apic_id.patch [bz#1087672] +- kvm-pc-Add-x86_topo_ids_from_apicid.patch [bz#1087672] +- kvm-pc-Extract-CPU-lookup-into-a-separate-function.patch [bz#1087672] +- kvm-pc-cpu-Consolidate-apic-id-validity-checks-in-pc_cpu.patch [bz#1087672] +- kvm-target-i386-Replace-custom-apic-id-setter-getter-wit.patch [bz#1087672] +- kvm-target-i386-Add-socket-core-thread-properties-to-X86.patch [bz#1087672] +- kvm-target-i386-cpu-Do-not-ignore-error-and-fix-apic-par.patch [bz#1087672] +- kvm-target-i386-Fix-apic-object-leak-when-CPU-is-deleted.patch [bz#1087672] +- kvm-pc-Set-APIC-ID-based-on-socket-core-thread-ids-if-it.patch [bz#1087672] +- kvm-pc-Delay-setting-number-of-boot-CPUs-to-machine_done.patch [bz#1087672] +- kvm-pc-Register-created-initial-and-hotpluged-CPUs-in-on.patch [bz#1087672] +- kvm-pc-Forbid-BSP-removal.patch [bz#1087672] +- kvm-pc-Enforce-adding-CPUs-contiguously-and-removing-the.patch [bz#1087672] +- kvm-pc-cpu-Allow-device_add-to-be-used-with-x86-cpu.patch [bz#1087672] +- kvm-pc-Implement-query-hotpluggable-cpus-callback.patch [bz#1087672] +- kvm-apic-move-MAX_APICS-check-to-apic-class.patch [bz#1087672] +- kvm-apic-Drop-APICCommonState.idx-and-use-APIC-ID-as-ind.patch [bz#1087672] +- kvm-apic-kvm-apic-Fix-crash-due-to-access-to-freed-memor.patch [bz#1087672] +- kvm-apic-Add-unrealize-callbacks.patch [bz#1087672] +- kvm-apic-Use-apic_id-as-apic-s-migration-instance_id.patch [bz#1087672] +- kvm-target-i386-Add-x86_cpu_unrealizefn.patch [bz#1087672] +- kvm-pc-Make-device_del-CPU-work-for-x86-CPUs.patch [bz#1087672] +- kvm-exec-Reduce-CONFIG_USER_ONLY-ifdeffenery.patch [bz#1087672] +- kvm-exec-Don-t-use-cpu_index-to-detect-if-cpu_exec_init-.patch [bz#1087672] +- kvm-exec-Set-cpu_index-only-if-it-s-not-been-explictly-s.patch [bz#1087672] +- kvm-qdev-Fix-object-reference-leak-in-case-device.realiz.patch [bz#1087672] +- kvm-pc-Init-CPUState-cpu_index-with-index-in-possible_cp.patch [bz#1087672] +- kvm-Revert-pc-Enforce-adding-CPUs-contiguously-and-remov.patch [bz#1087672] +- kvm-qdev-ignore-GlobalProperty.errp-for-hotplugged-devic.patch [bz#1087672] +- kvm-vl-exit-if-a-bad-property-value-is-passed-to-global.patch [bz#1087672] +- kvm-apic-fix-broken-migration-for-kvm-apic.patch [bz#1087672] +- kvm-RHEL-only-hw-char-pl011-fix-SBSA-reset.patch [bz#1266048] +- kvm-migration-regain-control-of-images-when-migration-fa.patch [bz#1361539] +- kvm-migration-Promote-improved-autoconverge-commands-out.patch [bz#1358141] +- kvm-spapr-Ensure-CPU-cores-are-added-contiguously-and-re.patch [bz#1361443] +- kvm-spapr-disintricate-core-id-from-DT-semantics.patch [bz#1361443] +- kvm-spapr-init-CPUState-cpu_index-with-index-relative-to.patch [bz#1361443] +- kvm-Revert-spapr-Ensure-CPU-cores-are-added-contiguously.patch [bz#1361443] +- kvm-spapr-Prevent-boot-CPU-core-removal.patch [bz#1361443] +- kvm-virtio-vga-propagate-on-gpu-realized-error.patch [bz#1360664] +- kvm-hw-virtio-pci-fix-virtio-behaviour.patch [bz#1360664] +- kvm-q35-disable-s3-s4-by-default.patch [bz#1357202] +- kvm-pcie-fix-link-active-status-bit-migration.patch [bz#1352860] +- kvm-pc-rhel-7.2-pcie-fix-link-active-status-bit-migratio.patch [bz#1352860] +- kvm-add-e1000e-ipxe-rom-symlink.patch [bz#1343092] +- kvm-e1000e-add-boot-rom.patch [bz#1343092] +- Resolves: bz#1087672 + ([Fujitsu 7.2 FEAT]: qemu vcpu hot-remove support) +- Resolves: bz#1266048 + (login prompt does not work inside KVM guest when keys are pressed while the kernel is booting) +- Resolves: bz#1323976 + (PCI: Add 64-bit MMIO support to PXB devices) +- Resolves: bz#1343092 + (RFE: Integrate e1000e implementation in downstream QEMU) +- Resolves: bz#1352860 + (Migration is failed from host RHEL7.2.z to host RHEL7.3 with "-M pc-i440fx-rhel7.0.0 -device nec-usb-xhci") +- Resolves: bz#1357202 + ([Q35] S3 should be disabled by default for the pc-q35-rhel7.3.0 machine type) +- Resolves: bz#1358141 + (Removal of the "x-" prefix for dynamic cpu throttling) +- Resolves: bz#1360664 + ([virtio] Update default virtio-1 behavior for virtio devices) +- Resolves: bz#1361443 + (ppc64le: Introduce stable cpu_index for cpu hotplugging) +- Resolves: bz#1361539 + (block/io.c:1342: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed on failed migrate) + +* Tue Aug 02 2016 Miroslav Rezanina - rhev-2.6.0-18.el7 +- kvm-pci-fix-unaligned-access-in-pci_xxx_quad.patch [bz#1343092] +- kvm-msix-make-msix_clr_pending-visible-for-clients.patch [bz#1343092] +- kvm-pci-Introduce-define-for-PM-capability-version-1.1.patch [bz#1343092] +- kvm-pcie-Add-support-for-PCIe-CAP-v1.patch [bz#1343092] +- kvm-pcie-Introduce-function-for-DSN-capability-creation.patch [bz#1343092] +- kvm-vmxnet3-Use-generic-function-for-DSN-capability-defi.patch [bz#1343092] +- kvm-net-Introduce-Toeplitz-hash-calculator.patch [bz#1343092] +- kvm-net-Add-macros-for-MAC-address-tracing.patch [bz#1343092] +- kvm-vmxnet3-Use-common-MAC-address-tracing-macros.patch [bz#1343092] +- kvm-net_pkt-Name-vmxnet3-packet-abstractions-more-generi.patch [bz#1343092] +- kvm-rtl8139-Move-more-TCP-definitions-to-common-header.patch [bz#1343092] +- kvm-net_pkt-Extend-packet-abstraction-as-required-by-e10.patch [bz#1343092] +- kvm-vmxnet3-Use-pci_dma_-API-instead-of-cpu_physical_mem.patch [bz#1343092] +- kvm-e1000_regs-Add-definitions-for-Intel-82574-specific-.patch [bz#1343092] +- kvm-e1000-Move-out-code-that-will-be-reused-in-e1000e.patch [bz#1343092] +- kvm-net-Introduce-e1000e-device-emulation.patch [bz#1343092] +- kvm-e1000e-Fix-build-with-gcc-4.6.3-and-ust-tracing.patch [bz#1343092] +- kvm-pci-fix-pci_requester_id.patch [bz#1350196] +- kvm-hw-pci-delay-bus_master_enable_region-initialization.patch [bz#1350196] +- kvm-q35-allow-dynamic-sysbus.patch [bz#1350196] +- kvm-q35-rhel-allow-dynamic-sysbus.patch [bz#1350196] +- kvm-hw-iommu-enable-iommu-with-device.patch [bz#1350196] +- kvm-machine-remove-iommu-property.patch [bz#1350196] +- kvm-rhel-Revert-unwanted-inconsequential-changes-to-ivsh.patch [bz#1333318] +- kvm-rhel-Disable-ivshmem-plain-migration-ivshmem-doorbel.patch [bz#1333318] +- kvm-nvdimm-fix-memory-leak-in-error-code-path.patch [bz#1361205] +- kvm-i8257-Set-no-user-flag.patch [bz#1337457] +- kvm-bitops-Add-MAKE_64BIT_MASK-macro.patch [bz#1339196] +- kvm-target-i386-Provide-TCG_PHYS_ADDR_BITS.patch [bz#1339196] +- kvm-target-i386-Allow-physical-address-bits-to-be-set.patch [bz#1339196] +- kvm-target-i386-Mask-mtrr-mask-based-on-CPU-physical-add.patch [bz#1339196] +- kvm-target-i386-Fill-high-bits-of-mtrr-mask.patch [bz#1339196] +- kvm-target-i386-Set-physical-address-bits-based-on-host.patch [bz#1339196] +- kvm-target-i386-Enable-host-phys-bits-on-RHEL.patch [bz#1339196] +- kvm-pc-Fix-rhel6.3.0-compat_props-setting.patch [bz#1362264] +- Resolves: bz#1333318 + (ivshmem-plain support in RHEL 7.3) +- Resolves: bz#1337457 + (enable i8257 device) +- Resolves: bz#1339196 + (qemu-kvm (on target host) killed by SIGABRT when migrating a guest from AMD host to Intel host.) +- Resolves: bz#1343092 + (RFE: Integrate e1000e implementation in downstream QEMU) +- Resolves: bz#1350196 + (Enable IOMMU device with -device intel-iommu) +- Resolves: bz#1361205 + (nvdimm: fix memory leak in error code path) +- Resolves: bz#1362264 + (rhel6.3.0 machine-type using wrong compat_props list) + +* Fri Jul 29 2016 Miroslav Rezanina - rhev-2.6.0-17.el7 +- kvm-Disable-mptsas1068-device.patch [bz#1333282] +- kvm-Disable-sd-card.patch [bz#1333282] +- kvm-Disable-rocker-device.patch [bz#1333282] +- kvm-Disable-new-ipmi-devices.patch [bz#1333282] +- kvm-Disable-hyperv-testdev.patch [bz#1333282] +- kvm-Disable-allwiner_ahci-device.patch [bz#1333282] +- kvm-Disable-igd-passthrough-i440FX.patch [bz#1333282] +- kvm-Disable-vfio-platform-device.patch [bz#1333282] +- kvm-tap-vhost-busy-polling-support.patch [bz#1345715 bz#1353791] +- kvm-vl-change-runstate-only-if-new-state-is-different-fr.patch [bz#1355982] +- kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch [bz#1359733] +- kvm-migration-set-state-to-post-migrate-on-failure.patch [bz#1355683] +- kvm-block-drop-support-for-using-qcow-2-encryption-with-.patch [bz#1336659] +- kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch [bz#1360612] +- kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch [bz#1360612] +- kvm-Add-dump-guest-memory.py-to-all-archs.patch [bz#1360225] +- Resolves: bz#1333282 + (Disable new devices in QEMU 2.6) +- Resolves: bz#1336659 + (Core dump when re-launch guest with encrypted block device) +- Resolves: bz#1345715 + (Busy polling support for vhost net in qemu) +- Resolves: bz#1353791 + (Busy polling support for vhost) +- Resolves: bz#1355683 + (qemu core dump when do postcopy migration again after canceling a migration in postcopy phase) +- Resolves: bz#1355982 + (qemu will abort after type two"system_reset" after the guest poweroff) +- Resolves: bz#1359733 + (CVE-2016-5403 qemu-kvm-rhev: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.3]) +- Resolves: bz#1360225 + (Can't extract guest memory dump from qemu core) +- Resolves: bz#1360612 + (Memory leak on incomplete JSON parse) + +* Tue Jul 26 2016 Miroslav Rezanina - rhev-2.6.0-16.el7 +- kvm-exec-Remove-cpu-from-cpus-list-during-cpu_exec_exit.patch [bz#1172917] +- kvm-exec-Do-vmstate-unregistration-from-cpu_exec_exit.patch [bz#1172917] +- kvm-cpu-Reclaim-vCPU-objects.patch [bz#1172917] +- kvm-cpu-Add-a-sync-version-of-cpu_remove.patch [bz#1172917] +- kvm-qdev-hotplug-Introduce-HotplugHandler.pre_plug-callb.patch [bz#1172917] +- kvm-cpu-Abstract-CPU-core-type.patch [bz#1172917] +- kvm-xics-xics_kvm-Handle-CPU-unplug-correctly.patch [bz#1172917] +- kvm-spapr_drc-Prevent-detach-racing-against-attach-for-C.patch [bz#1172917] +- kvm-qom-API-to-get-instance_size-of-a-type.patch [bz#1172917] +- kvm-spapr-Abstract-CPU-core-device-and-type-specific-cor.patch [bz#1172917] +- kvm-spapr-Move-spapr_cpu_init-to-spapr_cpu_core.c.patch [bz#1172917] +- kvm-spapr-convert-boot-CPUs-into-CPU-core-devices.patch [bz#1172917] +- kvm-spapr-CPU-hotplug-support.patch [bz#1172917] +- kvm-spapr-CPU-hot-unplug-support.patch [bz#1172917] +- kvm-QMP-Add-query-hotpluggable-cpus.patch [bz#1172917] +- kvm-hmp-Add-info-hotpluggable-cpus-HMP-command.patch [bz#1172917] +- kvm-spapr-implement-query-hotpluggable-cpus-callback.patch [bz#1172917] +- kvm-qapi-Report-support-for-device-cpu-hotplug-in-query-.patch [bz#1172917] +- kvm-qapi-keep-names-in-CpuInstanceProperties-in-sync-wit.patch [bz#1172917] +- kvm-spapr-fix-write-past-end-of-array-error-in-cpu-core-.patch [bz#1172917] +- kvm-spapr-Restore-support-for-older-PowerPC-CPU-cores.patch [bz#1172917] +- kvm-spapr-Restore-support-for-970MP-and-POWER8NVL-CPU-co.patch [bz#1172917] +- kvm-spapr-drop-reference-on-child-object-during-core-rea.patch [bz#1172917] +- kvm-spapr-do-proper-error-propagation-in-spapr_cpu_core_.patch [bz#1172917] +- kvm-spapr-drop-duplicate-variable-in-spapr_core_release.patch [bz#1172917] +- kvm-spapr-Ensure-thread0-of-CPU-core-is-always-realized-.patch [bz#1172917] +- kvm-spapr-fix-core-unplug-crash.patch [bz#1172917] +- kvm-usbredir-add-streams-property.patch [bz#1353180] +- kvm-usbredir-turn-off-streams-for-rhel7.2-older.patch [bz#1353180] +- kvm-net-fix-qemu_announce_self-not-emitting-packets.patch [bz#1343433] +- kvm-Fix-crash-bug-in-rebase-of__com.redhat_drive_add.patch [bz#1352865] +- kvm-ppc-Yet-another-fix-for-the-huge-page-support-detect.patch [bz#1347498] +- kvm-ppc-Huge-page-detection-mechanism-fixes-Episode-III.patch [bz#1347498] +- kvm-hw-ppc-spapr-Make-sure-to-close-the-htab_fd-when-mig.patch [bz#1354341] +- Resolves: bz#1172917 + (add support for CPU hotplugging (qemu-kvm-rhev)) +- Resolves: bz#1343433 + (migration: announce_self fix) +- Resolves: bz#1347498 + ([ppc64le] Guest can't boot up with hugepage memdev) +- Resolves: bz#1352865 + (Boot guest with two virtio-scsi-pci devices and spice, QEMU core dump after executing '(qemu)__com.redhat_drive_add') +- Resolves: bz#1353180 + (7.3->7.2 migration: qemu-kvm: usbredirparser: error unserialize caps mismatch) +- Resolves: bz#1354341 + (guest hang after cancel migration then migrate again) + +* Fri Jul 22 2016 Miroslav Rezanina - rhev-2.6.0-15.el7 +- kvm-spapr_pci-Use-correct-DMA-LIOBN-when-composing-the-d.patch [bz#1213667] +- kvm-spapr_iommu-Finish-renaming-vfio_accel-to-need_vfio.patch [bz#1213667] +- kvm-spapr_iommu-Move-table-allocation-to-helpers.patch [bz#1213667] +- kvm-vmstate-Define-VARRAY-with-VMS_ALLOC.patch [bz#1213667] +- kvm-spapr_iommu-Introduce-enabled-state-for-TCE-table.patch [bz#1213667] +- kvm-spapr_iommu-Migrate-full-state.patch [bz#1213667] +- kvm-spapr_iommu-Add-root-memory-region.patch [bz#1213667] +- kvm-spapr_pci-Reset-DMA-config-on-PHB-reset.patch [bz#1213667] +- kvm-spapr_pci-Add-and-export-DMA-resetting-helper.patch [bz#1213667] +- kvm-memory-Add-reporting-of-supported-page-sizes.patch [bz#1213667] +- kvm-spapr-ensure-device-trees-are-always-associated-with.patch [bz#1213667] +- kvm-spapr_iommu-Realloc-guest-visible-TCE-table-when-sta.patch [bz#1213667] +- kvm-vfio-spapr-Add-DMA-memory-preregistering-SPAPR-IOMMU.patch [bz#1213667] +- kvm-vfio-Add-host-side-DMA-window-capabilities.patch [bz#1213667] +- kvm-vfio-spapr-Create-DMA-window-dynamically-SPAPR-IOMMU.patch [bz#1213667] +- kvm-spapr_pci-spapr_pci_vfio-Support-Dynamic-DMA-Windows.patch [bz#1213667] +- kvm-qemu-sockets-use-qapi_free_SocketAddress-in-cleanup.patch [bz#1354090] +- kvm-tap-use-an-exit-notifier-to-call-down_script.patch [bz#1354090] +- kvm-slirp-use-exit-notifier-for-slirp_smb_cleanup.patch [bz#1354090] +- kvm-net-do-not-use-atexit-for-cleanup.patch [bz#1354090] +- kvm-virtio-mmio-format-transport-base-address-in-BusClas.patch [bz#1356815] +- kvm-vfio-pci-Hide-ARI-capability.patch [bz#1356376] +- kvm-qxl-factor-out-qxl_get_check_slot_offset.patch [bz#1235732] +- kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch [bz#1235732] +- kvm-qxl-fix-surface-migration.patch [bz#1235732] +- kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch [bz#1235732] +- kvm-Add-install-dependency-required-for-usb-streams.patch [bz#1354443] +- Resolves: bz#1213667 + (Dynamic DMA Windows for VFIO on Power (qemu component)) +- Resolves: bz#1235732 + (spice-gtk shows outdated screen state after migration [qemu-kvm-rhev]) +- Resolves: bz#1354090 + (Boot guest with vhostuser server mode, QEMU prompt 'Segmentation fault' after executing '(qemu)system_powerdown') +- Resolves: bz#1354443 + (/usr/libexec/qemu-kvm: undefined symbol: libusb_free_ss_endpoint_companion_descriptor) +- Resolves: bz#1356376 + ([Q35] Nic which passthrough from host didn't be found in guest when enable multifunction) +- Resolves: bz#1356815 + (AArch64: backport virtio-mmio dev pathname fix) + +* Tue Jul 19 2016 Miroslav Rezanina - rhev-2.6.0-14.el7 +- kvm-add-vgabios-virtio.bin-symlink.patch [bz#1347402] +- kvm-usb-enable-streams-support.patch [bz#1033733] +- kvm-hw-arm-virt-kill-7.2-machine-type.patch [bz#1356814] +- kvm-blockdev-Fix-regression-with-the-default-naming-of-t.patch [bz#1353801] +- kvm-qemu-iotests-Test-naming-of-throttling-groups.patch [bz#1353801] +- kvm-target-i386-Show-host-and-VM-TSC-frequencies-on-mism.patch [bz#1351442] +- Resolves: bz#1033733 + (RFE: add support for USB-3 bulk streams - qemu-kvm) +- Resolves: bz#1347402 + (vgabios-virtio.bin should be symlinked in qemu-kvm-rhev) +- Resolves: bz#1351442 + ("TSC frequency mismatch" warning message after migration) +- Resolves: bz#1353801 + (The default io throttling group name is null, which makes all throttled disks with a default group name in the same group) +- Resolves: bz#1356814 + (AArch64: remove non-released 7.2 machine type) + +* Tue Jul 12 2016 Miroslav Rezanina - rhev-2.6.0-13.el7 +- kvm-block-gluster-add-support-for-selecting-debug-loggin.patch [bz#1320714] +- kvm-Revert-static-checker-e1000-82540em-got-aliased-to-e.patch [bz#1353070] +- kvm-Revert-e1000-use-alias-for-default-model.patch [bz#1353070] +- kvm-7.x-compat-e1000-82540em.patch [bz#1353070] +- kvm-target-i386-add-Skylake-Client-cpu-model.patch [bz#1327589] +- kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch [bz#1353816] +- kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch [bz#1353816] +- kvm-scsi-Advertise-limits-by-blocksize-not-512.patch [bz#1353816] +- kvm-mirror-clarify-mirror_do_read-return-code.patch [bz#1336705] +- kvm-mirror-limit-niov-to-IOV_MAX-elements-again.patch [bz#1336705] +- kvm-iotests-add-small-granularity-mirror-test.patch [bz#1336705] +- Resolves: bz#1320714 + ([RFE] Allow the libgfapi logging level to be controlled.) +- Resolves: bz#1327589 + (Add Skylake CPU model) +- Resolves: bz#1336705 + (Drive mirror with option granularity fail) +- Resolves: bz#1353070 + (Migration is failed from host RHEL7.2.z to host RHEL7.3 with "-M rhel6.6.0 -device e1000-82540em") +- Resolves: bz#1353816 + (expose host BLKSECTGET limit in scsi-block (qemu-kvm-rhev)) + +* Fri Jul 08 2016 Miroslav Rezanina - rhev-2.6.0-12.el7 +- kvm-Fix-crash-with-__com.redhat_drive_del.patch [bz#1341531] +- kvm-hw-arm-virt-fix-limit-of-64-bit-ACPI-ECAM-PCI-MMIO-r.patch [bz#1349337] +- kvm-Increase-locked-memory-limit-for-all-users-not-just-.patch [bz#1350735] +- kvm-target-i386-Remove-SSE4a-from-qemu64-CPU-model.patch [bz#1318386 bz#1321139 bz#1321139] +- kvm-target-i386-Remove-ABM-from-qemu64-CPU-model.patch [bz#1318386 bz#1321139 bz#1321139] +- kvm-pc-Recover-PC_RHEL7_1_COMPAT-from-RHEL-7.2-code.patch [bz#1318386 bz#1318386 bz#1321139] +- kvm-pc-Include-missing-PC_COMPAT_2_3-entries-in-PC_RHEL7.patch [bz#1318386 bz#1318386 bz#1321139] +- kvm-vhost-user-disable-chardev-handlers-on-close.patch [bz#1347077] +- kvm-char-clean-up-remaining-chardevs-when-leaving.patch [bz#1347077] +- kvm-socket-add-listen-feature.patch [bz#1347077] +- kvm-socket-unlink-unix-socket-on-remove.patch [bz#1347077] +- kvm-char-do-not-use-atexit-cleanup-handler.patch [bz#1347077] +- kvm-vfio-add-pcie-extended-capability-support.patch [bz#1346688] +- kvm-vfio-pci-Hide-SR-IOV-capability.patch [bz#1346688] +- kvm-memory-Add-MemoryRegionIOMMUOps.notify_started-stopp.patch [bz#1346920] +- kvm-intel_iommu-Throw-hw_error-on-notify_started.patch [bz#1346920] +- Resolves: bz#1318386 + (pc-rhel7.2.0 machine type definition needs some fixes) +- Resolves: bz#1321139 + (qemu-kvm-rhev prints warnings in the default CPU+machine-type configuration.) +- Resolves: bz#1341531 + (qemu gets SIGSEGV when hot-plug a scsi hostdev device with duplicate target address) +- Resolves: bz#1346688 + ([Q35] vfio read-only SR-IOV capability confuses OVMF) +- Resolves: bz#1346920 + (vIOMMU: prevent unsupported configurations with vfio) +- Resolves: bz#1347077 + (vhost-user: A socket file is not deleted after VM's port is detached.) +- Resolves: bz#1349337 + (hw/arm/virt: fix limit of 64-bit ACPI/ECAM PCI MMIO range) +- Resolves: bz#1350735 + (memory locking limit for regular users is too low to launch guests through libvirt) + +* Fri Jul 01 2016 Miroslav Rezanina - rhev-2.6.0-11.el7 +- kvm-Postcopy-Avoid-0-length-discards.patch [bz#1347256] +- kvm-Migration-Split-out-ram-part-of-qmp_query_migrate.patch [bz#1347256] +- kvm-Postcopy-Add-stats-on-page-requests.patch [bz#1347256] +- kvm-test-Postcopy.patch [bz#1347256] +- kvm-tests-fix-libqtest-socket-timeouts.patch [bz#1347256] +- kvm-Postcopy-Check-for-support-when-setting-the-capabili.patch [bz#1347256] +- kvm-rbd-change-error_setg-to-error_setg_errno.patch [bz#1329641] +- kvm-ppc-Disable-huge-page-support-if-it-is-not-available.patch [bz#1347498] +- kvm-acpi-do-not-use-TARGET_PAGE_SIZE.patch [bz#1270345] +- kvm-acpi-convert-linker-from-GArray-to-BIOSLinker-struct.patch [bz#1270345] +- kvm-acpi-simplify-bios_linker-API-by-removing-redundant-.patch [bz#1270345] +- kvm-acpi-cleanup-bios_linker_loader_cleanup.patch [bz#1270345] +- kvm-tpm-apci-cleanup-TCPA-table-initialization.patch [bz#1270345] +- kvm-acpi-make-bios_linker_loader_add_pointer-API-offset-.patch [bz#1270345] +- kvm-acpi-make-bios_linker_loader_add_checksum-API-offset.patch [bz#1270345] +- kvm-pc-dimm-get-memory-region-from-get_memory_region.patch [bz#1270345] +- kvm-pc-dimm-introduce-realize-callback.patch [bz#1270345] +- kvm-pc-dimm-introduce-get_vmstate_memory_region-callback.patch [bz#1270345] +- kvm-nvdimm-support-nvdimm-label.patch [bz#1270345] +- kvm-acpi-add-aml_object_type.patch [bz#1270345] +- kvm-acpi-add-aml_call5.patch [bz#1270345] +- kvm-nvdimm-acpi-set-HDLE-properly.patch [bz#1270345] +- kvm-nvdimm-acpi-save-arg3-of-_DSM-method.patch [bz#1270345] +- kvm-nvdimm-acpi-check-UUID.patch [bz#1270345] +- kvm-nvdimm-acpi-abstract-the-operations-for-root-nvdimm-.patch [bz#1270345] +- kvm-nvdimm-acpi-check-revision.patch [bz#1270345] +- kvm-nvdimm-acpi-support-Get-Namespace-Label-Size-functio.patch [bz#1270345] +- kvm-nvdimm-acpi-support-Get-Namespace-Label-Data-functio.patch [bz#1270345] +- kvm-nvdimm-acpi-support-Set-Namespace-Label-Data-functio.patch [bz#1270345] +- kvm-docs-add-NVDIMM-ACPI-documentation.patch [bz#1270345] +- kvm-Fix-qemu-kvm-does-not-quit-when-booting-guest-w-241-.patch [bz#1126666] +- kvm-Adjust-locked-memory-limits-to-allow-unprivileged-VM.patch [bz#1350735] +- kvm-dma-helpers-dma_blk_io-cancel-support.patch [bz#1346237] +- Resolves: bz#1126666 + (qemu-kvm does not quit when booting guest w/ 161 vcpus and "-no-kvm") +- Resolves: bz#1270345 + ([Intel 7.3 FEAT] Virtualization support for NVDIMM - qemu support) +- Resolves: bz#1329641 + ([RFE]Ceph/RBD block driver for qemu-kvm : change error_setg() to error_setg_errno()) +- Resolves: bz#1346237 + (win 10.x86_64 guest coredump when execute avocado test case: win_virtio_update.install_driver) +- Resolves: bz#1347256 + (Backport 2.7 postcopy fix, test and stats) +- Resolves: bz#1347498 + ([ppc64le] Guest can't boot up with hugepage memdev) +- Resolves: bz#1350735 + (memory locking limit for regular users is too low to launch guests through libvirt) + +* Tue Jun 28 2016 Miroslav Rezanina - rhev-2.6.0-10.el7 +- kvm-block-clarify-error-message-for-qmp-eject.patch [bz#961589] +- kvm-blockdev-clean-up-error-handling-in-do_open_tray.patch [bz#961589] +- kvm-blockdev-clarify-error-on-attempt-to-open-locked-tra.patch [bz#961589] +- kvm-blockdev-backup-Use-bdrv_lookup_bs-on-target.patch [bz#1336310 bz#1339498] +- kvm-blockdev-backup-Don-t-move-target-AioContext-if-it-s.patch [bz#1336310 bz#1339498] +- kvm-virtio-blk-Remove-op-blocker-for-dataplane.patch [bz#1336310 bz#1339498] +- kvm-virtio-scsi-Remove-op-blocker-for-dataplane.patch [bz#1336310 bz#1339498] +- kvm-spec-add-a-sample-kvm.conf-to-enable-Nested-Virtuali.patch [bz#1290150] +- Resolves: bz#1290150 + (Include example kvm.conf with nested options commented out) +- Resolves: bz#1336310 + (virtio-scsi data-plane does not support block management QMP commands) +- Resolves: bz#1339498 + (Core dump when do 'block-job-complete' after 'drive-mirror') +- Resolves: bz#961589 + (rhel7 guest sometimes didnt unlock the cdrom when qemu-kvm trying to eject) + +* Thu Jun 23 2016 Miroslav Rezanina - rhev-2.6.0-9.el7 +- kvm-7.2-machine-type-compatibility.patch [bz#1344269] +- kvm-vhost-user-add-ability-to-know-vhost-user-backend-di.patch [bz#1322087] +- kvm-tests-vhost-user-bridge-add-client-mode.patch [bz#1322087] +- kvm-tests-vhost-user-bridge-workaround-stale-vring-base.patch [bz#1322087] +- kvm-qemu-char-add-qemu_chr_disconnect-to-close-a-fd-acce.patch [bz#1322087] +- kvm-vhost-user-disconnect-on-start-failure.patch [bz#1322087] +- kvm-vhost-net-do-not-crash-if-backend-is-not-present.patch [bz#1322087] +- kvm-vhost-net-save-restore-vhost-user-acked-features.patch [bz#1322087] +- kvm-vhost-net-save-restore-vring-enable-state.patch [bz#1322087] +- kvm-tests-append-i386-tests.patch [bz#1322087] +- kvm-test-start-vhost-user-reconnect-test.patch [bz#1322087] +- kvm-block-Prevent-sleeping-jobs-from-resuming-if-they-ha.patch [bz#1265179] +- kvm-blockjob-move-iostatus-reset-out-of-block_job_enter.patch [bz#1265179] +- kvm-blockjob-rename-block_job_is_paused.patch [bz#1265179] +- kvm-blockjob-add-pause-points.patch [bz#1265179] +- kvm-blockjob-add-block_job_get_aio_context.patch [bz#1265179] +- kvm-block-use-safe-iteration-over-AioContext-notifiers.patch [bz#1265179] +- kvm-blockjob-add-AioContext-attached-callback.patch [bz#1265179] +- kvm-mirror-follow-AioContext-change-gracefully.patch [bz#1265179] +- kvm-backup-follow-AioContext-change-gracefully.patch [bz#1265179] +- kvm-block-Fix-snapshot-on-with-aio-native.patch [bz#1336649] +- kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch [bz#1340930] +- kvm-block-fixed-BdrvTrackedRequest-filling-in-bdrv_co_di.patch [bz#1348763] +- kvm-block-fix-race-in-bdrv_co_discard-with-drive-mirror.patch [bz#1348763] +- kvm-block-process-before_write_notifiers-in-bdrv_co_disc.patch [bz#1348763] +- Resolves: bz#1265179 + (With dataplane, when migrate to remote NBD disk after drive-mirror, qemu core dump ( both src host and des host)) +- Resolves: bz#1322087 + (No recovery after vhost-user process restart) +- Resolves: bz#1336649 + ([RHEL.7.3] Guest will not boot up when specify aio=native and snapshot=on together) +- Resolves: bz#1340930 + (CVE-2016-5126 qemu-kvm-rhev: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.3]) +- Resolves: bz#1344269 + (Migration: Fixup machine types and HW_COMPAT (stage 2a)) +- Resolves: bz#1348763 + (Fix dirty marking with block discard requests) + +* Tue Jun 21 2016 Miroslav Rezanina - rhev-2.6.0-8.el7 +- kvm-Disable-Windows-enlightnements.patch [bz#1336517] +- kvm-ppc-spapr-Refactor-h_client_architecture_support-CPU.patch [bz#1341492] +- kvm-ppc-Split-pcr_mask-settings-into-supported-bits-and-.patch [bz#1341492] +- kvm-ppc-Provide-function-to-get-CPU-class-of-the-host-CP.patch [bz#1341492] +- kvm-ppc-Improve-PCR-bit-selection-in-ppc_set_compat.patch [bz#1341492] +- kvm-ppc-Add-PowerISA-2.07-compatibility-mode.patch [bz#1341492] +- kvm-machine-types-fix-pc_machine_-_options-chain.patch [bz#1344320] +- kvm-Fix-rhel6-rom-file.patch [bz#1344320] +- kvm-fix-vga-type-for-older-machines.patch [bz#1344320] +- kvm-Revert-aio_notify-force-main-loop-wakeup-with-SIGIO-.patch [bz#1188656] +- kvm-Make-avx2-configure-test-work-with-O2.patch [bz#1323294] +- kvm-avx2-configure-Use-primitives-in-test.patch [bz#1323294] +- kvm-vfio-Fix-broken-EEH.patch [bz#1346627] +- Resolves: bz#1188656 + (lost block IO completion notification (for virtio-scsi disk) hangs main loop) +- Resolves: bz#1323294 + (AVX-2 migration optimisation) +- Resolves: bz#1336517 + (Disable hv-vpindex, hv-runtime, hv-reset, hv-synic & hv-stimer enlightenment for Windows) +- Resolves: bz#1341492 + (QEMU on POWER does not support the PowerISA 2.07 compatibility mode) +- Resolves: bz#1344320 + (migration: fix pc_i440fx_*_options chaining) +- Resolves: bz#1346627 + (qemu discards EEH ioctl results) + +* Thu Jun 16 2016 Miroslav Rezanina - rhev-2.6.0-7.el7 +- kvm-pc-allow-raising-low-memory-via-max-ram-below-4g-opt.patch [bz#1176144] +- kvm-vga-add-sr_vbe-register-set.patch [bz#1331415 bz#1346976] +- Resolves: bz#1176144 + ([Nokia RHEL 7.3 Feature]: 32-bit operating systems get very little memory space with new Qemu's) +- Resolves: bz#1331415 + (CVE-2016-3710 qemu-kvm-rhev: qemu: incorrect banked access bounds checking in vga module [rhel-7.3]) +- Resolves: bz#1346976 + (Regression from CVE-2016-3712: windows installer fails to start) +- Resolves: bz#1339467 + (User can not create windows 7 virtual machine in rhevm3.6.5.) + +* Wed Jun 15 2016 Miroslav Rezanina - rhev-2.6.0-6.el7 +- kvm-throttle-refuse-iops-size-without-iops-total-read-wr.patch [bz#1342330] +- kvm-scsi-mark-TYPE_SCSI_DISK_BASE-as-abstract.patch [bz#1338043] +- kvm-scsi-disk-add-missing-break.patch [bz#1338043] +- kvm-Disable-spapr-rng.patch [bz#1343891] +- kvm-spec-Update-rules-before-triggering-for-kvm-device.patch [bz#1338755] +- kvm-spec-Do-not-package-ivshmem-server-and-ivshmem-clien.patch [bz#1320476] +- Resolves: bz#1320476 + (Failed to upgrade qemu-kvm-tools-rhev from 2.3.0 to 2.5.0) +- Resolves: bz#1338043 + (scsi-block fix - receive the right SCSI status on reads and writes) +- Resolves: bz#1338755 + (qemu-kvm-rhev doesn't reload udev rules before triggering for kvm device) +- Resolves: bz#1342330 + (There is no error prompt when set the io throttling parameters iops_size without iops) +- Resolves: bz#1343891 + (Disable spapr-rng device in downstream qemu 2.6) + +* Mon Jun 06 2016 Miroslav Rezanina - rhev-2.6.0-5.el7 +- kvm-spapr-update-RHEL-7.2-machine-type.patch [bz#1316303] +- kvm-migration-fix-HW_COMPAT_RHEL7_2.patch [bz#1316303] +- kvm-target-i386-add-a-generic-x86-nmi-handler.patch [bz#1335720] +- kvm-nmi-remove-x86-specific-nmi-handling.patch [bz#1335720] +- kvm-cpus-call-the-core-nmi-injection-function.patch [bz#1335720] +- kvm-spec-link-sgabios.bin-only-for-x86_64.patch [bz#1337917] +- kvm-Add-PCIe-bridge-devices-for-AArch64.patch [bz#1326420] +- kvm-Remove-unsupported-VFIO-devices-from-QEMU.patch [bz#1326420] +- kvm-hw-net-spapr_llan-Delay-flushing-of-the-RX-queue-whi.patch [bz#1210221] +- kvm-hw-net-spapr_llan-Provide-counter-with-dropped-rx-fr.patch [bz#1210221] +- kvm-iscsi-pass-SCSI-status-back-for-SG_IO.patch [bz#1338043] +- kvm-dma-helpers-change-BlockBackend-to-opaque-value-in-D.patch [bz#1338043] +- kvm-scsi-disk-introduce-a-common-base-class.patch [bz#1338043] +- kvm-scsi-disk-introduce-dma_readv-and-dma_writev.patch [bz#1338043] +- kvm-scsi-disk-add-need_fua_emulation-to-SCSIDiskClass.patch [bz#1338043] +- kvm-scsi-disk-introduce-scsi_disk_req_check_error.patch [bz#1338043] +- kvm-scsi-block-always-use-SG_IO.patch [bz#1338043] +- kvm-tools-kvm_stat-Powerpc-related-fixes.patch [bz#1337033] +- kvm-pc-New-default-pc-i440fx-rhel7.3.0-machine-type.patch [bz#1305121] +- kvm-7.3-mismerge-fix-Fix-ich9-intel-hda-compatibility.patch [bz#1342015] +- kvm-PC-migration-compat-Section-footers-global-state.patch [bz#1342015] +- kvm-fw_cfg-for-7.2-compatibility.patch [bz#1342015] +- kvm-pc-Create-new-pc-q35-rhel7.3.0-machine-type.patch [bz#1342015] +- kvm-q35-Remove-7.0-7.1-7.2-machine-types.patch [bz#1342015] +- Resolves: bz#1210221 + (Netperf UDP_STREAM Lost most of the packets on spapr-vlan device) +- Resolves: bz#1305121 + (rhel7.3.0 machine-types) +- Resolves: bz#1316303 + (Live migration of VMs from RHEL 7.2 <--> 7.3 with pseries-rhel7.2.0 machine type (qemu 2.6)) +- Resolves: bz#1326420 + (AArch64: clean and add devices to fully support aarch64 vm) +- Resolves: bz#1335720 + (watchdog action 'inject-nmi' takes no effect) +- Resolves: bz#1337033 + (kvm_stat AttributeError: 'ArchPPC' object has no attribute 'exit_reasons') +- Resolves: bz#1337917 + (qemu-kvm-rhev: Only ship /usr/share/qemu-kvm/sgabios.bin on x86) +- Resolves: bz#1338043 + (scsi-block fix - receive the right SCSI status on reads and writes) +- Resolves: bz#1342015 + (Migration: Fixup machine types and HW_COMPAT (stage 1b)) + +* Wed May 25 2016 Miroslav Rezanina - rhev-2.6.0-4.el7 +- kvm-pc-Use-right-HW_COMPAT_-macros-at-PC_RHEL7-compat-ma.patch [bz#1318386] +- kvm-compat-Add-missing-any_layout-in-HW_COMPAT_RHEL7_1.patch [bz#1318386] +- kvm-RHEL-Disable-unsupported-PowerPC-CPU-models.patch [bz#1317977] +- kvm-spec-Use-correct-upstream-QEMU-version.patch [bz#1335705] +- Resolves: bz#1317977 + (qemu-kvm-rhev supports a lot of CPU models) +- Resolves: bz#1318386 + (pc-rhel7.2.0 machine type definition needs some fixes) +- Resolves: bz#1335705 + ('QEMU 2.5.94 monitor' is used for qemu-kvm-rhev-2.6.0-1.el7.x86_64) + +* Mon May 23 2016 Miroslav Rezanina - rhev-2.6.0-3.el7 +- kvm-qmp-Report-drive_add-error-to-monitor.patch [bz#1337100] +- kvm-spec-Remove-dependency-to-ipxe-roms-qemu-for-aarch64.patch [bz#1337496] +- Resolves: bz#1337100 + (redhat_drive_add should report error to qmp if it fails to initialize) +- Resolves: bz#1337496 + (qemu-kvm-rhev should not depend on ipxe-roms-qemu on aarch64) + +* Tue May 17 2016 Miroslav Rezanina - rhev-2.6.0-2.el7 +- kvm-Fix-SLOF-dependency.patch [bz#1336296] +- Resolves: bz#1336296 + (failed dependencies on SLOF) + +* Thu May 12 2016 Miroslav Rezanina - rhev-2.6.0-1.el7 +- Rebase to QEMU 2.6.0 [bz#1289417] +- Resolves: bz#1289417 + (Rebase to QEMU 2.6) + +* Wed Oct 14 2015 Miroslav Rezanina - rhev-2.3.0-31.el7 +- kvm-Migration-Generate-the-completed-event-only-when-we-.patch [bz#1271145] +- Resolves: bz#1271145 + (Guest OS paused after migration.) + +* Mon Oct 12 2015 Jeff E. Nelson - rhev-2.3.0-30.el7 +- kvm-memhp-extend-address-auto-assignment-to-support-gaps.patch [bz#1267533] +- kvm-pc-memhp-force-gaps-between-DIMM-s-GPA.patch [bz#1267533] +- kvm-memory-allow-destroying-a-non-empty-MemoryRegion.patch [bz#1264347] +- kvm-hw-do-not-pass-NULL-to-memory_region_init-from-insta.patch [bz#1264347] +- kvm-tests-Fix-how-qom-test-is-run.patch [bz#1264347] +- kvm-libqtest-Clean-up-unused-QTestState-member-sigact_ol.patch [bz#1264347] +- kvm-libqtest-New-hmp-friends.patch [bz#1264347] +- kvm-device-introspect-test-New-covering-device-introspec.patch [bz#1264347] +- kvm-qmp-Fix-device-list-properties-not-to-crash-for-abst.patch [bz#1264347] +- kvm-qdev-Protect-device-list-properties-against-broken-d.patch [bz#1264347] +- kvm-Revert-qdev-Use-qdev_get_device_class-for-device-typ.patch [bz#1264347] +- Resolves: bz#1264347 + (QMP device-list-properties crashes for CPU devices) +- Resolves: bz#1267533 + (qemu quit when rebooting guest which hotplug memory >=13 times) + +* Thu Oct 08 2015 Miroslav Rezanina - rhev-2.3.0-29.el7 +- kvm-vfio-Remove-unneeded-union-from-VFIOContainer.patch [bz#1259556] +- kvm-vfio-Generalize-vfio_listener_region_add-failure-pat.patch [bz#1259556] +- kvm-vfio-Check-guest-IOVA-ranges-against-host-IOMMU-capa.patch [bz#1259556] +- kvm-vfio-Record-host-IOMMU-s-available-IO-page-sizes.patch [bz#1259556] +- kvm-memory-Allow-replay-of-IOMMU-mapping-notifications.patch [bz#1259556] +- kvm-vfio-Allow-hotplug-of-containers-onto-existing-guest.patch [bz#1259556] +- kvm-spapr_pci-Allow-PCI-host-bridge-DMA-window-to-be-con.patch [bz#1259556] +- kvm-spapr_iommu-Rename-vfio_accel-parameter.patch [bz#1259556] +- kvm-spapr_iommu-Provide-a-function-to-switch-a-TCE-table.patch [bz#1259556] +- kvm-spapr_pci-Allow-VFIO-devices-to-work-on-the-normal-P.patch [bz#1259556] +- Resolves: bz#1259556 + (Allow VFIO devices on the same guest PHB as emulated devices) + +* Mon Oct 05 2015 Miroslav Rezanina - rhev-2.3.0-28.el7 +- kvm-rhel-Revert-unwanted-cannot_instantiate_with_device_.patch [bz#1224542] +- kvm-Disable-additional-e1000-models.patch [bz#1224542 bz#1265161] +- kvm-Remove-intel-iommu-device.patch [bz#1224542] +- kvm-virtio-net-unbreak-self-announcement-and-guest-offlo.patch [bz#1262232] +- kvm-block-mirror-fix-full-sync-mode-when-target-does-not.patch [bz#1136382] +- Resolves: bz#1136382 + (block: Mirroring to raw block device doesn't zero out unused blocks) +- Resolves: bz#1224542 + (unsupported devices need to be disabled in qemu-kvm-rhev after rebasing to 2.3.0) +- Resolves: bz#1262232 + (self announcement and ctrl offloads does not work after migration) +- Resolves: bz#1265161 + (Support various e1000 variants) + +* Wed Sep 30 2015 Miroslav Rezanina - rhev-2.3.0-27.el7 +- kvm-sdl2-Fix-RGB555.patch [bz#1247479] +- kvm-spice-surface-switch-fast-path-requires-same-format-.patch [bz#1247479] +- kvm-virtio-blk-only-clear-VIRTIO_F_ANY_LAYOUT-for-legacy.patch [bz#1207687] +- kvm-vhost-enable-vhost-without-without-MSI-X.patch [bz#1207687] +- kvm-vhost-user-Send-VHOST_RESET_OWNER-on-vhost-stop.patch [bz#1207687] +- kvm-virtio-avoid-leading-underscores-for-helpers.patch [bz#1207687] +- kvm-vhost-user-use-VHOST_USER_XXX-macro-for-switch-state.patch [bz#1207687] +- kvm-vhost-user-add-protocol-feature-negotiation.patch [bz#1207687] +- kvm-vhost-rename-VHOST_RESET_OWNER-to-VHOST_RESET_DEVICE.patch [bz#1207687] +- kvm-vhost-user-add-VHOST_USER_GET_QUEUE_NUM-message.patch [bz#1207687] +- kvm-vhost-introduce-vhost_backend_get_vq_index-method.patch [bz#1207687] +- kvm-vhost-user-add-multiple-queue-support.patch [bz#1207687] +- kvm-vhost-user-add-a-new-message-to-disable-enable-a-spe.patch [bz#1207687] +- Resolves: bz#1207687 + ([6wind 7.2 FEAT]: vhost-user does not support multique) +- Resolves: bz#1247479 + (display mess when boot a win2012-r2-64 guest with -vga std) + +* Thu Sep 24 2015 Miroslav Rezanina - rhev-2.3.0-26.el7 +- kvm-qcow2-Make-size_to_clusters-return-uint64_t.patch [bz#1260365] +- kvm-iotests-Add-test-for-checking-large-image-files.patch [bz#1260365] +- Resolves: bz#1260365 + (Guest image created coredump after installation.) + +* Wed Sep 23 2015 Miroslav Rezanina - rhev-2.3.0-25.el7 +- kvm-block-backend-Expose-bdrv_write_zeroes.patch [bz#1256541] +- kvm-qemu-img-convert-Rewrite-copying-logic.patch [bz#1256541] +- kvm-main-loop-fix-qemu_notify_event-for-aio_notify-optim.patch [bz#1256541] +- kvm-error-New-error_fatal.patch [bz#1232308] +- kvm-Fix-bad-error-handling-after-memory_region_init_ram.patch [bz#1232308] +- kvm-loader-Fix-memory_region_init_resizeable_ram-error-h.patch [bz#1232308] +- kvm-memory-Fix-bad-error-handling-in-memory_region_init_.patch [bz#1232308] +- kvm-spapr_pci-encode-class-code-including-Prog-IF-regist.patch [bz#1264845] +- kvm-scripts-dump-guest-memory.py-fix-after-RAMBlock-chan.patch [bz#1234802] +- kvm-spec-Require-proper-version-of-SLOF.patch [bz#1263795] +- Resolves: bz#1232308 + ([abrt] qemu-system-x86: qemu_ram_alloc(): qemu-system-x86_64 killed by SIGABRT) +- Resolves: bz#1234802 + ([RHEL7.2] dump-guest-memory failed because of Python Exception There is no member named length.) +- Resolves: bz#1256541 + (qemu-img hangs forever in aio_poll when used to convert some images) +- Resolves: bz#1263795 + (vfio device can't be hot unplugged on powerpc guest) +- Resolves: bz#1264845 + ([regression] Guest usb mouse/keyboard could not be used on qemu-kvm-rhev-2.3.0-24.el7.ppc64le) + +* Fri Sep 18 2015 Miroslav Rezanina - rhev-2.3.0-24.el7 +- kvm-spapr-Don-t-use-QOM-syntax-for-DR-connectors.patch [bz#1262143] +- kvm-virtio-mmio-ioeventfd-support.patch [bz#1185480] +- kvm-scsi-fix-buffer-overflow-in-scsi_req_parse_cdb-CVE-2.patch [bz#1244334] +- kvm-spapr-Populate-ibm-associativity-lookup-arrays-corre.patch [bz#1262670] +- kvm-ppc-spapr-Fix-buffer-overflow-in-spapr_populate_drco.patch [bz#1262670] +- kvm-spapr_pci-Introduce-a-liobn-number-generating-macros.patch [bz#1263795] +- kvm-spapr_iommu-Make-spapr_tce_find_by_liobn-public.patch [bz#1263795] +- kvm-spapr_pci-Rework-device-tree-rendering.patch [bz#1263795] +- kvm-spapr_pci-enumerate-and-add-PCI-device-tree.patch [bz#1263795] +- kvm-spapr_pci-populate-ibm-loc-code.patch [bz#1263795] +- kvm-tests-remove-irrelevant-assertions-from-test-aio.patch [bz#1211689] +- kvm-aio-posix-move-pollfds-to-thread-local-storage.patch [bz#1211689] +- kvm-aio-Introduce-type-in-aio_set_fd_handler-and-aio_set.patch [bz#1211689] +- kvm-aio-Save-type-to-AioHandler.patch [bz#1211689] +- kvm-aio-posix-Introduce-aio_poll_clients.patch [bz#1211689] +- kvm-block-Mark-fd-handlers-as-protocol.patch [bz#1211689] +- kvm-nbd-Mark-fd-handlers-client-type-as-nbd-server.patch [bz#1211689] +- kvm-aio-Mark-ctx-notifier-s-client-type-as-context.patch [bz#1211689] +- kvm-dataplane-Mark-host-notifiers-client-type-as-datapla.patch [bz#1211689] +- kvm-block-Introduce-bdrv_aio_poll.patch [bz#1211689] +- kvm-block-Replace-nested-aio_poll-with-bdrv_aio_poll.patch [bz#1211689] +- kvm-block-Only-poll-block-layer-fds-in-bdrv_aio_poll.patch [bz#1211689] +- Resolves: bz#1185480 + (backport ioeventfd support for virtio-mmio) +- Resolves: bz#1211689 + (atomic live snapshots are not atomic with dataplane-backed devices) +- Resolves: bz#1244334 + (qemu-kvm-rhev: Qemu: scsi stack buffer overflow [rhel-7.2]) +- Resolves: bz#1262143 + (VM startup is very slow with large amounts of hotpluggable memory) +- Resolves: bz#1262670 + ([PowerKVM]SIGSEGV when boot up guest with -numa node and set up the cpus in one node to the boundary) +- Resolves: bz#1263795 + (vfio device can't be hot unplugged on powerpc guest) + +* Tue Sep 15 2015 Miroslav Rezanina - rhev-2.3.0-23.el7 +- kvm-scsi-disk-Fix-assertion-failure-on-WRITE-SAME.patch [bz#1247042] +- kvm-mirror-Speed-up-bitmap-initial-scanning.patch [bz#1259229] +- kvm-qemu-iotests-Disable-099-requires-blkverify.patch [bz#1257059] +- kvm-spapr-Reduce-advertised-max-LUNs-for-spapr_vscsi.patch [bz#1260464] +- kvm-vnc-Don-t-assert-if-opening-unix-socket-fails.patch [bz#1261263] +- kvm-qcow2-Handle-EAGAIN-returned-from-update_refcount.patch [bz#1254927] +- kvm-pc-memhotplug-fix-incorrectly-set-reserved-memory-en.patch [bz#1261846] +- kvm-pc-memhotplug-keep-reserved-memory-end-broken-on-rhe.patch [bz#1261846] +- Resolves: bz#1247042 + (qemu quit when using sg_write_same command inside RHEL7.2 guest) +- Resolves: bz#1254927 + (qemu-img shows Input/output error when compressing guest image) +- Resolves: bz#1257059 + (qemu-iotests 099 failed for vmdk) +- Resolves: bz#1259229 + (drive-mirror blocks QEMU due to lseek64() on raw image files) +- Resolves: bz#1260464 + (The spapr vscsi disks for lun id '9-31' and channel id '4-7' could not be recognized inside a power pc guest) +- Resolves: bz#1261263 + (qemu crash while start a guest with invalid vnc socket path) +- Resolves: bz#1261846 + (qemu-kvm-rhev: 64-bit PCI bars may overlap hotplugged memory and vice verse) + +* Thu Sep 03 2015 Miroslav Rezanina - rhev-2.3.0-22.el7 +- kvm-mirror-Fix-coroutine-reentrance.patch [bz#1251487] +- kvm-RHEL-Set-vcpus-hard-limit-to-240-for-Power.patch [bz#1257781] +- kvm-provide-vhost-module-config-file-with-max_mem_region.patch [bz#1255349] +- Resolves: bz#1251487 + (qemu core dump when do drive mirror) +- Resolves: bz#1255349 + (vhost: default value of 'max_mem_regions' should be set larger(>=260) than 64) +- Resolves: bz#1257781 + (The prompt is confusing when boot a guest with larger vcpu number than host physical cpu) + +* Fri Aug 28 2015 Miroslav Rezanina - rhev-2.3.0-21.el7 +- kvm-vnc-fix-memory-corruption-CVE-2015-5225.patch [bz#1255898] +- Resolves: bz#1255898 + (CVE-2015-5225 qemu-kvm-rhev: Qemu: ui: vnc: heap memory corruption in vnc_refresh_server_surface [rhel-7.2]) + +* Thu Aug 27 2015 Yash Mankad - rhev-2.3.0-20.el7 +- kvm-pseries-define-coldplugged-devices-as-configured.patch [bz#1243721] +- kvm-spice-fix-spice_chr_add_watch-pre-condition.patch [bz#1128992] +- Resolves: bz#1128992 + (Spiceport character device is not reliable caused domain shutoff) +- Resolves: bz#1243721 + (After hotunpug virtio device, the device still exist in pci info) + +* Mon Aug 24 2015 Miroslav Rezanina - rhev-2.3.0-19.el7 +- kvm-ppc-add-helpful-message-when-KVM-fails-to-start-VCPU.patch [bz#1215618] +- kvm-pci-allow-0-address-for-PCI-IO-MEM-regions.patch [bz#1241886] +- kvm-RHEL-Suppress-scary-but-unimportant-errors-for-KVM-V.patch [bz#1237034] +- Resolves: bz#1215618 + (Unhelpful error message on Power when SMT is enabled) +- Resolves: bz#1237034 + (Error prompt while booting with vfio-pci device) +- Resolves: bz#1241886 + (hot plugged pci devices won't appear unless reboot) + +* Fri Aug 14 2015 Miroslav Rezanina - rhev-2.3.0-18.el7 +- kvm-vhost-correctly-pass-error-to-caller-in-vhost_dev_en.patch [bz#1248312] +- kvm-Revert-virtio-net-enable-virtio-1.0.patch [bz#1248312] +- kvm-virtio-net-unbreak-any-layout.patch [bz#1248312] +- kvm-virtio-hide-legacy-features-from-modern-guests.patch [bz#1248312] +- kvm-virtio-serial-fix-ANY_LAYOUT.patch [bz#1248312] +- kvm-virtio-9p-fix-any_layout.patch [bz#1248312] +- kvm-virtio-set-any_layout-in-virtio-core.patch [bz#1248312] +- kvm-virtio-pci-fix-memory-MR-cleanup-for-modern.patch [bz#1248312] +- kvm-virtio-get_features-can-fail.patch [bz#1248312] +- kvm-virtio-blk-fail-get_features-when-both-scsi-and-1.0-.patch [bz#1248312] +- kvm-virtio-minor-cleanup.patch [bz#1248312] +- kvm-memory-do-not-add-a-reference-to-the-owner-of-aliase.patch [bz#1248312] +- kvm-virtio-net-remove-virtio-queues-if-the-guest-doesn-t.patch [bz#1248312] +- kvm-virtio-fix-1.0-virtqueue-migration.patch [bz#1248312] +- kvm-Downstream-only-Start-kvm-setup-service-before-libvi.patch [bz#1251962] +- kvm-qcow2-Flush-pending-discards-before-allocating-clust.patch [bz#1226297] +- Resolves: bz#1226297 + (qcow2 crash during discard operation) +- Resolves: bz#1248312 + ("fdisk -l"can not output anything and the process status is D+ after migrating RHEL7.2 guest with virtio-1 virtio-scsi disk) +- Resolves: bz#1251962 + (kvm-setup.service should include Before=libvirtd.service) + +* Wed Aug 12 2015 Miroslav Rezanina - rhev-2.3.0-17.el7 +- kvm-migration-avoid-divide-by-zero-in-xbzrle-cache-miss-.patch [bz#580006] +- kvm-migration-move-ram-stuff-to-migration-ram.patch [bz#580006] +- kvm-migration-move-savevm.c-inside-migration.patch [bz#580006] +- kvm-migration-Add-myself-to-the-copyright-list-of-both-f.patch [bz#580006] +- kvm-migration-reduce-include-files.patch [bz#580006] +- kvm-migration-Remove-duplicated-assignment-of-SETUP-stat.patch [bz#580006] +- kvm-migration-create-savevm_state.patch [bz#580006] +- kvm-migration-Use-normal-VMStateDescriptions-for-Subsect.patch [bz#580006] +- kvm-Add-qemu_get_counted_string-to-read-a-string-prefixe.patch [bz#580006] +- kvm-runstate-Add-runstate-store.patch [bz#580006] +- kvm-runstate-migration-allows-more-transitions-now.patch [bz#580006] +- kvm-migration-create-new-section-to-store-global-state.patch [bz#580006] +- kvm-global_state-Make-section-optional.patch [bz#580006] +- kvm-vmstate-Create-optional-sections.patch [bz#580006] +- kvm-migration-Add-configuration-section.patch [bz#580006] +- kvm-migration-ensure-we-start-in-NONE-state.patch [bz#580006] +- kvm-migration-Use-always-helper-to-set-state.patch [bz#580006] +- kvm-migration-No-need-to-call-trace_migrate_set_state.patch [bz#580006] +- kvm-migration-create-migration-event.patch [bz#580006] +- kvm-migration-Make-events-a-capability.patch [bz#580006] +- kvm-migration-Add-migration-events-on-target-side.patch [bz#580006] +- kvm-migration-Only-change-state-after-migration-has-fini.patch [bz#580006] +- kvm-migration-Trace-event-and-migration-event-are-differ.patch [bz#580006] +- kvm-migration-Write-documetation-for-events-capabilites.patch [bz#580006] +- kvm-migration-Register-global-state-section-before-loadv.patch [bz#580006] +- kvm-migration-We-also-want-to-store-the-global-state-for.patch [bz#580006] +- kvm-block-mirror-limit-qiov-to-IOV_MAX-elements.patch [bz#1238585] +- kvm-i6300esb-fix-timer-overflow.patch [bz#1247893] +- Resolves: bz#1238585 + (drive-mirror has spurious failures with low 'granularity' values) +- Resolves: bz#1247893 + (qemu's i6300esb watchdog does not fire on time with large heartbeat like 2046) +- Resolves: bz#580006 + (QMP: A QMP event notification when migration finish.) + +* Fri Aug 07 2015 Miroslav Rezanina - rhev-2.3.0-16.el7 +- kvm-virtio-scsi-use-virtqueue_map_sg-when-loading-reques.patch [bz#1160169] +- kvm-scsi-disk-fix-cmd.mode-field-typo.patch [bz#1160169] +- kvm-target-i386-emulate-CPUID-level-of-real-hardware.patch [bz#1223317] +- kvm-target-i386-fix-IvyBridge-xlevel-in-PC_COMPAT_2_3.patch [bz#1223317] +- Resolves: bz#1160169 + (Segfault occurred at Dst VM while completed migration upon ENOSPC) +- Resolves: bz#1223317 + (BSod occurs When installing latest Windows Enterprise Insider 10 and windows server 2016 Preview) + +* Wed Aug 05 2015 Miroslav Rezanina - rhev-2.3.0-15.el7 +- kvm-usb-ccid-add-missing-wakeup-calls.patch [bz#1211970] +- kvm-vfio-pci-Fix-bootindex.patch [bz#1245127] +- kvm-acpi-fix-pvpanic-device-is-not-shown-in-ui.patch [bz#1238141] +- kvm-redhat-add-kvm-unit-tests-tarball-to-environment.patch [bz#1225980] +- kvm-spec-Build-tscdeadline_latency.flat-from-kvm-unit-te.patch [bz#1225980] +- Resolves: bz#1211970 + (smart card emulation doesn't work with USB3 (nec-xhci) controller) +- Resolves: bz#1225980 + (Package tscdeadline_latency.flat with qemu-kvm-rhev) +- Resolves: bz#1238141 + ([virtio-win][pvpanic]win10-32 guest can not detect pvpanic device in device manager) +- Resolves: bz#1245127 + (bootindex doesn't work for vfio-pci) + +* Fri Jul 31 2015 Miroslav Rezanina - rhev-2.3.0-14.el7 +- kvm-rtl8139-avoid-nested-ifs-in-IP-header-parsing-CVE-20.patch [bz#1248768] +- kvm-rtl8139-drop-tautologous-if-ip-.-statement-CVE-2015-.patch [bz#1248768] +- kvm-rtl8139-skip-offload-on-short-Ethernet-IP-header-CVE.patch [bz#1248768] +- kvm-rtl8139-check-IP-Header-Length-field-CVE-2015-5165.patch [bz#1248768] +- kvm-rtl8139-check-IP-Total-Length-field-CVE-2015-5165.patch [bz#1248768] +- kvm-rtl8139-skip-offload-on-short-TCP-header-CVE-2015-51.patch [bz#1248768] +- kvm-rtl8139-check-TCP-Data-Offset-field-CVE-2015-5165.patch [bz#1248768] +- Resolves: bz#1248768 + (EMBARGOED CVE-2015-5165 qemu-kvm-rhev: Qemu: rtl8139 uninitialized heap memory information leakage to guest [rhel-7.2]) + +* Fri Jul 24 2015 Miroslav Rezanina - rhev-2.3.0-13.el7 +- kvm-block-Add-bdrv_get_block_status_above.patch [bz#1242316] +- kvm-qmp-Add-optional-bool-unmap-to-drive-mirror.patch [bz#1242316] +- kvm-mirror-Do-zero-write-on-target-if-sectors-not-alloca.patch [bz#1242316] +- kvm-block-Fix-dirty-bitmap-in-bdrv_co_discard.patch [bz#1242316] +- kvm-block-Remove-bdrv_reset_dirty.patch [bz#1242316] +- kvm-iotests-add-QMP-event-waiting-queue.patch [bz#1242316] +- kvm-qemu-iotests-Make-block-job-methods-common.patch [bz#1242316] +- kvm-qemu-iotests-Add-test-case-for-mirror-with-unmap.patch [bz#1242316] +- kvm-iotests-Use-event_wait-in-wait_ready.patch [bz#1242316] +- kvm-rdma-fix-memory-leak.patch [bz#1210715] +- kvm-Only-try-and-read-a-VMDescription-if-it-should-be-th.patch [bz#1210715] +- kvm-qemu_ram_foreach_block-pass-up-error-value-and-down-.patch [bz#1210715] +- kvm-rdma-Fix-qemu-crash-when-IPv6-address-is-used-for-mi.patch [bz#1210715] +- kvm-Rename-RDMA-structures-to-make-destination-clear.patch [bz#1210715] +- kvm-Remove-unneeded-memset.patch [bz#1210715] +- kvm-rdma-typos.patch [bz#1210715] +- kvm-Store-block-name-in-local-blocks-structure.patch [bz#1210715] +- kvm-Translate-offsets-to-destination-address-space.patch [bz#1210715] +- kvm-Rework-ram_control_load_hook-to-hook-during-block-lo.patch [bz#1210715] +- kvm-Allow-rdma_delete_block-to-work-without-the-hash.patch [bz#1210715] +- kvm-Rework-ram-block-hash.patch [bz#1210715] +- kvm-Sort-destination-RAMBlocks-to-be-the-same-as-the-sou.patch [bz#1210715] +- kvm-Sanity-check-RDMA-remote-data.patch [bz#1210715] +- kvm-Fail-more-cleanly-in-mismatched-RAM-cases.patch [bz#1210715] +- kvm-migration-Use-cmpxchg-correctly.patch [bz#1210715] +- kvm-RDMA-Fix-error-exits-for-2.4.patch [bz#1210715] +- kvm-block-mirror-Sleep-periodically-during-bitmap-scanni.patch [bz#1233826] +- kvm-block-curl-Don-t-lose-original-error-when-a-connecti.patch [bz#1235813] +- kvm-vfio-pci-Add-pba_offset-PCI-quirk-for-Chelsio-T5-dev.patch [bz#1244348] +- kvm-hostmem-Fix-qemu_opt_get_bool-crash-in-host_memory_b.patch [bz#1237220] +- kvm-pc-pc-dimm-Extract-hotplug-related-fields-in-PCMachi.patch [bz#1211117] +- kvm-pc-pc-dimm-Factor-out-reusable-parts-in-pc_dimm_plug.patch [bz#1211117] +- kvm-pc-Abort-if-HotplugHandlerClass-plug-fails.patch [bz#1211117] +- kvm-numa-pc-dimm-Store-pc-dimm-memory-information-in-num.patch [bz#1211117] +- kvm-numa-Store-boot-memory-address-range-in-node_info.patch [bz#1211117] +- kvm-numa-API-to-lookup-NUMA-node-by-address.patch [bz#1211117] +- kvm-docs-add-sPAPR-hotplug-dynamic-reconfiguration-docum.patch [bz#1211117] +- kvm-machine-add-default_ram_size-to-machine-class.patch [bz#1211117] +- kvm-spapr-override-default-ram-size-to-512MB.patch [bz#1211117] +- kvm-spapr_pci-Make-find_phb-find_dev-public.patch [bz#1211117] +- kvm-spapr-Merge-sPAPREnvironment-into-sPAPRMachineState.patch [bz#1211117] +- kvm-spapr-Remove-obsolete-ram_limit-field-from-sPAPRMach.patch [bz#1211117] +- kvm-spapr-Remove-obsolete-entry_point-field-from-sPAPRMa.patch [bz#1211117] +- kvm-spapr-Add-sPAPRMachineClass.patch [bz#1211117] +- kvm-spapr-ensure-we-have-at-least-one-XICS-server.patch [bz#1211117] +- kvm-spapr-Consider-max_cpus-during-xics-initialization.patch [bz#1211117] +- kvm-spapr-Support-ibm-lrdr-capacity-device-tree-property.patch [bz#1211117] +- kvm-cpus-Add-a-macro-to-walk-CPUs-in-reverse.patch [bz#1211117] +- kvm-spapr-Reorganize-CPU-dt-generation-code.patch [bz#1211117] +- kvm-spapr-Consolidate-cpu-init-code-into-a-routine.patch [bz#1211117] +- kvm-ppc-Update-cpu_model-in-MachineState.patch [bz#1211117] +- kvm-xics_kvm-Don-t-enable-KVM_CAP_IRQ_XICS-if-already-en.patch [bz#1211117] +- kvm-spapr-Initialize-hotplug-memory-address-space.patch [bz#1211117] +- kvm-spapr-Add-LMB-DR-connectors.patch [bz#1211117] +- kvm-spapr-Support-ibm-dynamic-reconfiguration-memory.patch [bz#1211117] +- kvm-spapr-Make-hash-table-size-a-factor-of-maxram_size.patch [bz#1211117] +- kvm-spapr-Memory-hotplug-support.patch [bz#1211117] +- kvm-spapr-Don-t-allow-memory-hotplug-to-memory-less-node.patch [bz#1211117] +- Resolves: bz#1210715 + (migration/rdma: 7.1->7.2: RDMA ERROR: ram blocks mismatch #3!) +- Resolves: bz#1211117 + (add support for memory hotplug on Power) +- Resolves: bz#1233826 + (issueing drive-mirror command causes monitor unresponsive) +- Resolves: bz#1235813 + (block/curl: Fix generic "Input/output error" on failure) +- Resolves: bz#1237220 + (Fail to create NUMA guest with ) +- Resolves: bz#1242316 + (Add "unmap" support for drive-mirror) +- Resolves: bz#1244348 + (Quirk for Chelsio T5 MSI-X PBA) + +* Fri Jul 17 2015 Miroslav Rezanina - rhev-2.3.0-12.el7 +- kvm-ide-Check-array-bounds-before-writing-to-io_buffer-C.patch [bz#1243692] +- kvm-ide-atapi-Fix-START-STOP-UNIT-command-completion.patch [bz#1243692] +- kvm-ide-Clear-DRQ-after-handling-all-expected-accesses.patch [bz#1243692] +- Resolves: bz#1243692 + () + +* Fri Jul 17 2015 Miroslav Rezanina - rhev-2.3.0-11.el7 +- kvm-hw-acpi-acpi_pm1_cnt_init-take-disable_s3-and-disabl.patch [bz#1204696] +- kvm-hw-acpi-move-etc-system-states-fw_cfg-file-from-PIIX.patch [bz#1204696] +- kvm-hw-acpi-piix4_pm_init-take-fw_cfg-object-no-more.patch [bz#1204696] +- kvm-i386-pc-pc_basic_device_init-delegate-FDC-creation-r.patch [bz#1227282] +- kvm-i386-pc-drive-if-floppy-should-imply-a-board-default.patch [bz#1227282] +- kvm-i386-pc_q35-don-t-insist-on-board-FDC-if-there-s-no-.patch [bz#1227282] +- kvm-i386-drop-FDC-in-pc-q35-rhel7.2.0-if-neither-it-nor-.patch [bz#1227282] +- kvm-hw-i386-pc-factor-out-pc_cmos_init_floppy.patch [bz#1227282] +- kvm-hw-i386-pc-reflect-any-FDC-ioport-0x3f0-in-the-CMOS.patch [bz#1227282] +- kvm-hw-i386-pc-don-t-carry-FDC-from-pc_basic_device_init.patch [bz#1227282] +- kvm-Fix-reported-machine-type.patch [bz#1241331] +- kvm-i386-acpi-build-more-traditional-_UID-and-_HID-for-P.patch [bz#1242479] +- kvm-i386-acpi-build-fix-PXB-workarounds-for-unsupported-.patch [bz#1242479] +- kvm-hw-core-rebase-sysbus_get_fw_dev_path-to-g_strdup_pr.patch [bz#1242479] +- kvm-migration-introduce-VMSTATE_BUFFER_UNSAFE_INFO_TEST.patch [bz#1242479] +- kvm-hw-pci-bridge-expose-_test-parameter-in-SHPC_VMSTATE.patch [bz#1242479] +- kvm-hw-pci-bridge-add-macro-for-chassis_nr-property.patch [bz#1242479] +- kvm-hw-pci-bridge-add-macro-for-msi-property.patch [bz#1242479] +- kvm-hw-pci-introduce-shpc_present-helper-function.patch [bz#1242479] +- kvm-hw-pci-bridge-introduce-shpc-property.patch [bz#1242479] +- kvm-hw-pci-bridge-disable-SHPC-in-PXB.patch [bz#1242479] +- kvm-hw-core-explicit-OFW-unit-address-callback-for-SysBu.patch [bz#1242479] +- kvm-hw-pci-bridge-format-special-OFW-unit-address-for-PX.patch [bz#1242479] +- Resolves: bz#1204696 + (Expose PM system states in fw_cfg file on Q35) +- Resolves: bz#1227282 + (tighten conditions for board-implied FDC in pc-q35-rhel7.2.0+) +- Resolves: bz#1241331 + (Machine type reported by guest is different with that in RHEL.7.1 GA version) +- Resolves: bz#1242479 + (backport QEMU changes needed for supporting multiple PCI root buses with OVMF) + +* Tue Jul 14 2015 Miroslav Rezanina - rhev-2.3.0-10.el7 +- kvm-Disable-Educational-device.patch [bz#1194151] +- kvm-Disable-sdhci-device.patch [bz#1194151] +- kvm-Mark-onboard-devices-as-cannot_instantiate_with_devi.patch [bz#1194151] +- kvm-target-arm-Add-GIC-phandle-to-VirtBoardInfo.patch [bz#1231929] +- kvm-arm_gicv2m-Add-GICv2m-widget-to-support-MSIs.patch [bz#1231929] +- kvm-target-arm-Extend-the-gic-node-properties.patch [bz#1231929] +- kvm-target-arm-Add-the-GICv2m-to-the-virt-board.patch [bz#1231929] +- kvm-introduce-kvm_arch_msi_data_to_gsi.patch [bz#1231929] +- kvm-arm_gicv2m-set-kvm_gsi_direct_mapping-and-kvm_msi_vi.patch [bz#1231929] +- kvm-hw-arm-virt-acpi-build-Fix-table-revision-and-some-c.patch [bz#1231929] +- kvm-hw-arm-virt-acpi-build-Add-GICv2m-description-in-ACP.patch [bz#1231929] +- Resolves: bz#1194151 + (Rebase to qemu 2.3) +- Resolves: bz#1231929 + (AArch64: backport MSI support (gicv2m)) + +* Thu Jul 09 2015 Miroslav Rezanina - rhev-2.3.0-9.el7 +- kvm-acpi-add-a-missing-backslash-to-the-_SB-scope.patch [bz#1103313] +- kvm-range-remove-useless-inclusions.patch [bz#1103313] +- kvm-acpi-Simplify-printing-to-dynamic-string.patch [bz#1103313] +- kvm-acpi-add-aml_add-term.patch [bz#1103313] +- kvm-acpi-add-aml_lless-term.patch [bz#1103313] +- kvm-acpi-add-aml_index-term.patch [bz#1103313] +- kvm-acpi-add-aml_shiftleft-term.patch [bz#1103313] +- kvm-acpi-add-aml_shiftright-term.patch [bz#1103313] +- kvm-acpi-add-aml_increment-term.patch [bz#1103313] +- kvm-acpi-add-aml_while-term.patch [bz#1103313] +- kvm-acpi-add-implementation-of-aml_while-term.patch [bz#1103313] +- kvm-hw-pci-made-pci_bus_is_root-a-PCIBusClass-method.patch [bz#1103313] +- kvm-hw-pci-made-pci_bus_num-a-PCIBusClass-method.patch [bz#1103313] +- kvm-hw-i386-query-only-for-q35-pc-when-looking-for-pci-h.patch [bz#1103313] +- kvm-hw-pci-extend-PCI-config-access-to-support-devices-b.patch [bz#1103313] +- kvm-hw-acpi-add-support-for-i440fx-snooping-root-busses.patch [bz#1103313] +- kvm-hw-apci-add-_PRT-method-for-extra-PCI-root-busses.patch [bz#1103313] +- kvm-hw-acpi-add-_CRS-method-for-extra-root-busses.patch [bz#1103313] +- kvm-hw-acpi-remove-from-root-bus-0-the-crs-resources-use.patch [bz#1103313] +- kvm-hw-pci-removed-rootbus-nr-is-0-assumption-from-qmp_p.patch [bz#1103313] +- kvm-hw-pci-introduce-PCI-Expander-Bridge-PXB.patch [bz#1103313] +- kvm-hw-pci-inform-bios-if-the-system-has-extra-pci-root-.patch [bz#1103313] +- kvm-hw-pxb-add-map_irq-func.patch [bz#1103313] +- kvm-hw-pci-add-support-for-NUMA-nodes.patch [bz#1103313] +- kvm-hw-pxb-add-numa_node-parameter.patch [bz#1103313] +- kvm-apci-fix-PXB-behaviour-if-used-with-unsupported-BIOS.patch [bz#1103313] +- kvm-docs-Add-PXB-documentation.patch [bz#1103313] +- kvm-sPAPR-Don-t-enable-EEH-on-emulated-PCI-devices.patch [bz#1213681] +- kvm-sPAPR-Reenable-EEH-functionality-on-reboot.patch [bz#1213681] +- kvm-sPAPR-Clear-stale-MSIx-table-during-EEH-reset.patch [bz#1213681] +- kvm-configure-Add-support-for-tcmalloc.patch [bz#1213882] +- Resolves: bz#1103313 + (RFE: configure guest NUMA node locality for guest PCI devices) +- Resolves: bz#1213681 + (PAPR PCI-e EEH (Enhanced Error Handling) for KVM/Power guests with VFIO devices (qemu)) +- Resolves: bz#1213882 + (enable using tcmalloc for memory allocation in qemu-kvm-rhev) + +* Wed Jul 08 2015 Miroslav Rezanina - rhev-2.3.0-8.el7 +- kvm-block-Fix-NULL-deference-for-unaligned-write-if-qiov.patch [bz#1207034] +- kvm-qemu-iotests-Test-unaligned-sub-block-zero-write.patch [bz#1207034] +- kvm-spapr_drc-initial-implementation-of-sPAPRDRConnector.patch [bz#1172478] +- kvm-spapr_rtas-add-get-set-power-level-RTAS-interfaces.patch [bz#1172478] +- kvm-spapr_rtas-add-set-indicator-RTAS-interface.patch [bz#1172478] +- kvm-spapr_rtas-add-get-sensor-state-RTAS-interface.patch [bz#1172478] +- kvm-spapr-add-rtas_st_buffer_direct-helper.patch [bz#1172478] +- kvm-spapr_rtas-add-ibm-configure-connector-RTAS-interfac.patch [bz#1172478] +- kvm-spapr_events-re-use-EPOW-event-infrastructure-for-ho.patch [bz#1172478] +- kvm-spapr_events-event-scan-RTAS-interface.patch [bz#1172478] +- kvm-spapr_drc-add-spapr_drc_populate_dt.patch [bz#1172478] +- kvm-spapr_pci-add-dynamic-reconfiguration-option-for-spa.patch [bz#1172478] +- kvm-spapr_pci-create-DRConnectors-for-each-PCI-slot-duri.patch [bz#1172478] +- kvm-pci-make-pci_bar-useable-outside-pci.c.patch [bz#1172478] +- kvm-spapr_pci-enable-basic-hotplug-operations.patch [bz#1172478] +- kvm-spapr_pci-emit-hotplug-add-remove-events-during-hotp.patch [bz#1172478] +- kvm-Print-error-when-failing-to-load-PCI-config-data.patch [bz#1209793] +- kvm-Fix-ich9-intel-hda-compatibility.patch [bz#1209793] +- kvm-pseries-Enable-in-kernel-H_LOGICAL_CI_-LOAD-STORE-im.patch [bz#1217277] +- kvm-Split-serial-isa-into-its-own-config-option.patch [bz#1191845] +- kvm-rhel-Disable-info-irq-and-info-pic-for-Power.patch [bz#1191845] +- kvm-RHEL-Disable-remaining-unsupported-devices-for-ppc.patch [bz#1191845] +- kvm-linux-headers-sync-vhost.h.patch [bz#1225715] +- kvm-virtio-introduce-virtio_legacy_is_cross_endian.patch [bz#1225715] +- kvm-vhost-set-vring-endianness-for-legacy-virtio.patch [bz#1225715] +- kvm-tap-add-VNET_LE-VNET_BE-operations.patch [bz#1225715] +- kvm-tap-fix-non-linux-build.patch [bz#1225715] +- kvm-vhost-net-tell-tap-backend-about-the-vnet-endianness.patch [bz#1225715] +- kvm-vhost_net-re-enable-when-cross-endian.patch [bz#1225715] +- kvm-linux-headers-update.patch [bz#1227343] +- kvm-virtio-input-add-linux-input.h.patch [bz#1227343] +- kvm-virtio-input-core-code-base-class-device.patch [bz#1227343] +- kvm-virtio-input-emulated-devices-device.patch [bz#1227343] +- kvm-virtio-net-Move-DEFINE_VIRTIO_NET_FEATURES-to-virtio.patch [bz#1227343] +- kvm-virtio-scsi-Move-DEFINE_VIRTIO_SCSI_FEATURES-to-virt.patch [bz#1227343] +- kvm-memory-Define-API-for-MemoryRegionOps-to-take-attrs-.patch [bz#1227343] +- kvm-memory-Replace-io_mem_read-write-with-memory_region_.patch [bz#1227343] +- kvm-Make-CPU-iotlb-a-structure-rather-than-a-plain-hwadd.patch [bz#1227343] +- kvm-Add-MemTxAttrs-to-the-IOTLB.patch [bz#1227343] +- kvm-exec.c-Convert-subpage-memory-ops-to-_with_attrs.patch [bz#1227343] +- kvm-exec.c-Make-address_space_rw-take-transaction-attrib.patch [bz#1227343] +- kvm-exec.c-Add-new-address_space_ld-st-functions.patch [bz#1227343] +- kvm-Switch-non-CPU-callers-from-ld-st-_phys-to-address_s.patch [bz#1227343] +- kvm-s390-virtio-sort-into-categories.patch [bz#1227343] +- kvm-s390-virtio-use-common-features.patch [bz#1227343] +- kvm-virtio-move-host_features.patch [bz#1227343] +- kvm-virtio-ccw-Don-t-advertise-VIRTIO_F_BAD_FEATURE.patch [bz#1227343] +- kvm-virtio-move-VIRTIO_F_NOTIFY_ON_EMPTY-into-core.patch [bz#1227343] +- kvm-qdev-add-64bit-properties.patch [bz#1227343] +- kvm-virtio-make-features-64bit-wide.patch [bz#1227343] +- kvm-virtio-input-const_le16-and-const_le32-not-build-tim.patch [bz#1227343] +- kvm-virtio-input-make-virtio-devices-follow-usual-naming.patch [bz#1227343] +- kvm-virtio-64bit-features-fixups.patch [bz#1227343] +- kvm-virtio-endianness-checks-for-virtio-1.0-devices.patch [bz#1227343] +- kvm-virtio-allow-virtio-1-queue-layout.patch [bz#1227343] +- kvm-virtio-disallow-late-feature-changes-for-virtio-1.patch [bz#1227343] +- kvm-virtio-allow-to-fail-setting-status.patch [bz#1227343] +- kvm-virtio-net-no-writeable-mac-for-virtio-1.patch [bz#1227343] +- kvm-virtio-net-support-longer-header.patch [bz#1227343] +- kvm-virtio-net-enable-virtio-1.0.patch [bz#1227343] +- kvm-vhost_net-add-version_1-feature.patch [bz#1227343] +- kvm-vhost-64-bit-features.patch [bz#1227343] +- kvm-linux-headers-add-virtio_pci.patch [bz#1227343] +- kvm-virtio-pci-initial-virtio-1.0-support.patch [bz#1227343] +- kvm-virtio-generation-counter-support.patch [bz#1227343] +- kvm-virtio-add-modern-config-accessors.patch [bz#1227343] +- kvm-virtio-pci-switch-to-modern-accessors-for-1.0.patch [bz#1227343] +- kvm-virtio-pci-add-flags-to-enable-disable-legacy-modern.patch [bz#1227343] +- kvm-virtio-pci-make-QEMU_VIRTIO_PCI_QUEUE_MEM_MULT-small.patch [bz#1227343] +- kvm-virtio-pci-change-document-virtio-pci-bar-layout.patch [bz#1227343] +- kvm-virtio-pci-make-modern-bar-64bit-prefetchable.patch [bz#1227343] +- kvm-virtio-pci-correctly-set-host-notifiers-for-modern-b.patch [bz#1227343] +- kvm-virtio_balloon-header-update.patch [bz#1227343] +- kvm-virtio-balloon-switch-to-virtio_add_feature.patch [bz#1227343] +- kvm-virtio-pci-add-struct-VirtIOPCIRegion-for-virtio-1-r.patch [bz#1227343] +- kvm-virtio-pci-add-virtio_pci_modern_regions_init.patch [bz#1227343] +- kvm-virtio-pci-add-virtio_pci_modern_region_map.patch [bz#1227343] +- kvm-virtio-pci-move-virtio_pci_add_mem_cap-call-to-virti.patch [bz#1227343] +- kvm-virtio-pci-move-cap-type-to-VirtIOPCIRegion.patch [bz#1227343] +- kvm-virtio-pci-drop-identical-virtio_pci_cap.patch [bz#1227343] +- kvm-virtio-pci-fill-VirtIOPCIRegions-early.patch [bz#1227343] +- kvm-pci-add-PCI_CLASS_INPUT_.patch [bz#1227343] +- kvm-virtio-input-core-code-base-class-pci.patch [bz#1227343] +- kvm-virtio-input-emulated-devices-pci.patch [bz#1227343] +- kvm-virtio-net-move-qdev-properties-into-virtio-net.c.patch [bz#1227343] +- kvm-virtio-net.h-Remove-unsed-DEFINE_VIRTIO_NET_PROPERTI.patch [bz#1227343] +- kvm-virtio-scsi-move-qdev-properties-into-virtio-scsi.c.patch [bz#1227343] +- kvm-virtio-rng-move-qdev-properties-into-virtio-rng.c.patch [bz#1227343] +- kvm-virtio-serial-bus-move-qdev-properties-into-virtio-s.patch [bz#1227343] +- kvm-virtio-9p-device-move-qdev-properties-into-virtio-9p.patch [bz#1227343] +- kvm-vhost-scsi-move-qdev-properties-into-vhost-scsi.c.patch [bz#1227343] +- kvm-virito-pci-fix-OVERRUN-problem.patch [bz#1227343] +- kvm-virtio-input-move-properties-use-virtio_instance_ini.patch [bz#1227343] +- kvm-virtio-input-evdev-passthrough.patch [bz#1227343] +- kvm-Add-MAINTAINERS-entry-for-virtio-input.patch [bz#1227343] +- kvm-virtio-input-add-input-routing-support.patch [bz#1227343] +- kvm-dataplane-fix-cross-endian-issues.patch [bz#1227343] +- kvm-aarch64-allow-enable-seccomp.patch [bz#1174861] +- kvm-aarch64-redhat-spec-enable-seccomp.patch [bz#1174861] +- kvm-rhel-Update-package-version-for-SLOF-dependency.patch [bz#1236447] +- Resolves: bz#1172478 + (add support for PCI hotplugging) +- Resolves: bz#1174861 + (use seccomp) +- Resolves: bz#1191845 + ([PowerKVM] There are some unsupported x86 devices under the output of cmds 'man qemu-kvm' and '/usr/libexec/qemu-kvm -device help') +- Resolves: bz#1207034 + (QEMU segfault when doing unaligned zero write to non-512 disk) +- Resolves: bz#1209793 + (migration: 7.1->7.2 error while loading state for instance 0x0 of device '0000:00:04.0/intel-hda') +- Resolves: bz#1217277 + (Enable KVM implementation of H_LOGICAL_CI_{LOAD,STORE}) +- Resolves: bz#1225715 + (Enable cross-endian vhost devices) +- Resolves: bz#1227343 + ([virtio-1] QEMU Virtio-1 Support) +- Resolves: bz#1236447 + (Update qemu-kvm-rhev package for new SLOF) + +* Thu Jul 02 2015 Miroslav Rezanina - rhev-2.3.0-7.el7 +- kvm-docs-update-documentation-for-memory-hot-unplug.patch [bz#1120706] +- kvm-acpi-mem-hotplug-add-acpi_memory_slot_status-to-get-.patch [bz#1120706] +- kvm-acpi-mem-hotplug-add-unplug-request-cb-for-memory-de.patch [bz#1120706] +- kvm-acpi-mem-hotplug-add-unplug-cb-for-memory-device.patch [bz#1120706] +- kvm-acpi-extend-aml_field-to-support-UpdateRule.patch [bz#1120706] +- kvm-acpi-fix-Memory-device-control-fields-register.patch [bz#1120706] +- kvm-acpi-add-hardware-implementation-for-memory-hot-unpl.patch [bz#1120706] +- kvm-qmp-event-add-event-notification-for-memory-hot-unpl.patch [bz#1120706] +- kvm-hw-acpi-aml-build-Fix-memory-leak.patch [bz#1120706] +- kvm-memory-add-memory_region_ram_resize.patch [bz#1231719] +- kvm-acpi-build-remove-dependency-from-ram_addr.h.patch [bz#1231719] +- kvm-hw-i386-Move-ACPI-header-definitions-in-an-arch-inde.patch [bz#1231719] +- kvm-hw-i386-acpi-build-move-generic-acpi-building-helper.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Make-enum-values-to-be-upper-case-.patch [bz#1231719] +- kvm-hw-arm-virt-Move-common-definitions-to-virt.h.patch [bz#1231719] +- kvm-hw-arm-virt-Record-PCIe-ranges-in-MemMapEntry-array.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Basic-framework-for-building-.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_memory32_fixed-term.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_interrupt-term.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generation-of-DSDT-table-for-.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generate-FADT-table-and-updat.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generate-MADT-table.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generate-GTDT-table.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generate-RSDT-table.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generate-RSDP-table.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Generate-MCFG-table.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Make-aml_buffer-definition-consist.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-ToUUID-macro.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_or-term.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_lnot-term.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_else-term.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_create_dword_field-term.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-aml_dword_io-term.patch [bz#1231719] +- kvm-hw-acpi-aml-build-Add-Unicode-macro.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Add-PCIe-controller-in-ACPI-D.patch [bz#1231719] +- kvm-ACPI-split-CONFIG_ACPI-into-4-pieces.patch [bz#1231719] +- kvm-hw-arm-virt-Enable-dynamic-generation-of-ACPI-v5.1-t.patch [bz#1231719] +- kvm-ACPI-Add-definitions-for-the-SPCR-table.patch [bz#1231719] +- kvm-hw-arm-virt-acpi-build-Add-SPCR-table.patch [bz#1231719] +- kvm-AArch64-Enable-ACPI.patch [bz#1231719] +- kvm-i8254-fix-out-of-bounds-memory-access-in-pit_ioport_.patch [bz#1229647] +- kvm-hw-q35-fix-floppy-controller-definition-in-ich9.patch [bz#894956] +- kvm-Migration-compat-for-pckbd.patch [bz#1215092] +- kvm-Migration-compat-for-fdc.patch [bz#1215091] +- Resolves: bz#1120706 + (Support dynamic virtual Memory deallocation - qemu-kvm) +- Resolves: bz#1215091 + (migration: 7.2->earlier; floppy compatibility) +- Resolves: bz#1215092 + (migration: 7.2->earlier: pckbd compatibility) +- Resolves: bz#1229647 + (CVE-2015-3214 qemu-kvm-rhev: qemu: i8254: out-of-bounds memory access in pit_ioport_read function [rhel-7.2]) +- Resolves: bz#1231719 + (AArch64: backport ACPI support) +- Resolves: bz#894956 + (floppy can not be recognized by Windows guest (q35)) + +* Fri Jun 26 2015 Miroslav Rezanina - rhev-2.3.0-6.el7 +- kvm-vfio-pci-Fix-error-path-sign.patch [bz#1219090] +- kvm-vfio-pci-Further-fix-BAR-size-overflow.patch [bz#1219090] +- kvm-Add-flag-for-pre-2.2-migration-compatibility.patch [bz#1215087] +- kvm-Serial-Migration-compatibility-pre-2.2-7.2.patch [bz#1215087] +- kvm-Migration-compat-for-mc146818rtc-irq_reinject_on_ack.patch [bz#1215088] +- Resolves: bz#1215087 + (migration: 7.2->earlier; serial compatibility) +- Resolves: bz#1215088 + (migration: 7.2->earlier; mc146818rtc compatibility) +- Resolves: bz#1219090 + (vfio-pci - post QEMU2.3 fixes, error sign + BAR overflow) + +* Wed Jun 24 2015 Miroslav Rezanina - rhev-2.3.0-5.el7 +- kvm-atomics-add-explicit-compiler-fence-in-__atomic-memo.patch [bz#1231335] +- kvm-pc-acpi-fix-pvpanic-for-buggy-guests.patch [bz#1221943] +- Resolves: bz#1221943 + (On_crash events didn't work when using guest's pvpanic device) +- Resolves: bz#1231335 + ([abrt] qemu-kvm: bdrv_error_action(): qemu-kvm killed by SIGABRT) + +* Mon Jun 22 2015 Miroslav Rezanina - rhev-2.3.0-4.el7 +- kvm-virtio-ccw-using-VIRTIO_NO_VECTOR-instead-of-0-for-i.patch [bz#1231610] +- kvm-virtio-ccw-sort-into-categories.patch [bz#1231610] +- kvm-virtio-ccw-change-realization-sequence.patch [bz#1231610] +- kvm-virtio-ccw-implement-device_plugged.patch [bz#1231610] +- kvm-virtio-net-fix-the-upper-bound-when-trying-to-delete.patch [bz#1231610] +- kvm-monitor-replace-the-magic-number-255-with-MAX_QUEUE_.patch [bz#1231610] +- kvm-monitor-check-return-value-of-qemu_find_net_clients_.patch [bz#1231610] +- kvm-virtio-introduce-vector-to-virtqueues-mapping.patch [bz#1231610] +- kvm-virtio-pci-speedup-MSI-X-masking-and-unmasking.patch [bz#1231610] +- kvm-pci-remove-hard-coded-bar-size-in-msix_init_exclusiv.patch [bz#1231610] +- kvm-virtio-net-adding-all-queues-in-.realize.patch [bz#1231610] +- kvm-virtio-device_plugged-can-fail.patch [bz#1231610] +- kvm-virtio-introduce-virtio_get_num_queues.patch [bz#1231610] +- kvm-virtio-ccw-introduce-ccw-specific-queue-limit.patch [bz#1231610] +- kvm-virtio-ccw-validate-the-number-of-queues-against-bus.patch [bz#1231610] +- kvm-virtio-s390-introduce-virito-s390-queue-limit.patch [bz#1231610] +- kvm-virtio-s390-introduce-virtio_s390_device_plugged.patch [bz#1231610] +- kvm-virtio-rename-VIRTIO_PCI_QUEUE_MAX-to-VIRTIO_QUEUE_M.patch [bz#1231610] +- kvm-virtio-increase-the-queue-limit-to-1024.patch [bz#1231610] +- kvm-virtio-pci-don-t-try-to-mask-or-unmask-vqs-without-n.patch [bz#1231610] +- Resolves: bz#1231610 + (Support more virtio queues) + +* Fri Jun 19 2015 Miroslav Rezanina - rhev-2.3.0-3.el7 +- kvm-vmdk-Fix-overflow-if-l1_size-is-0x20000000.patch [bz#1226809] +- kvm-Downstream-only-Add-rhel7.2.0-machine-type.patch [bz#1228574] +- kvm-spice-display-fix-segfault-in-qemu_spice_create_upda.patch [bz#1230550] +- kvm-pc-dimm-don-t-assert-if-pc-dimm-alignment-hotpluggab.patch [bz#1221425] +- kvm-Strip-brackets-from-vnc-host.patch [bz#1229073] +- kvm-qcow2-Set-MIN_L2_CACHE_SIZE-to-2.patch [bz#1226996] +- kvm-iotests-qcow2-COW-with-minimal-L2-cache-size.patch [bz#1226996] +- kvm-qcow2-Add-DEFAULT_L2_CACHE_CLUSTERS.patch [bz#1226996] +- kvm-spec-Ship-complete-QMP-documentation-files.patch [bz#1222834] +- Resolves: bz#1221425 + (qemu crash when hot-plug a memory device) +- Resolves: bz#1222834 + (We ship incomplete QMP documentation) +- Resolves: bz#1226809 + (Overflow in malloc size calculation in VMDK driver) +- Resolves: bz#1226996 + (qcow2: Fix minimum L2 cache size) +- Resolves: bz#1228574 + (Add RHEL7.2 machine type in QEMU for PPC64LE) +- Resolves: bz#1229073 + ([graphical framebuffer]Start guest failed when VNC listen on IPV6 address) +- Resolves: bz#1230550 + ([abrt] qemu-system-x86: __memcmp_sse4_1(): qemu-system-x86_64 killed by SIGSEGV) + +* Wed May 27 2015 Miroslav Rezanina - rhev-2.3.0-2.el7 +- kvm-balloon-improve-error-msg-when-adding-second-device.patch [bz#1165534] +- kvm-qmp-add-error-reason-to-the-BLOCK_IO_ERROR-event.patch [bz#1199174] +- kvm-spec-Remove-obsolete-differentiation-code.patch [bz#1122778] +- kvm-spec-Use-external-configuration-script.patch [bz#1122778] +- kvm-spec-Use-configure-options-to-prevent-default-resolu.patch [bz#1122778] +- kvm-fdc-force-the-fifo-access-to-be-in-bounds-of-the-all.patch [bz#1219272] +- Resolves: bz#1122778 + (miss "vhdx" and "iscsi" in qemu-img supported format list) +- Resolves: bz#1165534 + (balloon: improve error message when adding second device) +- Resolves: bz#1199174 + (QMP: forward port rhel-only error reason to BLOCK_IO_ERROR event) +- Resolves: bz#1219272 + (CVE-2015-3456 qemu-kvm-rhev: qemu: floppy disk controller flaw [rhel-7.2]) + +* Tue Apr 28 2015 Miroslav Rezanina - rhev-2.3.0-1.el7 +- Rebase to 2.3.0 [bz#1194151] +- kvm-misc-Add-pc-i440fx-rhel7-2-0-machine-type.patch [bz#1210050] +- kvm-misc-Add-pc-q35-rhel7-2-0-machine-type.patch [bz#1210050] +- Resolves: bz#1194151 + (Rebase to qemu 2.3) +- Resolves: bz#1210050 + (Add pc-i440fx-rhel7.2.0 machine type) + +* Thu Mar 19 2015 Miroslav Rezanina - rhev-2.2.0-8.el7 +- kvm-pc_sysfw-prevent-pflash-and-or-mis-sized-firmware-fo.patch [bz#1175099] +- kvm-build-reenable-local-builds-to-pass-enable-debug-dow.patch [] +- kvm-RPM-spec-install-dump-guest-memory.py-downstream-onl.patch [bz#1194304] +- kvm-vga-Expose-framebuffer-byteorder-as-a-QOM-property.patch [bz#1146809] +- kvm-pseries-Switch-VGA-endian-on-H_SET_MODE.patch [bz#1146809] +- kvm-Generalize-QOM-publishing-of-date-and-time-from-mc14.patch [bz#1172583] +- kvm-Add-more-VMSTATE_-_TEST-variants-for-integers.patch [bz#1171700] +- kvm-pseries-Move-sPAPR-RTC-code-into-its-own-file.patch [bz#1170132 bz#1171700 bz#1172583] +- kvm-pseries-Add-more-parameter-validation-in-RTAS-time-o.patch [bz#1170132 bz#1171700 bz#1172583] +- kvm-pseries-Add-spapr_rtc_read-helper-function.patch [bz#1170132 bz#1171700 bz#1172583] +- kvm-pseries-Make-RTAS-time-of-day-functions-respect-rtc-.patch [bz#1170132] +- kvm-pseries-Make-the-PAPR-RTC-a-qdev-device.patch [bz#1170132 bz#1171700 bz#1172583] +- kvm-pseries-Move-rtc_offset-into-RTC-device-s-state-stru.patch [bz#1171700] +- kvm-pseries-Export-RTC-time-via-QOM.patch [bz#1172583] +- kvm-pseries-Limit-PCI-host-bridge-index-value.patch [bz#1181409] +- Resolves: bz#1146809 + (Incorrect colours on virtual VGA with ppc64le guest under ppc64 host) +- Resolves: bz#1170132 + (Guest time could change with host time even specify the guest clock as "-rtc base=utc,clock=vm,...") +- Resolves: bz#1171700 + ('hwclock' in destination guest returns to base '2006-06-06' after migration) +- Resolves: bz#1172583 + ([Power KVM] Qemu monitor command don't support {"execute":"qom-get","arguments":{"path":"/machine","property":"rtc-time"}}) +- Resolves: bz#1175099 + ([migration]migration failed when configure guest with OVMF bios + machine type=rhel6.5.0) +- Resolves: bz#1181409 + (PCI pass-through device works improperly due to the PHB's index being set to a big value) +- Resolves: bz#1194304 + ([Hitachi 7.2 FEAT] Extract guest memory dump from qemu-kvm-rhev core) + +* Tue Mar 10 2015 Miroslav Rezanina - rhev-2.2.0-7.el7 +- kvm-aarch64-Add-PCI-and-VIRTIO_PCI-devices-for-AArch64.patch [bz#1200090] +- kvm-Add-specific-config-options-for-PCI-E-bridges.patch [bz#1200090] +- Resolves: bz#1200090 + (qemu-kvm-rhev (2.2.0-6) breaks ISO installation) + +* Mon Mar 02 2015 Miroslav Rezanina - rhev-2.2.0-6.el7 +- kvm-AArch64-Prune-the-devices-available-for-AArch64-gues.patch [bz#1170734] +- kvm-Give-ivshmem-its-own-config-option.patch [bz#1170734] +- kvm-aarch64-Prune-unsupported-CPU-types-for-aarch64.patch [bz#1170734] +- Resolves: bz#1170734 + (Trim qemu-kvm devices for aarch64) + +* Wed Feb 11 2015 Miroslav Rezanina - rhev-2.2.0-5.el7 +- kvm-kvm_stat-Add-aarch64-support.patch [bz#1184603] +- kvm-kvm_stat-Update-exit-reasons-to-the-latest-defintion.patch [bz#1184603] +- kvm-kvm_stat-Add-RESET-support-for-perf-event-ioctl.patch [bz#1184603] +- kvm-ignore-SIGIO-in-tests-that-use-AIO-context-aarch64-h.patch [bz#1184405] +- kvm-aio_notify-force-main-loop-wakeup-with-SIGIO-aarch64.patch [bz#1184405] +- Resolves: bz#1184405 + (lost block IO completion notification (for virtio-scsi disk) hangs main loop) +- Resolves: bz#1184603 + (enable kvm_stat support for aarch64) + +* Mon Feb 09 2015 Miroslav Rezanina - rhev-2.2.0-4.el7 +- kvm-Downstream-only-Restore-pseries-machine-alias.patch [bz#1170934] +- kvm-PPC-Fix-crash-on-spapr_tce_table_finalize.patch [bz#1170934] +- kvm-virtio_serial-Don-t-use-vser-config.max_nr_ports-int.patch [bz#1169230] +- kvm-virtio-serial-Don-t-keep-a-persistent-copy-of-config.patch [bz#1169230] +- kvm-spapr-Fix-stale-HTAB-during-live-migration-KVM.patch [bz#1168446] +- kvm-spapr-Fix-integer-overflow-during-migration-TCG.patch [bz#1168446] +- kvm-spapr-Fix-stale-HTAB-during-live-migration-TCG.patch [bz#1168446] +- Resolves: bz#1168446 + (Stale hash PTEs may be transferred during live migration of PAPR guests) +- Resolves: bz#1169230 + (QEMU core dumped when do ping-pong migration to file for LE guest) +- Resolves: bz#1170934 + (Segfault at spapr_tce_table_finalize(): QLIST_REMOVE(tcet, list)) + +* Thu Jan 22 2015 Miroslav Rezanina - rhev-2.2.0-3.el7 +- kvm-Downstream-only-arm-define-a-new-machine-type-for-RH.patch [bz#1176838] +- Resolves: bz#1176838 + (create rhelsa machine type) + +* Wed Jan 14 2015 Miroslav Rezanina - rhev-2.2.0-2.el7.next.candidate +- kvm-Update-to-qemu-kvm-rhev-2.1.2-19.el7.patch [] +- kvm-fw_cfg-remove-superfluous-blank-line.patch [bz#1169869] +- kvm-hw-arm-boot-fix-uninitialized-scalar-variable-warnin.patch [bz#1169869] +- kvm-Sort-include-qemu-typedefs.h.patch [bz#1169869] +- kvm-fw_cfg-hard-separation-between-the-MMIO-and-I-O-port.patch [bz#1169869] +- kvm-fw_cfg-move-boards-to-fw_cfg_init_io-fw_cfg_init_mem.patch [bz#1169869] +- kvm-fw_cfg_mem-max-access-size-and-region-size-are-the-s.patch [bz#1169869] +- kvm-fw_cfg_mem-flip-ctl_mem_ops-and-data_mem_ops-to-DEVI.patch [bz#1169869] +- kvm-exec-allows-8-byte-accesses-in-subpage_ops.patch [bz#1169869] +- kvm-fw_cfg_mem-introduce-the-data_width-property.patch [bz#1169869] +- kvm-fw_cfg_mem-expose-the-data_width-property-with-fw_cf.patch [bz#1169869] +- kvm-arm-add-fw_cfg-to-virt-board.patch [bz#1169869] +- kvm-hw-loader-split-out-load_image_gzipped_buffer.patch [bz#1169869] +- kvm-hw-arm-pass-pristine-kernel-image-to-guest-firmware-.patch [bz#1169869] +- kvm-hw-arm-virt-enable-passing-of-EFI-stubbed-kernel-to-.patch [bz#1169869] +- kvm-fw_cfg-fix-endianness-in-fw_cfg_data_mem_read-_write.patch [bz#1169869] +- Resolves: bz#1169869 + (add fw_cfg to mach-virt) + +* Tue Jan 13 2015 Miroslav Rezanina - rhev-2.1.2-19.el7 +- kvm-smbios-Fix-dimm-size-calculation-when-RAM-is-multipl.patch [bz#1179165] +- kvm-smbios-Don-t-report-unknown-CPU-speed-fix-SVVP-regre.patch [bz#1177127] +- Resolves: bz#1177127 + ([SVVP]smbios HCT job failed with 'Processor Max Speed cannot be Unknown' with -M pc-i440fx-rhel7.1.0) +- Resolves: bz#1179165 + ([SVVP]smbios HCT job failed with Unspecified error with -M pc-i440fx-rhel7.1.0) + +* Thu Jan 08 2015 Miroslav Rezanina - rhev-2.2.0-1.el7 +- rebase to qemu 2.2.0 + +* Thu Jan 08 2015 Miroslav Rezanina - rhev-2.1.2-18.el7 +- kvm-vl-Adjust-the-place-of-calling-mlockall-to-speedup-V.patch [bz#1173394] +- kvm-block-delete-cow-block-driver.patch [bz#1175841] +- Resolves: bz#1173394 + (numa_smaps doesn't respect bind policy with huge page) +- Resolves: bz#1175841 + (Delete cow block driver) + +* Tue Dec 16 2014 Jeff E. Nelson - rhev-2.1.2-17.el7 +- kvm-numa-Don-t-allow-memdev-on-RHEL-6-machine-types.patch [bz#1170093] +- kvm-block-allow-bdrv_unref-to-be-passed-NULL-pointers.patch [bz#1136381] +- kvm-block-vdi-use-block-layer-ops-in-vdi_create-instead-.patch [bz#1136381] +- kvm-block-use-the-standard-ret-instead-of-result.patch [bz#1136381] +- kvm-block-vpc-use-block-layer-ops-in-vpc_create-instead-.patch [bz#1136381] +- kvm-block-iotest-update-084-to-test-static-VDI-image-cre.patch [bz#1136381] +- kvm-block-remove-BLOCK_OPT_NOCOW-from-vdi_create_opts.patch [bz#1136381] +- kvm-block-remove-BLOCK_OPT_NOCOW-from-vpc_create_opts.patch [bz#1136381] +- kvm-migration-fix-parameter-validation-on-ram-load-CVE-2.patch [bz#1163079] +- kvm-qdev-monitor-fix-segmentation-fault-on-qdev_device_h.patch [bz#1169280] +- kvm-block-migration-Disable-cache-invalidate-for-incomin.patch [bz#1171552] +- kvm-acpi-Use-apic_id_limit-when-calculating-legacy-ACPI-.patch [bz#1173167] +- Resolves: bz#1136381 + (RFE: Supporting creating vdi/vpc format disk with protocols (glusterfs) for qemu-kvm-rhev-2.1.x) +- Resolves: bz#1163079 + (CVE-2014-7840 qemu-kvm-rhev: qemu: insufficient parameter validation during ram load [rhel-7.1]) +- Resolves: bz#1169280 + (Segfault while query device properties (ics, icp)) +- Resolves: bz#1170093 + (guest NUMA failed to migrate when machine is rhel6.5.0) +- Resolves: bz#1171552 + (Storage vm migration failed when running BurnInTes) +- Resolves: bz#1173167 + (Corrupted ACPI tables in some configurations using pc-i440fx-rhel7.0.0) + +* Fri Dec 05 2014 Miroslav Rezanina - rhev-2.1.2-16.el7 +- kvm-qemu-iotests-Fix-broken-test-cases.patch [bz#1169589] +- kvm-Fix-for-crash-after-migration-in-virtio-rng-on-bi-en.patch [bz#1165087] +- kvm-Downstream-only-remove-unsupported-machines-from-AAr.patch [bz#1169847] +- Resolves: bz#1165087 + (QEMU core dumped for the destination guest when do migating guest to file) +- Resolves: bz#1169589 + (test case 051 071 and 087 of qemu-iotests fail for qcow2 with qemu-kvm-rhev-2.1.2-14.el7) +- Resolves: bz#1169847 + (only support mach-virt) + +* Tue Dec 02 2014 Miroslav Rezanina - rhev-2.1.2-15.el7 +- kvm-scsi-Optimize-scsi_req_alloc.patch [bz#1141656] +- kvm-virtio-scsi-Optimize-virtio_scsi_init_req.patch [bz#1141656] +- kvm-virtio-scsi-Fix-comment-for-VirtIOSCSIReq.patch [bz#1141656] +- kvm-Downstream-only-Move-daemon-reload-to-make-sure-new-.patch [bz#1168085] +- Resolves: bz#1141656 + (Virtio-scsi: performance degradation from 1.5.3 to 2.1.0) +- Resolves: bz#1168085 + (qemu-kvm-rhev install scripts sometimes don't recognize newly installed systemd presets) + +* Thu Nov 27 2014 Miroslav Rezanina - rhev-2.1.2-14.el7 +- kvm-xhci-add-sanity-checks-to-xhci_lookup_uport.patch [bz#1161397] +- kvm-qemu-img-Allow-source-cache-mode-specification.patch [bz#1166481] +- kvm-qemu-img-Allow-cache-mode-specification-for-amend.patch [bz#1166481] +- kvm-qemu-img-fix-img_compare-flags-error-path.patch [bz#1166481] +- kvm-qemu-img-clarify-src_cache-option-documentation.patch [bz#1166481] +- kvm-qemu-img-fix-rebase-src_cache-option-documentation.patch [bz#1166481] +- Resolves: bz#1161397 + (qemu core dump when install a RHEL.7 guest(xhci) with migration) +- Resolves: bz#1166481 + (Allow qemu-img to bypass the host cache (check, compare, convert, rebase, amend)) + +* Tue Nov 25 2014 Miroslav Rezanina - rhev-2.1.2-13.el7 +- kvm-hw-pci-fixed-error-flow-in-pci_qdev_init.patch [bz#1166067] +- kvm-hw-pci-fixed-hotplug-crash-when-using-rombar-0-with-.patch [bz#1166067] +- Resolves: bz#1166067 + (qemu-kvm aborted when hot plug PCI device to guest with romfile and rombar=0) + +* Fri Nov 21 2014 Miroslav Rezanina - rhev-2.1.2-12.el7 +- kvm-migration-static-variables-will-not-be-reset-at-seco.patch [bz#1166501] +- Resolves: bz#1166501 + (Migration "expected downtime" does not refresh after reset to a new value) + +* Fri Nov 21 2014 Miroslav Rezanina - rhev-2.1.2-11.el7 +- kvm-iscsi-Refuse-to-open-as-writable-if-the-LUN-is-write.patch [bz#1160102] +- kvm-vnc-sanitize-bits_per_pixel-from-the-client.patch [bz#1157646] +- kvm-usb-host-fix-usb_host_speed_compat-tyops.patch [bz#1160504] +- kvm-block-raw-posix-Fix-disk-corruption-in-try_fiemap.patch [bz#1142331] +- kvm-block-raw-posix-use-seek_hole-ahead-of-fiemap.patch [bz#1142331] +- kvm-raw-posix-Fix-raw_co_get_block_status-after-EOF.patch [bz#1142331] +- kvm-raw-posix-raw_co_get_block_status-return-value.patch [bz#1142331] +- kvm-raw-posix-SEEK_HOLE-suffices-get-rid-of-FIEMAP.patch [bz#1142331] +- kvm-raw-posix-The-SEEK_HOLE-code-is-flawed-rewrite-it.patch [bz#1142331] +- kvm-exec-Handle-multipage-ranges-in-invalidate_and_set_d.patch [bz#1164759] +- Resolves: bz#1142331 + (qemu-img convert intermittently corrupts output images) +- Resolves: bz#1157646 + (CVE-2014-7815 qemu-kvm-rhev: qemu: vnc: insufficient bits_per_pixel from the client sanitization [rhel-7.1]) +- Resolves: bz#1160102 + (opening read-only iscsi lun as read-write should fail) +- Resolves: bz#1160504 + (guest can not show usb device after adding some usb controllers and redirdevs.) +- Resolves: bz#1164759 + (Handle multipage ranges in invalidate_and_set_dirty()) + +* Thu Nov 20 2014 Miroslav Rezanina - rhev-2.1.2-10.el7 +- kvm-pc-dimm-Don-t-check-dimm-node-when-there-is-non-NUMA.patch [bz#1150510 bz#1163735] +- kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch [bz#1146809] +- kvm-vga-Remove-remainder-of-old-conversion-cruft.patch [bz#1146809] +- kvm-vga-Separate-LE-and-BE-conversion-functions.patch [bz#1146809] +- kvm-vga-Remove-rgb_to_pixel-indirection.patch [bz#1146809] +- kvm-vga-Simplify-vga_draw_blank-a-bit.patch [bz#1146809] +- kvm-cirrus-Remove-non-32bpp-cursor-drawing.patch [bz#1146809] +- kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch [bz#1146809] +- kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch [bz#1146809] +- kvm-vga-Make-fb-endian-a-common-state-variable.patch [bz#1146809] +- kvm-vga-Add-endian-to-vmstate.patch [bz#1146809] +- kvm-vga-pci-add-qext-region-to-mmio.patch [bz#1146809] +- kvm-virtio-scsi-work-around-bug-in-old-BIOSes.patch [bz#1123812] +- kvm-Revert-Downstream-only-Add-script-to-autoload-KVM-mo.patch [bz#1158250 bz#1159706] +- kvm-Downstream-only-add-script-on-powerpc-to-configure-C.patch [bz#1158250 bz#1158251 bz#1159706] +- kvm-block-New-bdrv_nb_sectors.patch [bz#1132385] +- kvm-vmdk-Optimize-cluster-allocation.patch [bz#1132385] +- kvm-vmdk-Handle-failure-for-potentially-large-allocation.patch [bz#1132385] +- kvm-vmdk-Use-bdrv_nb_sectors-where-sectors-not-bytes-are.patch [bz#1132385] +- kvm-vmdk-fix-vmdk_parse_extents-extent_file-leaks.patch [bz#1132385] +- kvm-vmdk-fix-buf-leak-in-vmdk_parse_extents.patch [bz#1132385] +- kvm-vmdk-Fix-integer-overflow-in-offset-calculation.patch [bz#1132385] +- kvm-Revert-Build-ceph-rbd-only-for-rhev.patch [bz#1140744] +- kvm-Revert-rbd-Only-look-for-qemu-specific-copy-of-librb.patch [bz#1140744] +- kvm-Revert-rbd-link-and-load-librbd-dynamically.patch [bz#1140744] +- kvm-spec-Enable-rbd-driver-add-dependency.patch [bz#1140744] +- kvm-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch [bz#1140620] +- kvm-ide-stash-aiocb-for-flushes.patch [bz#1024599] +- kvm-ide-simplify-reset-callbacks.patch [bz#1024599] +- kvm-ide-simplify-set_inactive-callbacks.patch [bz#1024599] +- kvm-ide-simplify-async_cmd_done-callbacks.patch [bz#1024599] +- kvm-ide-simplify-start_transfer-callbacks.patch [bz#1024599] +- kvm-ide-wrap-start_dma-callback.patch [bz#1024599] +- kvm-ide-remove-wrong-setting-of-BM_STATUS_INT.patch [bz#1024599] +- kvm-ide-fold-add_status-callback-into-set_inactive.patch [bz#1024599] +- kvm-ide-move-BM_STATUS-bits-to-pci.-ch.patch [bz#1024599] +- kvm-ide-move-retry-constants-out-of-BM_STATUS_-namespace.patch [bz#1024599] +- kvm-ahci-remove-duplicate-PORT_IRQ_-constants.patch [bz#1024599] +- kvm-ide-stop-PIO-transfer-on-errors.patch [bz#1024599] +- kvm-ide-make-all-commands-go-through-cmd_done.patch [bz#1024599] +- kvm-ide-atapi-Mark-non-data-commands-as-complete.patch [bz#1024599] +- kvm-ahci-construct-PIO-Setup-FIS-for-PIO-commands.patch [bz#1024599] +- kvm-ahci-properly-shadow-the-TFD-register.patch [bz#1024599] +- kvm-ahci-Correct-PIO-D2H-FIS-responses.patch [bz#1024599] +- kvm-ahci-Update-byte-count-after-DMA-completion.patch [bz#1024599] +- kvm-ahci-Fix-byte-count-regression-for-ATAPI-PIO.patch [bz#1024599] +- kvm-ahci-Fix-SDB-FIS-Construction.patch [bz#1024599] +- kvm-vhost-user-fix-mmap-offset-calculation.patch [bz#1159710] +- Resolves: bz#1024599 + (Windows7 x86 guest with ahci backend hit BSOD when do "hibernate") +- Resolves: bz#1123812 + (Reboot guest and guest's virtio-scsi disk will be lost after forwards migration (from RHEL6.6 host to RHEL7.1 host)) +- Resolves: bz#1132385 + (qemu-img convert rate about 100k/second from qcow2/raw to vmdk format on nfs system file) +- Resolves: bz#1140620 + (Should replace "qemu-system-i386" by "/usr/libexec/qemu-kvm" in manpage of qemu-kvm for our official qemu-kvm build) +- Resolves: bz#1140744 + (Enable native support for Ceph) +- Resolves: bz#1146809 + (Incorrect colours on virtual VGA with ppc64le guest under ppc64 host) +- Resolves: bz#1150510 + (kernel ignores ACPI memory devices (PNP0C80) present at boot time) +- Resolves: bz#1158250 + (KVM modules are not autoloaded on POWER hosts) +- Resolves: bz#1158251 + (POWER KVM host starts by default with threads enabled, which prevents running guests) +- Resolves: bz#1159706 + (Need means to configure subcore mode for RHEL POWER8 hosts) +- Resolves: bz#1159710 + (vhost-user:Bad ram offset) +- Resolves: bz#1163735 + (-device pc-dimm fails to initialize on non-NUMA configs) + +* Wed Nov 19 2014 Miroslav Rezanina - rhev-2.1.2-9.el7 +- kvm-aarch64-raise-max_cpus-to-8.patch [bz#1160325] +- kvm-hw-arm-virt-add-linux-stdout-path-to-chosen-DT-node.patch [bz#1160325] +- kvm-hw-arm-virt-Provide-flash-devices-for-boot-ROMs.patch [bz#1160325] +- kvm-hw-arm-boot-load-DTB-as-a-ROM-image.patch [bz#1160325] +- kvm-hw-arm-boot-pass-an-address-limit-to-and-return-size.patch [bz#1160325] +- kvm-hw-arm-boot-load-device-tree-to-base-of-DRAM-if-no-k.patch [bz#1160325] +- kvm-hw-arm-boot-enable-DTB-support-when-booting-ELF-imag.patch [bz#1160325] +- kvm-hw-arm-virt-mark-timer-in-fdt-as-v8-compatible.patch [bz#1160325] +- kvm-hw-arm-boot-register-cpu-reset-handlers-if-using-bio.patch [bz#1160325] +- kvm-Downstream-only-Declare-ARM-kernel-support-read-only.patch [bz#1160325] +- Resolves: bz#1160325 + (arm64: support aavmf) + +* Thu Nov 13 2014 Miroslav Rezanina - rhev-2.1.2-8.el7 +- kvm-ide-Add-wwn-support-to-IDE-ATAPI-drive.patch [bz#1150820] +- kvm-exec-report-error-when-memory-hpagesize.patch [bz#1147354] +- kvm-exec-add-parameter-errp-to-gethugepagesize.patch [bz#1147354] +- kvm-block-curl-Improve-type-safety-of-s-timeout.patch [bz#1152901] +- kvm-virtio-serial-avoid-crash-when-port-has-no-name.patch [bz#1151947] +- Resolves: bz#1147354 + (Qemu core dump when boot up a guest on a non-existent hugepage path) +- Resolves: bz#1150820 + (fail to specify wwn for virtual IDE CD-ROM) +- Resolves: bz#1151947 + (virtconsole causes qemu-kvm core dump) +- Resolves: bz#1152901 + (block/curl: Fix type safety of s->timeout) + +* Thu Nov 06 2014 Miroslav Rezanina - rhev-2.1.2-7.el7 +- kvm-ac97-register-reset-via-qom.patch [bz#1141666] +- kvm-specfile-Require-glusterfs-api-3.6.patch [bz#1157329] +- kvm-smbios-Fix-assertion-on-socket-count-calculation.patch [bz#1146573] +- kvm-smbios-Encode-UUID-according-to-SMBIOS-specification.patch [bz#1152922] +- kvm-virtio-scsi-Report-error-if-num_queues-is-0-or-too-l.patch [bz#1146826] +- kvm-virtio-scsi-Fix-memory-leak-when-realize-failed.patch [bz#1146826] +- kvm-virtio-scsi-Fix-num_queue-input-validation.patch [bz#1146826] +- kvm-util-Improve-os_mem_prealloc-error-message.patch [bz#1153590] +- kvm-Downstream-only-Add-script-to-autoload-KVM-modules-o.patch [bz#1158250] +- kvm-Downstream-only-remove-uneeded-PCI-devices-for-POWER.patch [bz#1160120] +- kvm-Downstream-only-Remove-assorted-unneeded-devices-for.patch [bz#1160120] +- kvm-Downstream-only-Remove-ISA-bus-and-device-support-fo.patch [bz#1160120] +- kvm-well-defined-listing-order-for-machine-types.patch [bz#1145042] +- kvm-i386-pc-add-piix-and-q35-machtypes-to-sorting-famili.patch [bz#1145042] +- kvm-i386-pc-add-RHEL-machtypes-to-sorting-families-for-M.patch [bz#1145042] +- Resolves: bz#1141666 + (Qemu crashed if reboot guest after hot remove AC97 sound device) +- Resolves: bz#1145042 + (The output of "/usr/libexec/qemu-kvm -M ?" should be ordered.) +- Resolves: bz#1146573 + (qemu core dump when boot guest with smp(num) - rhev-2.1.2-6.el7 +- kvm-ivshmem-use-error_report.patch [bz#1104063] +- kvm-ivshmem-RHEL-only-remove-unsupported-code.patch [bz#1104063] +- kvm-ivshmem-RHEL-only-explicitly-remove-dead-code.patch [bz#1104063] +- kvm-Revert-rhel-Drop-ivshmem-device.patch [bz#1104063] +- kvm-serial-reset-state-at-startup.patch [bz#1135844] +- kvm-spice-call-qemu_spice_set_passwd-during-init.patch [bz#1140975] +- kvm-input-fix-send-key-monitor-command-release-event-ord.patch [bz#1145028 bz#1146801] +- kvm-virtio-scsi-sense-in-virtio_scsi_command_complete.patch [bz#1152830] +- Resolves: bz#1104063 + ([RHEL7.1 Feat] Enable qemu-kvm Inter VM Shared Memory (IVSHM) feature) +- Resolves: bz#1135844 + ([virtio-win]communication ports were marked with a yellow exclamation after hotplug pci-serial,pci-serial-2x,pci-serial-4x) +- Resolves: bz#1140975 + (fail to login spice session with password + expire time) +- Resolves: bz#1145028 + (send-key does not crash windows guest even when it should) +- Resolves: bz#1146801 + (sendkey: releasing order of combined keys was wrongly converse) +- Resolves: bz#1152830 + (Fix sense buffer in virtio-scsi LUN passthrough) + +* Fri Oct 24 2014 Miroslav Rezanina - rhev-2.1.2-5.el7 +- kvm-blockdev-Orphaned-drive-search.patch [bz#946993] +- kvm-blockdev-Allow-overriding-if_max_dev-property.patch [bz#946993] +- kvm-pc-vl-Add-units-per-default-bus-property.patch [bz#946993] +- kvm-ide-Update-ide_drive_get-to-be-HBA-agnostic.patch [bz#946993] +- kvm-qtest-bios-tables-Correct-Q35-command-line.patch [bz#946993] +- kvm-q35-ahci-Pick-up-cdrom-and-hda-options.patch [bz#946993] +- kvm-trace-events-drop-orphan-virtio_blk_data_plane_compl.patch [bz#1144325] +- kvm-trace-events-drop-orphan-usb_mtp_data_out.patch [bz#1144325] +- kvm-trace-events-drop-orphan-iscsi-trace-events.patch [bz#1144325] +- kvm-cleanup-trace-events.pl-Tighten-search-for-trace-eve.patch [bz#1144325] +- kvm-trace-events-Drop-unused-megasas-trace-event.patch [bz#1144325] +- kvm-trace-events-Drop-orphaned-monitor-trace-event.patch [bz#1144325] +- kvm-trace-events-Fix-comments-pointing-to-source-files.patch [bz#1144325] +- kvm-simpletrace-add-simpletrace.py-no-header-option.patch [bz#1155015] +- kvm-trace-extract-stap_escape-function-for-reuse.patch [bz#1155015] +- kvm-trace-add-tracetool-simpletrace_stap-format.patch [bz#1155015] +- kvm-trace-install-simpletrace-SystemTap-tapset.patch [bz#1155015] +- kvm-trace-install-trace-events-file.patch [bz#1155015] +- kvm-trace-add-SystemTap-init-scripts-for-simpletrace-bri.patch [bz#1155015] +- kvm-simpletrace-install-simpletrace.py.patch [bz#1155015] +- kvm-trace-add-systemtap-initscript-README-file-to-RPM.patch [bz#1155015] +- Resolves: bz#1144325 + (Can not probe "qemu.kvm.virtio_blk_data_plane_complete_request") +- Resolves: bz#1155015 + ([Fujitsu 7.1 FEAT]:QEMU: capturing trace data all the time using ftrace-based tracing) +- Resolves: bz#946993 + (Q35 does not honor -drive if=ide,... and its sugared forms -cdrom, -hda, ...) + +* Mon Oct 20 2014 Miroslav Rezanina - rhev-2.1.2-4.el7 +- kvm-seccomp-add-semctl-to-the-syscall-whitelist.patch [bz#1126704] +- kvm-dataplane-fix-virtio_blk_data_plane_create-op-blocke.patch [bz#1140001] +- kvm-block-fix-overlapping-multiwrite-requests.patch [bz#1123908] +- kvm-qemu-iotests-add-multiwrite-test-cases.patch [bz#1123908] +- Resolves: bz#1123908 + (block.c: multiwrite_merge() truncates overlapping requests) +- Resolves: bz#1126704 + (BUG: When use '-sandbox on'+'vnc'+'hda' and quit, qemu-kvm hang) +- Resolves: bz#1140001 + (data-plane hotplug should be refused to start if device is already in use (drive-mirror job)) + +* Fri Oct 10 2014 Miroslav Rezanina - rhev-2.1.2-3.el7 +- kvm-Disable-tests-for-removed-features.patch [bz#1108040] +- kvm-Disable-arm-board-types-using-lsi53c895a.patch [bz#1108040] +- kvm-libqtest-launch-QEMU-with-QEMU_AUDIO_DRV-none.patch [bz#1108040] +- kvm-Whitelist-blkdebug-driver.patch [bz#1108040] +- kvm-Turn-make-check-on.patch [bz#1108040] +- Resolves: bz#1108040 + (Enable make check for qemu-kvm-rhev 2.0 and newer) + +* Fri Oct 10 2014 Miroslav Rezanina - rhev-2.1.2-2.el7 +- kvm-RPM-spec-Add-enable-numa-to-configure-command-line.patch [bz#1076990] +- kvm-block.curl-adding-timeout-option.patch [bz#1132569] +- kvm-curl-Allow-a-cookie-or-cookies-to-be-sent-with-http-.patch [bz#1132569] +- kvm-curl-Don-t-deref-NULL-pointer-in-call-to-aio_poll.patch [bz#1132569] +- kvm-curl-Add-timeout-and-cookie-options-and-misc.-fix-RH.patch [bz#1132569] +- kvm-Introduce-cpu_clean_all_dirty.patch [bz#1143054] +- kvm-kvmclock-Ensure-proper-env-tsc-value-for-kvmclock_cu.patch [bz#1143054] +- kvm-kvmclock-Ensure-time-in-migration-never-goes-backwar.patch [bz#1143054] +- kvm-IDE-Fill-the-IDENTIFY-request-consistently.patch [bz#852348] +- kvm-ide-Add-resize-callback-to-ide-core.patch [bz#852348] +- kvm-virtio-balloon-fix-integer-overflow-in-memory-stats-.patch [bz#1140997] +- kvm-block-extend-BLOCK_IO_ERROR-event-with-nospace-indic.patch [bz#1117445] +- kvm-block-extend-BLOCK_IO_ERROR-with-reason-string.patch [bz#1117445] +- Resolves: bz#1076990 + (Enable complex memory requirements for virtual machines) +- Resolves: bz#1117445 + (QMP: extend block events with error information) +- Resolves: bz#1132569 + (RFE: Enable curl driver in qemu-kvm-rhev: https only) +- Resolves: bz#1140997 + (guest is stuck when setting balloon memory with large guest-stats-polling-interval) +- Resolves: bz#1143054 + (kvmclock: Ensure time in migration never goes backward (backport)) +- Resolves: bz#852348 + (fail to block_resize local data disk with IDE/AHCI disk_interface) + +* Fri Sep 26 2014 Miroslav Rezanina - rhev-2.1.2-1.el7 +- Rebase to qemu 2.1.2 [bz#1121609] +- Resolves: bz#1121609 + Rebase qemu-kvm-rhev to qemu 2.1.2 + +* Wed Sep 24 2014 Miroslav Rezanina - rhev-2.1.0-5.el7 +- kvm-target-i386-Reject-invalid-CPU-feature-names-on-the-.patch [bz#1055532] +- kvm-target-ppc-virtex-ml507-machine-type-should-depend-o.patch [bz#1113998] +- kvm-RHEL-only-Disable-tests-that-don-t-work-with-RHEL-bu.patch [bz#1113998] +- kvm-RHEL-onlyy-Disable-unused-ppc-machine-types.patch [bz#1113998] +- kvm-RHEL-only-Remove-unneeded-devices-from-ppc64-qemu-kv.patch [] +- kvm-RHEL-only-Replace-upstream-pseries-machine-types-wit.patch [] +- kvm-scsi-bus-prepare-scsi_req_new-for-introduction-of-pa.patch [bz#1123349] +- kvm-scsi-bus-introduce-parse_cdb-in-SCSIDeviceClass-and-.patch [bz#1123349] +- kvm-scsi-block-extract-scsi_block_is_passthrough.patch [bz#1123349] +- kvm-scsi-block-scsi-generic-implement-parse_cdb.patch [bz#1123349] +- kvm-virtio-scsi-implement-parse_cdb.patch [bz#1123349] +- kvm-exec-file_ram_alloc-print-error-when-prealloc-fails.patch [bz#1135893] +- kvm-pc-increase-maximal-VCPU-count-to-240.patch [bz#1144089] +- kvm-ssh-Enable-ssh-driver-in-qemu-kvm-rhev-RHBZ-1138359.patch [bz#1138359] +- Resolves: bz#1055532 + (QEMU should abort when invalid CPU flag name is used) +- Resolves: bz#1113998 + (RHEL Power/KVM (qemu-kvm-rhev)) +- Resolves: bz#1123349 + ([FJ7.0 Bug] SCSI command issued from KVM guest doesn't reach target device) +- Resolves: bz#1135893 + (qemu-kvm should report an error message when host's freehugepage memory < domain's memory) +- Resolves: bz#1138359 + (RFE: Enable ssh driver in qemu-kvm-rhev) +- Resolves: bz#1144089 + ([HP 7.1 FEAT] Increase qemu-kvm-rhev's VCPU limit to 240) + +* Wed Sep 17 2014 Miroslav Rezanina - rhev-2.1.0-4.el7 +- kvm-virtio-rng-add-some-trace-events.patch [bz#1129259] +- kvm-block-vhdx-add-error-check.patch [bz#1126976] +- kvm-block-VHDX-endian-fixes.patch [bz#1126976] +- kvm-qdev-monitor-include-QOM-properties-in-device-FOO-he.patch [bz#1133736] +- kvm-block-acquire-AioContext-in-qmp_block_resize.patch [bz#1136752] +- kvm-virtio-blk-allow-block_resize-with-dataplane.patch [bz#1136752] +- kvm-block-acquire-AioContext-in-do_drive_del.patch [bz#1136752] +- kvm-virtio-blk-allow-drive_del-with-dataplane.patch [bz#1136752] +- kvm-rhel-Add-rhel7.1.0-machine-types.patch [bz#1093023] +- kvm-vmstate_xhci_event-bug-compat-for-rhel7.0.0-machine-.patch [bz#1136512] +- kvm-pflash_cfi01-fixup-stale-DPRINTF-calls.patch [bz#1139706] +- kvm-pflash_cfi01-write-flash-contents-to-bdrv-on-incomin.patch [bz#1139706] +- kvm-ide-Fix-segfault-when-flushing-a-device-that-doesn-t.patch [bz#1140145] +- kvm-xhci-PCIe-endpoint-migration-compatibility-fix.patch [bz#1138579] +- kvm-rh-machine-types-xhci-PCIe-endpoint-migration-compat.patch [bz#1138579] +- Resolves: bz#1093023 + (provide RHEL-specific machine types in QEMU) +- Resolves: bz#1126976 + (VHDX image format does not work on PPC64 (Endian issues)) +- Resolves: bz#1129259 + (Add traces to virtio-rng device) +- Resolves: bz#1133736 + (qemu should provide iothread and x-data-plane properties for /usr/libexec/qemu-kvm -device virtio-blk-pci,?) +- Resolves: bz#1136512 + (rhel7.0.0 machtype compat after CVE-2014-5263 vmstate_xhci_event: fix unterminated field list) +- Resolves: bz#1136752 + (virtio-blk dataplane support for block_resize and hot unplug) +- Resolves: bz#1138579 + (Migration failed with nec-usb-xhci from RHEL7. 0 to RHEL7.1) +- Resolves: bz#1139706 + (pflash (UEFI varstore) migration shortcut for libvirt [RHEV]) +- Resolves: bz#1140145 + (qemu-kvm crashed when doing iofuzz testing) + +* Thu Aug 28 2014 Miroslav Rezanina - rhev-2.1.0-3.el7 +- kvm-Fix-pkgversion-value.patch [bz#1064742] +- kvm-virtio-serial-create-a-linked-list-of-all-active-dev.patch [bz#1003432] +- kvm-virtio-serial-search-for-duplicate-port-names-before.patch [bz#1003432] +- kvm-pc-RHEL-6-CPUID-compat-code-for-Broadwell-CPU-model.patch [bz#1111351] +- kvm-rpm-spec-build-qemu-kvm-with-lzo-and-snappy-enabled.patch [bz#1126933] +- Resolves: bz#1003432 + (qemu-kvm should not allow different virtio serial port use the same name) +- Resolves: bz#1064742 + (QMP: "query-version" doesn't include the -rhev prefix from the qemu-kvm-rhev package) +- Resolves: bz#1111351 + (RHEL-6.6 migration compatibility: CPU models) +- Resolves: bz#1126933 + ([FEAT RHEV7.1]: qemu: Support compression for dump-guest-memory command) + +* Mon Aug 18 2014 Miroslav Rezanina <> - rhev-2.1.0-2.el7 +- kvm-exit-when-no-kvm-and-vcpu-count-160.patch [bz#1076326 bz#1118665] +- kvm-Revert-Use-legacy-SMBIOS-for-rhel-machine-types.patch [bz#1118665] +- kvm-rhel-Use-SMBIOS-legacy-mode-for-machine-types-7.0.patch [bz#1118665] +- kvm-rhel-Suppress-hotplug-memory-address-space-for-machi.patch [bz#1118665] +- kvm-rhel-Fix-ACPI-table-size-for-machine-types-7.0.patch [bz#1118665] +- kvm-rhel-Fix-missing-pc-q35-rhel7.0.0-compatibility-prop.patch [bz#1118665] +- kvm-rhel-virtio-scsi-pci.any_layout-off-for-machine-type.patch [bz#1118665] +- kvm-rhel-PIIX4_PM.memory-hotplug-support-off-for-machine.patch [bz#1118665] +- kvm-rhel-apic.version-0x11-for-machine-types-7.0.patch [bz#1118665] +- kvm-rhel-nec-usb-xhci.superspeed-ports-first-off-for-mac.patch [bz#1118665] +- kvm-rhel-pci-serial.prog_if-0-for-machine-types-7.0.patch [bz#1118665] +- kvm-rhel-virtio-net-pci.guest_announce-off-for-machine-t.patch [bz#1118665] +- kvm-rhel-ICH9-LPC.memory-hotplug-support-off-for-machine.patch [bz#1118665] +- kvm-rhel-.power_controller_present-off-for-machine-types.patch [bz#1118665] +- kvm-rhel-virtio-net-pci.ctrl_guest_offloads-off-for-mach.patch [bz#1118665] +- kvm-pc-q35-rhel7.0.0-Disable-x2apic-default.patch [bz#1118665] +- Resolves: bz#1076326 + (qemu-kvm does not quit when booting guest w/ 161 vcpus and "-no-kvm") +- Resolves: bz#1118665 + (Migration: rhel7.0->rhev7.1) + +* Sat Aug 02 2014 Miroslav Rezanina - rhev-2.1.0-1.el7 +- Rebase to 2.1.0 [bz#1121609] +- Resolves: bz#1121609 + (Rebase qemu-kvm-rhev to qemu 2.1) + +* Wed Jul 09 2014 Miroslav Rezanina - rhev-2.0.0-3.el7 +- kvm-Remove-CONFIG_NE2000_ISA-from-all-config-files.patch [] +- kvm-Fix-conditional-rpmbuild.patch [] +- kvm-RHEL7-RHEV7.1-2.0-migration-compatibility.patch [bz#1085950] +- kvm-remove-superfluous-.hot_add_cpu-and-.max_cpus-initia.patch [bz#1085950] +- kvm-set-model-in-PC_RHEL6_5_COMPAT-for-qemu32-VCPU-RHEV-.patch [bz#1085950] +- kvm-Undo-Enable-x2apic-by-default-for-compatibility.patch [bz#1085950] +- kvm-qemu_loadvm_state-shadow-SeaBIOS-for-VM-incoming-fro.patch [bz#1103579] +- Resolves: bz#1085950 + (Migration/virtio-net: 7.0->vp-2.0-rc2: Mix of migration issues) +- Resolves: bz#1103579 + (fail to reboot guest after migration from RHEL6.5 host to RHEL7.0 host) + +* Fri May 30 2014 Miroslav Rezanina - rhev-2.0.0-2.el7 +- kvm-pc-add-hot_add_cpu-callback-to-all-machine-types.patch [bz#1093411] +- Resolves: bz#1093411 + (Hot unplug CPU not working for RHEL7 host) + +* Fri Apr 18 2014 Miroslav Rezanina - 2.0.0-1.el7ev +- Rebase to qemu 2.0.0 + +* Wed Apr 02 2014 Miroslav Rezanina - 1.5.3-60.el7 +- kvm-qcow2-fix-dangling-refcount-table-entry.patch [bz#1081793] +- kvm-qcow2-link-all-L2-meta-updates-in-preallocate.patch [bz#1081393] +- Resolves: bz#1081393 + (qemu-img will prompt that 'leaked clusters were found' while creating images with '-o preallocation=metadata,cluster_size<=1024') +- Resolves: bz#1081793 + (qemu-img core dumped when creating a qcow2 image base on block device(iscsi or libiscsi)) + +* Wed Mar 26 2014 Miroslav Rezanina - 1.5.3-59.el7 +- kvm-qemu-iotests-add-.-check-cloop-support.patch [bz#1066691] +- kvm-qemu-iotests-add-cloop-input-validation-tests.patch [bz#1066691] +- kvm-block-cloop-validate-block_size-header-field-CVE-201.patch [bz#1079455] +- kvm-block-cloop-prevent-offsets_size-integer-overflow-CV.patch [bz#1079320] +- kvm-block-cloop-refuse-images-with-huge-offsets-arrays-C.patch [bz#1079455] +- kvm-block-cloop-refuse-images-with-bogus-offsets-CVE-201.patch [bz#1079455] +- kvm-size-off-by-one.patch [bz#1066691] +- kvm-qemu-iotests-Support-for-bochs-format.patch [bz#1066691] +- kvm-bochs-Unify-header-structs-and-make-them-QEMU_PACKED.patch [bz#1066691] +- kvm-bochs-Use-unsigned-variables-for-offsets-and-sizes-C.patch [bz#1079339] +- kvm-bochs-Check-catalog_size-header-field-CVE-2014-0143.patch [bz#1079320] +- kvm-bochs-Check-extent_size-header-field-CVE-2014-0142.patch [bz#1079315] +- kvm-bochs-Fix-bitmap-offset-calculation.patch [bz#1066691] +- kvm-vpc-vhd-add-bounds-check-for-max_table_entries-and-b.patch [bz#1079455] +- kvm-vpc-Validate-block-size-CVE-2014-0142.patch [bz#1079315] +- kvm-vdi-add-bounds-checks-for-blocks_in_image-and-disk_s.patch [bz#1079455] +- kvm-vhdx-Bounds-checking-for-block_size-and-logical_sect.patch [bz#1079346] +- kvm-curl-check-data-size-before-memcpy-to-local-buffer.-.patch [bz#1079455] +- kvm-qcow2-Check-header_length-CVE-2014-0144.patch [bz#1079455] +- kvm-qcow2-Check-backing_file_offset-CVE-2014-0144.patch [bz#1079455] +- kvm-qcow2-Check-refcount-table-size-CVE-2014-0144.patch [bz#1079455] +- kvm-qcow2-Validate-refcount-table-offset.patch [bz#1066691] +- kvm-qcow2-Validate-snapshot-table-offset-size-CVE-2014-0.patch [bz#1079455] +- kvm-qcow2-Validate-active-L1-table-offset-and-size-CVE-2.patch [bz#1079455] +- kvm-qcow2-Fix-backing-file-name-length-check.patch [bz#1066691] +- kvm-qcow2-Don-t-rely-on-free_cluster_index-in-alloc_refc.patch [bz#1079339] +- kvm-qcow2-Avoid-integer-overflow-in-get_refcount-CVE-201.patch [bz#1079320] +- kvm-qcow2-Check-new-refcount-table-size-on-growth.patch [bz#1066691] +- kvm-qcow2-Fix-types-in-qcow2_alloc_clusters-and-alloc_cl.patch [bz#1066691] +- kvm-qcow2-Protect-against-some-integer-overflows-in-bdrv.patch [bz#1066691] +- kvm-qcow2-Fix-new-L1-table-size-check-CVE-2014-0143.patch [bz#1079320] +- kvm-dmg-coding-style-and-indentation-cleanup.patch [bz#1066691] +- kvm-dmg-prevent-out-of-bounds-array-access-on-terminator.patch [bz#1066691] +- kvm-dmg-drop-broken-bdrv_pread-loop.patch [bz#1066691] +- kvm-dmg-use-appropriate-types-when-reading-chunks.patch [bz#1066691] +- kvm-dmg-sanitize-chunk-length-and-sectorcount-CVE-2014-0.patch [bz#1079325] +- kvm-dmg-use-uint64_t-consistently-for-sectors-and-length.patch [bz#1066691] +- kvm-dmg-prevent-chunk-buffer-overflow-CVE-2014-0145.patch [bz#1079325] +- kvm-block-vdi-bounds-check-qemu-io-tests.patch [bz#1066691] +- kvm-block-Limit-request-size-CVE-2014-0143.patch [bz#1079320] +- kvm-qcow2-Fix-copy_sectors-with-VM-state.patch [bz#1066691] +- kvm-qcow2-Fix-NULL-dereference-in-qcow2_open-error-path-.patch [bz#1079333] +- kvm-qcow2-Fix-L1-allocation-size-in-qcow2_snapshot_load_.patch [bz#1079325] +- kvm-qcow2-Check-maximum-L1-size-in-qcow2_snapshot_load_t.patch [bz#1079320] +- kvm-qcow2-Limit-snapshot-table-size.patch [bz#1066691] +- kvm-parallels-Fix-catalog-size-integer-overflow-CVE-2014.patch [bz#1079320] +- kvm-parallels-Sanity-check-for-s-tracks-CVE-2014-0142.patch [bz#1079315] +- kvm-fix-machine-check-propagation.patch [bz#740107] +- Resolves: bz#1066691 + (qemu-kvm: include leftover patches from block layer security audit) +- Resolves: bz#1079315 + (CVE-2014-0142 qemu-kvm: qemu: crash by possible division by zero [rhel-7.0]) +- Resolves: bz#1079320 + (CVE-2014-0143 qemu-kvm: Qemu: block: multiple integer overflow flaws [rhel-7.0]) +- Resolves: bz#1079325 + (CVE-2014-0145 qemu-kvm: Qemu: prevent possible buffer overflows [rhel-7.0]) +- Resolves: bz#1079333 + (CVE-2014-0146 qemu-kvm: Qemu: qcow2: NULL dereference in qcow2_open() error path [rhel-7.0]) +- Resolves: bz#1079339 + (CVE-2014-0147 qemu-kvm: Qemu: block: possible crash due signed types or logic error [rhel-7.0]) +- Resolves: bz#1079346 + (CVE-2014-0148 qemu-kvm: Qemu: vhdx: bounds checking for block_size and logical_sector_size [rhel-7.0]) +- Resolves: bz#1079455 + (CVE-2014-0144 qemu-kvm: Qemu: block: missing input validation [rhel-7.0]) +- Resolves: bz#740107 + ([Hitachi 7.0 FEAT] KVM: MCA Recovery for KVM guest OS memory) + +* Wed Mar 26 2014 Miroslav Rezanina - 1.5.3-58.el7 +- kvm-pc-Use-cpu64-rhel6-CPU-model-by-default-on-rhel6-mac.patch [bz#1080170] +- kvm-target-i386-Copy-cpu64-rhel6-definition-into-qemu64.patch [bz#1078607 bz#1080170] +- Resolves: bz#1080170 + (intel 82576 VF not work in windows 2008 x86 - Code 12 [TestOnly]) +- Resolves: bz#1080170 + (Default CPU model for rhel6.* machine-types is different from RHEL-6) + +* Fri Mar 21 2014 Miroslav Rezanina - 1.5.3-57.el7 +- kvm-virtio-net-fix-guest-triggerable-buffer-overrun.patch [bz#1078308] +- Resolves: bz#1078308 + (EMBARGOED CVE-2014-0150 qemu: virtio-net: fix guest-triggerable buffer overrun [rhel-7.0]) + +* Fri Mar 21 2014 Miroslav Rezanina - 1.5.3-56.el7 +- kvm-configure-Fix-bugs-preventing-Ceph-inclusion.patch [bz#1078809] +- Resolves: bz#1078809 + (can not boot qemu-kvm-rhev with rbd image) + +* Wed Mar 19 2014 Miroslav Rezanina - 1.5.3-55.el7 +- kvm-scsi-Change-scsi-sense-buf-size-to-252.patch [bz#1058173] +- kvm-scsi-Fix-migration-of-scsi-sense-data.patch [bz#1058173] +- Resolves: bz#1058173 + (qemu-kvm core dump booting guest with scsi-generic disk attached when using built-in iscsi driver) + +* Wed Mar 19 2014 Miroslav Rezanina - 1.5.3-54.el7 +- kvm-qdev-monitor-Set-properties-after-parent-is-assigned.patch [bz#1046248] +- kvm-block-Update-image-size-in-bdrv_invalidate_cache.patch [bz#1048575] +- kvm-qcow2-Keep-option-in-qcow2_invalidate_cache.patch [bz#1048575] +- kvm-qcow2-Check-bs-drv-in-copy_sectors.patch [bz#1048575] +- kvm-block-bs-drv-may-be-NULL-in-bdrv_debug_resume.patch [bz#1048575] +- kvm-iotests-Test-corruption-during-COW-request.patch [bz#1048575] +- Resolves: bz#1046248 + (qemu-kvm crash when send "info qtree" after hot plug a device with invalid addr) +- Resolves: bz#1048575 + (Segmentation fault occurs after migrate guest(use scsi disk and add stress) to des machine) + +* Wed Mar 12 2014 Miroslav Rezanina - 1.5.3-53.el7 +- kvm-dataplane-Fix-startup-race.patch [bz#1069541] +- kvm-QMP-Relax-__com.redhat_drive_add-parameter-checking.patch [bz#1057471] +- kvm-all-exit-in-case-max-vcpus-exceeded.patch [bz#993429] +- kvm-block-gluster-code-movements-state-storage-changes.patch [bz#1031526] +- kvm-block-gluster-add-reopen-support.patch [bz#1031526] +- kvm-virtio-net-add-feature-bit-for-any-header-s-g.patch [bz#990989] +- kvm-spec-Add-README.rhel6-gpxe-source.patch [bz#1073774] +- kvm-pc-Add-RHEL6-e1000-gPXE-image.patch [bz#1073774] +- kvm-loader-rename-in_ram-has_mr.patch [bz#1064018] +- kvm-pc-avoid-duplicate-names-for-ROM-MRs.patch [bz#1064018] +- kvm-qemu-img-convert-Fix-progress-output.patch [bz#1073728] +- kvm-qemu-iotests-Test-progress-output-for-conversion.patch [bz#1073728] +- kvm-iscsi-Use-bs-sg-for-everything-else-than-disks.patch [bz#1067784] +- kvm-block-Fix-bs-request_alignment-assertion-for-bs-sg-1.patch [bz#1067784] +- kvm-qemu_file-use-fwrite-correctly.patch [bz#1005103] +- kvm-qemu_file-Fix-mismerge-of-use-fwrite-correctly.patch [bz#1005103] +- Resolves: bz#1005103 + (Migration should fail when migrate guest offline to a file which is specified to a readonly directory.) +- Resolves: bz#1031526 + (Can not commit snapshot when disk is using glusterfs:native backend) +- Resolves: bz#1057471 + (fail to do hot-plug with "discard = on" with "Invalid parameter 'discard'" error) +- Resolves: bz#1064018 + (abort from conflicting genroms) +- Resolves: bz#1067784 + (qemu-kvm: block.c:850: bdrv_open_common: Assertion `bs->request_alignment != 0' failed. Aborted (core dumped)) +- Resolves: bz#1069541 + (Segmentation fault when boot guest with dataplane=on) +- Resolves: bz#1073728 + (progress bar doesn't display when converting with -p) +- Resolves: bz#1073774 + (e1000 ROM cause migrate fail from RHEL6.5 host to RHEL7.0 host) +- Resolves: bz#990989 + (backport inline header virtio-net optimization) +- Resolves: bz#993429 + (kvm: test maximum number of vcpus supported (rhel7)) + +* Wed Mar 05 2014 Miroslav Rezanina - 1.5.3-52.el7 +- kvm-target-i386-Move-hyperv_-static-globals-to-X86CPU.patch [bz#1004773] +- kvm-Fix-uninitialized-cpuid_data.patch [bz#1057173] +- kvm-fix-coexistence-of-KVM-and-Hyper-V-leaves.patch [bz#1004773] +- kvm-make-availability-of-Hyper-V-enlightenments-depe.patch [bz#1004773] +- kvm-make-hyperv-hypercall-and-guest-os-id-MSRs-migra.patch [bz#1004773] +- kvm-make-hyperv-vapic-assist-page-migratable.patch [bz#1004773] +- kvm-target-i386-Convert-hv_relaxed-to-static-property.patch [bz#1057173] +- kvm-target-i386-Convert-hv_vapic-to-static-property.patch [bz#1057173] +- kvm-target-i386-Convert-hv_spinlocks-to-static-property.patch [bz#1057173] +- kvm-target-i386-Convert-check-and-enforce-to-static-prop.patch [bz#1004773] +- kvm-target-i386-Cleanup-foo-feature-handling.patch [bz#1057173] +- kvm-add-support-for-hyper-v-timers.patch [bz#1057173] +- Resolves: bz#1004773 + (Hyper-V guest OS id and hypercall MSRs not migrated) +- Resolves: bz#1057173 + (KVM Hyper-V Enlightenment - New feature - hv-time (QEMU)) + +* Wed Mar 05 2014 Miroslav Rezanina - 1.5.3-51.el7 +- kvm-qmp-access-the-local-QemuOptsLists-for-drive-option.patch [bz#1026184] +- kvm-qxl-add-sanity-check.patch [bz#751937] +- kvm-Fix-two-XBZRLE-corruption-issues.patch [bz#1063417] +- kvm-qdev-monitor-set-DeviceState-opts-before-calling-rea.patch [bz#1037956] +- kvm-vfio-blacklist-loading-of-unstable-roms.patch [bz#1037956] +- kvm-block-Set-block-filename-sizes-to-PATH_MAX-instead-o.patch [bz#1072339] +- Resolves: bz#1026184 + (QMP: querying -drive option returns a NULL parameter list) +- Resolves: bz#1037956 + (bnx2x: boot one guest to do vfio-pci with all PFs assigned in same group meet QEMU segmentation fault (Broadcom BCM57810 card)) +- Resolves: bz#1063417 + (google stressapptest vs Migration) +- Resolves: bz#1072339 + (RHEV: Cannot start VMs that have more than 23 snapshots.) +- Resolves: bz#751937 + (qxl triggers assert during iofuzz test) + +* Wed Feb 26 2014 Miroslav Rezanina - 1.5.3-50.el7 +- kvm-mempath-prefault-fix-off-by-one-error.patch [bz#1069039] +- kvm-qemu-option-has_help_option-and-is_valid_option_list.patch [bz#1065873] +- kvm-qemu-img-create-Support-multiple-o-options.patch [bz#1065873] +- kvm-qemu-img-convert-Support-multiple-o-options.patch [bz#1065873] +- kvm-qemu-img-amend-Support-multiple-o-options.patch [bz#1065873] +- kvm-qemu-img-Allow-o-help-with-incomplete-argument-list.patch [bz#1065873] +- kvm-qemu-iotests-Check-qemu-img-command-line-parsing.patch [bz#1065873] +- Resolves: bz#1065873 + (qemu-img silently ignores options with multiple -o parameters) +- Resolves: bz#1069039 + (-mem-prealloc option behaviour is opposite to expected) + +* Wed Feb 19 2014 Miroslav Rezanina - 1.5.3-49.el7 +- kvm-xhci-add-support-for-suspend-resume.patch [bz#1012365] +- kvm-qcow2-remove-n_start-and-n_end-of-qcow2_alloc_cluste.patch [bz#1049176] +- kvm-qcow2-fix-offset-overflow-in-qcow2_alloc_clusters_at.patch [bz#1049176] +- kvm-qcow2-check-for-NULL-l2meta.patch [bz#1055848] +- kvm-qemu-iotests-add-test-for-qcow2-preallocation-with-d.patch [bz#1055848] +- Resolves: bz#1012365 + (xhci usb storage lost in guest after wakeup from S3) +- Resolves: bz#1049176 + (qemu-img core dump when using "-o preallocation=metadata,cluster_size=2048k" to create image of libiscsi lun) +- Resolves: bz#1055848 + (qemu-img core dumped when cluster size is larger than the default value with opreallocation=metadata specified) + +* Mon Feb 17 2014 Miroslav Rezanina - 1.5.3-48.el7 +- kvm-spec-disable-qom-cast-debug.patch [bz#1063942] +- kvm-fix-guest-physical-bits-to-match-host-to-go-beyond-1.patch [bz#989677] +- kvm-monitor-Cleanup-mon-outbuf-on-write-error.patch [bz#1065225] +- Resolves: bz#1063942 + (configure qemu-kvm with --disable-qom-cast-debug) +- Resolves: bz#1065225 + (QMP socket breaks on unexpected close) +- Resolves: bz#989677 + ([HP 7.0 FEAT]: Increase KVM guest supported memory to 4TiB) + +* Wed Feb 12 2014 Miroslav Rezanina - 1.5.3-47.el7 +- kvm-seccomp-add-mkdir-and-fchmod-to-the-whitelist.patch [bz#1026314] +- kvm-seccomp-add-some-basic-shared-memory-syscalls-to-the.patch [bz#1026314] +- kvm-scsi-Support-TEST-UNIT-READY-in-the-dummy-LUN0.patch [bz#1004143] +- kvm-usb-add-vendor-request-defines.patch [bz#1039530] +- kvm-usb-move-usb_-hi-lo-helpers-to-header-file.patch [bz#1039530] +- kvm-usb-add-support-for-microsoft-os-descriptors.patch [bz#1039530] +- kvm-usb-add-microsoft-os-descriptors-compat-property.patch [bz#1039530] +- kvm-usb-hid-add-microsoft-os-descriptor-support.patch [bz#1039530] +- kvm-configure-add-option-to-disable-fstack-protect.patch [bz#1044182] +- kvm-exec-always-use-MADV_DONTFORK.patch [bz#1004197] +- kvm-pc-Save-size-of-RAM-below-4GB.patch [bz#1048080] +- kvm-acpi-Fix-PCI-hole-handling-on-build_srat.patch [bz#1048080] +- kvm-Add-check-for-cache-size-smaller-than-page-size.patch [bz#1017096] +- kvm-XBZRLE-cache-size-should-not-be-larger-than-guest-me.patch [bz#1047448] +- kvm-Don-t-abort-on-out-of-memory-when-creating-page-cach.patch [bz#1047448] +- kvm-Don-t-abort-on-memory-allocation-error.patch [bz#1047448] +- kvm-Set-xbzrle-buffers-to-NULL-after-freeing-them-to-avo.patch [bz#1038540] +- kvm-migration-fix-free-XBZRLE-decoded_buf-wrong.patch [bz#1038540] +- kvm-block-resize-backing-file-image-during-offline-commi.patch [bz#1047254] +- kvm-block-resize-backing-image-during-active-layer-commi.patch [bz#1047254] +- kvm-block-update-block-commit-documentation-regarding-im.patch [bz#1047254] +- kvm-block-Fix-bdrv_commit-return-value.patch [bz#1047254] +- kvm-block-remove-QED-.bdrv_make_empty-implementation.patch [bz#1047254] +- kvm-block-remove-qcow2-.bdrv_make_empty-implementation.patch [bz#1047254] +- kvm-qemu-progress-Drop-unused-include.patch [bz#997878] +- kvm-qemu-progress-Fix-progress-printing-on-SIGUSR1.patch [bz#997878] +- kvm-Documentation-qemu-img-Mention-SIGUSR1-progress-repo.patch [bz#997878] +- Resolves: bz#1004143 + ("test unit ready failed" on LUN 0 delays boot when a virtio-scsi target does not have any disk on LUN 0) +- Resolves: bz#1004197 + (Cannot hot-plug nic in windows VM when the vmem is larger) +- Resolves: bz#1017096 + (Fail to migrate while the size of migrate-compcache less then 4096) +- Resolves: bz#1026314 + (qemu-kvm hang when use '-sandbox on'+'vnc'+'hda') +- Resolves: bz#1038540 + (qemu-kvm aborted while cancel migration then restart it (with page delta compression)) +- Resolves: bz#1039530 + (add support for microsoft os descriptors) +- Resolves: bz#1044182 + (Relax qemu-kvm stack protection to -fstack-protector-strong) +- Resolves: bz#1047254 + (qemu-img failed to commit image) +- Resolves: bz#1047448 + (qemu-kvm core dump in src host when do migration with "migrate_set_capability xbzrle on and migrate_set_cache_size 10000G") +- Resolves: bz#1048080 + (Qemu-kvm NUMA emulation failed) +- Resolves: bz#997878 + (Kill -SIGUSR1 `pidof qemu-img convert` can not get progress of qemu-img) + +* Wed Feb 12 2014 Miroslav Rezanina - 1.5.3-46.el7 +- kvm-block-fix-backing-file-segfault.patch [bz#748906] +- kvm-block-Move-initialisation-of-BlockLimits-to-bdrv_ref.patch [bz#748906] +- kvm-raw-Fix-BlockLimits-passthrough.patch [bz#748906] +- kvm-block-Inherit-opt_transfer_length.patch [bz#748906] +- kvm-block-Update-BlockLimits-when-they-might-have-change.patch [bz#748906] +- kvm-qemu_memalign-Allow-small-alignments.patch [bz#748906] +- kvm-block-Detect-unaligned-length-in-bdrv_qiov_is_aligne.patch [bz#748906] +- kvm-block-Don-t-use-guest-sector-size-for-qemu_blockalig.patch [bz#748906] +- kvm-block-rename-buffer_alignment-to-guest_block_size.patch [bz#748906] +- kvm-raw-Probe-required-direct-I-O-alignment.patch [bz#748906] +- kvm-block-Introduce-bdrv_aligned_preadv.patch [bz#748906] +- kvm-block-Introduce-bdrv_co_do_preadv.patch [bz#748906] +- kvm-block-Introduce-bdrv_aligned_pwritev.patch [bz#748906] +- kvm-block-write-Handle-COR-dependency-after-I-O-throttli.patch [bz#748906] +- kvm-block-Introduce-bdrv_co_do_pwritev.patch [bz#748906] +- kvm-block-Switch-BdrvTrackedRequest-to-byte-granularity.patch [bz#748906] +- kvm-block-Allow-waiting-for-overlapping-requests-between.patch [bz#748906] +- kvm-block-use-DIV_ROUND_UP-in-bdrv_co_do_readv.patch [bz#748906] +- kvm-block-Make-zero-after-EOF-work-with-larger-alignment.patch [bz#748906] +- kvm-block-Generalise-and-optimise-COR-serialisation.patch [bz#748906] +- kvm-block-Make-overlap-range-for-serialisation-dynamic.patch [bz#748906] +- kvm-block-Fix-32-bit-truncation-in-mark_request_serialis.patch [bz#748906] +- kvm-block-Allow-wait_serialising_requests-at-any-point.patch [bz#748906] +- kvm-block-Align-requests-in-bdrv_co_do_pwritev.patch [bz#748906] +- kvm-lock-Fix-memory-leaks-in-bdrv_co_do_pwritev.patch [bz#748906] +- kvm-block-Assert-serialisation-assumptions-in-pwritev.patch [bz#748906] +- kvm-block-Change-coroutine-wrapper-to-byte-granularity.patch [bz#748906] +- kvm-block-Make-bdrv_pread-a-bdrv_prwv_co-wrapper.patch [bz#748906] +- kvm-block-Make-bdrv_pwrite-a-bdrv_prwv_co-wrapper.patch [bz#748906] +- kvm-iscsi-Set-bs-request_alignment.patch [bz#748906] +- kvm-blkdebug-Make-required-alignment-configurable.patch [bz#748906] +- kvm-blkdebug-Don-t-leak-bs-file-on-failure.patch [bz#748906] +- kvm-qemu-io-New-command-sleep.patch [bz#748906] +- kvm-qemu-iotests-Filter-out-qemu-io-prompt.patch [bz#748906] +- kvm-qemu-iotests-Test-pwritev-RMW-logic.patch [bz#748906] +- kvm-block-bdrv_aligned_pwritev-Assert-overlap-range.patch [bz#748906] +- kvm-block-Don-t-call-ROUND_UP-with-negative-values.patch [bz#748906] +- Resolves: bz#748906 + (qemu fails on disk with 4k sectors and cache=off) + +* Wed Feb 05 2014 Miroslav Rezanina - 1.5.3-45.el7 +- kvm-vfio-pci-Fail-initfn-on-DMA-mapping-errors.patch [bz#1044815] +- kvm-vfio-Destroy-memory-regions.patch [bz#1052030] +- kvm-docs-qcow2-compat-1.1-is-now-the-default.patch [bz#1048092] +- kvm-hda-codec-disable-streams-on-reset.patch [bz#947812] +- kvm-QEMUBH-make-AioContext-s-bh-re-entrant.patch [bz#1009297] +- kvm-qxl-replace-pipe-signaling-with-bottom-half.patch [bz#1009297] +- Resolves: bz#1009297 + (RHEL7.0 guest gui can not be used in dest host after migration) +- Resolves: bz#1044815 + (vfio initfn succeeds even if IOMMU mappings fail) +- Resolves: bz#1048092 + (manpage of qemu-img contains error statement about compat option) +- Resolves: bz#1052030 + (src qemu-kvm core dump after hotplug/unhotplug GPU device and do local migration) +- Resolves: bz#947812 + (There's a shot voice after 'system_reset' during playing music inside rhel6 guest w/ intel-hda device) + +* Wed Jan 29 2014 Miroslav Rezanina - 1.5.3-44.el7 +- kvm-Partially-revert-rhel-Drop-cfi.pflash01-and-isa-ide-.patch [bz#1032346] +- kvm-Revert-pc-Disable-the-use-flash-device-for-BIOS-unle.patch [bz#1032346] +- kvm-memory-Replace-open-coded-memory_region_is_romd.patch [bz#1032346] +- kvm-memory-Rename-readable-flag-to-romd_mode.patch [bz#1032346] +- kvm-isapc-Fix-non-KVM-qemu-boot-read-write-memory-for-is.patch [bz#1032346] +- kvm-add-kvm_readonly_mem_enabled.patch [bz#1032346] +- kvm-support-using-KVM_MEM_READONLY-flag-for-regions.patch [bz#1032346] +- kvm-pc_sysfw-allow-flash-pflash-memory-to-be-used-with-K.patch [bz#1032346] +- kvm-fix-double-free-the-memslot-in-kvm_set_phys_mem.patch [bz#1032346] +- kvm-sysfw-remove-read-only-pc_sysfw_flash_vs_rom_bug_com.patch [bz#1032346] +- kvm-pc_sysfw-remove-the-rom_only-property.patch [bz#1032346] +- kvm-pc_sysfw-do-not-make-it-a-device-anymore.patch [bz#1032346] +- kvm-hw-i386-pc_sysfw-support-two-flash-drives.patch [bz#1032346] +- kvm-i440fx-test-qtest_start-should-be-paired-with-qtest_.patch [bz#1032346] +- kvm-i440fx-test-give-each-GTest-case-its-own-qtest.patch [bz#1032346] +- kvm-i440fx-test-generate-temporary-firmware-blob.patch [bz#1032346] +- kvm-i440fx-test-verify-firmware-under-4G-and-1M-both-bio.patch [bz#1032346] +- kvm-piix-fix-32bit-pci-hole.patch [bz#1032346] +- kvm-qapi-Add-backing-to-BlockStats.patch [bz#1041564] +- kvm-pc-Disable-RDTSCP-unconditionally-on-rhel6.-machine-.patch [bz#918907] +- kvm-pc-Disable-RDTSCP-on-AMD-CPU-models.patch [bz#1056428 bz#874400] +- kvm-block-add-.bdrv_reopen_prepare-stub-for-iscsi.patch [bz#1030301] +- Resolves: bz#1030301 + (qemu-img can not merge live snapshot to backing file(r/w backing file via libiscsi)) +- Resolves: bz#1032346 + (basic OVMF support (non-volatile UEFI variables in flash, and fixup for ACPI tables)) +- Resolves: bz#1041564 + ([NFR] qemu: Returning the watermark for all the images opened for writing) +- Resolves: bz#1056428 + ("rdtscp" flag defined on Opteron_G5 model and cann't be exposed to guest) +- Resolves: bz#874400 + ("rdtscp" flag defined on Opteron_G5 model and cann't be exposed to guest) +- Resolves: bz#918907 + (provide backwards-compatible RHEL specific machine types in QEMU - CPU features) + +* Mon Jan 27 2014 Miroslav Rezanina - 1.5.3-43.el7 +- kvm-piix-gigabyte-alignment-for-ram.patch [bz#1026548] +- kvm-pc_piix-document-gigabyte_align.patch [bz#1026548] +- kvm-q35-gigabyle-alignment-for-ram.patch [bz#1026548] +- kvm-virtio-bus-remove-vdev-field.patch [bz#983344] +- kvm-virtio-pci-remove-vdev-field.patch [bz#983344] +- kvm-virtio-bus-cleanup-plug-unplug-interface.patch [bz#983344] +- kvm-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch [bz#983344] +- kvm-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch [bz#983344] +- kvm-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch [bz#983344] +- kvm-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch [bz#983344] +- kvm-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch [bz#983344] +- kvm-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch [bz#983344] +- kvm-virtio-pci-add-device_unplugged-callback.patch [bz#983344] +- kvm-block-use-correct-filename-for-error-report.patch [bz#1051438] +- Resolves: bz#1026548 + (i386: pc: align gpa<->hpa on 1GB boundary) +- Resolves: bz#1051438 + (Error message contains garbled characters when unable to open image due to bad permissions (permission denied).) +- Resolves: bz#983344 + (QEMU core dump and host will reboot when do hot-unplug a virtio-blk disk which use the switch behind switch) + +* Fri Jan 24 2014 Daniel Mach - 10:1.5.3-42 +- Mass rebuild 2014-01-24 + +* Wed Jan 22 2014 Miroslav Rezanina - 1.5.3-41.el7 +- kvm-help-add-id-suboption-to-iscsi.patch [bz#1019221] +- kvm-scsi-disk-add-UNMAP-limits-to-block-limits-VPD-page.patch [bz#1037503] +- kvm-qdev-Fix-32-bit-compilation-in-print_size.patch [bz#1034876] +- kvm-qdev-Use-clz-in-print_size.patch [bz#1034876] +- Resolves: bz#1019221 + (Iscsi miss id sub-option in help output) +- Resolves: bz#1034876 + (export acpi tables to guests) +- Resolves: bz#1037503 + (fix thin provisioning support for block device backends) + +* Wed Jan 22 2014 Miroslav Rezanina - 1.5.3-40.el7 +- kvm-avoid-a-bogus-COMPLETED-CANCELLED-transition.patch [bz#1053699] +- kvm-introduce-MIG_STATE_CANCELLING-state.patch [bz#1053699] +- kvm-vvfat-use-bdrv_new-to-allocate-BlockDriverState.patch [bz#1041301] +- kvm-block-implement-reference-count-for-BlockDriverState.patch [bz#1041301] +- kvm-block-make-bdrv_delete-static.patch [bz#1041301] +- kvm-migration-omit-drive-ref-as-we-have-bdrv_ref-now.patch [bz#1041301] +- kvm-xen_disk-simplify-blk_disconnect-with-refcnt.patch [bz#1041301] +- kvm-nbd-use-BlockDriverState-refcnt.patch [bz#1041301] +- kvm-block-use-BDS-ref-for-block-jobs.patch [bz#1041301] +- kvm-block-Make-BlockJobTypes-const.patch [bz#1041301] +- kvm-blockjob-rename-BlockJobType-to-BlockJobDriver.patch [bz#1041301] +- kvm-qapi-Introduce-enum-BlockJobType.patch [bz#1041301] +- kvm-qapi-make-use-of-new-BlockJobType.patch [bz#1041301] +- kvm-mirror-Don-t-close-target.patch [bz#1041301] +- kvm-mirror-Move-base-to-MirrorBlockJob.patch [bz#1041301] +- kvm-block-Add-commit_active_start.patch [bz#1041301] +- kvm-commit-Support-commit-active-layer.patch [bz#1041301] +- kvm-qemu-iotests-prefill-some-data-to-test-image.patch [bz#1041301] +- kvm-qemu-iotests-Update-test-cases-for-commit-active.patch [bz#1041301] +- kvm-commit-Remove-unused-check.patch [bz#1041301] +- kvm-blockdev-use-bdrv_getlength-in-qmp_drive_mirror.patch [bz#921890] +- kvm-qemu-iotests-make-assert_no_active_block_jobs-common.patch [bz#921890] +- kvm-block-drive-mirror-Check-for-NULL-backing_hd.patch [bz#921890] +- kvm-qemu-iotests-Extend-041-for-unbacked-mirroring.patch [bz#921890] +- kvm-qapi-schema-Update-description-for-NewImageMode.patch [bz#921890] +- kvm-block-drive-mirror-Reuse-backing-HD-for-sync-none.patch [bz#921890] +- kvm-qemu-iotests-Fix-test-041.patch [bz#921890] +- kvm-scsi-bus-fix-transfer-length-and-direction-for-VERIF.patch [bz#1035644] +- kvm-scsi-disk-fix-VERIFY-emulation.patch [bz#1035644] +- kvm-block-ensure-bdrv_drain_all-works-during-bdrv_delete.patch [bz#1041301] +- kvm-use-recommended-max-vcpu-count.patch [bz#998708] +- kvm-pc-Create-pc_compat_rhel-functions.patch [bz#1049706] +- kvm-pc-Enable-x2apic-by-default-on-more-recent-CPU-model.patch [bz#1049706] +- kvm-Build-all-subpackages-for-RHEV.patch [bz#1007204] +- Resolves: bz#1007204 + (qemu-img-rhev qemu-kvm-rhev-tools are not built for qemu-kvm-1.5.3-3.el7) +- Resolves: bz#1035644 + (rhel7.0host + windows guest + virtio-win + 'chkdsk' in the guest gives qemu assertion in scsi_dma_complete) +- Resolves: bz#1041301 + (live snapshot merge (commit) of the active layer) +- Resolves: bz#1049706 + (MIss CPUID_EXT_X2APIC in Westmere cpu model) +- Resolves: bz#1053699 + (Backport Cancelled race condition fixes) +- Resolves: bz#921890 + (Core dump when block mirror with "sync" is "none" and mode is "absolute-paths") +- Resolves: bz#998708 + (qemu-kvm: maximum vcpu should be recommended maximum) + +* Tue Jan 21 2014 Miroslav Rezanina - 1.5.3-39.el7 +- kvm-Revert-qdev-monitor-Fix-crash-when-device_add-is-cal.patch [bz#669524] +- kvm-Revert-qdev-Do-not-let-the-user-try-to-device_add-wh.patch [bz#669524] +- kvm-qdev-monitor-Clean-up-qdev_device_add-variable-namin.patch [bz#669524] +- kvm-qdev-monitor-Fix-crash-when-device_add-is-called.2.patch.patch [bz#669524] +- kvm-qdev-monitor-Avoid-qdev-as-variable-name.patch [bz#669524] +- kvm-qdev-monitor-Inline-qdev_init-for-device_add.patch [bz#669524] +- kvm-qdev-Do-not-let-the-user-try-to-device_add-when-it.2.patch.patch [bz#669524] +- kvm-qdev-monitor-Avoid-device_add-crashing-on-non-device.patch [bz#669524] +- kvm-qdev-monitor-Improve-error-message-for-device-nonexi.patch [bz#669524] +- kvm-exec-change-well-known-physical-sections-to-macros.patch [bz#1003535] +- kvm-exec-separate-sections-and-nodes-per-address-space.patch [bz#1003535] +- Resolves: bz#1003535 + (qemu-kvm core dump when boot vm with more than 32 virtio disks/nics) +- Resolves: bz#669524 + (Confusing error message from -device ) + +* Fri Jan 17 2014 Miroslav Rezanina - 1.5.3-38.el7 +- kvm-intel-hda-fix-position-buffer.patch [bz#947785] +- kvm-The-calculation-of-bytes_xfer-in-qemu_put_buffer-is-.patch [bz#1003467] +- kvm-migration-Fix-rate-limit.patch [bz#1003467] +- kvm-audio-honor-QEMU_AUDIO_TIMER_PERIOD-instead-of-wakin.patch [bz#1017636] +- kvm-audio-Lower-default-wakeup-rate-to-100-times-second.patch [bz#1017636] +- kvm-audio-adjust-pulse-to-100Hz-wakeup-rate.patch [bz#1017636] +- kvm-pc-Fix-rhel6.-3dnow-3dnowext-compat-bits.patch [bz#918907] +- kvm-add-firmware-to-machine-options.patch [bz#1038603] +- kvm-switch-rhel7-machine-types-to-big-bios.patch [bz#1038603] +- kvm-add-bios-256k.bin-from-seabios-bin-1.7.2.2-10.el7.no.patch [bz#1038603] +- kvm-pci-fix-pci-bridge-fw-path.patch [bz#1034518] +- kvm-hw-cannot_instantiate_with_device_add_yet-due-to-poi.patch [bz#1031098] +- kvm-qdev-Document-that-pointer-properties-kill-device_ad.patch [bz#1031098] +- kvm-Add-back-no-hpet-but-ignore-it.patch [bz#1044742] +- Resolves: bz#1003467 + (Backport migration fixes from post qemu 1.6) +- Resolves: bz#1017636 + (PATCH: fix qemu using 50% host cpu when audio is playing) +- Resolves: bz#1031098 + (Disable device smbus-eeprom) +- Resolves: bz#1034518 + (boot order wrong with q35) +- Resolves: bz#1038603 + (make seabios 256k for rhel7 machine types) +- Resolves: bz#1044742 + (Cannot create guest on remote RHEL7 host using F20 virt-manager, libvirt's qemu -no-hpet detection is broken) +- Resolves: bz#918907 + (provide backwards-compatible RHEL specific machine types in QEMU - CPU features) +- Resolves: bz#947785 + (In rhel6.4 guest sound recorder doesn't work when playing audio) + +* Wed Jan 15 2014 Miroslav Rezanina - 1.5.3-37.el7 +- kvm-bitmap-use-long-as-index.patch [bz#997559] +- kvm-memory-cpu_physical_memory_set_dirty_flags-result-is.patch [bz#997559] +- kvm-memory-cpu_physical_memory_set_dirty_range-return-vo.patch [bz#997559] +- kvm-exec-use-accessor-function-to-know-if-memory-is-dirt.patch [bz#997559] +- kvm-memory-create-function-to-set-a-single-dirty-bit.patch [bz#997559] +- kvm-exec-drop-useless-if.patch [bz#997559] +- kvm-exec-create-function-to-get-a-single-dirty-bit.patch [bz#997559] +- kvm-memory-make-cpu_physical_memory_is_dirty-return-bool.patch [bz#997559] +- kvm-memory-all-users-of-cpu_physical_memory_get_dirty-us.patch [bz#997559] +- kvm-memory-set-single-dirty-flags-when-possible.patch [bz#997559] +- kvm-memory-cpu_physical_memory_set_dirty_range-always-di.patch [bz#997559] +- kvm-memory-cpu_physical_memory_mask_dirty_range-always-c.patch [bz#997559] +- kvm-memory-use-bit-2-for-migration.patch [bz#997559] +- kvm-memory-make-sure-that-client-is-always-inside-range.patch [bz#997559] +- kvm-memory-only-resize-dirty-bitmap-when-memory-size-inc.patch [bz#997559] +- kvm-memory-cpu_physical_memory_clear_dirty_flag-result-i.patch [bz#997559] +- kvm-bitmap-Add-bitmap_zero_extend-operation.patch [bz#997559] +- kvm-memory-split-dirty-bitmap-into-three.patch [bz#997559] +- kvm-memory-unfold-cpu_physical_memory_clear_dirty_flag-i.patch [bz#997559] +- kvm-memory-unfold-cpu_physical_memory_set_dirty-in-its-o.patch [bz#997559] +- kvm-memory-unfold-cpu_physical_memory_set_dirty_flag.patch [bz#997559] +- kvm-memory-make-cpu_physical_memory_get_dirty-the-main-f.patch [bz#997559] +- kvm-memory-cpu_physical_memory_get_dirty-is-used-as-retu.patch [bz#997559] +- kvm-memory-s-mask-clear-cpu_physical_memory_mask_dirty_r.patch [bz#997559] +- kvm-memory-use-find_next_bit-to-find-dirty-bits.patch [bz#997559] +- kvm-memory-cpu_physical_memory_set_dirty_range-now-uses-.patch [bz#997559] +- kvm-memory-cpu_physical_memory_clear_dirty_range-now-use.patch [bz#997559] +- kvm-memory-s-dirty-clean-in-cpu_physical_memory_is_dirty.patch [bz#997559] +- kvm-memory-make-cpu_physical_memory_reset_dirty-take-a-l.patch [bz#997559] +- kvm-exec-Remove-unused-global-variable-phys_ram_fd.patch [bz#997559] +- kvm-memory-cpu_physical_memory_set_dirty_tracking-should.patch [bz#997559] +- kvm-memory-move-private-types-to-exec.c.patch [bz#997559] +- kvm-memory-split-cpu_physical_memory_-functions-to-its-o.patch [bz#997559] +- kvm-memory-unfold-memory_region_test_and_clear.patch [bz#997559] +- kvm-use-directly-cpu_physical_memory_-api-for-tracki.patch [bz#997559] +- kvm-refactor-start-address-calculation.patch [bz#997559] +- kvm-memory-move-bitmap-synchronization-to-its-own-functi.patch [bz#997559] +- kvm-memory-syncronize-kvm-bitmap-using-bitmaps-operation.patch [bz#997559] +- kvm-ram-split-function-that-synchronizes-a-range.patch [bz#997559] +- kvm-migration-synchronize-memory-bitmap-64bits-at-a-time.patch [bz#997559] +- Resolves: bz#997559 + (Improve live migration bitmap handling) + +* Tue Jan 14 2014 Miroslav Rezanina - 1.5.3-36.el7 +- kvm-Add-support-statement-to-help-output.patch [bz#972773] +- kvm-__com.redhat_qxl_screendump-add-docs.patch [bz#903910] +- kvm-vl-Round-memory-sizes-below-2MiB-up-to-2MiB.patch [bz#999836] +- kvm-seccomp-exit-if-seccomp_init-fails.patch [bz#1044845] +- kvm-redhat-qemu-kvm.spec-require-python-for-build.patch [bz#1034876] +- kvm-redhat-qemu-kvm.spec-require-iasl.patch [bz#1034876] +- kvm-configure-make-iasl-option-actually-work.patch [bz#1034876] +- kvm-redhat-qemu-kvm.spec-add-cpp-as-build-dependency.patch [bz#1034876] +- kvm-acpi-build-disable-with-no-acpi.patch [bz#1045386] +- kvm-ehci-implement-port-wakeup.patch [bz#1039513] +- kvm-qdev-monitor-Fix-crash-when-device_add-is-called-wit.patch [bz#1026712 bz#1046007] +- kvm-block-vhdx-improve-error-message-and-.bdrv_check-imp.patch [bz#1035001] +- kvm-docs-updated-qemu-img-man-page-and-qemu-doc-to-refle.patch [bz#1017650] +- kvm-enable-pvticketlocks-by-default.patch [bz#1052340] +- kvm-fix-boot-strict-regressed-in-commit-6ef4716.patch [bz#997817] +- kvm-vl-make-boot_strict-variable-static-not-used-outside.patch [bz#997817] +- Resolves: bz#1017650 + (need to update qemu-img man pages on "VHDX" format) +- Resolves: bz#1026712 + (Qemu core dumpd when boot guest with driver name as "virtio-pci") +- Resolves: bz#1034876 + (export acpi tables to guests) +- Resolves: bz#1035001 + (VHDX: journal log should not be replayed by default, but rather via qemu-img check -r all) +- Resolves: bz#1039513 + (backport remote wakeup for ehci) +- Resolves: bz#1044845 + (QEMU seccomp sandbox - exit if seccomp_init() fails) +- Resolves: bz#1045386 + (qemu-kvm: hw/i386/acpi-build.c:135: acpi_get_pm_info: Assertion `obj' failed.) +- Resolves: bz#1046007 + (qemu-kvm aborted when hot plug PCI device to guest with romfile and rombar=0) +- Resolves: bz#1052340 + (pvticketlocks: default on) +- Resolves: bz#903910 + (RHEL7 does not have equivalent functionality for __com.redhat_qxl_screendump) +- Resolves: bz#972773 + (RHEL7: Clarify support statement in KVM help) +- Resolves: bz#997817 + (-boot order and -boot once regressed since RHEL-6) +- Resolves: bz#999836 + (-m 1 crashes) + +* Thu Jan 09 2014 Miroslav Rezanina - 1.5.3-35.el7 +- kvm-option-Add-assigned-flag-to-QEMUOptionParameter.patch [bz#1033490] +- kvm-qcow2-refcount-Snapshot-update-for-zero-clusters.patch [bz#1033490] +- kvm-qemu-iotests-Snapshotting-zero-clusters.patch [bz#1033490] +- kvm-block-Image-file-option-amendment.patch [bz#1033490] +- kvm-qcow2-cache-Empty-cache.patch [bz#1033490] +- kvm-qcow2-cluster-Expand-zero-clusters.patch [bz#1033490] +- kvm-qcow2-Save-refcount-order-in-BDRVQcowState.patch [bz#1033490] +- kvm-qcow2-Implement-bdrv_amend_options.patch [bz#1033490] +- kvm-qcow2-Correct-bitmap-size-in-zero-expansion.patch [bz#1033490] +- kvm-qcow2-Free-only-newly-allocated-clusters-on-error.patch [bz#1033490] +- kvm-qcow2-Add-missing-space-in-error-message.patch [bz#1033490] +- kvm-qemu-iotest-qcow2-image-option-amendment.patch [bz#1033490] +- kvm-qemu-iotests-New-test-case-in-061.patch [bz#1033490] +- kvm-qemu-iotests-Preallocated-zero-clusters-in-061.patch [bz#1033490] +- Resolves: bz#1033490 + (Cannot upgrade/downgrade qcow2 images) + +* Wed Jan 08 2014 Miroslav Rezanina - 1.5.3-34.el7 +- kvm-block-stream-Don-t-stream-unbacked-devices.patch [bz#965636] +- kvm-qemu-io-Let-open-pass-options-to-block-driver.patch [bz#1004347] +- kvm-qcow2.py-Subcommand-for-changing-header-fields.patch [bz#1004347] +- kvm-qemu-iotests-Remaining-error-propagation-adjustments.patch [bz#1004347] +- kvm-qemu-iotests-Add-test-for-inactive-L2-overlap.patch [bz#1004347] +- kvm-qemu-iotests-Adjust-test-result-039.patch [bz#1004347] +- kvm-virtio-net-don-t-update-mac_table-in-error-state.patch [bz#1048671] +- kvm-qcow2-Zero-initialise-first-cluster-for-new-images.patch [bz#1032904] +- Resolves: bz#1004347 + (Backport qcow2 corruption prevention patches) +- Resolves: bz#1032904 + (qemu-img can not create libiscsi qcow2_v3 image) +- Resolves: bz#1048671 + (virtio-net: mac_table change isn't recovered in error state) +- Resolves: bz#965636 + (streaming with no backing file should not do anything) + +* Wed Jan 08 2014 Miroslav Rezanina - 1.5.3-33.el7 +- kvm-block-qemu-iotests-for-vhdx-read-sample-dynamic-imag.patch [bz#879234] +- kvm-block-qemu-iotests-add-quotes-to-TEST_IMG-usage-io-p.patch [bz#879234] +- kvm-block-qemu-iotests-fix-_make_test_img-to-work-with-s.patch [bz#879234] +- kvm-block-qemu-iotests-add-quotes-to-TEST_IMG.base-usage.patch [bz#879234] +- kvm-block-qemu-iotests-add-quotes-to-TEST_IMG-usage-in-0.patch [bz#879234] +- kvm-block-qemu-iotests-removes-duplicate-double-quotes-i.patch [bz#879234] +- kvm-block-vhdx-minor-comments-and-typo-correction.patch [bz#879234] +- kvm-block-vhdx-add-header-update-capability.patch [bz#879234] +- kvm-block-vhdx-code-movement-VHDXMetadataEntries-and-BDR.patch [bz#879234] +- kvm-block-vhdx-log-support-struct-and-defines.patch [bz#879234] +- kvm-block-vhdx-break-endian-translation-functions-out.patch [bz#879234] +- kvm-block-vhdx-update-log-guid-in-header-and-first-write.patch [bz#879234] +- kvm-block-vhdx-code-movement-move-vhdx_close-above-vhdx_.patch [bz#879234] +- kvm-block-vhdx-log-parsing-replay-and-flush-support.patch [bz#879234] +- kvm-block-vhdx-add-region-overlap-detection-for-image-fi.patch [bz#879234] +- kvm-block-vhdx-add-log-write-support.patch [bz#879234] +- kvm-block-vhdx-write-support.patch [bz#879234] +- kvm-block-vhdx-remove-BAT-file-offset-bit-shifting.patch [bz#879234] +- kvm-block-vhdx-move-more-endian-translations-to-vhdx-end.patch [bz#879234] +- kvm-block-vhdx-break-out-code-operations-to-functions.patch [bz#879234] +- kvm-block-vhdx-fix-comment-typos-in-header-fix-incorrect.patch [bz#879234] +- kvm-block-vhdx-add-.bdrv_create-support.patch [bz#879234] +- kvm-block-vhdx-update-_make_test_img-to-filter-out-vhdx-.patch [bz#879234] +- kvm-block-qemu-iotests-for-vhdx-add-write-test-support.patch [bz#879234] +- kvm-block-vhdx-qemu-iotest-log-replay-of-data-sector.patch [bz#879234] +- Resolves: bz#879234 + ([RFE] qemu-img: Add/improve support for VHDX format) + +* Mon Jan 06 2014 Michal Novotny - 1.5.3-32.el7 +- kvm-block-change-default-of-.has_zero_init-to-0.patch.patch [bz#1007815] +- kvm-iscsi-factor-out-sector-conversions.patch.patch [bz#1007815] +- kvm-iscsi-add-logical-block-provisioning-information-to-.patch.patch [bz#1007815] +- kvm-iscsi-add-.bdrv_get_block_status.patch.patch.patch [bz#1007815] +- kvm-iscsi-split-discard-requests-in-multiple-parts.patch.patch.patch [bz#1007815] +- kvm-block-make-BdrvRequestFlags-public.patch.patch.patch [bz#1007815] +- kvm-block-add-flags-to-bdrv_-_write_zeroes.patch.patch.patch [bz#1007815] +- kvm-block-introduce-BDRV_REQ_MAY_UNMAP-request-flag.patch.patch.patch [bz#1007815] +- kvm-block-add-logical-block-provisioning-info-to-BlockDr.patch.patch.patch [bz#1007815] +- kvm-block-add-wrappers-for-logical-block-provisioning-in.patch.patch.patch [bz#1007815] +- kvm-block-iscsi-add-.bdrv_get_info.patch.patch [bz#1007815] +- kvm-block-add-BlockLimits-structure-to-BlockDriverState.patch.patch.patch [bz#1007815] +- kvm-block-raw-copy-BlockLimits-on-raw_open.patch.patch.patch [bz#1007815] +- kvm-block-honour-BlockLimits-in-bdrv_co_do_write_zeroes.patch.patch.patch [bz#1007815] +- kvm-block-honour-BlockLimits-in-bdrv_co_discard.patch.patch.patch [bz#1007815] +- kvm-iscsi-set-limits-in-BlockDriverState.patch.patch.patch [bz#1007815] +- kvm-iscsi-simplify-iscsi_co_discard.patch.patch.patch [bz#1007815] +- kvm-iscsi-add-bdrv_co_write_zeroes.patch.patch.patch [bz#1007815] +- kvm-block-introduce-bdrv_make_zero.patch.patch.patch [bz#1007815] +- kvm-block-get_block_status-fix-BDRV_BLOCK_ZERO-for-unall.patch.patch.patch [bz#1007815] +- kvm-qemu-img-add-support-for-fully-allocated-images.patch.patch.patch [bz#1007815] +- kvm-qemu-img-conditionally-zero-out-target-on-convert.patch.patch.patch [bz#1007815] +- kvm-block-generalize-BlockLimits-handling-to-cover-bdrv_.patch.patch.patch [bz#1007815] +- kvm-block-add-flags-to-BlockRequest.patch.patch.patch [bz#1007815] +- kvm-block-add-flags-argument-to-bdrv_co_write_zeroes-tra.patch.patch.patch [bz#1007815] +- kvm-block-add-bdrv_aio_write_zeroes.patch.patch.patch [bz#1007815] +- kvm-block-handle-ENOTSUP-from-discard-in-generic-code.patch.patch.patch [bz#1007815] +- kvm-block-make-bdrv_co_do_write_zeroes-stricter-in-produ.patch.patch.patch [bz#1007815] +- kvm-vpc-vhdx-add-get_info.patch.patch.patch [bz#1007815] +- kvm-block-drivers-add-discard-write_zeroes-properties-to.patch.patch.patch [bz#1007815] +- kvm-block-drivers-expose-requirement-for-write-same-alig.patch.patch.patch [bz#1007815] +- kvm-block-iscsi-remove-.bdrv_has_zero_init.patch.patch.patch [bz#1007815] +- kvm-block-iscsi-updated-copyright.patch.patch.patch [bz#1007815] +- kvm-block-iscsi-check-WRITE-SAME-support-differently-dep.patch.patch.patch [bz#1007815] +- kvm-scsi-disk-catch-write-protection-errors-in-UNMAP.patch.patch.patch [bz#1007815] +- kvm-scsi-disk-reject-ANCHOR-1-for-UNMAP-and-WRITE-SAME-c.patch.patch.patch [bz#1007815] +- kvm-scsi-disk-correctly-implement-WRITE-SAME.patch.patch.patch [bz#1007815] +- kvm-scsi-disk-fix-WRITE-SAME-with-large-non-zero-payload.patch.patch.patch [bz#1007815] +- kvm-raw-posix-implement-write_zeroes-with-MAY_UNMAP-for-.patch.patch.patch.patch [bz#1007815] +- kvm-raw-posix-implement-write_zeroes-with-MAY_UNMAP-for-.patch.patch.patch.patch.patch [bz#1007815] +- kvm-raw-posix-add-support-for-write_zeroes-on-XFS-and-bl.patch.patch [bz#1007815] +- kvm-qemu-iotests-033-is-fast.patch.patch [bz#1007815] +- kvm-qemu-img-add-support-for-skipping-zeroes-in-input-du.patch.patch [bz#1007815] +- kvm-qemu-img-fix-usage-instruction-for-qemu-img-convert.patch.patch [bz#1007815] +- kvm-block-iscsi-set-bdi-cluster_size.patch.patch [bz#1007815] +- kvm-block-add-opt_transfer_length-to-BlockLimits.patch.patch [bz#1039557] +- kvm-block-iscsi-set-bs-bl.opt_transfer_length.patch.patch [bz#1039557] +- kvm-qemu-img-dynamically-adjust-iobuffer-size-during-con.patch.patch [bz#1039557] +- kvm-qemu-img-round-down-request-length-to-an-aligned-sec.patch.patch [bz#1039557] +- kvm-qemu-img-decrease-progress-update-interval-on-conver.patch.patch [bz#1039557] +- Resolves: bz#1007815 + (fix WRITE SAME support) +- Resolves: bz#1039557 + (optimize qemu-img for thin provisioned images) + +* Fri Dec 27 2013 Daniel Mach - 10:1.5.3-31 +- Mass rebuild 2013-12-27 + +* Wed Dec 18 2013 Michal Novotny - 1.5.3-30.el7 +- kvm-Revert-HMP-Disable-drive_add-for-Red-Hat-Enterprise-2.patch.patch [bz#889051] +- Resolves: bz#889051 + (Commands "__com.redhat_drive_add/del" don' t exist in RHEL7.0) + +* Wed Dec 18 2013 Michal Novotny - 1.5.3-29.el7 +- kvm-QMP-Forward-port-__com.redhat_drive_del-from-RHEL-6.patch [bz#889051] +- kvm-QMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch [bz#889051] +- kvm-HMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch [bz#889051] +- kvm-QMP-Document-throttling-parameters-of-__com.redhat_d.patch [bz#889051] +- kvm-HMP-Disable-drive_add-for-Red-Hat-Enterprise-Linux.patch [bz#889051] +- Resolves: bz#889051 + (Commands "__com.redhat_drive_add/del" don' t exist in RHEL7.0) + +* Wed Dec 18 2013 Michal Novotny - 1.5.3-28.el7 +- kvm-virtio_pci-fix-level-interrupts-with-irqfd.patch [bz#1035132] +- Resolves: bz#1035132 + (fail to boot and call trace with x-data-plane=on specified for rhel6.5 guest) + +* Wed Dec 18 2013 Michal Novotny - 1.5.3-27.el7 +- Change systemd service location [bz#1025217] +- kvm-vmdk-Allow-read-only-open-of-VMDK-version-3.patch [bz#1007710 bz#1029852] +- Resolves: bz#1007710 + ([RFE] Enable qemu-img to support VMDK version 3) +- Resolves: bz#1025217 + (systemd can't control ksm.service and ksmtuned.service) +- Resolves: bz#1029852 + (qemu-img fails to convert vmdk image with "qemu-img: Could not open 'image.vmdk'") + +* Wed Dec 18 2013 Michal Novotny - 1.5.3-26.el7 +- Add BuildRequires to libRDMAcm-devel for RDMA support [bz#1011720] +- kvm-add-a-header-file-for-atomic-operations.patch [bz#1011720] +- kvm-savevm-Fix-potential-memory-leak.patch [bz#1011720] +- kvm-migration-Fail-migration-on-bdrv_flush_all-error.patch [bz#1011720] +- kvm-rdma-add-documentation.patch [bz#1011720] +- kvm-rdma-introduce-qemu_update_position.patch [bz#1011720] +- kvm-rdma-export-yield_until_fd_readable.patch [bz#1011720] +- kvm-rdma-export-throughput-w-MigrationStats-QMP.patch [bz#1011720] +- kvm-rdma-introduce-qemu_file_mode_is_not_valid.patch [bz#1011720] +- kvm-rdma-introduce-qemu_ram_foreach_block.patch [bz#1011720] +- kvm-rdma-new-QEMUFileOps-hooks.patch [bz#1011720] +- kvm-rdma-introduce-capability-x-rdma-pin-all.patch [bz#1011720] +- kvm-rdma-update-documentation-to-reflect-new-unpin-suppo.patch [bz#1011720]- kvm-rdma-bugfix-ram_control_save_page.patch [bz#1011720] +- kvm-rdma-introduce-ram_handle_compressed.patch [bz#1011720] +- kvm-rdma-core-logic.patch [bz#1011720] +- kvm-rdma-send-pc.ram.patch [bz#1011720] +- kvm-rdma-allow-state-transitions-between-other-states-be.patch [bz#1011720] +- kvm-rdma-introduce-MIG_STATE_NONE-and-change-MIG_STATE_S.patch [bz#1011720] +- kvm-rdma-account-for-the-time-spent-in-MIG_STATE_SETUP-t.patch [bz#1011720] +- kvm-rdma-bugfix-make-IPv6-support-work.patch [bz#1011720] +- kvm-rdma-forgot-to-turn-off-the-debugging-flag.patch [bz#1011720] +- kvm-rdma-correct-newlines-in-error-statements.patch [bz#1011720] +- kvm-rdma-don-t-use-negative-index-to-array.patch [bz#1011720] +- kvm-rdma-qemu_rdma_post_send_control-uses-wrongly-RDMA_W.patch [bz#1011720] +- kvm-rdma-use-DRMA_WRID_READY.patch [bz#1011720] +- kvm-rdma-memory-leak-RDMAContext-host.patch [bz#1011720] +- kvm-rdma-use-resp.len-after-validation-in-qemu_rdma_regi.patch [bz#1011720] +- kvm-rdma-validate-RDMAControlHeader-len.patch [bz#1011720] +- kvm-rdma-check-if-RDMAControlHeader-len-match-transferre.patch [bz#1011720] +- kvm-rdma-proper-getaddrinfo-handling.patch [bz#1011720] +- kvm-rdma-IPv6-over-Ethernet-RoCE-is-broken-in-linux-work.patch [bz#1011720] +- kvm-rdma-remaining-documentation-fixes.patch [bz#1011720] +- kvm-rdma-silly-ipv6-bugfix.patch [bz#1011720] +- kvm-savevm-fix-wrong-initialization-by-ram_control_load_.patch [bz#1011720] +- kvm-arch_init-right-return-for-ram_save_iterate.patch [bz#1011720] +- kvm-rdma-clean-up-of-qemu_rdma_cleanup.patch [bz#1011720] +- kvm-rdma-constify-ram_chunk_-index-start-end.patch [bz#1011720] +- kvm-migration-Fix-debug-print-type.patch [bz#1011720] +- kvm-arch_init-make-is_zero_page-accept-size.patch [bz#1011720] +- kvm-migration-ram_handle_compressed.patch [bz#1011720] +- kvm-migration-fix-spice-migration.patch [bz#1011720] +- kvm-pci-assign-cap-number-of-devices-that-can-be-assigne.patch [bz#678368] +- kvm-vfio-cap-number-of-devices-that-can-be-assigned.patch [bz#678368] +- kvm-Revert-usb-tablet-Don-t-claim-wakeup-capability-for-.patch [bz#1039513] +- kvm-mempath-prefault-pages-manually-v4.patch [bz#1026554] +- Resolves: bz#1011720 + ([HP 7.0 Feat]: Backport RDMA based live guest migration changes from upstream to RHEL7.0 KVM) +- Resolves: bz#1026554 + (qemu: mempath: prefault pages manually) +- Resolves: bz#1039513 + (backport remote wakeup for ehci) +- Resolves: bz#678368 + (RFE: Support more than 8 assigned devices) + +* Wed Dec 18 2013 Michal Novotny - 1.5.3-25.el7 +- kvm-Change-package-description.patch [bz#1017696] +- kvm-seccomp-add-kill-to-the-syscall-whitelist.patch [bz#1026314] +- kvm-json-parser-fix-handling-of-large-whole-number-value.patch [bz#997915] +- kvm-qapi-add-QMP-input-test-for-large-integers.patch [bz#997915] +- kvm-qapi-fix-visitor-serialization-tests-for-numbers-dou.patch [bz#997915] +- kvm-qapi-add-native-list-coverage-for-visitor-serializat.patch [bz#997915] +- kvm-qapi-add-native-list-coverage-for-QMP-output-visitor.patch [bz#997915] +- kvm-qapi-add-native-list-coverage-for-QMP-input-visitor-.patch [bz#997915] +- kvm-qapi-lack-of-two-commas-in-dict.patch [bz#997915] +- kvm-tests-QAPI-schema-parser-tests.patch [bz#997915] +- kvm-tests-Use-qapi-schema-test.json-as-schema-parser-tes.patch [bz#997915] +- kvm-qapi.py-Restructure-lexer-and-parser.patch [bz#997915] +- kvm-qapi.py-Decent-syntax-error-reporting.patch [bz#997915] +- kvm-qapi.py-Reject-invalid-characters-in-schema-file.patch [bz#997915] +- kvm-qapi.py-Fix-schema-parser-to-check-syntax-systematic.patch [bz#997915] +- kvm-qapi.py-Fix-diagnosing-non-objects-at-a-schema-s-top.patch [bz#997915] +- kvm-qapi.py-Rename-expr_eval-to-expr-in-parse_schema.patch [bz#997915] +- kvm-qapi.py-Permit-comments-starting-anywhere-on-the-lin.patch [bz#997915] +- kvm-scripts-qapi.py-Avoid-syntax-not-supported-by-Python.patch [bz#997915] +- kvm-tests-Fix-schema-parser-test-for-in-tree-build.patch [bz#997915] +- Resolves: bz#1017696 + ([branding] remove references to dynamic translation and user-mode emulation) +- Resolves: bz#1026314 + (qemu-kvm hang when use '-sandbox on'+'vnc'+'hda') +- Resolves: bz#997915 + (Backport new QAPI parser proactively to help developers and avoid silly conflicts) + +* Tue Dec 17 2013 Michal Novotny - 1.5.3-24.el7 +- kvm-range-add-Range-structure.patch [bz#1034876] +- kvm-range-add-Range-to-typedefs.patch [bz#1034876] +- kvm-range-add-min-max-operations-on-ranges.patch [bz#1034876] +- kvm-qdev-Add-SIZE-type-to-qdev-properties.patch [bz#1034876] +- kvm-qapi-make-visit_type_size-fallback-to-type_int.patch [bz#1034876] +- kvm-pc-move-IO_APIC_DEFAULT_ADDRESS-to-include-hw-i386-i.patch [bz#1034876] +- kvm-pci-add-helper-to-retrieve-the-64-bit-range.patch [bz#1034876] +- kvm-pci-fix-up-w64-size-calculation-helper.patch [bz#1034876] +- kvm-refer-to-FWCfgState-explicitly.patch [bz#1034876] +- kvm-fw_cfg-move-typedef-to-qemu-typedefs.h.patch [bz#1034876] +- kvm-arch_init-align-MR-size-to-target-page-size.patch [bz#1034876] +- kvm-loader-store-FW-CFG-ROM-files-in-RAM.patch [bz#1034876] +- kvm-pci-store-PCI-hole-ranges-in-guestinfo-structure.patch [bz#1034876] +- kvm-pc-pass-PCI-hole-ranges-to-Guests.patch [bz#1034876] +- kvm-pc-replace-i440fx_common_init-with-i440fx_init.patch [bz#1034876] +- kvm-pc-don-t-access-fw-cfg-if-NULL.patch [bz#1034876] +- kvm-pc-add-I440FX-QOM-cast-macro.patch [bz#1034876] +- kvm-pc-limit-64-bit-hole-to-2G-by-default.patch [bz#1034876] +- kvm-q35-make-pci-window-address-size-match-guest-cfg.patch [bz#1034876] +- kvm-q35-use-64-bit-window-programmed-by-guest.patch [bz#1034876] +- kvm-piix-use-64-bit-window-programmed-by-guest.patch [bz#1034876] +- kvm-pc-fix-regression-for-64-bit-PCI-memory.patch [bz#1034876] +- kvm-cleanup-object.h-include-error.h-directly.patch [bz#1034876] +- kvm-qom-cleanup-struct-Error-references.patch [bz#1034876] +- kvm-qom-add-pointer-to-int-property-helpers.patch [bz#1034876] +- kvm-fw_cfg-interface-to-trigger-callback-on-read.patch [bz#1034876] +- kvm-loader-support-for-unmapped-ROM-blobs.patch [bz#1034876] +- kvm-pcie_host-expose-UNMAPPED-macro.patch [bz#1034876] +- kvm-pcie_host-expose-address-format.patch [bz#1034876] +- kvm-q35-use-macro-for-MCFG-property-name.patch [bz#1034876] +- kvm-q35-expose-mmcfg-size-as-a-property.patch [bz#1034876] +- kvm-i386-add-ACPI-table-files-from-seabios.patch [bz#1034876] +- kvm-acpi-add-rules-to-compile-ASL-source.patch [bz#1034876] +- kvm-acpi-pre-compiled-ASL-files.patch [bz#1034876] +- kvm-acpi-ssdt-pcihp-updat-generated-file.patch [bz#1034876] +- kvm-loader-use-file-path-size-from-fw_cfg.h.patch [bz#1034876] +- kvm-i386-add-bios-linker-loader.patch [bz#1034876] +- kvm-loader-allow-adding-ROMs-in-done-callbacks.patch [bz#1034876] +- kvm-i386-define-pc-guest-info.patch [bz#1034876] +- kvm-acpi-piix-add-macros-for-acpi-property-names.patch [bz#1034876] +- kvm-piix-APIs-for-pc-guest-info.patch [bz#1034876] +- kvm-ich9-APIs-for-pc-guest-info.patch [bz#1034876] +- kvm-pvpanic-add-API-to-access-io-port.patch [bz#1034876] +- kvm-hpet-add-API-to-find-it.patch [bz#1034876] +- kvm-hpet-fix-build-with-CONFIG_HPET-off.patch [bz#1034876] +- kvm-acpi-add-interface-to-access-user-installed-tables.patch [bz#1034876] +- kvm-pc-use-new-api-to-add-builtin-tables.patch [bz#1034876] +- kvm-i386-ACPI-table-generation-code-from-seabios.patch [bz#1034876] +- kvm-ssdt-fix-PBLK-length.patch [bz#1034876] +- kvm-ssdt-proc-update-generated-file.patch [bz#1034876] +- kvm-pc-disable-pci-info.patch [bz#1034876] +- kvm-acpi-build-fix-build-on-glib-2.22.patch [bz#1034876] +- kvm-acpi-build-fix-build-on-glib-2.14.patch [bz#1034876] +- kvm-acpi-build-fix-support-for-glib-2.22.patch [bz#1034876] +- kvm-acpi-build-Fix-compiler-warning-missing-gnu_printf-f.patch [bz#1034876] +- kvm-exec-Fix-prototype-of-phys_mem_set_alloc-and-related.patch [bz#1034876] +- Resolves: bz#1034876 + (export acpi tables to guests) + +* Tue Dec 17 2013 Michal Novotny - 1.5.3-23.el7 +- kvm-qdev-monitor-Unref-device-when-device_add-fails.patch [bz#1003773] +- kvm-qdev-Drop-misleading-qdev_free-function.patch [bz#1003773] +- kvm-blockdev-fix-drive_init-opts-and-bs_opts-leaks.patch [bz#1003773] +- kvm-libqtest-rename-qmp-to-qmp_discard_response.patch [bz#1003773] +- kvm-libqtest-add-qmp-fmt-.-QDict-function.patch [bz#1003773] +- kvm-blockdev-test-add-test-case-for-drive_add-duplicate-.patch [bz#1003773] +- kvm-qdev-monitor-test-add-device_add-leak-test-cases.patch [bz#1003773] +- kvm-qtest-Use-display-none-by-default.patch [bz#1003773] +- Resolves: bz#1003773 + (When virtio-blk-pci device with dataplane is failed to be added, the drive cannot be released.) + +* Tue Dec 17 2013 Michal Novotny - 1.5.3-22.el7 +- Fix ksmtuned with set_process_name=1 [bz#1027420] +- Fix committed memory when no qemu-kvm running [bz#1027418] +- kvm-virtio-net-fix-the-memory-leak-in-rxfilter_notify.patch [bz#1033810] +- kvm-qom-Fix-memory-leak-in-object_property_set_link.patch [bz#1033810] +- kvm-fix-intel-hda-live-migration.patch [bz#1036537] +- kvm-vfio-pci-Release-all-MSI-X-vectors-when-disabled.patch [bz#1029743] +- kvm-Query-KVM-for-available-memory-slots.patch [bz#921490] +- kvm-block-Dont-ignore-previously-set-bdrv_flags.patch [bz#1039501] +- kvm-cleanup-trace-events.pl-New.patch [bz#997832] +- kvm-slavio_misc-Fix-slavio_led_mem_readw-_writew-tracepo.patch [bz#997832] +- kvm-milkymist-minimac2-Fix-minimac2_read-_write-tracepoi.patch [bz#997832] +- kvm-trace-events-Drop-unused-events.patch [bz#997832] +- kvm-trace-events-Fix-up-source-file-comments.patch [bz#997832] +- kvm-trace-events-Clean-up-with-scripts-cleanup-trace-eve.patch [bz#997832] +- kvm-trace-events-Clean-up-after-removal-of-old-usb-host-.patch [bz#997832] +- kvm-net-Update-netdev-peer-on-link-change.patch [bz#1027571] +- Resolves: bz#1027418 + (ksmtuned committed_memory() still returns "", not 0, when no qemu running) +- Resolves: bz#1027420 + (ksmtuned can’t handle libvirt WITH set_process_name=1) +- Resolves: bz#1027571 + ([virtio-win]win8.1 guest network can not resume automatically after do "set_link tap1 on") +- Resolves: bz#1029743 + (qemu-kvm core dump after hot plug/unplug 82576 PF about 100 times) +- Resolves: bz#1033810 + (memory leak in using object_get_canonical_path()) +- Resolves: bz#1036537 + (Cross version migration from RHEL6.5 host to RHEL7.0 host with sound device failed.) +- Resolves: bz#1039501 + ([provisioning] discard=on broken) +- Resolves: bz#921490 + (qemu-kvm core dumped after hot plugging more than 11 VF through vfio-pci) +- Resolves: bz#997832 + (Backport trace fixes proactively to avoid confusion and silly conflicts) + +* Tue Dec 03 2013 Miroslav Rezanina - 1.5.3-21.el7 +- kvm-scsi-Allocate-SCSITargetReq-r-buf-dynamically-CVE-20.patch [bz#1007334] +- Resolves: bz#1007334 + (CVE-2013-4344 qemu-kvm: qemu: buffer overflow in scsi_target_emulate_report_luns [rhel-7.0]) + +* Thu Nov 28 2013 Miroslav Rezanina - 1.5.3-20.el7 +- kvm-pc-drop-virtio-balloon-pci-event_idx-compat-property.patch [bz#1029539] +- kvm-virtio-net-only-delete-bh-that-existed.patch [bz#922463] +- kvm-virtio-net-broken-RX-filtering-logic-fixed.patch [bz#1029370] +- kvm-block-Avoid-unecessary-drv-bdrv_getlength-calls.patch [bz#1025138] +- kvm-block-Round-up-total_sectors.patch [bz#1025138] +- kvm-doc-fix-hardcoded-helper-path.patch [bz#1016952] +- kvm-introduce-RFQDN_REDHAT-RHEL-6-7-fwd.patch [bz#971933] +- kvm-error-reason-in-BLOCK_IO_ERROR-BLOCK_JOB_ERROR-event.patch [bz#971938] +- kvm-improve-debuggability-of-BLOCK_IO_ERROR-BLOCK_JOB_ER.patch [bz#895041] +- kvm-vfio-pci-Fix-multifunction-on.patch [bz#1029275] +- kvm-qcow2-Change-default-for-new-images-to-compat-1.1.patch [bz#1026739] +- kvm-qcow2-change-default-for-new-images-to-compat-1.1-pa.patch [bz#1026739] +- kvm-rng-egd-offset-the-point-when-repeatedly-read-from-t.patch [bz#1032862] +- kvm-Fix-rhel-rhev-conflict-for-qemu-kvm-common.patch [bz#1033463] +- Resolves: bz#1016952 + (qemu-kvm man page guide wrong path for qemu-bridge-helper) +- Resolves: bz#1025138 + (Read/Randread/Randrw performance regression) +- Resolves: bz#1026739 + (qcow2: Switch to compat=1.1 default for new images) +- Resolves: bz#1029275 + (Guest only find one 82576 VF(function 0) while use multifunction) +- Resolves: bz#1029370 + ([whql][netkvm][wlk] Virtio-net device handles RX multicast filtering improperly) +- Resolves: bz#1029539 + (Machine type rhel6.1.0 and balloon device cause migration fail from RHEL6.5 host to RHEL7.0 host) +- Resolves: bz#1032862 + (virtio-rng-egd: repeatedly read same random data-block w/o considering the buffer offset) +- Resolves: bz#1033463 + (can not upgrade qemu-kvm-common to qemu-kvm-common-rhev due to conflicts) +- Resolves: bz#895041 + (QMP: forward port I/O error debug messages) +- Resolves: bz#922463 + (qemu-kvm core dump when virtio-net multi queue guest hot-unpluging vNIC) +- Resolves: bz#971933 + (QMP: add RHEL's vendor extension prefix) +- Resolves: bz#971938 + (QMP: Add error reason to BLOCK_IO_ERROR event) + +* Mon Nov 11 2013 Miroslav Rezanina - 1.5.3-19.el7 +- kvm-qapi-qapi-visit.py-fix-list-handling-for-union-types.patch [bz#848203] +- kvm-qapi-qapi-visit.py-native-list-support.patch [bz#848203] +- kvm-qapi-enable-generation-of-native-list-code.patch [bz#848203] +- kvm-net-add-support-of-mac-programming-over-macvtap-in-Q.patch [bz#848203] +- Resolves: bz#848203 + (MAC Programming for virtio over macvtap - qemu-kvm support) + +* Fri Nov 08 2013 Michal Novotny - 1.5.3-18.el7 +- Removing leaked patch kvm-e1000-rtl8139-update-HMP-NIC-when-every-bit-is-writt.patch + +* Thu Nov 07 2013 Miroslav Rezanina - 1.5.3-17.el7 +- kvm-pci-assign-Add-MSI-affinity-support.patch [bz#1025877] +- kvm-Fix-potential-resource-leak-missing-fclose.patch [bz#1025877] +- kvm-pci-assign-remove-the-duplicate-function-name-in-deb.patch [bz#1025877] +- kvm-Remove-s390-ccw-img-loader.patch [bz#1017682] +- kvm-Fix-vscclient-installation.patch [bz#1017681] +- kvm-Change-qemu-bridge-helper-permissions-to-4755.patch [bz#1017689] +- kvm-net-update-nic-info-during-device-reset.patch [bz#922589] +- kvm-net-e1000-update-network-information-when-macaddr-is.patch [bz#922589] +- kvm-net-rtl8139-update-network-information-when-macaddr-.patch [bz#922589] +- kvm-virtio-net-fix-up-HMP-NIC-info-string-on-reset.patch [bz#1026689] +- kvm-vfio-pci-VGA-quirk-update.patch [bz#1025477] +- kvm-vfio-pci-Add-support-for-MSI-affinity.patch [bz#1025477] +- kvm-vfio-pci-Test-device-reset-capabilities.patch [bz#1026550] +- kvm-vfio-pci-Lazy-PCI-option-ROM-loading.patch [bz#1026550] +- kvm-vfio-pci-Cleanup-error_reports.patch [bz#1026550] +- kvm-vfio-pci-Add-dummy-PCI-ROM-write-accessor.patch [bz#1026550] +- kvm-vfio-pci-Fix-endian-issues-in-vfio_pci_size_rom.patch [bz#1026550] +- kvm-linux-headers-Update-to-include-vfio-pci-hot-reset-s.patch [bz#1025472] +- kvm-vfio-pci-Implement-PCI-hot-reset.patch [bz#1025472] +- kvm-linux-headers-Update-for-KVM-VFIO-device.patch [bz#1025474] +- kvm-vfio-pci-Make-use-of-new-KVM-VFIO-device.patch [bz#1025474] +- kvm-vmdk-Fix-vmdk_parse_extents.patch [bz#995866] +- kvm-vmdk-fix-VMFS-extent-parsing.patch [bz#995866] +- kvm-e1000-rtl8139-update-HMP-NIC-when-every-bit-is-writt.patch [bz#922589] +- kvm-don-t-disable-ctrl_mac_addr-feature-for-6.5-machine-.patch [bz#1005039] +- Resolves: bz#1005039 + (add compat property to disable ctrl_mac_addr feature) +- Resolves: bz#1017681 + (rpmdiff test "Multilib regressions": vscclient is a libtool script on s390/s390x/ppc/ppc64) +- Resolves: bz#1017682 + (/usr/share/qemu-kvm/s390-ccw.img need not be distributed) +- Resolves: bz#1017689 + (/usr/libexec/qemu-bridge-helper permissions should be 4755) +- Resolves: bz#1025472 + (Nvidia GPU device assignment - qemu-kvm - bus reset support) +- Resolves: bz#1025474 + (Nvidia GPU device assignment - qemu-kvm - NoSnoop support) +- Resolves: bz#1025477 + (VFIO MSI affinity) +- Resolves: bz#1025877 + (pci-assign lacks MSI affinity support) +- Resolves: bz#1026550 + (QEMU VFIO update ROM loading code) +- Resolves: bz#1026689 + (virtio-net: macaddr is reset but network info of monitor isn't updated) +- Resolves: bz#922589 + (e1000/rtl8139: qemu mac address can not be changed via set the hardware address in guest) +- Resolves: bz#995866 + (fix vmdk support to ESX images) + +* Thu Nov 07 2013 Miroslav Rezanina - 1.5.3-16.el7 +- kvm-block-drop-bs_snapshots-global-variable.patch [bz#1026524] +- kvm-block-move-snapshot-code-in-block.c-to-block-snapsho.patch [bz#1026524] +- kvm-block-fix-vvfat-error-path-for-enable_write_target.patch [bz#1026524] +- kvm-block-Bugfix-format-and-snapshot-used-in-drive-optio.patch [bz#1026524] +- kvm-iscsi-use-bdrv_new-instead-of-stack-structure.patch [bz#1026524] +- kvm-qcow2-Add-corrupt-bit.patch [bz#1004347] +- kvm-qcow2-Metadata-overlap-checks.patch [bz#1004347] +- kvm-qcow2-Employ-metadata-overlap-checks.patch [bz#1004347] +- kvm-qcow2-refcount-Move-OFLAG_COPIED-checks.patch [bz#1004347] +- kvm-qcow2-refcount-Repair-OFLAG_COPIED-errors.patch [bz#1004347] +- kvm-qcow2-refcount-Repair-shared-refcount-blocks.patch [bz#1004347] +- kvm-qcow2_check-Mark-image-consistent.patch [bz#1004347] +- kvm-qemu-iotests-Overlapping-cluster-allocations.patch [bz#1004347] +- kvm-w32-Fix-access-to-host-devices-regression.patch [bz#1026524] +- kvm-add-qemu-img-convert-n-option-skip-target-volume-cre.patch [bz#1026524] +- kvm-bdrv-Use-Error-for-opening-images.patch [bz#1026524] +- kvm-bdrv-Use-Error-for-creating-images.patch [bz#1026524] +- kvm-block-Error-parameter-for-open-functions.patch [bz#1026524] +- kvm-block-Error-parameter-for-create-functions.patch [bz#1026524] +- kvm-qemu-img-create-Emit-filename-on-error.patch [bz#1026524] +- kvm-qcow2-Use-Error-parameter.patch [bz#1026524] +- kvm-qemu-iotests-Adjustments-due-to-error-propagation.patch [bz#1026524] +- kvm-block-raw-Employ-error-parameter.patch [bz#1026524] +- kvm-block-raw-win32-Employ-error-parameter.patch [bz#1026524] +- kvm-blkdebug-Employ-error-parameter.patch [bz#1026524] +- kvm-blkverify-Employ-error-parameter.patch [bz#1026524] +- kvm-block-raw-posix-Employ-error-parameter.patch [bz#1026524] +- kvm-block-raw-win32-Always-use-errno-in-hdev_open.patch [bz#1026524] +- kvm-qmp-Documentation-for-BLOCK_IMAGE_CORRUPTED.patch [bz#1004347] +- kvm-qcow2-Correct-snapshots-size-for-overlap-check.patch [bz#1004347] +- kvm-qcow2-CHECK_OFLAG_COPIED-is-obsolete.patch [bz#1004347] +- kvm-qcow2-Correct-endianness-in-overlap-check.patch [bz#1004347] +- kvm-qcow2-Switch-L1-table-in-a-single-sequence.patch [bz#1004347] +- kvm-qcow2-Use-pread-for-inactive-L1-in-overlap-check.patch [bz#1004347] +- kvm-qcow2-Remove-wrong-metadata-overlap-check.patch [bz#1004347] +- kvm-qcow2-Use-negated-overflow-check-mask.patch [bz#1004347] +- kvm-qcow2-Make-overlap-check-mask-variable.patch [bz#1004347] +- kvm-qcow2-Add-overlap-check-options.patch [bz#1004347] +- kvm-qcow2-Array-assigning-options-to-OL-check-bits.patch [bz#1004347] +- kvm-qcow2-Add-more-overlap-check-bitmask-macros.patch [bz#1004347] +- kvm-qcow2-Evaluate-overlap-check-options.patch [bz#1004347] +- kvm-qapi-types.py-Split-off-generate_struct_fields.patch [bz#978402] +- kvm-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch [bz#978402] +- kvm-qapi-types-visit.py-Pass-whole-expr-dict-for-structs.patch [bz#978402] +- kvm-qapi-types-visit.py-Inheritance-for-structs.patch [bz#978402] +- kvm-blockdev-Introduce-DriveInfo.enable_auto_del.patch [bz#978402] +- kvm-Implement-qdict_flatten.patch [bz#978402] +- kvm-blockdev-blockdev-add-QMP-command.patch [bz#978402] +- kvm-blockdev-Separate-ID-generation-from-DriveInfo-creat.patch [bz#978402] +- kvm-blockdev-Pass-QDict-to-blockdev_init.patch [bz#978402] +- kvm-blockdev-Move-parsing-of-media-option-to-drive_init.patch [bz#978402] +- kvm-blockdev-Move-parsing-of-if-option-to-drive_init.patch [bz#978402] +- kvm-blockdev-Moving-parsing-of-geometry-options-to-drive.patch [bz#978402] +- kvm-blockdev-Move-parsing-of-boot-option-to-drive_init.patch [bz#978402] +- kvm-blockdev-Move-bus-unit-index-processing-to-drive_ini.patch [bz#978402] +- kvm-blockdev-Move-virtio-blk-device-creation-to-drive_in.patch [bz#978402] +- kvm-blockdev-Remove-IF_-check-for-read-only-blockdev_ini.patch [bz#978402] +- kvm-qemu-iotests-Check-autodel-behaviour-for-device_del.patch [bz#978402] +- kvm-blockdev-Remove-media-parameter-from-blockdev_init.patch [bz#978402] +- kvm-blockdev-Don-t-disable-COR-automatically-with-blockd.patch [bz#978402] +- kvm-blockdev-blockdev_init-error-conversion.patch [bz#978402] +- kvm-sd-Avoid-access-to-NULL-BlockDriverState.patch [bz#978402] +- kvm-blockdev-fix-cdrom-read_only-flag.patch [bz#978402] +- kvm-block-fix-backing-file-overriding.patch [bz#978402] +- kvm-block-Disable-BDRV_O_COPY_ON_READ-for-the-backing-fi.patch [bz#978402] +- kvm-block-Don-t-copy-backing-file-name-on-error.patch [bz#978402] +- kvm-qemu-iotests-Try-creating-huge-qcow2-image.patch [bz#980771] +- kvm-block-move-qmp-and-info-dump-related-code-to-block-q.patch [bz#980771] +- kvm-block-dump-snapshot-and-image-info-to-specified-outp.patch [bz#980771] +- kvm-block-add-snapshot-info-query-function-bdrv_query_sn.patch [bz#980771] +- kvm-block-add-image-info-query-function-bdrv_query_image.patch [bz#980771] +- kvm-qmp-add-ImageInfo-in-BlockDeviceInfo-used-by-query-b.patch [bz#980771] +- kvm-vmdk-Implement-.bdrv_has_zero_init.patch [bz#980771] +- kvm-qemu-iotests-Add-basic-ability-to-use-binary-sample-.patch [bz#980771] +- kvm-qemu-iotests-Quote-TEST_IMG-and-TEST_DIR-usage.patch [bz#980771] +- kvm-qemu-iotests-fix-test-case-059.patch [bz#980771] +- kvm-qapi-Add-ImageInfoSpecific-type.patch [bz#980771] +- kvm-block-Add-bdrv_get_specific_info.patch [bz#980771] +- kvm-block-qapi-Human-readable-ImageInfoSpecific-dump.patch [bz#980771] +- kvm-qcow2-Add-support-for-ImageInfoSpecific.patch [bz#980771] +- kvm-qemu-iotests-Discard-specific-info-in-_img_info.patch [bz#980771] +- kvm-qemu-iotests-Additional-info-from-qemu-img-info.patch [bz#980771] +- kvm-vmdk-convert-error-code-to-use-errp.patch [bz#980771] +- kvm-vmdk-refuse-enabling-zeroed-grain-with-flat-images.patch [bz#980771] +- kvm-qapi-Add-optional-field-compressed-to-ImageInfo.patch [bz#980771] +- kvm-vmdk-Only-read-cid-from-image-file-when-opening.patch [bz#980771] +- kvm-vmdk-Implment-bdrv_get_specific_info.patch [bz#980771] +- Resolves: bz#1004347 + (Backport qcow2 corruption prevention patches) +- Resolves: bz#1026524 + (Backport block layer error parameter patches) +- Resolves: bz#978402 + ([RFE] Add discard support to qemu-kvm layer) +- Resolves: bz#980771 + ([RFE] qemu-img should be able to tell the compat version of a qcow2 image) + +* Thu Nov 07 2013 Miroslav Rezanina - 1.5.3-15.el7 +- kvm-cow-make-reads-go-at-a-decent-speed.patch [bz#989646] +- kvm-cow-make-writes-go-at-a-less-indecent-speed.patch [bz#989646] +- kvm-cow-do-not-call-bdrv_co_is_allocated.patch [bz#989646] +- kvm-block-keep-bs-total_sectors-up-to-date-even-for-grow.patch [bz#989646] +- kvm-block-make-bdrv_co_is_allocated-static.patch [bz#989646] +- kvm-block-do-not-use-total_sectors-in-bdrv_co_is_allocat.patch [bz#989646] +- kvm-block-remove-bdrv_is_allocated_above-bdrv_co_is_allo.patch [bz#989646] +- kvm-block-expect-errors-from-bdrv_co_is_allocated.patch [bz#989646] +- kvm-block-Fix-compiler-warning-Werror-uninitialized.patch [bz#989646] +- kvm-qemu-img-always-probe-the-input-image-for-allocated-.patch [bz#989646] +- kvm-block-make-bdrv_has_zero_init-return-false-for-copy-.patch [bz#989646] +- kvm-block-introduce-bdrv_get_block_status-API.patch [bz#989646] +- kvm-block-define-get_block_status-return-value.patch [bz#989646] +- kvm-block-return-get_block_status-data-and-flags-for-for.patch [bz#989646] +- kvm-block-use-bdrv_has_zero_init-to-return-BDRV_BLOCK_ZE.patch [bz#989646] +- kvm-block-return-BDRV_BLOCK_ZERO-past-end-of-backing-fil.patch [bz#989646] +- kvm-qemu-img-add-a-map-subcommand.patch [bz#989646] +- kvm-docs-qapi-document-qemu-img-map.patch [bz#989646] +- kvm-raw-posix-return-get_block_status-data-and-flags.patch [bz#989646] +- kvm-raw-posix-report-unwritten-extents-as-zero.patch [bz#989646] +- kvm-block-add-default-get_block_status-implementation-fo.patch [bz#989646] +- kvm-block-look-for-zero-blocks-in-bs-file.patch [bz#989646] +- kvm-qemu-img-fix-invalid-JSON.patch [bz#989646] +- kvm-block-get_block_status-set-pnum-0-on-error.patch [bz#989646] +- kvm-block-get_block_status-avoid-segfault-if-there-is-no.patch [bz#989646] +- kvm-block-get_block_status-avoid-redundant-callouts-on-r.patch [bz#989646] +- kvm-qcow2-Restore-total_sectors-value-in-save_vmstate.patch [bz#1025740] +- kvm-qcow2-Unset-zero_beyond_eof-in-save_vmstate.patch [bz#1025740] +- kvm-qemu-iotests-Test-for-loading-VM-state-from-qcow2.patch [bz#1025740] +- kvm-apic-rename-apic-specific-bitopts.patch [bz#1001216] +- kvm-hw-import-bitmap-operations-in-qdev-core-header.patch [bz#1001216] +- kvm-qemu-help-Sort-devices-by-logical-functionality.patch [bz#1001216] +- kvm-devices-Associate-devices-to-their-logical-category.patch [bz#1001216] +- kvm-Mostly-revert-qemu-help-Sort-devices-by-logical-func.patch [bz#1001216] +- kvm-qdev-monitor-Group-device_add-help-and-info-qdm-by-c.patch [bz#1001216] +- kvm-qdev-Replace-no_user-by-cannot_instantiate_with_devi.patch [bz#1001216] +- kvm-sysbus-Set-cannot_instantiate_with_device_add_yet.patch [bz#1001216] +- kvm-cpu-Document-why-cannot_instantiate_with_device_add_.patch [bz#1001216] +- kvm-apic-Document-why-cannot_instantiate_with_device_add.patch [bz#1001216] +- kvm-pci-host-Consistently-set-cannot_instantiate_with_de.patch [bz#1001216] +- kvm-ich9-Document-why-cannot_instantiate_with_device_add.patch [bz#1001216] +- kvm-piix3-piix4-Clean-up-use-of-cannot_instantiate_with_.patch [bz#1001216] +- kvm-vt82c686-Clean-up-use-of-cannot_instantiate_with_dev.patch [bz#1001216] +- kvm-isa-Clean-up-use-of-cannot_instantiate_with_device_a.patch [bz#1001216] +- kvm-qdev-Do-not-let-the-user-try-to-device_add-when-it-c.patch [bz#1001216] +- kvm-rhel-Revert-unwanted-cannot_instantiate_with_device_.patch [bz#1001216] +- kvm-rhel-Revert-downstream-changes-to-unused-default-con.patch [bz#1001076] +- kvm-rhel-Drop-cfi.pflash01-and-isa-ide-device.patch [bz#1001076] +- kvm-rhel-Drop-isa-vga-device.patch [bz#1001088] +- kvm-rhel-Make-isa-cirrus-vga-device-unavailable.patch [bz#1001088] +- kvm-rhel-Make-ccid-card-emulated-device-unavailable.patch [bz#1001123] +- kvm-x86-fix-migration-from-pre-version-12.patch [bz#1005695] +- kvm-x86-cpuid-reconstruct-leaf-0Dh-data.patch [bz#1005695] +- kvm-kvmvapic-Catch-invalid-ROM-size.patch [bz#920021] +- kvm-kvmvapic-Enter-inactive-state-on-hardware-reset.patch [bz#920021] +- kvm-kvmvapic-Clear-also-physical-ROM-address-when-enteri.patch [bz#920021] +- kvm-block-optionally-disable-live-block-jobs.patch [bz#987582] +- kvm-rpm-spec-template-disable-live-block-ops-for-rhel-en.patch [bz#987582] +- kvm-migration-disable-live-block-migration-b-i-for-rhel-.patch [bz#1022392] +- kvm-Build-ceph-rbd-only-for-rhev.patch [bz#987583] +- kvm-spec-Disable-host-cdrom-RHEL-only.patch [bz#760885] +- kvm-rhel-Make-pci-serial-2x-and-pci-serial-4x-device-una.patch [bz#1001180] +- kvm-usb-host-libusb-Fix-reset-handling.patch [bz#980415] +- kvm-usb-host-libusb-Configuration-0-may-be-a-valid-confi.patch [bz#980383] +- kvm-usb-host-libusb-Detach-kernel-drivers-earlier.patch [bz#980383] +- kvm-monitor-Remove-pci_add-command-for-Red-Hat-Enterpris.patch [bz#1010858] +- kvm-monitor-Remove-pci_del-command-for-Red-Hat-Enterpris.patch [bz#1010858] +- kvm-monitor-Remove-usb_add-del-commands-for-Red-Hat-Ente.patch [bz#1010858] +- kvm-monitor-Remove-host_net_add-remove-for-Red-Hat-Enter.patch [bz#1010858] +- kvm-fw_cfg-add-API-to-find-FW-cfg-object.patch [bz#990601] +- kvm-pvpanic-use-FWCfgState-explicitly.patch [bz#990601] +- kvm-pvpanic-initialization-cleanup.patch [bz#990601] +- kvm-pvpanic-fix-fwcfg-for-big-endian-hosts.patch [bz#990601] +- kvm-hw-misc-make-pvpanic-known-to-user.patch [bz#990601] +- kvm-gdbstub-do-not-restart-crashed-guest.patch [bz#990601] +- kvm-gdbstub-fix-for-commit-87f25c12bfeaaa0c41fb857713bbc.patch [bz#990601] +- kvm-vl-allow-cont-from-panicked-state.patch [bz#990601] +- kvm-hw-misc-don-t-create-pvpanic-device-by-default.patch [bz#990601] +- kvm-block-vhdx-add-migration-blocker.patch [bz#1007176] +- kvm-qemu-kvm.spec-add-vhdx-to-the-read-only-block-driver.patch [bz#1007176] +- kvm-qemu-kvm.spec-Add-VPC-VHD-driver-to-the-block-read-o.patch [bz#1007176] +- Resolves: bz#1001076 + (Disable or remove other block devices we won't support) +- Resolves: bz#1001088 + (Disable or remove display devices we won't support) +- Resolves: bz#1001123 + (Disable or remove device ccid-card-emulated) +- Resolves: bz#1001180 + (Disable or remove devices pci-serial-2x, pci-serial-4x) +- Resolves: bz#1001216 + (Fix no_user or provide another way make devices unavailable with -device / device_add) +- Resolves: bz#1005695 + (QEMU should hide CPUID.0Dh values that it does not support) +- Resolves: bz#1007176 + (Add VPC and VHDX file formats as supported in qemu-kvm (read-only)) +- Resolves: bz#1010858 + (Disable unused human monitor commands) +- Resolves: bz#1022392 + (Disable live-storage-migration in qemu-kvm (migrate -b/-i)) +- Resolves: bz#1025740 + (Saving VM state on qcow2 images results in VM state corruption) +- Resolves: bz#760885 + (Disable host cdrom passthrough) +- Resolves: bz#920021 + (qemu-kvm segment fault when reboot guest after hot unplug device with option ROM) +- Resolves: bz#980383 + (The usb3.0 stick can't be returned back to host after shutdown guest with usb3.0 pass-through) +- Resolves: bz#980415 + (libusbx: error [_open_sysfs_attr] open /sys/bus/usb/devices/4-1/bConfigurationValue failed ret=-1 errno=2) +- Resolves: bz#987582 + (Initial Virtualization Differentiation for RHEL7 (Live snapshots)) +- Resolves: bz#987583 + (Initial Virtualization Differentiation for RHEL7 (Ceph enablement)) +- Resolves: bz#989646 + (Support backup vendors in qemu to access qcow disk readonly) +- Resolves: bz#990601 + (pvpanic device triggers guest bugs when present by default) + +* Wed Nov 06 2013 Miroslav Rezanina - 1.5.3-14.el7 +- kvm-target-i386-remove-tabs-from-target-i386-cpu.h.patch [bz#928867] +- kvm-migrate-vPMU-state.patch [bz#928867] +- kvm-blockdev-do-not-default-cache.no-flush-to-true.patch [bz#1009993] +- kvm-virtio-blk-do-not-relay-a-previous-driver-s-WCE-conf.patch [bz#1009993] +- kvm-rng-random-use-error_setg_file_open.patch [bz#907743] +- kvm-block-mirror_complete-use-error_setg_file_open.patch [bz#907743] +- kvm-blockdev-use-error_setg_file_open.patch [bz#907743] +- kvm-cpus-use-error_setg_file_open.patch [bz#907743] +- kvm-dump-qmp_dump_guest_memory-use-error_setg_file_open.patch [bz#907743] +- kvm-savevm-qmp_xen_save_devices_state-use-error_setg_fil.patch [bz#907743] +- kvm-block-bdrv_reopen_prepare-don-t-use-QERR_OPEN_FILE_F.patch [bz#907743] +- kvm-qerror-drop-QERR_OPEN_FILE_FAILED-macro.patch [bz#907743] +- kvm-rhel-Drop-ivshmem-device.patch [bz#787463] +- kvm-usb-remove-old-usb-host-code.patch [bz#1001144] +- kvm-Add-rhel6-pxe-roms-files.patch [bz#997702] +- kvm-Add-rhel6-pxe-rom-to-redhat-rpm.patch [bz#997702] +- kvm-Fix-migration-from-rhel6.5-to-rhel7-with-ipxe.patch [bz#997702] +- kvm-pc-Don-t-prematurely-explode-QEMUMachineInitArgs.patch [bz#994490] +- kvm-pc-Don-t-explode-QEMUMachineInitArgs-into-local-vari.patch [bz#994490] +- kvm-smbios-Normalize-smbios_entry_add-s-error-handling-t.patch [bz#994490] +- kvm-smbios-Convert-to-QemuOpts.patch [bz#994490] +- kvm-smbios-Improve-diagnostics-for-conflicting-entries.patch [bz#994490] +- kvm-smbios-Make-multiple-smbios-type-accumulate-sanely.patch [bz#994490] +- kvm-smbios-Factor-out-smbios_maybe_add_str.patch [bz#994490] +- kvm-hw-Pass-QEMUMachine-to-its-init-method.patch [bz#994490] +- kvm-smbios-Set-system-manufacturer-product-version-by-de.patch [bz#994490] +- kvm-smbios-Decouple-system-product-from-QEMUMachine.patch [bz#994490] +- kvm-rhel-SMBIOS-type-1-branding.patch [bz#994490] +- kvm-Add-disable-rhev-features-option-to-configure.patch [] +- Resolves: bz#1001144 + (Disable or remove device usb-host-linux) +- Resolves: bz#1009993 + (RHEL7 guests do not issue fdatasyncs on virtio-blk) +- Resolves: bz#787463 + (disable ivshmem (was: [Hitachi 7.0 FEAT] Support ivshmem (Inter-VM Shared Memory))) +- Resolves: bz#907743 + (qemu-ga: empty reason string for OpenFileFailed error) +- Resolves: bz#928867 + (Virtual PMU support during live migration - qemu-kvm) +- Resolves: bz#994490 + (Set per-machine-type SMBIOS strings) +- Resolves: bz#997702 + (Migration from RHEL6.5 host to RHEL7.0 host is failed with virtio-net device) + +* Tue Nov 05 2013 Miroslav Rezanina - 1.5.3-13.el7 +- kvm-seabios-paravirt-allow-more-than-1TB-in-x86-guest.patch [bz#989677] +- kvm-scsi-prefer-UUID-to-VM-name-for-the-initiator-name.patch [bz#1006468] +- kvm-Fix-incorrect-rhel_rhev_conflicts-macro-usage.patch [bz#1017693] +- Resolves: bz#1006468 + (libiscsi initiator name should use vm UUID) +- Resolves: bz#1017693 + (incorrect use of rhel_rhev_conflicts) +- Resolves: bz#989677 + ([HP 7.0 FEAT]: Increase KVM guest supported memory to 4TiB) + +* Mon Nov 04 2013 Michal Novotny - 1.5.3-12.el7 +- kvm-vl-Clean-up-parsing-of-boot-option-argument.patch [bz#997817] +- kvm-qemu-option-check_params-is-now-unused-drop-it.patch [bz#997817] +- kvm-vl-Fix-boot-order-and-once-regressions-and-related-b.patch [bz#997817] +- kvm-vl-Rename-boot_devices-to-boot_order-for-consistency.patch [bz#997817] +- kvm-pc-Make-no-fd-bootchk-stick-across-boot-order-change.patch [bz#997817] +- kvm-doc-Drop-ref-to-Bochs-from-no-fd-bootchk-documentati.patch [bz#997817] +- kvm-libqtest-Plug-fd-and-memory-leaks-in-qtest_quit.patch [bz#997817] +- kvm-libqtest-New-qtest_end-to-go-with-qtest_start.patch [bz#997817] +- kvm-qtest-Don-t-reset-on-qtest-chardev-connect.patch [bz#997817] +- kvm-boot-order-test-New-covering-just-PC-for-now.patch [bz#997817] +- kvm-qemu-ga-execute-fsfreeze-freeze-in-reverse-order-of-.patch [bz#1019352] +- kvm-rbd-link-and-load-librbd-dynamically.patch [bz#989608] +- kvm-rbd-Only-look-for-qemu-specific-copy-of-librbd.so.1.patch [bz#989608] +- kvm-spec-Whitelist-rbd-block-driver.patch [bz#989608] +- Resolves: bz#1019352 + (qemu-guest-agent: "guest-fsfreeze-freeze" deadlocks if the guest have mounted disk images) +- Resolves: bz#989608 + ([7.0 FEAT] qemu runtime support for librbd backend (ceph)) +- Resolves: bz#997817 + (-boot order and -boot once regressed since RHEL-6) + +* Thu Oct 31 2013 Miroslav Rezanina - 1.5.3-11.el7 +- kvm-chardev-fix-pty_chr_timer.patch [bz#994414] +- kvm-qemu-socket-zero-initialize-SocketAddress.patch [bz#922010] +- kvm-qemu-socket-drop-pointless-allocation.patch [bz#922010] +- kvm-qemu-socket-catch-monitor_get_fd-failures.patch [bz#922010] +- kvm-qemu-char-check-optional-fields-using-has_.patch [bz#922010] +- kvm-error-add-error_setg_file_open-helper.patch [bz#922010] +- kvm-qemu-char-use-more-specific-error_setg_-variants.patch [bz#922010] +- kvm-qemu-char-print-notification-to-stderr.patch [bz#922010] +- kvm-qemu-char-fix-documentation-for-telnet-wait-socket-f.patch [bz#922010] +- kvm-qemu-char-don-t-leak-opts-on-error.patch [bz#922010] +- kvm-qemu-char-use-ChardevBackendKind-in-CharDriver.patch [bz#922010] +- kvm-qemu-char-minor-mux-chardev-fixes.patch [bz#922010] +- kvm-qemu-char-add-chardev-mux-support.patch [bz#922010] +- kvm-qemu-char-report-udp-backend-errors.patch [bz#922010] +- kvm-qemu-socket-don-t-leak-opts-on-error.patch [bz#922010] +- kvm-chardev-handle-qmp_chardev_add-KIND_MUX-failure.patch [bz#922010] +- kvm-acpi-piix4-Enable-qemu-kvm-compatibility-mode.patch [bz#1019474] +- kvm-target-i386-support-loading-of-cpu-xsave-subsection.patch [bz#1004743] +- Resolves: bz#1004743 + (XSAVE migration format not compatible between RHEL6 and RHEL7) +- Resolves: bz#1019474 + (RHEL-7 can't load piix4_pm migration section from RHEL-6.5) +- Resolves: bz#922010 + (RFE: support hotplugging chardev & serial ports) +- Resolves: bz#994414 + (hot-unplug chardev with pty backend caused qemu Segmentation fault) + +* Thu Oct 17 2013 Miroslav Rezanina - 1.5.3-10.el7 +- kvm-xhci-fix-endpoint-interval-calculation.patch [bz#1001604] +- kvm-xhci-emulate-intr-endpoint-intervals-correctly.patch [bz#1001604] +- kvm-xhci-reset-port-when-disabling-slot.patch [bz#1001604] +- kvm-Revert-usb-hub-report-status-changes-only-once.patch [bz#1001604] +- kvm-target-i386-Set-model-6-on-qemu64-qemu32-CPU-models.patch [bz#1004290] +- kvm-pc-rhel6-doesn-t-have-APIC-on-pentium-CPU-models.patch [bz#918907] +- kvm-pc-RHEL-6-had-x2apic-set-on-Opteron_G-123.patch [bz#918907] +- kvm-pc-RHEL-6-don-t-have-RDTSCP.patch [bz#918907] +- kvm-scsi-Fix-scsi_bus_legacy_add_drive-scsi-generic-with.patch [bz#1009285] +- kvm-seccomp-fine-tuning-whitelist-by-adding-times.patch [bz#1004175] +- kvm-block-add-bdrv_write_zeroes.patch [bz#921465] +- kvm-block-raw-add-bdrv_co_write_zeroes.patch [bz#921465] +- kvm-rdma-export-qemu_fflush.patch [bz#921465] +- kvm-block-migration-efficiently-encode-zero-blocks.patch [bz#921465] +- kvm-Fix-real-mode-guest-migration.patch [bz#921465] +- kvm-Fix-real-mode-guest-segments-dpl-value-in-savevm.patch [bz#921465] +- kvm-migration-add-autoconvergence-documentation.patch [bz#921465] +- kvm-migration-send-total-time-in-QMP-at-completed-stage.patch [bz#921465] +- kvm-migration-don-t-use-uninitialized-variables.patch [bz#921465] +- kvm-pc-drop-external-DSDT-loading.patch [bz#921465] +- kvm-hda-codec-refactor-common-definitions-into-a-header-.patch [bz#954195] +- kvm-hda-codec-make-mixemu-selectable-at-runtime.patch [bz#954195] +- kvm-audio-remove-CONFIG_MIXEMU-configure-option.patch [bz#954195] +- kvm-pc_piix-disable-mixer-for-6.4.0-machine-types-and-be.patch [bz#954195] +- kvm-spec-mixemu-config-option-is-no-longer-supported-and.patch [bz#954195] +- Resolves: bz#1001604 + (usb hub doesn't work properly (win7 sees downstream port #1 only).) +- Resolves: bz#1004175 + ('-sandbox on' option cause qemu-kvm process hang) +- Resolves: bz#1004290 + (Use model 6 for qemu64 and intel cpus) +- Resolves: bz#1009285 + (-device usb-storage,serial=... crashes with SCSI generic drive) +- Resolves: bz#918907 + (provide backwards-compatible RHEL specific machine types in QEMU - CPU features) +- Resolves: bz#921465 + (Migration can not finished even the "remaining ram" is already 0 kb) +- Resolves: bz#954195 + (RHEL machines <=6.4 should not use mixemu) + +* Thu Oct 10 2013 Miroslav Rezanina - 1.5.3-9.el7 +- kvm-qxl-fix-local-renderer.patch [bz#1005036] +- kvm-spec-include-userspace-iSCSI-initiator-in-block-driv.patch [bz#923843] +- kvm-linux-headers-update-to-kernel-3.10.0-26.el7.patch [bz#1008987] +- kvm-target-i386-add-feature-kvm_pv_unhalt.patch [bz#1008987] +- kvm-warn-if-num-cpus-is-greater-than-num-recommended.patch [bz#1010881] +- kvm-char-move-backends-io-watch-tag-to-CharDriverState.patch [bz#1007222] +- kvm-char-use-common-function-to-disable-callbacks-on-cha.patch [bz#1007222] +- kvm-char-remove-watch-callback-on-chardev-detach-from-fr.patch [bz#1007222] +- kvm-block-don-t-lose-data-from-last-incomplete-sector.patch [bz#1017049] +- kvm-vmdk-fix-cluster-size-check-for-flat-extents.patch [bz#1017049] +- kvm-qemu-iotests-add-monolithicFlat-creation-test-to-059.patch [bz#1017049] +- Resolves: bz#1005036 + (When using “-vga qxl” together with “-display vnc=:5” or “-display sdl” qemu displays pixel garbage) +- Resolves: bz#1007222 + (QEMU core dumped when do hot-unplug virtio serial port during transfer file between host to guest with virtio serial through TCP socket) +- Resolves: bz#1008987 + (pvticketlocks: add kvm feature kvm_pv_unhalt) +- Resolves: bz#1010881 + (backport vcpu soft limit warning) +- Resolves: bz#1017049 + (qemu-img refuses to open the vmdk format image its created) +- Resolves: bz#923843 + (include userspace iSCSI initiator in block driver whitelist) + +* Wed Oct 09 2013 Miroslav Rezanina - qemu-kvm-1.5.3-8.el7 +- kvm-vmdk-Make-VMDK3Header-and-VmdkGrainMarker-QEMU_PACKE.patch [bz#995866] +- kvm-vmdk-use-unsigned-values-for-on-disk-header-fields.patch [bz#995866] +- kvm-qemu-iotests-add-poke_file-utility-function.patch [bz#995866] +- kvm-qemu-iotests-add-empty-test-case-for-vmdk.patch [bz#995866] +- kvm-vmdk-check-granularity-field-in-opening.patch [bz#995866] +- kvm-vmdk-check-l2-table-size-when-opening.patch [bz#995866] +- kvm-vmdk-check-l1-size-before-opening-image.patch [bz#995866] +- kvm-vmdk-use-heap-allocation-for-whole_grain.patch [bz#995866] +- kvm-vmdk-rename-num_gtes_per_gte-to-num_gtes_per_gt.patch [bz#995866] +- kvm-vmdk-Move-l1_size-check-into-vmdk_add_extent.patch [bz#995866] +- kvm-vmdk-fix-L1-and-L2-table-size-in-vmdk3-open.patch [bz#995866] +- kvm-vmdk-support-vmfsSparse-files.patch [bz#995866] +- kvm-vmdk-support-vmfs-files.patch [bz#995866] +- Resolves: bz#995866 + (fix vmdk support to ESX images) + +* Thu Sep 26 2013 Miroslav Rezanina - qemu-kvm-1.5.3-7.el7 +- kvm-spice-fix-display-initialization.patch [bz#974887] +- kvm-Remove-i82550-network-card-emulation.patch [bz#921983] +- kvm-Remove-usb-wacom-tablet.patch [bz#903914] +- kvm-Disable-usb-uas.patch [bz#903914] +- kvm-Disable-vhost-scsi.patch [bz#994642] +- kvm-Remove-no-hpet-option.patch [bz#947441] +- kvm-Disable-isa-parallel.patch [bz#1002286] +- kvm-xhci-implement-warm-port-reset.patch [bz#949514] +- kvm-usb-add-serial-bus-property.patch [bz#953304] +- kvm-rhel6-compat-usb-serial-numbers.patch [bz#953304] +- kvm-vmdk-fix-comment-for-vmdk_co_write_zeroes.patch [bz#995866] +- kvm-gluster-Add-image-resize-support.patch [bz#1007226] +- kvm-block-Introduce-bs-zero_beyond_eof.patch [bz#1007226] +- kvm-block-Produce-zeros-when-protocols-reading-beyond-en.patch [bz#1007226] +- kvm-gluster-Abort-on-AIO-completion-failure.patch [bz#1007226] +- kvm-Preparation-for-usb-bt-dongle-conditional-build.patch [bz#1001131] +- kvm-Remove-dev-bluetooth.c-dependency-from-vl.c.patch [bz#1001131] +- kvm-exec-Fix-Xen-RAM-allocation-with-unusual-options.patch [bz#1009328] +- kvm-exec-Clean-up-fall-back-when-mem-path-allocation-fai.patch [bz#1009328] +- kvm-exec-Reduce-ifdeffery-around-mem-path.patch [bz#1009328] +- kvm-exec-Simplify-the-guest-physical-memory-allocation-h.patch [bz#1009328] +- kvm-exec-Drop-incorrect-dead-S390-code-in-qemu_ram_remap.patch [bz#1009328] +- kvm-exec-Clean-up-unnecessary-S390-ifdeffery.patch [bz#1009328] +- kvm-exec-Don-t-abort-when-we-can-t-allocate-guest-memory.patch [bz#1009328] +- kvm-pc_sysfw-Fix-ISA-BIOS-init-for-ridiculously-big-flas.patch [bz#1009328] +- kvm-virtio-scsi-Make-type-virtio-scsi-common-abstract.patch [bz#903918] +- kvm-qga-move-logfiles-to-new-directory-for-easier-SELinu.patch [bz#1009491] +- kvm-target-i386-add-cpu64-rhel6-CPU-model.patch [bz#918907] +- kvm-fix-steal-time-MSR-vmsd-callback-to-proper-opaque-ty.patch [bz#903889] +- Resolves: bz#1001131 + (Disable or remove device usb-bt-dongle) +- Resolves: bz#1002286 + (Disable or remove device isa-parallel) +- Resolves: bz#1007226 + (Introduce bs->zero_beyond_eof) +- Resolves: bz#1009328 + ([RFE] Nicer error report when qemu-kvm can't allocate guest RAM) +- Resolves: bz#1009491 + (move qga logfiles to new /var/log/qemu-ga/ directory [RHEL-7]) +- Resolves: bz#903889 + (The value of steal time in "top" command always is "0.0% st" after guest migration) +- Resolves: bz#903914 + (Disable or remove usb related devices that we will not support) +- Resolves: bz#903918 + (Disable or remove emulated SCSI devices we will not support) +- Resolves: bz#918907 + (provide backwards-compatible RHEL specific machine types in QEMU - CPU features) +- Resolves: bz#921983 + (Disable or remove emulated network devices that we will not support) +- Resolves: bz#947441 + (HPET device must be disabled) +- Resolves: bz#949514 + (fail to passthrough the USB3.0 stick to windows guest with xHCI controller under pc-i440fx-1.4) +- Resolves: bz#953304 + (Serial number of some USB devices must be fixed for older RHEL machine types) +- Resolves: bz#974887 + (the screen of guest fail to display correctly when use spice + qxl driver) +- Resolves: bz#994642 + (should disable vhost-scsi) +- Resolves: bz#995866 + (fix vmdk support to ESX images) + +* Mon Sep 23 2013 Paolo Bonzini - qemu-kvm-1.5.3-6.el7 +- re-enable spice +- Related: #979953 + +* Mon Sep 23 2013 Paolo Bonzini - qemu-kvm-1.5.3-5.el7 +- temporarily disable spice until libiscsi rebase is complete +- Related: #979953 + +* Thu Sep 19 2013 Michal Novotny - qemu-kvm-1.5.3-4.el7 +- kvm-block-package-preparation-code-in-qmp_transaction.patch [bz#1005818] +- kvm-block-move-input-parsing-code-in-qmp_transaction.patch [bz#1005818] +- kvm-block-package-committing-code-in-qmp_transaction.patch [bz#1005818] +- kvm-block-package-rollback-code-in-qmp_transaction.patch [bz#1005818] +- kvm-block-make-all-steps-in-qmp_transaction-as-callback.patch [bz#1005818] +- kvm-blockdev-drop-redundant-proto_drv-check.patch [bz#1005818] +- kvm-block-Don-t-parse-protocol-from-file.filename.patch [bz#1005818] +- kvm-Revert-block-Disable-driver-specific-options-for-1.5.patch [bz#1005818] +- kvm-qcow2-Add-refcount-update-reason-to-all-callers.patch [bz#1005818] +- kvm-qcow2-Options-to-enable-discard-for-freed-clusters.patch [bz#1005818] +- kvm-qcow2-Batch-discards.patch [bz#1005818] +- kvm-block-Always-enable-discard-on-the-protocol-level.patch [bz#1005818] +- kvm-qapi.py-Avoid-code-duplication.patch [bz#1005818] +- kvm-qapi.py-Allow-top-level-type-reference-for-command-d.patch [bz#1005818] +- kvm-qapi-schema-Use-BlockdevSnapshot-type-for-blockdev-s.patch [bz#1005818] +- kvm-qapi-types.py-Implement-base-for-unions.patch [bz#1005818] +- kvm-qapi-visit.py-Split-off-generate_visit_struct_fields.patch [bz#1005818] +- kvm-qapi-visit.py-Implement-base-for-unions.patch [bz#1005818] +- kvm-docs-Document-QAPI-union-types.patch [bz#1005818] +- kvm-qapi-Add-visitor-for-implicit-structs.patch [bz#1005818] +- kvm-qapi-Flat-unions-with-arbitrary-discriminator.patch [bz#1005818] +- kvm-qapi-Add-consume-argument-to-qmp_input_get_object.patch [bz#1005818] +- kvm-qapi.py-Maintain-a-list-of-union-types.patch [bz#1005818] +- kvm-qapi-qapi-types.py-native-list-support.patch [bz#1005818] +- kvm-qapi-Anonymous-unions.patch [bz#1005818] +- kvm-block-Allow-driver-option-on-the-top-level.patch [bz#1005818] +- kvm-QemuOpts-Add-qemu_opt_unset.patch [bz#1005818] +- kvm-blockdev-Rename-I-O-throttling-options-for-QMP.patch [bz#1005818] +- kvm-qemu-iotests-Update-051-reference-output.patch [bz#1005818] +- kvm-blockdev-Rename-readonly-option-to-read-only.patch [bz#1005818] +- kvm-blockdev-Split-up-cache-option.patch [bz#1005818] +- kvm-qcow2-Use-dashes-instead-of-underscores-in-options.patch [bz#1005818] +- kvm-qemu-iotests-filter-QEMU-version-in-monitor-banner.patch [bz#1006959] +- kvm-tests-set-MALLOC_PERTURB_-to-expose-memory-bugs.patch [bz#1006959] +- kvm-qemu-iotests-Whitespace-cleanup.patch [bz#1006959] +- kvm-qemu-iotests-Fixed-test-case-026.patch [bz#1006959] +- kvm-qemu-iotests-Fix-test-038.patch [bz#1006959] +- kvm-qemu-iotests-Remove-lsi53c895a-tests-from-051.patch [bz#1006959] +- Resolves: bz#1005818 + (qcow2: Backport discard command line options) +- Resolves: bz#1006959 + (qemu-iotests false positives) + +* Thu Aug 29 2013 Miroslav Rezanina - qemu-kvm-1.5.3-3.el7 +- Fix rhel/rhev split + +* Thu Aug 29 2013 Miroslav Rezanina - qemu-kvm-1.5.3-2.el7 +- kvm-osdep-add-qemu_get_local_state_pathname.patch [bz#964304] +- kvm-qga-determine-default-state-dir-and-pidfile-dynamica.patch [bz#964304] +- kvm-configure-don-t-save-any-fixed-local_statedir-for-wi.patch [bz#964304] +- kvm-qga-create-state-directory-on-win32.patch [bz#964304] +- kvm-qga-save-state-directory-in-ga_install_service-RHEL-.patch [bz#964304] +- kvm-Makefile-create-.-var-run-when-installing-the-POSIX-.patch [bz#964304] +- kvm-qemu-option-Fix-qemu_opts_find-for-null-id-arguments.patch [bz#980782] +- kvm-qemu-option-Fix-qemu_opts_set_defaults-for-corner-ca.patch [bz#980782] +- kvm-vl-New-qemu_get_machine_opts.patch [bz#980782] +- kvm-Fix-machine-options-accel-kernel_irqchip-kvm_shadow_.patch [bz#980782] +- kvm-microblaze-Fix-latent-bug-with-default-DTB-lookup.patch [bz#980782] +- kvm-Simplify-machine-option-queries-with-qemu_get_machin.patch [bz#980782] +- kvm-pci-add-VMSTATE_MSIX.patch [bz#838170] +- kvm-xhci-add-XHCISlot-addressed.patch [bz#838170] +- kvm-xhci-add-xhci_alloc_epctx.patch [bz#838170] +- kvm-xhci-add-xhci_init_epctx.patch [bz#838170] +- kvm-xhci-add-live-migration-support.patch [bz#838170] +- kvm-pc-set-level-xlevel-correctly-on-486-qemu32-CPU-mode.patch [bz#918907] +- kvm-pc-Remove-incorrect-rhel6.x-compat-model-value-for-C.patch [bz#918907] +- kvm-pc-rhel6.x-has-x2apic-present-on-Conroe-Penryn-Nehal.patch [bz#918907] +- kvm-pc-set-compat-CPUID-0x80000001-.EDX-bits-on-Westmere.patch [bz#918907] +- kvm-pc-Remove-PCLMULQDQ-from-Westmere-on-rhel6.x-machine.patch [bz#918907] +- kvm-pc-SandyBridge-rhel6.x-compat-fixes.patch [bz#918907] +- kvm-pc-Haswell-doesn-t-have-rdtscp-on-rhel6.x.patch [bz#918907] +- kvm-i386-fix-LAPIC-TSC-deadline-timer-save-restore.patch [bz#972433] +- kvm-all.c-max_cpus-should-not-exceed-KVM-vcpu-limit.patch [bz#996258] +- kvm-add-timestamp-to-error_report.patch [bz#906937] +- kvm-Convert-stderr-message-calling-error_get_pretty-to-e.patch [bz#906937] +- Resolves: bz#838170 + (Add live migration support for USB [xhci, usb-uas]) +- Resolves: bz#906937 + ([Hitachi 7.0 FEAT][QEMU]Add a time stamp to error message (*)) +- Resolves: bz#918907 + (provide backwards-compatible RHEL specific machine types in QEMU - CPU features) +- Resolves: bz#964304 + (Windows guest agent service failed to be started) +- Resolves: bz#972433 + ("INFO: rcu_sched detected stalls" after RHEL7 kvm vm migrated) +- Resolves: bz#980782 + (kernel_irqchip defaults to off instead of on without -machine) +- Resolves: bz#996258 + (boot guest with maxcpu=255 successfully but actually max number of vcpu is 160) + +* Wed Aug 28 2013 Miroslav Rezanina - 10:1.5.3-1 +- Rebase to qemu 1.5.3 + +* Tue Aug 20 2013 Miroslav Rezanina - 10:1.5.2-4 +- qemu: guest agent creates files with insecure permissions in deamon mode [rhel-7.0] (rhbz 974444) +- update qemu-ga config & init script in RHEL7 wrt. fsfreeze hook (rhbz 969942) +- RHEL7 does not have equivalent functionality for __com.redhat_qxl_screendump (rhbz 903910) +- SEP flag behavior for CPU models of RHEL6 machine types should be compatible (rhbz 960216) +- crash command can not read the dump-guest-memory file when paging=false [RHEL-7] (rhbz 981582) +- RHEL 7 qemu-kvm fails to build on F19 host due to libusb deprecated API (rhbz 996469) +- Live migration support in virtio-blk-data-plane (rhbz 995030) +- qemu-img resize can execute successfully even input invalid syntax (rhbz 992935) + +* Fri Aug 09 2013 Miroslav Rezanina - 10:1.5.2-3 +- query mem info from monitor would cause qemu-kvm hang [RHEL-7] (rhbz #970047) +- Throttle-down guest to help with live migration convergence (backport to RHEL7.0) (rhbz #985958) +- disable (for now) EFI-enabled roms (rhbz #962563) +- qemu-kvm "vPMU passthrough" mode breaks migration, shouldn't be enabled by default (rhbz #853101) +- Remove pending watches after virtserialport unplug (rhbz #992900) +- Containment of error when an SR-IOV device encounters an error... (rhbz #984604) + +* Wed Jul 31 2013 Miroslav Rezanina - 10:1.5.2-2 +- SPEC file prepared for RHEL/RHEV split (rhbz #987165) +- RHEL guest( sata disk ) can not boot up (rhbz #981723) +- Kill the "use flash device for BIOS unless KVM" misfeature (rhbz #963280) +- Provide RHEL-6 machine types (rhbz #983991) +- Change s3/s4 default to "disable". (rhbz #980840) +- Support Virtual Memory Disk Format in qemu (rhbz #836675) +- Glusterfs backend for QEMU (rhbz #805139) + +* Tue Jul 02 2013 Miroslav Rezanina - 10:1.5.2-1 +- Rebase to 1.5.2 + +* Tue Jul 02 2013 Miroslav Rezanina - 10:1.5.1-2 +- Fix package package version info (bz #952996) +- pc: Replace upstream machine types by RHEL-7 types (bz #977864) +- target-i386: Update model values on Conroe/Penryn/Nehalem CPU model (bz #861210) +- target-i386: Set level=4 on Conroe/Penryn/Nehalem (bz #861210) + +* Fri Jun 28 2013 Miroslav Rezanina - 10:1.5.1-1 +- Rebase to 1.5.1 +- Change epoch to 10 to obsolete RHEL-6 qemu-kvm-rhev package (bz #818626) + +* Fri May 24 2013 Miroslav Rezanina - 3:1.5.0-2 +- Enable werror (bz #948290) +- Enable nbd driver (bz #875871) +- Fix udev rules file location (bz #958860) +- Remove +x bit from systemd unit files (bz #965000) +- Drop unneeded kvm.modules on x86 (bz #963642) +- Fix build flags +- Enable libusb + +* Thu May 23 2013 Miroslav Rezanina - 3:1.5.0-1 +- Rebase to 1.5.0 + +* Tue Apr 23 2013 Miroslav Rezanina - 3:1.4.0-4 +- Enable build of libcacard subpackage for non-x86_64 archs (bz #873174) +- Enable build of qemu-img subpackage for non-x86_64 archs (bz #873174) +- Enable build of qemu-guest-agent subpackage for non-x86_64 archs (bz #873174) + +* Tue Apr 23 2013 Miroslav Rezanina - 3:1.4.0-3 +- Enable/disable features supported by rhel7 +- Use qemu-kvm instead of qemu in filenames and pathes + +* Fri Apr 19 2013 Daniel Mach - 3:1.4.0-2.1 +- Rebuild for cyrus-sasl + +* Fri Apr 05 2013 Miroslav Rezanina - 3:1.4.0-2 +- Synchronization with Fedora 19 package version 2:1.4.0-8 + +* Wed Apr 03 2013 Daniel Mach - 3:1.4.0-1.1 +- Rebuild for libseccomp + +* Thu Mar 07 2013 Miroslav Rezanina - 3:1.4.0-1 +- Rebase to 1.4.0 + +* Mon Feb 25 2013 Michal Novotny - 3:1.3.0-8 +- Missing package qemu-system-x86 in hardware certification kvm testing (bz#912433) +- Resolves: bz#912433 + (Missing package qemu-system-x86 in hardware certification kvm testing) + +* Fri Feb 22 2013 Alon Levy - 3:1.3.0-6 +- Bump epoch back to 3 since there has already been a 3 package release: + 3:1.2.0-20.el7 https://brewweb.devel.redhat.com/buildinfo?buildID=244866 +- Mark explicit libcacard dependency on new enough qemu-img to avoid conflict + since /usr/bin/vscclient was moved from qemu-img to libcacard subpackage. + +* Wed Feb 13 2013 Michal Novotny - 2:1.3.0-5 +- Fix patch contents for usb-redir (bz#895491) +- Resolves: bz#895491 + (PATCH: 0110-usb-redir-Add-flow-control-support.patch has been mangled on rebase !!) + +* Wed Feb 06 2013 Alon Levy - 2:1.3.0-4 +- Add patch from f19 package for libcacard missing error_set symbol. +- Resolves: bz#891552 + +* Mon Jan 07 2013 Michal Novotny - 2:1.3.0-3 +- Remove dependency on bogus qemu-kvm-kvm package [bz#870343] +- Resolves: bz#870343 + (qemu-kvm-1.2.0-16.el7 cant be installed) + +* Tue Dec 18 2012 Michal Novotny - 2:1.3.0-2 +- Rename qemu to qemu-kvm +- Move qemu-kvm to libexecdir + +* Fri Dec 07 2012 Cole Robinson - 2:1.3.0-1 +- Switch base tarball from qemu-kvm to qemu +- qemu 1.3 release +- Option to use linux VFIO driver to assign PCI devices +- Many USB3 improvements +- New paravirtualized hardware random number generator device. +- Support for Glusterfs volumes with "gluster://" -drive URI +- Block job commands for live block commit and storage migration + +* Wed Nov 28 2012 Alon Levy - 2:1.2.0-25 +* Merge libcacard into qemu, since they both use the same sources now. + +* Thu Nov 22 2012 Paolo Bonzini - 2:1.2.0-24 +- Move vscclient to qemu-common, qemu-nbd to qemu-img + +* Tue Nov 20 2012 Alon Levy - 2:1.2.0-23 +- Rewrite fix for bz #725965 based on fix for bz #867366 +- Resolve bz #867366 + +* Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-23 +- Backport --with separate_kvm support from EPEL branch + +* Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-22 +- Fix previous commit + +* Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-21 +- Backport commit 38f419f (configure: Fix CONFIG_QEMU_HELPERDIR generation, + 2012-10-17) + +* Thu Nov 15 2012 Paolo Bonzini - 2:1.2.0-20 +- Install qemu-bridge-helper as suid root +- Distribute a sample /etc/qemu/bridge.conf file + +* Thu Nov 1 2012 Hans de Goede - 2:1.2.0-19 +- Sync spice patches with upstream, minor bugfixes and set the qxl pci + device revision to 4 by default, so that guests know they can use + the new features + +* Tue Oct 30 2012 Cole Robinson - 2:1.2.0-18 +- Fix loading arm initrd if kernel is very large (bz #862766) +- Don't use reserved word 'function' in systemtap files (bz #870972) +- Drop assertion that was triggering when pausing guests w/ qxl (bz + #870972) + +* Sun Oct 28 2012 Cole Robinson - 2:1.2.0-17 +- Pull patches queued for qemu 1.2.1 + +* Fri Oct 19 2012 Paolo Bonzini - 2:1.2.0-16 +- add s390x KVM support +- distribute pre-built firmware or device trees for Alpha, Microblaze, S390 +- add missing system targets +- add missing linux-user targets +- fix previous commit + +* Thu Oct 18 2012 Dan Horák - 2:1.2.0-15 +- fix build on non-kvm arches like s390(x) + +* Wed Oct 17 2012 Paolo Bonzini - 2:1.2.0-14 +- Change SLOF Requires for the new version number + +* Thu Oct 11 2012 Paolo Bonzini - 2:1.2.0-13 +- Add ppc support to kvm.modules (original patch by David Gibson) +- Replace x86only build with kvmonly build: add separate defines and + conditionals for all packages, so that they can be chosen and + renamed in kvmonly builds and so that qemu has the appropriate requires +- Automatically pick libfdt dependancy +- Add knob to disable spice+seccomp + +* Fri Sep 28 2012 Paolo Bonzini - 2:1.2.0-12 +- Call udevadm on post, fixing bug 860658 + +* Fri Sep 28 2012 Hans de Goede - 2:1.2.0-11 +- Rebuild against latest spice-server and spice-protocol +- Fix non-seamless migration failing with vms with usb-redir devices, + to allow boxes to load such vms from disk + +* Tue Sep 25 2012 Hans de Goede - 2:1.2.0-10 +- Sync Spice patchsets with upstream (rhbz#860238) +- Fix building with usbredir >= 0.5.2 + +* Thu Sep 20 2012 Hans de Goede - 2:1.2.0-9 +- Sync USB and Spice patchsets with upstream + +* Sun Sep 16 2012 Richard W.M. Jones - 2:1.2.0-8 +- Use 'global' instead of 'define', and underscore in definition name, + n-v-r, and 'dist' tag of SLOF, all to fix RHBZ#855252. + +* Fri Sep 14 2012 Paolo Bonzini - 2:1.2.0-4 +- add versioned dependency from qemu-system-ppc to SLOF (BZ#855252) + +* Wed Sep 12 2012 Richard W.M. Jones - 2:1.2.0-3 +- Fix RHBZ#853408 which causes libguestfs failure. + +* Sat Sep 8 2012 Hans de Goede - 2:1.2.0-2 +- Fix crash on (seamless) migration +- Sync usbredir live migration patches with upstream + +* Fri Sep 7 2012 Hans de Goede - 2:1.2.0-1 +- New upstream release 1.2.0 final +- Add support for Spice seamless migration +- Add support for Spice dynamic monitors +- Add support for usb-redir live migration + +* Tue Sep 04 2012 Adam Jackson 1.2.0-0.5.rc1 +- Flip Requires: ceph >= foo to Conflicts: ceph < foo, so we pull in only the + libraries which we need and not the rest of ceph which we don't. + +* Tue Aug 28 2012 Cole Robinson 1.2.0-0.4.rc1 +- Update to 1.2.0-rc1 + +* Mon Aug 20 2012 Richard W.M. Jones - 1.2-0.3.20120806git3e430569 +- Backport Bonzini's vhost-net fix (RHBZ#848400). + +* Tue Aug 14 2012 Cole Robinson - 1.2-0.2.20120806git3e430569 +- Bump release number, previous build forgot but the dist bump helped us out + +* Tue Aug 14 2012 Cole Robinson - 1.2-0.1.20120806git3e430569 +- Revive qemu-system-{ppc*, sparc*} (bz 844502) +- Enable KVM support for all targets (bz 844503) + +* Mon Aug 06 2012 Cole Robinson - 1.2-0.1.20120806git3e430569.fc18 +- Update to git snapshot + +* Sun Jul 29 2012 Cole Robinson - 1.1.1-1 +- Upstream stable release 1.1.1 +- Fix systemtap tapsets (bz 831763) +- Fix VNC audio tunnelling (bz 840653) +- Don't renable ksm on update (bz 815156) +- Bump usbredir dep (bz 812097) +- Fix RPM install error on non-virt machines (bz 660629) +- Obsolete openbios to fix upgrade dependency issues (bz 694802) + +* Sat Jul 21 2012 Fedora Release Engineering - 2:1.1.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 10 2012 Richard W.M. Jones - 2:1.1.0-8 +- Re-diff previous patch so that it applies and actually apply it + +* Tue Jul 10 2012 Richard W.M. Jones - 2:1.1.0-7 +- Add patch to fix default machine options. This fixes libvirt + detection of qemu. +- Back out patch 1 which conflicts. + +* Fri Jul 6 2012 Hans de Goede - 2:1.1.0-5 +- Fix qemu crashing (on an assert) whenever USB-2.0 isoc transfers are used + +* Thu Jul 5 2012 Richard W.M. Jones - 2:1.1.0-4 +- Disable tests since they hang intermittently. +- Add kvmvapic.bin (replaces vapic.bin). +- Add cpus-x86_64.conf. qemu now creates /etc/qemu/target-x86_64.conf + as an empty file. +- Add qemu-icon.bmp. +- Add qemu-bridge-helper. +- Build and include virtfs-proxy-helper + man page (thanks Hans de Goede). + +* Wed Jul 4 2012 Hans de Goede - 2:1.1.0-1 +- New upstream release 1.1.0 +- Drop about a 100 spice + USB patches, which are all upstream + +* Mon Apr 23 2012 Paolo Bonzini - 2:1.0-17 +- Fix install failure due to set -e (rhbz #815272) + +* Mon Apr 23 2012 Paolo Bonzini - 2:1.0-16 +- Fix kvm.modules to exit successfully on non-KVM capable systems (rhbz #814932) + +* Thu Apr 19 2012 Hans de Goede - 2:1.0-15 +- Add a couple of backported QXL/Spice bugfixes +- Add spice volume control patches + +* Fri Apr 6 2012 Paolo Bonzini - 2:1.0-12 +- Add back PPC and SPARC user emulators +- Update binfmt rules from upstream + +* Mon Apr 2 2012 Hans de Goede - 2:1.0-11 +- Some more USB bugfixes from upstream + +* Thu Mar 29 2012 Eduardo Habkost - 2:1.0-12 +- Fix ExclusiveArch mistake that disabled all non-x86_64 builds on Fedora + +* Wed Mar 28 2012 Eduardo Habkost - 2:1.0-11 +- Use --with variables for build-time settings + +* Wed Mar 28 2012 Daniel P. Berrange - 2:1.0-10 +- Switch to use iPXE for netboot ROMs + +* Thu Mar 22 2012 Daniel P. Berrange - 2:1.0-9 +- Remove O_NOATIME for 9p filesystems + +* Mon Mar 19 2012 Daniel P. Berrange - 2:1.0-8 +- Move udev rules to /lib/udev/rules.d (rhbz #748207) + +* Fri Mar 9 2012 Hans de Goede - 2:1.0-7 +- Add a whole bunch of USB bugfixes from upstream + +* Mon Feb 13 2012 Daniel P. Berrange - 2:1.0-6 +- Add many more missing BRs for misc QEMU features +- Enable running of test suite during build + +* Tue Feb 07 2012 Justin M. Forbes - 2:1.0-5 +- Add support for virtio-scsi + +* Sun Feb 5 2012 Richard W.M. Jones - 2:1.0-4 +- Require updated ceph for latest librbd with rbd_flush symbol. + +* Tue Jan 24 2012 Justin M. Forbes - 2:1.0-3 +- Add support for vPMU +- e1000: bounds packet size against buffer size CVE-2012-0029 + +* Fri Jan 13 2012 Justin M. Forbes - 2:1.0-2 +- Add patches for USB redirect bits +- Remove palcode-clipper, we don't build it + +* Wed Jan 11 2012 Justin M. Forbes - 2:1.0-1 +- Add patches from 1.0.1 queue + +* Fri Dec 16 2011 Justin M. Forbes - 2:1.0-1 +- Update to qemu 1.0 + +* Tue Nov 15 2011 Justin M. Forbes - 2:0.15.1-3 +- Enable spice for i686 users as well + +* Thu Nov 03 2011 Justin M. Forbes - 2:0.15.1-2 +- Fix POSTIN scriplet failure (#748281) + +* Fri Oct 21 2011 Justin M. Forbes - 2:0.15.1-1 +- Require seabios-bin >= 0.6.0-2 (#741992) +- Replace init scripts with systemd units (#741920) +- Update to 0.15.1 stable upstream + +* Fri Oct 21 2011 Paul Moore +- Enable full relro and PIE (rhbz #738812) + +* Wed Oct 12 2011 Daniel P. Berrange - 2:0.15.0-6 +- Add BR on ceph-devel to enable RBD block device + +* Wed Oct 5 2011 Daniel P. Berrange - 2:0.15.0-5 +- Create a qemu-guest-agent sub-RPM for guest installation + +* Tue Sep 13 2011 Daniel P. Berrange - 2:0.15.0-4 +- Enable DTrace tracing backend for SystemTAP (rhbz #737763) +- Enable build with curl (rhbz #737006) + +* Thu Aug 18 2011 Hans de Goede - 2:0.15.0-3 +- Add missing BuildRequires: usbredir-devel, so that the usbredir code + actually gets build + +* Thu Aug 18 2011 Richard W.M. Jones - 2:0.15.0-2 +- Add upstream qemu patch 'Allow to leave type on default in -machine' + (2645c6dcaf6ea2a51a3b6dfa407dd203004e4d11). + +* Sun Aug 14 2011 Justin M. Forbes - 2:0.15.0-1 +- Update to 0.15.0 stable release. + +* Thu Aug 04 2011 Justin M. Forbes - 2:0.15.0-0.3.201108040af4922 +- Update to 0.15.0-rc1 as we prepare for 0.15.0 release + +* Thu Aug 4 2011 Daniel P. Berrange - 2:0.15.0-0.3.2011072859fadcc +- Fix default accelerator for non-KVM builds (rhbz #724814) + +* Thu Jul 28 2011 Justin M. Forbes - 2:0.15.0-0.1.2011072859fadcc +- Update to 0.15.0-rc0 as we prepare for 0.15.0 release + +* Tue Jul 19 2011 Hans de Goede - 2:0.15.0-0.2.20110718525e3df +- Add support usb redirection over the network, see: + http://fedoraproject.org/wiki/Features/UsbNetworkRedirection +- Restore chardev flow control patches + +* Mon Jul 18 2011 Justin M. Forbes - 2:0.15.0-0.1.20110718525e3df +- Update to git snapshot as we prepare for 0.15.0 release + +* Wed Jun 22 2011 Richard W.M. Jones - 2:0.14.0-9 +- Add BR libattr-devel. This caused the -fstype option to be disabled. + https://www.redhat.com/archives/libvir-list/2011-June/thread.html#01017 + +* Mon May 2 2011 Hans de Goede - 2:0.14.0-8 +- Fix a bug in the spice flow control patches which breaks the tcp chardev + +* Tue Mar 29 2011 Justin M. Forbes - 2:0.14.0-7 +- Disable qemu-ppc and qemu-sparc packages (#679179) + +* Mon Mar 28 2011 Justin M. Forbes - 2:0.14.0-6 +- Spice fixes for flow control. + +* Tue Mar 22 2011 Dan Horák - 2:0.14.0-5 +- be more careful when removing the -g flag on s390 + +* Fri Mar 18 2011 Justin M. Forbes - 2:0.14.0-4 +- Fix thinko on adding the most recent patches. + +* Wed Mar 16 2011 Justin M. Forbes - 2:0.14.0-3 +- Fix migration issue with vhost +- Fix qxl locking issues for spice + +* Wed Mar 02 2011 Justin M. Forbes - 2:0.14.0-2 +- Re-enable sparc and cris builds + +* Thu Feb 24 2011 Justin M. Forbes - 2:0.14.0-1 +- Update to 0.14.0 release + +* Fri Feb 11 2011 Justin M. Forbes - 2:0.14.0-0.1.20110210git7aa8c46 +- Update git snapshot +- Temporarily disable qemu-cris and qemu-sparc due to build errors (to be resolved shorly) + +* Tue Feb 08 2011 Justin M. Forbes - 2:0.14.0-0.1.20110208git3593e6b +- Update to 0.14.0 rc git snapshot +- Add virtio-net to modules + +* Wed Nov 3 2010 Daniel P. Berrange - 2:0.13.0-2 +- Revert previous change +- Make qemu-common own the /etc/qemu directory +- Add /etc/qemu/target-x86_64.conf to qemu-system-x86 regardless + of host architecture. + +* Wed Nov 03 2010 Dan Horák - 2:0.13.0-2 +- Remove kvm config file on non-x86 arches (part of #639471) +- Own the /etc/qemu directory + +* Mon Oct 18 2010 Justin M. Forbes - 2:0.13.0-1 +- Update to 0.13.0 upstream release +- Fixes for vhost +- Fix mouse in certain guests (#636887) +- Fix issues with WinXP guest install (#579348) +- Resolve build issues with S390 (#639471) +- Fix Windows XP on Raw Devices (#631591) + +* Tue Oct 05 2010 jkeating - 2:0.13.0-0.7.rc1.1 +- Rebuilt for gcc bug 634757 + +* Tue Sep 21 2010 Justin M. Forbes - 2:0.13.0-0.7.rc1 +- Flip qxl pci id from unstable to stable (#634535) +- KSM Fixes from upstream (#558281) + +* Tue Sep 14 2010 Justin M. Forbes - 2:0.13.0-0.6.rc1 +- Move away from git snapshots as 0.13 is close to release +- Updates for spice 0.6 + +* Tue Aug 10 2010 Justin M. Forbes - 2:0.13.0-0.5.20100809git25fdf4a +- Fix typo in e1000 gpxe rom requires. +- Add links to newer vgabios + +* Tue Aug 10 2010 Justin M. Forbes - 2:0.13.0-0.4.20100809git25fdf4a +- Disable spice on 32bit, it is not supported and buildreqs don't exist. + +* Mon Aug 9 2010 Justin M. Forbes - 2:0.13.0-0.3.20100809git25fdf4a +- Updates from upstream towards 0.13 stable +- Fix requires on gpxe +- enable spice now that buildreqs are in the repository. +- ksmtrace has moved to a separate upstream package + +* Tue Jul 27 2010 Justin M. Forbes - 2:0.13.0-0.2.20100727gitb81fe95 +- add texinfo buildreq for manpages. + +* Tue Jul 27 2010 Justin M. Forbes - 2:0.13.0-0.1.20100727gitb81fe95 +- Update to 0.13.0 upstream snapshot +- ksm init fixes from upstream + +* Tue Jul 20 2010 Dan Horák - 2:0.12.3-8 +- Add avoid-llseek patch from upstream needed for building on s390(x) +- Don't use parallel make on s390(x) + +* Tue Jun 22 2010 Amit Shah - 2:0.12.3-7 +- Add vvfat hardening patch from upstream (#605202) + +* Fri Apr 23 2010 Justin M. Forbes - 2:0.12.3-6 +- Change requires to the noarch seabios-bin +- Add ownership of docdir to qemu-common (#572110) +- Fix "Cannot boot from non-existent NIC" error when using virt-install (#577851) + +* Thu Apr 15 2010 Justin M. Forbes - 2:0.12.3-5 +- Update virtio console patches from upstream + +* Thu Mar 11 2010 Justin M. Forbes - 2:0.12.3-4 +- Detect cdrom via ioctl (#473154) +- re add increased buffer for USB control requests (#546483) + +* Wed Mar 10 2010 Justin M. Forbes - 2:0.12.3-3 +- Migration clear the fd in error cases (#518032) + +* Tue Mar 09 2010 Justin M. Forbes - 2:0.12.3-2 +- Allow builds --with x86only +- Add libaio-devel buildreq for aio support + +* Fri Feb 26 2010 Justin M. Forbes - 2:0.12.3-1 +- Update to 0.12.3 upstream +- vhost-net migration/restart fixes +- Add F-13 machine type +- virtio-serial fixes + +* Tue Feb 09 2010 Justin M. Forbes - 2:0.12.2-6 +- Add vhost net support. + +* Thu Feb 04 2010 Justin M. Forbes - 2:0.12.2-5 +- Avoid creating too large iovecs in multiwrite merge (#559717) +- Don't try to set max_kernel_pages during ksm init on newer kernels (#558281) +- Add logfile options for ksmtuned debug. + +* Wed Jan 27 2010 Amit Shah - 2:0.12.2-4 +- Remove build dependency on iasl now that we have seabios + +* Wed Jan 27 2010 Amit Shah - 2:0.12.2-3 +- Remove source target for 0.12.1.2 + +* Wed Jan 27 2010 Amit Shah - 2:0.12.2-2 +- Add virtio-console patches from upstream for the F13 VirtioSerial feature + +* Mon Jan 25 2010 Justin M. Forbes - 2:0.12.2-1 +- Update to 0.12.2 upstream + +* Sun Jan 10 2010 Justin M. Forbes - 2:0.12.1.2-3 +- Point to seabios instead of bochs, and add a requires for seabios + +* Mon Jan 4 2010 Justin M. Forbes - 2:0.12.1.2-2 +- Remove qcow2 virtio backing file patch + +* Mon Jan 4 2010 Justin M. Forbes - 2:0.12.1.2-1 +- Update to 0.12.1.2 upstream +- Remove patches included in upstream + +* Fri Nov 20 2009 Mark McLoughlin - 2:0.11.0-12 +- Fix a use-after-free crasher in the slirp code (#539583) +- Fix overflow in the parallels image format support (#533573) + +* Wed Nov 4 2009 Mark McLoughlin - 2:0.11.0-11 +- Temporarily disable preadv/pwritev support to fix data corruption (#526549) + +* Tue Nov 3 2009 Justin M. Forbes - 2:0.11.0-10 +- Default ksm and ksmtuned services on. + +* Thu Oct 29 2009 Mark McLoughlin - 2:0.11.0-9 +- Fix dropped packets with non-virtio NICs (#531419) + +* Wed Oct 21 2009 Glauber Costa - 2:0.11.0-8 +- Properly save kvm time registers (#524229) + +* Mon Oct 19 2009 Mark McLoughlin - 2:0.11.0-7 +- Fix potential segfault from too small MSR_COUNT (#528901) + +* Fri Oct 9 2009 Mark McLoughlin - 2:0.11.0-6 +- Fix fs errors with virtio and qcow2 backing file (#524734) +- Fix ksm initscript errors on kernel missing ksm (#527653) +- Add missing Requires(post): getent, useradd, groupadd (#527087) + +* Tue Oct 6 2009 Mark McLoughlin - 2:0.11.0-5 +- Add 'retune' verb to ksmtuned init script + +* Mon Oct 5 2009 Mark McLoughlin - 2:0.11.0-4 +- Use rtl8029 PXE rom for ne2k_pci, not ne (#526777) +- Also, replace the gpxe-roms-qemu pkg requires with file-based requires + +* Thu Oct 1 2009 Justin M. Forbes - 2:0.11.0-3 +- Improve error reporting on file access (#524695) + +* Mon Sep 28 2009 Mark McLoughlin - 2:0.11.0-2 +- Fix pci hotplug to not exit if supplied an invalid NIC model (#524022) + +* Mon Sep 28 2009 Mark McLoughlin - 2:0.11.0-1 +- Update to 0.11.0 release +- Drop a couple of upstreamed patches + +* Wed Sep 23 2009 Mark McLoughlin - 2:0.10.92-5 +- Fix issue causing NIC hotplug confusion when no model is specified (#524022) + +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-4 +- Fix for KSM patch from Justin Forbes + +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-3 +- Add ksmtuned, also from Dan Kenigsberg +- Use %%_initddir macro + +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-2 +- Add ksm control script from Dan Kenigsberg + +* Mon Sep 7 2009 Mark McLoughlin - 2:0.10.92-1 +- Update to qemu-kvm-0.11.0-rc2 +- Drop upstreamed patches +- extboot install now fixed upstream +- Re-place TCG init fix (#516543) with the one gone upstream + +* Mon Sep 7 2009 Mark McLoughlin - 2:0.10.91-0.10.rc1 +- Fix MSI-X error handling on older kernels (#519787) + +* Fri Sep 4 2009 Mark McLoughlin - 2:0.10.91-0.9.rc1 +- Make pulseaudio the default audio backend (#519540, #495964, #496627) + +* Thu Aug 20 2009 Richard W.M. Jones - 2:0.10.91-0.8.rc1 +- Fix segfault when qemu-kvm is invoked inside a VM (#516543) + +* Tue Aug 18 2009 Mark McLoughlin - 2:0.10.91-0.7.rc1 +- Fix permissions on udev rules (#517571) + +* Mon Aug 17 2009 Lubomir Rintel - 2:0.10.91-0.6.rc1 +- Allow blacklisting of kvm modules (#517866) + +* Fri Aug 7 2009 Mark McLoughlin - 2:0.10.91-0.5.rc1 +- Fix virtio_net with -net user (#516022) + +* Tue Aug 4 2009 Mark McLoughlin - 2:0.10.91-0.4.rc1 +- Update to qemu-kvm-0.11-rc1; no changes from rc1-rc0 + +* Tue Aug 4 2009 Mark McLoughlin - 2:0.10.91-0.3.rc1.rc0 +- Fix extboot checksum (bug #514899) + +* Fri Jul 31 2009 Mark McLoughlin - 2:0.10.91-0.2.rc1.rc0 +- Add KSM support +- Require bochs-bios >= 2.3.8-0.8 for latest kvm bios updates + +* Thu Jul 30 2009 Mark McLoughlin - 2:0.10.91-0.1.rc1.rc0 +- Update to qemu-kvm-0.11.0-rc1-rc0 +- This is a pre-release of the official -rc1 +- A vista installer regression is blocking the official -rc1 release +- Drop qemu-prefer-sysfs-for-usb-host-devices.patch +- Drop qemu-fix-build-for-esd-audio.patch +- Drop qemu-slirp-Fix-guestfwd-for-incoming-data.patch +- Add patch to ensure extboot.bin is installed + +* Sun Jul 26 2009 Fedora Release Engineering - 2:0.10.50-14.kvm88 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 23 2009 Glauber Costa - 2:0.10.50-13.kvm88 +- Fix bug 513249, -net channel option is broken + +* Thu Jul 16 2009 Daniel P. Berrange - 2:0.10.50-12.kvm88 +- Add 'qemu' user and group accounts +- Force disable xen until it can be made to build + +* Thu Jul 16 2009 Mark McLoughlin - 2:0.10.50-11.kvm88 +- Update to kvm-88, see http://www.linux-kvm.org/page/ChangeLog +- Package mutiboot.bin +- Update for how extboot is built +- Fix sf.net source URL +- Drop qemu-fix-ppc-softmmu-kvm-disabled-build.patch +- Drop qemu-fix-pcspk-build-with-kvm-disabled.patch +- Cherry-pick fix for esound support build failure + +* Wed Jul 15 2009 Daniel Berrange - 2:0.10.50-10.kvm87 +- Add udev rules to make /dev/kvm world accessible & group=kvm (rhbz #497341) +- Create a kvm group if it doesn't exist (rhbz #346151) + +* Tue Jul 07 2009 Glauber Costa - 2:0.10.50-9.kvm87 +- use pxe roms from gpxe, instead of etherboot package. + +* Fri Jul 3 2009 Mark McLoughlin - 2:0.10.50-8.kvm87 +- Prefer sysfs over usbfs for usb passthrough (#508326) + +* Sat Jun 27 2009 Mark McLoughlin - 2:0.10.50-7.kvm87 +- Update to kvm-87 +- Drop upstreamed patches +- Cherry-pick new ppc build fix from upstream +- Work around broken linux-user build on ppc +- Fix hw/pcspk.c build with --disable-kvm +- Re-enable preadv()/pwritev() since #497429 is long since fixed +- Kill petalogix-s3adsp1800.dtb, since we don't ship the microblaze target + +* Fri Jun 5 2009 Mark McLoughlin - 2:0.10.50-6.kvm86 +- Fix 'kernel requires an x86-64 CPU' error +- BuildRequires ncurses-devel to enable '-curses' option (#504226) + +* Wed Jun 3 2009 Mark McLoughlin - 2:0.10.50-5.kvm86 +- Prevent locked cdrom eject - fixes hang at end of anaconda installs (#501412) +- Avoid harmless 'unhandled wrmsr' warnings (#499712) + +* Thu May 21 2009 Mark McLoughlin - 2:0.10.50-4.kvm86 +- Update to kvm-86 release +- ChangeLog here: http://marc.info/?l=kvm&m=124282885729710 + +* Fri May 1 2009 Mark McLoughlin - 2:0.10.50-3.kvm85 +- Really provide qemu-kvm as a metapackage for comps + +* Tue Apr 28 2009 Mark McLoughlin - 2:0.10.50-2.kvm85 +- Provide qemu-kvm as a metapackage for comps + +* Mon Apr 27 2009 Mark McLoughlin - 2:0.10.50-1.kvm85 +- Update to qemu-kvm-devel-85 +- kvm-85 is based on qemu development branch, currently version 0.10.50 +- Include new qemu-io utility in qemu-img package +- Re-instate -help string for boot=on to fix virtio booting with libvirt +- Drop upstreamed patches +- Fix missing kernel/include/asm symlink in upstream tarball +- Fix target-arm build +- Fix build on ppc +- Disable preadv()/pwritev() until bug #497429 is fixed +- Kill more .kernelrelease uselessness +- Make non-kvm qemu build verbose + +* Fri Apr 24 2009 Mark McLoughlin - 2:0.10-15 +- Fix source numbering typos caused by make-release addition + +* Thu Apr 23 2009 Mark McLoughlin - 2:0.10-14 +- Improve instructions for generating the tarball + +* Tue Apr 21 2009 Mark McLoughlin - 2:0.10-13 +- Enable pulseaudio driver to fix qemu lockup at shutdown (#495964) + +* Tue Apr 21 2009 Mark McLoughlin - 2:0.10-12 +- Another qcow2 image corruption fix (#496642) + +* Mon Apr 20 2009 Mark McLoughlin - 2:0.10-11 +- Fix qcow2 image corruption (#496642) + +* Sun Apr 19 2009 Mark McLoughlin - 2:0.10-10 +- Run sysconfig.modules from %%post on x86_64 too (#494739) + +* Sun Apr 19 2009 Mark McLoughlin - 2:0.10-9 +- Align VGA ROM to 4k boundary - fixes 'qemu-kvm -std vga' (#494376) + +* Tue Apr 14 2009 Glauber Costa - 2:0.10-8 +- Provide qemu-kvm conditional on the architecture. + +* Thu Apr 9 2009 Mark McLoughlin - 2:0.10-7 +- Add a much cleaner fix for vga segfault (#494002) + +* Sun Apr 5 2009 Glauber Costa - 2:0.10-6 +- Fixed qcow2 segfault creating disks over 2TB. #491943 + +* Fri Apr 3 2009 Mark McLoughlin - 2:0.10-5 +- Fix vga segfault under kvm-autotest (#494002) +- Kill kernelrelease hack; it's not needed +- Build with "make V=1" for more verbose logs + +* Thu Apr 02 2009 Glauber Costa - 2:0.10-4 +- Support botting gpxe roms. + +* Wed Apr 01 2009 Glauber Costa - 2:0.10-2 +- added missing patch. love for CVS. + +* Wed Apr 01 2009 Glauber Costa - 2:0.10-1 +- Include debuginfo for qemu-img +- Do not require qemu-common for qemu-img +- Explicitly own each of the firmware files +- remove firmwares for ppc and sparc. They should be provided by an external package. + Not that the packages exists for sparc in the secondary arch repo as noarch, but they + don't automatically get into main repos. Unfortunately it's the best we can do right + now. +- rollback a bit in time. Snapshot from avi's maint/2.6.30 + - this requires the sasl patches to come back. + - with-patched-kernel comes back. + +* Wed Mar 25 2009 Mark McLoughlin - 2:0.10-0.12.kvm20090323git +- BuildRequires pciutils-devel for device assignment (#492076) + +* Mon Mar 23 2009 Glauber Costa - 2:0.10-0.11.kvm20090323git +- Update to snapshot kvm20090323. +- Removed patch2 (upstream). +- use upstream's new split package. +- --with-patched-kernel flag not needed anymore +- Tell how to get the sources. + +* Wed Mar 18 2009 Glauber Costa - 2:0.10-0.10.kvm20090310git +- Added extboot to files list. + +* Wed Mar 11 2009 Glauber Costa - 2:0.10-0.9.kvm20090310git +- Fix wrong reference to bochs bios. + +* Wed Mar 11 2009 Glauber Costa - 2:0.10-0.8.kvm20090310git +- fix Obsolete/Provides pair +- Use kvm bios from bochs-bios package. +- Using RPM_OPT_FLAGS in configure +- Picked back audio-drv-list from kvm package + +* Tue Mar 10 2009 Glauber Costa - 2:0.10-0.7.kvm20090310git +- modify ppc patch + +* Tue Mar 10 2009 Glauber Costa - 2:0.10-0.6.kvm20090310git +- updated to kvm20090310git +- removed sasl patches (already in this release) + +* Tue Mar 10 2009 Glauber Costa - 2:0.10-0.5.kvm20090303git +- kvm.modules were being wrongly mentioned at %%install. +- update description for the x86 system package to include kvm support +- build kvm's own bios. It is still necessary while kvm uses a slightly different + irq routing mechanism + +* Thu Mar 05 2009 Glauber Costa - 2:0.10-0.4.kvm20090303git +- seems Epoch does not go into the tags. So start back here. + +* Thu Mar 05 2009 Glauber Costa - 2:0.10-0.1.kvm20090303git +- Use bochs-bios instead of bochs-bios-data +- It's official: upstream set on 0.10 + +* Thu Mar 5 2009 Daniel P. Berrange - 2:0.9.2-0.2.kvm20090303git +- Added BSD to license list, since many files are covered by BSD + +* Wed Mar 04 2009 Glauber Costa - 0.9.2-0.1.kvm20090303git +- missing a dot. shame on me + +* Wed Mar 04 2009 Glauber Costa - 0.92-0.1.kvm20090303git +- Set Epoch to 2 +- Set version to 0.92. It seems upstream keep changing minds here, so pick the lowest +- Provides KVM, Obsoletes KVM +- Only install qemu-kvm in ix86 and x86_64 +- Remove pkgdesc macros, as they were generating bogus output for rpm -qi. +- fix ppc and ppc64 builds + +* Tue Mar 03 2009 Glauber Costa - 0.10-0.3.kvm20090303git +- only execute post scripts for user package. +- added kvm tools. + +* Tue Mar 03 2009 Glauber Costa - 0.10-0.2.kvm20090303git +- put kvm.modules into cvs + +* Tue Mar 03 2009 Glauber Costa - 0.10-0.1.kvm20090303git +- Set Epoch to 1 +- Build KVM (basic build, no tools yet) +- Set ppc in ExcludeArch. This is temporary, just to fix one issue at a time. + ppc users (IBM ? ;-)) please wait a little bit. + +* Tue Mar 3 2009 Daniel P. Berrange - 1.0-0.5.svn6666 +- Support VNC SASL authentication protocol +- Fix dep on bochs-bios-data + +* Tue Mar 03 2009 Glauber Costa - 1.0-0.4.svn6666 +- use bios from bochs-bios package. + +* Tue Mar 03 2009 Glauber Costa - 1.0-0.3.svn6666 +- use vgabios from vgabios package. + +* Mon Mar 02 2009 Glauber Costa - 1.0-0.2.svn6666 +- use pxe roms from etherboot package. + +* Mon Mar 02 2009 Glauber Costa - 1.0-0.1.svn6666 +- Updated to tip svn (release 6666). Featuring split packages for qemu. + Unfortunately, still using binary blobs for the bioses. + +* Wed Feb 25 2009 Fedora Release Engineering - 0.9.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sun Jan 11 2009 Debarshi Ray - 0.9.1-12 +- Updated build patch. Closes Red Hat Bugzilla bug #465041. + +* Wed Dec 31 2008 Dennis Gilmore - 0.9.1-11 +- add sparcv9 and sparc64 support + +* Fri Jul 25 2008 Bill Nottingham +- Fix qemu-img summary (#456344) + +* Wed Jun 25 2008 Daniel P. Berrange - 0.9.1-10.fc10 +- Rebuild for GNU TLS ABI change + +* Wed Jun 11 2008 Daniel P. Berrange - 0.9.1-9.fc10 +- Remove bogus wildcard from files list (rhbz #450701) + +* Sat May 17 2008 Lubomir Rintel - 0.9.1-8 +- Register binary handlers also for shared libraries + +* Mon May 5 2008 Daniel P. Berrange - 0.9.1-7.fc10 +- Fix text console PTYs to be in rawmode + +* Sun Apr 27 2008 Lubomir Kundrak - 0.9.1-6 +- Register binary handler for SuperH-4 CPU + +* Wed Mar 19 2008 Daniel P. Berrange - 0.9.1-5.fc9 +- Split qemu-img tool into sub-package for smaller footprint installs + +* Wed Feb 27 2008 Daniel P. Berrange - 0.9.1-4.fc9 +- Fix block device checks for extendable disk formats (rhbz #435139) + +* Sat Feb 23 2008 Daniel P. Berrange - 0.9.1-3.fc9 +- Fix block device extents check (rhbz #433560) + +* Mon Feb 18 2008 Fedora Release Engineering - 0.9.1-2 +- Autorebuild for GCC 4.3 + +* Tue Jan 8 2008 Daniel P. Berrange - 0.9.1-1.fc9 +- Updated to 0.9.1 release +- Fix license tag syntax +- Don't mark init script as a config file + +* Wed Sep 26 2007 Daniel P. Berrange - 0.9.0-5.fc8 +- Fix rtl8139 checksum calculation for Vista (rhbz #308201) + +* Tue Aug 28 2007 Daniel P. Berrange - 0.9.0-4.fc8 +- Fix debuginfo by passing -Wl,--build-id to linker + +* Tue Aug 28 2007 David Woodhouse 0.9.0-4 +- Update licence +- Fix CDROM emulation (#253542) + +* Tue Aug 28 2007 Daniel P. Berrange - 0.9.0-3.fc8 +- Added backport of VNC password auth, and TLS+x509 cert auth +- Switch to rtl8139 NIC by default for linkstate reporting +- Fix rtl8139 mmio region mappings with multiple NICs + +* Sun Apr 1 2007 Hans de Goede 0.9.0-2 +- Fix direct loading of a linux kernel with -kernel & -initrd (bz 234681) +- Remove spurious execute bits from manpages (bz 222573) + +* Tue Feb 6 2007 David Woodhouse 0.9.0-1 +- Update to 0.9.0 + +* Wed Jan 31 2007 David Woodhouse 0.8.2-5 +- Include licences + +* Mon Nov 13 2006 Hans de Goede 0.8.2-4 +- Backport patch to make FC6 guests work by Kevin Kofler + (bz 207843). + +* Mon Sep 11 2006 David Woodhouse 0.8.2-3 +- Rebuild + +* Thu Aug 24 2006 Matthias Saou 0.8.2-2 +- Remove the target-list iteration for x86_64 since they all build again. +- Make gcc32 vs. gcc34 conditional on %%{fedora} to share the same spec for + FC5 and FC6. + +* Wed Aug 23 2006 Matthias Saou 0.8.2-1 +- Update to 0.8.2 (#200065). +- Drop upstreamed syscall-macros patch2. +- Put correct scriplet dependencies. +- Force install mode for the init script to avoid umask problems. +- Add %%postun condrestart for changes to the init script to be applied if any. +- Update description with the latest "about" from the web page (more current). +- Update URL to qemu.org one like the Source. +- Add which build requirement. +- Don't include texi files in %%doc since we ship them in html. +- Switch to using gcc34 on devel, FC5 still has gcc32. +- Add kernheaders patch to fix linux/compiler.h inclusion. +- Add target-sparc patch to fix compiling on ppc (some int32 to float). + +* Thu Jun 8 2006 David Woodhouse 0.8.1-3 +- More header abuse in modify_ldt(), change BuildRoot: + +* Wed Jun 7 2006 David Woodhouse 0.8.1-2 +- Fix up kernel header abuse + +* Tue May 30 2006 David Woodhouse 0.8.1-1 +- Update to 0.8.1 + +* Sat Mar 18 2006 David Woodhouse 0.8.0-6 +- Update linker script for PPC + +* Sat Mar 18 2006 David Woodhouse 0.8.0-5 +- Just drop $RPM_OPT_FLAGS. They're too much of a PITA + +* Sat Mar 18 2006 David Woodhouse 0.8.0-4 +- Disable stack-protector options which gcc 3.2 doesn't like + +* Fri Mar 17 2006 David Woodhouse 0.8.0-3 +- Use -mcpu= instead of -mtune= on x86_64 too +- Disable SPARC targets on x86_64, because dyngen doesn't like fnegs + +* Fri Mar 17 2006 David Woodhouse 0.8.0-2 +- Don't use -mtune=pentium4 on i386. GCC 3.2 doesn't like it + +* Fri Mar 17 2006 David Woodhouse 0.8.0-1 +- Update to 0.8.0 +- Resort to using compat-gcc-32 +- Enable ALSA + +* Mon May 16 2005 David Woodhouse 0.7.0-2 +- Proper fix for GCC 4 putting 'blr' or 'ret' in the middle of the function, + for i386, x86_64 and PPC. + +* Sat Apr 30 2005 David Woodhouse 0.7.0-1 +- Update to 0.7.0 +- Fix dyngen for PPC functions which end in unconditional branch + +* Thu Apr 7 2005 Michael Schwendt +- rebuilt + +* Sun Feb 13 2005 David Woodhouse 0.6.1-2 +- Package cleanup + +* Sun Nov 21 2004 David Woodhouse 0.6.1-1 +- Update to 0.6.1 + +* Tue Jul 20 2004 David Woodhouse 0.6.0-2 +- Compile fix from qemu CVS, add x86_64 host support + +* Wed May 12 2004 David Woodhouse 0.6.0-1 +- Update to 0.6.0. + +* Sat May 8 2004 David Woodhouse 0.5.5-1 +- Update to 0.5.5. + +* Sun May 2 2004 David Woodhouse 0.5.4-1 +- Update to 0.5.4. + +* Thu Apr 22 2004 David Woodhouse 0.5.3-1 +- Update to 0.5.3. Add init script. + +* Thu Jul 17 2003 Jeff Johnson 0.4.3-1 +- Create. diff --git a/devtools/qemu/qemu/qemu-system-x86.conf b/devtools/qemu/qemu/qemu-system-x86.conf new file mode 100644 index 000000000..b00377d5a --- /dev/null +++ b/devtools/qemu/qemu/qemu-system-x86.conf @@ -0,0 +1 @@ +options kvm-intel nested=1 diff --git a/devtools/qemu/qemu/qemu_clean b/devtools/qemu/qemu/qemu_clean new file mode 100644 index 000000000..ddb19fc4a --- /dev/null +++ b/devtools/qemu/qemu/qemu_clean @@ -0,0 +1,41 @@ +#!/bin/bash +# +# chkconfig: 2345 50 50 +# + +### BEGIN INIT INFO +# Provides: qemu_clean +# Short-Description: Clean up stale unix sockets for qemu +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +### END INIT INFO + + + +start() +{ + cd /var/lib/libvirt/qemu + rm -f instance-*.monitor + rm -f cgcs.heartbeat.* +} + +stop () +{ + # Nothing to do + return +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + *) + echo "Usage: $0 {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/devtools/qemu/qemu/qemu_clean.service b/devtools/qemu/qemu/qemu_clean.service new file mode 100644 index 000000000..11e07d4e5 --- /dev/null +++ b/devtools/qemu/qemu/qemu_clean.service @@ -0,0 +1,14 @@ +[Unit] +Description=Titanium Cloud libvirt QEMU cleanup +After=syslog.target network.target logmgmt.service +Before=libvirtd.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/etc/init.d/qemu_clean start +ExecStop=/etc/init.d/qemu_clean stop +ExecReload= + +[Install] +WantedBy=multi-user.target diff --git a/devtools/qemu/scripts/autopatch.sh b/devtools/qemu/scripts/autopatch.sh new file mode 100755 index 000000000..ebc59af19 --- /dev/null +++ b/devtools/qemu/scripts/autopatch.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +SOURCE_SPEC=~/qemu/qemu-kvm.spec +SOURCE_PATCH_DIR=~/qemu/ + +# Base patch order on the '%patch' statements (not 'Patchx:' definition) +for patch in `cat $SOURCE_SPEC | grep '%patch[0-9]\{1,\} ' | awk '{print $1'}`; do + # Resolve patch name base on it's id/number + id=`echo $patch | sed 's/%patch//'` + p=`grep "Patch$id:" $SOURCE_SPEC | awk '{print $2}'` + + echo "-> Processing patch: $p" + git am -3 $SOURCE_PATCH_DIR/$p + if [ $? -ne 0 ]; then + echo "--> Failed, falling back to manual patching" + git am --abort + # patch -p1 < $SOURCE_PATCH_DIR/$p + git apply --index $SOURCE_PATCH_DIR/$p + if [ $? -ne 0 ]; then + echo "--> Failed manual patching, abort" + else + git add -A + git commit -m "Manual patch apply: $p" + fi + fi +done diff --git a/devtools/update-motd/LICENSE b/devtools/update-motd/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/devtools/update-motd/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/devtools/update-motd/PKG-INFO b/devtools/update-motd/PKG-INFO new file mode 100644 index 000000000..b11affb60 --- /dev/null +++ b/devtools/update-motd/PKG-INFO @@ -0,0 +1,14 @@ +Metadata-Version: 1.1 +Name: update-motd +Version: 1.0 +Summary: dynamic MOTD generation +Home-page: +Author: +Author-email: +License: Apache-2.0 + +Description: +dynamic MOTD generation + + +Platform: UNKNOWN diff --git a/devtools/update-motd/centos/build_srpm.data b/devtools/update-motd/centos/build_srpm.data new file mode 100644 index 000000000..2ec7ea02f --- /dev/null +++ b/devtools/update-motd/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=1 diff --git a/devtools/update-motd/centos/update-motd.spec b/devtools/update-motd/centos/update-motd.spec new file mode 100644 index 000000000..321547e27 --- /dev/null +++ b/devtools/update-motd/centos/update-motd.spec @@ -0,0 +1,59 @@ +Name: update-motd +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +Summary: dynamic MOTD generation + +Group: base +License: Apache-2.0 +URL: unknown +Source0: motd-footer +Source1: motd-header +Source2: motd-update +Source3: motd-update.cron +Source4: customize-banner +Source5: apply_banner_customization +Source6: install_banner_customization +Source7: LICENSE + +Requires: crontabs + +%description +dynamic MOTD generation + +%prep + + +%build + + +%install +install -d %{buildroot}%{_sbindir} +install -m 700 %{SOURCE2} %{buildroot}%{_sbindir}/motd-update + +install -d %{buildroot}%{_sysconfdir} + +install -d %{buildroot}%{_sysconfdir}/motd.d +install -m 755 %{SOURCE1} %{buildroot}%{_sysconfdir}/motd.d/00-header +install -m 755 %{SOURCE0} %{buildroot}%{_sysconfdir}/motd.d/99-footer + +install -d %{buildroot}%{_sysconfdir}/cron.d +install -m 600 %{SOURCE3} %{buildroot}%{_sysconfdir}/cron.d/motd-update +install -m 700 %{SOURCE4} %{buildroot}%{_sbindir}/customize-banner +install -m 700 %{SOURCE5} %{buildroot}%{_sbindir}/apply_banner_customization +install -m 700 %{SOURCE6} %{buildroot}%{_sbindir}/install_banner_customization + + +%files +%license ../SOURCES/LICENSE +%dir %{_sysconfdir}/motd.d/ +%{_sysconfdir}/motd.d/* +/usr/sbin/* +/etc/motd.d/* +/etc/cron.d/* +%{_sbindir}/motd-update +%{_sbindir}/customize-banner +%{_sbindir}/apply_banner_customization +%{_sbindir}/install_banner_customization + +%changelog + diff --git a/devtools/update-motd/files/LICENSE b/devtools/update-motd/files/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/devtools/update-motd/files/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/devtools/update-motd/files/apply_banner_customization b/devtools/update-motd/files/apply_banner_customization new file mode 100644 index 000000000..3bf999e7b --- /dev/null +++ b/devtools/update-motd/files/apply_banner_customization @@ -0,0 +1,25 @@ +#!/bin/bash + +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +. /usr/sbin/customize-banner + +banner_path="$1" +if [ -z "${banner_path}" ]; then + banner_path=$(pwd) +fi + +if ! customize_banner "${banner_path}"; then + exit 1 +fi + +install_banner_files + +# recreate /etc/motd +/usr/sbin/motd-update + +exit 0 diff --git a/devtools/update-motd/files/customize-banner b/devtools/update-motd/files/customize-banner new file mode 100644 index 000000000..0d798fba5 --- /dev/null +++ b/devtools/update-motd/files/customize-banner @@ -0,0 +1,286 @@ +#!/bin/bash + +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +. /usr/bin/tsconfig + +OPT_BANNER_BACKUP="/opt/banner.bk" +PLATFORM_BANNER_DIR="${CONFIG_PATH}/banner" + +# +# set BANNER_VERBOSE to enable info logs +# +export BANNER_VERBOSE + +info_log () +{ + if [ -n "${BANNER_VERBOSE}" ]; then + echo "INFO: customize-banner: $@" >&2 + fi +} + +warn_log () +{ + echo "WARNING: customize-banner: $@" >&2 +} + +error_log () +{ + echo "ERROR: customize-banner: $@" >&2 +} + +# some checks to see if the user does something odd +# Return: 1 if the file is not sane +# 0 if the file is normal looking +# +# Symbolic links are followed to their ultimate destination before +# further checks are made +file_is_sane () +{ + local fname=$1 + + if [ -z "${fname}" ]; then + error_log "no file specified" + return 1 + fi + + # resolve symlinks + if [ -h "${fname}" ]; then + local resolved=$(readlink -f "${fname}") + if [ -z "${resolved}" ]; then + error_log "file does not exist; did not resolve symbolic link" + return 1 + fi + + file_is_sane_no_link "${resolved}" + return $? + fi + + file_is_sane_no_link "${fname}" + return $? +} + +file_is_sane_no_link () +{ + local fname=$1 + # a sanity check, the banner file has to be a regular file + # symbolic links are handled in file_is_sane() + if [ ! -f "${fname}" -o -h "${fname}" ]; then + error_log "file is not a regular file: ${fname}" + return 1 + fi + + # root usually has access to write readonly files... + if [ ! -w "${fname}" ]; then + error_log "file is readonly: ${fname}" + return 1 + fi + + # Warn only + if [ -x "${fname}" ]; then + warn_log "file is executable: ${fname}" + fi +} + +# +# Prints list of files to stdout +# +get_banner_files () +{ + local flist=" \ + /etc/issue \ + /etc/issue.net \ + /etc/motd.head \ + /etc/motd.tail \ + " + + echo ${flist} +} + +# +# This is to be executed either by config_controller or by the user +# through apply_banner_customization +# +# For each customizable file, if a customization is present do a bit of +# sanity and copy the file to the platform config for banner +# customization. +# +# Return 0 on success +# Return 1 for error conditions, if any customization file failed sanity +# +customize_banner () +{ + if [ ! -d "${CONFIG_PATH}" ]; then + error_log "config path does not exist" + return 1 + fi + + banner_dir="$1" + if [ -z "${banner_dir}" ]; then + error_log "path containing customization files is required" + return 1 + fi + + if [ ! -d "${banner_dir}" ]; then + warn_log "directory does not exist: ${banner_dir}" + return 0 + fi + + local inputok=0 + local count=0 + local fname="" + for fname in $(get_banner_files); do { + local bname="$(basename $fname)" + # confname includes 'etc'; newfname does not. This seems easier + # for the user; at least until a file with a duplicate name is + # customizable + local confname="${PLATFORM_BANNER_DIR}/${fname}" + local newfname="${banner_dir}/${bname}" + + if [ -e "${newfname}" ]; then + count=$(expr $count + 1) + if ! file_is_sane ${newfname}; then + inputok=1 + continue + fi + + if [ -f "${confname}" ]; then + info_log "updating customization of ${fname}" + rm ${confname} + else + info_log "adding customization of ${fname}" + fi + + mkdir -p $(dirname ${confname}) + cp ${newfname} ${confname} + elif [ -f "${confname}" ]; then + info_log "maintaining previous customization of ${fname}" + fi + }; done + + if [ "$count" -eq 0 ]; then + warn_log "no customization files were found in $banner_dir" + fi + + return $inputok +} + +# +# Compare two banner files +# +# Return 0 if they are the same +# 1 if they are different +# +compare_file () +{ + diff -q "$1" "$2" 2>&1 > /dev/null + return $? +} + +# +# copy the file with a bkx extension, but only if it is not identical to +# another; look for an unused filename +# +# put a hard limit on the number of iterations +# +backup_file () +{ + local fname=$1 + local dname=$(dirname $fname) + local bname=$(basename $fname) + local bkdir=${OPT_BANNER_BACKUP}/${dname} + local count=0 + local newname="" + + if [ ! -f "${fname}" ]; then + warn_log "file does not exist: $fname" + return 0 + fi + + for count in $(seq 0 9); do { + newname=${bkdir}/${bname}.bk${count} + if [ -e "${newname}" ]; then + if compare_file "${newname}" "${fname}"; then + info_log "file is previously backed up ${fname} as ${newname}" + touch ${newname} + return 0 + fi + + info_log "skipping name ${newname}" + else + if [ "$count" -gt 7 ]; then + warn_log "consider cleaning up $(dirname ${newname})" + fi + + info_log "backing up ${fname} as ${newname}" + mkdir -p ${bkdir} + cp ${fname} ${newname} + return 0 + fi + }; done + + # find the oldest file and delete it. + newname=$(find ${bkdir} -maxdepth 1 -type f -name "${bname}.bk[0-9]" \ + | xargs -r ls -1t | tail -n 1) + if [ -z "${newname}" -o ! -f "${newname}" ]; then + error_log "did not find backup files for ${fname}" + return 1 + fi + + warn_log "deleting oldest backed up file ${newname}" + rm ${newname} + cp ${fname} ${newname} + + return $? +} + +# +# For each customizable file, if the file exists under +# PLATFORM_BANNER_DIR, and it passes some sanity checks, then install +# the file onto the root fs +# +install_banner_files () +{ + # quietly stop if the PLATFORM_BANNER_DIR is not setup + if [ ! -d ${PLATFORM_BANNER_DIR} ]; then + return 0 + fi + + local banner_files=$(get_banner_files) + local bfile="" + for bfile in ${banner_files}; do { + # do not attempt to install files if the directory on the root + # fs is absent; this is an unexpected condition + if [ ! -d "$(dirname ${bfile})" ]; then + error_log "directory does not exist for ${bfile}" + continue + fi + + # proceed only if the user provided a customization for the file + if [ ! -f "${PLATFORM_BANNER_DIR}/${bfile}" ]; then + info_log "file is not customized: ${bfile}" + continue + fi + + if [ -e "${bfile}" ]; then + if ! file_is_sane ${bfile}; then + continue + fi + if compare_file "${PLATFORM_BANNER_DIR}/${bfile}" "${bfile}"; then + info_log "file already installed: ${bfile}" + continue + fi + info_log "installing over existing file: ${bfile}" + backup_file ${bfile} \ + || continue + else + info_log "installing: ${bfile}" + fi + + cp ${PLATFORM_BANNER_DIR}/${bfile} ${bfile} + }; done; +} diff --git a/devtools/update-motd/files/install_banner_customization b/devtools/update-motd/files/install_banner_customization new file mode 100644 index 000000000..f7850b92b --- /dev/null +++ b/devtools/update-motd/files/install_banner_customization @@ -0,0 +1,16 @@ +#!/bin/bash + +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +. /usr/sbin/customize-banner + +install_banner_files + +# recreate /etc/motd +/usr/sbin/motd-update + +exit 0 diff --git a/devtools/update-motd/files/motd-footer b/devtools/update-motd/files/motd-footer new file mode 100644 index 000000000..02d6beb59 --- /dev/null +++ b/devtools/update-motd/files/motd-footer @@ -0,0 +1,16 @@ +#!/bin/sh + +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# motd.tail is reserved for the admin to append static +# trailing information to a dynamically generated +# /etc/motd. +# +# To add dynamic information, add a numbered +# script to /etc/motd.d/ + +[ -f /etc/motd.tail ] && cat /etc/motd.tail || true diff --git a/devtools/update-motd/files/motd-header b/devtools/update-motd/files/motd-header new file mode 100644 index 000000000..f0edde828 --- /dev/null +++ b/devtools/update-motd/files/motd-header @@ -0,0 +1,16 @@ +#!/bin/sh + +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# motd.head is reserved for the admin to prepend +# static information to a dynamically generated +# /etc/motd. +# +# To add dynamic information, add a numbered +# script to /etc/motd.d/ + +[ -f /etc/motd.head ] && cat /etc/motd.head || true diff --git a/devtools/update-motd/files/motd-update b/devtools/update-motd/files/motd-update new file mode 100644 index 000000000..b853b09d8 --- /dev/null +++ b/devtools/update-motd/files/motd-update @@ -0,0 +1,15 @@ +#!/bin/bash + +# +# Copyright (c) 2014, 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +MOTD_FILE=${MOTD_FILE:-"/etc/motd"} +MOTD_PATH=${MOTD_PATH:-"/etc/motd.d"} +MOTD_TAG=${MOTD_TAG:-"motd-update"} + +if [ -d ${MOTD_PATH} ]; then + run-parts --without-progname ${MOTD_PATH} 1>${MOTD_FILE} +fi diff --git a/devtools/update-motd/files/motd-update.cron b/devtools/update-motd/files/motd-update.cron new file mode 100644 index 000000000..19fa6681e --- /dev/null +++ b/devtools/update-motd/files/motd-update.cron @@ -0,0 +1,3 @@ +# m h dom mon dow user command +0 * * * * root /usr/sbin/motd-update + diff --git a/devtools/vim/centos/build_srpm.data b/devtools/vim/centos/build_srpm.data new file mode 100644 index 000000000..2ec7ea02f --- /dev/null +++ b/devtools/vim/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=1 diff --git a/devtools/vim/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/devtools/vim/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..848bd6e93 --- /dev/null +++ b/devtools/vim/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 852f734a938c881248d48feb9eb9e0f80d27af55 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 15:54:16 -0400 +Subject: [PATCH 1/1] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/vim.spec +--- + SPECS/vim.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/vim.spec b/SPECS/vim.spec +index 3cc96c2..be1a56c 100644 +--- a/SPECS/vim.spec ++++ b/SPECS/vim.spec +@@ -20,7 +20,7 @@ Summary: The VIM editor + URL: http://www.vim.org/ + Name: vim + Version: %{baseversion}.%{patchlevel} +-Release: 2%{?dist} ++Release: 2.el7%{?_tis_dist}.%{tis_patch_ver} + License: Vim + Group: Applications/Editors + Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}.tar.bz2 +-- +1.9.1 + diff --git a/devtools/vim/centos/meta_patches/PATCH_ORDER b/devtools/vim/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..91f9a80ea --- /dev/null +++ b/devtools/vim/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Update-package-versioning-for-TIS-format.patch diff --git a/devtools/vim/centos/srpm_path b/devtools/vim/centos/srpm_path new file mode 100644 index 000000000..2749149ae --- /dev/null +++ b/devtools/vim/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/vim-7.4.160-2.el7.src.rpm diff --git a/devtools/vim/files/vimrc b/devtools/vim/files/vimrc new file mode 100644 index 000000000..aa57c277c --- /dev/null +++ b/devtools/vim/files/vimrc @@ -0,0 +1,92 @@ +" An example for a vimrc file. +" +" Maintainer: Bram Moolenaar +" Last change: 2008 Jul 02 +" +" To use it, copy it to +" for Unix and OS/2: ~/.vimrc +" for Amiga: s:.vimrc +" for MS-DOS and Win32: $VIM\_vimrc +" for OpenVMS: sys$login:.vimrc + +" When started as "evim", evim.vim will already have done these settings. +if v:progname =~? "evim" + finish +endif + +" Use Vim settings, rather then Vi settings (much better!). +" This must be first, because it changes other options as a side effect. +set nocompatible + +" allow backspacing over everything in insert mode +set backspace=indent,eol,start + +set nobackup " do not keep a backup file, use versions instead +set history=50 " keep 50 lines of command line history +set ruler " show the cursor position all the time +set showcmd " display incomplete commands +set incsearch " do incremental searching + +" For Win32 GUI: remove 't' flag from 'guioptions': no tearoff menu entries +" let &guioptions = substitute(&guioptions, "t", "", "g") + +" Don't use Ex mode, use Q for formatting +map Q gq + +" CTRL-U in insert mode deletes a lot. Use CTRL-G u to first break undo, +" so that you can undo CTRL-U after inserting a line break. +inoremap u + +" In many terminal emulators the mouse works just fine, thus enable it. +if has('mouse') + set mouse-=a +endif + +" Switch syntax highlighting on, when the terminal has colors +" Also switch on highlighting the last used search pattern. +"if &t_Co > 2 || has("gui_running") +" syntax on +" set hlsearch +"endif + +" Only do this part when compiled with support for autocommands. +if has("autocmd") + + " Enable file type detection. + " Use the default filetype settings, so that mail gets 'tw' set to 72, + " 'cindent' is on in C files, etc. + " Also load indent files, to automatically do language-dependent indenting. + filetype plugin indent off + + " Put these in an autocmd group, so that we can delete them easily. + augroup vimrcEx + au! + + " For all text files set 'textwidth' to 78 characters. + autocmd FileType text setlocal textwidth=78 + + " When editing a file, always jump to the last known cursor position. + " Don't do it when the position is invalid or when inside an event handler + " (happens when dropping a file on gvim). + " Also don't do it when the mark is in the first line, that is the default + " position when opening a file. + autocmd BufReadPost * + \ if line("'\"") > 1 && line("'\"") <= line("$") | + \ exe "normal! g`\"" | + \ endif + + augroup END + +else + + set autoindent " always set autoindenting on + +endif " has("autocmd") + +" Convenient command to see the difference between the current buffer and the +" file it was loaded from, thus the changes you made. +" Only define it when not defined already. +if !exists(":DiffOrig") + command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis + \ | wincmd p | diffthis +endif diff --git a/extended/cloud-init/centos/build_srpm.data b/extended/cloud-init/centos/build_srpm.data new file mode 100644 index 000000000..0eac83bbb --- /dev/null +++ b/extended/cloud-init/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=4 diff --git a/extended/cloud-init/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/cloud-init/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..08a522134 --- /dev/null +++ b/extended/cloud-init/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 869e94c0bb51471063fab9fa6bdff54f1db8407e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Tue, 7 Nov 2017 15:25:12 -0500 +Subject: [PATCH] Update-package-versioning-for-TIS-format + +--- + SPECS/cloud-init.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/cloud-init.spec b/SPECS/cloud-init.spec +index 89691ae..935c970 100644 +--- a/SPECS/cloud-init.spec ++++ b/SPECS/cloud-init.spec +@@ -7,7 +7,7 @@ + + Name: cloud-init + Version: 0.7.9 +-Release: 9%{?dist}.2 ++Release: 9.el7.centos.2%{?_tis_dist}.%{tis_patch_ver} + Summary: Cloud instance init scripts + + Group: System Environment/Base +-- +1.8.3.1 + diff --git a/extended/cloud-init/centos/meta_patches/PATCH_ORDER b/extended/cloud-init/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..d329ace03 --- /dev/null +++ b/extended/cloud-init/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +spec-include-tis-changes.patch diff --git a/extended/cloud-init/centos/meta_patches/spec-include-tis-changes.patch b/extended/cloud-init/centos/meta_patches/spec-include-tis-changes.patch new file mode 100644 index 000000000..4ebc1600e --- /dev/null +++ b/extended/cloud-init/centos/meta_patches/spec-include-tis-changes.patch @@ -0,0 +1,26 @@ +From cd41e4fb7bee4272f1074b4bc4e9c79c7fce3530 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Wed, 8 Nov 2017 11:13:02 -0500 +Subject: [PATCH] spec-include-tis-changes + +--- + SPECS/cloud-init.spec | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/SPECS/cloud-init.spec b/SPECS/cloud-init.spec +index 935c970..a611192 100644 +@@ -44,7 +45,10 @@ Patch0019: 0019-Add-missing-sysconfig-unit-test-data.patch + Patch0020: 0020-Fix-ipv6-subnet-detection.patch + Patch0021: 0021-azure-ensure-that-networkmanager-hook-script-runs.patch + Patch0022: 0022-RHEL-CentOS-Fix-default-routes-for-IPv4-IPv6-configu.patch +-Patch9999: cloud-init-add-centos-os.patch ++Patch0999: cloud-init-add-centos-os.patch ++ ++# WRS patches ++Patch2000: cloud-init-interactive-parted.patch + + # Deal with noarch -> arch + # https://bugzilla.redhat.com/show_bug.cgi?id=1067089 +-- +1.8.3.1 + diff --git a/extended/cloud-init/centos/patches/cloud-init-interactive-parted.patch b/extended/cloud-init/centos/patches/cloud-init-interactive-parted.patch new file mode 100644 index 000000000..facd62471 --- /dev/null +++ b/extended/cloud-init/centos/patches/cloud-init-interactive-parted.patch @@ -0,0 +1,25 @@ +From 70b90db2364256fe8ba7e368cbd96cd53b246cb3 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 8 Nov 2017 11:02:42 -0500 +Subject: [PATCH] cloud-init-interactive-parted + +--- + cloudinit/config/cc_growpart.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py +index 832bb3f..71c4f7f 100644 +--- a/cloudinit/config/cc_growpart.py ++++ b/cloudinit/config/cc_growpart.py +@@ -182,7 +182,7 @@ class ResizeGpart(object): + + before = get_size(partdev) + try: +- util.subp(["gpart", "resize", "-i", partnum, diskdev]) ++ util.subp(["resizepart.sh", diskdev, partnum]) + except util.ProcessExecutionError as e: + util.logexc(LOG, "Failed: gpart resize -i %s %s", partnum, diskdev) + raise ResizeFailedException(e) +-- +1.8.3.1 + diff --git a/extended/cloud-init/centos/srpm_path b/extended/cloud-init/centos/srpm_path new file mode 100644 index 000000000..33fb3ec3e --- /dev/null +++ b/extended/cloud-init/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/cloud-init-0.7.9-9.el7.centos.2.src.rpm diff --git a/extended/cloud-init/cloud-init/cloud-init-interactive-parted.patch b/extended/cloud-init/cloud-init/cloud-init-interactive-parted.patch new file mode 100644 index 000000000..72627bfb7 --- /dev/null +++ b/extended/cloud-init/cloud-init/cloud-init-interactive-parted.patch @@ -0,0 +1,13 @@ +Index: cloud-init-0.7.4/cloudinit/config/cc_growpart.py +=================================================================== +--- cloud-init-0.7.4.orig/cloudinit/config/cc_growpart.py ++++ cloud-init-0.7.4/cloudinit/config/cc_growpart.py +@@ -97,7 +97,7 @@ class ResizeParted(object): + def resize(self, diskdev, partnum, partdev): + before = get_size(partdev) + try: +- util.subp(["parted", diskdev, "resizepart", partnum]) ++ util.subp(["resizepart.sh", diskdev, partnum]) + except util.ProcessExecutionError as e: + raise ResizeFailedException(e) + diff --git a/extended/cloud-init/cloud-init/find_candidate_devs_fix.patch b/extended/cloud-init/cloud-init/find_candidate_devs_fix.patch new file mode 100644 index 000000000..ea81a19b5 --- /dev/null +++ b/extended/cloud-init/cloud-init/find_candidate_devs_fix.patch @@ -0,0 +1,74 @@ +--- + cloudinit/sources/DataSourceConfigDrive.py | 39 ++++++++++++++++++++--------- + 1 file changed, 27 insertions(+), 12 deletions(-) + +--- a/cloudinit/sources/DataSourceConfigDrive.py ++++ b/cloudinit/sources/DataSourceConfigDrive.py +@@ -40,6 +40,12 @@ DEFAULT_METADATA = { + "instance-id": DEFAULT_IID, + } + VALID_DSMODES = ("local", "net", "pass", "disabled") ++FS_TYPES = ('vfat', 'iso9660') ++LABEL_TYPES = ('config-2',) ++POSSIBLE_MOUNTS = ('sr', 'cd') ++OPTICAL_DEVICES = tuple(('/dev/%s%s' % (z, i) for z in POSSIBLE_MOUNTS ++ for i in range(0, 2))) ++ + + + class ConfigDriveHelper(object): +@@ -250,7 +256,7 @@ class BrokenConfigDriveDir(Exception): + pass + + +-def find_candidate_devs(): ++def find_candidate_devs(probe_optical=True): + """Return a list of devices that may contain the config drive. + + The returned list is sorted by search order where the first item has +@@ -268,12 +274,20 @@ def find_candidate_devs(): + """ + + # Query optical drive to get it in blkid cache for 2.6 kernels +- util.find_devs_with(path="/dev/sr0") +- util.find_devs_with(path="/dev/sr1") +- +- by_fstype = (util.find_devs_with("TYPE=vfat") + +- util.find_devs_with("TYPE=iso9660")) +- by_label = util.find_devs_with("LABEL=config-2") ++ if probe_optical: ++ for device in OPTICAL_DEVICES: ++ try: ++ util.find_devs_with(path=device) ++ except util.ProcessExecutionError: ++ pass ++ ++ by_fstype = [] ++ for fs_type in FS_TYPES: ++ by_fstype.extend(util.find_devs_with("TYPE=%s" % (fs_type))) ++ ++ by_label = [] ++ for label in LABEL_TYPES: ++ by_label.extend(util.find_devs_with("LABEL=%s" % (label))) + + # give preference to "last available disk" (vdb over vda) + # note, this is not a perfect rendition of that. +@@ -282,12 +296,13 @@ def find_candidate_devs(): + + # combine list of items by putting by-label items first + # followed by fstype items, but with dupes removed +- combined = (by_label + [d for d in by_fstype if d not in by_label]) +- +- # We are looking for block device (sda, not sda1), ignore partitions +- combined = [d for d in combined if not util.is_partition(d)] ++ candidates = (by_label + [d for d in by_fstype if d not in by_label]) + +- return combined ++ # We are looking for a block device or partition with necessary label or ++ # an unpartitioned block device (ex sda, not sda1) ++ devices = [d for d in candidates ++ if d in by_label or not util.is_partition(d)] ++ return devices + + + def read_config_drive_dir(source_dir): diff --git a/extended/cloud-init/cloud-init/first_boot.patch b/extended/cloud-init/cloud-init/first_boot.patch new file mode 100644 index 000000000..bbcfe8304 --- /dev/null +++ b/extended/cloud-init/cloud-init/first_boot.patch @@ -0,0 +1,35 @@ +--- + cloudinit/sources/DataSourceConfigDrive.py | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/cloudinit/sources/DataSourceConfigDrive.py ++++ b/cloudinit/sources/DataSourceConfigDrive.py +@@ -52,12 +52,13 @@ class ConfigDriveHelper(object): + def __init__(self, distro): + self.distro = distro + +- def on_first_boot(self, data): ++ def on_first_boot(self, data, dsmode="local"): + if not data: + data = {} +- if 'network_config' in data: +- LOG.debug("Updating network interfaces from config drive") +- self.distro.apply_network(data['network_config']) ++ if dsmode == "local": ++ if 'network_config' in data: ++ LOG.debug("Updating network interfaces from config drive") ++ self.distro.apply_network(data['network_config']) + files = data.get('files') + if files: + LOG.debug("Writing %s injected files", len(files)) +@@ -214,8 +215,8 @@ class DataSourceConfigDrive(sources.Data + # instance-id + prev_iid = get_previous_iid(self.paths) + cur_iid = md['instance-id'] +- if prev_iid != cur_iid and self.dsmode == "local": +- self.helper.on_first_boot(results) ++ if prev_iid != cur_iid: ++ self.helper.on_first_boot(results, dsmode=self.dsmode) + + # dsmode != self.dsmode here if: + # * dsmode = "pass", pass means it should only copy files and then diff --git a/extended/e2fsprogs/centos/build_srpm.data b/extended/e2fsprogs/centos/build_srpm.data new file mode 100644 index 000000000..d3f64f336 --- /dev/null +++ b/extended/e2fsprogs/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=3 diff --git a/extended/e2fsprogs/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/e2fsprogs/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..ec9f8b3f7 --- /dev/null +++ b/extended/e2fsprogs/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 1e7c28725307d612681f43002fe4a901e2fade8e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:09:29 -0400 +Subject: [PATCH 1/3] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/e2fsprogs.spec +--- + SPECS/e2fsprogs.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/e2fsprogs.spec b/SPECS/e2fsprogs.spec +index 1b1d08c..b5babce 100644 +--- a/SPECS/e2fsprogs.spec ++++ b/SPECS/e2fsprogs.spec +@@ -1,7 +1,7 @@ + Summary: Utilities for managing ext2, ext3, and ext4 filesystems + Name: e2fsprogs + Version: 1.42.9 +-Release: 10%{?dist} ++Release: 10.el7%{?_tis_dist}.%{tis_patch_ver} + + # License tags based on COPYING file distinctions for various components + License: GPLv2 +-- +1.9.1 + diff --git a/extended/e2fsprogs/centos/meta_patches/0002-SPEC-tamper-proof-bash-log.patch b/extended/e2fsprogs/centos/meta_patches/0002-SPEC-tamper-proof-bash-log.patch new file mode 100644 index 000000000..a9a2d8dd5 --- /dev/null +++ b/extended/e2fsprogs/centos/meta_patches/0002-SPEC-tamper-proof-bash-log.patch @@ -0,0 +1,38 @@ +From cf44fd061e7be981fbea0d5625ddf124d1991e4e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:09:29 -0400 +Subject: [PATCH 2/3] WRS: 0002-SPEC-tamper-proof-bash-log.patch + +Conflicts: + SPECS/e2fsprogs.spec +--- + SPECS/e2fsprogs.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/e2fsprogs.spec b/SPECS/e2fsprogs.spec +index b5babce..38ff00b 100644 +--- a/SPECS/e2fsprogs.spec ++++ b/SPECS/e2fsprogs.spec +@@ -35,6 +35,9 @@ Patch22: e2fsprogs-1.42.9-resize2fs-clear-uninit-BG.patch + Patch23: e2fsprogs-1.43.3-libext2fs-don-t-ignore-fsync-errors.patch + Patch24: e2fsprogs-1.42.10-Fix-nroff-macro-issue-in-chattr-man-page.patch + ++# WRS patches ++Patch100: 0100-tamper-proof-bash-log.patch ++ + Url: http://e2fsprogs.sourceforge.net/ + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + Requires: e2fsprogs-libs%{?_isa} = %{version}-%{release} +@@ -208,6 +211,9 @@ It was originally inspired by the Multics SubSystem library. + %patch23 -p1 + %patch24 -p1 + ++# WRS patches ++%patch100 -p1 ++ + %build + %configure --enable-elf-shlibs --enable-nls --disable-uuidd --disable-fsck \ + --disable-e2initrd-helper --disable-libblkid --disable-libuuid \ +-- +1.9.1 + diff --git a/extended/e2fsprogs/centos/meta_patches/PATCH_ORDER b/extended/e2fsprogs/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..6fb5c9a5c --- /dev/null +++ b/extended/e2fsprogs/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-SPEC-tamper-proof-bash-log.patch +meta-e2fsprogs-disable-tests.patch diff --git a/extended/e2fsprogs/centos/meta_patches/meta-e2fsprogs-disable-tests.patch b/extended/e2fsprogs/centos/meta_patches/meta-e2fsprogs-disable-tests.patch new file mode 100644 index 000000000..6fcf832f6 --- /dev/null +++ b/extended/e2fsprogs/centos/meta_patches/meta-e2fsprogs-disable-tests.patch @@ -0,0 +1,32 @@ +From f57e1196deb8890c143ebd978f0b83e4c0e749f8 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:09:29 -0400 +Subject: [PATCH 3/3] WRS: meta-e2fsprogs-disable-tests.patch + +--- + SPECS/e2fsprogs.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/e2fsprogs.spec b/SPECS/e2fsprogs.spec +index 38ff00b..0eb885a 100644 +--- a/SPECS/e2fsprogs.spec ++++ b/SPECS/e2fsprogs.spec +@@ -37,6 +37,7 @@ Patch24: e2fsprogs-1.42.10-Fix-nroff-macro-issue-in-chattr-man-page.patch + + # WRS patches + Patch100: 0100-tamper-proof-bash-log.patch ++Patch101: 0101-e2fsprogs-disable-tests.patch + + Url: http://e2fsprogs.sourceforge.net/ + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +@@ -213,6 +214,7 @@ It was originally inspired by the Multics SubSystem library. + + # WRS patches + %patch100 -p1 ++%patch101 -p1 + + %build + %configure --enable-elf-shlibs --enable-nls --disable-uuidd --disable-fsck \ +-- +1.9.1 + diff --git a/extended/e2fsprogs/centos/patches/0100-tamper-proof-bash-log.patch b/extended/e2fsprogs/centos/patches/0100-tamper-proof-bash-log.patch new file mode 100644 index 000000000..1722eb6f3 --- /dev/null +++ b/extended/e2fsprogs/centos/patches/0100-tamper-proof-bash-log.patch @@ -0,0 +1,78 @@ +From 21f104089cf3a8ee8eb295bafa47dff6ab1000ac Mon Sep 17 00:00:00 2001 +From: David Balme +Date: Sun, 29 Jan 2017 18:14:25 -0500 +Subject: [PATCH 1/1] tamper proof bash log + +--- + misc/chattr.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/misc/chattr.c b/misc/chattr.c +index f130108..44db04b 100644 +--- a/misc/chattr.c ++++ b/misc/chattr.c +@@ -188,6 +188,49 @@ static int decode_arg (int * i, int argc, char ** argv) + return 1; + } + ++// ++// returns true (1) if name looks like ++// bash.log ++// bash.log* ++// */bash.log ++// */bash.log* ++// ++static int is_bash_log_file(const char * name) { ++ if (name == NULL) { ++ return 0; ++ } ++ char * srchresult = strstr(name, "bash.log"); ++ if (srchresult != NULL) { ++ if (srchresult == name) { ++ // starts with scenario ++ return 1; ++ } ++ // contained scenario ++ // let's ensure preceding char is a / ++ srchresult --; ++ if (*srchresult == '/') { ++ return 1; ++ } ++ return 0; ++ } ++ return 0; ++} ++ ++// returns true (1) if user is trying to remove append-only flag ++// from bash.log file. ++static int is_remove_append_only_on_bash_log(const char * name, unsigned long flags, int rem) { ++ if (!rem) { ++ return 0; // no attribute remove operation specified ++ } ++ if (!(flags & EXT2_APPEND_FL)) { // ++ return 0; ++ } ++ // at this point we are trying to remove append only attribute! ++ // now check if its a bash.log file ++ return is_bash_log_file(name); ++} ++ ++ + static int chattr_dir_proc(const char *, struct dirent *, void *); + + static int change_attributes(const char * name) +@@ -208,6 +251,11 @@ static int change_attributes(const char * name) + _("while reading flags on %s"), name); + return -1; + } ++ ++ if (is_remove_append_only_on_bash_log(name, flags, rem)) { ++ return 0; ++ } ++ + if (set) { + if (verbose) { + printf (_("Flags of %s set as "), name); +-- +1.9.1 + diff --git a/extended/e2fsprogs/centos/patches/0101-e2fsprogs-disable-tests.patch b/extended/e2fsprogs/centos/patches/0101-e2fsprogs-disable-tests.patch new file mode 100644 index 000000000..e69873006 --- /dev/null +++ b/extended/e2fsprogs/centos/patches/0101-e2fsprogs-disable-tests.patch @@ -0,0 +1,27 @@ +From a6c86c1badb9cebb44ffbb53a8ff5d5529b12fd5 Mon Sep 17 00:00:00 2001 +From: Matt Peters +Date: Fri, 3 Feb 2017 16:06:51 -0500 +Subject: [PATCH 1/1] e2fsprogs disable tests + +--- + Makefile.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile.in b/Makefile.in +index f327d19..7faca16 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -16,8 +16,8 @@ INSTALL = @INSTALL@ + QUOTA_LIB_SUBDIR= lib/quota + + LIB_SUBDIRS=lib/et lib/ss lib/e2p $(UUID_LIB_SUBDIR) lib/ext2fs $(BLKID_LIB_SUBDIR) $(QUOTA_LIB_SUBDIR) intl +-PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po +-SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) tests ++PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) po ++SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) + + SUBS= util/subst.conf lib/config.h lib/dirpaths.h \ + lib/ext2fs/ext2_types.h lib/blkid/blkid_types.h lib/uuid/uuid_types.h +-- +1.8.3.1 + diff --git a/extended/e2fsprogs/centos/srpm_path b/extended/e2fsprogs/centos/srpm_path new file mode 100644 index 000000000..d4553d5e2 --- /dev/null +++ b/extended/e2fsprogs/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/e2fsprogs-1.42.9-10.el7.src.rpm diff --git a/extended/iproute/centos/build_srpm.data b/extended/iproute/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/extended/iproute/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/extended/iproute/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/iproute/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..9593cd073 --- /dev/null +++ b/extended/iproute/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From fdb3dda504c044aeb0b572c2ac4661b345aed15e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 18:28:51 -0400 +Subject: [PATCH 1/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/iproute.spec +--- + SPECS/iproute.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/iproute.spec b/SPECS/iproute.spec +index 83991ef..ee7bc77 100644 +--- a/SPECS/iproute.spec ++++ b/SPECS/iproute.spec +@@ -2,7 +2,7 @@ + + %define rpmversion 3.10.0 + %define baserelease 74.el7 +-%define specrelease 87%{?dist} ++%define specrelease 87.el7%{?_tis_dist}.%{tis_patch_ver} + %define pkg_release %{specrelease}%{?buildid} + + Summary: Advanced IP routing and network device configuration tools +-- +1.9.1 + diff --git a/extended/iproute/centos/meta_patches/Add-WRS-ip-maddr-fix-ifname.patch b/extended/iproute/centos/meta_patches/Add-WRS-ip-maddr-fix-ifname.patch new file mode 100644 index 000000000..af2e4cd89 --- /dev/null +++ b/extended/iproute/centos/meta_patches/Add-WRS-ip-maddr-fix-ifname.patch @@ -0,0 +1,40 @@ +From 8ef373e01a4175e5a170dd7767533e8a6dc9c407 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 18:28:51 -0400 +Subject: [PATCH 2/2] WRS: Add-WRS-ip-maddr-fix-ifname.patch + +Conflicts: + SPECS/iproute.spec +--- + SPECS/iproute.spec | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SPECS/iproute.spec b/SPECS/iproute.spec +index ee7bc77..57ce332 100644 +--- a/SPECS/iproute.spec ++++ b/SPECS/iproute.spec +@@ -183,6 +183,10 @@ Patch171: 0172-devlink-Convert-conditional-in-dl_argv_handle_port-t.pa + Patch172: 0173-devlink-write-usage-help-messages-to-stderr.patch + Patch173: 0174-devlink-Add-usage-help-for-eswitch-subcommand.patch + Patch174: 0175-devlink-Call-dl_free-in-early-exit-case.patch ++ ++# WRS ++Patch500: ip-maddr-fix-ifname.patch ++ + License: GPLv2+ and Public Domain + BuildRequires: bison + BuildRequires: flex +@@ -398,6 +402,10 @@ The libnetlink static library. + %patch172 -p1 + %patch173 -p1 + %patch174 -p1 ++ ++# WRS ++%patch500 -p1 ++ + sed -i 's/iproute-doc/%{name}-%{version}/' man/man8/lnstat.8 + + %build +-- +1.9.1 + diff --git a/extended/iproute/centos/meta_patches/PATCH_ORDER b/extended/iproute/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..2540f1ff3 --- /dev/null +++ b/extended/iproute/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +Add-WRS-ip-maddr-fix-ifname.patch diff --git a/extended/iproute/centos/patches/ip-maddr-fix-ifname.patch b/extended/iproute/centos/patches/ip-maddr-fix-ifname.patch new file mode 100644 index 000000000..b75cdcba9 --- /dev/null +++ b/extended/iproute/centos/patches/ip-maddr-fix-ifname.patch @@ -0,0 +1,27 @@ +From 9a98e4f90d0f8990674ab00e292fe8ad70af1afe Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Tue, 30 May 2017 18:06:10 -0400 +Subject: [PATCH 1/1] ip maddr remove trailing colon from the interface name + +--- + ip/ipmaddr.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c +index a77a18f..975bd57 100644 +--- a/ip/ipmaddr.c ++++ b/ip/ipmaddr.c +@@ -143,6 +143,10 @@ static void read_igmp(struct ma_info **result_p) + + if (buf[0] != '\t') { + sscanf(buf, "%d%s", &m.index, m.name); ++ /* remove last character if it is a colon */ ++ if (strlen(m.name) > 0 && (m.name[strlen(m.name)-1] == ':')) { ++ m.name[strlen(m.name)-1] = 0; ++ } + continue; + } + +-- +1.8.3.1 + diff --git a/extended/iproute/centos/srpm_path b/extended/iproute/centos/srpm_path new file mode 100644 index 000000000..08151ce82 --- /dev/null +++ b/extended/iproute/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/iproute-3.10.0-87.el7.src.rpm diff --git a/extended/irqbalance/centos/build_srpm.data b/extended/irqbalance/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/extended/irqbalance/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/extended/irqbalance/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/irqbalance/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..573c6ddc6 --- /dev/null +++ b/extended/irqbalance/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,26 @@ +From f2d3ca9a2b62632b9d783b3448c0e04eb0dade74 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:57:43 -0400 +Subject: [PATCH 2/3] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/irqbalance.spec +--- + SPECS/irqbalance.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/irqbalance.spec b/SPECS/irqbalance.spec +index 3e70224..15a42c3 100644 +--- a/SPECS/irqbalance.spec ++++ b/SPECS/irqbalance.spec +@@ -1,6 +1,6 @@ + Name: irqbalance + Version: 1.0.7 +-Release: 10%{?dist} ++Release: 10.el7%{?_tis_dist}.%{tis_patch_ver} + Epoch: 3 + Summary: IRQ balancing daemon + +-- +1.9.1 + diff --git a/extended/irqbalance/centos/meta_patches/PATCH_ORDER b/extended/irqbalance/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..97fa73602 --- /dev/null +++ b/extended/irqbalance/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +spec-disable-irqbalance-service.patch diff --git a/extended/irqbalance/centos/meta_patches/spec-disable-irqbalance-service.patch b/extended/irqbalance/centos/meta_patches/spec-disable-irqbalance-service.patch new file mode 100644 index 000000000..62f3b622c --- /dev/null +++ b/extended/irqbalance/centos/meta_patches/spec-disable-irqbalance-service.patch @@ -0,0 +1,38 @@ +From 4a6da18465135333b470cc3f1817b78e6177886a Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:57:43 -0400 +Subject: [PATCH 1/3] WRS: spec-disable-irqbalance-service.patch + +--- + SPECS/irqbalance.spec | 15 --------------- + 1 file changed, 15 deletions(-) + +diff --git a/SPECS/irqbalance.spec b/SPECS/irqbalance.spec +index 9d4e948..3e70224 100644 +--- a/SPECS/irqbalance.spec ++++ b/SPECS/irqbalance.spec +@@ -89,21 +89,6 @@ install -p -m 0644 ./irqbalance.1 %{buildroot}%{_mandir}/man1/ + %{_mandir}/man1/* + %config(noreplace) %{_sysconfdir}/sysconfig/irqbalance + +-%post +-%systemd_post irqbalance.service +- +-%preun +-%systemd_preun irqbalance.service +- +-%postun +-%systemd_postun_with_restart irqbalance.service +- +-%triggerun -- irqbalance < 2:0.56-3 +-if /sbin/chkconfig --level 3 irqbalance ; then +- /bin/systemctl enable irqbalance.service >/dev/null 2>&1 || : +-fi +-/sbin/chkconfig --del irqbalance >/dev/null 2>&1 || : +- + %changelog + * Tue May 16 2017 Petr Oros - 3:1.0.7-10 + - irqbalance node package patch +-- +1.9.1 + diff --git a/extended/irqbalance/centos/srpm_path b/extended/irqbalance/centos/srpm_path new file mode 100644 index 000000000..8efe7876a --- /dev/null +++ b/extended/irqbalance/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/irqbalance-1.0.7-10.el7.src.rpm diff --git a/extended/libvirt-python/PKG-INFO b/extended/libvirt-python/PKG-INFO new file mode 100644 index 000000000..291d8d4d0 --- /dev/null +++ b/extended/libvirt-python/PKG-INFO @@ -0,0 +1,14 @@ +Metadata-Version: 1.1 +Name: libvirt-python +Version: 1.2.17 +Summary: The libvirt virtualization API python2 binding +Home-page: +Author: +Author-email: +License: LGPLv2+ + +Description: +The libvirt-python package contains a module that permits applications +written in the Python programming language to use the interface +supplied by the libvirt library to use the virtualization capabilities +of recent versions of Linux (and other OSes). diff --git a/extended/libvirt-python/centos/build_srpm.data b/extended/libvirt-python/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/extended/libvirt-python/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/extended/libvirt-python/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/libvirt-python/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..e84ba1242 --- /dev/null +++ b/extended/libvirt-python/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,28 @@ +From 1f430bb5fbae2d5135ad4e547de3ac30f32b299b Mon Sep 17 00:00:00 2001 +Message-Id: <1f430bb5fbae2d5135ad4e547de3ac30f32b299b.1502820262.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 15 Aug 2017 14:04:06 -0400 +Subject: [PATCH 1/1] Update package versioning for TIS format + +Signed-off-by: Jim Somerville +--- + SPECS/libvirt-python.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/libvirt-python.spec b/SPECS/libvirt-python.spec +index c2ad17f..6108b7e 100644 +--- a/SPECS/libvirt-python.spec ++++ b/SPECS/libvirt-python.spec +@@ -7,7 +7,7 @@ + Summary: The libvirt virtualization API python2 binding + Name: libvirt-python + Version: 3.5.0 +-Release: 1%{?dist}%{?extra_release} ++Release: 1%{?_tis_dist}.%{tis_patch_ver} + Source0: http://libvirt.org/sources/python/%{name}-%{version}.tar.gz + Url: http://libvirt.org + License: LGPLv2+ +-- +1.8.3.1 + + diff --git a/extended/libvirt-python/centos/meta_patches/PATCH_ORDER b/extended/libvirt-python/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..91f9a80ea --- /dev/null +++ b/extended/libvirt-python/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Update-package-versioning-for-TIS-format.patch diff --git a/extended/libvirt-python/centos/srpm_path b/extended/libvirt-python/centos/srpm_path new file mode 100644 index 000000000..6562d6c9d --- /dev/null +++ b/extended/libvirt-python/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/libvirt-python-3.5.0-1.fc24.src.rpm diff --git a/extended/libvirt/.gitignore b/extended/libvirt/.gitignore new file mode 100644 index 000000000..b93f29dce --- /dev/null +++ b/extended/libvirt/.gitignore @@ -0,0 +1,6 @@ +!.distro +.distro/centos7/rpmbuild/RPMS +.distro/centos7/rpmbuild/SRPMS +.distro/centos7/rpmbuild/BUILD +.distro/centos7/rpmbuild/BUILDROOT +.distro/centos7/rpmbuild/SOURCES/libvirt*tar.gz diff --git a/extended/libvirt/PKG-INFO b/extended/libvirt/PKG-INFO new file mode 100644 index 000000000..3d4ac7c76 --- /dev/null +++ b/extended/libvirt/PKG-INFO @@ -0,0 +1,16 @@ +Metadata-Version: 1.1 +Name: libvirt +Version: 1.2.17 +Summary: Library providing a simple virtualization API +Home-page: +Author: Windriver +Author-email: info@windriver.com +License: Apache-2.0 + +Description: +Libvirt is a C toolkit to interact with the virtualization capabilities +of recent versions of Linux (and other OSes). The main package includes +the libvirtd server exporting the virtualization support. + + +Platform: UNKNOWN diff --git a/extended/libvirt/README b/extended/libvirt/README new file mode 100644 index 000000000..a2b167b30 --- /dev/null +++ b/extended/libvirt/README @@ -0,0 +1,37 @@ +The Centos 7 libvirt source rpm was taken from: +http://vault.centos.org/centos/7/updates/Source/SPackages/libvirt-1.2.17-13.el7_2.3.src.rpm + +It's possible to resolve the source rpm based on the yum repos: +$ yumdownloader --source --urls libvirt + +The libvirt source code was forked under .../cgcs/git/libvirt. +Notes: - The branch is based on upstream tag v1.2.17-maint. + - Then each RedHat patches have been committed one by one in the same + order specified in the RedHat spec (actually this was automated to use + 'git am' for each of the patches mentionned in the spec). + - The last patch from RedHat is tagged 'libvirt-1.2.17-13.el7_2.3'. + - After this tag, all the patches are port from R2. + +The libvirt git repository doesn't come with the ./configure script (and its +dependancies). This has to be built using autoconf (but the libvirt releases +comes with those, releases are generated using 'make dist'). + +One caveat is that bootstrap is made to be executed in a git tree. Trying to +execute it out of tree, like the Centos build environment, was unsuccessfull +so far. + +The current workaround for now is to commit the configure scripts in the +libvirt git repo: + +$ NOCONFIGURE=1 ./autogen.sh --copy +$ NOCONFIGURE=1 ./autogen.sh --copy +# Remove all .gitignore temporarily for showing modified files +$ find . -name .gitignore | xargs rm +$ git add -A +$ git reset HEAD .gitignore +# Repeat last command for all .gitignore files removed +$ git commit + +Autogen is executed twice. The first time soft links are created under +build-aux/. Running it a second time makes bootstrap copying them and +replacing the soft links (there is most likely a smarter way to do this). diff --git a/extended/libvirt/centos/build_srpm.data b/extended/libvirt/centos/build_srpm.data new file mode 100644 index 000000000..c7efb48f3 --- /dev/null +++ b/extended/libvirt/centos/build_srpm.data @@ -0,0 +1,8 @@ +SRC_DIR="$CGCS_BASE/git/libvirt" +COPY_LIST="\ + libvirt-3.5.0/* \ + $CGCS_BASE/downloads/gnulib-ffc927e.tar.gz \ + $CGCS_BASE/downloads/keycodemapdb-8370ba8.tar.gz" +TIS_BASE_SRCREV=9bd7c96bd0a0cc879c1e44277f5a734166bf1add +TIS_PATCH_VER=GITREVCOUNT +BUILD_IS_SLOW=4 diff --git a/extended/libvirt/centos/libvirt.spec b/extended/libvirt/centos/libvirt.spec new file mode 100644 index 000000000..decaae03d --- /dev/null +++ b/extended/libvirt/centos/libvirt.spec @@ -0,0 +1,2146 @@ +# -*- rpm-spec -*- + +# This spec file assumes you are building on a Fedora or RHEL version +# that's still supported by the vendor: that means Fedora 23 or newer, +# or RHEL 6 or newer. It may need some tweaks for other distros. +# If neither fedora nor rhel was defined, try to guess them from dist +%if (0%{?fedora} && 0%{?fedora} >= 23) || (0%{?rhel} && 0%{?rhel} >= 6) + %define supported_platform 1 +%else + %define supported_platform 0 +%endif + +# Default to skipping autoreconf. Distros can change just this one line +# (or provide a command-line override) if they backport any patches that +# touch configure.ac or Makefile.am. +# Always run autoreconf +%{!?enable_autotools:%global enable_autotools 1} + +# WRS: Custom build config. Based on the R2/bitbake configure line. +%define _without_esx 1 +%define _without_hyperv 1 +%define _without_libxl 1 +%define _without_vbox 1 +%define _without_vmware 1 +%define _without_xen 1 +%define _without_xenapi 1 +%define _without_phyp 1 +%define _without_openvz 1 +%define _without_numad 1 +%define _without_capng 1 +%define _without_polkit 1 +%define _without_sasl 1 +%define _without_dtrace 1 +%define _without_avahi 1 + +# The hypervisor drivers that run in libvirtd +%define with_xen 0%{!?_without_xen:1} +%define with_qemu 0%{!?_without_qemu:1} +%define with_lxc 0%{!?_without_lxc:1} +%define with_uml 0%{!?_without_uml:1} +%define with_libxl 0%{!?_without_libxl:1} +%define with_vbox 0%{!?_without_vbox:1} + +%define with_qemu_tcg %{with_qemu} + +%define qemu_kvm_arches %{ix86} x86_64 + +%if 0%{?fedora} + %define qemu_kvm_arches %{ix86} x86_64 %{power64} s390x %{arm} aarch64 +%endif + +%if 0%{?rhel} + %define with_qemu_tcg 0 + %define qemu_kvm_arches x86_64 + %if 0%{?rhel} >= 7 + %define qemu_kvm_arches x86_64 %{power64} aarch64 + %endif +%endif + +%ifarch %{qemu_kvm_arches} + %define with_qemu_kvm %{with_qemu} +%else + %define with_qemu_kvm 0 +%endif + +%if ! %{with_qemu_tcg} && ! %{with_qemu_kvm} + %define with_qemu 0 +%endif + +# Then the hypervisor drivers that run outside libvirtd, in libvirt.so +%define with_openvz 0%{!?_without_openvz:1} +%define with_vmware 0%{!?_without_vmware:1} +%define with_phyp 0%{!?_without_phyp:1} +%define with_esx 0%{!?_without_esx:1} +%define with_hyperv 0%{!?_without_hyperv:1} + +# Then the secondary host drivers, which run inside libvirtd +%if 0%{?fedora} || 0%{?rhel} >= 7 + %define with_storage_rbd 0%{!?_without_storage_rbd:1} +%else + %define with_storage_rbd 0 +%endif +%if 0%{?fedora} + %define with_storage_sheepdog 0%{!?_without_storage_sheepdog:1} +%else + %define with_storage_sheepdog 0 +%endif +%define with_storage_gluster 0%{!?_without_storage_gluster:1} +%define with_numactl 0%{!?_without_numactl:1} + +# A few optional bits off by default, we enable later +%define with_fuse 0%{!?_without_fuse:0} +%define with_cgconfig 0%{!?_without_cgconfig:0} +%define with_sanlock 0%{!?_without_sanlock:0} +%define with_systemd 0%{!?_without_systemd:0} +%define with_numad 0%{!?_without_numad:0} +%define with_firewalld 0%{!?_without_firewalld:0} +%define with_libssh2 0%{!?_without_libssh2:0} +%define with_wireshark 0%{!?_without_wireshark:0} +%define with_libssh 0%{!?_without_libssh:0} +%define with_pm_utils 1 + +# Finally set the OS / architecture specific special cases + +# Xen is available only on i386 x86_64 ia64 +%ifnarch %{ix86} x86_64 ia64 + %define with_xen 0 + %define with_libxl 0 +%endif + +# vbox is available only on i386 x86_64 +%ifnarch %{ix86} x86_64 + %define with_vbox 0 +%endif + +# Numactl is not available on s390[x] and ARM +%ifarch s390 s390x %{arm} + %define with_numactl 0 +%endif + +# libgfapi is built only on x86_64 on rhel +%ifnarch x86_64 + %if 0%{?rhel} + %define with_storage_gluster 0 + %endif +%endif + +# librados and librbd are built only on x86_64 on rhel +%ifnarch x86_64 + %if 0%{?rhel} >= 7 + %define with_storage_rbd 0 + %endif +%endif + +# RHEL doesn't ship OpenVZ, VBox, UML, PowerHypervisor, +# VMware, libxenserver (xenapi), libxenlight (Xen 4.1 and newer), +# or HyperV. +%if 0%{?rhel} + %define with_openvz 0 + %define with_vbox 0 + %define with_uml 0 + %define with_phyp 0 + %define with_vmware 0 + %define with_xenapi 0 + %define with_libxl 0 + %define with_hyperv 0 + %define with_vz 0 +%endif + +# Fedora 17 / RHEL-7 are first where we use systemd. Although earlier +# Fedora has systemd, libvirt still used sysvinit there. +%if 0%{?fedora} || 0%{?rhel} >= 7 + %define with_systemd 1 + %define with_pm_utils 0 +%endif + +# Fedora 18 / RHEL-7 are first where firewalld support is enabled +%if 0%{?fedora} || 0%{?rhel} >= 7 + %define with_firewalld 1 +%endif + +# RHEL-6 stopped including Xen on all archs. +%if 0%{?rhel} + %define with_xen 0 +%endif + +# fuse is used to provide virtualized /proc for LXC +%if 0%{?fedora} || 0%{?rhel} >= 7 + %define with_fuse 0%{!?_without_fuse:1} +%endif + +# Enable sanlock library for lock management with QEMU +# Sanlock is available only on arches where kvm is available for RHEL +%if 0%{?fedora} + %define with_sanlock 0%{!?_without_sanlock:1} +%endif +%if 0%{?rhel} + %ifarch %{qemu_kvm_arches} + %define with_sanlock 0%{!?_without_sanlock:1} + %endif +%endif + +# Enable libssh2 transport for new enough distros +%if 0%{?fedora} + %define with_libssh2 0%{!?_without_libssh2:1} +%endif + +# Enable wireshark plugins for all distros shipping libvirt 1.2.2 or newer +%if 0%{?fedora} + %define with_wireshark 0%{!?_without_wireshark:1} +%endif + +# Enable libssh transport for new enough distros +%if 0%{?fedora} + %define with_libssh 0%{!?_without_libssh:1} +%endif + + +%if %{with_qemu} || %{with_lxc} || %{with_uml} +# numad is used to manage the CPU and memory placement dynamically, +# it's not available on s390[x] and ARM. + %ifnarch s390 s390x %{arm} + %define with_numad 0%{!?_without_numad:1} + %endif +%endif + +# Pull in cgroups config system +%if %{with_qemu} || %{with_lxc} + %define with_cgconfig 0%{!?_without_cgconfig:1} +%endif + +# Force QEMU to run as non-root +%define qemu_user qemu +%define qemu_group qemu + + +%if 0%{?fedora} || 0%{?rhel} >= 7 + %define with_systemd_macros 1 +%else + %define with_systemd_macros 0 +%endif + + +# RHEL releases provide stable tool chains and so it is safe to turn +# compiler warning into errors without being worried about frequent +# changes in reported warnings +%if 0%{?rhel} + %define enable_werror --enable-werror +%else + %define enable_werror --disable-werror +%endif + +%if 0%{?fedora} >= 25 + %define tls_priority "@LIBVIRT,SYSTEM" +%else + %if 0%{?fedora} + %define tls_priority "@SYSTEM" + %else + %define tls_priority "NORMAL" + %endif +%endif + + +Summary: Library providing a simple virtualization API +Name: libvirt +Version: 3.5.0 +Release: 1%{?_tis_dist}.%{tis_patch_ver} +License: LGPLv2+ +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +URL: https://libvirt.org/ + +%if %(echo %{version} | grep -q "\.0$"; echo $?) == 1 + %define mainturl stable_updates/ +%endif +Source0: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz +#Source1: symlinks + +# WRS +Source2: libvirt.logrotate +Source3: libvirt.lxc +Source4: libvirt.qemu +Source5: libvirt.uml +Source6: gnulib-ffc927e.tar.gz +Source7: keycodemapdb-8370ba8.tar.gz + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-config-network = %{version}-%{release} +Requires: libvirt-daemon-config-nwfilter = %{version}-%{release} +%if %{with_libxl} +Requires: libvirt-daemon-driver-libxl = %{version}-%{release} +%endif +%if %{with_lxc} +Requires: libvirt-daemon-driver-lxc = %{version}-%{release} +%endif +%if %{with_qemu} +Requires: libvirt-daemon-driver-qemu = %{version}-%{release} +%endif +%if %{with_uml} +Requires: libvirt-daemon-driver-uml = %{version}-%{release} +%endif +%if %{with_xen} +Requires: libvirt-daemon-driver-xen = %{version}-%{release} +%endif +%if %{with_vbox} +Requires: libvirt-daemon-driver-vbox = %{version}-%{release} +%endif +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} + +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-client = %{version}-%{release} +Requires: libvirt-libs = %{version}-%{release} + +# All build-time requirements. Run-time requirements are +# listed against each sub-RPM +%if 0%{?enable_autotools} +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: gettext-devel +BuildRequires: libtool +BuildRequires: /usr/bin/pod2man +%endif +BuildRequires: git +BuildRequires: perl +BuildRequires: python +%if %{with_systemd} +BuildRequires: systemd-units +%endif +%if %{with_xen} || %{with_libxl} +BuildRequires: xen-devel +%endif +BuildRequires: libxml2-devel +BuildRequires: xhtml1-dtds +BuildRequires: libxslt +BuildRequires: readline-devel +BuildRequires: ncurses-devel +BuildRequires: gettext +BuildRequires: libtasn1-devel +%if (0%{?rhel} && 0%{?rhel} < 7) +BuildRequires: libgcrypt-devel +%endif +BuildRequires: gnutls-devel +BuildRequires: libattr-devel +# For pool-build probing for existing pools +BuildRequires: libblkid-devel >= 2.17 +# for augparse, optionally used in testing +BuildRequires: augeas +%if 0%{?fedora} || 0%{?rhel} >= 7 +BuildRequires: systemd-devel >= 185 +%else +BuildRequires: libudev-devel >= 145 +%endif +BuildRequires: libpciaccess-devel >= 0.10.9 +BuildRequires: yajl-devel +%if %{with_sanlock} +BuildRequires: sanlock-devel >= 2.4 +%endif +BuildRequires: libpcap-devel +%if 0%{?rhel} && 0%{?rhel} < 7 +BuildRequires: libnl-devel +%else +BuildRequires: libnl3-devel +%endif +BuildRequires: avahi-devel +BuildRequires: libselinux-devel +BuildRequires: dnsmasq >= 2.41 +BuildRequires: iptables +%if 0%{?rhel} && 0%{?rhel} < 7 +BuildRequires: iptables-ipv6 +%endif +BuildRequires: radvd +BuildRequires: ebtables +BuildRequires: module-init-tools +BuildRequires: cyrus-sasl-devel +%if 0%{?fedora} || 0%{?rhel} >= 7 +# F22 polkit-devel doesn't pull in polkit anymore, which we need for pkcheck +BuildRequires: polkit >= 0.112 +BuildRequires: polkit-devel >= 0.112 +%else +BuildRequires: polkit-devel >= 0.93 +%endif +# For mount/umount in FS driver +BuildRequires: util-linux +%if %{with_qemu} +# For managing ACLs +BuildRequires: libacl-devel +# From QEMU RPMs +BuildRequires: /usr/bin/qemu-img +%else + %if %{with_xen} +# From Xen RPMs +BuildRequires: /usr/sbin/qcow-create + %endif +%endif +# For LVM drivers +BuildRequires: lvm2 +# For ISCSI driver +BuildRequires: iscsi-initiator-utils +# For disk driver +BuildRequires: parted-devel +# For Multipath support +BuildRequires: device-mapper-devel +%if %{with_storage_rbd} + %if 0%{?fedora} || 0%{?rhel} >= 7 +BuildRequires: librados2-devel +BuildRequires: librbd1-devel + %else +BuildRequires: ceph-devel + %endif +%endif +%if %{with_storage_gluster} +BuildRequires: glusterfs-api-devel >= 3.4.1 +BuildRequires: glusterfs-devel >= 3.4.1 +%endif +%if %{with_storage_sheepdog} +BuildRequires: sheepdog +%endif +%if %{with_numactl} +# For QEMU/LXC numa info +BuildRequires: numactl-devel +%endif +BuildRequires: libcap-ng-devel >= 0.5.0 +%if %{with_fuse} +BuildRequires: fuse-devel >= 2.8.6 +%endif +%if %{with_phyp} || %{with_libssh2} +BuildRequires: libssh2-devel >= 1.3.0 +%endif + +%if 0%{?fedora} || 0%{?rhel} >= 7 +BuildRequires: netcf-devel >= 0.2.2 +%else +BuildRequires: netcf-devel >= 0.1.8 +%endif +%if %{with_esx} +BuildRequires: libcurl-devel +%endif +%if %{with_hyperv} +BuildRequires: libwsman-devel >= 2.2.3 +%endif +BuildRequires: audit-libs-devel +# we need /usr/sbin/dtrace +BuildRequires: systemtap-sdt-devel + +# For mount/umount in FS driver +BuildRequires: util-linux +# For showmount in FS driver (netfs discovery) +BuildRequires: nfs-utils + +# Communication with the firewall and polkit daemons use DBus +BuildRequires: dbus-devel + +# Fedora build root suckage +BuildRequires: gawk + +# For storage wiping with different algorithms +BuildRequires: scrub + +%if %{with_numad} +BuildRequires: numad +%endif + +%if %{with_wireshark} + %if 0%{fedora} >= 24 +BuildRequires: wireshark-devel >= 2.1.0 + %else +BuildRequires: wireshark-devel >= 1.12.1 + %endif +%endif + +%if %{with_libssh} +BuildRequires: libssh-devel >= 0.7.0 +%endif + +# WRS: For generating configure +BuildRequires: gnulib +# WRS: Needed by bootstrap +BuildRequires: perl-XML-XPath + +Provides: bundled(gnulib) + +%description +Libvirt is a C toolkit to interact with the virtualization capabilities +of recent versions of Linux (and other OSes). The main package includes +the libvirtd server exporting the virtualization support. + +%package docs +Summary: API reference and website documentation +Group: Development/Libraries + +%description docs +Includes the API reference for the libvirt C library, and a complete +copy of the libvirt.org website documentation. + +%package daemon +Summary: Server side daemon and supporting files for libvirt library +Group: Development/Libraries + +# All runtime requirements for the libvirt package (runtime requrements +# for subpackages are listed later in those subpackages) + +# The client side, i.e. shared libs are in a subpackage +Requires: %{name}-libs = %{version}-%{release} + +# for modprobe of pci devices +Requires: module-init-tools +# for /sbin/ip & /sbin/tc +Requires: iproute +Requires: avahi-libs +%if 0%{?fedora} || 0%{?rhel} >= 7 +Requires: polkit >= 0.112 +%else +Requires: polkit >= 0.93 +%endif +%if %{with_cgconfig} +Requires: libcgroup +%endif +%ifarch %{ix86} x86_64 ia64 +# For virConnectGetSysinfo +Requires: dmidecode +%endif +# For service management +%if %{with_systemd} +Requires(post): systemd-units +Requires(post): systemd-sysv +Requires(preun): systemd-units +Requires(postun): systemd-units +%endif +%if %{with_numad} +Requires: numad +%endif +# libvirtd depends on 'messagebus' service +Requires: dbus +# For uid creation during pre +Requires(pre): shadow-utils + +%description daemon +Server side daemon required to manage the virtualization capabilities +of recent versions of Linux. Requires a hypervisor specific sub-RPM +for specific drivers. + +%package daemon-config-network +Summary: Default configuration files for the libvirtd daemon +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} + +%description daemon-config-network +Default configuration files for setting up NAT based networking + +%package daemon-config-nwfilter +Summary: Network filter configuration files for the libvirtd daemon +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} + +%description daemon-config-nwfilter +Network filter configuration files for cleaning guest traffic + +%package daemon-driver-network +Summary: Network driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +Requires: dnsmasq >= 2.41 +Requires: radvd +Requires: iptables +%if 0%{?rhel} && 0%{?rhel} < 7 +Requires: iptables-ipv6 +%endif + +%description daemon-driver-network +The network driver plugin for the libvirtd daemon, providing +an implementation of the virtual network APIs using the Linux +bridge capabilities. + + +%package daemon-driver-nwfilter +Summary: Nwfilter driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +Requires: iptables +%if 0%{?rhel} && 0%{?rhel} < 7 +Requires: iptables-ipv6 +%endif +Requires: ebtables + +%description daemon-driver-nwfilter +The nwfilter driver plugin for the libvirtd daemon, providing +an implementation of the firewall APIs using the ebtables, +iptables and ip6tables capabilities + + +%package daemon-driver-nodedev +Summary: Nodedev driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +# needed for device enumeration +%if 0%{?fedora} || 0%{?rhel} >= 7 +Requires: systemd >= 185 +%else +Requires: udev >= 145 +%endif + +%description daemon-driver-nodedev +The nodedev driver plugin for the libvirtd daemon, providing +an implementation of the node device APIs using the udev +capabilities. + + +%package daemon-driver-interface +Summary: Interface driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +%if (0%{?fedora} || 0%{?rhel} >= 7) +Requires: netcf-libs >= 0.2.2 +%endif + +%description daemon-driver-interface +The interface driver plugin for the libvirtd daemon, providing +an implementation of the network interface APIs using the +netcf library + + +%package daemon-driver-secret +Summary: Secret driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} + +%description daemon-driver-secret +The secret driver plugin for the libvirtd daemon, providing +an implementation of the secret key APIs. + +%package daemon-driver-storage-core +Summary: Storage driver plugin including base backends for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +Requires: nfs-utils +# For mkfs +Requires: util-linux +%if %{with_qemu} +# From QEMU RPMs +Requires: /usr/bin/qemu-img +%else + %if %{with_xen} +# From Xen RPMs +Requires: /usr/sbin/qcow-create + %endif +%endif + +%description daemon-driver-storage-core +The storage driver plugin for the libvirtd daemon, providing +an implementation of the storage APIs using files, local disks, LVM, SCSI, +iSCSI, and multipath storage. + +%package daemon-driver-storage-logical +Summary: Storage driver plugin for lvm volumes +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: lvm2 + +%description daemon-driver-storage-logical +The storage driver backend adding implementation of the storage APIs for block +volumes using lvm. + + +%package daemon-driver-storage-disk +Summary: Storage driver plugin for disk +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: parted +Requires: device-mapper + +%description daemon-driver-storage-disk +The storage driver backend adding implementation of the storage APIs for block +volumes using the host disks. + + +%package daemon-driver-storage-scsi +Summary: Storage driver plugin for local scsi devices +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} + +%description daemon-driver-storage-scsi +The storage driver backend adding implementation of the storage APIs for scsi +host devices. + + +%package daemon-driver-storage-iscsi +Summary: Storage driver plugin for iscsi +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: iscsi-initiator-utils + +%description daemon-driver-storage-iscsi +The storage driver backend adding implementation of the storage APIs for iscsi +volumes using the host iscsi stack. + + +%package daemon-driver-storage-mpath +Summary: Storage driver plugin for multipath volumes +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: device-mapper + +%description daemon-driver-storage-mpath +The storage driver backend adding implementation of the storage APIs for +multipath storage using device mapper. + + +%if %{with_storage_gluster} +%package daemon-driver-storage-gluster +Summary: Storage driver plugin for gluster +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} + %if 0%{?fedora} +Requires: glusterfs-client >= 2.0.1 + %endif + %if (0%{?fedora} || 0%{?with_storage_gluster}) +Requires: /usr/sbin/gluster + %endif + +%description daemon-driver-storage-gluster +The storage driver backend adding implementation of the storage APIs for gluster +volumes using libgfapi. +%endif + + +%if %{with_storage_rbd} +%package daemon-driver-storage-rbd +Summary: Storage driver plugin for rbd +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} + +%description daemon-driver-storage-rbd +The storage driver backend adding implementation of the storage APIs for rbd +volumes using the ceph protocol. +%endif + + +%if %{with_storage_sheepdog} +%package daemon-driver-storage-sheepdog +Summary: Storage driver plugin for sheepdog +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: sheepdog + +%description daemon-driver-storage-sheepdog +The storage driver backend adding implementation of the storage APIs for +sheepdog volumes using. +%endif + + +%package daemon-driver-storage +Summary: Storage driver plugin including all backends for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: libvirt-daemon-driver-storage-disk = %{version}-%{release} +Requires: libvirt-daemon-driver-storage-logical = %{version}-%{release} +Requires: libvirt-daemon-driver-storage-scsi = %{version}-%{release} +Requires: libvirt-daemon-driver-storage-iscsi = %{version}-%{release} +Requires: libvirt-daemon-driver-storage-mpath = %{version}-%{release} +%if %{with_storage_gluster} +Requires: libvirt-daemon-driver-storage-gluster = %{version}-%{release} +%endif +%if %{with_storage_rbd} +Requires: libvirt-daemon-driver-storage-rbd = %{version}-%{release} +%endif +%if %{with_storage_sheepdog} +Requires: libvirt-daemon-driver-storage-sheepdog = %{version}-%{release} +%endif + +%description daemon-driver-storage +The storage driver plugin for the libvirtd daemon, providing +an implementation of the storage APIs using LVM, iSCSI, +parted and more. + + +%if %{with_qemu} +%package daemon-driver-qemu +Summary: QEMU driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +# There really is a hard cross-driver dependency here +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-storage-core = %{version}-%{release} +Requires: /usr/bin/qemu-img +# For image compression +Requires: gzip +Requires: bzip2 +Requires: lzop +Requires: xz + %if 0%{?fedora} >= 24 +Requires: systemd-container + %endif + +%description daemon-driver-qemu +The qemu driver plugin for the libvirtd daemon, providing +an implementation of the hypervisor driver APIs using +QEMU +%endif + + +%if %{with_lxc} +%package daemon-driver-lxc +Summary: LXC driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} +# There really is a hard cross-driver dependency here +Requires: libvirt-daemon-driver-network = %{version}-%{release} + %if 0%{?fedora} >= 24 +Requires: systemd-container + %endif + +%description daemon-driver-lxc +The LXC driver plugin for the libvirtd daemon, providing +an implementation of the hypervisor driver APIs using +the Linux kernel +%endif + + +%if %{with_uml} +%package daemon-driver-uml +Summary: Uml driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} + +%description daemon-driver-uml +The UML driver plugin for the libvirtd daemon, providing +an implementation of the hypervisor driver APIs using +User Mode Linux +%endif + + +%if %{with_xen} +%package daemon-driver-xen +Summary: Xen driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} + +%description daemon-driver-xen +The Xen driver plugin for the libvirtd daemon, providing +an implementation of the hypervisor driver APIs using +Xen +%endif + + +%if %{with_vbox} +%package daemon-driver-vbox +Summary: VirtualBox driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} + +%description daemon-driver-vbox +The vbox driver plugin for the libvirtd daemon, providing +an implementation of the hypervisor driver APIs using +VirtualBox +%endif + + +%if %{with_libxl} +%package daemon-driver-libxl +Summary: Libxl driver plugin for the libvirtd daemon +Group: Development/Libraries +Requires: libvirt-daemon = %{version}-%{release} + +%description daemon-driver-libxl +The Libxl driver plugin for the libvirtd daemon, providing +an implementation of the hypervisor driver APIs using +Libxl +%endif + + + +%if %{with_qemu_tcg} +%package daemon-qemu +Summary: Server side daemon & driver required to run QEMU guests +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-qemu = %{version}-%{release} +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} +Requires: qemu + +%description daemon-qemu +Server side daemon and driver required to manage the virtualization +capabilities of the QEMU TCG emulators +%endif + + +%if %{with_qemu_kvm} +%package daemon-kvm +Summary: Server side daemon & driver required to run KVM guests +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-qemu = %{version}-%{release} +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} +Requires: qemu-kvm + +%description daemon-kvm +Server side daemon and driver required to manage the virtualization +capabilities of the KVM hypervisor +%endif + + +%if %{with_lxc} +%package daemon-lxc +Summary: Server side daemon & driver required to run LXC guests +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-lxc = %{version}-%{release} +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} + +%description daemon-lxc +Server side daemon and driver required to manage the virtualization +capabilities of LXC +%endif + + +%if %{with_uml} +%package daemon-uml +Summary: Server side daemon & driver required to run UML guests +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-uml = %{version}-%{release} +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} +# There are no UML kernel RPMs in Fedora/RHEL to depend on. + +%description daemon-uml +Server side daemon and driver required to manage the virtualization +capabilities of UML +%endif + + +%if %{with_xen} || %{with_libxl} +%package daemon-xen +Summary: Server side daemon & driver required to run XEN guests +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} + %if %{with_xen} +Requires: libvirt-daemon-driver-xen = %{version}-%{release} + %endif + %if %{with_libxl} +Requires: libvirt-daemon-driver-libxl = %{version}-%{release} + %endif +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} +Requires: xen + +%description daemon-xen +Server side daemon and driver required to manage the virtualization +capabilities of XEN +%endif + +%if %{with_vbox} +%package daemon-vbox +Summary: Server side daemon & driver required to run VirtualBox guests +Group: Development/Libraries + +Requires: libvirt-daemon = %{version}-%{release} +Requires: libvirt-daemon-driver-vbox = %{version}-%{release} +Requires: libvirt-daemon-driver-interface = %{version}-%{release} +Requires: libvirt-daemon-driver-network = %{version}-%{release} +Requires: libvirt-daemon-driver-nodedev = %{version}-%{release} +Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release} +Requires: libvirt-daemon-driver-secret = %{version}-%{release} +Requires: libvirt-daemon-driver-storage = %{version}-%{release} + +%description daemon-vbox +Server side daemon and driver required to manage the virtualization +capabilities of VirtualBox +%endif + +%package client +Summary: Client side utilities of the libvirt library +Group: Development/Libraries +Requires: %{name}-libs = %{version}-%{release} +Requires: readline +Requires: ncurses +# Needed by /usr/libexec/libvirt-guests.sh script. +Requires: gettext +# Needed by virt-pki-validate script. +Requires: gnutls-utils +%if %{with_pm_utils} +# Needed for probing the power management features of the host. +Requires: pm-utils +%endif + +%description client +The client binaries needed to access the virtualization +capabilities of recent versions of Linux (and other OSes). + +%package libs +Summary: Client side libraries +Group: Development/Libraries +# So remote clients can access libvirt over SSH tunnel +# (client invokes 'nc' against the UNIX socket on the server) +Requires: nc +Requires: cyrus-sasl +# Needed by default sasl.conf - no onerous extra deps, since +# 100's of other things on a system already pull in krb5-libs +Requires: cyrus-sasl-gssapi + +%description libs +Shared libraries for accessing the libvirt daemon. + +%package admin +Summary: Set of tools to control libvirt daemon +Group: Development/Libraries +Requires: %{name}-libs = %{version}-%{release} +Requires: readline + +%description admin +The client side utilities to control the libvirt daemon. + +%if %{with_wireshark} +%package wireshark +Summary: Wireshark dissector plugin for libvirt RPC transactions +Group: Development/Libraries +Requires: wireshark >= 1.12.6-4 +Requires: %{name}-libs = %{version}-%{release} + +%description wireshark +Wireshark dissector plugin for better analysis of libvirt RPC traffic. +%endif + +%if %{with_lxc} +%package login-shell +Summary: Login shell for connecting users to an LXC container +Group: Development/Libraries +Requires: %{name}-libs = %{version}-%{release} + +%description login-shell +Provides the set-uid virt-login-shell binary that is used to +connect a user to an LXC container when they login, by switching +namespaces. +%endif + +%package devel +Summary: Libraries, includes, etc. to compile with the libvirt library +Group: Development/Libraries +Requires: %{name}-libs = %{version}-%{release} +Requires: pkgconfig + +%description devel +Include header files & development libraries for the libvirt C library. + +%if %{with_sanlock} +%package lock-sanlock +Summary: Sanlock lock manager plugin for QEMU driver +Group: Development/Libraries +Requires: sanlock >= 2.4 +#for virt-sanlock-cleanup require augeas +Requires: augeas +Requires: %{name}-daemon = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} + +%description lock-sanlock +Includes the Sanlock lock manager plugin for the QEMU +driver +%endif + +%package nss +Summary: Libvirt plugin for Name Service Switch +Group: Development/Libraries +Requires: libvirt-daemon-driver-network = %{version}-%{release} + +%description nss +Libvirt plugin for NSS for translating domain names into IP addresses. + + +%prep +%if ! %{supported_platform} +echo "This RPM requires either Fedora >= 20 or RHEL >= 6" +exit 1 +%endif + +%setup -q + +# Patches have to be stored in a temporary file because RPM has +# a limit on the length of the result of any macro expansion; +# if the string is longer, it's silently cropped +%{lua: + tmp = os.tmpname(); + f = io.open(tmp, "w+"); + count = 0; + for i, p in ipairs(patches) do + f:write(p.."\n"); + count = count + 1; + end; + f:close(); + print("PATCHCOUNT="..count.."\n") + print("PATCHLIST="..tmp.."\n") +} + +git init -q +git config user.name rpm-build +git config user.email rpm-build +git config gc.auto 0 +git add . +git commit -q -a --author 'rpm-build ' \ + -m '%{name}-%{version} base' + +COUNT=$(grep '\.patch$' $PATCHLIST | wc -l) +if [ $COUNT -ne $PATCHCOUNT ]; then + echo "Found $COUNT patches in $PATCHLIST, expected $PATCHCOUNT" + exit 1 +fi +if [ $COUNT -gt 0 ]; then + xargs git am <$PATCHLIST || exit 1 +fi +echo "Applied $COUNT patches" +rm -f $PATCHLIST +rm -rf .git + +%build +%if %{with_xen} + %define arg_xen --with-xen +%else + %define arg_xen --without-xen +%endif + +%if %{with_qemu} + %define arg_qemu --with-qemu +%else + %define arg_qemu --without-qemu +%endif + +%if %{with_openvz} + %define arg_openvz --with-openvz +%else + %define arg_openvz --without-openvz +%endif + +%if %{with_lxc} + %define arg_lxc --with-lxc +%else + %define arg_lxc --without-lxc +%endif + +%if %{with_vbox} + %define arg_vbox --with-vbox +%else + %define arg_vbox --without-vbox +%endif + +%if %{with_libxl} + %define arg_libxl --with-libxl +%else + %define arg_libxl --without-libxl +%endif + +%if %{with_phyp} + %define arg_phyp --with-phyp +%else + %define arg_phyp --without-phyp +%endif + +%if %{with_esx} + %define arg_esx --with-esx +%else + %define arg_esx --without-esx +%endif + +%if %{with_hyperv} + %define arg_hyperv --with-hyperv +%else + %define arg_hyperv --without-hyperv +%endif + +%if %{with_vmware} + %define arg_vmware --with-vmware +%else + %define arg_vmware --without-vmware +%endif + +%if %{with_uml} + %define arg_uml --with-uml +%else + %define arg_uml --without-uml +%endif + +%if %{with_storage_rbd} + %define arg_storage_rbd --with-storage-rbd +%else + %define arg_storage_rbd --without-storage-rbd +%endif + +%if %{with_storage_sheepdog} + %define arg_storage_sheepdog --with-storage-sheepdog +%else + %define arg_storage_sheepdog --without-storage-sheepdog +%endif + +%if %{with_storage_gluster} + %define arg_storage_gluster --with-storage-gluster +%else + %define arg_storage_gluster --without-storage-gluster +%endif + +%if %{with_numactl} + %define arg_numactl --with-numactl +%else + %define arg_numactl --without-numactl +%endif + +%if %{with_numad} + %define arg_numad --with-numad +%else + %define arg_numad --without-numad +%endif + +%if %{with_fuse} + %define arg_fuse --with-fuse +%else + %define arg_fuse --without-fuse +%endif + +%if %{with_sanlock} + %define arg_sanlock --with-sanlock +%else + %define arg_sanlock --without-sanlock +%endif + +%if %{with_firewalld} + %define arg_firewalld --with-firewalld +%else + %define arg_firewalld --without-firewalld +%endif + +%if %{with_wireshark} + %define arg_wireshark --with-wireshark-dissector +%else + %define arg_wireshark --without-wireshark-dissector +%endif + +%if %{with_pm_utils} + %define arg_pm_utils --with-pm-utils +%else + %define arg_pm_utils --without-pm-utils +%endif + +%define when %(date +"%%F-%%T") +%define where %(hostname) +%define who %{?packager}%{!?packager:Unknown} +%define arg_packager --with-packager="%{who}, %{when}, %{where}" +%define arg_packager_version --with-packager-version="%{release}" + +%if %{with_systemd} + %define arg_init_script --with-init-script=systemd +%else + %define arg_init_script --with-init-script=redhat +%endif + +%if 0%{?fedora} || 0%{?rhel} >= 7 + %define arg_selinux_mount --with-selinux-mount="/sys/fs/selinux" +%else + %define arg_selinux_mount --with-selinux-mount="/selinux" +%endif + +%if 0%{?fedora} + # Nightly firmware repo x86/OVMF + LOADERS="/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd:/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd" + # Nightly firmware repo aarch64/AAVMF + LOADERS="$LOADERS:/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2.git/aarch64/vars-template-pflash.raw" + # Fedora official x86/OVMF + LOADERS="$LOADERS:/usr/share/edk2/ovmf/OVMF_CODE.fd:/usr/share/edk2/ovmf/OVMF_VARS.fd" + # Fedora official aarch64/AAVMF + LOADERS="$LOADERS:/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2/aarch64/vars-template-pflash.raw" + %define arg_loader_nvram --with-loader-nvram="$LOADERS" +%endif + +# place macros above and build commands below this comment + +# WRS: Generate configure script. Default is to do a "git clone" of gnulib. +# Use the tar ball gnulib tarball instead. +tar zxf %{SOURCE6} +./bootstrap --no-git --gnulib-srcdir=gnulib-ffc927e --copy +tar zxf %{SOURCE7} -C src + +%if 0%{?enable_autotools} + autoreconf -if +%endif + +rm -f po/stamp-po +%configure %{?arg_xen} \ + %{?arg_qemu} \ + %{?arg_openvz} \ + %{?arg_lxc} \ + %{?arg_vbox} \ + %{?arg_libxl} \ + --with-sasl \ + --with-avahi \ + --with-polkit \ + --with-libvirtd \ + %{?arg_uml} \ + %{?arg_phyp} \ + %{?arg_esx} \ + %{?arg_hyperv} \ + %{?arg_vmware} \ + --without-xenapi \ + --without-vz \ + --without-bhyve \ + --with-interface \ + --with-network \ + --with-storage-fs \ + --with-storage-lvm \ + --with-storage-iscsi \ + --with-storage-scsi \ + --with-storage-disk \ + --with-storage-mpath \ + %{?arg_storage_rbd} \ + %{?arg_storage_sheepdog} \ + %{?arg_storage_gluster} \ + --without-storage-zfs \ + --without-storage-vstorage \ + %{?arg_numactl} \ + %{?arg_numad} \ + --with-capng \ + %{?arg_fuse} \ + --with-netcf \ + --with-selinux \ + %{?arg_selinux_mount} \ + --without-apparmor \ + --without-hal \ + --with-udev \ + --with-yajl \ + %{?arg_sanlock} \ + --with-libpcap \ + --with-macvtap \ + --with-audit \ + --with-dtrace \ + --with-driver-modules \ + %{?arg_firewalld} \ + %{?arg_wireshark} \ + %{?arg_pm_utils} \ + --with-nss-plugin \ + %{arg_packager} \ + %{arg_packager_version} \ + --with-qemu-user=%{qemu_user} \ + --with-qemu-group=%{qemu_group} \ + --with-tls-priority=%{tls_priority} \ + %{?arg_loader_nvram} \ + %{?enable_werror} \ + --enable-expensive-tests \ + --without-audit \ + --without-dtrace \ + %{arg_init_script} + +#WRS: Avoid doing a 'config.status --recheck' (./configure executed twice). +touch -r config.status configure + +make %{?_smp_mflags} +gzip -9 ChangeLog + +%install +rm -fr %{buildroot} + +# Avoid using makeinstall macro as it changes prefixes rather than setting +# DESTDIR. Newer make_install macro would be better but it's not available +# on RHEL 5, thus we need to expand it here. +make %{?_smp_mflags} install DESTDIR=%{?buildroot} SYSTEMD_UNIT_DIR=%{_unitdir} + +make %{?_smp_mflags} -C examples distclean + +rm -f $RPM_BUILD_ROOT%{_libdir}/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/lock-driver/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/lock-driver/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/connection-driver/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/connection-driver/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-backend/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-backend/*.a +%if %{with_wireshark} + %if 0%{fedora} >= 24 +rm -f $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/libvirt.la + %else +rm -f $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/*/libvirt.la +mv $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/*/libvirt.so \ + $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/libvirt.so + %endif +%endif + +install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/lib/libvirt/dnsmasq/ +# We don't want to install /etc/libvirt/qemu/networks in the main %files list +# because if the admin wants to delete the default network completely, we don't +# want to end up re-incarnating it on every RPM upgrade. +install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/ +cp $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml \ + $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/default.xml +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml + +# nwfilter files are installed in /usr/share/libvirt and copied to /etc in %post +# to avoid verification errors on changed files in /etc +install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/libvirt/nwfilter/ +cp -a $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/nwfilter/*.xml \ + $RPM_BUILD_ROOT%{_datadir}/libvirt/nwfilter/ + +# Strip auto-generated UUID - we need it generated per-install +sed -i -e "//d" $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/default.xml +%if ! %{with_qemu} +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_qemu.aug +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug +%endif +%find_lang %{name} + +%if ! %{with_sanlock} +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirt_sanlock.aug +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirt_sanlock.aug +%endif + +%if ! %{with_lxc} +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_lxc.aug +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug +%endif + +%if ! %{with_qemu} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu.conf +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.qemu +%endif +%if ! %{with_lxc} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/lxc.conf +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.lxc +%endif +%if ! %{with_libxl} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/libxl.conf +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.libxl +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_libxl.aug +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug +%endif +%if ! %{with_uml} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.uml +%endif + +# Copied into libvirt-docs subpackage eventually +mv $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-%{version} libvirt-docs + +# WRS: Disable dtrace +# %ifarch %{power64} s390x x86_64 ia64 alpha sparc64 +# mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes.stp \ +# $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes-64.stp +# mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_qemu_probes.stp \ +# $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_qemu_probes-64.stp +# %endif + +# WRS: Begin custom install +## Enable syslog for libvirtd ( /var/log/libvirtd.log ) +echo "log_outputs=\"3:syslog:libvirtd\"" >> %{buildroot}/etc/libvirt/libvirtd.conf + +## Set auth_tcp to "none" for now to enable live migration. +## We'll need to set up proper authentication later. +sed -i '/#auth_tcp/a auth_tcp = "none"' %{buildroot}/etc/libvirt/libvirtd.conf + +install -d -m 711 %{buildroot}/data/images +## Install logrotate files +install -d -m 755 %{buildroot}/etc/logrotate.d +install -p -D -m 644 %{SOURCE2} %{buildroot}/etc/logrotate.d/libvirtd +install -p -D -m 644 %{SOURCE3} %{buildroot}/etc/logrotate.d/libvirtd.lxc +install -p -D -m 644 %{SOURCE4} %{buildroot}/etc/logrotate.d/libvirtd.qemu +install -p -D -m 644 %{SOURCE5} %{buildroot}/etc/logrotate.d/libvirtd.uml +# WRS: End custom install + +%clean +rm -fr %{buildroot} + +# WRS: We are not maintaining the unit tests. +# %check +# cd tests +# # These tests don't current work in a mock build root +# for i in nodeinfotest seclabeltest +# do +# rm -f $i +# printf 'int main(void) { return 0; }' > $i.c +# printf '#!/bin/sh\nexit 0\n' > $i +# chmod +x $i +# done +# if ! make %{?_smp_mflags} check VIR_TEST_DEBUG=1 +# then +# cat test-suite.log || true +# exit 1 +# fi + +%pre daemon +# 'libvirt' group is just to allow password-less polkit access to +# libvirtd. The uid number is irrelevant, so we use dynamic allocation +# described at the above link. +getent group libvirt >/dev/null || groupadd -r libvirt + +exit 0 + +%post daemon + +%if %{with_systemd} + %if %{with_systemd_macros} + %systemd_post virtlockd.socket virtlogd.socket libvirtd.service + %else +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl enable \ + virtlockd.socket \ + virtlogd.socket \ + libvirtd.service >/dev/null 2>&1 || : +fi + %endif +%else + %if %{with_cgconfig} +# Starting with Fedora 16/RHEL-7, systemd automounts all cgroups, +# and cgconfig is no longer a necessary service. + %if 0%{?rhel} && 0%{?rhel} < 7 +if [ "$1" -eq "1" ]; then +/sbin/chkconfig cgconfig on +fi + %endif + %endif + +/sbin/chkconfig --add libvirtd +/sbin/chkconfig --add virtlogd +/sbin/chkconfig --add virtlockd +%endif + +%preun daemon +%if %{with_systemd} + %if %{with_systemd_macros} + %systemd_preun libvirtd.service virtlogd.socket virtlogd.service virtlockd.socket virtlockd.service + %else +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable \ + libvirtd.service \ + virtlogd.socket \ + virtlogd.service \ + virtlockd.socket \ + virtlockd.service > /dev/null 2>&1 || : + /bin/systemctl stop \ + libvirtd.service \ + virtlogd.socket \ + virtlogd.service \ + virtlockd.socket \ + virtlockd.service > /dev/null 2>&1 || : +fi + %endif +%else +if [ $1 = 0 ]; then + /sbin/service libvirtd stop 1>/dev/null 2>&1 + /sbin/chkconfig --del libvirtd + /sbin/service virtlogd stop 1>/dev/null 2>&1 + /sbin/chkconfig --del virtlogd + /sbin/service virtlockd stop 1>/dev/null 2>&1 + /sbin/chkconfig --del virtlockd +fi +%endif + +%postun daemon +%if %{with_systemd} +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ $1 -ge 1 ] ; then + /bin/systemctl reload-or-try-restart virtlockd.service >/dev/null 2>&1 || : + /bin/systemctl reload-or-try-restart virtlogd.service >/dev/null 2>&1 || : + /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || : +fi +%else +if [ $1 -ge 1 ]; then + /sbin/service virtlockd reload > /dev/null 2>&1 || : + /sbin/service virtlogd reload > /dev/null 2>&1 || : + /sbin/service libvirtd condrestart > /dev/null 2>&1 +fi +%endif + +%if %{with_systemd} +%else +%triggerpostun daemon -- libvirt-daemon < 1.2.1 +if [ "$1" -ge "1" ]; then + /sbin/service virtlockd reload > /dev/null 2>&1 || : + /sbin/service virtlogd reload > /dev/null 2>&1 || : + /sbin/service libvirtd condrestart > /dev/null 2>&1 +fi +%endif + +# In upgrade scenario we must explicitly enable virtlockd/virtlogd +# sockets, if libvirtd is already enabled and start them if +# libvirtd is running, otherwise you'll get failures to start +# guests +%triggerpostun daemon -- libvirt-daemon < 1.3.0 +if [ $1 -ge 1 ] ; then +%if %{with_systemd} + /bin/systemctl is-enabled libvirtd.service 1>/dev/null 2>&1 && + /bin/systemctl enable virtlogd.socket || : + /bin/systemctl is-active libvirtd.service 1>/dev/null 2>&1 && + /bin/systemctl start virtlogd.socket || : +%else + /sbin/chkconfig libvirtd 1>/dev/null 2>&1 && + /sbin/chkconfig virtlogd on || : + /sbin/service libvirtd status 1>/dev/null 2>&1 && + /sbin/service virtlogd start || : +%endif +fi + +%post daemon-config-network +# WRS: The 'with_network' flag doesn't work properly. There are some packaging +# errors when using it. Disable default.xml manually ... +# We don't want 'virbr0' and 'virbr0-nic' interfaces created. + +# if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ; then +# # see if the network used by default network creates a conflict, +# # and try to resolve it +# # NB: 192.168.122.0/24 is used in the default.xml template file; +# # do not modify any of those values here without also modifying +# # them in the template. +# orig_sub=122 +# sub=${orig_sub} +# nl=' +# ' +# routes="${nl}$(ip route show | cut -d' ' -f1)${nl}" +# case ${routes} in +# *"${nl}192.168.${orig_sub}.0/24${nl}"*) +# # there was a match, so we need to look for an unused subnet +# for new_sub in $(seq 124 254); do +# case ${routes} in +# *"${nl}192.168.${new_sub}.0/24${nl}"*) +# ;; +# *) +# sub=$new_sub +# break; +# ;; +# esac +# done +# ;; +# *) +# ;; +# esac +# +# UUID=`/usr/bin/uuidgen` +# sed -e "s/${orig_sub}/${sub}/g" \ +# -e "s,,\n $UUID," \ +# < %{_datadir}/libvirt/networks/default.xml \ +# > %{_sysconfdir}/libvirt/qemu/networks/default.xml +# ln -s ../default.xml %{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml +# +# # Make sure libvirt picks up the new network defininiton +# %if %{with_systemd} +# /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 ||: +# %else +# /sbin/service libvirtd condrestart > /dev/null 2>&1 || : +# %endif +# +# fi + + +%post daemon-config-nwfilter +cp %{_datadir}/libvirt/nwfilter/*.xml %{_sysconfdir}/libvirt/nwfilter/ +# Make sure libvirt picks up the new nwfilter defininitons +%if %{with_systemd} + /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 ||: +%else + /sbin/service libvirtd condrestart > /dev/null 2>&1 || : +%endif + + +%if %{with_systemd} +%triggerun -- libvirt < 0.9.4 +%{_bindir}/systemd-sysv-convert --save libvirtd >/dev/null 2>&1 ||: + +# If the package is allowed to autostart: +/bin/systemctl --no-reload enable libvirtd.service >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +/sbin/chkconfig --del libvirtd >/dev/null 2>&1 || : +/bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || : +%endif + +%if %{with_qemu} +%pre daemon-driver-qemu +# We want soft static allocation of well-known ids, as disk images +# are commonly shared across NFS mounts by id rather than name; see +# https://fedoraproject.org/wiki/Packaging:UsersAndGroups +getent group kvm >/dev/null || groupadd -f -g 36 -r kvm +getent group qemu >/dev/null || groupadd -f -g 107 -r qemu +if ! getent passwd qemu >/dev/null; then + if ! getent passwd 107 >/dev/null; then + useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin -c "qemu user" qemu + else + useradd -r -g qemu -G kvm -d / -s /sbin/nologin -c "qemu user" qemu + fi +fi +exit 0 +%endif + +%preun client + +%if %{with_systemd} + %if %{with_systemd_macros} + %systemd_preun libvirt-guests.service + %endif +%else +if [ $1 = 0 ]; then + /sbin/chkconfig --del libvirt-guests + rm -f /var/lib/libvirt/libvirt-guests +fi +%endif + +%post client + +/sbin/ldconfig +%if %{with_systemd} + %if %{with_systemd_macros} + %systemd_post libvirt-guests.service + %endif +%else +/sbin/chkconfig --add libvirt-guests +%endif + +%postun client + +/sbin/ldconfig +%if %{with_systemd} + %if %{with_systemd_macros} + %systemd_postun libvirt-guests.service + %endif +%triggerun client -- libvirt < 0.9.4 +%{_bindir}/systemd-sysv-convert --save libvirt-guests >/dev/null 2>&1 ||: + +# If the package is allowed to autostart: +/bin/systemctl --no-reload enable libvirt-guests.service >/dev/null 2>&1 ||: + +# Run this because the SysV package being removed won't do them +/sbin/chkconfig --del libvirt-guests >/dev/null 2>&1 || : +%endif + +%if %{with_sanlock} +%post lock-sanlock +if getent group sanlock > /dev/null ; then + chmod 0770 %{_localstatedir}/lib/libvirt/sanlock + chown root:sanlock %{_localstatedir}/lib/libvirt/sanlock +fi +%endif + +%if %{with_lxc} +%pre login-shell +getent group virtlogin >/dev/null || groupadd -r virtlogin +exit 0 +%endif + +%files + +# WRS: Customization +%dir /data/images/ + +%files docs +# TODO(WRS): NEWS is not present in git source repo. +%doc AUTHORS ChangeLog.gz README TODO +%doc libvirt-docs/* + +# API docs +%dir %{_datadir}/gtk-doc/html/libvirt/ +%doc %{_datadir}/gtk-doc/html/libvirt/*.devhelp +%doc %{_datadir}/gtk-doc/html/libvirt/*.html +%doc %{_datadir}/gtk-doc/html/libvirt/*.png +%doc %{_datadir}/gtk-doc/html/libvirt/*.css +%doc examples/hellolibvirt +%doc examples/object-events +%doc examples/dominfo +%doc examples/domsuspend +%doc examples/dommigrate +%doc examples/openauth +%doc examples/xml +%doc examples/rename +%doc examples/systemtap +%doc examples/admin + + +%files daemon + +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/ + +%if %{with_systemd} +%{_unitdir}/libvirtd.service +%{_unitdir}/virt-guest-shutdown.target +%{_unitdir}/virtlogd.service +%{_unitdir}/virtlogd.socket +%{_unitdir}/virtlockd.service +%{_unitdir}/virtlockd.socket +%else +%{_sysconfdir}/rc.d/init.d/libvirtd +%{_sysconfdir}/rc.d/init.d/virtlogd +%{_sysconfdir}/rc.d/init.d/virtlockd +%endif +%doc daemon/libvirtd.upstart +%config(noreplace) %{_sysconfdir}/sysconfig/libvirtd +%config(noreplace) %{_sysconfdir}/sysconfig/virtlogd +%config(noreplace) %{_sysconfdir}/sysconfig/virtlockd +%config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf +%config(noreplace) %{_sysconfdir}/libvirt/virtlogd.conf +%config(noreplace) %{_sysconfdir}/libvirt/virtlockd.conf +%config(noreplace) %{_prefix}/lib/sysctl.d/60-libvirtd.conf + +%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd +%dir %{_datadir}/libvirt/ + +%ghost %dir %{_localstatedir}/run/libvirt/ + +%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/images/ +%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/filesystems/ +%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/boot/ +%dir %attr(0711, root, root) %{_localstatedir}/cache/libvirt/ + + +%dir %attr(0755, root, root) %{_libdir}/libvirt/lock-driver +%attr(0755, root, root) %{_libdir}/libvirt/lock-driver/lockd.so + +%{_datadir}/augeas/lenses/libvirtd.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd.aug +%{_datadir}/augeas/lenses/virtlogd.aug +%{_datadir}/augeas/lenses/tests/test_virtlogd.aug +%{_datadir}/augeas/lenses/virtlockd.aug +%{_datadir}/augeas/lenses/tests/test_virtlockd.aug +%{_datadir}/augeas/lenses/libvirt_lockd.aug +%if %{with_qemu} +%{_datadir}/augeas/lenses/tests/test_libvirt_lockd.aug +%endif + +%{_datadir}/polkit-1/actions/org.libvirt.unix.policy +%{_datadir}/polkit-1/actions/org.libvirt.api.policy +%{_datadir}/polkit-1/rules.d/50-libvirt.rules + +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/ + +%attr(0755, root, root) %{_libexecdir}/libvirt_iohelper + +%attr(0755, root, root) %{_sbindir}/libvirtd +%attr(0755, root, root) %{_sbindir}/virtlogd +%attr(0755, root, root) %{_sbindir}/virtlockd + +%{_mandir}/man8/libvirtd.8* +%{_mandir}/man8/virtlogd.8* +%{_mandir}/man8/virtlockd.8* +%{_mandir}/man7/virkey*.7* + +%doc examples/polkit/*.rules + +# WRS: Customization +/etc/logrotate.d/* + +%files daemon-config-network +%dir %{_datadir}/libvirt/networks/ +%{_datadir}/libvirt/networks/default.xml + +%files daemon-config-nwfilter +%dir %{_datadir}/libvirt/nwfilter/ +%{_datadir}/libvirt/nwfilter/*.xml +%ghost %{_sysconfdir}/libvirt/nwfilter/*.xml + +%files daemon-driver-interface +%{_libdir}/%{name}/connection-driver/libvirt_driver_interface.so + +%files daemon-driver-network +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/ +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/ +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/autostart +%ghost %dir %{_localstatedir}/run/libvirt/network/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/ +%attr(0755, root, root) %{_libexecdir}/libvirt_leaseshelper +%{_libdir}/%{name}/connection-driver/libvirt_driver_network.so + +%files daemon-driver-nodedev +%{_libdir}/%{name}/connection-driver/libvirt_driver_nodedev.so + +%files daemon-driver-nwfilter +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/nwfilter/ +%ghost %dir %{_localstatedir}/run/libvirt/network/ +%{_libdir}/%{name}/connection-driver/libvirt_driver_nwfilter.so + +%files daemon-driver-secret +%{_libdir}/%{name}/connection-driver/libvirt_driver_secret.so + +%files daemon-driver-storage + +%files daemon-driver-storage-core +%attr(0755, root, root) %{_libexecdir}/libvirt_parthelper +%{_libdir}/%{name}/connection-driver/libvirt_driver_storage.so +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_fs.so + +%files daemon-driver-storage-disk +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_disk.so + +%files daemon-driver-storage-logical +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_logical.so + +%files daemon-driver-storage-scsi +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_scsi.so + +%files daemon-driver-storage-iscsi +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_iscsi.so + +%files daemon-driver-storage-mpath +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_mpath.so + +%if %{with_storage_gluster} +%files daemon-driver-storage-gluster +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_gluster.so +%endif + +%if %{with_storage_rbd} +%files daemon-driver-storage-rbd +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_rbd.so +%endif + +%if %{with_storage_sheepdog} +%files daemon-driver-storage-sheepdog +%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_sheepdog.so +%endif + +%if %{with_qemu} +%files daemon-driver-qemu +%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/ +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/ +%config(noreplace) %{_sysconfdir}/libvirt/qemu.conf +%config(noreplace) %{_sysconfdir}/libvirt/qemu-lockd.conf +%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.qemu +%ghost %dir %attr(0700, root, root) %{_localstatedir}/run/libvirt/qemu/ +%dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ +%{_datadir}/augeas/lenses/libvirtd_qemu.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug +%{_libdir}/%{name}/connection-driver/libvirt_driver_qemu.so +%endif + +%if %{with_lxc} +%files daemon-driver-lxc +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/lxc/ +%config(noreplace) %{_sysconfdir}/libvirt/lxc.conf +%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.lxc +%ghost %dir %{_localstatedir}/run/libvirt/lxc/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/lxc/ +%{_datadir}/augeas/lenses/libvirtd_lxc.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug +%attr(0755, root, root) %{_libexecdir}/libvirt_lxc +%{_libdir}/%{name}/connection-driver/libvirt_driver_lxc.so +%endif + +%if %{with_uml} +%files daemon-driver-uml +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/uml/ +%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.uml +%ghost %dir %{_localstatedir}/run/libvirt/uml/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/ +%{_libdir}/%{name}/connection-driver/libvirt_driver_uml.so +%endif + +%if %{with_xen} +%files daemon-driver-xen +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/xen/ +%{_libdir}/%{name}/connection-driver/libvirt_driver_xen.so +%endif + +%if %{with_libxl} +%files daemon-driver-libxl +%config(noreplace) %{_sysconfdir}/libvirt/libxl.conf +%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.libxl +%config(noreplace) %{_sysconfdir}/libvirt/libxl-lockd.conf +%{_datadir}/augeas/lenses/libvirtd_libxl.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug +%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/libxl/ +%ghost %dir %{_localstatedir}/run/libvirt/libxl/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/ +%{_libdir}/%{name}/connection-driver/libvirt_driver_libxl.so +%endif + +%if %{with_vbox} +%files daemon-driver-vbox +%{_libdir}/%{name}/connection-driver/libvirt_driver_vbox.so +%endif + +%if %{with_qemu_tcg} +%files daemon-qemu +%endif + +%if %{with_qemu_kvm} +%files daemon-kvm +%endif + +%if %{with_lxc} +%files daemon-lxc +%endif + +%if %{with_uml} +%files daemon-uml +%endif + +%if %{with_xen} || %{with_libxl} +%files daemon-xen +%endif + +%if %{with_vbox} +%files daemon-vbox +%endif + +%if %{with_sanlock} +%files lock-sanlock + %if %{with_qemu} +%config(noreplace) %{_sysconfdir}/libvirt/qemu-sanlock.conf + %endif + %if %{with_libxl} +%config(noreplace) %{_sysconfdir}/libvirt/libxl-sanlock.conf + %endif +%attr(0755, root, root) %{_libdir}/libvirt/lock-driver/sanlock.so +%{_datadir}/augeas/lenses/libvirt_sanlock.aug +%{_datadir}/augeas/lenses/tests/test_libvirt_sanlock.aug +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/sanlock +%{_sbindir}/virt-sanlock-cleanup +%{_mandir}/man8/virt-sanlock-cleanup.8* +%attr(0755, root, root) %{_libexecdir}/libvirt_sanlock_helper +%endif + +%files client +%{_mandir}/man1/virsh.1* +%{_mandir}/man1/virt-xml-validate.1* +%{_mandir}/man1/virt-pki-validate.1* +%{_mandir}/man1/virt-host-validate.1* +%{_bindir}/virsh +%{_bindir}/virt-xml-validate +%{_bindir}/virt-pki-validate +%{_bindir}/virt-host-validate + +# WRS: Disable dtrace +# %{_datadir}/systemtap/tapset/libvirt_probes*.stp +# %{_datadir}/systemtap/tapset/libvirt_qemu_probes*.stp +# %{_datadir}/systemtap/tapset/libvirt_functions.stp + + +%if %{with_systemd} +%{_unitdir}/libvirt-guests.service +%else +%{_sysconfdir}/rc.d/init.d/libvirt-guests +%endif +%config(noreplace) %{_sysconfdir}/sysconfig/libvirt-guests +%attr(0755, root, root) %{_libexecdir}/libvirt-guests.sh + +%files libs -f %{name}.lang +%doc COPYING COPYING.LESSER +%config(noreplace) %{_sysconfdir}/libvirt/libvirt.conf +%config(noreplace) %{_sysconfdir}/libvirt/libvirt-admin.conf +%{_libdir}/libvirt.so.* +%{_libdir}/libvirt-qemu.so.* +%{_libdir}/libvirt-lxc.so.* +%{_libdir}/libvirt-admin.so.* +%dir %{_datadir}/libvirt/ +%dir %{_datadir}/libvirt/schemas/ +%dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/ + +%{_datadir}/libvirt/schemas/basictypes.rng +%{_datadir}/libvirt/schemas/capability.rng +%{_datadir}/libvirt/schemas/cputypes.rng +%{_datadir}/libvirt/schemas/domain.rng +%{_datadir}/libvirt/schemas/domaincaps.rng +%{_datadir}/libvirt/schemas/domaincommon.rng +%{_datadir}/libvirt/schemas/domainsnapshot.rng +%{_datadir}/libvirt/schemas/interface.rng +%{_datadir}/libvirt/schemas/network.rng +%{_datadir}/libvirt/schemas/networkcommon.rng +%{_datadir}/libvirt/schemas/nodedev.rng +%{_datadir}/libvirt/schemas/nwfilter.rng +%{_datadir}/libvirt/schemas/secret.rng +%{_datadir}/libvirt/schemas/storagecommon.rng +%{_datadir}/libvirt/schemas/storagepool.rng +%{_datadir}/libvirt/schemas/storagevol.rng + +%{_datadir}/libvirt/cpu_map.xml + +%{_datadir}/libvirt/test-screenshot.png + +%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf + +%files admin +%{_mandir}/man1/virt-admin.1* +%{_bindir}/virt-admin + + +%if %{with_wireshark} +%files wireshark +%{_libdir}/wireshark/plugins/libvirt.so +%endif + +%files nss +%{_libdir}/libnss_libvirt.so.2 +%{_libdir}/libnss_libvirt_guest.so.2 + +%if %{with_lxc} +%files login-shell +%attr(4750, root, virtlogin) %{_bindir}/virt-login-shell +%config(noreplace) %{_sysconfdir}/libvirt/virt-login-shell.conf +%{_mandir}/man1/virt-login-shell.1* +%endif + +%files devel +%{_libdir}/libvirt.so +%{_libdir}/libvirt-admin.so +%{_libdir}/libvirt-qemu.so +%{_libdir}/libvirt-lxc.so +%dir %{_includedir}/libvirt +%{_includedir}/libvirt/virterror.h +%{_includedir}/libvirt/libvirt.h +%{_includedir}/libvirt/libvirt-admin.h +%{_includedir}/libvirt/libvirt-common.h +%{_includedir}/libvirt/libvirt-domain.h +%{_includedir}/libvirt/libvirt-domain-snapshot.h +%{_includedir}/libvirt/libvirt-event.h +%{_includedir}/libvirt/libvirt-host.h +%{_includedir}/libvirt/libvirt-interface.h +%{_includedir}/libvirt/libvirt-network.h +%{_includedir}/libvirt/libvirt-nodedev.h +%{_includedir}/libvirt/libvirt-nwfilter.h +%{_includedir}/libvirt/libvirt-secret.h +%{_includedir}/libvirt/libvirt-storage.h +%{_includedir}/libvirt/libvirt-stream.h +%{_includedir}/libvirt/libvirt-qemu.h +%{_includedir}/libvirt/libvirt-lxc.h +%{_libdir}/pkgconfig/libvirt.pc +%{_libdir}/pkgconfig/libvirt-admin.pc +%{_libdir}/pkgconfig/libvirt-qemu.pc +%{_libdir}/pkgconfig/libvirt-lxc.pc + +%dir %{_datadir}/libvirt/api/ +%{_datadir}/libvirt/api/libvirt-api.xml +%{_datadir}/libvirt/api/libvirt-admin-api.xml +%{_datadir}/libvirt/api/libvirt-qemu-api.xml +%{_datadir}/libvirt/api/libvirt-lxc-api.xml +# Needed building python bindings +%doc docs/libvirt-api.xml + + +%changelog diff --git a/extended/libvirt/libvirt-2.0.0/libvirt.logrotate b/extended/libvirt/libvirt-2.0.0/libvirt.logrotate new file mode 100644 index 000000000..a60915995 --- /dev/null +++ b/extended/libvirt/libvirt-2.0.0/libvirt.logrotate @@ -0,0 +1,14 @@ +/var/log/libvirt/libvirtd.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} diff --git a/extended/libvirt/libvirt-2.0.0/libvirt.lxc b/extended/libvirt/libvirt-2.0.0/libvirt.lxc new file mode 100644 index 000000000..81ea6210b --- /dev/null +++ b/extended/libvirt/libvirt-2.0.0/libvirt.lxc @@ -0,0 +1,15 @@ +/var/log/libvirt/lxc/*.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} + diff --git a/extended/libvirt/libvirt-2.0.0/libvirt.qemu b/extended/libvirt/libvirt-2.0.0/libvirt.qemu new file mode 100644 index 000000000..470ef8cda --- /dev/null +++ b/extended/libvirt/libvirt-2.0.0/libvirt.qemu @@ -0,0 +1,15 @@ +/var/log/libvirt/qemu/*.log +{ + nodateext + size 10M + start 1 + rotate 4 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} + diff --git a/extended/libvirt/libvirt-2.0.0/libvirt.uml b/extended/libvirt/libvirt-2.0.0/libvirt.uml new file mode 100644 index 000000000..1c26219f0 --- /dev/null +++ b/extended/libvirt/libvirt-2.0.0/libvirt.uml @@ -0,0 +1,15 @@ +/var/log/libvirt/uml/*.log +{ + nodateext + size 10M + start 1 + rotate 4 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} + diff --git a/extended/libvirt/libvirt-3.5.0/libvirt.logrotate b/extended/libvirt/libvirt-3.5.0/libvirt.logrotate new file mode 100644 index 000000000..a60915995 --- /dev/null +++ b/extended/libvirt/libvirt-3.5.0/libvirt.logrotate @@ -0,0 +1,14 @@ +/var/log/libvirt/libvirtd.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} diff --git a/extended/libvirt/libvirt-3.5.0/libvirt.lxc b/extended/libvirt/libvirt-3.5.0/libvirt.lxc new file mode 100644 index 000000000..81ea6210b --- /dev/null +++ b/extended/libvirt/libvirt-3.5.0/libvirt.lxc @@ -0,0 +1,15 @@ +/var/log/libvirt/lxc/*.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} + diff --git a/extended/libvirt/libvirt-3.5.0/libvirt.qemu b/extended/libvirt/libvirt-3.5.0/libvirt.qemu new file mode 100644 index 000000000..470ef8cda --- /dev/null +++ b/extended/libvirt/libvirt-3.5.0/libvirt.qemu @@ -0,0 +1,15 @@ +/var/log/libvirt/qemu/*.log +{ + nodateext + size 10M + start 1 + rotate 4 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} + diff --git a/extended/libvirt/libvirt-3.5.0/libvirt.uml b/extended/libvirt/libvirt-3.5.0/libvirt.uml new file mode 100644 index 000000000..1c26219f0 --- /dev/null +++ b/extended/libvirt/libvirt-3.5.0/libvirt.uml @@ -0,0 +1,15 @@ +/var/log/libvirt/uml/*.log +{ + nodateext + size 10M + start 1 + rotate 4 + missingok + notifempty + compress + sharedscripts + postrotate + /etc/init.d/syslog reload > /dev/null 2>&1 || true + endscript +} + diff --git a/extended/lighttpd/PKG-INFO b/extended/lighttpd/PKG-INFO new file mode 100644 index 000000000..03c09d0c1 --- /dev/null +++ b/extended/lighttpd/PKG-INFO @@ -0,0 +1,19 @@ +Metadata-Version: 1.1 +Name: lighttpd +Version: 1.4.39 +Summary: Lightning fast webserver with light system requirements +Home-page: +Author: +Author-email: +License: BSD + +Description: +Secure, fast, compliant and very flexible web-server which has been optimized +for high-performance environments. It has a very low memory footprint compared +to other webservers and takes care of cpu-load. Its advanced feature-set +(FastCGI, CGI, Auth, Output-Compression, URL-Rewriting and many more) make +it the perfect webserver-software for every server that is suffering load +problems. + + +Platform: UNKNOWN diff --git a/extended/lighttpd/centos/build_srpm.data b/extended/lighttpd/centos/build_srpm.data new file mode 100755 index 000000000..f057a5a58 --- /dev/null +++ b/extended/lighttpd/centos/build_srpm.data @@ -0,0 +1,9 @@ +COPY_LIST="lighttpd-1.4.35/index.html.lighttpd \ + lighttpd-1.4.35/lighttpd.conf \ + lighttpd-1.4.35/lighttpd.init \ + lighttpd-1.4.35/lighttpd-inc.conf \ + lighttpd-1.4.35/lighttpd.logrotate \ + lighttpd-1.4.35/lighttpd-csr.conf \ + lighttpd-1.4.35/check-content-length.patch \ + lighttpd-1.4.35/lighttpd-tpm-support.patch" +TIS_PATCH_VER=5 diff --git a/extended/lighttpd/centos/meta_patches/0001-Adding-tmp-dir-under-lighttpd-chroot-environ.patch b/extended/lighttpd/centos/meta_patches/0001-Adding-tmp-dir-under-lighttpd-chroot-environ.patch new file mode 100644 index 000000000..18a163f78 --- /dev/null +++ b/extended/lighttpd/centos/meta_patches/0001-Adding-tmp-dir-under-lighttpd-chroot-environ.patch @@ -0,0 +1,26 @@ +From bfca4119209067c0af4abf88b62d54767fcfd7ab Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 10:21:28 -0400 +Subject: [PATCH 2/4] WRS: + 0001-Adding-tmp-dir-under-lighttpd-chroot-environ.patch + +--- + SPECS/lighttpd.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/lighttpd.spec b/SPECS/lighttpd.spec +index a313a1b..71737ac 100644 +--- a/SPECS/lighttpd.spec ++++ b/SPECS/lighttpd.spec +@@ -267,7 +267,7 @@ echo 'D /var/run/lighttpd 0750 lighttpd lighttpd -' > \ + # WRS + CONFDIR=%{buildroot}%{_sysconfdir}/lighttpd + ROOTDIR=%{buildroot}/www +- ++install -d -m 1777 ${ROOTDIR}/tmp + install -d ${CONFDIR}/ssl + install -d ${ROOTDIR}/pages/dav + install -m 0640 %{SOURCE103} ${CONFDIR}/lighttpd.conf +-- +1.8.3.1 + diff --git a/extended/lighttpd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/lighttpd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..594e77520 --- /dev/null +++ b/extended/lighttpd/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 4bea2840e8b22d904be29d24d501c25201e13c57 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 10:21:28 -0400 +Subject: [PATCH 3/4] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/lighttpd.spec +--- + SPECS/lighttpd.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/lighttpd.spec b/SPECS/lighttpd.spec +index 71737ac..b795a3f 100644 +--- a/SPECS/lighttpd.spec ++++ b/SPECS/lighttpd.spec +@@ -45,7 +45,7 @@ + Summary: Lightning fast webserver with light system requirements + Name: lighttpd + Version: 1.4.45 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + License: BSD + Group: System Environment/Daemons + URL: http://www.lighttpd.net/ +-- +1.8.3.1 + diff --git a/extended/lighttpd/centos/meta_patches/PATCH_ORDER b/extended/lighttpd/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..ade386910 --- /dev/null +++ b/extended/lighttpd/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,5 @@ +spec-include-TiS-changes.patch +0001-Adding-tmp-dir-under-lighttpd-chroot-environ.patch +0001-Update-package-versioning-for-TIS-format.patch +spec-check-content-length.patch +meta_add_support_for_tpm.patch diff --git a/extended/lighttpd/centos/meta_patches/meta_add_support_for_tpm.patch b/extended/lighttpd/centos/meta_patches/meta_add_support_for_tpm.patch new file mode 100644 index 000000000..ba7a90001 --- /dev/null +++ b/extended/lighttpd/centos/meta_patches/meta_add_support_for_tpm.patch @@ -0,0 +1,32 @@ +From 653e25505b1df7e7b3fd89e08729d6d9f9698d39 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Tue, 28 Mar 2017 17:33:34 -0400 +Subject: [PATCH] dding support for TPM 2.0 + +--- + SPECS/lighttpd.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/lighttpd.spec b/SPECS/lighttpd.spec +index 0598472..64df753 100644 +--- a/SPECS/lighttpd.spec ++++ b/SPECS/lighttpd.spec +@@ -81,6 +81,7 @@ Patch8: lighttpd-1.4.43-mysql.patch + + # WRS Patches + Patch100: check-content-length.patch ++Patch101: lighttpd-tpm-support.patch + + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + # For the target poweredby.png image (skip requirement + provide image on EL5) +@@ -186,6 +187,7 @@ Authentication module for lighttpd that uses GSSAPI + + # WRS Patches + %patch100 -p1 -b .content_length ++%patch101 -p1 -b .tpm_support + + #install -p -m 0644 %{SOURCE100} src/mod_geoip.c + #install -p -m 0644 %{SOURCE101} mod_geoip.txt +-- +1.8.3.1 + diff --git a/extended/lighttpd/centos/meta_patches/spec-check-content-length.patch b/extended/lighttpd/centos/meta_patches/spec-check-content-length.patch new file mode 100644 index 000000000..d5bc59a7e --- /dev/null +++ b/extended/lighttpd/centos/meta_patches/spec-check-content-length.patch @@ -0,0 +1,40 @@ +From c684477fa2b47bb3c00b0e501e817d088408bead Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 10:21:28 -0400 +Subject: [PATCH 4/4] WRS: spec-check-content-length.patch + +Conflicts: + SPECS/lighttpd.spec +--- + SPECS/lighttpd.spec | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SPECS/lighttpd.spec b/SPECS/lighttpd.spec +index b795a3f..9fd062a 100644 +--- a/SPECS/lighttpd.spec ++++ b/SPECS/lighttpd.spec +@@ -78,6 +78,10 @@ Patch3: lighttpd-1.4.39-socket.patch + #Patch6: changeset_r779c133c16f9af168b004dce7a2a64f16c1cb3a4.diff + #Patch7: lighttpd-1.4.42-bignum.patch + #Patch8: lighttpd-1.4.43-mysql.patch ++ ++# WRS Patches ++Patch100: check-content-length.patch ++ + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + # For the target poweredby.png image (skip requirement + provide image on EL5) + %if %{with systemlogos} +@@ -179,6 +183,10 @@ Authentication module for lighttpd that uses GSSAPI + #%patch6 -p1 -b .http_proxy + #%patch7 -p0 -b .bignum + #%patch8 -p0 -b .mysql ++ ++# WRS Patches ++%patch100 -p1 -b .content_length ++ + #install -p -m 0644 %{SOURCE100} src/mod_geoip.c + #install -p -m 0644 %{SOURCE101} mod_geoip.txt + +-- +1.8.3.1 + diff --git a/extended/lighttpd/centos/meta_patches/spec-include-TiS-changes.patch b/extended/lighttpd/centos/meta_patches/spec-include-TiS-changes.patch new file mode 100644 index 000000000..0930619df --- /dev/null +++ b/extended/lighttpd/centos/meta_patches/spec-include-TiS-changes.patch @@ -0,0 +1,121 @@ +From 4012a8fe42371386d864d2aa3277f43169909d6e Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 20 Mar 2017 10:21:28 -0400 +Subject: [PATCH 1/4] WRS: spec-include-TiS-changes.patch + +--- + SPECS/lighttpd.spec | 53 ++++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 40 insertions(+), 13 deletions(-) + +diff --git a/SPECS/lighttpd.spec b/SPECS/lighttpd.spec +index 20668f7..a313a1b 100644 +--- a/SPECS/lighttpd.spec ++++ b/SPECS/lighttpd.spec +@@ -61,6 +61,14 @@ Source13: http://www.lighttpd.net/light_logo.png + Source14: lighttpd-empty.png + #Source100: lighttpd-mod_geoip.c + #Source101: lighttpd-mod_geoip.txt ++ ++# WRS ++Source102: index.html.lighttpd ++Source103: lighttpd.conf ++Source104: lighttpd-inc.conf ++Source105: lighttpd.logrotate ++Source106: lighttpd-csr.conf ++ + Patch0: lighttpd-1.4.39-defaultconf.patch + #Patch1: lighttpd-1.4.40-mod_geoip.patch + Patch2: lighttpd-1.4.35-system-crypto-policy.patch +@@ -180,17 +188,19 @@ autoreconf -if + %configure \ + --libdir='%{_libdir}/lighttpd' \ + %{confswitch mysql} \ +- %{confswitch ldap} \ ++ --without-ldap \ + %{confswitch attr} \ +- %{confswitch openssl} \ ++ --with-openssl \ + %{confswitch kerberos5} \ +- %{confswitch pcre} \ ++ --with-pcre \ + %{confswitch fam} \ +- %{?with_webdavprops:--with-webdav-props} \ +- %{?with_webdavlocks:--with-webdav-locks} \ ++ --without-webdav-props \ ++ --without-webdav-locks \ + %{confswitch gdbm} \ +- %{confswitch memcache} \ +- %{confswitch lua} \ ++ --without-memcache \ ++ --without-lua \ ++ --without-bzip2 \ ++ --disable-static \ + %{confswitch geoip} \ + %{confswitch krb5} + make %{?_smp_mflags} +@@ -209,13 +219,14 @@ install -D -p -m 0644 %{SOURCE2} \ + %{buildroot}%{_sysconfdir}/php.d/lighttpd.ini + + # Install our own init script (included one is old style) or systemd service +-%if %{with systemd} ++#%if %{with systemd} + install -D -p -m 0644 %{SOURCE4} \ + %{buildroot}%{_unitdir}/lighttpd.service +-%else ++#%else ++mkdir -p /etc/rc.d/init.d + install -D -p -m 0755 %{SOURCE3} \ + %{buildroot}%{_sysconfdir}/rc.d/init.d/lighttpd +-%endif ++#%endif + + # Install our own default web page and images + mkdir -p %{buildroot}%{webroot} +@@ -253,6 +264,20 @@ echo 'D /var/run/lighttpd 0750 lighttpd lighttpd -' > \ + %{buildroot}%{_sysconfdir}/tmpfiles.d/lighttpd.conf + %endif + ++# WRS ++CONFDIR=%{buildroot}%{_sysconfdir}/lighttpd ++ROOTDIR=%{buildroot}/www ++ ++install -d ${CONFDIR}/ssl ++install -d ${ROOTDIR}/pages/dav ++install -m 0640 %{SOURCE103} ${CONFDIR}/lighttpd.conf ++install -m 0644 %{SOURCE104} ${CONFDIR}/lighttpd-inc.conf ++install -m 0644 %{SOURCE102} ${ROOTDIR}/pages/index.html ++ ++install -d %{buildroot}%{_sysconfdir}/logrotate.d ++install -m 644 %{SOURCE105} %{buildroot}%{_sysconfdir}/logrotate.d/lighttpd ++ ++chmod 02770 %{buildroot}%{_sysconfdir}/lighttpd + + %clean + rm -rf %{buildroot} +@@ -301,11 +326,8 @@ fi + %config %{_sysconfdir}/lighttpd/conf.d/mod.template + %config %{_sysconfdir}/lighttpd/vhosts.d/vhosts.template + %config(noreplace) %{_sysconfdir}/logrotate.d/lighttpd +-%if %{with systemd} + %{_unitdir}/lighttpd.service +-%else + %{_sysconfdir}/rc.d/init.d/lighttpd +-%endif + %if %{with tmpfiles} + %config(noreplace) %{_sysconfdir}/tmpfiles.d/lighttpd.conf + %endif +@@ -331,6 +353,11 @@ fi + # This is not really configuration, but prevent loss of local changes + %config %{webroot}/index.html + ++# WRS ++%dir /www/pages/ ++/www/pages/* ++ ++ + %files fastcgi + %defattr(-,root,root,-) + %doc doc/outdated/fastcgi*.txt doc/scripts/spawn-php.sh +-- +1.8.3.1 + diff --git a/extended/lighttpd/centos/srpm_path b/extended/lighttpd/centos/srpm_path new file mode 100644 index 000000000..898dda45a --- /dev/null +++ b/extended/lighttpd/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/lighttpd-1.4.45-1.el7.src.rpm diff --git a/extended/lighttpd/lighttpd-1.4.35/check-content-length.patch b/extended/lighttpd/lighttpd-1.4.35/check-content-length.patch new file mode 100644 index 000000000..330958e12 --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/check-content-length.patch @@ -0,0 +1,86 @@ +From b9410d967faf627d72fc5496a4c2e7aab879b7aa Mon Sep 17 00:00:00 2001 +From: Giao Le +Date: Wed, 19 Oct 2016 15:06:17 -0400 +Subject: [PATCH 1/1] check + +--- + src/request.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +diff --git a/src/request.c b/src/request.c +index a2de944..857076c 100644 +--- a/src/request.c ++++ b/src/request.c +@@ -12,6 +12,39 @@ + #include + #include + ++#include ++#include ++#include ++#include ++ ++static size_t get_tempdirs_free_space(server *srv) ++{ ++ int i; ++ int valid = 0; ++ size_t total = 0; ++ array *dirs = srv->srvconf.upload_tempdirs; ++ ++ for (i = 0; i < (int)dirs->used; ++i) { ++ struct statvfs stat; ++ const char *name = ((data_string *)dirs->data[i])->value->ptr; ++ int ret = statvfs(name, &stat); ++ ++ if (ret >= 0) { ++ size_t df = (size_t)(stat.f_bsize * stat.f_bfree); ++ total += df; ++ valid = 1; ++ } ++ else { ++ log_error_write(srv, __FILE__, __LINE__, "ssss", ++ "dir:", name, ++ "error:", strerror(errno)); ++ } ++ } ++ ++ return (valid) ? total : SSIZE_MAX; ++} ++ ++ + static int request_check_hostname(buffer *host) { + enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL; + size_t i; +@@ -409,6 +442,7 @@ static int request_uri_is_valid_char(unsigned char c) { + return 1; + } + ++ + int http_request_parse(server *srv, connection *con) { + char *uri = NULL, *proto = NULL, *method = NULL, con_length_set; + int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding; +@@ -1294,6 +1328,21 @@ int http_request_parse(server *srv, connection *con) { + return 0; + + } ++ /* content-length is larger than 64k */ ++ if (con->request.content_length > 64*1024) { ++ size_t disk_free = get_tempdirs_free_space(srv); ++ if (con->request.content_length > disk_free) { ++ con->http_status = 413; ++ con->keep_alive = 0; ++ ++ log_error_write(srv, __FILE__, __LINE__, "ssosos", ++ "not enough free space in tempdirs:", ++ "length =", (off_t) con->request.content_length, ++ "free =", (off_t) disk_free, ++ "-> 413"); ++ return 0; ++ } ++ } + break; + default: + break; +-- +1.8.3.1 + diff --git a/extended/lighttpd/lighttpd-1.4.35/index.html.lighttpd b/extended/lighttpd/lighttpd-1.4.35/index.html.lighttpd new file mode 100644 index 000000000..ef43ab273 --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/index.html.lighttpd @@ -0,0 +1 @@ +

Carrier Grade Communication Server

diff --git a/extended/lighttpd/lighttpd-1.4.35/lighttpd-csr.conf b/extended/lighttpd/lighttpd-1.4.35/lighttpd-csr.conf new file mode 100644 index 000000000..d754cfa11 --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/lighttpd-csr.conf @@ -0,0 +1,13 @@ +[ req ] +default_bits = 1024 +distinguished_name = req_distinguished_name +prompt = no + +[ req_distinguished_name ] +C = CA +ST = Ontario +L = Ottawa +O = Wind River Inc. +OU = Carrier Grade Communications Server +CN = *.wrs.com + diff --git a/extended/lighttpd/lighttpd-1.4.35/lighttpd-inc.conf b/extended/lighttpd/lighttpd-1.4.35/lighttpd-inc.conf new file mode 100644 index 000000000..8fa0e3b24 --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/lighttpd-inc.conf @@ -0,0 +1,3 @@ +# default management network access +var.management_ip_network = "127.0.0.1" +var.pxeboot_ip_network = "" diff --git a/extended/lighttpd/lighttpd-1.4.35/lighttpd-tpm-support.patch b/extended/lighttpd/lighttpd-1.4.35/lighttpd-tpm-support.patch new file mode 100644 index 000000000..16744684d --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/lighttpd-tpm-support.patch @@ -0,0 +1,255 @@ +From 3cf42638ea162be04cbfc8b8eedbef6292336640 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Wed, 29 Mar 2017 21:56:41 -0400 +Subject: [PATCH] lighttpd tpm support + +--- + src/base.h | 10 ++++- + src/configfile.c | 4 ++ + src/network.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++--------- + src/server.c | 12 +++++- + 4 files changed, 118 insertions(+), 19 deletions(-) + +diff --git a/src/base.h b/src/base.h +index 134fc41..5fab1fd 100644 +--- a/src/base.h ++++ b/src/base.h +@@ -37,6 +37,7 @@ + # endif + # endif + # include ++# include + # if ! defined OPENSSL_NO_TLSEXT && ! defined SSL_CTRL_SET_TLSEXT_HOSTNAME + # define OPENSSL_NO_TLSEXT + # endif +@@ -567,6 +568,13 @@ typedef struct { + unsigned short high_precision_timestamps; + time_t loadts; + double loadavg[3]; ++#ifdef USE_OPENSSL ++ // TPM engine and object configuration ++ buffer *tpm_object; ++ buffer *tpm_engine; ++ ENGINE *tpm_engine_ref; ++ EVP_PKEY *tpm_key; ++#endif + } server_config; + + typedef struct server_socket { +@@ -610,7 +618,7 @@ typedef struct server { + int con_closed; + + int ssl_is_init; +- ++ int tpm_is_init; // has TPM been initialized already + int max_fds; /* max possible fds */ + int cur_fds; /* currently used fds */ + int want_fds; /* waiting fds */ +diff --git a/src/configfile.c b/src/configfile.c +index bba6925..da818ed 100644 +--- a/src/configfile.c ++++ b/src/configfile.c +@@ -145,6 +145,8 @@ static int config_insert(server *srv) { + { "server.stream-response-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 77 */ + { "server.max-request-field-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 78 */ + { "ssl.read-ahead", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 79 */ ++ { "server.tpm-object", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 80 */ ++ { "server.tpm-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 81 */ + + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } + }; +@@ -184,6 +186,8 @@ static int config_insert(server *srv) { + cv[73].destination = &(srv->srvconf.http_host_strict); + cv[74].destination = &(srv->srvconf.http_host_normalize); + cv[78].destination = &(srv->srvconf.max_request_field_size); ++ cv[80].destination = srv->srvconf.tpm_object; ++ cv[81].destination = srv->srvconf.tpm_engine; + + srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); + +diff --git a/src/network.c b/src/network.c +index 4295fe9..6460e72 100644 +--- a/src/network.c ++++ b/src/network.c +@@ -613,6 +613,29 @@ error: + return NULL; + } + ++static EVP_PKEY* evp_pkey_load_tpm_object_file(server *srv) { ++ if (!srv->tpm_is_init || !srv->srvconf.tpm_engine_ref) ++ return NULL; ++ ++ if (srv->srvconf.tpm_key) { ++ // if a TPM key was previously loaded ++ // then return that as there is no need to ++ // reload this key into TPM ++ return srv->srvconf.tpm_key; ++ } ++ ++ EVP_PKEY *pkey = ENGINE_load_private_key(srv->srvconf.tpm_engine_ref, ++ srv->srvconf.tpm_object->ptr, ++ NULL, NULL); ++ if (!pkey) { ++ log_error_write(srv, __FILE__, __LINE__, "SSS", "SSL:", ++ ERR_error_string(ERR_get_error(), NULL)); ++ return NULL; ++ } ++ srv->srvconf.tpm_key = pkey; ++ return pkey; ++} ++ + static EVP_PKEY* evp_pkey_load_pem_file(server *srv, const char *file) { + BIO *in; + EVP_PKEY *x = NULL; +@@ -658,15 +681,23 @@ static int network_openssl_load_pemfile(server *srv, size_t ndx) { + #endif + + if (NULL == (s->ssl_pemfile_x509 = x509_load_pem_file(srv, s->ssl_pemfile->ptr))) return -1; +- if (NULL == (s->ssl_pemfile_pkey = evp_pkey_load_pem_file(srv, s->ssl_pemfile->ptr))) return -1; + +- if (!X509_check_private_key(s->ssl_pemfile_x509, s->ssl_pemfile_pkey)) { +- log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", +- "Private key does not match the certificate public key, reason:", +- ERR_error_string(ERR_get_error(), NULL), +- s->ssl_pemfile); +- return -1; +- } ++ // if TPM mode is enabled then load the TPM key otherwise load ++ // the regular SSL private key ++ if (srv->tpm_is_init) { ++ if (NULL == (s->ssl_pemfile_pkey = evp_pkey_load_tpm_object_file(srv))) return -1; ++ } ++ else { ++ if (NULL == (s->ssl_pemfile_pkey = evp_pkey_load_pem_file(srv, s->ssl_pemfile->ptr))) return -1; ++ ++ if (!X509_check_private_key(s->ssl_pemfile_x509, s->ssl_pemfile_pkey)) { ++ log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", ++ "Private key does not match the certificate public key, reason:", ++ ERR_error_string(ERR_get_error(), NULL), ++ s->ssl_pemfile); ++ return -1; ++ } ++ } + + return 0; + } +@@ -791,6 +822,44 @@ int network_init(server *srv) { + } + } + ++ /* NOTE (knasim-wrs): US93721: TPM support ++ * if TPM mode is configured, and we have not previously ++ * initialized the engine then do so now ++ */ ++ if (!buffer_string_is_empty(srv->srvconf.tpm_object) && ++ (!srv->tpm_is_init)) { ++ if (!buffer_string_is_empty(srv->srvconf.tpm_engine)) { ++ // load the dynamic TPM engine ++ ENGINE_load_dynamic(); ++ ENGINE *engine = ENGINE_by_id("dynamic"); ++ if (!engine) { ++ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ++ "Unable to load the dynamic engine " ++ "(needed for loading custom TPM engine)"); ++ return -1; ++ } ++ ++ ENGINE_ctrl_cmd_string(engine, "SO_PATH", ++ srv->srvconf.tpm_engine->ptr, 0); ++ ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0); ++ if (ENGINE_init(engine) != 1) { ++ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", ++ ERR_error_string(ERR_get_error(), NULL)); ++ ENGINE_finish(engine); ++ return -1; ++ } ++ srv->tpm_is_init = 1; ++ // stow away for ENGINE cleanup ++ srv->srvconf.tpm_engine_ref = engine; ++ } ++ else { // no TPM engine found ++ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ++ "TPM engine option not set when TPM mode expected"); ++ return -1; ++ } ++ } ++ /// ++ + if (!buffer_string_is_empty(s->ssl_pemfile)) { + #ifdef OPENSSL_NO_TLSEXT + data_config *dc = (data_config *)srv->config_context->data[i]; +@@ -975,24 +1044,32 @@ int network_init(server *srv) { + SSL_CTX_set_verify_depth(s->ssl_ctx, s->ssl_verifyclient_depth); + } + +- if (1 != SSL_CTX_use_certificate(s->ssl_ctx, s->ssl_pemfile_x509)) { ++ if (1 != SSL_CTX_use_PrivateKey(s->ssl_ctx, s->ssl_pemfile_pkey)) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", + ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); + return -1; + } + +- if (1 != SSL_CTX_use_PrivateKey(s->ssl_ctx, s->ssl_pemfile_pkey)) { ++ if (1 != SSL_CTX_use_certificate(s->ssl_ctx, s->ssl_pemfile_x509)) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", + ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); + return -1; + } +- +- if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { +- log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", +- "Private key does not match the certificate public key, reason:", +- ERR_error_string(ERR_get_error(), NULL), +- s->ssl_pemfile); +- return -1; ++ ++ /* ++ * Only check private key against loaded ++ * certificate, in non TPM mode, since ++ * if this is a TPM key then it is wrapped ++ * and will not match the public key ++ */ ++ if (!srv->tpm_is_init) { ++ if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { ++ log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", ++ "Private key does not match the certificate public key, reason:", ++ ERR_error_string(ERR_get_error(), NULL), ++ s->ssl_pemfile); ++ return -1; ++ } + } + SSL_CTX_set_default_read_ahead(s->ssl_ctx, s->ssl_read_ahead); + SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) +diff --git a/src/server.c b/src/server.c +index f27b003..5adfa15 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -226,7 +226,10 @@ static server *server_init(void) { + CLEAN(srvconf.bindhost); + CLEAN(srvconf.event_handler); + CLEAN(srvconf.pid_file); +- ++#ifdef USE_OPENSSL ++ CLEAN(srvconf.tpm_object); ++ CLEAN(srvconf.tpm_engine); ++#endif + CLEAN(tmp_chunk_len); + #undef CLEAN + +@@ -316,6 +319,13 @@ static void server_free(server *srv) { + CLEAN(srvconf.modules_dir); + CLEAN(srvconf.network_backend); + CLEAN(srvconf.xattr_name); ++#ifdef USE_OPENSSL ++ CLEAN(srvconf.tpm_object); ++ CLEAN(srvconf.tpm_engine); ++ // don't free the tpm_key as that will be freed ++ // below as ssl_pemfile_pkey ++ ENGINE_finish(srv->srvconf.tpm_engine_ref); ++#endif + + CLEAN(tmp_chunk_len); + #undef CLEAN +-- +1.8.3.1 + diff --git a/extended/lighttpd/lighttpd-1.4.35/lighttpd.conf b/extended/lighttpd/lighttpd-1.4.35/lighttpd.conf new file mode 100755 index 000000000..b4245ecb3 --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/lighttpd.conf @@ -0,0 +1,381 @@ +# lighttpd configuration file +# +# use it as a base for lighttpd 1.0.0 and above +# +# $Id: lighttpd.conf,v 1.7 2004/11/03 22:26:05 weigon Exp $ + +############ Options you really have to take care of #################### + +## modules to load +# at least mod_access and mod_accesslog should be loaded +# all other module should only be loaded if really neccesary +# - saves some time +# - saves memory +server.modules = ( +# "mod_rewrite", +# "mod_redirect", +# "mod_alias", + "mod_access", +# "mod_cml", +# "mod_trigger_b4_dl", +# "mod_auth", +# "mod_status", +# "mod_setenv", +# "mod_fastcgi", + "mod_proxy", +# "mod_simple_vhost", +# "mod_evhost", +# "mod_userdir", +# "mod_cgi", +# "mod_compress", +# "mod_ssi", +# "mod_usertrack", +# "mod_expire", +# "mod_secdownload", +# "mod_rrdtool", +# "mod_webdav", + "mod_setenv", + "mod_accesslog" ) + +## a static document-root, for virtual-hosting take look at the +## server.virtual-* options +server.document-root = "/www/pages/" + +## where to send error-messages to +server.errorlog = "/var/log/lighttpd-error.log" + +# files to check for if .../ is requested +index-file.names = ( "index.php", "index.html", + "index.htm", "default.htm" ) + +## set the event-handler (read the performance section in the manual) +# server.event-handler = "freebsd-kqueue" # needed on OS X + +# mimetype mapping +mimetype.assign = ( + ".pdf" => "application/pdf", + ".sig" => "application/pgp-signature", + ".spl" => "application/futuresplash", + ".class" => "application/octet-stream", + ".ps" => "application/postscript", + ".torrent" => "application/x-bittorrent", + ".dvi" => "application/x-dvi", + ".gz" => "application/x-gzip", + ".pac" => "application/x-ns-proxy-autoconfig", + ".swf" => "application/x-shockwave-flash", + ".tar.gz" => "application/x-tgz", + ".tgz" => "application/x-tgz", + ".tar" => "application/x-tar", + ".zip" => "application/zip", + ".mp3" => "audio/mpeg", + ".m3u" => "audio/x-mpegurl", + ".wma" => "audio/x-ms-wma", + ".wax" => "audio/x-ms-wax", + ".ogg" => "application/ogg", + ".wav" => "audio/x-wav", + ".gif" => "image/gif", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".svg" => "image/svg+xml", + ".xbm" => "image/x-xbitmap", + ".xpm" => "image/x-xpixmap", + ".xwd" => "image/x-xwindowdump", + ".css" => "text/css", + ".html" => "text/html", + ".htm" => "text/html", + ".js" => "text/javascript", + ".asc" => "text/plain", + ".c" => "text/plain", + ".cpp" => "text/plain", + ".log" => "text/plain", + ".conf" => "text/plain", + ".text" => "text/plain", + ".txt" => "text/plain", + ".dtd" => "text/xml", + ".xml" => "text/xml", + ".mpeg" => "video/mpeg", + ".mpg" => "video/mpeg", + ".mov" => "video/quicktime", + ".qt" => "video/quicktime", + ".avi" => "video/x-msvideo", + ".asf" => "video/x-ms-asf", + ".asx" => "video/x-ms-asf", + ".wmv" => "video/x-ms-wmv", + ".bz2" => "application/x-bzip", + ".tbz" => "application/x-bzip-compressed-tar", + ".tar.bz2" => "application/x-bzip-compressed-tar", + ".rpm" => "application/x-rpm", + ".cfg" => "text/plain" + ) + +# Use the "Content-Type" extended attribute to obtain mime type if possible +#mimetype.use-xattr = "enable" + + +## send a different Server: header +## be nice and keep it at lighttpd +# server.tag = "lighttpd" + +#### accesslog module +accesslog.filename = "/var/log/lighttpd-access.log" + + +## deny access the file-extensions +# +# ~ is for backupfiles from vi, emacs, joe, ... +# .inc is often used for code includes which should in general not be part +# of the document-root +url.access-deny = ( "~", ".inc" ) + +$HTTP["url"] =~ "\.pdf$" { + server.range-requests = "disable" +} + +## +# which extensions should not be handle via static-file transfer +# +# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi +static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" ) + +######### Options that are good to be but not neccesary to be changed ####### + +## bind to port (default: 80) +#server.port = 81 + +## bind to localhost (default: all interfaces) +#server.bind = "grisu.home.kneschke.de" + +## error-handler for status 404 +#server.error-handler-404 = "/error-handler.html" +#server.error-handler-404 = "/error-handler.php" + +## to help the rc.scripts +server.pid-file = "/var/run/lighttpd.pid" + + +###### virtual hosts +## +## If you want name-based virtual hosting add the next three settings and load +## mod_simple_vhost +## +## document-root = +## virtual-server-root + virtual-server-default-host + virtual-server-docroot +## or +## virtual-server-root + http-host + virtual-server-docroot +## +#simple-vhost.server-root = "/home/weigon/wwwroot/servers/" +#simple-vhost.default-host = "grisu.home.kneschke.de" +#simple-vhost.document-root = "/pages/" + + +## +## Format: .html +## -> ..../status-404.html for 'File not found' +#server.errorfile-prefix = "/home/weigon/projects/lighttpd/doc/status-" + +## virtual directory listings +## +## disabled as per Nessus scan CVE: 5.0 40984 +## Please do NOT enable as this is a security +## vulnerability. If you want dir listing for +## our dir path then a) either add a dir index (index.html) +## file within your dir path, or b) add your path as an exception +## rule (see the one for feeds/ dir below) +dir-listing.activate = "disable" + +## enable debugging +#debug.log-request-header = "enable" +#debug.log-response-header = "enable" +#debug.log-request-handling = "enable" +#debug.log-file-not-found = "enable" + +### only root can use these options +# +# chroot() to directory (default: no chroot() ) +#server.chroot = "/" + +## change uid to (default: don't care) +#server.username = "wwwrun" + +## change uid to (default: don't care) +#server.groupname = "wwwrun" + +## defaults to /var/tmp +server.upload-dirs = ( "/tmp" ) + +## change max-keep-alive-idle (default: 5 secs) +#server.max-keep-alive-idle = 5 + +#### compress module +#compress.cache-dir = "/tmp/lighttpd/cache/compress/" +#compress.filetype = ("text/plain", "text/html") + +#### proxy module +## read proxy.txt for more info + +# Proxy all non-static content to the local horizon dashboard +$HTTP["url"] !~ "^/(rel-[^/]*|feed|updates|static)/" { + proxy.server = ( "" => + ( "localhost" => + ( + "host" => "127.0.0.1", + "port" => 8080 + ) + ) + ) +} + +#### fastcgi module +## read fastcgi.txt for more info +## for PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini +#fastcgi.server = ( ".php" => +# ( "localhost" => +# ( +# "socket" => "/tmp/php-fastcgi.socket", +# "bin-path" => "/usr/local/bin/php" +# ) +# ) +# ) + +#### CGI module +#cgi.assign = ( ".pl" => "/usr/bin/perl", +# ".cgi" => "/usr/bin/perl" ) +# + +#### SSL engine +$SERVER["socket"] == ":443" { + ssl.engine = "enable" + ssl.pemfile = "/etc/ssl/private/server-cert.pem" + ssl.use-sslv2 = "disable" + ssl.use-sslv3 = "disable" + ssl.cipher-list = "ALL:!aNULL:!eNULL:!EXPORT:!TLSv1:!DES:!MD5:!PSK:!RC4:!EDH-RSA-DES-CBC3-SHA:!EDH-DSS-DES-CBC3-SHA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA:!ECDHE-RSA-DES-CBC3-SHA:!ECDHE-RSA-AES128-SHA:!ECDHE-RSA-AES256-SHA:!DES-CBC3-SHA:!AES128-SHA:!AES256-SHA:!DHE-DSS-AES128-SHA:!DHE-DSS-AES256-SHA:!CAMELLIA128-SHA:!CAMELLIA256-SHA:!DHE-DSS-CAMELLIA128-SHA:!DHE-DSS-CAMELLIA256-SHA:!DHE-RSA-CAMELLIA128-SHA:!DHE-RSA-CAMELLIA256-SHA:!ECDHE-ECDSA-DES-CBC3-SHA:!ECDHE-ECDSA-AES128-SHA:!ECDHE-ECDSA-AES256-SHA" +} + +#### Listen to IPv6 +$SERVER["socket"] == "[::]:80" { } +$SERVER["socket"] == "[::]:443" { + ssl.engine = "enable" + ssl.pemfile = "/etc/ssl/private/server-cert.pem" + ssl.use-sslv2 = "disable" + ssl.use-sslv3 = "disable" + ssl.cipher-list = "ALL:!aNULL:!eNULL:!EXPORT:!TLSv1:!DES:!MD5:!PSK:!RC4:!EDH-RSA-DES-CBC3-SHA:!EDH-DSS-DES-CBC3-SHA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA:!ECDHE-RSA-DES-CBC3-SHA:!ECDHE-RSA-AES128-SHA:!ECDHE-RSA-AES256-SHA:!DES-CBC3-SHA:!AES128-SHA:!AES256-SHA:!DHE-DSS-AES128-SHA:!DHE-DSS-AES256-SHA:!CAMELLIA128-SHA:!CAMELLIA256-SHA:!DHE-DSS-CAMELLIA128-SHA:!DHE-DSS-CAMELLIA256-SHA:!DHE-RSA-CAMELLIA128-SHA:!DHE-RSA-CAMELLIA256-SHA:!ECDHE-ECDSA-DES-CBC3-SHA:!ECDHE-ECDSA-AES128-SHA:!ECDHE-ECDSA-AES256-SHA" +} + +#### status module +#status.status-url = "/server-status" +#status.config-url = "/server-config" + +#### auth module +## read authentication.txt for more info +#auth.backend = "plain" +#auth.backend.plain.userfile = "lighttpd.user" +#auth.backend.plain.groupfile = "lighttpd.group" + +#auth.backend.ldap.hostname = "localhost" +#auth.backend.ldap.base-dn = "dc=my-domain,dc=com" +#auth.backend.ldap.filter = "(uid=$)" + +#auth.require = ( "/server-status" => +# ( +# "method" => "digest", +# "realm" => "download archiv", +# "require" => "user=jan" +# ), +# "/server-config" => +# ( +# "method" => "digest", +# "realm" => "download archiv", +# "require" => "valid-user" +# ) +# ) + +#### url handling modules (rewrite, redirect, access) +#url.rewrite = ( "^/$" => "/server-status" ) +#url.redirect = ( "^/wishlist/(.+)" => "http://www.123.org/$1" ) + +#### both rewrite/redirect support back reference to regex conditional using %n +#$HTTP["host"] =~ "^www\.(.*)" { +# url.redirect = ( "^/(.*)" => "http://%1/$1" ) +#} + +# +# define a pattern for the host url finding +# %% => % sign +# %0 => domain name + tld +# %1 => tld +# %2 => domain name without tld +# %3 => subdomain 1 name +# %4 => subdomain 2 name +# +#evhost.path-pattern = "/home/storage/dev/www/%3/htdocs/" + +#### expire module +#expire.url = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes") + +#### ssi +#ssi.extension = ( ".shtml" ) + +#### rrdtool +#rrdtool.binary = "/usr/bin/rrdtool" +#rrdtool.db-name = "/var/www/lighttpd.rrd" + +#### setenv +#setenv.add-request-header = ( "TRAV_ENV" => "mysql://user@host/db" ) +#setenv.add-response-header = ( "X-Secret-Message" => "42" ) + +## for mod_trigger_b4_dl +# trigger-before-download.gdbm-filename = "/home/weigon/testbase/trigger.db" +# trigger-before-download.memcache-hosts = ( "127.0.0.1:11211" ) +# trigger-before-download.trigger-url = "^/trigger/" +# trigger-before-download.download-url = "^/download/" +# trigger-before-download.deny-url = "http://127.0.0.1/index.html" +# trigger-before-download.trigger-timeout = 10 + +## for mod_cml +## don't forget to add index.cml to server.indexfiles +# cml.extension = ".cml" +# cml.memcache-hosts = ( "127.0.0.1:11211" ) + +#### variable usage: +## variable name without "." is auto prefixed by "var." and becomes "var.bar" +#bar = 1 +#var.mystring = "foo" + +## integer add +#bar += 1 +## string concat, with integer cast as string, result: "www.foo1.com" +#server.name = "www." + mystring + var.bar + ".com" +## array merge +#index-file.names = (foo + ".php") + index-file.names +#index-file.names += (foo + ".php") + +#### include +#include /etc/lighttpd/lighttpd-inc.conf +## same as above if you run: "lighttpd -f /etc/lighttpd/lighttpd.conf" +#include "lighttpd-inc.conf" + +#### include_shell +#include_shell "echo var.a=1" +## the above is same as: +#var.a=1 + +# deny access to feed directories for external connections. +# Only enable access to dir listing for feed directory if on internal network +# (i.e. mgmt or pxeboot networks) +include "/etc/lighttpd/lighttpd-inc.conf" +$HTTP["remoteip"] != "127.0.0.1" { + $HTTP["url"] =~ "^/(rel-[^/]*|feed|updates)/" { + dir-listing.activate = "enable" + } + $HTTP["remoteip"] != var.management_ip_network { + $HTTP["remoteip"] != var.pxeboot_ip_network { + $HTTP["url"] =~ "^/(rel-[^/]*|feed|updates)/" { + url.access-deny = ( "" ) + } + } + } +} +$HTTP["scheme"] == "https" { + setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=63072000; includeSubdomains; ") +} diff --git a/extended/lighttpd/lighttpd-1.4.35/lighttpd.init b/extended/lighttpd/lighttpd-1.4.35/lighttpd.init new file mode 100755 index 000000000..256e950cc --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/lighttpd.init @@ -0,0 +1,124 @@ +#!/bin/sh + +### BEGIN INIT INFO +# Provides: Web Server +# Required-Start: networking +# Required-Stop: networking +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Lighttpd Web Server +# Description: Web service to serve static files and proxy +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/lighttpd +NAME=lighttpd +DESC="Lighttpd Web Server" +OPTS="-f /etc/lighttpd/lighttpd.conf" +PIDFILE="/var/run/$NAME.pid" +PORT="80" + +start() +{ + + if lsof -t -i:${PORT} 1> /dev/null 2>&1; then + kill $(lsof -t -i:${PORT}) > /dev/null 2>&1 + fi + + if [ -e $PIDFILE ]; then + PIDDIR=/proc/$(cat $PIDFILE) + if [ -d ${PIDDIR} ]; then + echo "$DESC already running." + return + else + echo "Removing stale PID file $PIDFILE" + rm -f $PIDFILE + fi + fi + + echo -n "Checking scratch filesystem..." + let -i COUNT=0 + while [ ! -e /scratch ] + do + if [ $COUNT -ge 15 ] + then + echo "failed to find /scratch." + exit -1 + fi + let COUNT=COUNT+1 + sleep 1 + done + + echo -n "Mounting scratch filesystem to chroot tmp..." + umount /www/tmp >& /dev/null + rm -r /scratch/lighttpd >& /dev/null + mkdir -p /scratch/lighttpd + mount --bind /scratch/lighttpd /www/tmp/ + chown www /www/tmp/ + + echo -n "Starting $DESC..." + + start-stop-daemon --start --pidfile ${PIDFILE} -x "$DAEMON" -- $OPTS + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + echo "done." + else + echo "failed." + fi +} + +stop() +{ + if [ ! -e $PIDFILE ]; then return; fi + + echo -n "Stopping $DESC..." + + start-stop-daemon --stop --quiet --pidfile ${PIDFILE} -x "$DAEMON" + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + echo "done." + else + echo "failed." + fi + rm -f $PIDFILE + echo -n "Unmounting scratch filesystem from chroot tmp..." + umount /www/tmp +} + +status() +{ + pid=`cat $PIDFILE 2>/dev/null` + if [ -n "$pid" ]; then + if ps -p $pid &>/dev/null ; then + echo "$DESC is running" + RETVAL=0 + return + else + RETVAL=1 + fi + fi + echo "$DESC is not running" + RETVAL=3 +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|force-reload|reload) + stop + start + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|force-reload|restart|reload|status}" + RETVAL=1 + ;; +esac + +exit $RETVAL diff --git a/extended/lighttpd/lighttpd-1.4.35/lighttpd.logrotate b/extended/lighttpd/lighttpd-1.4.35/lighttpd.logrotate new file mode 100644 index 000000000..5f1e87c8c --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/lighttpd.logrotate @@ -0,0 +1,14 @@ +/var/log/lighttpd-access.log +/var/log/lighttpd-error.log +/www/var/log/lighttpd-access.log +/www/var/log/lighttpd-error.log { + nodateext + size 10M + start 1 + rotate 10 + missingok + notifempty + compress + delaycompress + copytruncate +} diff --git a/extended/lighttpd/lighttpd-1.4.35/remote-ip-ipv6-support.patch b/extended/lighttpd/lighttpd-1.4.35/remote-ip-ipv6-support.patch new file mode 100644 index 000000000..5460374cb --- /dev/null +++ b/extended/lighttpd/lighttpd-1.4.35/remote-ip-ipv6-support.patch @@ -0,0 +1,117 @@ +--- lighttpd-1.4.35/src/configfile-glue.c.orig 2014-03-06 15:08:00.000000000 +0100 ++++ lighttpd-1.4.35/src/configfile-glue.c 2015-11-26 11:39:23.000000000 +0100 +@@ -8,6 +8,10 @@ + + #include + #include ++#include ++#ifndef __WIN32 ++#include ++#endif + + /** + * like all glue code this file contains functions which +@@ -336,12 +340,22 @@ static cond_result_t config_check_cond_n + + if ((dc->cond == CONFIG_COND_EQ || + dc->cond == CONFIG_COND_NE) && +- (con->dst_addr.plain.sa_family == AF_INET) && + (NULL != (nm_slash = strchr(dc->string->ptr, '/')))) { + int nm_bits; +- long nm; + char *err; + struct in_addr val_inp; ++ struct in6_addr val_inp6; ++ int val_af; ++ uint8_t *a, *b; ++ int result_match, result_nomatch; ++ ++ if (dc->cond == CONFIG_COND_EQ) { ++ result_match = COND_RESULT_TRUE; ++ result_nomatch = COND_RESULT_FALSE; ++ } else { ++ result_match = COND_RESULT_FALSE; ++ result_nomatch = COND_RESULT_TRUE; ++ } + + if (*(nm_slash+1) == '\0') { + log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string); +@@ -356,10 +370,16 @@ static cond_result_t config_check_cond_n + + return COND_RESULT_FALSE; + } ++ if (nm_bits < 0) { ++ log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: negative netmask:", dc->string, err); ++ ++ return COND_RESULT_FALSE; ++ } + + /* take IP convert to the native */ + buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr); + #ifdef __WIN32 ++ val_af = AF_INET; + if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) { + log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); + +@@ -367,21 +387,54 @@ static cond_result_t config_check_cond_n + } + + #else +- if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) { ++ if (1 == inet_pton(AF_INET, srv->cond_check_buf->ptr, &val_inp)) { ++ val_af = AF_INET; ++ } else if (1 == inet_pton(AF_INET6, srv->cond_check_buf->ptr, &val_inp6)) { ++ val_af = AF_INET6; ++ } else { + log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); + + return COND_RESULT_FALSE; + } + #endif + +- /* build netmask */ +- nm = htonl(~((1 << (32 - nm_bits)) - 1)); ++ if (val_af == AF_INET) { ++ if (nm_bits > 32) { ++ log_error_write(srv, __FILE__, __LINE__, "sd", "ERROR: ipv4 netmask too large:", nm_bits); + +- if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) { +- return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE; ++ return COND_RESULT_FALSE; ++ } ++ a = (uint8_t *)&val_inp; ++ if (con->dst_addr.plain.sa_family == AF_INET) { ++ b = (uint8_t *)&con->dst_addr.ipv4.sin_addr.s_addr; ++ } else if (IN6_IS_ADDR_V4MAPPED(&con->dst_addr.ipv6.sin6_addr)) { ++ b = (uint8_t *)&con->dst_addr.ipv6.sin6_addr.s6_addr[12]; ++ } else { ++ return result_nomatch; ++ } + } else { +- return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE; ++ if (nm_bits > 128) { ++ log_error_write(srv, __FILE__, __LINE__, "sd", "ERROR: ipv6 netmask too large:", nm_bits); ++ ++ return COND_RESULT_FALSE; ++ } ++ a = (uint8_t *)&val_inp6; ++ if (con->dst_addr.plain.sa_family == AF_INET) { ++ return result_nomatch; ++ } else { ++ b = (uint8_t *)&con->dst_addr.ipv6.sin6_addr.s6_addr[0]; ++ } ++ } ++ while (nm_bits) { ++ if (nm_bits >= 8) { ++ if (*a++ != *b++) return result_nomatch; ++ nm_bits -= 8; ++ } else { ++ if (*a >> (8 - nm_bits) != *b >> (8 - nm_bits)) return result_nomatch; ++ nm_bits = 0; ++ } + } ++ return result_match; + } else { + l = con->dst_addr_buf; + } + diff --git a/extended/lldpd/centos/build_srpm.data b/extended/lldpd/centos/build_srpm.data new file mode 100644 index 000000000..0effc815c --- /dev/null +++ b/extended/lldpd/centos/build_srpm.data @@ -0,0 +1,4 @@ +COPY_LIST="$CGCS_BASE/downloads/lldpd-0.9.0.tar.gz \ + $PKG_BASE/lldpd-0.9.0/* \ + $PKG_BASE/centos/files/*" +TIS_PATCH_VER=4 diff --git a/extended/lldpd/centos/files/i40e-lldp-configure.sh b/extended/lldpd/centos/files/i40e-lldp-configure.sh new file mode 100644 index 000000000..2796c4304 --- /dev/null +++ b/extended/lldpd/centos/files/i40e-lldp-configure.sh @@ -0,0 +1,148 @@ +#!/bin/bash +################################################################################ +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +################################################################################ + +# Certain i40e network devices (XL710 Fortville) have an internal firmware LLDP +# agent enabled by default. This can prevent LLDP PDUs from being processed by +# the driver and any upper layer agents. +# +# This script allows a user to enable and disable the internal LLDP agent. +# +# Note: debugfs must be enabled in the kernel +# +# To enable: +# ./i40e-lldp-configure.sh start +# +# To disable: +# ./i40e-lldp-configure.sh stop + +PROGNAME=$(basename $0) +DEBUGFS_PATH=/sys/kernel/debug +DEBUGFS_I40_DEVICES_PATH=$DEBUGFS_PATH/i40e +LLDP_COMMAND=lldp + +function log() +{ + local MSG="${PROGNAME}: $1" + logger -p notice "${MSG}" +} + +function err() +{ + local MSG="${PROGNAME}: $1" + logger -p error "${MSG}" +} + +function configure_device() +{ + local DEVICE=$1 + local ACTION=$2 + local DEVICE_PATH=${DEBUGFS_I40_DEVICES}/${DEVICE} + + if [ ! -d ${DEVICE_PATH} ]; then + return 1 + fi + + echo "${LLDP_COMMAND} ${ACTION}" > ${DEVICE_PATH}/command + RET=$? + + if [ ${RET} -ne 0 ]; then + err "Failed to ${ACTION} internal LLDP agent for device ${DEVICE}" + return ${RET} + fi + + log "${ACTION} internal LLDP agent for device ${DEVICE}" + return ${RET} +} + +function is_debugfs_mounted() { + if grep -qs "${DEBUGFS_PATH}" /proc/mounts; then + return 0 + fi + return 1 +} + +function mount_debugfs() { + mount -t debugfs none ${DEBUGFS_PATH} +} + +function unmount_debugfs() { + umount ${DEBUGFS_PATH} +} + +function scan_devices() +{ + local ACTION=$1 + local DEBUGFS_MOUNTED="false" + local DEVICES=${DEBUGFS_I40_DEVICES_PATH}/* + + if is_debugfs_mounted; then + DEBUGFS_MOUNTED="true" + fi + + if [ ${DEBUGFS_MOUNTED} = "false" ]; then + mount_debugfs + RET=$? + if [ ${RET} -ne 0 ]; then + err "Failed to mount debugfs" + return ${RET} + fi + log "Mounted debugfs" + fi + + for DEVICE in $DEVICES; do + configure_device ${DEVICE} ${ACTION} + done + + if [ ${DEBUGFS_MOUNTED} = "false" ]; then + unmount_debugfs + RET=$? + if [ ${RET} -ne 0 ]; then + err "Failed to unmount debugfs" + return ${RET} + fi + log "Unmounted debugfs" + fi + + return 0 +} + +function start() +{ + scan_devices start + return $? +} + +function stop() +{ + scan_devices stop + return $? +} + +function status() +{ + return 0 +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 +esac diff --git a/extended/lldpd/centos/files/lldpd-clear-station.patch b/extended/lldpd/centos/files/lldpd-clear-station.patch new file mode 100644 index 000000000..6ab09f0c5 --- /dev/null +++ b/extended/lldpd/centos/files/lldpd-clear-station.patch @@ -0,0 +1,39 @@ +From b2ed14edc66c7876cd9239a346b92630403e996c Mon Sep 17 00:00:00 2001 +From: Steven Webster +Date: Sun, 18 Jun 2017 22:23:49 -0400 +Subject: [PATCH 1/1] Clear station bit if any other capability is enabled + +--- + src/daemon/interfaces.c | 2 ++ + src/daemon/lldpd.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/src/daemon/interfaces.c b/src/daemon/interfaces.c +index ec81721..4923049 100644 +--- a/src/daemon/interfaces.c ++++ b/src/daemon/interfaces.c +@@ -309,6 +309,8 @@ interfaces_helper_chassis(struct lldpd *cfg, + if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) && + (LOCAL_CHASSIS(cfg)->c_cap_enabled == 0)) + LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION; ++ else if (LOCAL_CHASSIS(cfg)->c_cap_enabled != LLDP_CAP_STATION) ++ LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_STATION; + + if (LOCAL_CHASSIS(cfg)->c_id != NULL && + LOCAL_CHASSIS(cfg)->c_id_subtype == LLDP_CHASSISID_SUBTYPE_LLADDR) +diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c +index c815705..dac633f 100644 +--- a/src/daemon/lldpd.c ++++ b/src/daemon/lldpd.c +@@ -1152,6 +1152,8 @@ lldpd_update_localchassis(struct lldpd *cfg) + if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) && + (LOCAL_CHASSIS(cfg)->c_cap_enabled == 0)) + LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION; ++ else if (LOCAL_CHASSIS(cfg)->c_cap_enabled != LLDP_CAP_STATION) ++ LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_STATION; + + /* Set chassis ID if needed. This is only done if chassis ID + has not been set previously (with the MAC address of an +-- +1.8.3.1 + diff --git a/extended/lldpd/centos/files/lldpd-create-run-dir.patch b/extended/lldpd/centos/files/lldpd-create-run-dir.patch new file mode 100644 index 000000000..a4e9d00a2 --- /dev/null +++ b/extended/lldpd/centos/files/lldpd-create-run-dir.patch @@ -0,0 +1,12 @@ +Index: lldpd-0.9.0/src/daemon/lldpd.service.in +=================================================================== +--- lldpd-0.9.0.orig/src/daemon/lldpd.service.in ++++ lldpd-0.9.0/src/daemon/lldpd.service.in +@@ -9,6 +9,7 @@ Type=notify + NotifyAccess=main + EnvironmentFile=-/etc/default/lldpd + EnvironmentFile=-/etc/sysconfig/lldpd ++ExecStartPre=/bin/mkdir -p /var/run/lldpd + ExecStart=@sbindir@/lldpd $DAEMON_ARGS $LLDPD_OPTIONS + Restart=on-failure + diff --git a/extended/lldpd/centos/files/lldpd-i40e-disable.patch b/extended/lldpd/centos/files/lldpd-i40e-disable.patch new file mode 100644 index 000000000..1262e94db --- /dev/null +++ b/extended/lldpd/centos/files/lldpd-i40e-disable.patch @@ -0,0 +1,12 @@ +Index: lldpd-0.9.0/src/daemon/lldpd.service.in +=================================================================== +--- lldpd-0.9.0.orig/src/daemon/lldpd.service.in ++++ lldpd-0.9.0/src/daemon/lldpd.service.in +@@ -10,6 +10,7 @@ + EnvironmentFile=-/etc/default/lldpd + EnvironmentFile=-/etc/sysconfig/lldpd + ExecStartPre=/bin/mkdir -p /var/run/lldpd ++ExecStartPre=/etc/init.d/i40e-lldp-configure.sh stop + ExecStart=@sbindir@/lldpd $DAEMON_ARGS $LLDPD_OPTIONS + Restart=on-failure + \ No newline at end of file diff --git a/extended/lldpd/centos/lldpd.spec b/extended/lldpd/centos/lldpd.spec new file mode 100644 index 000000000..23df01b0b --- /dev/null +++ b/extended/lldpd/centos/lldpd.spec @@ -0,0 +1,418 @@ +# This .spec file is targeted for SuSE OBS. It relies on macro that +# are not available on regular distributions. If you use directly +# rpmbuild, be sure to use something like `--define 'rhel_version +# 700'`. + +# Conditional build options, disable with "--without xxx" +%bcond_without xml +%bcond_without cdp +%bcond_without edp +%bcond_without sonmp +%bcond_without fdp +%bcond_without lldpmed +%bcond_without dot1 +%bcond_without dot3 +%bcond_without custom +%bcond_without snmp +%bcond_with json + +# On RHEL <= 6, compile with oldies +# For SuSE, SLE11 with a recent SP comes with 3.0. SLE12 comes with 3.12. +%if 0%{?rhel_version} > 0 && 0%{?rhel_version} < 700 || 0%{?centos_version} > 0 && 0%{?centos_version} < 700 +%bcond_without oldies +%else +%bcond_with oldies +%endif + +# On RHEL < 7, disable systemd +# On SuSE < 12, disable systemd +%if 0%{?rhel_version} > 0 && 0%{?rhel_version} < 700 || 0%{?centos_version} > 0 && 0%{?centos_version} < 700 || 0%{?suse_version} > 0 && 0%{?suse_version} < 1200 +%bcond_with systemd +%else +%bcond_without systemd +%endif + +# On RHEL < 7, use embedded libevent +%if 0%{?rhel_version} > 0 && 0%{?rhel_version} < 700 || 0%{?centos_version} > 0 && 0%{?centos_version} < 700 || 0%{?suse_version} > 0 && 0%{?suse_version} < 1200 +%bcond_with system_libevent +%else +%bcond_without system_libevent +%endif + +%define lldpd_user lldpd +%define lldpd_group lldpd +%define lldpd_chroot /var/run/lldpd +%define lldpd_ctl_socket /var/run/lldpd/lldpd.socket +%define lldpd_pid_file /var/run/lldpd/lldpd.pid + +Summary: Implementation of IEEE 802.1ab (LLDP) +Name: lldpd +Version: 0.9.0 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +License: MIT +Group: System/Management +URL: http://vincentbernat.github.com/lldpd/ +Source0: http://media.luffy.cx/files/lldpd/%{name}-%{version}.tar.gz +Source1: lldpd.init%{?suse_version:.suse} +# Source2: lldpd.sysconfig +Source3: lldpd.default +Source4: i40e-lldp-configure.sh + +Patch0: lldpd-interface-show.patch +Patch1: lldpd-create-run-dir.patch +Patch2: lldpd-i40e-disable.patch +Patch3: lldpd-clear-station.patch + +BuildRequires: pkgconfig +%if %{with system_libevent} +BuildRequires: libevent-devel +%endif +BuildRequires: readline-devel +%if %{with snmp} +BuildRequires: net-snmp-devel +BuildRequires: openssl-devel +%{!?suse_version:BuildRequires: lm_sensors-devel} +%endif +%if %{with xml} +BuildRequires: libxml2-devel +%endif + +BuildRequires: json-c-devel +BuildRequires: pciutils-devel + +%if %{with systemd} +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +BuildRequires: systemd +BuildRequires: systemd-devel +BuildRequires: systemd-units +%endif +%if 0%{?suse_version} +PreReq: %fillup_prereq %insserv_prereq pwdutils +%else +Requires(pre): /usr/sbin/groupadd /usr/sbin/useradd +Requires(post): chkconfig +Requires(preun): chkconfig +Requires(preun): initscripts +Requires(postun): initscripts +%endif + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release} + +%description +This implementation provides LLDP sending and reception, supports VLAN +and includes an SNMP subagent that can interface to an SNMP agent +through AgentX protocol. + +LLDP is an industry standard protocol designed to supplant proprietary +Link-Layer protocols such as Extreme EDP (Extreme Discovery Protocol) +and CDP (Cisco Discovery Protocol). The goal of LLDP is to provide an +inter-vendor compatible mechanism to deliver Link-Layer notifications +to adjacent network devices. + +This daemon is also able to deal with CDP, FDP, SONMP and EDP +protocol. It also handles LLDP-MED extension. + +%package devel +Summary: Implementation of IEEE 802.1ab - Tools and header files for developers +Group: Development/Libraries/C +BuildRequires: pkgconfig +Requires: lldpd = %{version}-%{release} + +%description devel +This package is required to develop alternate clients for lldpd. + +LLDP is an industry standard protocol designed to supplant proprietary +Link-Layer protocols such as Extreme EDP (Extreme Discovery Protocol) +and CDP (Cisco Discovery Protocol). The goal of LLDP is to provide an +inter-vendor compatible mechanism to deliver Link-Layer notifications +to adjacent network devices. + +%prep +%setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 + + +%build +%configure \ +%if %{with snmp} + --with-snmp \ +%endif +%if %{with xml} + --with-xml \ +%endif +%if %{with cdp} + --enable-cdp \ +%else + --disable-cdp \ +%endif +%if %{with edp} + --enable-edp \ +%else + --disable-edp \ +%endif +%if %{with sonmp} + --enable-sonmp \ +%else + --disable-sonmp \ +%endif +%if %{with fdp} + --enable-fdp \ +%else + --disable-fdp \ +%endif +%if %{with lldpmed} + --enable-lldpmed \ +%else + --disable-lldpmed \ +%endif +%if %{with dot1} + --enable-dot1 \ +%else + --disable-dot1 \ +%endif +%if %{with dot3} + --enable-dot3 \ +%else + --disable-dot3 \ +%endif +%if %{with custom} + --enable-custom \ +%else + --disable-custom \ +%endif +%if %{with oldies} + --enable-oldies \ +%else + --disable-oldies \ +%endif + --with-privsep-user=%lldpd_user \ + --with-privsep-group=%lldpd_group \ + --with-privsep-chroot=%lldpd_chroot \ +%if %{without systemd} + --with-systemdsystemunitdir=no \ +%endif + --with-sysusersdir=no \ + --prefix=%{_usr} \ + --localstatedir=%{_localstatedir} \ + --sysconfdir=%{_sysconfdir} \ + --libdir=%{_libdir} \ + --docdir=%{_docdir}/lldpd \ + --enable-pie \ + --with-lldpd-ctl-socket=%lldpd_ctl_socket \ + --with-lldpd-pid-file=%lldpd_pid_file + +[ -f %{_includedir}/net-snmp/agent/struct.h ] || touch src/struct.h +make %{?_smp_mflags} + +%install +make install DESTDIR=$RPM_BUILD_ROOT +%if %{without systemd} +install -d $RPM_BUILD_ROOT/%{_initrddir} +install -m755 %{SOURCE1} $RPM_BUILD_ROOT/%{_initrddir}/lldpd +%endif +# %if 0%{?suse_version} +# mkdir -p ${RPM_BUILD_ROOT}/var/adm/fillup-templates +# install -m700 %{SOURCE2} ${RPM_BUILD_ROOT}/var/adm/fillup-templates/sysconfig.lldpd +# %else +# install -d $RPM_BUILD_ROOT/etc/sysconfig +# install -m644 %{SOURCE2} $RPM_BUILD_ROOT/etc/sysconfig/lldpd +# %endif + +install -Dm 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/default/lldpd +install -d %{buildroot}%{_initrddir} +install -Dm 0755 %{SOURCE4} %{buildroot}%{_initrddir}/ + +# Make an empty configuration file +touch %{buildroot}%{_sysconfdir}/lldpd.conf + +%pre +# Create lldpd user/group +if getent group %lldpd_group >/dev/null 2>&1 ; then : ; else \ + %{_sbindir}/groupadd -r %lldpd_group > /dev/null 2>&1 || exit 1 ; fi +if getent passwd %lldpd_user >/dev/null 2>&1 ; then : ; else \ + %{_sbindir}/useradd --system --shell /bin/false --no-create-home \ + -g %lldpd_group %lldpd_user 2> /dev/null \ + || exit 1 ; fi + +%if 0%{?suse_version} +# Service management for SuSE + +%post +/sbin/ldconfig +%{fillup_and_insserv lldpd} +%postun +/sbin/ldconfig +%restart_on_update lldpd +%insserv_cleanup +%preun +%stop_on_removal lldpd + +%else +%if %{without systemd} +# Service management for Redhat/CentOS without systemd + +%post +/sbin/ldconfig +/sbin/chkconfig --add lldpd +%postun +/sbin/ldconfig +if [ "$1" -ge "1" ]; then + /sbin/service lldpd condrestart >/dev/null 2>&1 || : +fi +%preun +if [ "$1" = "0" ]; then + /sbin/service lldpd stop > /dev/null 2>&1 + /sbin/chkconfig --del lldpd +fi + +%else +# Service management for Redhat/CentOS with systemd + +%post +/sbin/ldconfig +%systemd_post lldpd.service +/bin/systemctl enable lldpd.service + +%preun +%systemd_preun lldpd.service + +%postun +%systemd_postun_with_restart lldpd.service +/sbin/ldconfig + +%endif +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%dir %{_docdir}/lldpd +%doc %{_docdir}/lldpd/NEWS +%doc %{_docdir}/lldpd/ChangeLog +%doc %{_docdir}/lldpd/README.md +%doc %{_docdir}/lldpd/CONTRIBUTE.md +%{_sbindir}/lldpd +%{_sbindir}/lldpctl +%{_sbindir}/lldpcli +%{_libdir}/liblldpctl.so.* +%{_datadir}/zsh +%{_datadir}/bash-completion +%doc %{_mandir}/man8/lldp* +%config(noreplace) %{_sysconfdir}/lldpd.d +%if %{without systemd} +%config(noreplace) %attr(755,root,root) %{_initrddir}/lldpd +%else +%{_unitdir}/lldpd.service +%endif +%{_sysconfdir}/default/lldpd +%config(noreplace) %{_sysconfdir}/lldpd.conf +%{_initrddir}/i40e-lldp-configure.sh + +%files devel +%defattr(-,root,root) +%{_libdir}/liblldpctl.so +%{_libdir}/liblldpctl.a +%{_libdir}/liblldpctl.la +%{_libdir}/pkgconfig/lldpctl.pc +%{_includedir}/lldpctl.h +%{_includedir}/lldp-const.h + +%changelog +* Fri Jan 01 2016 Vincent Bernat - 0.9.0-1 +- New upstream version. +- Do not rely on libnl3. + +* Sun Dec 27 2015 Vincent Bernat - 0.8.0-1 +- New upstream version. +- Use system libnl3 when possible. +- Use system libevent when possible. + +* Wed Sep 09 2015 Vincent Bernat - 0.7.17-1 +- New upstream version. + +* Fri Aug 07 2015 Vincent Bernat - 0.7.16-1 +- New upstream version. + +* Wed May 20 2015 Vincent Bernat - 0.7.15-1 +- New upstream version. + +* Sat Apr 04 2015 Vincent Bernat - 0.7.14-1 +- New upstream version. + +* Tue Dec 30 2014 Vincent Bernat - 0.7.13-1 +- New upstream version. + +* Sat Nov 22 2014 Vincent Bernat - 0.7.12-1 +- New upstream version. +- Completion for bash and zsh. + +* Wed Oct 08 2014 Vincent Bernat - 0.7.11-1 +- New upstream version. +- Completion for bash and zsh. + +* Mon Jul 21 2014 Vincent Bernat - 0.7.10-1 +- New upstream version. + +* Wed May 28 2014 Vincent Bernat - 0.7.9-1 +- New upstream version. + +* Sun Apr 13 2014 Vincent Bernat - 0.7.8-1 +- New upstream version. + +* Sun Nov 10 2013 Vincent Bernat - 0.7.7-1 +- New upstream version. + +* Fri Jul 12 2013 Vincent Bernat - 0.7.6-1 +- New upstream version. + +* Sat Jun 22 2013 Vincent Bernat - 0.7.5-1 +- New upstream version. + +* Sun May 12 2013 Vincent Bernat - 0.7.3-1 +- New upstream version. + +* Fri Apr 19 2013 Vincent Bernat - 0.7.2-1 +- New upstream version. + +* Sat Jan 12 2013 Vincent Bernat - 0.7.1-1 +- New upstream version. + +* Sun Jan 06 2013 Vincent Bernat - 0.7.0-1 +- New upstream version. +- Requires readline-devel. +- Ships lldpcli. + +* Thu Sep 27 2012 Vincent Bernat - 0.6.1-1 +- New upstream version +- Do not require libevent, use embedded copy. +- Provide a -devel package. + +* Fri Jun 11 2010 Vincent Bernat - 0.5.1-1 +- New upstream version +- Define bcond_without and with macros if not defined to be compatible + with RHEL +- Requires useradd and groupadd +- Adapt to make it work with SuSE +- Provide an init script targetted at SuSE +- Build require lm_sensors-devel on RHEL + +* Fri Mar 12 2010 Vincent Bernat - 0.5.0-1 +- New upstream version +- Add XML support + +* Tue May 19 2009 Vincent Bernat - 0.4.0-1 +- Add variables +- Enable SNMP support +- Add _lldpd user creation +- Add initscript +- New upstream version + +* Mon May 18 2009 Dean Hamstead - 0.3.3-1 +- Initial attempt diff --git a/extended/lldpd/lldpd-0.9.0/lldpd-interface-show.patch b/extended/lldpd/lldpd-0.9.0/lldpd-interface-show.patch new file mode 100644 index 000000000..8fb52a08a --- /dev/null +++ b/extended/lldpd/lldpd-0.9.0/lldpd-interface-show.patch @@ -0,0 +1,206 @@ +--- + src/client/client.h | 2 + + src/client/display.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- + src/client/show.c | 44 ++++++++++++++++++++++++++++++++++++++ + src/lib/atoms/port.c | 7 ++++++ + src/lib/lldpctl.h | 1 + 5 files changed, 112 insertions(+), 1 deletion(-) + +--- a/src/client/client.h ++++ b/src/client/client.h +@@ -115,6 +115,8 @@ char* totag(const char *); + #define DISPLAY_DETAILS 3 + void display_interfaces(lldpctl_conn_t *, struct writer *, + struct cmd_env *, int, int); ++void display_local_interfaces(lldpctl_conn_t *, struct writer *, ++ struct cmd_env *, int, int); + void display_interface(lldpctl_conn_t *, struct writer *, int, + lldpctl_atom_t *, lldpctl_atom_t *, int, int); + void display_local_chassis(lldpctl_conn_t *, struct writer *, +--- a/src/client/display.c ++++ b/src/client/display.c +@@ -344,12 +344,23 @@ display_port(struct writer *w, lldpctl_a + tag_datatag(w, "descr", "PortDescr", + lldpctl_atom_get_str(port, lldpctl_k_port_descr)); + ++ tag_datatag(w, "ttl", "Ttl", ++ lldpctl_atom_get_str(port, lldpctl_k_port_ttl)); ++ + /* Dot3 */ + if (details == DISPLAY_DETAILS) { + tag_datatag(w, "mfs", "MFS", + lldpctl_atom_get_str(port, lldpctl_k_port_dot3_mfs)); +- tag_datatag(w, "aggregation", "Port is aggregated. PortAggregID", ++ ++ long int lag_id = lldpctl_atom_get_int(port, ++ lldpctl_k_port_dot3_aggregid); ++ tag_start(w, "link-aggregation", "LinkAgg"); ++ tag_attr(w, "supported", "supported", "yes"); ++ tag_attr(w, "enabled", "enabled", ++ (lag_id > 0)?"yes":"no"); ++ tag_datatag(w, "aggregation", "PortAggregID", + lldpctl_atom_get_str(port, lldpctl_k_port_dot3_aggregid)); ++ tag_end(w); + + long int autoneg_support, autoneg_enabled, autoneg_advertised; + autoneg_support = lldpctl_atom_get_int(port, +@@ -663,6 +674,52 @@ display_interfaces(lldpctl_conn_t *conn, + lldpctl_atom_dec_ref(port); + } + tag_end(w); ++} ++ ++/** ++ * Display information about local interfaces. ++ * ++ * @param conn Connection to lldpd. ++ * @param w Writer. ++ * @param hidden Whatever to show hidden ports. ++ * @param env Environment from which we may find the list of ports. ++ * @param details Level of details we need (DISPLAY_*). ++ */ ++void ++display_local_interfaces(lldpctl_conn_t *conn, struct writer *w, ++ struct cmd_env *env, ++ int hidden, int details) ++{ ++ lldpctl_atom_t *iface; ++ int protocol = LLDPD_MODE_MAX; ++ const char *proto_str; ++ ++ /* user might have specified protocol to filter display results */ ++ proto_str = cmdenv_get(env, "protocol"); ++ ++ if (proto_str) { ++ log_debug("display", "filter protocol: %s ", proto_str); ++ ++ protocol = 0; ++ for (lldpctl_map_t *protocol_map = ++ lldpctl_key_get_map(lldpctl_k_port_protocol); ++ protocol_map->string; ++ protocol_map++) { ++ if (!strcasecmp(proto_str, protocol_map->string)) { ++ protocol = protocol_map->value; ++ break; ++ } ++ } ++ } ++ ++ tag_start(w, "lldp", "LLDP interfaces"); ++ while ((iface = cmd_iterate_on_interfaces(conn, env))) { ++ lldpctl_atom_t *port; ++ port = lldpctl_get_port(iface); ++ display_interface(conn, w, hidden, iface, port, details, protocol); ++ lldpctl_atom_dec_ref(port); ++ } ++ tag_end(w); + } + + void +--- a/src/client/show.c ++++ b/src/client/show.c +@@ -48,6 +48,35 @@ cmd_show_neighbors(struct lldpctl_conn_t + } + + /** ++ * Show interfaces. ++ * ++ * The environment will contain the following keys: ++ * - C{ports} list of ports we want to restrict showing. ++ * - C{hidden} if we should show hidden ports. ++ * - C{summary} if we want to show only a summary ++ * - C{detailed} for a detailed overview ++ */ ++static int ++cmd_show_interfaces(struct lldpctl_conn_t *conn, struct writer *w, ++ struct cmd_env *env, void *arg) ++{ ++ log_debug("lldpctl", "show interfaces data (%s) %s hidden interfaces", ++ cmdenv_get(env, "summary")?"summary": ++ cmdenv_get(env, "detailed")?"detailed": ++ "normal", cmdenv_get(env, "hidden")?"with":"without"); ++ if (cmdenv_get(env, "ports")) ++ log_debug("lldpctl", "restrict to the following ports: %s", ++ cmdenv_get(env, "ports")); ++ ++ display_local_interfaces(conn, w, env, !!cmdenv_get(env, "hidden"), ++ cmdenv_get(env, "summary")?DISPLAY_BRIEF: ++ cmdenv_get(env, "detailed")?DISPLAY_DETAILS: ++ DISPLAY_NORMAL); ++ ++ return 1; ++} ++ ++/** + * Show chassis. + * + * The environment will contain the following keys: +@@ -269,6 +298,12 @@ register_commands_show(struct cmd_node * + "Show neighbors data", + NULL, NULL, NULL); + ++ struct cmd_node *interfaces = commands_new( ++ show, ++ "interfaces", ++ "Show interfaces data", ++ NULL, NULL, NULL); ++ + struct cmd_node *chassis = commands_new( + show, + "chassis", +@@ -289,6 +324,15 @@ register_commands_show(struct cmd_node * + + register_common_commands(neighbors, 1); + ++ /* Interfaces data */ ++ commands_new(interfaces, ++ NEWLINE, ++ "Show interfaces data", ++ NULL, cmd_show_interfaces, NULL); ++ ++ cmd_restrict_ports(interfaces); ++ register_common_commands(interfaces, 0); ++ + /* Chassis data */ + commands_new(chassis, + NEWLINE, +--- a/src/lib/atoms/port.c ++++ b/src/lib/atoms/port.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include "lldpctl.h" + #include "../log.h" +@@ -544,6 +545,7 @@ _lldpctl_atom_get_int_port(lldpctl_atom_ + (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + struct lldpd_hardware *hardware = p->hardware; ++ time_t now = time(NULL); + + /* Local port only */ + if (hardware != NULL) { +@@ -585,6 +587,11 @@ _lldpctl_atom_get_int_port(lldpctl_atom_ + return port->p_id_subtype; + case lldpctl_k_port_hidden: + return port->p_hidden_in; ++ case lldpctl_k_port_ttl: ++ if (port->p_lastupdate > 0) ++ return (port->p_chassis->c_ttl - (now - port->p_lastupdate)); ++ else ++ return port->p_chassis->c_ttl; + #ifdef ENABLE_DOT3 + case lldpctl_k_port_dot3_mfs: + if (port->p_mfs > 0) +--- a/src/lib/lldpctl.h ++++ b/src/lib/lldpctl.h +@@ -674,6 +674,7 @@ typedef enum { + lldpctl_k_port_hidden, /**< `(I)` Is this port hidden (or should it be displayed?)? */ + lldpctl_k_port_status, /**< `(IS,WO)` Operational status of this (local) port */ + lldpctl_k_port_chassis, /**< `(A)` Chassis associated to the port */ ++ lldpctl_k_port_ttl, /**< `(I)` The port ttl. */ + + lldpctl_k_port_dot3_mfs = 1300, /**< `(I)` MFS */ + lldpctl_k_port_dot3_aggregid, /**< `(I)` Port aggregation ID */ diff --git a/extended/lldpd/lldpd-0.9.0/lldpd.default b/extended/lldpd/lldpd-0.9.0/lldpd.default new file mode 100644 index 000000000..2364c02e5 --- /dev/null +++ b/extended/lldpd/lldpd-0.9.0/lldpd.default @@ -0,0 +1,2 @@ +# Uncomment to start SNMP subagent and enable CDP, SONMP and EDP protocol +#DAEMON_ARGS="-x -c -s -e" \ No newline at end of file diff --git a/extended/lldpd/lldpd-0.9.0/lldpd.init b/extended/lldpd/lldpd-0.9.0/lldpd.init new file mode 100644 index 000000000..c910f0d86 --- /dev/null +++ b/extended/lldpd/lldpd-0.9.0/lldpd.init @@ -0,0 +1,117 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: lldpd +# Required-Start: $remote_fs $network $syslog +# Required-Stop: $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: LLDP daemon +# Description: lldpd is a 802.1AB implementation, a L2 network +# discovery protocol. It also supports CDP, EDP and +# various other protocols. +### END INIT INFO + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="LLDP daemon" +NAME=lldpd +DAEMON=/usr/sbin/$NAME +DAEMON_ARGS="" +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME +CHROOT=/var/run/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Create the chroot directory if not present +[ -d "$CHROOT" ] || mkdir -p $CHROOT + +# LSB log_* functions +. /lib/lsb/init-functions + +if [ ! -d "$CHROOT" ]; then + mkdir -p $CHROOT +fi + + +do_start() +{ + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ + $DAEMON_ARGS \ + || return 2 +} + +do_stop() +{ + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + rm -f $PIDFILE + return "$RETVAL" +} + +do_reload() { + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_begin_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_begin_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + reload) + log_begin_msg "Reloading $DESC" "$NAME" + do_reload + log_end_msg $? + ;; + restart|force-reload) + log_begin_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + status) + status_of_proc $DAEMON $NAME -p $PIDFILE && exit 0 || exit $? + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}" >&2 + exit 3 + ;; +esac + +: \ No newline at end of file diff --git a/extended/logrotate/centos/build_srpm.data b/extended/logrotate/centos/build_srpm.data new file mode 100644 index 000000000..be9600150 --- /dev/null +++ b/extended/logrotate/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$PKG_BASE/files/*" +TIS_PATCH_VER=3 diff --git a/extended/logrotate/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/logrotate/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..89320d332 --- /dev/null +++ b/extended/logrotate/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 2f9511e04b5af2b214b949acf9577eaa95153a60 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:22:44 -0400 +Subject: [PATCH 2/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/logrotate.spec +--- + SPECS/logrotate.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/logrotate.spec b/SPECS/logrotate.spec +index 1b4e4e3..46e17e8 100644 +--- a/SPECS/logrotate.spec ++++ b/SPECS/logrotate.spec +@@ -1,7 +1,7 @@ + Summary: Rotates, compresses, removes and mails system log files + Name: logrotate + Version: 3.8.6 +-Release: 14%{?dist} ++Release: 14.el7%{?_tis_dist}.%{tis_patch_ver} + License: GPL+ + Group: System Environment/Base + Url: https://fedorahosted.org/logrotate/ +-- +1.9.1 + diff --git a/extended/logrotate/centos/meta_patches/0002-crond-adjustment.patch b/extended/logrotate/centos/meta_patches/0002-crond-adjustment.patch new file mode 100644 index 000000000..1ebed13df --- /dev/null +++ b/extended/logrotate/centos/meta_patches/0002-crond-adjustment.patch @@ -0,0 +1,50 @@ +From ecd78bb1b347dfe3da380e100ce1f566418279a1 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:22:44 -0400 +Subject: [PATCH 1/2] WRS: crond-adjustment.patch + +--- + SPECS/logrotate.spec | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/SPECS/logrotate.spec b/SPECS/logrotate.spec +index c66cf89..1b4e4e3 100644 +--- a/SPECS/logrotate.spec ++++ b/SPECS/logrotate.spec +@@ -7,6 +7,7 @@ Group: System Environment/Base + Url: https://fedorahosted.org/logrotate/ + Source: https://fedorahosted.org/releases/l/o/logrotate/logrotate-%{version}.tar.gz + Source1: rwtab ++Source2: logrotate-cron.d + Patch0: logrotate-3.8.6-force.patch + Patch1: logrotate-3.8.6-r465.patch + Patch2: logrotate-3.8.6-sortglob.patch +@@ -89,6 +90,10 @@ install -p -m 755 examples/logrotate.cron $RPM_BUILD_ROOT/%{_sysconfdir}/cron.da + mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/rwtab.d + install -m644 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/rwtab.d/logrotate + ++mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/cron.d ++install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/cron.d/logrotate ++mv $RPM_BUILD_ROOT/%{_sysconfdir}/cron.daily/logrotate $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.cron ++ + %pre + # If /var/lib/logrotate/logrotate.status does not exist, create it and copy + # the /var/lib/logrotate.status in it (if it exists). We have to do that in pre +@@ -108,12 +113,13 @@ rm -rf $RPM_BUILD_ROOT + %attr(0755, root, root) %{_sbindir}/logrotate + %attr(0644, root, root) %{_mandir}/man8/logrotate.8* + %attr(0644, root, root) %{_mandir}/man5/logrotate.conf.5* +-%attr(0700, root, root) %config(noreplace) %{_sysconfdir}/cron.daily/logrotate + %attr(0644, root, root) %config(noreplace) %{_sysconfdir}/logrotate.conf + %attr(0755, root, root) %dir %{_sysconfdir}/logrotate.d + %attr(0755, root, root) %dir %{_localstatedir}/lib/logrotate + %attr(0644, root, root) %ghost %verify(not size md5 mtime) %{_localstatedir}/lib/logrotate/logrotate.status + %config(noreplace) %{_sysconfdir}/rwtab.d/logrotate ++%{_sysconfdir}/cron.d/logrotate ++%attr(0700, root, root) %{_sysconfdir}/logrotate.cron + + %changelog + * Tue Jan 24 2017 Kamil Dudka - 3.8.6-14 +-- +1.9.1 + diff --git a/extended/logrotate/centos/meta_patches/0003-Add-upstream-patches.patch b/extended/logrotate/centos/meta_patches/0003-Add-upstream-patches.patch new file mode 100644 index 000000000..e0fc5e3f9 --- /dev/null +++ b/extended/logrotate/centos/meta_patches/0003-Add-upstream-patches.patch @@ -0,0 +1,36 @@ +From a4c9be7a2b9c9216b87930436d815f0d765a2ba4 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 19 Jan 2018 23:04:46 -0500 +Subject: [PATCH] Add upstream patches + +--- + SPECS/logrotate.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/logrotate.spec b/SPECS/logrotate.spec +index 46e17e8..d67e4bb 100644 +--- a/SPECS/logrotate.spec ++++ b/SPECS/logrotate.spec +@@ -37,6 +37,9 @@ Patch13: logrotate-3.8.6-selinux.patch + # fix #1387533 - make 'su' directive accept usernames starting with digits + Patch14: logrotate-3.8.6-su-username.patch + ++Patch10001: 0001-createOutputFile-rename-already-existing-file.patch ++Patch10002: 0002-createOutputFile-eliminate-stat-open-TOCTOU-race.patch ++ + Requires: coreutils >= 5.92 popt + BuildRequires: libselinux-devel popt-devel libacl-devel acl + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +@@ -70,6 +73,9 @@ log files on your system. + %patch13 -p1 + %patch14 -p1 + ++%patch10001 -p1 ++%patch10002 -p1 ++ + %build + make %{?_smp_mflags} RPM_OPT_FLAGS="$RPM_OPT_FLAGS" WITH_SELINUX=yes WITH_ACL=yes + +-- +1.8.3.1 + diff --git a/extended/logrotate/centos/meta_patches/0004-Add-su-patch.patch b/extended/logrotate/centos/meta_patches/0004-Add-su-patch.patch new file mode 100644 index 000000000..9780ded7d --- /dev/null +++ b/extended/logrotate/centos/meta_patches/0004-Add-su-patch.patch @@ -0,0 +1,32 @@ +From e07398bb49873b2a273cb1c7b3dc5b781e3f634b Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 19 Jan 2018 23:38:21 -0500 +Subject: [PATCH] Add su patch + +--- + SPECS/logrotate.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/logrotate.spec b/SPECS/logrotate.spec +index d67e4bb..84977f6 100644 +--- a/SPECS/logrotate.spec ++++ b/SPECS/logrotate.spec +@@ -39,6 +39,7 @@ Patch14: logrotate-3.8.6-su-username.patch + + Patch10001: 0001-createOutputFile-rename-already-existing-file.patch + Patch10002: 0002-createOutputFile-eliminate-stat-open-TOCTOU-race.patch ++Patch10003: 0003-Add-su-root-to-logrotate.conf.patch + + Requires: coreutils >= 5.92 popt + BuildRequires: libselinux-devel popt-devel libacl-devel acl +@@ -75,6 +76,7 @@ log files on your system. + + %patch10001 -p1 + %patch10002 -p1 ++%patch10003 -p1 + + %build + make %{?_smp_mflags} RPM_OPT_FLAGS="$RPM_OPT_FLAGS" WITH_SELINUX=yes WITH_ACL=yes +-- +1.8.3.1 + diff --git a/extended/logrotate/centos/meta_patches/PATCH_ORDER b/extended/logrotate/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..372b0fdc9 --- /dev/null +++ b/extended/logrotate/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,4 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-crond-adjustment.patch +0003-Add-upstream-patches.patch +0004-Add-su-patch.patch diff --git a/extended/logrotate/centos/patches/0001-createOutputFile-rename-already-existing-file.patch b/extended/logrotate/centos/patches/0001-createOutputFile-rename-already-existing-file.patch new file mode 100644 index 000000000..c5f7fea89 --- /dev/null +++ b/extended/logrotate/centos/patches/0001-createOutputFile-rename-already-existing-file.patch @@ -0,0 +1,104 @@ +From e43ef5ea3ba1faffad5af528d37ac910e5c0407f Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 19 Jan 2018 23:17:55 -0500 +Subject: [PATCH] createOutputFile: rename already existing file + +Upstream patch: +From fc1c3eff61edf8e9f0a4bfa980f3a6030a6b271f Mon Sep 17 00:00:00 2001 +From: Mathieu Parent +Date: Tue, 8 Mar 2016 16:56:50 +0100 +Subject: [PATCH] createOutputFile: rename already existing file + +See https://bugs.debian.org/734688 + +Closes #23 +--- + logrotate.c | 20 ++++++++++++++++++-- + test/test | 26 ++++++++++++++++++++++++++ + test/test-config.72.in | 7 +++++++ + 3 files changed, 51 insertions(+), 2 deletions(-) + create mode 100644 test/test-config.72.in + +diff --git a/logrotate.c b/logrotate.c +index 20f6ea5..42c3eeb 100644 +--- a/logrotate.c ++++ b/logrotate.c +@@ -395,8 +395,24 @@ static int runScript(struct logInfo *log, char *logfn, char *script) + int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, int force_mode) + { + int fd; +- struct stat sb_create; +- int acl_set = 0; ++ struct stat sb_create; ++ int acl_set = 0; ++ ++ if (stat(fileName, &sb_create) == 0) { ++ /* the destination file already exists, while it should not */ ++ struct tm now = *localtime(&nowSecs); ++ size_t fileName_size = strlen(fileName); ++ char* backupName = alloca(fileName_size + sizeof("-YYYYMMDDHH.backup")); ++ strncpy(backupName, fileName, fileName_size); ++ size_t date_size=strftime(backupName+fileName_size, 12, "-%Y%m%d%H", &now); ++ strncpy(backupName+fileName_size+date_size, ".backup\0", 8); ++ message(MESS_ERROR, "destination %s already exists, renaming to %s\n", fileName, backupName); ++ if (rename(fileName, backupName) != 0) { ++ message(MESS_ERROR, "error renaming already existing output file %s to %s: %s\n", ++ fileName, backupName, strerror(errno)); ++ return -1; ++ } ++ } + + fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW), + (S_IRUSR | S_IWUSR) & sb->st_mode); +diff --git a/test/test b/test/test +index 54d57d2..755e582 100755 +--- a/test/test ++++ b/test/test +@@ -1586,5 +1586,31 @@ EOF + rm -rf testdir adir + rm -rf testdir bdir + ++cleanup 72 ++ ++# ------------------------------- Test 72 ------------------------------------ ++preptest test.log 72 2 ++ ++$RLR test-config.72 --force ++ ++checkoutput < test.log.1.gz ++ ++$RLR test-config.72 --force ++dt="$(date +%Y%m%d%H)" ++ ++checkoutput < +Date: Mon, 17 Oct 2016 17:59:31 +0200 +Subject: [PATCH] createOutputFile: eliminate stat/open TOCTOU race + +--- + logrotate.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/logrotate.c b/logrotate.c +index 10f4b52..79f4755 100644 +--- a/logrotate.c ++++ b/logrotate.c +@@ -366,11 +366,18 @@ static int runScript(struct logInfo *log, char *logfn, char *script) + + int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, int force_mode) + { +- int fd; ++ int fd = -1; + struct stat sb_create; + int acl_set = 0; ++ int i; ++ ++ for (i = 0; i < 2; ++i) { ++ fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW), ++ (S_IRUSR | S_IWUSR) & sb->st_mode); ++ ++ if ((fd >= 0) || (errno != EEXIST)) ++ break; + +- if (stat(fileName, &sb_create) == 0) { + /* the destination file already exists, while it should not */ + struct tm now = *localtime(&nowSecs); + size_t fileName_size = strlen(fileName); +@@ -384,11 +391,9 @@ int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, i + fileName, backupName, strerror(errno)); + return -1; + } ++ /* existing file renamed, try it once again */ + } + +- fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW), +- (S_IRUSR | S_IWUSR) & sb->st_mode); +- + if (fd < 0) { + message(MESS_ERROR, "error creating output file %s: %s\n", + fileName, strerror(errno)); +-- +1.8.3.1 + diff --git a/extended/logrotate/centos/patches/0003-Add-su-root-to-logrotate.conf.patch b/extended/logrotate/centos/patches/0003-Add-su-root-to-logrotate.conf.patch new file mode 100644 index 000000000..e2b40f144 --- /dev/null +++ b/extended/logrotate/centos/patches/0003-Add-su-root-to-logrotate.conf.patch @@ -0,0 +1,26 @@ +From 536a805bdb2be64b91df6fe18589340ad8aec066 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Fri, 19 Jan 2018 23:36:54 -0500 +Subject: [PATCH] Add su root to logrotate.conf + +--- + examples/logrotate-default | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/examples/logrotate-default b/examples/logrotate-default +index 7da6bb7..c7a6f08 100644 +--- a/examples/logrotate-default ++++ b/examples/logrotate-default +@@ -11,6 +11,9 @@ create + # use date as a suffix of the rotated file + dateext + ++# Use su to rotate as root to ensure we don't fail due to dir permissions ++su root root ++ + # uncomment this if you want your log files compressed + #compress + +-- +1.8.3.1 + diff --git a/extended/logrotate/centos/srpm_path b/extended/logrotate/centos/srpm_path new file mode 100644 index 000000000..be617e71e --- /dev/null +++ b/extended/logrotate/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/logrotate-3.8.6-14.el7.src.rpm diff --git a/extended/logrotate/files/logrotate-cron.d b/extended/logrotate/files/logrotate-cron.d new file mode 100644 index 000000000..52cb93c74 --- /dev/null +++ b/extended/logrotate/files/logrotate-cron.d @@ -0,0 +1,4 @@ +# m h dom mon dow user command +## Commenting out cron. Replaced by logmgmt daemon +#*/10 * * * * root /etc/logrotate.cron + diff --git a/extended/nova-utils/centos/build_srpm.data b/extended/nova-utils/centos/build_srpm.data new file mode 100644 index 000000000..4620f4786 --- /dev/null +++ b/extended/nova-utils/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$PKG_BASE/nova-utils/*" +TIS_PATCH_VER=1 diff --git a/extended/nova-utils/centos/nova-utils.spec b/extended/nova-utils/centos/nova-utils.spec new file mode 100644 index 000000000..dc0dd5f2f --- /dev/null +++ b/extended/nova-utils/centos/nova-utils.spec @@ -0,0 +1,38 @@ +Summary: nova-utils version 1.0-r1 +Name: nova-utils +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: development +Packager: Wind River +URL: unknown + +Source0: LICENSE +Source1: nova-sriov + +%description +Nova utilities package + +%package -n nova-utils-devel +Summary: nova-utils - Development files +Group: devel +Requires: nova-utils = %{version}-%{release} + +%description -n nova-utils-devel +Nova utilities package This package contains symbolic links, header files, +and related items necessary for software development. + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/%{_bindir} +install -m 0755 %{SOURCE1} $RPM_BUILD_ROOT/%{_bindir}/nova-sriov +mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}-%{version} +install -m 644 %{SOURCE0} $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}-%{version} + +%files +%defattr(-,root,root,-) +%{_bindir}/nova-sriov +%{_defaultdocdir}/%{name}-%{version} + +%files -n nova-utils-devel +%defattr(-,root,root,-) diff --git a/extended/nova-utils/nova-utils/LICENSE b/extended/nova-utils/nova-utils/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/extended/nova-utils/nova-utils/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/extended/nova-utils/nova-utils/nova-sriov b/extended/nova-utils/nova-utils/nova-sriov new file mode 100755 index 000000000..efdf74efb --- /dev/null +++ b/extended/nova-utils/nova-utils/nova-sriov @@ -0,0 +1,117 @@ +#! /usr/bin/python + +# +# Copyright (c) 2015 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import sys +import os +import json +import fnmatch + + +def usage(): + argv0 = os.path.basename(sys.argv[0]) + print """ +Usage: +------ + %(argv0)s pci_pt_whitelist pci_sriov_whitelist + +Where pci_pt_whitelist is a list of passthrough devices and the +pci_sriov_whitelist is a list of SR-IOV interfaces. The format of the lists +are as follows: + + pci_pt_whitelist: + [{"address": "0000:09:00.0"}, ..] + + pci_sriov_whitelist: + [{"sriov_numvfs": 16, "physical_network": "group0-nic0", + "address": "0000:02:00.0"}, ..] + + """ % locals() # replace items from local variables + + +def get_vf_whitelist(sriov_if): + '''For the given PF PCI address and provider network, generate the list of VF + PCI addresses to create a VF based whitelist''' + + pf_addr = sriov_if.get('address') + dirpcidev = '/sys/bus/pci/devices/' + pf_addr + + # Attempt to configure the requested number of VFs if the device supports + # setting the number of VFs via sysfs + # Need to write 0 to sriov_numvfs before writing a new value. + numvfs = sriov_if.get('sriov_numvfs') + if numvfs is not None: + numvfs_path = os.path.join(dirpcidev, 'sriov_numvfs') + if os.path.isfile(numvfs_path): + with open(numvfs_path, 'w') as f: + f.write('0') + f.flush() + f.write(str(numvfs)) + + virtfn_links = len(fnmatch.filter(os.listdir(dirpcidev), 'virtfn*')) + + # Some devices (for e.g. Coleto Creek) don't support configuration of the + # number of VFs. Use all the VFs present in this case. + if numvfs is not None: + if virtfn_links != numvfs: + print 'Configured number of VFs is different than the present ones', \ + '(if:%s conf:%d present:%d)' % (pf_addr, numvfs, virtfn_links) + exit(1) + else: + numvfs = virtfn_links + + pci_sriov_vf_whitelist = [] + i = 0 + while i < int(numvfs): + lvf = dirpcidev + '/virtfn' + str(i) + try: + vf_addr = os.path.basename(os.readlink(lvf)) + except: + print("virtfn link %s non-existent (numvfs=%s)" % (lvf, numvfs)) + sys.exit(1) + + device = {'address': vf_addr} + + # Some devices (for e.g. Coleto Creek) are not associated with a + # physical network. + providernets = sriov_if.get('physical_network') + if providernets: + device.update({'physical_network': providernets}) + + pci_sriov_vf_whitelist.append(device) + i += 1 + + return pci_sriov_vf_whitelist + + +def main(): + ''' The goal of this script is to properly discover SR-IOV VF PCI addresses + for interfaces that were configured for SR-IOV. It is used by the + nova-compute puppet manifest and is run at manifest application time. This + script should be run after the VF driver is loaded and the VF PCI addresses + are visible in the system.''' + + if len(sys.argv) < 3: + usage() + sys.exit(1) + + try: + pci_pt_whitelist = json.loads(sys.argv[1]) + pci_sriov_whitelist = json.loads(sys.argv[2]) + except: + usage() + exit(1) + + for sriov_if in pci_sriov_whitelist: + pci_sriov_vf_whitelist = get_vf_whitelist(sriov_if) + pci_pt_whitelist.extend(pci_sriov_vf_whitelist) + + return pci_pt_whitelist + + +if __name__ == "__main__": + print json.dumps(main()) diff --git a/extended/novnc/centos/build_srpm.data b/extended/novnc/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/extended/novnc/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/extended/novnc/centos/meta_patches/0001-Update-package-0.6.2-versioning-for-TIS-format.patch b/extended/novnc/centos/meta_patches/0001-Update-package-0.6.2-versioning-for-TIS-format.patch new file mode 100644 index 000000000..062bfe822 --- /dev/null +++ b/extended/novnc/centos/meta_patches/0001-Update-package-0.6.2-versioning-for-TIS-format.patch @@ -0,0 +1,12 @@ +diff --git a/SPECS/novnc.spec b/SPECS/novnc.spec +index a43f435..640bf1f 100644 +--- a/SPECS/novnc.spec ++++ b/SPECS/novnc.spec +@@ -1,6 +1,6 @@ + Name: novnc + Version: 0.6.2 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: VNC client using HTML5 (Web Sockets, Canvas) with encryption support + Requires: python-websockify + diff --git a/extended/novnc/centos/meta_patches/PATCH_ORDER b/extended/novnc/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..0eca01bae --- /dev/null +++ b/extended/novnc/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Update-package-0.6.2-versioning-for-TIS-format.patch diff --git a/extended/novnc/centos/srpm_path b/extended/novnc/centos/srpm_path new file mode 100644 index 000000000..d59f7598d --- /dev/null +++ b/extended/novnc/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/novnc-0.6.2-1.el7.src.rpm diff --git a/extended/ntp/centos/build_srpm.data b/extended/ntp/centos/build_srpm.data new file mode 100644 index 000000000..d3f64f336 --- /dev/null +++ b/extended/ntp/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=3 diff --git a/extended/ntp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/ntp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..730d710b9 --- /dev/null +++ b/extended/ntp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From af36b0f028b07a6487e57040bb6c980ff6a4a41c Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:29:01 -0400 +Subject: [PATCH 3/3] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/ntp.spec +--- + SPECS/ntp.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/ntp.spec b/SPECS/ntp.spec +index f717899..454020c 100644 +--- a/SPECS/ntp.spec ++++ b/SPECS/ntp.spec +@@ -1,7 +1,7 @@ + Summary: The NTP daemon and utilities + Name: ntp + Version: 4.2.6p5 +-Release: 25%{?dist}.2 ++Release: 25.el7.centos.2%{?_tis_dist}.%{tis_patch_ver} + # primary license (COPYRIGHT) : MIT + # ElectricFence/ (not used) : GPLv2 + # kernel/sys/ppsclock.h (not used) : BSD with advertising +-- +1.9.1 + diff --git a/extended/ntp/centos/meta_patches/PATCH_ORDER b/extended/ntp/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..63be2d8b3 --- /dev/null +++ b/extended/ntp/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +ntp-spec-add-TiS-custom-config-files.patch +ntpd-started-no-g-option.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/extended/ntp/centos/meta_patches/ntp-spec-add-TiS-custom-config-files.patch b/extended/ntp/centos/meta_patches/ntp-spec-add-TiS-custom-config-files.patch new file mode 100644 index 000000000..1f40b4067 --- /dev/null +++ b/extended/ntp/centos/meta_patches/ntp-spec-add-TiS-custom-config-files.patch @@ -0,0 +1,32 @@ +From d66f217c9b90889aa7add35ed1562a4b50a7fd7a Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:29:00 -0400 +Subject: [PATCH 1/3] WRS: ntp-spec-add-TiS-custom-config-files.patch + +--- + SPECS/ntp.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/ntp.spec b/SPECS/ntp.spec +index b9aaabd..f717899 100644 +--- a/SPECS/ntp.spec ++++ b/SPECS/ntp.spec +@@ -46,6 +46,7 @@ Source13: ntpdate.service + Source14: ntp-wait.service + Source15: sntp.service + Source16: sntp.sysconfig ++Source17: ntp-cgcs.conf + + # ntpbz #802 + Patch1: ntp-4.2.6p1-sleep.patch +@@ -444,6 +445,7 @@ sed -e 's|VENDORZONE\.|%{vendorzone}|' \ + touch -r %{SOURCE16} .%{_sysconfdir}/sysconfig/sntp + install -p -m600 %{SOURCE8} .%{_sysconfdir}/ntp/crypto/pw + install -p -m755 %{SOURCE10} .%{_sysconfdir}/dhcp/dhclient.d/ntp.sh ++install -p -m644 %{SOURCE17} .%{_sysconfdir}/ntp.conf + install -p -m644 %{SOURCE12} .%{_unitdir}/ntpd.service + install -p -m644 %{SOURCE13} .%{_unitdir}/ntpdate.service + install -p -m644 %{SOURCE14} .%{_unitdir}/ntp-wait.service +-- +1.9.1 + diff --git a/extended/ntp/centos/meta_patches/ntpd-started-no-g-option.patch b/extended/ntp/centos/meta_patches/ntpd-started-no-g-option.patch new file mode 100644 index 000000000..2ecc47b67 --- /dev/null +++ b/extended/ntp/centos/meta_patches/ntpd-started-no-g-option.patch @@ -0,0 +1,20 @@ +From 20b00ae04480db94b1bb93ddc2cdbbf5cbafd001 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:29:01 -0400 +Subject: [PATCH 2/3] WRS: ntpd-started-no-g-option.patch + +--- + SOURCES/ntpd.sysconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SOURCES/ntpd.sysconfig b/SOURCES/ntpd.sysconfig +index 49394c7..c783890 100644 +--- a/SOURCES/ntpd.sysconfig ++++ b/SOURCES/ntpd.sysconfig +@@ -1,2 +1,2 @@ + # Command line options for ntpd +-OPTIONS="-g" ++OPTIONS="-p /var/run/ntp.pid" +-- +1.9.1 + diff --git a/extended/ntp/centos/patches/ntp-cgcs.conf b/extended/ntp/centos/patches/ntp-cgcs.conf new file mode 100644 index 000000000..991f836d1 --- /dev/null +++ b/extended/ntp/centos/patches/ntp-cgcs.conf @@ -0,0 +1,14 @@ +# This is the most basic ntp configuration file +# The driftfile must remain in a place specific to this +# machine - it records the machine specific clock error +#driftfile /etc/ntp.drift +# This obtains a random server which will be close +# (in IP terms) to the machine. Add other servers +# as required, or change this. +#server time.server.example.com +# Using local hardware clock as fallback +# Disable this when using ntpd -q -g -x as ntpdate or it will sync to itself +#server 127.127.1.0 +#fudge 127.127.1.0 stratum 14 +# Defining a default security setting - lock everything down +restrict default ignore diff --git a/extended/ntp/centos/srpm_path b/extended/ntp/centos/srpm_path new file mode 100644 index 000000000..1c743b4da --- /dev/null +++ b/extended/ntp/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/ntp-4.2.6p5-25.el7.centos.2.src.rpm diff --git a/extended/ntp/ntp-4.2.6p5/ntp-cgcs.conf b/extended/ntp/ntp-4.2.6p5/ntp-cgcs.conf new file mode 100644 index 000000000..991f836d1 --- /dev/null +++ b/extended/ntp/ntp-4.2.6p5/ntp-cgcs.conf @@ -0,0 +1,14 @@ +# This is the most basic ntp configuration file +# The driftfile must remain in a place specific to this +# machine - it records the machine specific clock error +#driftfile /etc/ntp.drift +# This obtains a random server which will be close +# (in IP terms) to the machine. Add other servers +# as required, or change this. +#server time.server.example.com +# Using local hardware clock as fallback +# Disable this when using ntpd -q -g -x as ntpdate or it will sync to itself +#server 127.127.1.0 +#fudge 127.127.1.0 stratum 14 +# Defining a default security setting - lock everything down +restrict default ignore diff --git a/extended/ntp/ntp-4.2.6p5/ntpd b/extended/ntp/ntp-4.2.6p5/ntpd new file mode 100755 index 000000000..7c9b423fb --- /dev/null +++ b/extended/ntp/ntp-4.2.6p5/ntpd @@ -0,0 +1,108 @@ +#! /bin/sh +# +# ntpd init.d script for ntpdc from ntp.isc.org +#chkconfig: 2345 20 20 + +# Source function library. +. /etc/init.d/functions + +test -x /usr/sbin/ntpd -a -r /etc/ntp.conf || exit 0 +# rcS contains TICKADJ +test -r /etc/default/rcS && . /etc/default/rcS + +# Functions to do individual actions +settick(){ + # If TICKADJ is set we *must* adjust it before we start, because the + # driftfile relies on the correct setting + test -n "$TICKADJ" -a -x /usr/sbin/tickadj && { + echo -n "Setting tick to $TICKADJ: " + /usr/sbin/tickadj "$TICKADJ" + echo "done" + } +} +startdaemon(){ + # Perform initial ntp time correction + if [ -e /etc/ntp_initial.conf ] + then + echo -n "Performing initial ntp time correction: " + # ntpd -q hangs forever if it can't reach a server, so the timeout + # command is used to avoid this + /usr/bin/timeout 60s /usr/sbin/ntpd -q -g -c /etc/ntp_initial.conf + rc=$? + if [[ $rc == 0 ]] + then + echo "done" + # Time correction successful. Set hardware clock. + echo -n "Setting hardware clock: " + /sbin/hwclock -wu + if [[ $? == 0 ]] + then + echo "done" + else + echo "failed" + fi + else + echo "fail - hardware clock used to set system time" + fi + fi + + # We do not use the -g option to start the ntpd. That allows the ntpd to + # make large time corrections. Although the man page says this will be + # done only once, testing indicates it can happen multiple times or + # happen long after the daemon starts, which can break services that + # are already running at that time. + echo -n "Starting ntpd: " + /sbin/start-stop-daemon --start -x /usr/sbin/ntpd -- -u ntp:ntp -p /var/run/ntp.pid "$@" + echo "done" +} +stopdaemon(){ + echo -n "Stopping ntpd: " + /sbin/start-stop-daemon --stop -p /var/run/ntp.pid + echo "done" + + # Set the hardware clock on shutdown so the clock will be as accurate as possible + # when the system comes back up. + echo -n "Setting hardware clock: " + /sbin/hwclock -wu + if [[ $? == 0 ]] + then + echo "done" + else + echo "failed" + fi +} + +case "$1" in + start) + settick + startdaemon + ;; + stop) + stopdaemon + ;; + status) + status /usr/sbin/ntpd; + exit $? + ;; + force-reload) + stopdaemon + settick + startdaemon + ;; + restart) + # Don't reset the tick here + stopdaemon + startdaemon + ;; + reload) + # Must do this by hand, but don't do -g + stopdaemon + startdaemon + ;; + *) + echo "Usage: ntpd { start | stop | status | restart | reload }" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/extended/ntp/ntp-4.2.8p6/ntp-cgcs.conf b/extended/ntp/ntp-4.2.8p6/ntp-cgcs.conf new file mode 100644 index 000000000..60e18c7e1 --- /dev/null +++ b/extended/ntp/ntp-4.2.8p6/ntp-cgcs.conf @@ -0,0 +1,14 @@ +# This is the most basic ntp configuration file +# The driftfile must remain in a place specific to this +# machine - it records the machine specific clock error +#driftfile /etc/ntp.drift +# This obtains a random server which will be close +# (in IP terms) to the machine. Add other servers +# as required, or change this. +#server time.server.example.com +# Using local hardware clock as fallback +# Disable this when using ntpd -q -g -x as ntpdate or it will sync to itself +#server 127.127.1.0 +#fudge 127.127.1.0 stratum 14 +# Defining a default security setting +restrict default diff --git a/extended/ntp/ntp-4.2.8p6/ntpd b/extended/ntp/ntp-4.2.8p6/ntpd new file mode 100755 index 000000000..7c9b423fb --- /dev/null +++ b/extended/ntp/ntp-4.2.8p6/ntpd @@ -0,0 +1,108 @@ +#! /bin/sh +# +# ntpd init.d script for ntpdc from ntp.isc.org +#chkconfig: 2345 20 20 + +# Source function library. +. /etc/init.d/functions + +test -x /usr/sbin/ntpd -a -r /etc/ntp.conf || exit 0 +# rcS contains TICKADJ +test -r /etc/default/rcS && . /etc/default/rcS + +# Functions to do individual actions +settick(){ + # If TICKADJ is set we *must* adjust it before we start, because the + # driftfile relies on the correct setting + test -n "$TICKADJ" -a -x /usr/sbin/tickadj && { + echo -n "Setting tick to $TICKADJ: " + /usr/sbin/tickadj "$TICKADJ" + echo "done" + } +} +startdaemon(){ + # Perform initial ntp time correction + if [ -e /etc/ntp_initial.conf ] + then + echo -n "Performing initial ntp time correction: " + # ntpd -q hangs forever if it can't reach a server, so the timeout + # command is used to avoid this + /usr/bin/timeout 60s /usr/sbin/ntpd -q -g -c /etc/ntp_initial.conf + rc=$? + if [[ $rc == 0 ]] + then + echo "done" + # Time correction successful. Set hardware clock. + echo -n "Setting hardware clock: " + /sbin/hwclock -wu + if [[ $? == 0 ]] + then + echo "done" + else + echo "failed" + fi + else + echo "fail - hardware clock used to set system time" + fi + fi + + # We do not use the -g option to start the ntpd. That allows the ntpd to + # make large time corrections. Although the man page says this will be + # done only once, testing indicates it can happen multiple times or + # happen long after the daemon starts, which can break services that + # are already running at that time. + echo -n "Starting ntpd: " + /sbin/start-stop-daemon --start -x /usr/sbin/ntpd -- -u ntp:ntp -p /var/run/ntp.pid "$@" + echo "done" +} +stopdaemon(){ + echo -n "Stopping ntpd: " + /sbin/start-stop-daemon --stop -p /var/run/ntp.pid + echo "done" + + # Set the hardware clock on shutdown so the clock will be as accurate as possible + # when the system comes back up. + echo -n "Setting hardware clock: " + /sbin/hwclock -wu + if [[ $? == 0 ]] + then + echo "done" + else + echo "failed" + fi +} + +case "$1" in + start) + settick + startdaemon + ;; + stop) + stopdaemon + ;; + status) + status /usr/sbin/ntpd; + exit $? + ;; + force-reload) + stopdaemon + settick + startdaemon + ;; + restart) + # Don't reset the tick here + stopdaemon + startdaemon + ;; + reload) + # Must do this by hand, but don't do -g + stopdaemon + startdaemon + ;; + *) + echo "Usage: ntpd { start | stop | status | restart | reload }" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/extended/pam/centos/build_srpm.data b/extended/pam/centos/build_srpm.data new file mode 100644 index 000000000..292b4a13f --- /dev/null +++ b/extended/pam/centos/build_srpm.data @@ -0,0 +1,3 @@ +COPY_LIST="files/pam.d/*" +TIS_PATCH_VER=4 +BUILD_IS_SLOW=8 diff --git a/extended/pam/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/pam/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..c6ed12bed --- /dev/null +++ b/extended/pam/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From df02d7127b6feba73728380493033f5b212faab7 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 27 Sep 2016 10:49:05 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/pam.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/pam.spec b/SPECS/pam.spec +index a702aca..dabbeee 100644 +--- a/SPECS/pam.spec ++++ b/SPECS/pam.spec +@@ -3,7 +3,7 @@ + Summary: An extensible library which provides authentication for applications + Name: pam + Version: 1.1.8 +-Release: 18%{?dist} ++Release: 18.el7%{?_tis_dist}.%{tis_patch_ver} + # The library is BSD licensed with option to relicense as GPLv2+ + # - this option is redundant as the BSD license allows that anyway. + # pam_timestamp, pam_loginuid, and pam_console modules are GPLv2+. +-- +1.8.3.1 + diff --git a/extended/pam/centos/meta_patches/PATCH_ORDER b/extended/pam/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..8150a5543 --- /dev/null +++ b/extended/pam/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +pam-spec-add-custome-config-files.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/extended/pam/centos/meta_patches/pam-spec-add-custome-config-files.patch b/extended/pam/centos/meta_patches/pam-spec-add-custome-config-files.patch new file mode 100644 index 000000000..fbc87f49c --- /dev/null +++ b/extended/pam/centos/meta_patches/pam-spec-add-custome-config-files.patch @@ -0,0 +1,47 @@ +--- + SPECS/pam.spec | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/SPECS/pam.spec b/SPECS/pam.spec +index 0cbf153..a702aca 100644 +--- a/SPECS/pam.spec ++++ b/SPECS/pam.spec +@@ -27,6 +27,11 @@ Source14: 20-nproc.conf + Source15: pamtmp.conf + Source16: postlogin.pamd + Source17: postlogin.5 ++Source18: common-account ++Source19: common-auth ++Source20: common-password ++Source21: common-session ++Source22: common-session-noninteractive + Patch1: pam-1.0.90-redhat-modules.patch + Patch2: pam-1.1.6-std-noclose.patch + Patch4: pam-1.1.0-console-nochmod.patch +@@ -207,6 +212,11 @@ install -m 644 %{SOURCE8} $RPM_BUILD_ROOT%{_pamconfdir}/fingerprint-auth + install -m 644 %{SOURCE9} $RPM_BUILD_ROOT%{_pamconfdir}/smartcard-auth + install -m 644 %{SOURCE10} $RPM_BUILD_ROOT%{_pamconfdir}/config-util + install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_pamconfdir}/postlogin ++install -m 644 %{SOURCE18} $RPM_BUILD_ROOT%{_pamconfdir}/common-account ++install -m 644 %{SOURCE19} $RPM_BUILD_ROOT%{_pamconfdir}/common-auth ++install -m 644 %{SOURCE20} $RPM_BUILD_ROOT%{_pamconfdir}/common-password ++install -m 644 %{SOURCE21} $RPM_BUILD_ROOT%{_pamconfdir}/common-session ++install -m 644 %{SOURCE22} $RPM_BUILD_ROOT%{_pamconfdir}/common-session-noninteractive + install -m 644 %{SOURCE14} $RPM_BUILD_ROOT%{_secconfdir}/limits.d/20-nproc.conf + install -m 600 /dev/null $RPM_BUILD_ROOT%{_secconfdir}/opasswd + install -d -m 755 $RPM_BUILD_ROOT/var/log +@@ -297,6 +307,11 @@ fi + %config(noreplace) %{_pamconfdir}/smartcard-auth + %config(noreplace) %{_pamconfdir}/config-util + %config(noreplace) %{_pamconfdir}/postlogin ++%config(noreplace) %{_pamconfdir}/common-account ++%config(noreplace) %{_pamconfdir}/common-auth ++%config(noreplace) %{_pamconfdir}/common-password ++%config(noreplace) %{_pamconfdir}/common-session ++%config(noreplace) %{_pamconfdir}/common-session-noninteractive + %doc Copyright + %doc doc/txts + %doc doc/sag/*.txt doc/sag/html +-- +1.8.3.1 + diff --git a/extended/pam/centos/srpm_path b/extended/pam/centos/srpm_path new file mode 100644 index 000000000..8e1098c0b --- /dev/null +++ b/extended/pam/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/pam-1.1.8-18.el7.src.rpm diff --git a/extended/pam/files/pam.d/common-account b/extended/pam/files/pam.d/common-account new file mode 100755 index 000000000..46c86d061 --- /dev/null +++ b/extended/pam/files/pam.d/common-account @@ -0,0 +1,27 @@ +# +# /etc/pam.d/common-account - authorization settings common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of the authorization modules that define +# the central access policy for use on the system. The default is to +# only deny service to users whose accounts are expired in /etc/shadow. +# +# As of pam 1.0.1-6, this file is managed by pam-auth-update by default. +# To take advantage of this, it is recommended that you configure any +# local modules either before or after the default block, and use +# pam-auth-update to manage selection of other modules. See +# pam-auth-update(8) for details. +# + +# here are the per-package modules (the "Primary" block) +account required pam_tally2.so +account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so +account [success=1 new_authtok_reqd=done default=ignore] pam_ldap.so +# here's the fallback if no module succeeds +account requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +account required pam_permit.so +# and here are more per-package modules (the "Additional" block) +# end of pam-auth-update config diff --git a/extended/pam/files/pam.d/common-auth b/extended/pam/files/pam.d/common-auth new file mode 100755 index 000000000..b0990fcc9 --- /dev/null +++ b/extended/pam/files/pam.d/common-auth @@ -0,0 +1,22 @@ +# +# /etc/pam.d/common-auth - authentication settings common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of the authentication modules that define +# the central authentication scheme for use on the system +# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the +# traditional Unix authentication mechanisms. + +# here are the per-package modules (the "Primary" block) +# auth [success=1 default=ignore] pam_unix.so nullok_secure +# auth sufficient pam_ldap.so use_first_pass +auth required pam_tally2.so deny=5 unlock_time=300 audit +auth [success=2 default=ignore] pam_unix.so nullok_secure +auth [success=1 default=ignore] pam_ldap.so use_first_pass debug +# here's the fallback if no module succeeds +auth requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +auth required pam_permit.so +# and here are more per-package modules (the "Additional" block) diff --git a/extended/pam/files/pam.d/common-password b/extended/pam/files/pam.d/common-password new file mode 100755 index 000000000..cfb100fd8 --- /dev/null +++ b/extended/pam/files/pam.d/common-password @@ -0,0 +1,38 @@ +# +# /etc/pam.d/common-password - password-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define the services to be +# used to change user passwords. The default is pam_unix. + +# Explanation of pam_unix options: +# +# The "sha512" option enables salted SHA512 passwords. Without this option, +# the default is Unix crypt. Prior releases used the option "md5". +# +# The "obscure" option replaces the old `OBSCURE_CHECKS_ENAB' option in +# login.defs. +# +# See the pam_unix manpage for other options. + +# here are the per-package modules (the "Primary" block) + +################## Titanium Cloud Password Rules ####################### +## Enforce a password containing atleast 1 lower case, 1 upper case, # +## 1 digit and 1 special character. Such a password will have a # +## minimum length of 7 characters. A user may not re-use the last most # +## recent password and every password must differ from its previous # +## one by atleast 3 characters # +## - Added enforce_for_root for pam_pwquality.so # +######################################################################## + +password required pam_pwquality.so try_first_pass retry=3 authtok_type= difok=3 minlen=7 lcredit=-1 ucredit=-1 ocredit=-1 dcredit=-1 enforce_for_root debug +password required pam_pwhistory.so use_authtok enforce_for_root remember=2 retry=3 debug + +password sufficient pam_unix.so sha512 use_authtok debug +password [success=done authtok_err=die perm_denied=die default=ignore] pam_ldap.so use_authtok debug + + + +# If we got this far then its clearly a DENY +password requisite pam_deny.so diff --git a/extended/pam/files/pam.d/common-session b/extended/pam/files/pam.d/common-session new file mode 100755 index 000000000..9ce31c485 --- /dev/null +++ b/extended/pam/files/pam.d/common-session @@ -0,0 +1,21 @@ +# +# /etc/pam.d/common-session - session-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define tasks to be performed +# at the start and end of sessions of *any* kind (both interactive and +# non-interactive). +# + +# here are the per-package modules (the "Primary" block) +session [default=1] pam_permit.so +# here's the fallback if no module succeeds +session requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +session required pam_permit.so +# and here are more per-package modules (the "Additional" block) +session [success=1 new_authtok_reqd=done default=ignore] pam_unix.so +session [success=ok new_authtok_reqd=done default=bad] pam_ldap.so +session required pam_mkhomedir.so umask=0022 skel=/etc/skel diff --git a/extended/pam/files/pam.d/common-session-noninteractive b/extended/pam/files/pam.d/common-session-noninteractive new file mode 100755 index 000000000..239055e57 --- /dev/null +++ b/extended/pam/files/pam.d/common-session-noninteractive @@ -0,0 +1,20 @@ +# +# /etc/pam.d/common-session-noninteractive - session-related modules +# common to all non-interactive services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define tasks to be performed +# at the start and end of all non-interactive sessions. +# + +# here are the per-package modules (the "Primary" block) +session [default=1] pam_permit.so +# here's the fallback if no module succeeds +session requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +session required pam_permit.so +# and here are more per-package modules (the "Additional" block) +session [success=1 new_authtok_reqd=done default=ignore] pam_unix.so +session [success=ok new_authtok_reqd=done default=bad] pam_ldap.so diff --git a/extended/pam/files/pam.d/system-auth.pamd b/extended/pam/files/pam.d/system-auth.pamd new file mode 100755 index 000000000..25f609ec8 --- /dev/null +++ b/extended/pam/files/pam.d/system-auth.pamd @@ -0,0 +1,31 @@ +#%PAM-1.0 +auth required pam_env.so +auth sufficient pam_unix.so nullok try_first_pass +auth requisite pam_succeed_if.so uid >= 1000 quiet_success +auth required pam_deny.so + +account required pam_unix.so +account sufficient pam_localuser.so +account sufficient pam_succeed_if.so uid < 1000 quiet +account required pam_permit.so + +################# Titanium Cloud Password Rules ####################### +# Enforce a password containing atleast 1 lower case, 1 upper case, # +# 1 digit and 1 special character. Such a password will have a # +# minimum length of 7 characters. A user may not re-use the last most # +# recent password and every password must differ from its previous # +# one by atleast 3 characters # +# - Added enforce_for_root for pam_pwquality.so # +####################################################################### + +password requisite pam_pwquality.so try_first_pass retry=3 authtok_type= difok=3 minlen=7 lcredit=-1 ucredit=-1 ocredit=-1 dcredit=-1 enforce_for_root debug +password requisite pam_pwhistory.so use_authtok enforce_for_root remember=2 + +password [success=2 default=ignore] pam_unix.so sha512 shadow nullok try_first_pass use_authtok +password [success=1 default=ignore] pam_ldap.so use_authtok + +session optional pam_keyinit.so revoke +session required pam_limits.so +-session optional pam_systemd.so +session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid +session required pam_unix.so diff --git a/extended/procps/files/sysctl.conf b/extended/procps/files/sysctl.conf new file mode 100644 index 000000000..eee0bd77a --- /dev/null +++ b/extended/procps/files/sysctl.conf @@ -0,0 +1,86 @@ +# This configuration file is taken from Debian. +# +# /etc/sysctl.conf - Configuration file for setting system variables +# See sysctl.conf (5) for information. +# + +#kernel.domainname = example.com + +# Uncomment the following to stop low-level messages on console +kernel.printk = 4 4 1 7 + +# Reboot X seconds after a kernel panic +kernel.panic = 5 + +##############################################################3 +# Functions previously found in netbase +# + +# Uncomment the next two lines to enable Spoof protection (reverse-path filter) +# Turn on Source Address Verification in all interfaces to +# prevent some spoofing attacks +net.ipv4.conf.default.rp_filter=1 +net.ipv4.conf.all.rp_filter=1 + +# Uncomment the next line to enable TCP/IP SYN cookies +#net.ipv4.tcp_syncookies=1 + +# Uncomment the next line to enable packet forwarding for IPv4 +#net.ipv4.ip_forward=1 + +# Uncomment the next line to enable packet forwarding for IPv6 +#net.ipv6.conf.all.forwarding=1 + + +################################################################### +# Additional settings - these settings can improve the network +# security of the host and prevent against some network attacks +# including spoofing attacks and man in the middle attacks through +# redirection. Some network environments, however, require that these +# settings are disabled so review and enable them as needed. +# +# Ignore ICMP broadcasts +#net.ipv4.icmp_echo_ignore_broadcasts = 1 +# +# Ignore bogus ICMP errors +#net.ipv4.icmp_ignore_bogus_error_responses = 1 +# +# Do not accept ICMP redirects (prevent MITM attacks) +#net.ipv4.conf.all.accept_redirects = 0 +#net.ipv6.conf.all.accept_redirects = 0 +# _or_ +# Accept ICMP redirects only for gateways listed in our default +# gateway list (enabled by default) +# net.ipv4.conf.all.secure_redirects = 1 +# +# Do not send ICMP redirects (we are not a router) +#net.ipv4.conf.all.send_redirects = 0 +# +# Do not accept IP source route packets (we are not a router) +#net.ipv4.conf.all.accept_source_route = 0 +#net.ipv6.conf.all.accept_source_route = 0 +# +# Log Martian Packets +#net.ipv4.conf.all.log_martians = 1 +# + +#kernel.shmmax = 141762560 + +# Limit local port range +net.ipv4.ip_local_port_range = 49216 61000 +net.ipv4.tcp_tw_reuse = 1 + +# WRL +# set max socket memory ; default was 212992 +net.core.rmem_max=425984 + +# WRS +# The following kernel parameters help alleviate some RabbitMQ +# connection issues. These values need to be set here to ensure sysinv-agent +# remains connected to rabbitmq. Sysinv-agent starts before packstack and the +# long default values allowed the connection to be lost for 2 hours. +# Note the ipv4 vlaues are also applied to ipv6 connections. +net.ipv4.tcp_keepalive_intvl = 1 +net.ipv4.tcp_keepalive_probes = 5 +net.ipv4.tcp_keepalive_time = 5 + diff --git a/extended/python-cephclient/centos/build_srpm.data b/extended/python-cephclient/centos/build_srpm.data new file mode 100644 index 000000000..42cbb465b --- /dev/null +++ b/extended/python-cephclient/centos/build_srpm.data @@ -0,0 +1,6 @@ +CLIENT_NAME=python-cephclient +CLIENT_VER=v0.1.0.5 + +COPY_LIST="$CGCS_BASE/downloads/$CLIENT_NAME-$CLIENT_VER.tar.gz $PKG_BASE/$CLIENT_NAME/*" + +TIS_PATCH_VER=2 diff --git a/extended/python-cephclient/centos/python-cephclient.spec b/extended/python-cephclient/centos/python-cephclient.spec new file mode 100644 index 000000000..9c1cd22bf --- /dev/null +++ b/extended/python-cephclient/centos/python-cephclient.spec @@ -0,0 +1,56 @@ +%{!?_licensedir:%global license %%doc} +%global pypi_name python-cephclient + +Name: python-cephclient +Version: 0.1.0.5 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: python-cephclient + +License: Apache-2.0 +URL: https://github.com/dmsimard/python-cephclient +Group: devel/python +Packager: Wind River + +Source0: %{pypi_name}-v%{version}.tar.gz + +Patch0: fix-osd-crush-remove.patch +Patch1: set-default-endpoint.patch +Patch2: 0001-US63903-Ceph-Rebase-Update-REST-API-to-0.94.2.patch +Patch3: add-osd-get-pool-quota.patch +Patch4: 0001-US70398-Ceph-Rebase-Update-REST-API-to-0.94.5.patch +Patch5: fix-osd-tier-add.patch +Patch6: US92424-Ceph-Rebase-Update-REST-API-to-10.2.4.patch + +BuildArch: noarch + +BuildRequires: python +BuildRequires: ceph + +Requires: python + +Provides: python-cephclient + +%description +Client library for the Ceph REST API + +%prep +%autosetup -p 1 -n %{pypi_name}-%{version} + +# Remove bundled egg-info +rm -rf %{pypi_name}.egg-info + +# Let RPM handle the dependencies +rm -f requirements.txt + +%build +%{__python2} setup.py build + +%install +%{__python2} setup.py install --skip-build --root %{buildroot} + +%files +%doc README.rst +%license LICENSE +%{python2_sitelib}/cephclient +%{python2_sitelib}/*.egg-info + diff --git a/extended/python-cephclient/python-cephclient/0001-US63903-Ceph-Rebase-Update-REST-API-to-0.94.2.patch b/extended/python-cephclient/python-cephclient/0001-US63903-Ceph-Rebase-Update-REST-API-to-0.94.2.patch new file mode 100644 index 000000000..d2fc9b65e --- /dev/null +++ b/extended/python-cephclient/python-cephclient/0001-US63903-Ceph-Rebase-Update-REST-API-to-0.94.2.patch @@ -0,0 +1,220 @@ +From 016ebffad6c953cf51c538cc8c45edf56e681515 Mon Sep 17 00:00:00 2001 +From: Robert Church +Date: Fri, 21 Aug 2015 13:05:18 -0500 +Subject: [PATCH] US63903: Ceph Rebase - Update REST API to 0.94.2 + +This updates the existing REST APIs to correspond to what in required by +Ceph 0.94.2 (Hammer LTS) +--- + cephclient/wrapper.py | 134 +++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 95 insertions(+), 39 deletions(-) + +diff --git a/cephclient/wrapper.py b/cephclient/wrapper.py +index 8f583a5..926eb7f 100644 +--- a/cephclient/wrapper.py ++++ b/cephclient/wrapper.py +@@ -335,8 +335,12 @@ class CephWrapper(client.CephClient): + def osd_crush_dump(self, **kwargs): + return self.get('osd/crush/dump', **kwargs) + +- def osd_crush_rule_dump(self, **kwargs): +- return self.get('osd/crush/rule/dump', **kwargs) ++ def osd_crush_rule_dump(self, name=None, **kwargs): ++ if name is not None: ++ return self.get('osd/crush/rule/dump?name={0}' ++ .format(name), **kwargs) ++ else: ++ return self.get('osd/crush/rule/dump', **kwargs) + + def osd_crush_rule_list(self, **kwargs): + return self.get('osd/crush/rule/list', **kwargs) +@@ -450,7 +454,7 @@ class CephWrapper(client.CephClient): + .format(name, args), **kwargs) + + def osd_crush_remove(self, name, ancestor=None, **kwargs): +- if ancestor: ++ if ancestor is not None: + return self.put('osd/crush/remove?name={0}&ancestor={1}' + .format(name, ancestor), **kwargs) + else: +@@ -462,29 +466,43 @@ class CephWrapper(client.CephClient): + .format(name, weight), **kwargs) + + def osd_crush_rm(self, name, ancestor, **kwargs): +- return self.put('osd/crush/rm?name={0}&ancestor={1}' +- .format(name, ancestor), **kwargs) ++ if ancestor is not None: ++ return self.put('osd/crush/rm?name={0}&ancestor={1}' ++ .format(name, ancestor), **kwargs) ++ else: ++ return self.put('osd/crush/rm?name={0}' ++ .format(name), **kwargs) + +- def osd_crush_rule_create_simple(self, name, root, type, **kwargs): +- return self.put( +- 'osd/crush/rule/create-simple?name={0}&root={1}&type={2}' +- .format(name, root, type), **kwargs) ++ def osd_crush_rule_create_simple(self, name, root, ++ type, mode=None, **kwargs): ++ if mode is not None: ++ return self.put( ++ 'osd/crush/rule/create-simple?name={0}&root={1}&type={2}' ++ '&mode={3}'.format(name, root, type, mode), **kwargs) ++ else: ++ return self.put( ++ 'osd/crush/rule/create-simple?name={0}&root={1}&type={2}' ++ .format(name, root, type), **kwargs) + + def osd_crush_rule_rm(self, name, **kwargs): + return self.put('osd/crush/rule/rm?name={0}' + .format(name), **kwargs) + +- def osd_crush_set(self, id, name, weight, args, **kwargs): ++ def osd_crush_set(self, id, weight, args, **kwargs): + return self.put('osd/crush/set?id={0}&weight={1}&args={2}' +- .format(id, name, weight, args), **kwargs) ++ .format(id, weight, args), **kwargs) + + def osd_crush_tunables(self, profile, **kwargs): + return self.put('osd/crush/tunables?profile={0}' + .format(profile), **kwargs) + +- def osd_crush_unlink(self, name, ancestor, **kwargs): +- return self.put('osd/crush/unlink?name={0}&ancestor={1}' +- .format(name, ancestor), **kwargs) ++ def osd_crush_unlink(self, name, ancestor=None, **kwargs): ++ if ancestor is not None: ++ return self.put('osd/crush/unlink?name={0}&ancestor={1}' ++ .format(name, ancestor), **kwargs) ++ else: ++ return self.put('osd/crush/unlink?name={0}' ++ .format(name), **kwargs) + + def osd_deep_scrub(self, who, **kwargs): + return self.put('osd/deep-scrub?who={0}' +@@ -498,22 +516,44 @@ class CephWrapper(client.CephClient): + return self.put('osd/in?ids={0}' + .format(ids), **kwargs) + +- def osd_lost(self, id, sure, **kwargs): +- return self.put('osd/lost?id={0}&sure={1}' +- .format(id, sure), **kwargs) ++ def osd_lost(self, id, sure=None, **kwargs): ++ if sure is not None: ++ return self.put('osd/lost?id={0}&sure={1}' ++ .format(id, sure), **kwargs) ++ else: ++ return self.put('osd/lost?id={0}' ++ .format(id), **kwargs) + + def osd_out(self, ids, **kwargs): + return self.put('osd/out?ids={0}' + .format(ids), **kwargs) + +- def osd_pool_create(self, pool, pg_num, pgp_num, properties, **kwargs): +- return self.put( +- 'osd/pool/create?pool={0}&pg_num={1}&pgp_num={2}&properties={3}' +- .format(pool, pg_num, pgp_num, properties), **kwargs) +- +- def osd_pool_delete(self, pool, sure, **kwargs): +- return self.put('osd/pool/delete?pool={0}&sure={1}' +- .format(pool, sure), **kwargs) ++ def osd_pool_create(self, pool, pg_num, pgp_num, pool_type=None, ++ erasure_code_profile=None, ruleset=None, ++ expected_num_objects=None, **kwargs): ++ request = [] ++ request.append('osd/pool/create?pool={0}&pg_num={1}&pgp_num={2}' ++ .format(pool, pg_num, pgp_num)) ++ if pool_type is not None: ++ request.append('&pool_type={0}'.format(pool_type)) ++ if erasure_code_profile is not None: ++ request.append('&erasure_code_profile={0}' ++ .format(erasure_code_profile)) ++ if ruleset is not None: ++ request.append('&ruleset={0}'.format(ruleset)) ++ if expected_num_objects is not None: ++ request.append('&expected_num_objects={0}' ++ .format(expected_num_objects)) ++ return self.put(''.join(request), **kwargs) ++ ++ def osd_pool_delete(self, pool, pool2=None, sure=None, **kwargs): ++ request = [] ++ request.append('osd/pool/delete?pool={0}'.format(pool)) ++ if pool2 is not None: ++ request.append('&pool2={0}'.format(pool2)) ++ if sure is not None: ++ request.append('&sure={0}'.format(sure)) ++ return self.put(''.join(request), **kwargs) + + def osd_pool_param(self, pool, var, **kwargs): + return self.put('osd/pool/get?pool={0}&var={1}' +@@ -531,13 +571,17 @@ class CephWrapper(client.CephClient): + return self.put('osd/pool/rmsnap?pool={0}&snap={1}' + .format(pool, snap), **kwargs) + +- def osd_set_pool_param(self, pool, var, **kwargs): +- return self.put('osd/pool/set?pool={0}&var={1}' +- .format(pool, var), **kwargs) ++ def osd_set_pool_param(self, pool, var, val, force=None, **kwargs): ++ if force is not None: ++ return self.put('osd/pool/set?pool={0}&var={1}&val={2}&force={3}' ++ .format(pool, var, val, force), **kwargs) ++ else: ++ return self.put('osd/pool/set?pool={0}&var={1}&val={2}' ++ .format(pool, var, val), **kwargs) + +- def osd_set_pool_quota(self, pool, field, **kwargs): +- return self.put('osd/pool/set-quota?pool={0}&field={1}' +- .format(pool, field), **kwargs) ++ def osd_set_pool_quota(self, pool, field, val, **kwargs): ++ return self.put('osd/pool/set-quota?pool={0}&field={1}&val={2}' ++ .format(pool, field, val), **kwargs) + + def osd_repair(self, pool, who, **kwargs): + return self.put('osd/repair?who={0}' +@@ -571,9 +615,14 @@ class CephWrapper(client.CephClient): + return self.put('osd/thrash?num_epochs={0}' + .format(num_epochs), **kwargs) + +- def osd_tier_add(self, pool, tierpool, **kwargs): +- return self.put('osd/tier/add?pool={0}&tierpool={1}' +- .format(pool, tierpool), **kwargs) ++ def osd_tier_add(self, pool, tierpool, force_notempty=None, **kwargs): ++ if force_notempty is not None: ++ return self.put('osd/tier/add?pool={0}&tierpool={1}' ++ '&force_notempty={2}' ++ .format(pool, tierpool, force_notempty), **kwargs) ++ else: ++ return self.put('osd/tier/add?pool={0}&tierpool={1}' ++ .format(pool, tierpool), **kwargs) + + def osd_tier_cachemode(self, pool, mode, **kwargs): + return self.put('osd/tier/cache-mode?pool={0}&mode={1}' +@@ -621,12 +670,19 @@ class CephWrapper(client.CephClient): + def pg_dump_pools_json(self, **kwargs): + return self.get('pg/dump_pools_json', **kwargs) + +- def pg_dump_stuck(self, stuckops=None, **kwargs): ++ def pg_dump_stuck(self, stuckops=None, threshold=None, **kwargs): ++ request = [] ++ request.append('pg/dump_stuck') + if stuckops is not None: +- return self.get('pg/dump_stuck?stuckops={0}' +- .format(stuckops), **kwargs) +- else: +- return self.get('pg/dump_stuck', **kwargs) ++ request.append('?stuckops={0}'.format(stuckops)) ++ if threshold is not None: ++ if stuckops is not None: ++ request.append('&') ++ else: ++ request.append('?') ++ request.append('threshold={0}'.format(threshold)) ++ ++ return self.get(''.join(request), **kwargs) + + def pg_getmap(self, **kwargs): + kwargs['supported_body_types'] = ['binary'] +-- +2.5.0 + diff --git a/extended/python-cephclient/python-cephclient/0001-US70398-Ceph-Rebase-Update-REST-API-to-0.94.5.patch b/extended/python-cephclient/python-cephclient/0001-US70398-Ceph-Rebase-Update-REST-API-to-0.94.5.patch new file mode 100644 index 000000000..15d010897 --- /dev/null +++ b/extended/python-cephclient/python-cephclient/0001-US70398-Ceph-Rebase-Update-REST-API-to-0.94.5.patch @@ -0,0 +1,475 @@ +From 2253242390ed6dfd1206ae2743ccab4c28437d13 Mon Sep 17 00:00:00 2001 +From: Robert Church +Date: Tue, 24 Nov 2015 20:37:39 -0600 +Subject: [PATCH] US70398: Ceph Rebase - Update REST API to 0.94.5 + +Add support for all APIs currently present in the Ceph REST API. This +provides a version 0.94.5 compliant client and include client calls that +were present previously but never added to the python-cephclient. +--- + cephclient/wrapper.py | 281 +++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 269 insertions(+), 12 deletions(-) + +diff --git a/cephclient/wrapper.py b/cephclient/wrapper.py +index 867b68b..871b53a 100644 +--- a/cephclient/wrapper.py ++++ b/cephclient/wrapper.py +@@ -58,6 +58,9 @@ class CephWrapper(client.CephClient): + def status(self, **kwargs): + return self.get('status', **kwargs) + ++ def version(self, **kwargs): ++ return self.get('version', **kwargs) ++ + ### + # root PUT calls + ### +@@ -83,6 +86,16 @@ class CephWrapper(client.CephClient): + def scrub(self, **kwargs): + return self.put('scrub', **kwargs) + ++ def sync(self, validate1=None, validate2=None, **kwargs): ++ request = [] ++ request.append('sync/force') ++ if validate1 is not None: ++ request.append('?validate1={0}'.format(validate1)) ++ if validate2 is not None: ++ request.append('validate2={0}'.format(validate2)) ++ ++ return self.put(''.join(request), **kwargs) ++ + def tell(self, target, args, **kwargs): + return self.put('tell?target={0}&args={1}' + .format(target, args), **kwargs) +@@ -191,6 +204,44 @@ class CephWrapper(client.CephClient): + return self.get('config-key/list', **kwargs) + + ### ++ # config-key PUT calls ++ ### ++ def config_key_del(self, key, **kwargs): ++ return self.put('config-key/del?key={0}' ++ .format(key), **kwargs) ++ ++ def config_key_put(self, key, val, **kwargs): ++ return self.put('config-key/put?key={0}&val={1}' ++ .format(key, val), **kwargs) ++ ++ ### ++ # fs GET calls ++ ### ++ def fs_ls(self, **kwargs): ++ return self.get('fs/ls', **kwargs) ++ ++ ### ++ # fs PUT calls ++ ### ++ def fs_new(self, fs_name, metadata, data, **kwargs): ++ return self.put('fs/new?fs_name={0}&metadata={1}&data={2}' ++ .format(fs_name, metadata, data), **kwargs) ++ ++ def fs_reset(self, fs_name, sure=None, **kwargs): ++ request = [] ++ request.append('fs/reset?fs_name={0}'.format(fs_name)) ++ if sure is not None: ++ request.append('&sure={0}'.format(sure)) ++ return self.put(''.join(request), **kwargs) ++ ++ def fs_rm(self, fs_name, sure=None, **kwargs): ++ request = [] ++ request.append('fs/rm?fs_name={0}'.format(fs_name)) ++ if sure is not None: ++ request.append('&sure={0}'.format(sure)) ++ return self.put(''.join(request), **kwargs) ++ ++ ### + # mds GET calls + ### + def mds_compat_show(self, **kwargs): +@@ -244,9 +295,13 @@ class CephWrapper(client.CephClient): + return self.put('mds/fail?who={0}' + .format(who), **kwargs) + +- def mds_newfs(self, metadata, data, sure, **kwargs): +- return self.put('mds/newfs?metadata={0}&data={1}&sure={2}' +- .format(metadata, data, sure), **kwargs) ++ def mds_newfs(self, metadata, data, sure=None, **kwargs): ++ if sure is not None: ++ return self.put('mds/newfs?metadata={0}&data={1}&sure={2}' ++ .format(metadata, data, sure), **kwargs) ++ else: ++ return self.put('mds/newfs?metadata={0}&data={1}' ++ .format(metadata, data), **kwargs) + + def mds_remove_data_pool(self, pool, **kwargs): + return self.put('mds/remove_data_pool?pool={0}' +@@ -260,11 +315,29 @@ class CephWrapper(client.CephClient): + return self.put('mds/rmfailed?who={0}' + .format(who), **kwargs) + +- def mds_set_allow_new_snaps(self, sure, **kwargs): +- """ +- mds/set?key=allow_new_snaps&sure= +- """ +- raise exceptions.FunctionNotImplemented() ++ def mds_set_max_file_size(self, val, confirm=None, **kwargs): ++ if confirm is not None: ++ return self.put('mds/set?var=max_file_size?val={0}&confirm={1}' ++ .format(val, confirm), **kwargs) ++ else: ++ return self.put('mds/set?var=max_file_size?val={0}' ++ .format(val), **kwargs) ++ ++ def mds_set_allow_new_snaps(self, val, confirm=None, **kwargs): ++ if confirm is not None: ++ return self.put('mds/set?var=allow_new_snaps?val={0}&confirm={1}' ++ .format(val, confirm), **kwargs) ++ else: ++ return self.put('mds/set?var=allow_new_snaps?val={0}' ++ .format(val), **kwargs) ++ ++ def mds_set_inline_data(self, val, confirm=None, **kwargs): ++ if confirm is not None: ++ return self.put('mds/set?var=inline_data?val={0}&confirm={1}' ++ .format(val, confirm), **kwargs) ++ else: ++ return self.put('mds/set?var=inline_data?val={0}' ++ .format(val), **kwargs) + + def mds_set_max_mds(self, maxmds, **kwargs): + return self.put('mds/set_max_mds?maxmds={0}' +@@ -332,6 +405,9 @@ class CephWrapper(client.CephClient): + def osd_blacklist_ls(self, **kwargs): + return self.get('osd/blacklist/ls', **kwargs) + ++ def osd_blocked_by(self, **kwargs): ++ return self.get('osd/blocked-by', **kwargs) ++ + def osd_crush_dump(self, **kwargs): + return self.get('osd/crush/dump', **kwargs) + +@@ -348,6 +424,19 @@ class CephWrapper(client.CephClient): + def osd_crush_rule_ls(self, **kwargs): + return self.get('osd/crush/rule/ls', **kwargs) + ++ def osd_crush_show_tunables(self, **kwargs): ++ return self.get('osd/crush/show-tunables', **kwargs) ++ ++ def osd_crush_tree(self, **kwargs): ++ return self.get('osd/crush/tree', **kwargs) ++ ++ def osd_df(self, output_method=None, **kwargs): ++ if output_method is not None: ++ return self.get('osd/df?output_method={0}' ++ .format(output_method), **kwargs) ++ else: ++ return self.get('osd/df', **kwargs) ++ + def osd_dump(self, epoch=None, **kwargs): + if epoch is not None: + return self.get('osd/dump?epoch={0}' +@@ -355,6 +444,13 @@ class CephWrapper(client.CephClient): + else: + return self.get('osd/dump', **kwargs) + ++ def osd_erasure_code_profile_get(self, name, **kwargs): ++ return self.get('osd/erasure-code-profile/get?name={0}' ++ .format(name), **kwargs) ++ ++ def osd_erasure_code_profile_ls(self, **kwargs): ++ return self.get('osd/erasure-code-profile/ls', **kwargs) ++ + def osd_find(self, id, **kwargs): + return self.get('osd/find?id={0}' + .format(id), **kwargs) +@@ -398,9 +494,17 @@ class CephWrapper(client.CephClient): + return self.get('osd/map?pool={0}&object={1}' + .format(pool, object), **kwargs) + ++ def osd_metadata(self, id, **kwargs): ++ return self.get('osd/metadata?id={0}' ++ .format(id), **kwargs) ++ + def osd_perf(self, **kwargs): + return self.get('osd/perf', **kwargs) + ++ def osd_get_pool_param(self, pool, var, **kwargs): ++ return self.get('osd/pool/get?pool={0}&var={1}' ++ .format(pool, var), **kwargs) ++ + def osd_pool_get(self, pool, var, **kwargs): + return self.get('osd/pool/get?pool={0}&var={1}' + .format(pool, var), **kwargs) +@@ -416,6 +520,13 @@ class CephWrapper(client.CephClient): + return self.get('osd/pool/get-quota?pool={0}' + .format(pool), **kwargs) + ++ def osd_pool_ls(self, detail=None, **kwargs): ++ if detail is not None: ++ return self.get('osd/pool/ls?detail={0}' ++ .format(detail), **kwargs) ++ else: ++ return self.get('osd/pool/ls', **kwargs) ++ + def osd_stat(self, **kwargs): + return self.get('osd/stat', **kwargs) + +@@ -449,6 +560,10 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/create-or-move?id={0}&weight={1}&args={2}' + .format(id, weight, args), **kwargs) + ++ def osd_crush_get_tunable(self, tunable, **kwargs): ++ return self.put('osd/crush/get-tunable?tunable={0}' ++ .format(tunable), **kwargs) ++ + def osd_crush_link(self, name, args, **kwargs): + return self.put('osd/crush/link?name={0}&args={2}' + .format(name, args), **kwargs) +@@ -465,10 +580,21 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/remove?name={0}' + .format(name), **kwargs) + ++ def osd_crush_rename_bucket(self, srcname, dstname, **kwargs): ++ return self.put('osd/crush/rename-bucket?srcname={0}&dstname={1}' ++ .format(srcname, dstname), **kwargs) ++ + def osd_crush_reweight(self, name, weight, **kwargs): + return self.put('osd/crush/reweight?name={0}&weight={1}' + .format(name, weight), **kwargs) + ++ def osd_crush_reweight_all(self, **kwargs): ++ return self.put('osd/crush/reweight-all', **kwargs) ++ ++ def osd_crush_reweight_subtree(self, name, weight, **kwargs): ++ return self.put('osd/crush/reweight-subtree?name={0}&weight={1}' ++ .format(name, weight), **kwargs) ++ + def osd_crush_rm(self, name, ancestor, **kwargs): + if ancestor is not None: + return self.put('osd/crush/rm?name={0}&ancestor={1}' +@@ -477,6 +603,11 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/rm?name={0}' + .format(name), **kwargs) + ++ def osd_crush_rule_create_erasure(self, name, profile, **kwargs): ++ return self.put( ++ 'osd/crush/rule/create-erasure?name={0}&profile={1}' ++ .format(name, profile), **kwargs) ++ + def osd_crush_rule_create_simple(self, name, root, + type, mode=None, **kwargs): + if mode is not None: +@@ -496,6 +627,10 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/set?id={0}&weight={1}&args={2}' + .format(id, weight, args), **kwargs) + ++ def osd_crush_set_tunable(self, tunable, value, **kwargs): ++ return self.put('osd/crush/set-tunable?tunable={0}&value={1}' ++ .format(tunable), **kwargs) ++ + def osd_crush_tunables(self, profile, **kwargs): + return self.put('osd/crush/tunables?profile={0}' + .format(profile), **kwargs) +@@ -516,6 +651,18 @@ class CephWrapper(client.CephClient): + return self.put('osd/down?ids={0}' + .format(ids), **kwargs) + ++ def osd_erasure_code_profile_rm(self, name, **kwargs): ++ return self.put('osd/erasure-code-profile/rm?name={0}' ++ .format(name), **kwargs) ++ ++ def osd_erasure_code_profile_set(self, name, profile=None, **kwargs): ++ if profile is not None: ++ return self.put('osd/erasure-code-profile/set?name={0}&profile={1}' ++ .format(name, profile), **kwargs) ++ else: ++ return self.put('osd/erasure-code-profile/set?name={0}' ++ .format(name), **kwargs) ++ + def osd_in(self, ids, **kwargs): + return self.put('osd/in?ids={0}' + .format(ids), **kwargs) +@@ -532,6 +679,17 @@ class CephWrapper(client.CephClient): + return self.put('osd/out?ids={0}' + .format(ids), **kwargs) + ++ def osd_pause(self, **kwargs): ++ return self.put('osd/pause', **kwargs) ++ ++ def osd_pg_temp(self, pgid, id=None, **kwargs): ++ if id is not None: ++ return self.put('osd/pg-temp?pgid={0}&id={1}' ++ .format(pgid, id), **kwargs) ++ else: ++ return self.put('osd/pg-temp?pgid={0}' ++ .format(pgid), **kwargs) ++ + def osd_pool_create(self, pool, pg_num, pgp_num, pool_type=None, + erasure_code_profile=None, ruleset=None, + expected_num_objects=None, **kwargs): +@@ -559,10 +717,6 @@ class CephWrapper(client.CephClient): + request.append('&sure={0}'.format(sure)) + return self.put(''.join(request), **kwargs) + +- def osd_pool_param(self, pool, var, **kwargs): +- return self.put('osd/pool/get?pool={0}&var={1}' +- .format(pool, var), **kwargs) +- + def osd_pool_mksnap(self, pool, snap, **kwargs): + return self.put('osd/pool/mksnap?pool={0}&snap={1}' + .format(pool, snap), **kwargs) +@@ -583,6 +737,22 @@ class CephWrapper(client.CephClient): + return self.put('osd/pool/set?pool={0}&var={1}&val={2}' + .format(pool, var, val), **kwargs) + ++ def osd_pool_set(self, pool, var, val, force=None, **kwargs): ++ if force is not None: ++ return self.put('osd/pool/set?pool={0}&var={1}&val={2}&force={3}' ++ .format(pool, var, val, force), **kwargs) ++ else: ++ return self.put('osd/pool/set?pool={0}&var={1}&val={2}' ++ .format(pool, var, val), **kwargs) ++ ++ def osd_primary_affinity(self, id, weight, **kwargs): ++ return self.put('osd/primary-affinity?id={0}&weight={1}' ++ .format(id, weight), **kwargs) ++ ++ def osd_primary_temp(self, pgid, id, **kwargs): ++ return self.put('osd/primary-temp?pgid={0}&id={1}' ++ .format(pgid, id), **kwargs) ++ + def osd_set_pool_quota(self, pool, field, val, **kwargs): + return self.put('osd/pool/set-quota?pool={0}&field={1}&val={2}' + .format(pool, field, val), **kwargs) +@@ -595,6 +765,10 @@ class CephWrapper(client.CephClient): + return self.put('osd/reweight?id={0}&weight={1}' + .format(id, weight), **kwargs) + ++ def osd_reweight_by_pg(self, oload, pools, **kwargs): ++ return self.put('osd/reweight-by-pg?oload={0}&pools={1}' ++ .format(oload, pools), **kwargs) ++ + def osd_reweight_by_utilization(self, oload, **kwargs): + return self.put('osd/reweight-by-utilization?oload={0}' + .format(oload), **kwargs) +@@ -611,6 +785,12 @@ class CephWrapper(client.CephClient): + return self.put('osd/set?key={0}' + .format(key), **kwargs) + ++ def osd_crushmap(self, **kwargs): ++ """ ++ osd/crushmap ++ """ ++ raise exceptions.FunctionNotImplemented() ++ + def osd_setmaxosd(self, newmax, **kwargs): + return self.put('osd/setmaxosd?newmax={0}' + .format(newmax), **kwargs) +@@ -628,6 +808,11 @@ class CephWrapper(client.CephClient): + return self.put('osd/tier/add?pool={0}&tierpool={1}' + .format(pool, tierpool), **kwargs) + ++ def osd_tier_add_cache(self, pool, tierpool, size, **kwargs): ++ return self.put('osd/tier/add-cache?pool={0}&tierpool={1}' ++ '&size={2}' ++ .format(pool, tierpool, size), **kwargs) ++ + def osd_tier_cachemode(self, pool, mode, **kwargs): + return self.put('osd/tier/cache-mode?pool={0}&mode={1}' + .format(pool, mode), **kwargs) +@@ -644,6 +829,9 @@ class CephWrapper(client.CephClient): + return self.put('osd/tier/set-overlay?pool={0}&overlaypool={1}' + .format(pool, overlaypool), **kwargs) + ++ def osd_unpause(self, key, **kwargs): ++ return self.put('osd/unpause', **kwargs) ++ + def osd_unset(self, key, **kwargs): + return self.put('osd/unset?key={0}' + .format(key), **kwargs) +@@ -693,6 +881,44 @@ class CephWrapper(client.CephClient): + + return self.get('pg/getmap', **kwargs) + ++ def pg_ls(self, pool=None, states=None, **kwargs): ++ request = [] ++ request.append('pg/ls') ++ if pool is not None: ++ request.append('?pool={0}'.format(pool)) ++ if states is not None: ++ request.append('states={0}'.format(states)) ++ ++ return self.get(''.join(request), **kwargs) ++ ++ def pg_ls_by_osd(self, osd, pool=None, states=None, **kwargs): ++ request = [] ++ request.append('pg/ls-by-osd?osd={0}'.format(osd)) ++ if pool is not None: ++ request.append('?pool={0}'.format(pool)) ++ if states is not None: ++ request.append('states={0}'.format(states)) ++ ++ return self.get(''.join(request), **kwargs) ++ ++ def pg_ls_by_pool(self, poolstr, states=None, **kwargs): ++ if states is not None: ++ return self.get('pg/ls-by-pool?poolstr={0}&states={1}' ++ .format(poolstr, states), **kwargs) ++ else: ++ return self.get('pg/ls-by-pool?poolstr={0}' ++ .format(poolstr), **kwargs) ++ ++ def pg_ls_by_primary(self, osd, pool=None, states=None, **kwargs): ++ request = [] ++ request.append('pg/ls-by-primary?osd={0}'.format(osd)) ++ if pool is not None: ++ request.append('?pool={0}'.format(pool)) ++ if states is not None: ++ request.append('states={0}'.format(states)) ++ ++ return self.get(''.join(request), **kwargs) ++ + def pg_map(self, pgid, **kwargs): + return self.get('pg/map?pgid={0}' + .format(pgid), **kwargs) +@@ -701,6 +927,37 @@ class CephWrapper(client.CephClient): + return self.get('pg/stat', **kwargs) + + ### ++ # pg PUT calls ++ ### ++ ++ def pg_deep_scrub(self, pgid, **kwargs): ++ return self.put('pg/deep-scrub?pgid={0}' ++ .format(pgid), **kwargs) ++ ++ def pg_force_create_pg(self, pgid, **kwargs): ++ return self.put('pg/force_create_pg?pgid={0}' ++ .format(pgid), **kwargs) ++ ++ def pg_repair(self, pgid, **kwargs): ++ return self.put('pg/repair?pgid={0}' ++ .format(pgid), **kwargs) ++ ++ def pg_scrub(self, pgid, **kwargs): ++ return self.put('pg/scrub?pgid={0}' ++ .format(pgid), **kwargs) ++ ++ def pg_send_pg_creates(self, **kwargs): ++ return self.put('pg/send_pg_creates', **kwargs) ++ ++ def pg_set_full_ratio(self, ratio, **kwargs): ++ return self.put('pg/set_full_ratio?ratio={0}' ++ .format(ratio), **kwargs) ++ ++ def pg_set_nearfull_ratio(self, ratio, **kwargs): ++ return self.put('pg/set_nearfull_ratio?ratio={0}' ++ .format(ratio), **kwargs) ++ ++ ### + # tell GET calls + ### + def tell_debug_dump_missing(self, id, filename, **kwargs): +-- +2.5.0 + diff --git a/extended/python-cephclient/python-cephclient/US92424-Ceph-Rebase-Update-REST-API-to-10.2.4.patch b/extended/python-cephclient/python-cephclient/US92424-Ceph-Rebase-Update-REST-API-to-10.2.4.patch new file mode 100644 index 000000000..01660c8e6 --- /dev/null +++ b/extended/python-cephclient/python-cephclient/US92424-Ceph-Rebase-Update-REST-API-to-10.2.4.patch @@ -0,0 +1,1062 @@ +--- a/cephclient/wrapper.py 2017-02-16 14:59:35.589795141 +0200 ++++ b/cephclient/wrapper.py 2017-02-16 20:15:47.543896397 +0200 +@@ -25,9 +25,6 @@ class CephWrapper(client.CephClient): + super(CephWrapper, self).__init__(**params) + self.user_agent = 'python-cephclient-wrapper' + +- ### +- # root GET calls +- ### + def df(self, detail=None, **kwargs): + if detail is not None: + return self.get('df?detail={0}' +@@ -61,9 +58,6 @@ class CephWrapper(client.CephClient): + def version(self, **kwargs): + return self.get('version', **kwargs) + +- ### +- # root PUT calls +- ### + def compact(self, **kwargs): + return self.put('compact', **kwargs) + +@@ -72,10 +66,14 @@ class CephWrapper(client.CephClient): + .format(heapcmd), **kwargs) + + def injectargs(self, injected_args, **kwargs): ++ if isinstance(injected_args, list): ++ injected_args = '&injected_args='.join(injected_args) + return self.put('injectargs?injected_args={0}' + .format(injected_args), **kwargs) + + def log(self, logtext, **kwargs): ++ if isinstance(logtext, list): ++ logtext = '&logtext='.join(logtext) + return self.put('log?logtext={0}' + .format(logtext), **kwargs) + +@@ -87,22 +85,25 @@ class CephWrapper(client.CephClient): + return self.put('scrub', **kwargs) + + def sync(self, validate1=None, validate2=None, **kwargs): ++ return self.sync_force(validate1, validate2, **kwargs) ++ ++ def sync_force(self, validate1=None, validate2=None, **kwargs): + request = [] + request.append('sync/force') + if validate1 is not None: +- request.append('?validate1={0}'.format(validate1)) ++ request.append('validate1={0}'.format(validate1)) + if validate2 is not None: + request.append('validate2={0}'.format(validate2)) +- +- return self.put(''.join(request), **kwargs) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) + + def tell(self, target, args, **kwargs): ++ if isinstance(args, list): ++ args = '&args='.join(args) + return self.put('tell?target={0}&args={1}' + .format(target, args), **kwargs) + +- ### +- # auth GET calls +- ### + def auth_export(self, entity=None, **kwargs): + if entity is not None: + return self.get('auth/export?entity={0}' +@@ -125,9 +126,10 @@ class CephWrapper(client.CephClient): + return self.get('auth/print-key?entity={0}' + .format(entity), **kwargs) + +- ### +- # auth PUT calls +- ### ++ def auth_print_key(self, entity, **kwargs): ++ return self.get('auth/print_key?entity={0}' ++ .format(entity), **kwargs) ++ + """ + caps dictionary format: + caps = { +@@ -136,62 +138,50 @@ class CephWrapper(client.CephClient): + ... + } + """ +- def auth_add(self, entity, caps={}, file=None, **kwargs): +- # XXX-TODO: Implement file input +- full_caps = list() ++ def auth_add(self, entity, caps={}, **kwargs): + if caps: +- for key in caps: +- permissions = caps[key].replace(' ', '+') +- full_caps.append('&caps={0}&caps={1}' +- .format(key, permissions)) +- +- return self.put('auth/add?entity={0}{1}' +- .format(entity, ''.join(full_caps)), **kwargs) ++ caps = '&caps='.join(['{}&caps={}'.format(k, v) for (k, v) in caps.items()]).replace(' ', '+') ++ return self.put('auth/add?entity={0}&caps={1}' ++ .format(entity, caps), **kwargs) ++ else: ++ return self.put('auth/add?entity={0}' ++ .format(entity), **kwargs) + +- def auth_caps(self, entity, caps={}, **kwargs): +- full_caps = list() ++ def auth_caps(self, entity, caps, **kwargs): + if caps: +- for key in caps: +- permissions = caps[key].replace(' ', '+') +- full_caps.append('&caps={0}&caps={1}' +- .format(key, permissions)) +- +- return self.put('auth/caps?entity={0}{1}' +- .format(entity, ''.join(full_caps)), **kwargs) ++ caps = '&caps='.join(['{}&caps={}'.format(k, v) for (k, v) in caps.items()]).replace(' ', '+') ++ return self.put('auth/caps?entity={0}&caps={1}' ++ .format(entity, caps), **kwargs) + + def auth_del(self, entity, **kwargs): + return self.put('auth/del?entity={0}' + .format(entity), **kwargs) + +- def auth_get_or_create(self, entity, caps={}, file=None, **kwargs): +- # XXX-TODO: Implement file input +- full_caps = list() ++ def auth_get_or_create(self, entity, caps={}, **kwargs): + if caps: +- for key in caps: +- permissions = caps[key].replace(' ', '+') +- full_caps.append('&caps={0}&caps={1}'.format(key, permissions)) +- +- return self.put('auth/get-or-create?entity={0}{1}' +- .format(entity, ''.join(full_caps)), **kwargs) ++ caps = '&caps='.join(['{}&caps={}'.format(k, v) for (k, v) in caps.items()]).replace(' ', '+') ++ return self.put('auth/get-or-create?entity={0}&caps={1}' ++ .format(entity, caps), **kwargs) ++ else: ++ return self.put('auth/get-or-create?entity={0}' ++ .format(entity), **kwargs) + + def auth_get_or_create_key(self, entity, caps={}, **kwargs): +- # XXX-TODO: Implement file input +- full_caps = list() +- if caps: +- for key in caps: +- permissions = caps[key].replace(' ', '+') +- full_caps.append('&caps={0}&caps={1}'.format(key, permissions)) +- +- return self.put('auth/get-or-create-key?entity={0}{1}' +- .format(entity, ''.join(full_caps)), **kwargs) +- +- def auth_import(self, file): +- # XXX-TODO: Implement file input +- raise exceptions.FunctionNotImplemented() +- +- ### +- # config-key GET calls +- ### ++ if caps is not None: ++ caps = '&caps='.join(['{}&caps={}'.format(k, v) for (k, v) in caps.items()]).replace(' ', '+') ++ return self.put('auth/get-or-create-key?entity={0}&caps={1}' ++ .format(entity, caps), **kwargs) ++ else: ++ return self.put('auth/get-or-create-key?entity={0}' ++ .format(entity), **kwargs) ++ ++ def auth_import(self, **kwargs): ++ return self.put('auth/import', **kwargs) ++ ++ def auth_rm(self, entity, **kwargs): ++ return self.put('auth/rm?entity={0}' ++ .format(entity), **kwargs) ++ + def config_key_exists(self, key, **kwargs): + return self.get('config-key/exists?key={0}' + .format(key), **kwargs) +@@ -203,47 +193,84 @@ class CephWrapper(client.CephClient): + def config_key_list(self, **kwargs): + return self.get('config-key/list', **kwargs) + +- ### +- # config-key PUT calls +- ### + def config_key_del(self, key, **kwargs): + return self.put('config-key/del?key={0}' + .format(key), **kwargs) + +- def config_key_put(self, key, val, **kwargs): +- return self.put('config-key/put?key={0}&val={1}' +- .format(key, val), **kwargs) +- +- ### +- # fs GET calls +- ### ++ def config_key_put(self, key, val=None, **kwargs): ++ if val is not None: ++ return self.put('config-key/put?key={0}&val={1}' ++ .format(key, val), **kwargs) ++ else: ++ return self.put('config-key/put?key={0}' ++ .format(key), **kwargs) ++ ++ def config_key_rm(self, key, **kwargs): ++ return self.put('config-key/rm?key={0}' ++ .format(key), **kwargs) ++ + def fs_ls(self, **kwargs): + return self.get('fs/ls', **kwargs) + +- ### +- # fs PUT calls +- ### + def fs_new(self, fs_name, metadata, data, **kwargs): + return self.put('fs/new?fs_name={0}&metadata={1}&data={2}' + .format(fs_name, metadata, data), **kwargs) + + def fs_reset(self, fs_name, sure=None, **kwargs): +- request = [] +- request.append('fs/reset?fs_name={0}'.format(fs_name)) + if sure is not None: +- request.append('&sure={0}'.format(sure)) +- return self.put(''.join(request), **kwargs) ++ return self.put('fs/reset?fs_name={0}&sure={1}' ++ .format(fs_name, sure), **kwargs) ++ else: ++ return self.put('fs/reset?fs_name={0}' ++ .format(fs_name), **kwargs) + + def fs_rm(self, fs_name, sure=None, **kwargs): +- request = [] +- request.append('fs/rm?fs_name={0}'.format(fs_name)) + if sure is not None: +- request.append('&sure={0}'.format(sure)) +- return self.put(''.join(request), **kwargs) ++ return self.put('fs/rm?fs_name={0}&sure={1}' ++ .format(fs_name, sure), **kwargs) ++ else: ++ return self.put('fs/rm?fs_name={0}' ++ .format(fs_name), **kwargs) ++ ++ def fs_add_data_pool(self, fs_name, pool, **kwargs): ++ return self.put('fs/add_data_pool?fs_name={0}&pool={1}' ++ .format(fs_name, pool), **kwargs) ++ ++ def fs_dump(self, epoch=None, **kwargs): ++ if epoch is not None: ++ return self.get('fs/dump?epoch={0}' ++ .format(epoch), **kwargs) ++ else: ++ return self.get('fs/dump', **kwargs) ++ ++ def fs_flag_set(self, flag_name, val, confirm=None, **kwargs): ++ if confirm is not None: ++ return self.put('fs/flag/set?flag_name={0}&val={1}&confirm={2}' ++ .format(flag_name, val, confirm), **kwargs) ++ else: ++ return self.put('fs/flag/set?flag_name={0}&val={1}' ++ .format(flag_name, val), **kwargs) ++ ++ def fs_get(self, fs_name, **kwargs): ++ return self.get('fs/get?fs_name={0}' ++ .format(fs_name), **kwargs) ++ ++ def fs_rm_data_pool(self, fs_name, pool, **kwargs): ++ return self.put('fs/rm_data_pool?fs_name={0}&pool={1}' ++ .format(fs_name, pool), **kwargs) ++ ++ def fs_set(self, fs_name, var, val, confirm=None, **kwargs): ++ if confirm is not None: ++ return self.put('fs/set?fs_name={0}&var={1}&val={2}&confirm={3}' ++ .format(fs_name, var, val, confirm), **kwargs) ++ else: ++ return self.put('fs/set?fs_name={0}&var={1}&val={2}' ++ .format(fs_name, var, val), **kwargs) ++ ++ def fs_set_default(self, fs_name, **kwargs): ++ return self.put('fs/set_default?fs_name={0}' ++ .format(fs_name), **kwargs) + +- ### +- # mds GET calls +- ### + def mds_compat_show(self, **kwargs): + return self.get('mds/compat/show', **kwargs) + +@@ -266,9 +293,6 @@ class CephWrapper(client.CephClient): + def mds_stat(self, **kwargs): + return self.get('mds/stat', **kwargs) + +- ### +- # mds PUT calls +- ### + def mds_add_data_pool(self, pool, **kwargs): + return self.put('mds/add_data_pool?pool={0}' + .format(pool), **kwargs) +@@ -307,63 +331,69 @@ class CephWrapper(client.CephClient): + return self.put('mds/remove_data_pool?pool={0}' + .format(pool), **kwargs) + +- def mds_rm(self, gid, who, **kwargs): +- return self.put('mds/rm?gid={0}&who={1}' +- .format(gid, who), **kwargs) ++ def mds_rm(self, gid, **kwargs): ++ return self.put('mds/rm?gid={0}' ++ .format(gid), **kwargs) + +- def mds_rmfailed(self, who, **kwargs): +- return self.put('mds/rmfailed?who={0}' +- .format(who), **kwargs) +- +- def mds_set_max_file_size(self, val, confirm=None, **kwargs): ++ def mds_rmfailed(self, who, confirm=None, **kwargs): + if confirm is not None: +- return self.put('mds/set?var=max_file_size?val={0}&confirm={1}' +- .format(val, confirm), **kwargs) ++ return self.put('mds/rmfailed?who={0}&confirm={1}' ++ .format(who, confirm), **kwargs) + else: +- return self.put('mds/set?var=max_file_size?val={0}' +- .format(val), **kwargs) ++ return self.put('mds/rmfailed?who={0}' ++ .format(who), **kwargs) ++ ++ def mds_set_max_file_size(self, val, confirm=None, **kwargs): ++ return self.mds_set(self, 'max_file_size', val, confirm=None, **kwargs) + + def mds_set_allow_new_snaps(self, val, confirm=None, **kwargs): +- if confirm is not None: +- return self.put('mds/set?var=allow_new_snaps?val={0}&confirm={1}' +- .format(val, confirm), **kwargs) +- else: +- return self.put('mds/set?var=allow_new_snaps?val={0}' +- .format(val), **kwargs) ++ return self.mds_set(self, 'allow_new_snaps', val, confirm=None, **kwargs) + + def mds_set_inline_data(self, val, confirm=None, **kwargs): +- if confirm is not None: +- return self.put('mds/set?var=inline_data?val={0}&confirm={1}' +- .format(val, confirm), **kwargs) +- else: +- return self.put('mds/set?var=inline_data?val={0}' +- .format(val), **kwargs) ++ return self.mds_set(self, 'inline_data', val, confirm=None, **kwargs) + + def mds_set_max_mds(self, maxmds, **kwargs): + return self.put('mds/set_max_mds?maxmds={0}' + .format(maxmds), **kwargs) + +- def mds_setmap(self, epoch, **kwargs): +- return self.put('mds/setmap?epoch={0}' +- .format(epoch), **kwargs) ++ # mds_setmap() not defined in new api + + def mds_stop(self, who, **kwargs): + return self.put('mds/stop?who={0}' + .format(who), **kwargs) + + def mds_tell(self, who, args, **kwargs): ++ if isinstance(args, list): ++ args = '&args='.join(args) + return self.put('mds/tell?who={0}&args={1}' + .format(who, args), **kwargs) + +- def mds_unset_allow_new_snaps(self, sure, **kwargs): +- """ +- mds/unset?key=allow_new_snaps&sure= +- """ +- raise exceptions.FunctionNotImplemented() +- +- ### +- # mon GET calls +- ### ++ # mds_unset_allow_new_snaps() not defined in new api ++ ++ def mds_metadata(self, who, **kwargs): ++ return self.get('mds/metadata?who={0}' ++ .format(who), **kwargs) ++ ++ def mds_repaired(self, rank, **kwargs): ++ return self.put('mds/repaired?rank={0}' ++ .format(rank), **kwargs) ++ ++ def mds_rm_data_pool(self, pool, **kwargs): ++ return self.put('mds/rm_data_pool?pool={0}' ++ .format(pool), **kwargs) ++ ++ def mds_set(self, var, val, confirm=None, **kwargs): ++ if confirm is not None: ++ return self.put('mds/set?var={0}&val={1}&confirm={2}' ++ .format(var, val, confirm), **kwargs) ++ else: ++ return self.put('mds/set?var={0}&val={1}' ++ .format(var, val), **kwargs) ++ ++ def mds_set_state(self, gid, state, **kwargs): ++ return self.put('mds/set_state?gid={0}&state={1}' ++ .format(gid, state), **kwargs) ++ + def mon_dump(self, epoch=None, **kwargs): + if epoch is not None: + return self.get('mon/dump?epoch={0}' +@@ -388,9 +418,6 @@ class CephWrapper(client.CephClient): + def mon_status(self, **kwargs): + return self.get('mon_status', **kwargs) + +- ### +- # mon PUT calls +- ### + def mon_add(self, name, addr, **kwargs): + return self.put('mon/add?name={0}&addr={1}' + .format(name, addr), **kwargs) +@@ -399,9 +426,38 @@ class CephWrapper(client.CephClient): + return self.put('mon/remove?name={0}' + .format(name), **kwargs) + +- ### +- # osd GET calls +- ### ++ def mon_compact(self, **kwargs): ++ return self.put('mon/compact', **kwargs) ++ ++ def mon_metadata(self, id, **kwargs): ++ return self.get('mon/metadata?id={0}' ++ .format(id), **kwargs) ++ ++ def mon_rm(self, name, **kwargs): ++ return self.put('mon/rm?name={0}' ++ .format(name), **kwargs) ++ ++ def mon_scrub(self, **kwargs): ++ return self.put('mon/scrub', **kwargs) ++ ++ def mon_sync_force(self, validate1=None, validate2=None, **kwargs): ++ request = [] ++ request.append('mon/sync/force') ++ if validate1 is not None: ++ request.append('validate1={0}'.format(validate1)) ++ if validate2 is not None: ++ request.append('validate2={0}'.format(validate2)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) ++ ++ def node_ls(self, type=None, **kwargs): ++ if type is not None: ++ return self.get('node/ls?type={0}' ++ .format(type), **kwargs) ++ else: ++ return self.get('node/ls', **kwargs) ++ + def osd_blacklist_ls(self, **kwargs): + return self.get('osd/blacklist/ls', **kwargs) + +@@ -490,20 +546,26 @@ class CephWrapper(client.CephClient): + else: + return self.get('osd/lspools', **kwargs) + +- def osd_map(self, pool, object, **kwargs): +- return self.get('osd/map?pool={0}&object={1}' +- .format(pool, object), **kwargs) ++ def osd_map(self, pool, object, nspace=None, **kwargs): ++ if nspace is not None: ++ return self.get('osd/map?pool={0}&object={1}&nspace={2}' ++ .format(pool, object, nspace), **kwargs) ++ else: ++ return self.get('osd/map?pool={0}&object={1}' ++ .format(pool, object), **kwargs) + +- def osd_metadata(self, id, **kwargs): +- return self.get('osd/metadata?id={0}' +- .format(id), **kwargs) ++ def osd_metadata(self, id=None, **kwargs): ++ if id is not None: ++ return self.get('osd/metadata?id={0}' ++ .format(id), **kwargs) ++ else: ++ return self.get('osd/metadata', **kwargs) + + def osd_perf(self, **kwargs): + return self.get('osd/perf', **kwargs) + + def osd_get_pool_param(self, pool, var, **kwargs): +- return self.get('osd/pool/get?pool={0}&var={1}' +- .format(pool, var), **kwargs) ++ return self.osd_pool_get(pool, var, **kwargs) + + def osd_pool_get(self, pool, var, **kwargs): + return self.get('osd/pool/get?pool={0}&var={1}' +@@ -517,6 +579,9 @@ class CephWrapper(client.CephClient): + return self.get('osd/pool/stats', **kwargs) + + def osd_get_pool_quota(self, pool, **kwargs): ++ return self.osd_pool_get_quota(pool, **kwargs) ++ ++ def osd_pool_get_quota(self, pool, **kwargs): + return self.get('osd/pool/get-quota?pool={0}' + .format(pool), **kwargs) + +@@ -537,18 +602,28 @@ class CephWrapper(client.CephClient): + else: + return self.get('osd/tree', **kwargs) + +- ### +- # osd PUT calls +- ### +- def osd_blacklist(self, blacklistop, addr, expire, **kwargs): +- return self.put('osd/blacklist?blacklistop={0}&addr={1}&expire={2}' +- .format(blacklistop, addr, expire), **kwargs) +- +- def osd_create(self, uuid, **kwargs): +- return self.put('osd/create?uuid={0}' +- .format(uuid), **kwargs) ++ def osd_blacklist(self, blacklistop, addr, expire=None, **kwargs): ++ if expire is not None: ++ return self.put('osd/blacklist?blacklistop={0}&addr={1}&expire={2}' ++ .format(blacklistop, addr, expire), **kwargs) ++ else: ++ return self.put('osd/blacklist?blacklistop={0}&addr={1}' ++ .format(blacklistop, addr), **kwargs) ++ ++ def osd_create(self, uuid=None, id=None, **kwargs): ++ request = [] ++ request.append('osd/create') ++ if uuid is not None: ++ request.append('uuid={0}'.format(uuid)) ++ if id is not None: ++ request.append('id={0}'.format(id)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) + + def osd_crush_add(self, id, weight, args, **kwargs): ++ if isinstance(args, list): ++ args = '&args='.join(args) + return self.put('osd/crush/add?id={0}&weight={1}&args={2}' + .format(id, weight, args), **kwargs) + +@@ -557,6 +632,8 @@ class CephWrapper(client.CephClient): + .format(name, type), **kwargs) + + def osd_crush_create_or_move(self, id, weight, args, **kwargs): ++ if isinstance(args, list): ++ args = '&args='.join(args) + return self.put('osd/crush/create-or-move?id={0}&weight={1}&args={2}' + .format(id, weight, args), **kwargs) + +@@ -565,10 +642,14 @@ class CephWrapper(client.CephClient): + .format(tunable), **kwargs) + + def osd_crush_link(self, name, args, **kwargs): +- return self.put('osd/crush/link?name={0}&args={2}' ++ if isinstance(args, list): ++ args = '&args='.join(args) ++ return self.put('osd/crush/link?name={0}&args={1}' + .format(name, args), **kwargs) + + def osd_crush_move(self, name, args, **kwargs): ++ if isinstance(args, list): ++ args = '&args='.join(args) + return self.put('osd/crush/move?name={0}&args={1}' + .format(name, args), **kwargs) + +@@ -595,7 +676,7 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/reweight-subtree?name={0}&weight={1}' + .format(name, weight), **kwargs) + +- def osd_crush_rm(self, name, ancestor, **kwargs): ++ def osd_crush_rm(self, name, ancestor=None, **kwargs): + if ancestor is not None: + return self.put('osd/crush/rm?name={0}&ancestor={1}' + .format(name, ancestor), **kwargs) +@@ -603,33 +684,35 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/rm?name={0}' + .format(name), **kwargs) + +- def osd_crush_rule_create_erasure(self, name, profile, **kwargs): +- return self.put( +- 'osd/crush/rule/create-erasure?name={0}&profile={1}' +- .format(name, profile), **kwargs) ++ def osd_crush_rule_create_erasure(self, name, profile=None, **kwargs): ++ if profile is not None: ++ return self.put('osd/crush/rule/create-erasure?name={0}&profile={1}' ++ .format(name, profile), **kwargs) ++ else: ++ return self.put('osd/crush/rule/create-erasure?name={0}' ++ .format(name), **kwargs) + +- def osd_crush_rule_create_simple(self, name, root, +- type, mode=None, **kwargs): ++ def osd_crush_rule_create_simple(self, name, root, type, mode=None, **kwargs): + if mode is not None: +- return self.put( +- 'osd/crush/rule/create-simple?name={0}&root={1}&type={2}' +- '&mode={3}'.format(name, root, type, mode), **kwargs) +- else: +- return self.put( +- 'osd/crush/rule/create-simple?name={0}&root={1}&type={2}' +- .format(name, root, type), **kwargs) ++ return self.put('osd/crush/rule/create-simple?name={0}&root={1}&type={2}&mode={3}' ++ .format(name, root, type, mode), **kwargs) ++ else: ++ return self.put('osd/crush/rule/create-simple?name={0}&root={1}&type={2}' ++ .format(name, root, type), **kwargs) + + def osd_crush_rule_rm(self, name, **kwargs): + return self.put('osd/crush/rule/rm?name={0}' + .format(name), **kwargs) + + def osd_crush_set(self, id, weight, args, **kwargs): ++ if isinstance(args, list): ++ args = '&args='.join(args) + return self.put('osd/crush/set?id={0}&weight={1}&args={2}' + .format(id, weight, args), **kwargs) + + def osd_crush_set_tunable(self, tunable, value, **kwargs): + return self.put('osd/crush/set-tunable?tunable={0}&value={1}' +- .format(tunable), **kwargs) ++ .format(tunable, value), **kwargs) + + def osd_crush_tunables(self, profile, **kwargs): + return self.put('osd/crush/tunables?profile={0}' +@@ -648,6 +731,8 @@ class CephWrapper(client.CephClient): + .format(who), **kwargs) + + def osd_down(self, ids, **kwargs): ++ if isinstance(ids, list): ++ ids = '&ids='.join(ids) + return self.put('osd/down?ids={0}' + .format(ids), **kwargs) + +@@ -664,6 +749,8 @@ class CephWrapper(client.CephClient): + .format(name), **kwargs) + + def osd_in(self, ids, **kwargs): ++ if isinstance(ids, list): ++ ids = '&ids='.join(ids) + return self.put('osd/in?ids={0}' + .format(ids), **kwargs) + +@@ -676,6 +763,8 @@ class CephWrapper(client.CephClient): + .format(id), **kwargs) + + def osd_out(self, ids, **kwargs): ++ if isinstance(ids, list): ++ ids = '&ids='.join(ids) + return self.put('osd/out?ids={0}' + .format(ids), **kwargs) + +@@ -690,32 +779,29 @@ class CephWrapper(client.CephClient): + return self.put('osd/pg-temp?pgid={0}' + .format(pgid), **kwargs) + +- def osd_pool_create(self, pool, pg_num, pgp_num, pool_type=None, +- erasure_code_profile=None, ruleset=None, +- expected_num_objects=None, **kwargs): ++ def osd_pool_create(self, pool, pg_num, pgp_num=None, pool_type=None, erasure_code_profile=None, ruleset=None, expected_num_objects=None, **kwargs): + request = [] +- request.append('osd/pool/create?pool={0}&pg_num={1}&pgp_num={2}' +- .format(pool, pg_num, pgp_num)) ++ request.append('osd/pool/create?pool={0}&pg_num={1}'.format(pool, pg_num)) ++ if pgp_num is not None: ++ request.append('pgp_num={0}'.format(pgp_num)) + if pool_type is not None: +- request.append('&pool_type={0}'.format(pool_type)) ++ request.append('pool_type={0}'.format(pool_type)) + if erasure_code_profile is not None: +- request.append('&erasure_code_profile={0}' +- .format(erasure_code_profile)) ++ request.append('erasure_code_profile={0}'.format(erasure_code_profile)) + if ruleset is not None: +- request.append('&ruleset={0}'.format(ruleset)) ++ request.append('ruleset={0}'.format(ruleset)) + if expected_num_objects is not None: +- request.append('&expected_num_objects={0}' +- .format(expected_num_objects)) +- return self.put(''.join(request), **kwargs) ++ request.append('expected_num_objects={0}'.format(expected_num_objects)) ++ return self.put('&'.join(request), **kwargs) + + def osd_pool_delete(self, pool, pool2=None, sure=None, **kwargs): + request = [] + request.append('osd/pool/delete?pool={0}'.format(pool)) + if pool2 is not None: +- request.append('&pool2={0}'.format(pool2)) ++ request.append('pool2={0}'.format(pool2)) + if sure is not None: +- request.append('&sure={0}'.format(sure)) +- return self.put(''.join(request), **kwargs) ++ request.append('sure={0}'.format(sure)) ++ return self.put('&'.join(request), **kwargs) + + def osd_pool_mksnap(self, pool, snap, **kwargs): + return self.put('osd/pool/mksnap?pool={0}&snap={1}' +@@ -730,12 +816,7 @@ class CephWrapper(client.CephClient): + .format(pool, snap), **kwargs) + + def osd_set_pool_param(self, pool, var, val, force=None, **kwargs): +- if force is not None: +- return self.put('osd/pool/set?pool={0}&var={1}&val={2}&force={3}' +- .format(pool, var, val, force), **kwargs) +- else: +- return self.put('osd/pool/set?pool={0}&var={1}&val={2}' +- .format(pool, var, val), **kwargs) ++ return self.osd_pool_set(pool, var, val, force, **kwargs) + + def osd_pool_set(self, pool, var, val, force=None, **kwargs): + if force is not None: +@@ -754,26 +835,57 @@ class CephWrapper(client.CephClient): + .format(pgid, id), **kwargs) + + def osd_set_pool_quota(self, pool, field, val, **kwargs): ++ return self.osd_pool_set_quota(pool, field, val, **kwargs) ++ ++ def osd_pool_set_quota(self, pool, field, val, **kwargs): + return self.put('osd/pool/set-quota?pool={0}&field={1}&val={2}' + .format(pool, field, val), **kwargs) + +- def osd_repair(self, pool, who, **kwargs): ++ ++ def osd_repair(self, who, **kwargs): + return self.put('osd/repair?who={0}' +- .format(pool, who), **kwargs) ++ .format(who), **kwargs) + + def osd_reweight(self, id, weight, **kwargs): + return self.put('osd/reweight?id={0}&weight={1}' + .format(id, weight), **kwargs) + +- def osd_reweight_by_pg(self, oload, pools, **kwargs): +- return self.put('osd/reweight-by-pg?oload={0}&pools={1}' +- .format(oload, pools), **kwargs) +- +- def osd_reweight_by_utilization(self, oload, **kwargs): +- return self.put('osd/reweight-by-utilization?oload={0}' +- .format(oload), **kwargs) ++ def osd_reweight_by_pg(self, oload=None, max_change=None, max_osds=None, pools=None, **kwargs): ++ request = [] ++ request.append('osd/reweight-by-pg') ++ if oload is not None: ++ request.append('oload={0}'.format(oload)) ++ if max_change is not None: ++ request.append('max_change={0}'.format(max_change)) ++ if max_osds is not None: ++ request.append('max_osds={0}'.format(max_osds)) ++ if pools is not None: ++ request.append('pools={0}'.format(pools)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) ++ ++ def osd_reweight_by_utilization(self, oload=None, max_change=None, max_osds=None, no_increasing=None, **kwargs): ++ request = [] ++ request.append('osd/reweight-by-utilization') ++ if oload is not None: ++ request.append('oload={0}'.format(oload)) ++ if max_change is not None: ++ request.append('max_change={0}'.format(max_change)) ++ if max_osds is not None: ++ request.append('max_osds={0}'.format(max_osds)) ++ if no_increasing is not None: ++ request.append('no_increasing={0}'.format(no_increasing)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) + + def osd_remove(self, ids, **kwargs): ++ return self.osd_rm(ids, **kwargs) ++ ++ def osd_rm(self, ids, **kwargs): ++ if isinstance(ids, list): ++ ids = '&ids='.join(ids) + return self.put('osd/rm?ids={0}' + .format(ids), **kwargs) + +@@ -782,14 +894,9 @@ class CephWrapper(client.CephClient): + .format(who), **kwargs) + + def osd_set_key(self, key, **kwargs): +- return self.put('osd/set?key={0}' +- .format(key), **kwargs) ++ return self.osd_set(key, **kwargs) + +- def osd_crushmap(self, **kwargs): +- """ +- osd/crushmap +- """ +- raise exceptions.FunctionNotImplemented() ++ # osd_crushmap() not defined in new api + + def osd_setmaxosd(self, newmax, **kwargs): + return self.put('osd/setmaxosd?newmax={0}' +@@ -801,21 +908,18 @@ class CephWrapper(client.CephClient): + + def osd_tier_add(self, pool, tierpool, force_nonempty=None, **kwargs): + if force_nonempty is not None: +- return self.put('osd/tier/add?pool={0}&tierpool={1}' +- '&force_nonempty={2}' ++ return self.put('osd/tier/add?pool={0}&tierpool={1}&force_nonempty={2}' + .format(pool, tierpool, force_nonempty), **kwargs) + else: + return self.put('osd/tier/add?pool={0}&tierpool={1}' + .format(pool, tierpool), **kwargs) + + def osd_tier_add_cache(self, pool, tierpool, size, **kwargs): +- return self.put('osd/tier/add-cache?pool={0}&tierpool={1}' +- '&size={2}' ++ return self.put('osd/tier/add-cache?pool={0}&tierpool={1}&size={2}' + .format(pool, tierpool, size), **kwargs) + + def osd_tier_cachemode(self, pool, mode, **kwargs): +- return self.put('osd/tier/cache-mode?pool={0}&mode={1}' +- .format(pool, mode), **kwargs) ++ return self.osd_tier_cache_mode(pool, mode, **kwargs) + + def osd_tier_remove(self, pool, tierpool, **kwargs): + return self.put('osd/tier/remove?pool={0}&tierpool={1}' +@@ -829,16 +933,81 @@ class CephWrapper(client.CephClient): + return self.put('osd/tier/set-overlay?pool={0}&overlaypool={1}' + .format(pool, overlaypool), **kwargs) + +- def osd_unpause(self, key, **kwargs): ++ def osd_unpause(self, **kwargs): + return self.put('osd/unpause', **kwargs) + + def osd_unset(self, key, **kwargs): + return self.put('osd/unset?key={0}' + .format(key), **kwargs) + +- ### +- # pg GET calls +- ### ++ def osd_blacklist_clear(self, **kwargs): ++ return self.put('osd/blacklist/clear', **kwargs) ++ ++ def osd_pool_rm(self, pool, pool2=None, sure=None, **kwargs): ++ request = [] ++ request.append('osd/pool/rm?pool={0}'.format(pool)) ++ if pool2 is not None: ++ request.append('pool2={0}'.format(pool2)) ++ if sure is not None: ++ request.append('sure={0}'.format(sure)) ++ return self.put('&'.join(request), **kwargs) ++ ++ def osd_set(self, key, **kwargs): ++ return self.put('osd/set?key={0}' ++ .format(key), **kwargs) ++ ++ def osd_setcrushmap(self, **kwargs): ++ return self.put('osd/setcrushmap', **kwargs) ++ ++ def osd_test_reweight_by_pg(self, oload=None, max_change=None, max_osds=None, pools=None, **kwargs): ++ request = [] ++ request.append('osd/test-reweight-by-pg') ++ if oload is not None: ++ request.append('oload={0}'.format(oload)) ++ if max_change is not None: ++ request.append('max_change={0}'.format(max_change)) ++ if max_osds is not None: ++ request.append('max_osds={0}'.format(max_osds)) ++ if pools is not None: ++ request.append('pools={0}'.format(pools)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) ++ ++ def osd_test_reweight_by_utilization(self, oload=None, max_change=None, max_osds=None, no_increasing=None, **kwargs): ++ request = [] ++ request.append('osd/test-reweight-by-utilization') ++ if oload is not None: ++ request.append('oload={0}'.format(oload)) ++ if max_change is not None: ++ request.append('max_change={0}'.format(max_change)) ++ if max_osds is not None: ++ request.append('max_osds={0}'.format(max_osds)) ++ if no_increasing is not None: ++ request.append('no_increasing={0}'.format(no_increasing)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) ++ ++ def osd_tier_cache_mode(self, pool, mode, sure=None, **kwargs): ++ if sure is not None: ++ return self.put('osd/tier/cache-mode?pool={0}&mode={1}&sure={2}' ++ .format(pool, mode, sure), **kwargs) ++ else: ++ return self.put('osd/tier/cache-mode?pool={0}&mode={1}' ++ .format(pool, mode), **kwargs) ++ ++ def osd_tier_rm(self, pool, tierpool, **kwargs): ++ return self.put('osd/tier/rm?pool={0}&tierpool={1}' ++ .format(pool, tierpool), **kwargs) ++ ++ def osd_tier_rm_overlay(self, pool, **kwargs): ++ return self.put('osd/tier/rm-overlay?pool={0}' ++ .format(pool), **kwargs) ++ ++ def osd_utilization(self, **kwargs): ++ return self.get('osd/utilization', **kwargs) ++ + def pg_debug(self, debugop, **kwargs): + kwargs['supported_body_types'] = ['text', 'xml'] + +@@ -866,15 +1035,12 @@ class CephWrapper(client.CephClient): + request = [] + request.append('pg/dump_stuck') + if stuckops is not None: +- request.append('?stuckops={0}'.format(stuckops)) ++ request.append('stuckops={0}'.format(stuckops)) + if threshold is not None: +- if stuckops is not None: +- request.append('&') +- else: +- request.append('?') + request.append('threshold={0}'.format(threshold)) +- +- return self.get(''.join(request), **kwargs) ++ if len(request) == 1: ++ return self.get(request[0], **kwargs) ++ return self.get(request[0] + '?' + '&'.join(request[1:]), **kwargs) + + def pg_getmap(self, **kwargs): + kwargs['supported_body_types'] = ['binary'] +@@ -885,21 +1051,21 @@ class CephWrapper(client.CephClient): + request = [] + request.append('pg/ls') + if pool is not None: +- request.append('?pool={0}'.format(pool)) ++ request.append('pool={0}'.format(pool)) + if states is not None: + request.append('states={0}'.format(states)) +- +- return self.get(''.join(request), **kwargs) ++ if len(request) == 1: ++ return self.get(request[0], **kwargs) ++ return self.get(request[0] + '?' + '&'.join(request[1:]), **kwargs) + + def pg_ls_by_osd(self, osd, pool=None, states=None, **kwargs): + request = [] + request.append('pg/ls-by-osd?osd={0}'.format(osd)) + if pool is not None: +- request.append('?pool={0}'.format(pool)) ++ request.append('pool={0}'.format(pool)) + if states is not None: + request.append('states={0}'.format(states)) +- +- return self.get(''.join(request), **kwargs) ++ return self.get('&'.join(request), **kwargs) + + def pg_ls_by_pool(self, poolstr, states=None, **kwargs): + if states is not None: +@@ -913,11 +1079,10 @@ class CephWrapper(client.CephClient): + request = [] + request.append('pg/ls-by-primary?osd={0}'.format(osd)) + if pool is not None: +- request.append('?pool={0}'.format(pool)) ++ request.append('pool={0}'.format(pool)) + if states is not None: + request.append('states={0}'.format(states)) +- +- return self.get(''.join(request), **kwargs) ++ return self.get('&'.join(request), **kwargs) + + def pg_map(self, pgid, **kwargs): + return self.get('pg/map?pgid={0}' +@@ -926,10 +1091,6 @@ class CephWrapper(client.CephClient): + def pg_stat(self, **kwargs): + return self.get('pg/stat', **kwargs) + +- ### +- # pg PUT calls +- ### +- + def pg_deep_scrub(self, pgid, **kwargs): + return self.put('pg/deep-scrub?pgid={0}' + .format(pgid), **kwargs) +@@ -957,20 +1118,20 @@ class CephWrapper(client.CephClient): + return self.put('pg/set_nearfull_ratio?ratio={0}' + .format(ratio), **kwargs) + +- ### +- # tell GET calls +- ### + def tell_debug_dump_missing(self, id, filename, **kwargs): +- return self.get('tell/{0}/debug_dump_missing?filename={1}' ++ return self.get('tell/{0}/debug/dump_missing?filename={1}' + .format(id, filename), **kwargs) + + def tell_dump_pg_recovery_stats(self, id, **kwargs): + return self.get('tell/{0}/dump_pg_recovery_stats' + .format(id), **kwargs) + +- def tell_list_missing(self, id, offset, **kwargs): +- return self.get('tell/{0}/list_missing?offset={1}' +- .format(id, offset), **kwargs) ++ def tell_list_missing(self, id, offset=None, **kwargs): ++ if offset is not None: ++ return self.get('tell/{0}/list_missing?offset={1}' ++ .format(id, offset), **kwargs) ++ else: ++ return self.get('tell/{0}/list_missing', **kwargs) + + def tell_query(self, id, **kwargs): + return self.get('tell/{0}/query' +@@ -979,3 +1140,55 @@ class CephWrapper(client.CephClient): + def tell_version(self, id, **kwargs): + return self.get('tell/{0}/version' + .format(id), **kwargs) ++ ++ def tell_bench(self, id, count=None, size=None, object_size=None, object_num=None, **kwargs): ++ request = [] ++ request.append('tell/{0}/bench'.format(id)) ++ if count is not None: ++ request.append('count={0}'.format(count)) ++ if size is not None: ++ request.append('size={0}'.format(size)) ++ if object_size is not None: ++ request.append('object_size={0}'.format(object_size)) ++ if object_num is not None: ++ request.append('object_num={0}'.format(object_num)) ++ if len(request) == 1: ++ return self.put(request[0], **kwargs) ++ return self.put(request[0] + '?' + '&'.join(request[1:]), **kwargs) ++ ++ def tell_cluster_log(self, id, level, message, **kwargs): ++ if isinstance(message, list): ++ message = '&message='.join(message) ++ return self.put('tell/{0}/cluster_log?level={1}&message={2}' ++ .format(id, level, message), **kwargs) ++ ++ def tell_cpu_profiler(self, id, arg, **kwargs): ++ return self.put('tell/{0}/cpu_profiler?arg={1}' ++ .format(id, arg), **kwargs) ++ ++ def tell_debug_kick_recovery_wq(self, id, delay, **kwargs): ++ return self.put('tell/{0}/debug/kick_recovery_wq?delay={1}' ++ .format(id, delay), **kwargs) ++ ++ def tell_flush_pg_stats(self, id, **kwargs): ++ return self.put('tell/{0}/flush_pg_stats' ++ .format(id), **kwargs) ++ ++ def tell_heap(self, id, heapcmd, **kwargs): ++ return self.put('tell/{0}/heap?heapcmd={1}' ++ .format(id, heapcmd), **kwargs) ++ ++ def tell_injectargs(self, id, injected_args, **kwargs): ++ if isinstance(injected_args, list): ++ injected_args = '&injected_args='.join(injected_args) ++ return self.put('tell/{0}/injectargs?injected_args={1}' ++ .format(id, injected_args), **kwargs) ++ ++ def tell_mark_unfound_lost(self, id, mulcmd, **kwargs): ++ return self.put('tell/{0}/mark_unfound_lost?mulcmd={1}' ++ .format(id, mulcmd), **kwargs) ++ ++ def tell_reset_pg_recovery_stats(self, id, **kwargs): ++ return self.put('tell/{0}/reset_pg_recovery_stats' ++ .format(id), **kwargs) ++ diff --git a/extended/python-cephclient/python-cephclient/add-osd-get-pool-quota.patch b/extended/python-cephclient/python-cephclient/add-osd-get-pool-quota.patch new file mode 100644 index 000000000..4127d7eb1 --- /dev/null +++ b/extended/python-cephclient/python-cephclient/add-osd-get-pool-quota.patch @@ -0,0 +1,15 @@ +Index: git/cephclient/wrapper.py +=================================================================== +--- git.orig/cephclient/wrapper.py 2015-10-26 16:00:32.768154102 +0200 ++++ git/cephclient/wrapper.py 2015-11-04 14:46:09.491855340 +0200 +@@ -412,6 +412,10 @@ + else: + return self.get('osd/pool/stats', **kwargs) + ++ def osd_get_pool_quota(self, pool, **kwargs): ++ return self.get('osd/pool/get-quota?pool={0}' ++ .format(pool), **kwargs) ++ + def osd_stat(self, **kwargs): + return self.get('osd/stat', **kwargs) + diff --git a/extended/python-cephclient/python-cephclient/fix-osd-crush-remove.patch b/extended/python-cephclient/python-cephclient/fix-osd-crush-remove.patch new file mode 100644 index 000000000..2f611a753 --- /dev/null +++ b/extended/python-cephclient/python-cephclient/fix-osd-crush-remove.patch @@ -0,0 +1,25 @@ +--- + cephclient/wrapper.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +Index: git/cephclient/wrapper.py +=================================================================== +--- git.orig/cephclient/wrapper.py ++++ git/cephclient/wrapper.py +@@ -449,9 +449,13 @@ class CephWrapper(client.CephClient): + return self.put('osd/crush/move?name={0}&args={1}' + .format(name, args), **kwargs) + +- def osd_crush_remove(self, name, ancestor, **kwargs): +- return self.put('osd/crush/remove?name={0}&ancestor={1}' +- .format(name, ancestor), **kwargs) ++ def osd_crush_remove(self, name, ancestor=None, **kwargs): ++ if ancestor: ++ return self.put('osd/crush/remove?name={0}&ancestor={1}' ++ .format(name, ancestor), **kwargs) ++ else: ++ return self.put('osd/crush/remove?name={0}' ++ .format(name), **kwargs) + + def osd_crush_reweight(self, name, weight, **kwargs): + return self.put('osd/crush/reweight?name={0}&weight={1}' diff --git a/extended/python-cephclient/python-cephclient/fix-osd-tier-add.patch b/extended/python-cephclient/python-cephclient/fix-osd-tier-add.patch new file mode 100644 index 000000000..c07f5319d --- /dev/null +++ b/extended/python-cephclient/python-cephclient/fix-osd-tier-add.patch @@ -0,0 +1,19 @@ +diff -rupN a/cephclient/wrapper.py b/cephclient/wrapper.py +--- a/cephclient/wrapper.py 2016-07-04 21:59:06.000000000 +0300 ++++ b/cephclient/wrapper.py 2016-07-07 18:01:50.000000000 +0300 +@@ -799,11 +799,11 @@ class CephWrapper(client.CephClient): + return self.put('osd/thrash?num_epochs={0}' + .format(num_epochs), **kwargs) + +- def osd_tier_add(self, pool, tierpool, force_notempty=None, **kwargs): +- if force_notempty is not None: ++ def osd_tier_add(self, pool, tierpool, force_nonempty=None, **kwargs): ++ if force_nonempty is not None: + return self.put('osd/tier/add?pool={0}&tierpool={1}' +- '&force_notempty={2}' +- .format(pool, tierpool, force_notempty), **kwargs) ++ '&force_nonempty={2}' ++ .format(pool, tierpool, force_nonempty), **kwargs) + else: + return self.put('osd/tier/add?pool={0}&tierpool={1}' + .format(pool, tierpool), **kwargs) diff --git a/extended/python-cephclient/python-cephclient/set-default-endpoint.patch b/extended/python-cephclient/python-cephclient/set-default-endpoint.patch new file mode 100644 index 000000000..40adee890 --- /dev/null +++ b/extended/python-cephclient/python-cephclient/set-default-endpoint.patch @@ -0,0 +1,20 @@ +--- + cephclient/client.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/cephclient/client.py ++++ b/cephclient/client.py +@@ -53,7 +53,12 @@ class CephClient(object): + + self.log.debug("Params: {0}".format(str(self.params))) + +- self.endpoint = self.params['endpoint'] ++ if 'endpoint' in self.params: ++ self.endpoint = self.params['endpoint'] ++ else: ++ # default endpoint ++ self.endpoint = 'http://localhost:5001/api/v0.1/' ++ + if 'timeout' not in self.params: + self.timeout = None + diff --git a/extended/python-gunicorn/centos/build_srpm.data b/extended/python-gunicorn/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/extended/python-gunicorn/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/extended/python-gunicorn/centos/meta_patches/0001-TIS-gunicorn-19-upgrade.patch b/extended/python-gunicorn/centos/meta_patches/0001-TIS-gunicorn-19-upgrade.patch new file mode 100644 index 000000000..d7fb34750 --- /dev/null +++ b/extended/python-gunicorn/centos/meta_patches/0001-TIS-gunicorn-19-upgrade.patch @@ -0,0 +1,118 @@ +From 64d535d3cb2589c36a679ea71e2331e650dde4bb Mon Sep 17 00:00:00 2001 +From: Prajeesh Murukan +Date: Tue, 23 May 2017 12:37:05 -0400 +Subject: [PATCH] WRS: 0001-TIS-gunicorn-19-upgrade.patch + CGTS-6825 (Continual growth of memory consumption by public keystone-ap) + Fix :gunicorn upgrade to 19.7.1 v + + +--- + SPECS/python-gunicorn.spec | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/SPECS/python-gunicorn.spec b/SPECS/python-gunicorn.spec +index b06c1c7..4c19cd5 100644 +--- a/SPECS/python-gunicorn.spec ++++ b/SPECS/python-gunicorn.spec +@@ -3,7 +3,7 @@ + + Name: python-%{upstream_name} + Version: 19.7.1 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Python WSGI application server + License: MIT + URL: http://gunicorn.org/ +@@ -15,6 +15,7 @@ Patch1: deprecate-gaiohttp-worker.patch + Patch101: 0001-use-dev-log-for-syslog.patch + # upstream version requirements are unnecessarily strict + Patch102: 0002-relax-version-requirements.patch ++ + BuildArch: noarch + + %description +@@ -31,7 +32,7 @@ BuildRequires: python2-pytest + BuildRequires: python2-mock + BuildRequires: python2-pytest-cov + BuildRequires: python2-sphinx +-BuildRequires: python2-sphinx_rtd_theme ++BuildRequires: python-sphinx_rtd_theme + Requires: python2-setuptools + + %description -n python2-%{upstream_name} +@@ -39,6 +40,7 @@ Gunicorn ("Green Unicorn") is a Python WSGI HTTP server for UNIX. It uses the + pre-fork worker model, ported from Ruby's Unicorn project. It supports WSGI, + Django, and Paster applications. + ++%if 0%{?with_python3} + %package -n python3-%{upstream_name} + Summary: %{summary} + %{?python_provide:%python_provide python3-%{upstream_name}} +@@ -47,11 +49,14 @@ BuildRequires: python3-setuptools + BuildRequires: python3-pytest + BuildRequires: python3-pytest-cov + Requires: python3-setuptools ++%endif + ++%if 0%{?with_python3} + %description -n python3-%{upstream_name} + Gunicorn ("Green Unicorn") is a Python WSGI HTTP server for UNIX. It uses the + pre-fork worker model, ported from Ruby's Unicorn project. It supports WSGI, + Django, and Paster applications. ++%endif + + %package doc + Summary: Documentation for the %{name} package +@@ -67,23 +72,33 @@ Documentation for the %{name} package. + + %build + %py2_build ++ ++%if 0%{?with_python3} + %py3_build ++%endif ++ + %{__python2} setup.py build_sphinx + + %install ++%if 0%{?with_python3} + %py3_install + # rename executables in /usr/bin so they don't collide + for executable in %{upstream_name} %{upstream_name}_paster ; do + mv %{buildroot}%{_bindir}/$executable %{buildroot}%{_bindir}/python3-$executable + done ++%endif ++ + %py2_install + # need to remove gaiohttp worker from the Python 2 version, it is supported on + # Python 3 only and it fails byte compilation on 2.x due to using "yield from" + rm %{buildroot}%{python2_sitelib}/%{upstream_name}/workers/_gaiohttp.py* + + %check +-%{__python2} setup.py test ++#%{__python2} setup.py test ++ ++%if 0%{?with_python3} + %{__python3} setup.py test ++%endif + + %files -n python2-%{upstream_name} + %license LICENSE +@@ -92,12 +107,14 @@ rm %{buildroot}%{python2_sitelib}/%{upstream_name}/workers/_gaiohttp.py* + %{_bindir}/%{upstream_name} + %{_bindir}/%{upstream_name}_paster + ++%if 0%{?with_python3} + %files -n python3-%{upstream_name} + %license LICENSE + %doc NOTICE README.rst THANKS + %{python3_sitelib}/%{upstream_name}* + %{_bindir}/python3-%{upstream_name} + %{_bindir}/python3-%{upstream_name}_paster ++%endif + + %files doc + %license LICENSE +-- +1.8.3.1 +i diff --git a/extended/python-gunicorn/centos/meta_patches/0001-TIS-packaging.patch b/extended/python-gunicorn/centos/meta_patches/0001-TIS-packaging.patch new file mode 100644 index 000000000..eadc82978 --- /dev/null +++ b/extended/python-gunicorn/centos/meta_patches/0001-TIS-packaging.patch @@ -0,0 +1,25 @@ +From 1f7502ce81b5b662728a21618009802f4bfa47d2 Mon Sep 17 00:00:00 2001 +From: Giao Le +Date: Mon, 21 Nov 2016 15:27:34 -0500 +Subject: [PATCH 1/1] TIS packaging + +--- + SPECS/python-gunicorn.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/python-gunicorn.spec b/SPECS/python-gunicorn.spec +index 2da7590..86b6667 100644 +--- a/SPECS/python-gunicorn.spec ++++ b/SPECS/python-gunicorn.spec +@@ -7,7 +7,7 @@ + + Name: python-%{upstream_name} + Version: 18.0 +-Release: 2%{?dist} ++Release: 2.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Python WSGI application server + + Group: System Environment/Daemons +-- +1.8.3.1 + diff --git a/extended/python-gunicorn/centos/meta_patches/0001-add-worker-abort-patch.patch b/extended/python-gunicorn/centos/meta_patches/0001-add-worker-abort-patch.patch new file mode 100644 index 000000000..5b57db293 --- /dev/null +++ b/extended/python-gunicorn/centos/meta_patches/0001-add-worker-abort-patch.patch @@ -0,0 +1,32 @@ +From b0ad59c3a7992b5f171e8252cd02d1d207601f6a Mon Sep 17 00:00:00 2001 +From: Giao Le +Date: Tue, 22 Nov 2016 12:53:18 -0500 +Subject: [PATCH 1/1] add-worker-work-patch + +--- + SPECS/python-gunicorn.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/python-gunicorn.spec b/SPECS/python-gunicorn.spec +index 86b6667..acd6b90 100644 +--- a/SPECS/python-gunicorn.spec ++++ b/SPECS/python-gunicorn.spec +@@ -16,6 +16,7 @@ URL: http://gunicorn.org/ + Source0: http://pypi.python.org/packages/source/g/%{upstream_name}/%{upstream_name}-%{version}.tar.gz + # distro-specific, not upstreamable + Patch100: %{name}-dev-log.patch ++Patch200: 0001-add-worker-abort-hook.patch + + BuildArch: noarch + BuildRequires: python2-devel +@@ -48,6 +49,7 @@ Django, and Paster applications. + %prep + %setup -q -n %{upstream_name}-%{version} + %patch100 -p1 ++%patch200 -p1 + + %if 0%{?with_python3} + rm -rf %{py3dir} +-- +1.8.3.1 + diff --git a/extended/python-gunicorn/centos/meta_patches/PATCH_ORDER b/extended/python-gunicorn/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..108d333f4 --- /dev/null +++ b/extended/python-gunicorn/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-TIS-gunicorn-19-upgrade.patch diff --git a/extended/python-gunicorn/centos/patches/0001-add-worker-abort-hook.patch b/extended/python-gunicorn/centos/patches/0001-add-worker-abort-hook.patch new file mode 100644 index 000000000..b4ddbc6b7 --- /dev/null +++ b/extended/python-gunicorn/centos/patches/0001-add-worker-abort-hook.patch @@ -0,0 +1,92 @@ +From d78a84dc692f708afd90df3409f9e264c22231dd Mon Sep 17 00:00:00 2001 +From: Giao Le +Date: Tue, 22 Nov 2016 10:18:14 -0500 +Subject: [PATCH 1/1] add worker abort hook + +--- + gunicorn/arbiter.py | 9 +++++++-- + gunicorn/config.py | 18 ++++++++++++++++++ + gunicorn/workers/base.py | 7 +++++++ + 3 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py +index b48e5b7..4d2daad 100644 +--- a/gunicorn/arbiter.py ++++ b/gunicorn/arbiter.py +@@ -429,8 +429,13 @@ class Arbiter(object): + except ValueError: + continue + +- self.log.critical("WORKER TIMEOUT (pid:%s)", pid) +- self.kill_worker(pid, signal.SIGKILL) ++ if not worker.aborted: ++ self.log.critical("WORKER TIMEOUT (pid:%s)", pid) ++ worker.aborted = True ++ self.kill_worker(pid, signal.SIGABRT) ++ else: ++ self.kill_worker(pid, signal.SIGKILL) ++ + + def reap_workers(self): + """\ +diff --git a/gunicorn/config.py b/gunicorn/config.py +index efcc449..3aec7ae 100644 +--- a/gunicorn/config.py ++++ b/gunicorn/config.py +@@ -1282,6 +1282,24 @@ class PostWorkerInit(Setting): + """ + + ++class WorkerAbort(Setting): ++ name = "worker_abort" ++ section = "Server Hooks" ++ validator = validate_callable(1) ++ type = six.callable ++ ++ def worker_abort(worker): ++ pass ++ ++ default = staticmethod(worker_abort) ++ desc = """\ ++ Called when a worker received the SIGABRT signal. ++ This call generally happens on timeout. ++ The callable needs to accept one instance variable for the initialized ++ Worker. ++ """ ++ ++ + class PreExec(Setting): + name = "pre_exec" + section = "Server Hooks" +diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py +index 5566dd1..af785a1 100644 +--- a/gunicorn/workers/base.py ++++ b/gunicorn/workers/base.py +@@ -40,6 +40,7 @@ class Worker(object): + self.timeout = timeout + self.cfg = cfg + self.booted = False ++ self.aborted = False + + self.nr = 0 + self.max_requests = cfg.max_requests or MAXSIZE +@@ -120,6 +121,7 @@ class Worker(object): + signal.signal(signal.SIGINT, self.handle_exit) + signal.signal(signal.SIGWINCH, self.handle_winch) + signal.signal(signal.SIGUSR1, self.handle_usr1) ++ signal.signal(signal.SIGABRT, self.handle_abort) + # Don't let SIGQUIT and SIGUSR1 disturb active requests + # by interrupting system calls + if hasattr(signal, 'siginterrupt'): # python >= 2.6 +@@ -202,3 +204,8 @@ class Worker(object): + def handle_winch(self, sig, fname): + # Ignore SIGWINCH in worker. Fixes a crash on OpenBSD. + return ++ ++ def handle_abort(self, sig, frame): ++ self.alive = False ++ self.cfg.worker_abort(self) ++ sys.exit(1) +-- +1.8.3.1 + diff --git a/extended/python-gunicorn/centos/srpm_path b/extended/python-gunicorn/centos/srpm_path new file mode 100644 index 000000000..341ecdaf1 --- /dev/null +++ b/extended/python-gunicorn/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/python-gunicorn-19.7.1-1.fc27.src.rpm diff --git a/extended/python-ryu/centos/build_srpm.data b/extended/python-ryu/centos/build_srpm.data new file mode 100644 index 000000000..4a0fba410 --- /dev/null +++ b/extended/python-ryu/centos/build_srpm.data @@ -0,0 +1,4 @@ +TAR_NAME=python-ryu +SRC_DIR="$CGCS_BASE/git/ryu" +TIS_BASE_SRCREV=51a1130f6cdcb029a51b6a75d43ac5e4cdde7072 +TIS_PATCH_VER=GITREVCOUNT diff --git a/extended/python-ryu/centos/python-ryu.spec b/extended/python-ryu/centos/python-ryu.spec new file mode 100755 index 000000000..18c5a77aa --- /dev/null +++ b/extended/python-ryu/centos/python-ryu.spec @@ -0,0 +1,264 @@ +%{!?upstream_version: %global upstream_version %{version}%{?milestone}} + +%if 0%{?fedora} +%global with_python3 1 +%endif + +%global pypi_name ryu +%global service neutron + +Name: python-%{pypi_name} +Version: 4.19 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Summary: Component-based Software-defined Networking Framework + +License: Apache-2.0 +Url: https://osrg.github.io/ryu +Source0: %{name}-%{version}.tar.gz + +BuildArch: noarch + +%description +Ryu provides software components with well defined API that make it easy for developers to create new +network management and control applications. + +%package -n python2-%{pypi_name} +Summary: Component-based Software-defined Networking Framework +%{?python_provide:%python_provide python2-%{pypi_name}} + +Requires: python-eventlet +Requires: python-debtcollector +Requires: python-lxml +Requires: python-msgpack +Requires: python-netaddr +#Requires: python-openvswitch +Requires: python-oslo-config +Requires: python-paramiko +Requires: python-routes +Requires: python-six +Requires: python-tinyrpc +Requires: python-webob +Requires: python-%{pypi_name}-common = %{version}-%{release} + +BuildRequires: python2-devel +BuildRequires: python-debtcollector +BuildRequires: python-eventlet +BuildRequires: python-greenlet +BuildRequires: python-lxml +BuildRequires: python-msgpack +#BuildRequires: python-openvswitch +BuildRequires: python-oslo-config +BuildRequires: python-paramiko +BuildRequires: python-repoze-lru +BuildRequires: python-routes +BuildRequires: python-sphinx +BuildRequires: python-tinyrpc +BuildRequires: python-setuptools +BuildRequires: python-webob + +%if 0%{?with_check} +BuildRequires: pylint +BuildRequires: python-coverage +BuildRequires: python-formencode +BuildRequires: python-nose +BuildRequires: python-mock +BuildRequires: python-pep8 +BuildRequires: python-tinyrpc +%endif + +%description -n python2-%{pypi_name} +Ryu provides software components with well defined API that make it easy for developers to create new +network management and control applications. + +%if 0%{?with_python3} +%package -n python3-%{pypi_name} +Summary: Component-based Software-defined Networking Framework +%{?python_provide:%python_provide python3-%{pypi_name}} + +Requires: python3-eventlet +Requires: python3-debtcollector +Requires: python3-lxml +Requires: python3-msgpack +Requires: python3-netaddr +#Requires: python3-openvswitch +Requires: python3-oslo-config +Requires: python3-paramiko +Requires: python3-routes +Requires: python3-six +Requires: python3-tinyrpc +Requires: python3-webob +Requires: python-%{pypi_name}-common = %{version}-%{release} + +BuildRequires: python3-devel +BuildRequires: python3-debtcollector +BuildRequires: python3-eventlet +BuildRequires: python3-greenlet +BuildRequires: python3-lxml +BuildRequires: python3-msgpack +#BuildRequires: python3-openvswitch +BuildRequires: python3-oslo-config +BuildRequires: python3-paramiko +BuildRequires: python3-repoze-lru +BuildRequires: python3-routes +BuildRequires: python3-sphinx +BuildRequires: python3-setuptools +BuildRequires: python3-tinyrpc +BuildRequires: python3-webob + +%if 0%{?with_check} +BuildRequires: python3-coverage +BuildRequires: python3-formencode +BuildRequires: python3-mock +BuildRequires: python3-nose +BuildRequires: python3-pep8 +%endif + +%description -n python3-%{pypi_name} +Ryu provides software components with well defined API that make it easy for developers to create new +network management and control applications. + +This is the Python 3 version. +%endif + +%package -n python-%{pypi_name}-common +Summary: Component-based Software-defined Networking Framework + +%description -n python-%{pypi_name}-common +Ryu provides software components with well defined API that make it easy for developers to create new +network management and control applications. + +This package contains common data between python 2 and 3 versions + +%package -n python-%{pypi_name}-tests +Summary: Ryu tests +Requires: python-%{pypi_name} = %{version}-%{release} +%description -n python-%{pypi_name}-tests +Ryu set of tests + +%prep +%autosetup -n %{name}-%{upstream_version} +# Remove bundled egg-info +rm -rf %{pypi_name}.egg-info +# drop deps in egginfo, let rpm handle them +rm tools/*-requires +rm tools/install_venv.py +# Remove non-working tests (internet connection needed) +rm -vf %{pypi_name}/tests/unit/test_requirements.py +# Remove pip usage (used only in test_requirements.py) +sed -i '/^from pip/d' ryu/utils.py +# Remove docker based tests (internet connection needed) +rm -rf %{pypi_name}/tests/integrated/bgp +rm -rf %{pypi_name}/tests/integrated/common + +%build +export PBR_VERSION=%{version} +%py2_build +%if 0%{?with_python3} +%py3_build +%endif + +cd doc && make man + +%install +export PBR_VERSION=%{version} +%if 0%{?with_python3} +%py3_install +for bin in %{pypi_name}{,-manager}; do + mv %{buildroot}%{_bindir}/$bin %{buildroot}%{_bindir}/$bin-%{python3_version} + ln -s ./$bin-%{python3_version} %{buildroot}%{_bindir}/$bin-3 +done; +%endif +%py2_install +for bin in %{pypi_name}{,-manager}; do + mv %{buildroot}%{_bindir}/$bin %{buildroot}%{_bindir}/$bin-%{python2_version} + ln -s ./$bin-%{python2_version} %{buildroot}%{_bindir}/$bin-2 + ln -s ./$bin-%{python2_version} %{buildroot}%{_bindir}/$bin +done; + + +install -d -m 755 %{buildroot}%{_sysconfdir}/%{pypi_name} +mv %{buildroot}%{_prefix}%{_sysconfdir}/%{pypi_name}/%{pypi_name}.conf %{buildroot}%{_sysconfdir}/%{pypi_name}/%{pypi_name}.conf + +%if 0%{?with_check} +%check +%if 0%{?with_python3} +# Tests without virtualenv (N) and without PEP8 tests (P) +PYTHON=%{__python3} ./run_tests.sh -N -P +%endif +PYTHON=%{__python2} ./run_tests.sh -N -P +%endif + +%files -n python2-%{pypi_name} +%{python2_sitelib}/%{pypi_name}-%{version}-py?.?.egg-info +%{python2_sitelib}/%{pypi_name} +%{_bindir}/%{pypi_name} +%{_bindir}/%{pypi_name}-2 +%{_bindir}/%{pypi_name}-%{python2_version} +%{_bindir}/%{pypi_name}-manager +%{_bindir}/%{pypi_name}-manager-2 +%{_bindir}/%{pypi_name}-manager-%{python2_version} +%exclude %{python2_sitelib}/%{pypi_name}/tests + + +%if 0%{?with_python3} +%files -n python3-%{pypi_name} +%{python3_sitelib}/%{pypi_name}-%{version}-py?.?.egg-info +%{python3_sitelib}/%{pypi_name} +%{_bindir}/%{pypi_name} +%{_bindir}/%{pypi_name}-3 +%{_bindir}/%{pypi_name}-%{python3_version} +%{_bindir}/%{pypi_name}-manager +%{_bindir}/%{pypi_name}-manager-3 +%{_bindir}/%{pypi_name}-manager-%{python3_version} +%exclude %{python2_sitelib}/%{pypi_name}/tests +%endif + +%files -n python-%{pypi_name}-common +%doc README.rst +%license LICENSE +%dir %attr(0755, root, %{service}) %{_sysconfdir}/%{pypi_name} +%config(noreplace) %attr(0640, root, %{service}) %{_sysconfdir}/%{pypi_name}/%{pypi_name}.conf +%exclude %{python2_sitelib}/%{pypi_name}/tests + +%files -n python-%{pypi_name}-tests +%license LICENSE +%{python2_sitelib}/%{pypi_name}/tests + +%changelog +* Tue Jul 04 2017 Matt Peters - 4.15-0 +- Upstream 4.15 and Titanium versioning + +* Mon May 29 2017 Lumír Balhar - 4.13-2 +- Tests enabled + +* Mon May 29 2017 Alan Pevec 4.13-1 +- Update to 4.13 +- Add missing dependencies + +* Sat Feb 11 2017 Fedora Release Engineering - 4.3-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Dec 19 2016 Miro Hrončok - 4.3-5 +- Rebuild for Python 3.6 + +* Wed Sep 07 2016 Arie Bregman - 4.3-4 +- Moved tests related lines to depend on with_check + +* Tue Jul 19 2016 Fedora Release Engineering - 4.3-3 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Fri Jul 01 2016 Matthias Runge - 4.3-2 +- add python_provides for python2 package + +* Thu Jun 23 2016 Haïkel Guémar - 4.3-1 +- Upstream 4.3 +- Enable python3 subpackage + +* Thu Apr 7 2016 Haïkel Guémar - 3.30-1 +- Upstream 3.30 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.26-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Sun Nov 22 2015 Arie Bregman - 3.26-1 +- Initial package. diff --git a/extended/python-smartpm/centos/build_srpm.data b/extended/python-smartpm/centos/build_srpm.data new file mode 100644 index 000000000..04778b821 --- /dev/null +++ b/extended/python-smartpm/centos/build_srpm.data @@ -0,0 +1,6 @@ +CLIENT_NAME=python-smartpm +VERSION=1.4.1 + +COPY_LIST="$CGCS_BASE/downloads/$CLIENT_NAME-$VERSION.tar.gz $PKG_BASE/files/* $PKG_BASE/centos/patches/*" + +TIS_PATCH_VER=2 diff --git a/extended/python-smartpm/centos/centos.info b/extended/python-smartpm/centos/centos.info new file mode 100644 index 000000000..08d4d9dd4 --- /dev/null +++ b/extended/python-smartpm/centos/centos.info @@ -0,0 +1,6 @@ +https://github.com/smartpm/smart/releases/tag/1.4.1 + +Additional 20 patches from os-core/meta/recipes-devtools/python-smartpm + + + diff --git a/extended/python-smartpm/centos/patches/smart-add-for-rpm-ignoresize-check.patch b/extended/python-smartpm/centos/patches/smart-add-for-rpm-ignoresize-check.patch new file mode 100644 index 000000000..6ee23c5f3 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-add-for-rpm-ignoresize-check.patch @@ -0,0 +1,13 @@ +--- a/smart/backends/rpm/pm.py 2014-02-14 14:14:18.877737747 +0800 ++++ b/smart/backends/rpm/pm.py 2014-02-14 14:17:17.394560608 +0800 +@@ -232,6 +232,10 @@ + if sysconf.get("rpm-order"): + ts.order() + probfilter = rpm.RPMPROB_FILTER_OLDPACKAGE ++ if sysconf.get("rpm-ignoresize", False): ++ probfilter |= rpm.RPMPROB_FILTER_DISKNODES ++ probfilter |= rpm.RPMPROB_FILTER_DISKSPACE ++ + if force or reinstall: + probfilter |= rpm.RPMPROB_FILTER_REPLACEPKG + probfilter |= rpm.RPMPROB_FILTER_REPLACEOLDFILES diff --git a/extended/python-smartpm/centos/patches/smart-attempt.patch b/extended/python-smartpm/centos/patches/smart-attempt.patch new file mode 100644 index 000000000..82d2e6cf3 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-attempt.patch @@ -0,0 +1,223 @@ +From b105e7fe812da3ccaf7155c0fe14c8728b0d39a5 Mon Sep 17 00:00:00 2001 +From: Mark Hatle +Date: Mon, 20 Jan 2014 14:30:52 +0000 +Subject: [PATCH] Add mechanism to attempt install without failing + +In OpenEmbedded, for complementary and 'attemptonly' package processing, +we need a way to instruct smart to try to install, but ignore any +failures (usually conflicts). + +This option only works for the install operation. + +If a complementary install fails, an actual error occurred, one that +we can't ignore without losing the entire attempted transaction. Keep +this as an error so that we can catch these cases in the futre. + +Upstream-Status: Pending + +Signed-off-by: Mark Hatle +Signed-off-by: Paul Eggleton +--- + smart.py | 5 +++- + smart/commands/install.py | 5 ++++ + smart/transaction.py | 65 +++++++++++++++++++++++++++++++++++------------ + 3 files changed, 58 insertions(+), 17 deletions(-) + +Index: smart-1.4.1/smart/commands/install.py +=================================================================== +--- smart-1.4.1.orig/smart/commands/install.py ++++ smart-1.4.1/smart/commands/install.py +@@ -50,6 +50,8 @@ def option_parser(): + parser = OptionParser(usage=USAGE, + description=DESCRIPTION, + examples=EXAMPLES) ++ parser.add_option("--attempt", action="store_true", ++ help=_("attempt to install packages, ignore failures")) + parser.add_option("--stepped", action="store_true", + help=_("split operation in steps")) + parser.add_option("--urls", action="store_true", +@@ -80,6 +82,9 @@ def main(ctrl, opts): + if not opts.args: + raise Error, _("no package(s) given") + ++ if opts.attempt: ++ sysconf.set("attempt-install", True, soft=True) ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +Index: smart-1.4.1/smart/transaction.py +=================================================================== +--- smart-1.4.1.orig/smart/transaction.py ++++ smart-1.4.1/smart/transaction.py +@@ -555,6 +555,8 @@ class Transaction(object): + changeset.set(pkg, INSTALL) + isinst = changeset.installed + ++ attempt = sysconf.has("attempt-install", soft=True) ++ + # Remove packages conflicted by this one. + for cnf in pkg.conflicts: + for prv in cnf.providedby: +@@ -564,11 +566,16 @@ class Transaction(object): + if not isinst(prvpkg): + locked[prvpkg] = (LOCKED_CONFLICT_BY, pkg) + continue +- if prvpkg in locked: +- raise Failed, _("Can't install %s: conflicted package " +- "%s is locked") % (pkg, prvpkg) +- self._remove(prvpkg, changeset, locked, pending, depth) +- pending.append((PENDING_UPDOWN, prvpkg)) ++ if attempt: ++ del changeset[pkg] ++ raise Failed, _("Can't install %s: it conflicts with package " ++ "%s") % (pkg, prvpkg) ++ else: ++ if prvpkg in locked: ++ raise Failed, _("Can't install %s: conflicted package " ++ "%s is locked") % (pkg, prvpkg) ++ self._remove(prvpkg, changeset, locked, pending, depth) ++ pending.append((PENDING_UPDOWN, prvpkg)) + + # Remove packages conflicting with this one. + for prv in pkg.provides: +@@ -579,12 +586,18 @@ class Transaction(object): + if not isinst(cnfpkg): + locked[cnfpkg] = (LOCKED_CONFLICT, pkg) + continue +- if cnfpkg in locked: ++ if attempt: ++ del changeset[pkg] + raise Failed, _("Can't install %s: it's conflicted by " +- "the locked package %s") \ +- % (pkg, cnfpkg) +- self._remove(cnfpkg, changeset, locked, pending, depth) +- pending.append((PENDING_UPDOWN, cnfpkg)) ++ "the package %s") \ ++ % (pkg, cnfpkg) ++ else: ++ if cnfpkg in locked: ++ raise Failed, _("Can't install %s: it's conflicted by " ++ "the locked package %s") \ ++ % (pkg, cnfpkg) ++ self._remove(cnfpkg, changeset, locked, pending, depth) ++ pending.append((PENDING_UPDOWN, cnfpkg)) + + # Remove packages with the same name that can't + # coexist with this one. +@@ -594,10 +607,15 @@ class Transaction(object): + if not isinst(namepkg): + locked[namepkg] = (LOCKED_NO_COEXIST, pkg) + continue +- if namepkg in locked: ++ if attempt: ++ del changeset[pkg] + raise Failed, _("Can't install %s: it can't coexist " + "with %s") % (pkg, namepkg) +- self._remove(namepkg, changeset, locked, pending, depth) ++ else: ++ if namepkg in locked: ++ raise Failed, _("Can't install %s: it can't coexist " ++ "with %s") % (pkg, namepkg) ++ self._remove(namepkg, changeset, locked, pending, depth) + + # Install packages required by this one. + for req in pkg.requires + pkg.recommends: +@@ -1176,6 +1194,8 @@ class Transaction(object): + + self._policy.runStarting() + ++ attempt = sysconf.has("attempt-install", soft=True) ++ + try: + changeset = self._changeset.copy() + isinst = changeset.installed +@@ -1190,7 +1210,11 @@ class Transaction(object): + locked[pkg] = (LOCKED_KEEP, None) + elif op is INSTALL: + if not isinst(pkg) and pkg in locked: +- raise Failed, _("Can't install %s: it's locked") % pkg ++ if attempt: ++ iface.warning(_("Can't install %s: it's locked") % pkg) ++ del changeset[pkg] ++ else: ++ raise Failed, _("Can't install %s: it's locked") % pkg + changeset.set(pkg, INSTALL) + locked[pkg] = (LOCKED_INSTALL, None) + elif op is REMOVE: +@@ -1216,9 +1240,18 @@ class Transaction(object): + else: + op = REMOVE + if op is INSTALL or op is REINSTALL: +- self._install(pkg, changeset, locked, pending) +- if pkg in changeset: +- changeset.setRequested(pkg, True) ++ try: ++ self._install(pkg, changeset, locked, pending) ++ if pkg in changeset: ++ changeset.setRequested(pkg, True) ++ except Failed, e: ++ if attempt: ++ iface.warning(_("Can't install %s: %s") % (pkg, e)) ++ if pkg in changeset: ++ del changeset[pkg] ++ continue ++ else: ++ raise Failed, e + elif op is REMOVE: + self._remove(pkg, changeset, locked, pending) + elif op is UPGRADE: +Index: smart-1.4.1/smart/backends/rpm/pm.py +=================================================================== +--- smart-1.4.1.orig/smart/backends/rpm/pm.py ++++ smart-1.4.1/smart/backends/rpm/pm.py +@@ -243,15 +253,48 @@ class RPMPackageManager(PackageManager): + cb = RPMCallback(prog, upgradednames) + cb.grabOutput(True) + probs = None ++ retry = 0 + try: + probs = ts.run(cb, None) + finally: + del getTS.ts + cb.grabOutput(False) ++ if probs and sysconf.has("attempt-install", soft=True): ++ def remove_conflict(pkgNEVR): ++ for key in changeset.keys(): ++ if pkgNEVR == str(key): ++ del changeset[key] ++ del pkgpaths[key] ++ iface.warning("Removing %s due to file %s conflicting with %s" % (pkgNEVR, fname, altNEVR)) ++ break ++ ++ retry = 1 ++ for prob in probs: ++ if prob[1][0] == rpm.RPMPROB_NEW_FILE_CONFLICT: ++ msg = prob[0].split() ++ fname = msg[1] ++ pkgNEVR = msg[7] ++ altNEVR = msg[9] ++ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1] ++ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1] ++ remove_conflict(pkgNEVR) ++ elif prob[1][0] == rpm.RPMPROB_FILE_CONFLICT: ++ msg = prob[0].split() ++ fname = msg[1] ++ pkgNEVR = msg[5] ++ altNEVR = msg[11] ++ pkgNEVR = pkgNEVR.rsplit('.', 1)[0] + '@' + pkgNEVR.rsplit('.', 1)[1] ++ altNEVR = altNEVR.rsplit('.', 1)[0] + '@' + altNEVR.rsplit('.', 1)[1] ++ remove_conflict(pkgNEVR) ++ else: ++ retry = 0 ++ + prog.setDone() +- if probs: ++ if probs and (not retry): + raise Error, "\n".join([x[0] for x in probs]) + prog.stop() ++ if retry and len(changeset): ++ self.commit(changeset, pkgpaths) + + class RPMCallback: + def __init__(self, prog, upgradednames): diff --git a/extended/python-smartpm/centos/patches/smart-channelsdir.patch b/extended/python-smartpm/centos/patches/smart-channelsdir.patch new file mode 100644 index 000000000..e621b3387 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-channelsdir.patch @@ -0,0 +1,24 @@ +Make CHANNELSDIR in smart empty, since this causes host contamination issues +on some RPM-based hosts on which smart is already installed. + +[YOCTO #3881] + +Upstream-Status: Inappropriate [embedded specific] + +diff --git a/smart/plugins/channelsync.py b/smart/plugins/channelsync.py +index 3ba95ff..646d696 100644 +--- a/smart/plugins/channelsync.py ++++ b/smart/plugins/channelsync.py +@@ -23,7 +23,11 @@ from smart.channel import * + from smart import * + import os + +-CHANNELSDIR = "/etc/smart/channels/" ++# For now, we leave the definition of CHANNELSDIR empty. This prevents smart ++# from erroneously consider the build host's channels while setting up its ++# channels [YOCTO #3881]. If this feature will be used in the future, CHANNELSDIR ++# should be set to a proper value. ++CHANNELSDIR = "" + + def syncChannels(channelsdir, force=None): + diff --git a/extended/python-smartpm/centos/patches/smart-config-ignore-all-recommends.patch b/extended/python-smartpm/centos/patches/smart-config-ignore-all-recommends.patch new file mode 100644 index 000000000..df9d7799e --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-config-ignore-all-recommends.patch @@ -0,0 +1,24 @@ +Add a simple method to disable the install of recommended packages + +Upstream-Status: Pending + +Usage: + smart config --set ignore-all-recommends=1 + +Signed-off-by: Mark Hatle + +Index: smart-1.4.1/smart/transaction.py +=================================================================== +--- smart-1.4.1.orig/smart/transaction.py ++++ smart-1.4.1/smart/transaction.py +@@ -611,7 +611,9 @@ class Transaction(object): + for prv in req.providedby: + for prvpkg in prv.packages: + if not reqrequired: +- if pkgconf.testFlag("ignore-recommends", prvpkg): ++ if sysconf.get("ignore-all-recommends", 0) == 1: ++ continue ++ elif pkgconf.testFlag("ignore-recommends", prvpkg): + continue + if isinst(prvpkg): + found = True diff --git a/extended/python-smartpm/centos/patches/smart-conflict-provider.patch b/extended/python-smartpm/centos/patches/smart-conflict-provider.patch new file mode 100644 index 000000000..10a7447cb --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-conflict-provider.patch @@ -0,0 +1,196 @@ +Report a reason when a dependency could not be installed because it is locked + +If a requirement of a package is conflicted, depending on how the +solution is reached, the transaction code may eliminate all providers +of the requirement and then error out because nothing provides them. To +work around this, store a reason in the locked dict and report that back +if we need to, so for example instead of: + + error: Can't install packagegroup-core-ssh-dropbear-1.0-r1@all: no package provides dropbear + +we now get: + + error: Can't install packagegroup-core-ssh-dropbear-1.0-r1@all: unable to install provider for dropbear: + error: dropbear-2013.58-r1.0@armv5te is conflicted by openssh-sshd-6.2p2-r0@armv5te + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton +--- + smart/const.py | 7 +++++++ + smart/transaction.py | 58 +++++++++++++++++++++++++++++++++++++++++----------- + 2 files changed, 53 insertions(+), 12 deletions(-) + +diff --git a/smart/const.py b/smart/const.py +index 4d8e5cb..67c1ac5 100644 +--- a/smart/const.py ++++ b/smart/const.py +@@ -70,4 +70,11 @@ DATADIR = "/var/lib/smart/" + USERDATADIR = "~/.smart/" + CONFFILE = "config" + ++LOCKED_INSTALL = Enum('LOCKED_INSTALL') ++LOCKED_REMOVE = Enum('LOCKED_REMOVE') ++LOCKED_CONFLICT = Enum('LOCKED_CONFLICT') ++LOCKED_CONFLICT_BY = Enum('LOCKED_CONFLICT_BY') ++LOCKED_NO_COEXIST = Enum('LOCKED_NO_COEXIST') ++LOCKED_SYSCONF = Enum('LOCKED_SYSCONF') ++ + # vim:ts=4:sw=4:et +diff --git a/smart/transaction.py b/smart/transaction.py +index 300b9cc..dd9aa38 100644 +--- a/smart/transaction.py ++++ b/smart/transaction.py +@@ -19,10 +19,31 @@ + # along with Smart Package Manager; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # +-from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP ++from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP, LOCKED_INSTALL, LOCKED_CONFLICT, LOCKED_CONFLICT_BY, LOCKED_NO_COEXIST, LOCKED_SYSCONF, LOCKED_REMOVE + from smart.cache import PreRequires, Package + from smart import * + ++def lock_reason(pkg, lockvalue): ++ try: ++ (reason, otherpkg) = lockvalue ++ except TypeError: ++ reason = None ++ lockvalue = None ++ if reason == LOCKED_INSTALL: ++ return _("%s is to be installed") % pkg ++ elif reason == LOCKED_CONFLICT: ++ return _("%s conflicts with %s") % (pkg, otherpkg) ++ elif reason == LOCKED_CONFLICT_BY: ++ return _("%s is conflicted by %s") % (pkg, otherpkg) ++ elif reason == LOCKED_NO_COEXIST: ++ return _("%s cannot coexist with %s") % (pkg, otherpkg) ++ elif reason == LOCKED_SYSCONF: ++ return _("%s is locked in system configuration") % pkg ++ elif reason == LOCKED_REMOVE: ++ return _("%s is to be removed") % pkg ++ else: ++ return _("%s is locked (unknown reason)") % pkg ++ + class ChangeSet(dict): + + def __init__(self, cache, state=None, requested=None): +@@ -187,7 +208,7 @@ class Policy(object): + for pkg in pkgconf.filterByFlag("lock", cache.getPackages()): + if pkg not in self._locked: + self._sysconflocked.append(pkg) +- self._locked[pkg] = True ++ self._locked[pkg] = (LOCKED_SYSCONF, None) + + def runFinished(self): + self._priorities.clear() +@@ -524,7 +545,7 @@ class Transaction(object): + if ownpending: + pending = [] + +- locked[pkg] = True ++ locked[pkg] = (LOCKED_INSTALL, None) + changeset.set(pkg, INSTALL) + isinst = changeset.installed + +@@ -535,7 +556,7 @@ class Transaction(object): + if prvpkg is pkg: + continue + if not isinst(prvpkg): +- locked[prvpkg] = True ++ locked[prvpkg] = (LOCKED_CONFLICT_BY, pkg) + continue + if prvpkg in locked: + raise Failed, _("Can't install %s: conflicted package " +@@ -550,7 +571,7 @@ class Transaction(object): + if cnfpkg is pkg: + continue + if not isinst(cnfpkg): +- locked[cnfpkg] = True ++ locked[cnfpkg] = (LOCKED_CONFLICT, pkg) + continue + if cnfpkg in locked: + raise Failed, _("Can't install %s: it's conflicted by " +@@ -565,7 +586,7 @@ class Transaction(object): + for namepkg in namepkgs: + if namepkg is not pkg and not pkg.coexists(namepkg): + if not isinst(namepkg): +- locked[namepkg] = True ++ locked[namepkg] = (LOCKED_NO_COEXIST, pkg) + continue + if namepkg in locked: + raise Failed, _("Can't install %s: it can't coexist " +@@ -577,6 +598,7 @@ class Transaction(object): + + # Check if someone is already providing it. + prvpkgs = {} ++ lockedpkgs = {} + found = False + for prv in req.providedby: + for prvpkg in prv.packages: +@@ -585,6 +607,8 @@ class Transaction(object): + break + if prvpkg not in locked: + prvpkgs[prvpkg] = True ++ else: ++ lockedpkgs[prvpkg] = locked[prvpkg] + else: + continue + break +@@ -597,7 +621,17 @@ class Transaction(object): + if not prvpkgs: + # No packages provide it at all. Give up. + if req in pkg.requires: +- raise Failed, _("Can't install %s: no package provides %s") % \ ++ reasons = [] ++ for prv in req.providedby: ++ for prvpkg in prv.packages: ++ lockedres = lockedpkgs.get(prvpkg, None) ++ if lockedres: ++ reasons.append(lock_reason(prvpkg, lockedres)) ++ if reasons: ++ raise Failed, _("Can't install %s: unable to install provider for %s:\n %s") % \ ++ (pkg, req, '\n '.join(reasons)) ++ else: ++ raise Failed, _("Can't install %s: no package provides %s") % \ + (pkg, req) + else: + # It's only a recommend, skip +@@ -627,7 +661,7 @@ class Transaction(object): + if ownpending: + pending = [] + +- locked[pkg] = True ++ locked[pkg] = (LOCKED_REMOVE, None) + changeset.set(pkg, REMOVE) + isinst = changeset.installed + +@@ -1140,22 +1174,22 @@ class Transaction(object): + if op is KEEP: + if pkg in changeset: + del changeset[pkg] +- locked[pkg] = True ++ locked[pkg] = (LOCKED_KEEP, None) + elif op is INSTALL: + if not isinst(pkg) and pkg in locked: + raise Failed, _("Can't install %s: it's locked") % pkg + changeset.set(pkg, INSTALL) +- locked[pkg] = True ++ locked[pkg] = (LOCKED_INSTALL, None) + elif op is REMOVE: + if isinst(pkg) and pkg in locked: + raise Failed, _("Can't remove %s: it's locked") % pkg + changeset.set(pkg, REMOVE) +- locked[pkg] = True ++ locked[pkg] = (LOCKED_REMOVE, None) + elif op is REINSTALL: + if pkg in locked: + raise Failed, _("Can't reinstall %s: it's locked")%pkg + changeset.set(pkg, INSTALL, force=True) +- locked[pkg] = True ++ locked[pkg] = (LOCKED_INSTALL, None) + elif op is UPGRADE: + pass + +-- +1.8.1.2 + diff --git a/extended/python-smartpm/centos/patches/smart-dflags.patch b/extended/python-smartpm/centos/patches/smart-dflags.patch new file mode 100644 index 000000000..3f2726215 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-dflags.patch @@ -0,0 +1,40 @@ +backends/rpm: add support for setting dependency flags + +This is useful for OpenEmbedded so that we can do the equivalent of +the --nolinktos and --noparentdirs rpm command line options. + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py +index 707a146..aec82e7 100644 +--- a/smart/backends/rpm/pm.py ++++ b/smart/backends/rpm/pm.py +@@ -106,6 +106,23 @@ class RPMPackageManager(PackageManager): + flags |= rpm.RPMTRANS_FLAG_TEST + ts.setFlags(flags) + ++ dflags = ts.setDFlags(0) ++ if sysconf.get("rpm-noupgrade", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOUPGRADE ++ if sysconf.get("rpm-norequires", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOREQUIRES ++ if sysconf.get("rpm-noconflicts", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOCONFLICTS ++ if sysconf.get("rpm-noobsoletes", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOOBSOLETES ++ if sysconf.get("rpm-noparentdirs", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOPARENTDIRS ++ if sysconf.get("rpm-nolinktos", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOLINKTOS ++ if sysconf.get("rpm-nosuggest", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOSUGGEST ++ ts.setDFlags(dflags) ++ + # Set rpm verbosity level. + levelname = sysconf.get('rpm-log-level') + level = { +-- +1.7.9.5 + diff --git a/extended/python-smartpm/centos/patches/smart-filename-NAME_MAX.patch b/extended/python-smartpm/centos/patches/smart-filename-NAME_MAX.patch new file mode 100644 index 000000000..22794a738 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-filename-NAME_MAX.patch @@ -0,0 +1,35 @@ +From a17998b6be3319ae476a64f366737bc267a53a8a Mon Sep 17 00:00:00 2001 +From: Robert Yang +Date: Mon, 16 Sep 2013 05:54:13 -0400 +Subject: [PATCH] fetcher.py: truncate the filename to meet NAME_MAX + +The function getLocalPath() converts the filepath into the filename, +there would be a "File name too long" error when len(filename) > +NAME_MAX, truncate it to meet NAME_MAX will fix the problem. + +Signed-off-by: Robert Yang +--- + smart/fetcher.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/smart/fetcher.py b/smart/fetcher.py +--- a/smart/fetcher.py ++++ b/smart/fetcher.py +@@ -139,6 +139,14 @@ class Fetcher(object): + filename = os.path.basename(path) + if self._localpathprefix: + filename = self._localpathprefix+filename ++ # pathconf requires the path existed ++ if not os.path.exists(self._localdir): ++ os.makedirs(self._localdir) ++ name_max = os.pathconf(self._localdir, 'PC_NAME_MAX') ++ # The length of the filename should be less than NAME_MAX ++ if len(filename) > name_max: ++ iface.debug(_("Truncate %s to %s") % (filename, filename[-name_max:])) ++ filename = filename[-name_max:] + return os.path.join(self._localdir, filename) + + def setForceCopy(self, value): +-- +1.7.10.4 + diff --git a/extended/python-smartpm/centos/patches/smart-flag-exclude-packages.patch b/extended/python-smartpm/centos/patches/smart-flag-exclude-packages.patch new file mode 100644 index 000000000..21a28746a --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-flag-exclude-packages.patch @@ -0,0 +1,70 @@ +Add exclude-packages flag support + +Allow configuring specific packages to be excluded. This will allow +users to specify things NOT to install, and if they are attempted an +error will be generated. + +Upstream-Status: Pending + +Signed-off-by: Mark Hatle + +Index: smart-1.4.1/smart/const.py +=================================================================== +--- smart-1.4.1.orig/smart/const.py ++++ smart-1.4.1/smart/const.py +@@ -70,6 +70,7 @@ DATADIR = "/var/lib/smart/" + USERDATADIR = "~/.smart/" + CONFFILE = "config" + ++LOCKED_EXCLUDE = Enum('LOCKED_EXCLUDE') + LOCKED_INSTALL = Enum('LOCKED_INSTALL') + LOCKED_REMOVE = Enum('LOCKED_REMOVE') + LOCKED_CONFLICT = Enum('LOCKED_CONFLICT') +Index: smart-1.4.1/smart/transaction.py +=================================================================== +--- smart-1.4.1.orig/smart/transaction.py ++++ smart-1.4.1/smart/transaction.py +@@ -19,7 +19,7 @@ + # along with Smart Package Manager; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # +-from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP, LOCKED_INSTALL, LOCKED_CONFLICT, LOCKED_CONFLICT_BY, LOCKED_NO_COEXIST, LOCKED_SYSCONF, LOCKED_REMOVE ++from smart.const import INSTALL, REMOVE, UPGRADE, FIX, REINSTALL, KEEP, LOCKED_EXCLUDE, LOCKED_INSTALL, LOCKED_CONFLICT, LOCKED_CONFLICT_BY, LOCKED_NO_COEXIST, LOCKED_SYSCONF, LOCKED_REMOVE + from smart.cache import PreRequires, Package + from smart import * + +@@ -29,7 +29,9 @@ def lock_reason(pkg, lockvalue): + except TypeError: + reason = None + lockvalue = None +- if reason == LOCKED_INSTALL: ++ if reason == LOCKED_EXCLUDE: ++ return _("%s is to be excluded") % pkg ++ elif reason == LOCKED_INSTALL: + return _("%s is to be installed") % pkg + elif reason == LOCKED_CONFLICT: + return _("%s conflicts with %s") % (pkg, otherpkg) +@@ -210,6 +212,10 @@ class Policy(object): + self._sysconflocked.append(pkg) + self._locked[pkg] = (LOCKED_SYSCONF, None) + ++ for pkg in pkgconf.filterByFlag("exclude-packages", cache.getPackages()): ++ if pkg not in self._locked: ++ self._locked[pkg] = (LOCKED_EXCLUDE, None) ++ + def runFinished(self): + self._priorities.clear() + for pkg in self._sysconflocked: +Index: smart-1.4.1/smart/commands/flag.py +=================================================================== +--- smart-1.4.1.orig/smart/commands/flag.py ++++ smart-1.4.1/smart/commands/flag.py +@@ -47,6 +47,8 @@ Currently known flags are: + multi-version - Flagged packages may have more than one version + installed in the system at the same time + (backend dependent). ++ exclude-packages - Flagged packages will be excluded, if they are ++ required, an error will be generated. + ignore-recommends - Flagged packages will not be installed, if + they are only recommended by a package to be + installed rather than required. diff --git a/extended/python-smartpm/centos/patches/smart-flag-ignore-recommends.patch b/extended/python-smartpm/centos/patches/smart-flag-ignore-recommends.patch new file mode 100644 index 000000000..5d5c6f434 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-flag-ignore-recommends.patch @@ -0,0 +1,60 @@ +Add ignore-recommends flag support + +Allow configuring recommends on specific packages to be ignored. + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton +--- + smart/commands/flag.py | 3 +++ + smart/transaction.py | 7 ++++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/smart/commands/flag.py b/smart/commands/flag.py +index 8b90496..191bb11 100644 +--- a/smart/commands/flag.py ++++ b/smart/commands/flag.py +@@ -47,6 +47,9 @@ Currently known flags are: + multi-version - Flagged packages may have more than one version + installed in the system at the same time + (backend dependent). ++ ignore-recommends - Flagged packages will not be installed, if ++ they are only recommended by a package to be ++ installed rather than required. + + security - Flagged packages are updates for security errata. + bugfix - Flagged packages are updates for bugfix errata. +diff --git a/smart/transaction.py b/smart/transaction.py +index dd9aa38..38eabae 100644 +--- a/smart/transaction.py ++++ b/smart/transaction.py +@@ -596,12 +596,17 @@ class Transaction(object): + # Install packages required by this one. + for req in pkg.requires + pkg.recommends: + ++ reqrequired = req in pkg.requires ++ + # Check if someone is already providing it. + prvpkgs = {} + lockedpkgs = {} + found = False + for prv in req.providedby: + for prvpkg in prv.packages: ++ if not reqrequired: ++ if pkgconf.testFlag("ignore-recommends", prvpkg): ++ continue + if isinst(prvpkg): + found = True + break +@@ -620,7 +625,7 @@ class Transaction(object): + + if not prvpkgs: + # No packages provide it at all. Give up. +- if req in pkg.requires: ++ if reqrequired: + reasons = [] + for prv in req.providedby: + for prvpkg in prv.packages: +-- +1.8.1.2 + diff --git a/extended/python-smartpm/centos/patches/smart-improve-error-reporting.patch b/extended/python-smartpm/centos/patches/smart-improve-error-reporting.patch new file mode 100644 index 000000000..2ca0f6d59 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-improve-error-reporting.patch @@ -0,0 +1,253 @@ +Improve error reporting in smart + +Add code to check proper command line arguments for various +smart commands. Exit with error if erroneous/additional arguments +are given in the command line. + +Upstream-Status: Pending + +Signed-off-by: Bogdan Marinescu + +diff --git a/smart/commands/channel.py b/smart/commands/channel.py +index aa76f91..63fbb35 100644 +--- a/smart/commands/channel.py ++++ b/smart/commands/channel.py +@@ -157,7 +157,17 @@ def main(ctrl, opts): + opts.show is None and opts.yaml is None): + iface.warning(_("Can't edit channels information.")) + raise Error, _("Configuration is in readonly mode.") +- ++ ++ # Argument check ++ opts.check_args_of_option("set", -1) ++ opts.check_args_of_option("remove", -1) ++ opts.check_args_of_option("edit", 0) ++ opts.check_args_of_option("enable", -1) ++ opts.check_args_of_option("disable", -1) ++ opts.ensure_action("channel", ["add", "set", "remove", "remove_all", ++ "list", "show", "yaml", "enable", "disable"]) ++ opts.check_remaining_args() ++ + if opts.add is not None: + if not opts.add and opts.args == ["-"]: + newchannels = [] +diff --git a/smart/commands/check.py b/smart/commands/check.py +index b08608a..506e852 100644 +--- a/smart/commands/check.py ++++ b/smart/commands/check.py +@@ -72,6 +72,9 @@ def parse_options(argv): + + def main(ctrl, opts, reloadchannels=True): + ++ # Argument check ++ opts.check_args_of_option("channels", 1) ++ + if sysconf.get("auto-update"): + from smart.commands import update + updateopts = update.parse_options([]) +diff --git a/smart/commands/config.py b/smart/commands/config.py +index dd50dee..4fe4366 100644 +--- a/smart/commands/config.py ++++ b/smart/commands/config.py +@@ -80,6 +80,12 @@ def main(ctrl, opts): + globals["false"] = False + globals["no"] = False + ++ # Check arguments ++ opts.check_args_of_option("set", -1) ++ opts.check_args_of_option("remove", -1) ++ opts.ensure_action("config", ["set", "show", "yaml", "remove"]) ++ opts.check_remaining_args() ++ + if opts.set: + for opt in opts.set: + m = SETRE.match(opt) +diff --git a/smart/commands/download.py b/smart/commands/download.py +index 6837993..b853c61 100644 +--- a/smart/commands/download.py ++++ b/smart/commands/download.py +@@ -81,6 +81,14 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ opts.check_args_of_option("target", 1) ++ opts.check_args_of_option("output", 1) ++ opts.check_args_of_option("from_urls", -1) ++ opts.check_args_of_option("from_metalink", -1) ++ if not opts.args and not opts.from_metalink and not opts.from_urls: ++ raise Error, _("no package(s) given") ++ + packages = [] + if opts.args: + if sysconf.get("auto-update"): +diff --git a/smart/commands/info.py b/smart/commands/info.py +index 12f74f0..59fbe98 100644 +--- a/smart/commands/info.py ++++ b/smart/commands/info.py +@@ -58,6 +58,10 @@ def parse_options(argv): + + def main(ctrl, opts, reloadchannels=True): + ++ # Argument check ++ if not opts.args: ++ raise Error, _("No package(s) given") ++ + if sysconf.get("auto-update"): + from smart.commands import update + updateopts = update.parse_options([]) +diff --git a/smart/commands/install.py b/smart/commands/install.py +index 8a45954..590222c 100644 +--- a/smart/commands/install.py ++++ b/smart/commands/install.py +@@ -76,6 +76,10 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ if not opts.args: ++ raise Error, _("no package(s) given") ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/commands/reinstall.py b/smart/commands/reinstall.py +index e59d896..32da3e6 100644 +--- a/smart/commands/reinstall.py ++++ b/smart/commands/reinstall.py +@@ -68,7 +68,11 @@ def parse_options(argv): + return opts + + def main(ctrl, opts): +- ++ ++ # Argument check ++ if not opts.args: ++ raise Error, _("no package(s) given") ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/commands/remove.py b/smart/commands/remove.py +index b4823a6..acd3bbd 100644 +--- a/smart/commands/remove.py ++++ b/smart/commands/remove.py +@@ -74,6 +74,10 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ if not opts.args: ++ raise Error, _("no package(s) given") ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/commands/search.py b/smart/commands/search.py +index 0d0b573..44806b8 100644 +--- a/smart/commands/search.py ++++ b/smart/commands/search.py +@@ -44,6 +44,8 @@ def option_parser(): + def parse_options(argv): + opts = query.parse_options(argv, usage=USAGE, \ + description=DESCRIPTION, examples=EXAMPLES) ++ if not argv: ++ raise Error, _("Search expression not specified") + opts.name = opts.args + opts.summary = opts.args + opts.description = opts.args +diff --git a/smart/commands/upgrade.py b/smart/commands/upgrade.py +index ec86290..7e290d8 100644 +--- a/smart/commands/upgrade.py ++++ b/smart/commands/upgrade.py +@@ -91,6 +91,9 @@ def parse_options(argv): + + def main(ctrl, opts): + ++ # Argument check ++ opts.check_args_of_option("flag", 1) ++ + if opts.explain: + sysconf.set("explain-changesets", True, soft=True) + +diff --git a/smart/util/optparse.py b/smart/util/optparse.py +index 4a3d3a8..279b0bf 100644 +--- a/smart/util/optparse.py ++++ b/smart/util/optparse.py +@@ -70,6 +70,8 @@ import sys, os + import types + import textwrap + from gettext import gettext as _ ++from smart import Error ++import re + + def _repr(self): + return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self) +@@ -708,6 +710,12 @@ class Option: + self.action, self.dest, opt, value, values, parser) + + def take_action(self, action, dest, opt, value, values, parser): ++ # Keep all the options in the command line in the '_given_opts' array ++ # This will be used later to validate the command line ++ given_opts = getattr(parser.values, "_given_opts", []) ++ user_opt = re.sub(r"^\-*", "", opt).replace("-", "_") ++ given_opts.append(user_opt) ++ setattr(parser.values, "_given_opts", given_opts) + if action == "store": + setattr(values, dest, value) + elif action == "store_const": +@@ -819,6 +827,54 @@ class Values: + setattr(self, attr, value) + return getattr(self, attr) + ++ # Check if the given option has the specified number of arguments ++ # Raise an error if the option has an invalid number of arguments ++ # A negative number for 'nargs' means "at least |nargs| arguments are needed" ++ def check_args_of_option(self, opt, nargs, err=None): ++ given_opts = getattr(self, "_given_opts", []) ++ if not opt in given_opts: ++ return ++ values = getattr(self, opt, []) ++ if type(values) != type([]): ++ return ++ if nargs < 0: ++ nargs = -nargs ++ if len(values) >= nargs: ++ return ++ if not err: ++ if nargs == 1: ++ err = _("Option '%s' requires at least one argument") % opt ++ else: ++ err = _("Option '%s' requires at least %d arguments") % (opt, nargs) ++ raise Error, err ++ elif nargs == 0: ++ if len( values ) == 0: ++ return ++ raise Error, err ++ else: ++ if len(values) == nargs: ++ return ++ if not err: ++ if nargs == 1: ++ err = _("Option '%s' requires one argument") % opt ++ else: ++ err = _("Option '%s' requires %d arguments") % (opt, nargs) ++ raise Error, err ++ ++ # Check that at least one of the options in 'actlist' was given as an argument ++ # to the command 'cmdname' ++ def ensure_action(self, cmdname, actlist): ++ given_opts = getattr(self, "_given_opts", []) ++ for action in actlist: ++ if action in given_opts: ++ return ++ raise Error, _("No action specified for command '%s'") % cmdname ++ ++ # Check if there are any other arguments left after parsing the command line and ++ # raise an error if such arguments are found ++ def check_remaining_args(self): ++ if self.args: ++ raise Error, _("Invalid argument(s) '%s'" % str(self.args)) + + class OptionContainer: + diff --git a/extended/python-smartpm/centos/patches/smart-metadata-match.patch b/extended/python-smartpm/centos/patches/smart-metadata-match.patch new file mode 100644 index 000000000..d06f41660 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-metadata-match.patch @@ -0,0 +1,28 @@ +smart - backends/rmp/metadata.py: Fix incorrect call to the match function + +The match function should take three parameters, name, comparison, version... +The original code was passing it a reference to the object holding the data +instead, which caused the comparison in match to always fail. + +Upstream-Status: Pending + +Signed-off-by: Mark Hatle + +--- a/smart/backends/rpm/metadata.py ++++ b/smart/backends/rpm/metadata.py +@@ -332,13 +332,13 @@ + reqargs = [x for x in reqdict + if not ((x[2] is None or "=" in x[2]) and + (RPMProvides, x[1], x[3]) in prvdict or +- system_provides.match(*x[:3]))] ++ system_provides.match(x[1], x[2], x[3]))] + reqargs = collapse_libc_requires(reqargs) + + recargs = [x for x in recdict + if not ((x[2] is None or "=" in x[2]) and + (RPMProvides, x[1], x[3]) in prvdict or +- system_provides.match(*x[:3]))] ++ system_provides.match(x[1], x[2], x[3]))] + + prvargs = prvdict.keys() + cnfargs = cnfdict.keys() diff --git a/extended/python-smartpm/centos/patches/smart-multilib-fixes.patch b/extended/python-smartpm/centos/patches/smart-multilib-fixes.patch new file mode 100644 index 000000000..56fef79a5 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-multilib-fixes.patch @@ -0,0 +1,22 @@ +To fix some multilib issues, change the way the RPM backend decides +if two packages can coexist: if they have a different architecture, +automatically assume that they can coexist (which is fundamental for +multilib). + +Upstream-Status: Pending + +Signed-off-by: Bogdan Marinescu + +diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py +index 6e83d40..7140c1b 100644 +--- a/smart/backends/rpm/base.py ++++ b/smart/backends/rpm/base.py +@@ -228,6 +228,8 @@ class RPMPackage(Package): + return False + selfver, selfarch = splitarch(self.version) + otherver, otherarch = splitarch(other.version) ++ if selfarch != otherarch: ++ return True + selfcolor = getArchColor(selfarch) + othercolor = getArchColor(otherarch) + if (selfcolor and othercolor and selfcolor != othercolor and diff --git a/extended/python-smartpm/centos/patches/smart-recommends.patch b/extended/python-smartpm/centos/patches/smart-recommends.patch new file mode 100644 index 000000000..9e1076c20 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-recommends.patch @@ -0,0 +1,1362 @@ +Handle recommended packages in core and rpm backends + +Identify and store recommended packages in the cache, add a query option +to read them and ignore them if they are not present when installing. + +Initial identification code from Mark Hatle . + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py +index 0489e11..b9e9cb2 100644 +--- a/smart/backends/rpm/base.py ++++ b/smart/backends/rpm/base.py +@@ -198,6 +198,29 @@ class RPMPackage(Package): + break + else: + return False ++ srecs = fk(self.recommends) ++ orecs = fk(other.recommends) ++ if srecs != orecs: ++ for srec in srecs: ++ if srec.name[0] == "/" or srec in orecs: ++ continue ++ for orec in orecs: ++ if (srec.name == orec.name and ++ srec.relation == orec.relation and ++ checkver(srec.version, orec.version)): ++ break ++ else: ++ return False ++ for orec in orecs: ++ if orec.name[0] == "/" or orec in srecs: ++ continue ++ for srec in srecs: ++ if (srec.name == orec.name and ++ srec.relation == orec.relation and ++ checkver(srec.version, orec.version)): ++ break ++ else: ++ return False + return True + + def coexists(self, other): +diff --git a/smart/backends/rpm/header.py b/smart/backends/rpm/header.py +index 31786cc..4880f43 100644 +--- a/smart/backends/rpm/header.py ++++ b/smart/backends/rpm/header.py +@@ -292,6 +292,7 @@ class RPMHeaderLoader(Loader): + f = [0] + elif type(f) != list: + f = [f] ++ recdict = {} + reqdict = {} + for i in range(len(n)): + ni = n[i] +@@ -308,10 +309,16 @@ class RPMHeaderLoader(Loader): + # RPMSENSE_SCRIPT_PREUN | + # RPMSENSE_SCRIPT_POST | + # RPMSENSE_SCRIPT_POSTUN == 7744 +- reqdict[(f[i]&7744 and PreReq or Req, +- intern(ni), r, vi)] = True ++ #if (f[i]&rpm.RPMSENSE_MISSINGOK): ++ # recdict[(f[i]&7744 and PreReq or Req, ++ # intern(ni), r, vi)] = True ++ #else: ++ reqdict[(f[i]&7744 and PreReq or Req, ++ intern(ni), r, vi)] = True ++ recargs = collapse_libc_requires(recdict.keys()) + reqargs = collapse_libc_requires(reqdict.keys()) + else: ++ recargs = None + reqargs = None + + n = h[1054] # RPMTAG_CONFLICTNAME +@@ -365,7 +372,7 @@ class RPMHeaderLoader(Loader): + versionarch = "%s@%s" % (distversion, arch) + + pkg = self.buildPackage((Pkg, name, versionarch), +- prvargs, reqargs, upgargs, cnfargs) ++ prvargs, reqargs, upgargs, cnfargs, recargs) + pkg.loaders[self] = offset + self._offsets[offset] = pkg + self._groups[pkg] = intern(h[rpm.RPMTAG_GROUP]) +@@ -583,8 +590,8 @@ class URPMILoader(RPMHeaderListLoader): + def setErrataFlags(self, flagdict): + self._flagdict = flagdict + +- def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs): +- pkg = Loader.buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs) ++ def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs): ++ pkg = Loader.buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs) + name = pkgargs[1] + if hasattr(self, '_flagdict') and self._flagdict and name in self._flagdict: + if sysconf.getReadOnly(): +diff --git a/smart/backends/rpm/metadata.py b/smart/backends/rpm/metadata.py +index 2c54f39..568fe06 100644 +--- a/smart/backends/rpm/metadata.py ++++ b/smart/backends/rpm/metadata.py +@@ -165,6 +165,7 @@ class RPMMetaDataLoader(Loader): + distepoch = None + info = {} + reqdict = {} ++ recdict = {} + prvdict = {} + upgdict = {} + cnfdict = {} +@@ -287,12 +288,16 @@ class RPMMetaDataLoader(Loader): + + lasttag = queue[-1].tag + if lasttag == REQUIRES: +- if elem.get("pre") == "1": +- reqdict[(RPMPreRequires, +- ename, erelation, eversion)] = True ++ if elem.get("missingok") == "1": ++ recdict[(RPMRequires, ++ ename, erelation, eversion)] = True + else: +- reqdict[(RPMRequires, +- ename, erelation, eversion)] = True ++ if elem.get("pre") == "1": ++ reqdict[(RPMPreRequires, ++ ename, erelation, eversion)] = True ++ else: ++ reqdict[(RPMRequires, ++ ename, erelation, eversion)] = True + + elif lasttag == PROVIDES: + if ename[0] == "/": +@@ -328,6 +333,12 @@ class RPMMetaDataLoader(Loader): + (RPMProvides, x[1], x[3]) in prvdict or + system_provides.match(*x[:3]))] + reqargs = collapse_libc_requires(reqargs) ++ ++ recargs = [x for x in recdict ++ if not ((x[2] is None or "=" in x[2]) and ++ (RPMProvides, x[1], x[3]) in prvdict or ++ system_provides.match(*x[:3]))] ++ + prvargs = prvdict.keys() + cnfargs = cnfdict.keys() + upgargs = upgdict.keys() +@@ -339,7 +350,7 @@ class RPMMetaDataLoader(Loader): + versionarch = "%s@%s" % (distversion, arch) + + pkg = self.buildPackage((RPMPackage, name, versionarch), +- prvargs, reqargs, upgargs, cnfargs) ++ prvargs, reqargs, upgargs, cnfargs, recargs) + pkg.loaders[self] = info + + # Store the provided files for future usage. +@@ -362,6 +373,7 @@ class RPMMetaDataLoader(Loader): + distepoch = None + pkgid = None + reqdict.clear() ++ recdict.clear() + prvdict.clear() + upgdict.clear() + cnfdict.clear() +diff --git a/smart/cache.py b/smart/cache.py +index b829825..cec8bb3 100644 +--- a/smart/cache.py ++++ b/smart/cache.py +@@ -32,7 +32,8 @@ class Package(object): + self.name = name + self.version = version + self.provides = () +- self.requires = () ++ self.requires = [] ++ self.recommends = [] + self.upgrades = () + self.conflicts = () + self.installed = False +@@ -55,7 +56,9 @@ class Package(object): + fk([x for x in self.provides if x.name[0] != "/"]) != + fk([x for x in other.provides if x.name[0] != "/"]) or + fk([x for x in self.requires if x.name[0] != "/"]) != +- fk([x for x in other.requires if x.name[0] != "/"])): ++ fk([x for x in other.requires if x.name[0] != "/"]) or ++ fk([x for x in self.recommends if x.name[0] != "/"]) != ++ fk([x for x in other.recommends if x.name[0] != "/"])): + return False + return True + +@@ -110,6 +113,7 @@ class Package(object): + self.version, + self.provides, + self.requires, ++ self.recommends, + self.upgrades, + self.conflicts, + self.installed, +@@ -122,6 +126,7 @@ class Package(object): + self.version, + self.provides, + self.requires, ++ self.recommends, + self.upgrades, + self.conflicts, + self.installed, +@@ -274,6 +279,7 @@ class Provides(object): + self.version = version + self.packages = [] + self.requiredby = () ++ self.recommendedby = () + self.upgradedby = () + self.conflictedby = () + +@@ -401,7 +407,7 @@ class Loader(object): + def loadFileProvides(self, fndict): + pass + +- def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs): ++ def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs = None): + cache = self._cache + pkg = pkgargs[0](*pkgargs[1:]) + relpkgs = [] +@@ -427,6 +433,17 @@ class Loader(object): + relpkgs.append(req.packages) + pkg.requires.append(req) + ++ if recargs: ++ pkg.recommends = [] ++ for args in recargs: ++ rec = cache._objmap.get(args) ++ if not rec: ++ rec = args[0](*args[1:]) ++ cache._objmap[args] = rec ++ cache._recommends.append(rec) ++ relpkgs.append(rec.packages) ++ pkg.recommends.append(rec) ++ + if upgargs: + pkg.upgrades = [] + for args in upgargs: +@@ -572,6 +589,7 @@ class Cache(object): + self._packages = [] + self._provides = [] + self._requires = [] ++ self._recommends = [] + self._upgrades = [] + self._conflicts = [] + self._objmap = {} +@@ -581,6 +599,8 @@ class Cache(object): + del prv.packages[:] + if prv.requiredby: + del prv.requiredby[:] ++ if prv.recommendedby: ++ del prv.recommendedby[:] + if prv.upgradedby: + del prv.upgradedby[:] + if prv.conflictedby: +@@ -589,6 +609,10 @@ class Cache(object): + del req.packages[:] + if req.providedby: + del req.providedby[:] ++ for rec in self._recommends: ++ del rec.packages[:] ++ if rec.providedby: ++ del rec.providedby[:] + for upg in self._upgrades: + del upg.packages[:] + if upg.providedby: +@@ -600,6 +624,7 @@ class Cache(object): + del self._packages[:] + del self._provides[:] + del self._requires[:] ++ del self._recommends[:] + del self._upgrades[:] + del self._conflicts[:] + self._objmap.clear() +@@ -621,6 +646,7 @@ class Cache(object): + packages = {} + provides = {} + requires = {} ++ recommends = {} + upgrades = {} + conflicts = {} + objmap = self._objmap +@@ -646,6 +672,11 @@ class Cache(object): + if req not in requires: + objmap[req.getInitArgs()] = req + requires[req] = True ++ for rec in pkg.recommends[:]: ++ rec.packages.append(pkg) ++ if rec not in recommends: ++ objmap[rec.getInitArgs()] = rec ++ recommends[rec] = True + for upg in pkg.upgrades: + upg.packages.append(pkg) + if upg not in upgrades: +@@ -659,6 +690,7 @@ class Cache(object): + self._packages[:] = packages.keys() + self._provides[:] = provides.keys() + self._requires[:] = requires.keys() ++ self._recommends[:] = recommends.keys() + self._upgrades[:] = upgrades.keys() + self._conflicts[:] = conflicts.keys() + +@@ -710,6 +742,14 @@ class Cache(object): + lst.append(req) + else: + reqnames[name] = [req] ++ recnames = {} ++ for rec in self._recommends: ++ for name in rec.getMatchNames(): ++ lst = recnames.get(name) ++ if lst: ++ lst.append(rec) ++ else: ++ recnames[name] = [rec] + upgnames = {} + for upg in self._upgrades: + for name in upg.getMatchNames(): +@@ -739,6 +779,18 @@ class Cache(object): + prv.requiredby.append(req) + else: + prv.requiredby = [req] ++ lst = recnames.get(prv.name) ++ if lst: ++ for rec in lst: ++ if rec.matches(prv): ++ if rec.providedby: ++ rec.providedby.append(prv) ++ else: ++ rec.providedby = [prv] ++ if prv.recommendedby: ++ prv.recommendedby.append(rec) ++ else: ++ prv.recommendedby = [rec] + lst = upgnames.get(prv.name) + if lst: + for upg in lst: +@@ -782,6 +834,12 @@ class Cache(object): + else: + return [x for x in self._requires if x.name == name] + ++ def getRecommends(self, name=None): ++ if not name: ++ return self._recommends ++ else: ++ return [x for x in self._recommends if x.name == name] ++ + def getUpgrades(self, name=None): + if not name: + return self._upgrades +@@ -807,6 +865,12 @@ class Cache(object): + for req in self._requires: + if prvname in req.getMatchNames() and req.matches(prv): + searcher.addResult(req) ++ if searcher.recommends: ++ for prv in searcher.recommends: ++ prvname = prv.name ++ for req in self._recommends: ++ if prvname in req.getMatchNames() and req.matches(prv): ++ searcher.addResult(req) + if searcher.upgrades: + for prv in searcher.upgrades: + prvname = prv.name +@@ -839,6 +903,7 @@ class Cache(object): + self._packages = state["_packages"] + provides = {} + requires = {} ++ recommends = {} + upgrades = {} + conflicts = {} + for pkg in self._packages: +@@ -848,6 +913,9 @@ class Cache(object): + for req in pkg.requires: + req.packages.append(pkg) + requires[req] = True ++ for rec in pkg.recommends: ++ rec.packages.append(pkg) ++ recommends[rec] = True + for upg in pkg.upgrades: + upg.packages.append(pkg) + upgrades[upg] = True +@@ -856,6 +924,7 @@ class Cache(object): + conflicts[cnf] = True + self._provides = provides.keys() + self._requires = requires.keys() ++ self._recommends = recommends.keys() + self._upgrades = upgrades.keys() + self._conflicts = conflicts.keys() + self._objmap = {} +diff --git a/smart/ccache.c b/smart/ccache.c +index 7541e26..7193185 100644 +--- a/smart/ccache.c ++++ b/smart/ccache.c +@@ -82,6 +82,7 @@ typedef struct { + PyObject *version; + PyObject *provides; + PyObject *requires; ++ PyObject *recommends; + PyObject *upgrades; + PyObject *conflicts; + PyObject *installed; +@@ -96,6 +97,7 @@ typedef struct { + PyObject *version; + PyObject *packages; + PyObject *requiredby; ++ PyObject *recommendedby; + PyObject *upgradedby; + PyObject *conflictedby; + } ProvidesObject; +@@ -123,6 +125,7 @@ typedef struct { + PyObject *_packages; + PyObject *_provides; + PyObject *_requires; ++ PyObject *_recommends; + PyObject *_upgrades; + PyObject *_conflicts; + PyObject *_objmap; +@@ -211,7 +214,8 @@ Package_init(PackageObject *self, PyObject *args) + Py_INCREF(self->name); + Py_INCREF(self->version); + self->provides = PyTuple_New(0); +- self->requires = PyTuple_New(0); ++ self->requires = PyList_New(0); ++ self->recommends = PyList_New(0); + self->upgrades = PyTuple_New(0); + self->conflicts = PyTuple_New(0); + Py_INCREF(Py_False); +@@ -228,6 +232,7 @@ Package_traverse(PackageObject *self, visitproc visit, void *arg) + { + Py_VISIT(self->provides); + Py_VISIT(self->requires); ++ Py_VISIT(self->recommends); + Py_VISIT(self->upgrades); + Py_VISIT(self->conflicts); + Py_VISIT(self->loaders); +@@ -239,6 +244,7 @@ Package_clear(PackageObject *self) + { + Py_CLEAR(self->provides); + Py_CLEAR(self->requires); ++ Py_CLEAR(self->recommends); + Py_CLEAR(self->upgrades); + Py_CLEAR(self->conflicts); + Py_CLEAR(self->loaders); +@@ -252,6 +258,7 @@ Package_dealloc(PackageObject *self) + Py_XDECREF(self->version); + Py_XDECREF(self->provides); + Py_XDECREF(self->requires); ++ Py_XDECREF(self->recommends); + Py_XDECREF(self->upgrades); + Py_XDECREF(self->conflicts); + Py_XDECREF(self->installed); +@@ -453,6 +460,46 @@ Package_equals(PackageObject *self, PackageObject *other) + } + } + ++ ilen = 0; ++ jlen = 0; ++ for (i = 0; i != PyList_GET_SIZE(self->recommends); i++) { ++ PyObject *item = PyList_GET_ITEM(self->recommends, i); ++ if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) { ++ PyErr_SetString(PyExc_TypeError, "Depends instance expected"); ++ return NULL; ++ } ++ if (STR(((DependsObject *)item)->name)[0] != '/') ++ ilen += 1; ++ } ++ for (j = 0; j != PyList_GET_SIZE(other->recommends); j++) { ++ PyObject *item = PyList_GET_ITEM(other->recommends, j); ++ if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) { ++ PyErr_SetString(PyExc_TypeError, "Depends instance expected"); ++ return NULL; ++ } ++ if (STR(((DependsObject *)item)->name)[0] != '/') ++ jlen += 1; ++ } ++ if (ilen != jlen) { ++ ret = Py_False; ++ goto exit; ++ } ++ ++ ilen = PyList_GET_SIZE(self->recommends); ++ jlen = PyList_GET_SIZE(other->recommends); ++ for (i = 0; i != ilen; i++) { ++ PyObject *item = PyList_GET_ITEM(self->recommends, i); ++ if (STR(((DependsObject *)item)->name)[0] != '/') { ++ for (j = 0; j != jlen; j++) ++ if (item == PyList_GET_ITEM(other->recommends, j)) ++ break; ++ if (j == jlen) { ++ ret = Py_False; ++ goto exit; ++ } ++ } ++ } ++ + exit: + Py_INCREF(ret); + return ret; +@@ -606,13 +653,14 @@ Package_getPriority(PackageObject *self, PyObject *args) + static PyObject * + Package__getstate__(PackageObject *self, PyObject *args) + { +- PyObject *state = PyTuple_New(10); ++ PyObject *state = PyTuple_New(11); + if (!state) return NULL; + + Py_INCREF(self->name); + Py_INCREF(self->version); + Py_INCREF(self->provides); + Py_INCREF(self->requires); ++ Py_INCREF(self->recommends); + Py_INCREF(self->upgrades); + Py_INCREF(self->conflicts); + Py_INCREF(self->installed); +@@ -620,16 +668,17 @@ Package__getstate__(PackageObject *self, PyObject *args) + Py_INCREF(self->priority); + Py_INCREF(self->loaders); + +- PyTuple_SET_ITEM(state, 0, self->name); +- PyTuple_SET_ITEM(state, 1, self->version); +- PyTuple_SET_ITEM(state, 2, self->provides); +- PyTuple_SET_ITEM(state, 3, self->requires); +- PyTuple_SET_ITEM(state, 4, self->upgrades); +- PyTuple_SET_ITEM(state, 5, self->conflicts); +- PyTuple_SET_ITEM(state, 6, self->installed); +- PyTuple_SET_ITEM(state, 7, self->essential); +- PyTuple_SET_ITEM(state, 8, self->priority); +- PyTuple_SET_ITEM(state, 9, self->loaders); ++ PyTuple_SET_ITEM(state, 0, self->name); ++ PyTuple_SET_ITEM(state, 1, self->version); ++ PyTuple_SET_ITEM(state, 2, self->provides); ++ PyTuple_SET_ITEM(state, 3, self->requires); ++ PyTuple_SET_ITEM(state, 4, self->recommends); ++ PyTuple_SET_ITEM(state, 5, self->upgrades); ++ PyTuple_SET_ITEM(state, 6, self->conflicts); ++ PyTuple_SET_ITEM(state, 7, self->installed); ++ PyTuple_SET_ITEM(state, 8, self->essential); ++ PyTuple_SET_ITEM(state, 9, self->priority); ++ PyTuple_SET_ITEM(state, 10, self->loaders); + + return state; + } +@@ -637,7 +686,7 @@ Package__getstate__(PackageObject *self, PyObject *args) + static PyObject * + Package__setstate__(PackageObject *self, PyObject *state) + { +- if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != 10) { ++ if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != 11) { + PyErr_SetString(StateVersionError, ""); + return NULL; + } +@@ -645,18 +694,20 @@ Package__setstate__(PackageObject *self, PyObject *state) + self->version = PyTuple_GET_ITEM(state, 1); + self->provides = PyTuple_GET_ITEM(state, 2); + self->requires = PyTuple_GET_ITEM(state, 3); +- self->upgrades = PyTuple_GET_ITEM(state, 4); +- self->conflicts = PyTuple_GET_ITEM(state, 5); +- self->installed = PyTuple_GET_ITEM(state, 6); +- self->essential = PyTuple_GET_ITEM(state, 7); +- self->priority = PyTuple_GET_ITEM(state, 8); +- self->loaders = PyTuple_GET_ITEM(state, 9); ++ self->recommends = PyTuple_GET_ITEM(state, 4); ++ self->upgrades = PyTuple_GET_ITEM(state, 5); ++ self->conflicts = PyTuple_GET_ITEM(state, 6); ++ self->installed = PyTuple_GET_ITEM(state, 7); ++ self->essential = PyTuple_GET_ITEM(state, 8); ++ self->priority = PyTuple_GET_ITEM(state, 9); ++ self->loaders = PyTuple_GET_ITEM(state, 10); + + + Py_INCREF(self->name); + Py_INCREF(self->version); + Py_INCREF(self->provides); + Py_INCREF(self->requires); ++ Py_INCREF(self->recommends); + Py_INCREF(self->upgrades); + Py_INCREF(self->conflicts); + Py_INCREF(self->installed); +@@ -686,6 +737,7 @@ static PyMemberDef Package_members[] = { + {"version", T_OBJECT, OFF(version), 0, 0}, + {"provides", T_OBJECT, OFF(provides), 0, 0}, + {"requires", T_OBJECT, OFF(requires), 0, 0}, ++ {"recommends", T_OBJECT, OFF(recommends), 0, 0}, + {"upgrades", T_OBJECT, OFF(upgrades), 0, 0}, + {"conflicts", T_OBJECT, OFF(conflicts), 0, 0}, + {"installed", T_OBJECT, OFF(installed), 0, 0}, +@@ -750,6 +802,7 @@ Provides_init(ProvidesObject *self, PyObject *args) + Py_INCREF(self->version); + self->packages = PyList_New(0); + self->requiredby = PyTuple_New(0); ++ self->recommendedby = PyTuple_New(0); + self->upgradedby = PyTuple_New(0); + self->conflictedby = PyTuple_New(0); + return 0; +@@ -760,6 +813,7 @@ Provides_traverse(ProvidesObject *self, visitproc visit, void *arg) + { + Py_VISIT(self->packages); + Py_VISIT(self->requiredby); ++ Py_VISIT(self->recommendedby); + Py_VISIT(self->upgradedby); + Py_VISIT(self->conflictedby); + return 0; +@@ -770,6 +824,7 @@ Provides_clear(ProvidesObject *self) + { + Py_CLEAR(self->packages); + Py_CLEAR(self->requiredby); ++ Py_CLEAR(self->recommendedby); + Py_CLEAR(self->upgradedby); + Py_CLEAR(self->conflictedby); + return 0; +@@ -782,6 +837,7 @@ Provides_dealloc(ProvidesObject *self) + Py_XDECREF(self->version); + Py_XDECREF(self->packages); + Py_XDECREF(self->requiredby); ++ Py_XDECREF(self->recommendedby); + Py_XDECREF(self->upgradedby); + Py_XDECREF(self->conflictedby); + self->ob_type->tp_free((PyObject *)self); +@@ -960,6 +1016,7 @@ static PyMemberDef Provides_members[] = { + {"version", T_OBJECT, OFF(version), 0, 0}, + {"packages", T_OBJECT, OFF(packages), 0, 0}, + {"requiredby", T_OBJECT, OFF(requiredby), 0, 0}, ++ {"recommendedby", T_OBJECT, OFF(recommendedby), 0, 0}, + {"upgradedby", T_OBJECT, OFF(upgradedby), 0, 0}, + {"conflictedby", T_OBJECT, OFF(conflictedby), 0, 0}, + {NULL} +@@ -1555,6 +1612,7 @@ Loader_buildPackage(LoaderObject *self, PyObject *args) + PyObject *reqargs; + PyObject *upgargs; + PyObject *cnfargs; ++ PyObject *recargs = NULL; + PyObject *callargs; + + PyObject *pkg; +@@ -1574,9 +1632,10 @@ Loader_buildPackage(LoaderObject *self, PyObject *args) + + cache = (CacheObject *)self->_cache; + +- if (!PyArg_ParseTuple(args, "O!O&O&O&O&", &PyTuple_Type, &pkgargs, ++ if (!PyArg_ParseTuple(args, "O!O&O&O&O&|O&", &PyTuple_Type, &pkgargs, + mylist, &prvargs, mylist, &reqargs, +- mylist, &upgargs, mylist, &cnfargs)) ++ mylist, &upgargs, mylist, &cnfargs, ++ mylist, &recargs)) + return NULL; + + if (PyTuple_GET_SIZE(pkgargs) < 2) { +@@ -1701,6 +1760,59 @@ Loader_buildPackage(LoaderObject *self, PyObject *args) + } + } + ++ /* if recargs: */ ++ if (recargs) { ++ int i = 0; ++ int len = PyList_GET_SIZE(recargs); ++ /* pkg.recommends = [] */ ++ Py_DECREF(pkgobj->recommends); ++ pkgobj->recommends = PyList_New(len); ++ /* for args in recargs: */ ++ for (; i != len; i++) { ++ PyObject *args = PyList_GET_ITEM(recargs, i); ++ DependsObject *recobj; ++ PyObject *rec; ++ ++ if (!PyTuple_Check(args)) { ++ PyErr_SetString(PyExc_TypeError, ++ "Item in recargs is not a tuple"); ++ return NULL; ++ } ++ ++ /* rec = cache._objmap.get(args) */ ++ rec = PyDict_GetItem(cache->_objmap, args); ++ recobj = (DependsObject *)rec; ++ ++ /* if not rec: */ ++ if (!rec) { ++ if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 2) { ++ PyErr_SetString(PyExc_ValueError, "Invalid recargs tuple"); ++ return NULL; ++ } ++ /* rec = args[0](*args[1:]) */ ++ callargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); ++ rec = PyObject_CallObject(PyTuple_GET_ITEM(args, 0), callargs); ++ Py_DECREF(callargs); ++ if (!rec) return NULL; ++ recobj = (DependsObject *)rec; ++ ++ /* cache._objmap[args] = rec */ ++ PyDict_SetItem(cache->_objmap, args, rec); ++ Py_DECREF(rec); ++ ++ /* cache._recommends.append(rec) */ ++ PyList_Append(cache->_recommends, rec); ++ } ++ ++ /* relpkgs.append(rec.packages) */ ++ PyList_Append(relpkgs, recobj->packages); ++ ++ /* pkg.recommends.append(rec) */ ++ Py_INCREF(rec); ++ PyList_SET_ITEM(pkgobj->recommends, i, rec); ++ } ++ } ++ + /* if upgargs: */ + if (upgargs) { + int i = 0; +@@ -2391,6 +2503,7 @@ Cache_init(CacheObject *self, PyObject *args) + self->_packages = PyList_New(0); + self->_provides = PyList_New(0); + self->_requires = PyList_New(0); ++ self->_recommends = PyList_New(0); + self->_upgrades = PyList_New(0); + self->_conflicts = PyList_New(0); + self->_objmap = PyDict_New(); +@@ -2404,6 +2517,7 @@ Cache_traverse(CacheObject *self, visitproc visit, void *arg) + Py_VISIT(self->_packages); + Py_VISIT(self->_provides); + Py_VISIT(self->_requires); ++ Py_VISIT(self->_recommends); + Py_VISIT(self->_upgrades); + Py_VISIT(self->_conflicts); + Py_VISIT(self->_objmap); +@@ -2417,6 +2531,7 @@ Cache_clear(CacheObject *self) + Py_CLEAR(self->_packages); + Py_CLEAR(self->_provides); + Py_CLEAR(self->_requires); ++ Py_CLEAR(self->_recommends); + Py_CLEAR(self->_upgrades); + Py_CLEAR(self->_conflicts); + Py_CLEAR(self->_objmap); +@@ -2430,6 +2545,7 @@ Cache_dealloc(CacheObject *self) + Py_XDECREF(self->_packages); + Py_XDECREF(self->_provides); + Py_XDECREF(self->_requires); ++ Py_XDECREF(self->_recommends); + Py_XDECREF(self->_upgrades); + Py_XDECREF(self->_conflicts); + Py_XDECREF(self->_objmap); +@@ -2449,6 +2565,8 @@ Cache_reset(CacheObject *self, PyObject *args) + LIST_CLEAR(prvobj->packages); + if (PyList_Check(prvobj->requiredby)) + LIST_CLEAR(prvobj->requiredby); ++ if (PyList_Check(prvobj->recommendedby)) ++ LIST_CLEAR(prvobj->recommendedby); + if (PyList_Check(prvobj->upgradedby)) + LIST_CLEAR(prvobj->upgradedby); + if (PyList_Check(prvobj->conflictedby)) +@@ -2464,6 +2582,16 @@ Cache_reset(CacheObject *self, PyObject *args) + if (PyList_Check(reqobj->providedby)) + LIST_CLEAR(reqobj->providedby); + } ++ len = PyList_GET_SIZE(self->_recommends); ++ for (i = 0; i != len; i++) { ++ DependsObject *reqobj; ++ PyObject *req; ++ req = PyList_GET_ITEM(self->_recommends, i); ++ reqobj = (DependsObject *)req; ++ LIST_CLEAR(reqobj->packages); ++ if (PyList_Check(reqobj->providedby)) ++ LIST_CLEAR(reqobj->providedby); ++ } + len = PyList_GET_SIZE(self->_upgrades); + for (i = 0; i != len; i++) { + DependsObject *upgobj; +@@ -2487,6 +2615,7 @@ Cache_reset(CacheObject *self, PyObject *args) + LIST_CLEAR(self->_packages); + LIST_CLEAR(self->_provides); + LIST_CLEAR(self->_requires); ++ LIST_CLEAR(self->_recommends); + LIST_CLEAR(self->_upgrades); + LIST_CLEAR(self->_conflicts); + PyDict_Clear(self->_objmap); +@@ -2534,6 +2663,7 @@ Cache__reload(CacheObject *self, PyObject *args) + packages = {} + provides = {} + requires = {} ++ recommends = {} + upgrades = {} + conflicts = {} + objmap = self._objmap +@@ -2541,11 +2671,12 @@ Cache__reload(CacheObject *self, PyObject *args) + PyObject *packages = PyDict_New(); + PyObject *provides = PyDict_New(); + PyObject *requires = PyDict_New(); ++ PyObject *recommends = PyDict_New(); + PyObject *upgrades = PyDict_New(); + PyObject *conflicts = PyDict_New(); + PyObject *objmap = self->_objmap; + int i, ilen; +- if (!packages || !provides || !requires || !conflicts) ++ if (!packages || !provides || !requires || !recommends || !conflicts ) + return NULL; + + /* for loader in loaders: */ +@@ -2679,6 +2810,30 @@ Cache__reload(CacheObject *self, PyObject *args) + } + + /* ++ for rec in pkg.recommends: ++ rec.packages.append(pkg) ++ if rec not in recommends: ++ recommends[rec] = True ++ objmap[rec.getInitArgs()] = rec ++ */ ++ if (PyList_Check(pkg->recommends)) { ++ klen = PyList_GET_SIZE(pkg->recommends); ++ for (k = 0; k != klen; k++) { ++ PyObject *rec = PyList_GET_ITEM(pkg->recommends, k); ++ PyList_Append(((DependsObject *)rec)->packages, ++ (PyObject *)pkg); ++ if (!PyDict_GetItem(recommends, rec)) { ++ PyDict_SetItem(recommends, rec, Py_True); ++ args = PyObject_CallMethod(rec, "getInitArgs", ++ NULL); ++ if (!args) return NULL; ++ PyDict_SetItem(objmap, args, rec); ++ Py_DECREF(args); ++ } ++ } ++ } ++ ++ /* + for upg in pkg.upgrades: + upg.packages.append(pkg) + if upg not in upgrades: +@@ -2747,6 +2902,11 @@ Cache__reload(CacheObject *self, PyObject *args) + self->_requires = PyDict_Keys(requires); + Py_DECREF(requires); + ++ /* self._recommends[:] = recommends.keys() */ ++ Py_DECREF(self->_recommends); ++ self->_recommends = PyDict_Keys(recommends); ++ Py_DECREF(recommends); ++ + /* self._upgrades[:] = upgrades.keys() */ + Py_DECREF(self->_upgrades); + self->_upgrades = PyDict_Keys(upgrades); +@@ -2852,7 +3012,7 @@ PyObject * + Cache_linkDeps(CacheObject *self, PyObject *args) + { + int i, j, len; +- PyObject *reqnames, *upgnames, *cnfnames; ++ PyObject *reqnames, *recnames, *upgnames, *cnfnames; + PyObject *lst; + + /* reqnames = {} */ +@@ -2896,6 +3056,47 @@ Cache_linkDeps(CacheObject *self, PyObject *args) + Py_DECREF(seq); + } + ++ /* recnames = {} */ ++ recnames = PyDict_New(); ++ /* for rec in self._recommends: */ ++ len = PyList_GET_SIZE(self->_recommends); ++ for (i = 0; i != len; i++) { ++ PyObject *rec = PyList_GET_ITEM(self->_recommends, i); ++ ++ /* for name in rec.getMatchNames(): */ ++ PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL); ++ PyObject *seq = PySequence_Fast(names, "getMatchNames() returned " ++ "non-sequence object"); ++ int nameslen; ++ if (!seq) return NULL; ++ nameslen = PySequence_Fast_GET_SIZE(seq); ++ for (j = 0; j != nameslen; j++) { ++ PyObject *name = PySequence_Fast_GET_ITEM(seq, j); ++ ++ /* lst = recnames.get(name) */ ++ lst = PyDict_GetItem(recnames, name); ++ ++ /* ++ if lst: ++ lst.append(rec) ++ else: ++ recnames[name] = [rec] ++ */ ++ if (lst) { ++ PyList_Append(lst, rec); ++ } else { ++ lst = PyList_New(1); ++ Py_INCREF(rec); ++ PyList_SET_ITEM(lst, 0, rec); ++ PyDict_SetItem(recnames, name, lst); ++ Py_DECREF(lst); ++ } ++ } ++ ++ Py_DECREF(names); ++ Py_DECREF(seq); ++ } ++ + /* upgnames = {} */ + upgnames = PyDict_New(); + /* for upg in self._upgrades: */ +@@ -3035,6 +3236,56 @@ Cache_linkDeps(CacheObject *self, PyObject *args) + } + } + ++ /* lst = recnames.get(prv.name) */ ++ lst = PyDict_GetItem(recnames, prv->name); ++ ++ /* if lst: */ ++ if (lst) { ++ /* for rec in lst: */ ++ int reclen = PyList_GET_SIZE(lst); ++ for (j = 0; j != reclen; j++) { ++ DependsObject *rec = (DependsObject *)PyList_GET_ITEM(lst, j); ++ /* if rec.matches(prv): */ ++ PyObject *ret = PyObject_CallMethod((PyObject *)rec, "matches", ++ "O", (PyObject *)prv); ++ if (!ret) return NULL; ++ if (PyObject_IsTrue(ret)) { ++ /* ++ if rec.providedby: ++ rec.providedby.append(prv) ++ else: ++ rec.providedby = [prv] ++ */ ++ if (PyList_Check(rec->providedby)) { ++ PyList_Append(rec->providedby, (PyObject *)prv); ++ } else { ++ PyObject *_lst = PyList_New(1); ++ Py_INCREF(prv); ++ PyList_SET_ITEM(_lst, 0, (PyObject *)prv); ++ Py_DECREF(rec->providedby); ++ rec->providedby = _lst; ++ } ++ ++ /* ++ if prv.recommendedby: ++ prv.recommendedby.append(prv) ++ else: ++ prv.recommendedby = [prv] ++ */ ++ if (PyList_Check(prv->recommendedby)) { ++ PyList_Append(prv->recommendedby, (PyObject *)rec); ++ } else { ++ PyObject *_lst = PyList_New(1); ++ Py_INCREF(rec); ++ PyList_SET_ITEM(_lst, 0, (PyObject *)rec); ++ Py_DECREF(prv->recommendedby); ++ prv->recommendedby = _lst; ++ } ++ } ++ Py_DECREF(ret); ++ } ++ } ++ + /* lst = upgnames.get(prv.name) */ + lst = PyDict_GetItem(upgnames, prv->name); + +@@ -3139,6 +3390,7 @@ Cache_linkDeps(CacheObject *self, PyObject *args) + } + + Py_DECREF(reqnames); ++ Py_DECREF(recnames); + Py_DECREF(upgnames); + Py_DECREF(cnfnames); + +@@ -3215,6 +3467,29 @@ Cache_getRequires(CacheObject *self, PyObject *args) + } + + PyObject * ++Cache_getRecommends(CacheObject *self, PyObject *args) ++{ ++ const char *name = NULL; ++ PyObject *lst; ++ int i, len; ++ if (!PyArg_ParseTuple(args, "|s", &name)) ++ return NULL; ++ if (!name) { ++ Py_INCREF(self->_recommends); ++ return self->_recommends; ++ } ++ lst = PyList_New(0); ++ len = PyList_GET_SIZE(self->_recommends); ++ for (i = 0; i != len; i++) { ++ DependsObject *rec = ++ (DependsObject*)PyList_GET_ITEM(self->_recommends, i); ++ if (strcmp(STR(rec->name), name) == 0) ++ PyList_Append(lst, (PyObject *)rec); ++ } ++ return lst; ++} ++ ++PyObject * + Cache_getUpgrades(CacheObject *self, PyObject *args) + { + const char *name = NULL; +@@ -3324,6 +3599,38 @@ Cache_search(CacheObject *self, PyObject *searcher) + } + Py_DECREF(lst); + ++ lst = PyObject_GetAttrString(searcher, "recommends"); ++ if (lst == NULL || !PyList_Check(lst)) { ++ PyErr_SetString(PyExc_TypeError, "Invalid recommends attribute"); ++ return NULL; ++ } ++ for (i = 0; i != PyList_GET_SIZE(lst); i++) { ++ ProvidesObject *prv = (ProvidesObject *)PyList_GET_ITEM(lst, i); ++ for (j = 0; j != PyList_GET_SIZE(self->_recommends); j++) { ++ PyObject *rec = PyList_GET_ITEM(self->_recommends, j); ++ PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL); ++ PyObject *seq = PySequence_Fast(names, "getMatchNames() returned " ++ "non-sequence object"); ++ if (seq == NULL) return NULL; ++ for (k = 0; k != PySequence_Fast_GET_SIZE(seq); k++) { ++ if (strcmp(PyString_AS_STRING(PySequence_Fast_GET_ITEM(seq, k)), ++ PyString_AS_STRING(prv->name)) == 0) { ++ res = PyObject_CallMethod(rec, "matches", "O", prv); ++ if (res == NULL) ++ return NULL; ++ if (PyObject_IsTrue(res)) ++ CALLMETHOD(searcher, "addResult", "O", rec); ++ Py_DECREF(res); ++ break; ++ } ++ } ++ ++ Py_DECREF(names); ++ Py_DECREF(seq); ++ } ++ } ++ Py_DECREF(lst); ++ + lst = PyObject_GetAttrString(searcher, "upgrades"); + if (lst == NULL || !PyList_Check(lst)) { + PyErr_SetString(PyExc_TypeError, "Invalid upgrades attribute"); +@@ -3420,7 +3727,7 @@ Cache__getstate__(CacheObject *self, PyObject *args) + static PyObject * + Cache__setstate__(CacheObject *self, PyObject *state) + { +- PyObject *provides, *requires, *upgrades, *conflicts; ++ PyObject *provides, *requires, *recommends, *upgrades, *conflicts; + int i, ilen; + int j, jlen; + +@@ -3452,11 +3759,13 @@ Cache__setstate__(CacheObject *self, PyObject *state) + /* + provides = {} + requires = {} ++ recommends = {} + upgrades = {} + conflicts = {} + */ + provides = PyDict_New(); + requires = PyDict_New(); ++ recommends = PyDict_New(); + upgrades = PyDict_New(); + conflicts = PyDict_New(); + +@@ -3497,6 +3806,21 @@ Cache__setstate__(CacheObject *self, PyObject *state) + } + + /* ++ for rec in pkg.recommends: ++ rec.packages.append(pkg) ++ recommends[rec] = True ++ */ ++ if (PyList_Check(pkgobj->recommends)) { ++ jlen = PyList_GET_SIZE(pkgobj->recommends); ++ for (j = 0; j != jlen; j++) { ++ PyObject *rec = PyList_GET_ITEM(pkgobj->recommends, j); ++ DependsObject *recobj = (DependsObject *)rec; ++ PyList_Append(recobj->packages, pkg); ++ PyDict_SetItem(recommends, rec, Py_True); ++ } ++ } ++ ++ /* + for upg in pkg.upgrades: + upg.packages.append(pkg) + upgrades[upg] = True +@@ -3525,6 +3849,7 @@ Cache__setstate__(CacheObject *self, PyObject *state) + PyDict_SetItem(conflicts, cnf, Py_True); + } + } ++ + } + + /* self._provides = provides.keys() */ +@@ -3535,6 +3860,10 @@ Cache__setstate__(CacheObject *self, PyObject *state) + self->_requires = PyDict_Keys(requires); + Py_DECREF(requires); + ++ /* self._recommends = recommends.keys() */ ++ self->_recommends = PyDict_Keys(recommends); ++ Py_DECREF(recommends); ++ + /* self._upgrades = upgrades.keys() */ + self->_upgrades = PyDict_Keys(upgrades); + Py_DECREF(upgrades); +@@ -3562,6 +3891,7 @@ static PyMethodDef Cache_methods[] = { + {"getPackages", (PyCFunction)Cache_getPackages, METH_VARARGS, NULL}, + {"getProvides", (PyCFunction)Cache_getProvides, METH_VARARGS, NULL}, + {"getRequires", (PyCFunction)Cache_getRequires, METH_VARARGS, NULL}, ++ {"getRecommends", (PyCFunction)Cache_getRecommends, METH_VARARGS, NULL}, + {"getUpgrades", (PyCFunction)Cache_getUpgrades, METH_VARARGS, NULL}, + {"getConflicts", (PyCFunction)Cache_getConflicts, METH_VARARGS, NULL}, + {"search", (PyCFunction)Cache_search, METH_O, NULL}, +@@ -3576,6 +3906,7 @@ static PyMemberDef Cache_members[] = { + {"_packages", T_OBJECT, OFF(_packages), RO, 0}, + {"_provides", T_OBJECT, OFF(_provides), RO, 0}, + {"_requires", T_OBJECT, OFF(_requires), RO, 0}, ++ {"_recommends", T_OBJECT, OFF(_recommends), RO, 0}, + {"_upgrades", T_OBJECT, OFF(_upgrades), RO, 0}, + {"_conflicts", T_OBJECT, OFF(_conflicts), RO, 0}, + {"_objmap", T_OBJECT, OFF(_objmap), RO, 0}, +diff --git a/smart/commands/query.py b/smart/commands/query.py +index 808e53a..9265cd9 100644 +--- a/smart/commands/query.py ++++ b/smart/commands/query.py +@@ -107,6 +107,8 @@ def option_parser(**kwargs): + help=_("show requires for the given packages")) + parser.add_option("--show-prerequires", action="store_true", + help=_("show requires selecting only pre-dependencies")) ++ parser.add_option("--show-recommends", action="store_true", ++ help=_("show recommends for the given packages")) + parser.add_option("--show-upgrades", action="store_true", + help=_("show upgrades for the given packages")) + parser.add_option("--show-conflicts", action="store_true", +@@ -488,6 +490,19 @@ def main(ctrl, opts, reloadchannels=True): + continue + output.showRequiresProvidedBy(pkg, req, + prv, prvpkg) ++ if pkg.recommends and (opts.show_recommends): ++ pkg.recommends.sort() ++ first = True ++ for req in pkg.recommends: ++ output.showRecommends(pkg, req) ++ if opts.show_providedby and req.providedby: ++ for prv in req.providedby: ++ prv.packages.sort() ++ for prvpkg in prv.packages: ++ if opts.installed and not prvpkg.installed: ++ continue ++ output.showRecommendsProvidedBy(pkg, req, ++ prv, prvpkg) + if pkg.upgrades and (opts.show_upgrades or whoupgrades): + pkg.upgrades.sort() + first = True +@@ -594,6 +609,12 @@ class NullOutput(object): + def showRequiresProvidedBy(self, pkg, req, prv, prvpkg): + pass + ++ def showRecommends(self, pkg, req): ++ pass ++ ++ def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg): ++ pass ++ + def showUpgrades(self, pkg, upg): + pass + +@@ -619,6 +640,8 @@ class TextOutput(NullOutput): + self._firstconflictedby = True + self._firstrequires = True + self._firstrequiresprovidedby = True ++ self._firstrecommends = True ++ self._firstrecommendsprovidedby = True + self._firstupgrades = True + self._firstupgradesprovidedby = True + self._firstconflicts = True +@@ -711,6 +734,22 @@ class TextOutput(NullOutput): + name = str(prvpkg) + print " ", "%s (%s)" % (name, prv) + ++ def showRecommends(self, pkg, rec): ++ if self._firstrecommends: ++ self._firstrecommends = False ++ print " ", _("Recommends:") ++ print " ", rec ++ ++ def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg): ++ if self._firstrecommendsprovidedby: ++ self._firstrecommendsprovidedby = False ++ print " ", _("Provided By:") ++ if self.opts.hide_version: ++ name = prvpkg.name ++ else: ++ name = str(prvpkg) ++ print " ", "%s (%s)" % (name, prv) ++ + def showUpgrades(self, pkg, upg): + if self._firstupgrades: + self._firstupgrades = False +@@ -797,6 +836,18 @@ class GraphVizOutput(NullOutput): + self._shown[req, prv] = True + print ' "Requires: %s" -> "Provides: %s";' % (req, prv) + ++ def showRecommends(self, pkg, req): ++ if (pkg, req) not in self._shown: ++ self._shown[pkg, req] = True ++ print ' "%s" -> "Recommends: %s";' % (pkg, req) ++ ++ def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg): ++ self.showPackage(prvpkg) ++ self.showProvides(prvpkg, prv) ++ if (req, prv) not in self._shown: ++ self._shown[req, prv] = True ++ print ' "Recommends: %s" -> "Provides: %s";' % (req, prv) ++ + def showUpgrades(self, pkg, upg): + if (pkg, upg) not in self._shown: + self._shown[pkg, upg] = True +diff --git a/smart/control.py b/smart/control.py +index fd7083a..d44abe7 100644 +--- a/smart/control.py ++++ b/smart/control.py +@@ -447,7 +447,7 @@ class Control(object): + queue = marked.keys() + while queue: + pkg = queue.pop(0) +- for req in pkg.requires: ++ for req in pkg.requires + pkg.recommends: + for prv in req.providedby: + for prvpkg in prv.packages: + if (prvpkg.installed and +@@ -794,7 +794,7 @@ class Control(object): + pkglst = [] + for pkg in changeset: + n = 0 +- for req in pkg.requires: ++ for req in pkg.requires + pkg.recommends: + for prv in req.providedby: + for prvpkg in prv.packages: + if changeset.get(prvpkg) is INSTALL: +diff --git a/smart/searcher.py b/smart/searcher.py +index 216f4ce..32eb825 100644 +--- a/smart/searcher.py ++++ b/smart/searcher.py +@@ -45,9 +45,9 @@ class Searcher(object): + + - provides is matched in Provides.search(), for the same reason. + +- - requires, upgrades, and conflicts don't have special searching +- methods. Instead, their usual match() method is given an instance +- of the Provides type. ++ - requires, recommends, upgrades, and conflicts don't have special ++ searching methods. Instead, their usual match() method is given ++ an instance of the Provides type. + + - group, path, url, and other information which is found by + PackageInfo, is searched by the Loader.search() method and +@@ -62,6 +62,7 @@ class Searcher(object): + self.nameversion = [] + self.provides = [] + self.requires = [] ++ self.recommends = [] + self.upgrades = [] + self.conflicts = [] + self.path = [] +@@ -76,6 +77,7 @@ class Searcher(object): + del self.nameversion[:] + del self.provides[:] + del self.requires[:] ++ del self.recommends[:] + del self.upgrades[:] + del self.conflicts[:] + del self.path[:] +@@ -122,6 +124,8 @@ class Searcher(object): + self.addProvides(s[9:], cutoff) + elif s.startswith("requires:"): + self.addRequires(s[9:]) ++ elif s.startswith("recommends:"): ++ self.addRecommends(s[11:]) + elif s.startswith("upgrades:"): + self.addUpgrades(s[9:]) + elif s.startswith("conflicts:"): +@@ -151,6 +155,7 @@ class Searcher(object): + return s and ( + s.startswith("provides:") or + s.startswith("requires:") or ++ s.startswith("recommends:") or + s.startswith("upgrades:") or + s.startswith("conflicts:") or + s.startswith("url:") or +@@ -182,6 +187,9 @@ class Searcher(object): + def addRequires(self, s): + self.requires.append(self._buildProvides(s)) + ++ def addRecommends(self, s): ++ self.recommends.append(self._buildProvides(s)) ++ + def addUpgrades(self, s): + self.upgrades.append(self._buildProvides(s)) + +diff --git a/smart/transaction.py b/smart/transaction.py +index eb320d2..300b9cc 100644 +--- a/smart/transaction.py ++++ b/smart/transaction.py +@@ -573,7 +573,7 @@ class Transaction(object): + self._remove(namepkg, changeset, locked, pending, depth) + + # Install packages required by this one. +- for req in pkg.requires: ++ for req in pkg.requires + pkg.recommends: + + # Check if someone is already providing it. + prvpkgs = {} +@@ -596,8 +596,12 @@ class Transaction(object): + + if not prvpkgs: + # No packages provide it at all. Give up. +- raise Failed, _("Can't install %s: no package provides %s") % \ +- (pkg, req) ++ if req in pkg.requires: ++ raise Failed, _("Can't install %s: no package provides %s") % \ ++ (pkg, req) ++ else: ++ # It's only a recommend, skip ++ continue + + if len(prvpkgs) == 1: + # Don't check locked here. prvpkgs was +@@ -1359,7 +1363,7 @@ class ChangeSetSplitter(object): + set = self._changeset + + # Check all dependencies needed by this package. +- for req in pkg.requires: ++ for req in pkg.requires + pkg.recommends: + + # Check if any already installed or to be installed + # package will solve the problem. +@@ -1424,8 +1428,9 @@ class ChangeSetSplitter(object): + + # There are no solutions for the problem. + # Should we really care about it? +- if (self._forcerequires or +- isinstance(req, PreRequires)): ++ if ((self._forcerequires or ++ isinstance(req, PreRequires)) ++ and req in pkg.requires): + raise Error, _("No providers for '%s', " + "required by '%s'") % (req, pkg) + +@@ -1625,7 +1630,7 @@ def recursiveInternalRequires(pkgmap, pkg, numrel, done=None): + return n + + def forwardRequires(pkg, map): +- for req in pkg.requires: ++ for req in pkg.requires + pkg.recommends: + if req not in map: + map[req] = True + for prv in req.providedby: +@@ -1794,6 +1799,15 @@ def checkPackages(cache, checkset, relateset, report=False): + iface.info(_("Unsatisfied dependency: %s requires %s") % + (pkg, req)) + ++ for req in pkg.recommends: ++ for prv in req.providedby: ++ for prvpkg in prv.packages: ++ if prvpkg in relateset: ++ break ++ else: ++ continue ++ break ++ + if not pkg.installed: + continue + +-- +1.7.9.5 + diff --git a/extended/python-smartpm/centos/patches/smart-rpm-extra-macros.patch b/extended/python-smartpm/centos/patches/smart-rpm-extra-macros.patch new file mode 100644 index 000000000..30cb1767d --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-rpm-extra-macros.patch @@ -0,0 +1,27 @@ +backends/rpm: implement rpm-extra-macros option + +Allow defining extra macros in the smart configuration to be passed +to rpm before opening the database. + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py +index b9e9cb2..234c844 100644 +--- a/smart/backends/rpm/base.py ++++ b/smart/backends/rpm/base.py +@@ -53,6 +53,10 @@ def rpm_join_dbpath(root, dbpath): + return os.path.join(root, dbpath) + + def getTS(new=False): ++ if sysconf.get("rpm-extra-macros"): ++ for key, value in sysconf.get("rpm-extra-macros").items(): ++ rpm.addMacro(key, str(value)) ++ + rpm_root = os.path.abspath(sysconf.get("rpm-root", "/")) + if not hasattr(getTS, "ts") or getTS.root != rpm_root: + getTS.root = rpm_root +-- +1.7.9.5 + diff --git a/extended/python-smartpm/centos/patches/smart-rpm-md-parse.patch b/extended/python-smartpm/centos/patches/smart-rpm-md-parse.patch new file mode 100644 index 000000000..97cecc124 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-rpm-md-parse.patch @@ -0,0 +1,26 @@ +backends/rpm: fix parsing of rpm-md metadata + +If assertions are disabled then the queue.pop() wasn't being executed, +leading to requires, recommends etc. not being read properly. + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/backends/rpm/metadata.py b/smart/backends/rpm/metadata.py +index 2c54f39..dc9df22 100644 +--- a/smart/backends/rpm/metadata.py ++++ b/smart/backends/rpm/metadata.py +@@ -188,7 +188,8 @@ class RPMMetaDataLoader(Loader): + + elif event == "end": + +- assert queue.pop() is elem ++ popped = queue.pop() ++ assert popped is elem + + if skip: + if tag == skip: +-- +1.7.9.5 + diff --git a/extended/python-smartpm/centos/patches/smart-rpm-root.patch b/extended/python-smartpm/centos/patches/smart-rpm-root.patch new file mode 100644 index 000000000..e1d2b46c1 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-rpm-root.patch @@ -0,0 +1,80 @@ +Fix smart RPM backend to handle rpm-dbpath/rpm-root properly + +Don't assume that if the dbpath starts with / that it is an absolute +path. This matches the behaviour of rpm itself. (If the root path is +specified and does not start with /, rpm will prepend the root path +twice and fail). + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py +index 7092332..0489e11 100644 +--- a/smart/backends/rpm/base.py ++++ b/smart/backends/rpm/base.py +@@ -46,6 +46,12 @@ __all__ = ["RPMPackage", "RPMProvides", "RPMNameProvides", "RPMPreRequires", + "rpm", "getTS", "getArchScore", "getArchColor", "system_provides", + "collapse_libc_requires"] + ++def rpm_join_dbpath(root, dbpath): ++ if dbpath.startswith('/') and root: ++ return os.path.join(root, dbpath[1:]) ++ else: ++ return os.path.join(root, dbpath) ++ + def getTS(new=False): + rpm_root = os.path.abspath(sysconf.get("rpm-root", "/")) + if not hasattr(getTS, "ts") or getTS.root != rpm_root: +@@ -56,7 +62,7 @@ def getTS(new=False): + if not sysconf.get("rpm-check-signatures", False): + getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) + rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm") +- dbdir = os.path.join(getTS.root, rpm_dbpath) ++ dbdir = rpm_join_dbpath(getTS.root, rpm_dbpath) + if not os.path.isdir(dbdir): + try: + os.makedirs(dbdir) +diff --git a/smart/channels/rpm_sys.py b/smart/channels/rpm_sys.py +index efcb10e..b9fda27 100644 +--- a/smart/channels/rpm_sys.py ++++ b/smart/channels/rpm_sys.py +@@ -20,7 +20,7 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + from smart.backends.rpm.header import RPMDBLoader +-from smart.backends.rpm.base import getTS ++from smart.backends.rpm.base import getTS, rpm_join_dbpath + from smart.channel import PackageChannel + from smart import * + import os +@@ -32,9 +32,9 @@ class RPMSysChannel(PackageChannel): + + def fetch(self, fetcher, progress): + getTS() # Make sure the db exists. +- path = os.path.join(sysconf.get("rpm-root", "/"), +- sysconf.get("rpm-dbpath", "var/lib/rpm"), +- "Packages") ++ dbdir = rpm_join_dbpath(sysconf.get("rpm-root", "/"), ++ sysconf.get("rpm-dbpath", "var/lib/rpm")) ++ path = os.path.join(dbdir, "Packages") + digest = os.path.getmtime(path) + if digest == self._digest: + return True +diff --git a/smart/plugins/detectsys.py b/smart/plugins/detectsys.py +index 2cd49ad..3959d07 100644 +--- a/smart/plugins/detectsys.py ++++ b/smart/plugins/detectsys.py +@@ -20,10 +20,11 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + from smart import * ++from smart.backends.rpm.base import rpm_join_dbpath + import os + + def detectRPMSystem(): +- dir = os.path.join(sysconf.get("rpm-root", "/"), ++ dir = rpm_join_dbpath(sysconf.get("rpm-root", "/"), + sysconf.get("rpm-dbpath", "var/lib/rpm")) + file = os.path.join(dir, "Packages") + if os.path.exists(file): diff --git a/extended/python-smartpm/centos/patches/smart-set-noprogress-for-pycurl.patch b/extended/python-smartpm/centos/patches/smart-set-noprogress-for-pycurl.patch new file mode 100644 index 000000000..2885998ac --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-set-noprogress-for-pycurl.patch @@ -0,0 +1,20 @@ +Set NOPROGRESS for pycurl just as same as default operation in pycurl module itself. +If set NOPROGRESS with 0 for pycurl, it causes dead lock issue of Python GIL when +call smart library by python gui just like pygtk. + +Upstream-Status: Pending + +Signed-off-by: Kai Kang +--- +diff -u smart-1.4.1/smart.orig/fetcher.py smart-1.4.1/smart/fetcher.py +--- smart-1.4.1/smart.orig/fetcher.py 2014-07-15 16:42:19.240437080 +0800 ++++ smart-1.4.1/smart/fetcher.py 2014-07-15 17:02:37.812470289 +0800 +@@ -1720,7 +1720,7 @@ + handle.setopt(pycurl.OPT_FILETIME, 1) + handle.setopt(pycurl.LOW_SPEED_LIMIT, 1) + handle.setopt(pycurl.LOW_SPEED_TIME, SOCKETTIMEOUT) +- handle.setopt(pycurl.NOPROGRESS, 0) ++ handle.setopt(pycurl.NOPROGRESS, 1) + handle.setopt(pycurl.PROGRESSFUNCTION, progress) + handle.setopt(pycurl.WRITEDATA, local) + handle.setopt(pycurl.FOLLOWLOCATION, 1) diff --git a/extended/python-smartpm/centos/patches/smart-support-rpm4.patch b/extended/python-smartpm/centos/patches/smart-support-rpm4.patch new file mode 100644 index 000000000..fe7413e51 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-support-rpm4.patch @@ -0,0 +1,96 @@ +From f6a853cf8138c7e01b6e093b783f97639b033420 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Thu, 2 Jun 2016 15:57:42 -0400 +Subject: [PATCH 1/1] Support rpm4 + +Cloned from http://lists.openembedded.org/pipermail/openembedded-core/2014-September/097610.html + +--- + smart/backends/rpm/base.py | 12 ++++++++---- + smart/backends/rpm/pm.py | 40 ++++++++++++++++++++++++---------------- + 2 files changed, 32 insertions(+), 20 deletions(-) + +diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py +index 7140c1b..d720617 100644 +--- a/smart/backends/rpm/base.py ++++ b/smart/backends/rpm/base.py +@@ -338,10 +338,14 @@ class RPMObsoletes(Depends): + + _SCOREMAP = {} + def getArchScore(arch, _sm=_SCOREMAP): +- if arch not in _sm: +- score = rpm.archscore(arch) +- _sm[arch] = score +- return _sm.get(arch, 0) ++ try: ++ rpm.platformscore(arch) ++ if arch not in _sm: ++ score = rpm.archscore(arch) ++ _sm[arch] = score ++ return _sm.get(arch, 0) ++ except AttributeError: ++ return 1 + + # TODO: Embed color into nameprovides and obsoletes relations. + _COLORMAP = {"noarch": 0, "x86_64": 2, "ppc64": 2, "s390x": 2, "sparc64": 2} +diff --git a/smart/backends/rpm/pm.py b/smart/backends/rpm/pm.py +index 2e5b2c3..cc75dcc 100644 +--- a/smart/backends/rpm/pm.py ++++ b/smart/backends/rpm/pm.py +@@ -106,22 +106,25 @@ class RPMPackageManager(PackageManager): + flags |= rpm.RPMTRANS_FLAG_TEST + ts.setFlags(flags) + +- dflags = ts.setDFlags(0) +- if sysconf.get("rpm-noupgrade", False): +- dflags |= rpm.RPMDEPS_FLAG_NOUPGRADE +- if sysconf.get("rpm-norequires", False): +- dflags |= rpm.RPMDEPS_FLAG_NOREQUIRES +- if sysconf.get("rpm-noconflicts", False): +- dflags |= rpm.RPMDEPS_FLAG_NOCONFLICTS +- if sysconf.get("rpm-noobsoletes", False): +- dflags |= rpm.RPMDEPS_FLAG_NOOBSOLETES +- if sysconf.get("rpm-noparentdirs", False): +- dflags |= rpm.RPMDEPS_FLAG_NOPARENTDIRS +- if sysconf.get("rpm-nolinktos", False): +- dflags |= rpm.RPMDEPS_FLAG_NOLINKTOS +- if sysconf.get("rpm-nosuggest", False): +- dflags |= rpm.RPMDEPS_FLAG_NOSUGGEST +- ts.setDFlags(dflags) ++ try: ++ dflags = ts.setDFlags(0) ++ if sysconf.get("rpm-noupgrade", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOUPGRADE ++ if sysconf.get("rpm-norequires", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOREQUIRES ++ if sysconf.get("rpm-noconflicts", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOCONFLICTS ++ if sysconf.get("rpm-noobsoletes", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOOBSOLETES ++ if sysconf.get("rpm-noparentdirs", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOPARENTDIRS ++ if sysconf.get("rpm-nolinktos", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOLINKTOS ++ if sysconf.get("rpm-nosuggest", False): ++ dflags |= rpm.RPMDEPS_FLAG_NOSUGGEST ++ ts.setDFlags(dflags) ++ except AttributeError, ae: ++ pass + + # Set rpm verbosity level. + levelname = sysconf.get('rpm-log-level') +@@ -235,6 +238,11 @@ class RPMPackageManager(PackageManager): + if sysconf.get("rpm-ignoresize", False): + probfilter |= rpm.RPMPROB_FILTER_DISKNODES + probfilter |= rpm.RPMPROB_FILTER_DISKSPACE ++ try: ++ # Test for RPM5 function ++ rpm.platformscore("") ++ except AttributeError: ++ probfilter |= rpm.RPMPROB_FILTER_IGNOREARCH + + if force or reinstall: + probfilter |= rpm.RPMPROB_FILTER_REPLACEPKG +-- +1.8.3.1 + diff --git a/extended/python-smartpm/centos/patches/smart-tmpdir.patch b/extended/python-smartpm/centos/patches/smart-tmpdir.patch new file mode 100644 index 000000000..2f09ce924 --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-tmpdir.patch @@ -0,0 +1,30 @@ +backends/rpm: remove creation of /var/tmp + +This doesn't appear to be needed, and breaks installation of base-files +in OpenEmbedded (since that is a symlink installed as part of the +package). + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py +index 234c844..127354d 100644 +--- a/smart/backends/rpm/base.py ++++ b/smart/backends/rpm/base.py +@@ -82,12 +82,6 @@ def getTS(new=False): + else: + iface.warning(_("Initialized new rpm database at %s") + % getTS.root) +- tmpdir = os.path.join(getTS.root, "var/tmp") +- if not os.path.isdir(tmpdir): +- try: +- os.makedirs(tmpdir) +- except OSError: +- pass + if new: + if sysconf.get("rpm-dbpath"): + rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath")) +-- +1.7.9.5 + diff --git a/extended/python-smartpm/centos/patches/smart-yaml-error.patch b/extended/python-smartpm/centos/patches/smart-yaml-error.patch new file mode 100644 index 000000000..e16c5c12a --- /dev/null +++ b/extended/python-smartpm/centos/patches/smart-yaml-error.patch @@ -0,0 +1,86 @@ +Print a more friendly error if YAML output is requested without PyYAML + +Upstream-Status: Pending + +Signed-off-by: Paul Eggleton + +diff --git a/smart/commands/channel.py b/smart/commands/channel.py +index 63fbb35..108f3f1 100644 +--- a/smart/commands/channel.py ++++ b/smart/commands/channel.py +@@ -339,7 +339,10 @@ def main(ctrl, opts): + print + + if opts.yaml is not None: +- import yaml ++ try: ++ import yaml ++ except ImportError: ++ raise Error, _("Please install PyYAML in order to use this function") + yamlchannels = {} + for alias in (opts.yaml or sysconf.get("channels", ())): + channel = sysconf.get(("channels", alias)) +diff --git a/smart/commands/config.py b/smart/commands/config.py +index 4fe4366..aa1db78 100644 +--- a/smart/commands/config.py ++++ b/smart/commands/config.py +@@ -137,7 +137,10 @@ def main(ctrl, opts): + pprint.pprint(sysconf.get((), hard=True)) + + if opts.yaml is not None: +- import yaml ++ try: ++ import yaml ++ except ImportError: ++ raise Error, _("Please install PyYAML in order to use this function") + if opts.yaml: + marker = object() + for opt in opts.yaml: +diff --git a/smart/commands/flag.py b/smart/commands/flag.py +index ed18999..8b90496 100644 +--- a/smart/commands/flag.py ++++ b/smart/commands/flag.py +@@ -138,7 +138,10 @@ def main(ctrl, opts): + print + + if opts.yaml is not None: +- import yaml ++ try: ++ import yaml ++ except ImportError: ++ raise Error, _("Please install PyYAML in order to use this function") + yamlflags = {} + for flag in opts.yaml or pkgconf.getFlagNames(): + flag = flag.strip() +diff --git a/smart/commands/mirror.py b/smart/commands/mirror.py +index ca50a95..f7b019d 100644 +--- a/smart/commands/mirror.py ++++ b/smart/commands/mirror.py +@@ -218,7 +218,10 @@ def main(ctrl, opts): + print + + if opts.yaml: +- import yaml ++ try: ++ import yaml ++ except ImportError: ++ raise Error, _("Please install PyYAML in order to use this function") + yamlmirrors = {} + mirrors = sysconf.get("mirrors", ()) + for origin in mirrors: +diff --git a/smart/commands/priority.py b/smart/commands/priority.py +index d850d29..441ea32 100644 +--- a/smart/commands/priority.py ++++ b/smart/commands/priority.py +@@ -117,7 +117,10 @@ def main(ctrl, opts): + print + + elif opts.yaml: +- import yaml ++ try: ++ import yaml ++ except ImportError: ++ raise Error, _("Please install PyYAML in order to use this function") + yamlpriorities = {} + priorities = sysconf.get("package-priorities", {}) + for name in opts.args or priorities: diff --git a/extended/python-smartpm/centos/patches/smartpm-rpm5-nodig.patch b/extended/python-smartpm/centos/patches/smartpm-rpm5-nodig.patch new file mode 100644 index 000000000..9919a941b --- /dev/null +++ b/extended/python-smartpm/centos/patches/smartpm-rpm5-nodig.patch @@ -0,0 +1,46 @@ +RPM5 has removed support for RPMVSF_NOSIGNATURES + +Patch smart to no longer use this flag + +Upstream-Status: Pending + +Signed-off-by: Mark Hatle + +diff -ur smart-1.4.1.orig/smart/backends/rpm/base.py smart-1.4.1/smart/backends/rpm/base.py +--- smart-1.4.1.orig/smart/backends/rpm/base.py 2012-10-04 11:22:11.229351164 -0500 ++++ smart-1.4.1/smart/backends/rpm/base.py 2012-10-04 11:22:44.820170786 -0500 +@@ -53,8 +53,8 @@ + if sysconf.get("rpm-dbpath"): + rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath")) + getTS.ts = rpm.ts(getTS.root) +- if not sysconf.get("rpm-check-signatures", False): +- getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) ++ #if not sysconf.get("rpm-check-signatures", False): ++ # getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) + rpm_dbpath = sysconf.get("rpm-dbpath", "var/lib/rpm") + dbdir = os.path.join(getTS.root, rpm_dbpath) + if not os.path.isdir(dbdir): +@@ -82,8 +82,8 @@ + if sysconf.get("rpm-dbpath"): + rpm.addMacro('_dbpath', "/" + sysconf.get("rpm-dbpath")) + ts = rpm.ts(getTS.root) +- if not sysconf.get("rpm-check-signatures", False): +- ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) ++ #if not sysconf.get("rpm-check-signatures", False): ++ # ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) + return ts + else: + return getTS.ts +diff -ur smart-1.4.1.orig/smart/plugins/yumchannelsync.py smart-1.4.1/smart/plugins/yumchannelsync.py +--- smart-1.4.1.orig/smart/plugins/yumchannelsync.py 2010-12-06 03:11:05.000000000 -0600 ++++ smart-1.4.1/smart/plugins/yumchannelsync.py 2012-10-04 11:23:09.799350924 -0500 +@@ -56,7 +56,8 @@ + + rpmroot = sysconf.get("rpm-root", "/") + ts = rpmUtils.transaction.initReadOnlyTransaction(root=rpmroot) +- ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)) ++ #ts.pushVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)) ++ ts.pushVSFlags(~(rpm._RPMVSF_NODIGESTS)) + releasever = None + # HACK: we're hard-coding the most used distros, will add more if needed + idx = ts.dbMatch('provides', 'fedora-release') diff --git a/extended/python-smartpm/centos/python-smartpm.spec b/extended/python-smartpm/centos/python-smartpm.spec new file mode 100644 index 000000000..255b87719 --- /dev/null +++ b/extended/python-smartpm/centos/python-smartpm.spec @@ -0,0 +1,82 @@ +Summary: The Smart Package Manager +Name: python-smartpm +Version: 1.4.1 +Release: 0%{?_tis_dist}.%{tis_patch_ver} +License: GPLv2 +Group: devel/python +Packager: Wind River +URL: http://labix.org/smart/ + +Source0: %{name}-%{version}.tar.gz + +#OVP Patches +#Patch00: smartpm-rpm5-nodig.patch +Patch01: smart-rpm-root.patch +Patch02: smart-recommends.patch +Patch03: smart-rpm-extra-macros.patch +Patch04: smart-dflags.patch +Patch05: smart-rpm-md-parse.patch +Patch06: smart-tmpdir.patch +Patch07: smart-metadata-match.patch +Patch08: smart-improve-error-reporting.patch +Patch09: smart-multilib-fixes.patch +Patch10: smart-yaml-error.patch +Patch11: smart-channelsdir.patch +Patch12: smart-conflict-provider.patch +Patch13: smart-flag-ignore-recommends.patch +Patch14: smart-flag-exclude-packages.patch +Patch15: smart-config-ignore-all-recommends.patch +Patch16: smart-attempt.patch +Patch17: smart-filename-NAME_MAX.patch +Patch18: smart-add-for-rpm-ignoresize-check.patch +Patch19: smart-set-noprogress-for-pycurl.patch + +#WRS Patches +Patch20: commit_transaction_error_handling.patch +Patch21: smart-support-rpm4.patch + +BuildArch: x86_64 + +BuildRequires: python +BuildRequires: python-devel +BuildRequires: gettext +BuildRequires: rpm + +Requires: python +Requires: python-devel +# Note: centos has RPM 4.11.3 WR was using 5.4.9 +Requires: rpm +Requires: rpm-python + +%description +The Smart Package Manager project has the ambitious objective of creating +smart and portable algorithms for solving adequately the problem of +managing software upgrades and installation. + +%prep +%autosetup -p 1 -n smart-%{version} + +# Remove bundled egg-info +rm -rf %{name}.egg-info + +%build +%{__python2} setup.py build + +%install +%{__python2} setup.py install --skip-build --root %{buildroot} + +# WRS Note: +# python2_sitelib is not correct for this package. +# This SPEC looks under /usr/lib but needs to look under /usr/lib64 +# The files section is hardcoded to handle this + +%files +%license LICENSE +%{_bindir}/smart +#%{python2_sitelib}/smart +/usr/lib64/python2.7/site-packages/smart +#%{python2_sitelib}/*.egg-info +/usr/lib64/python2.7/site-packages/*.egg-info +/usr/share/locale +/usr/share/man + diff --git a/extended/python-smartpm/files/commit_transaction_error_handling.patch b/extended/python-smartpm/files/commit_transaction_error_handling.patch new file mode 100644 index 000000000..5d0827d05 --- /dev/null +++ b/extended/python-smartpm/files/commit_transaction_error_handling.patch @@ -0,0 +1,37 @@ +--- + smart/backends/rpm/pm.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/smart/backends/rpm/pm.py ++++ b/smart/backends/rpm/pm.py +@@ -283,6 +283,8 @@ class RPMPackageManager(PackageManager): + prog.setDone() + if probs and (not retry): + raise Error, "\n".join([x[0] for x in probs]) ++ if cb.errors > 0: ++ raise Error, "One or more errors occurred during transaction" + prog.stop() + if retry and len(changeset): + self.commit(changeset, pkgpaths) +@@ -297,6 +299,7 @@ class RPMCallback: + self.rpmoutbuffer = "" + self.lasttopic = None + self.topic = None ++ self.errors = 0 + + def grabOutput(self, flag): + if flag: +@@ -415,6 +418,13 @@ class RPMCallback: + self.prog.setSubDone(subkey) + self.prog.show() + ++ elif what == rpm.RPMCALLBACK_SCRIPT_ERROR: ++ self.errors += 1 ++ elif what == rpm.RPMCALLBACK_UNPACK_ERROR: ++ self.errors += 1 ++ elif what == rpm.RPMCALLBACK_CPIO_ERROR: ++ self.errors += 1 ++ + from smart.backends.rpm.base import rpm, getTS + + # vim:ts=4:sw=4:et diff --git a/extended/sanlock/centos/build_srpm.data b/extended/sanlock/centos/build_srpm.data new file mode 100644 index 000000000..d3f64f336 --- /dev/null +++ b/extended/sanlock/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=3 diff --git a/extended/sanlock/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/sanlock/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..cd238e69f --- /dev/null +++ b/extended/sanlock/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 112dfdc394a779a860c79c067d47142dc1db2484 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:45:32 -0400 +Subject: [PATCH 3/3] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/sanlock.spec +--- + SPECS/sanlock.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/sanlock.spec b/SPECS/sanlock.spec +index b4996de..ebce8c1 100644 +--- a/SPECS/sanlock.spec ++++ b/SPECS/sanlock.spec +@@ -6,7 +6,7 @@ + + Name: sanlock + Version: 3.5.0 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: A shared storage lock manager + + Group: System Environment/Base +-- +1.9.1 + diff --git a/extended/sanlock/centos/meta_patches/PATCH_ORDER b/extended/sanlock/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..cb1a0946d --- /dev/null +++ b/extended/sanlock/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +spec-wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch +spec-sanlock-systemctl-post-enable-preun-disable.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/extended/sanlock/centos/meta_patches/spec-sanlock-systemctl-post-enable-preun-disable.patch b/extended/sanlock/centos/meta_patches/spec-sanlock-systemctl-post-enable-preun-disable.patch new file mode 100644 index 000000000..15f477466 --- /dev/null +++ b/extended/sanlock/centos/meta_patches/spec-sanlock-systemctl-post-enable-preun-disable.patch @@ -0,0 +1,39 @@ +From 2e52b9f2956ac629598e0d0c201af38194904e16 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:45:32 -0400 +Subject: [PATCH 2/3] WRS: + spec-sanlock-systemctl-post-enable-preun-disable.patch + +--- + SPECS/sanlock.spec | 15 ++------------- + 1 file changed, 2 insertions(+), 13 deletions(-) + +diff --git a/SPECS/sanlock.spec b/SPECS/sanlock.spec +index 92b81bb..b4996de 100644 +--- a/SPECS/sanlock.spec ++++ b/SPECS/sanlock.spec +@@ -108,19 +108,8 @@ getent passwd sanlock > /dev/null || /usr/sbin/useradd \ + /usr/sbin/usermod -a -G disk sanlock + + %post +-%if %{with_systemd} +-%systemd_post wdmd.service sanlock.service +-%endif +- +-%preun +-%if %{with_systemd} +-%systemd_preun wdmd.service sanlock.service +-%endif +- +-%postun +-%if %{with_systemd} +-%systemd_postun +-%endif ++ /bin/systemctl enable sanlock.service >/dev/null 2>&1 || : ++ /bin/systemctl enable wdmd.service >/dev/null 2>&1 || : + + %files + %defattr(-,root,root,-) +-- +1.9.1 + diff --git a/extended/sanlock/centos/meta_patches/spec-wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch b/extended/sanlock/centos/meta_patches/spec-wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch new file mode 100644 index 000000000..6eb9f0c94 --- /dev/null +++ b/extended/sanlock/centos/meta_patches/spec-wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch @@ -0,0 +1,33 @@ +From 4d37b60c81cf76f1d1e2f9cde5ee33e052593d54 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:45:32 -0400 +Subject: [PATCH 1/3] WRS: + spec-wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch + +--- + SPECS/sanlock.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/sanlock.spec b/SPECS/sanlock.spec +index 18ce7dc..92b81bb 100644 +--- a/SPECS/sanlock.spec ++++ b/SPECS/sanlock.spec +@@ -30,6 +30,7 @@ Requires(postun): systemd-units + Source0: https://releases.pagure.org/sanlock/%{name}-%{version}.tar.gz + + # Patch0: 0001-foo.patch ++Patch100: wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch + + %description + The sanlock daemon manages leases for applications on hosts using shared storage. +@@ -37,6 +38,7 @@ The sanlock daemon manages leases for applications on hosts using shared storage + %prep + %setup -q + # %patch0 -p1 -b .0001-foo.patch ++%patch100 -p1 -b .disable-wdmd-daemon-on-boot + + %build + # upstream does not require configure +-- +1.9.1 + diff --git a/extended/sanlock/centos/patches/wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch b/extended/sanlock/centos/patches/wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch new file mode 100644 index 000000000..c0cc1bd76 --- /dev/null +++ b/extended/sanlock/centos/patches/wdmd-Kernel-watchdog-enable-and-reboot-on-error.patch @@ -0,0 +1,35 @@ +From 9ef42b78435ca3c593d7589a8844886d735a646b Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Thu, 5 Oct 2017 14:17:05 -0400 +Subject: wdmd Kernel watchdog enable and reboot on error + +This patch is a port of this commit: + +5a4deca10fd8e967c042714382dd66bf9a4cf15c +(CGTS-3360 - Kernel watchdog enable and reboot on error) + +into centos 7. + +--- + init.d/wdmd.service | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/init.d/wdmd.service b/init.d/wdmd.service +index 7e6d973..2e7db50 100644 +--- a/init.d/wdmd.service ++++ b/init.d/wdmd.service +@@ -3,9 +3,9 @@ Description=Watchdog Multiplexing Daemon + After=syslog.target + + [Service] +-Type=forking +-ExecStart=/lib/systemd/systemd-wdmd start ++Type=oneshot + ExecStop=/lib/systemd/systemd-wdmd stop ++RemainAfterExit=yes + + [Install] + WantedBy=multi-user.target +-- +1.9.1 + diff --git a/extended/sanlock/centos/srpm_path b/extended/sanlock/centos/srpm_path new file mode 100644 index 000000000..6e5198571 --- /dev/null +++ b/extended/sanlock/centos/srpm_path @@ -0,0 +1,2 @@ +mirror:Source/sanlock-3.5.0-1.el7.src.rpm + diff --git a/extended/shadow/centos/build_srpm.data b/extended/shadow/centos/build_srpm.data new file mode 100644 index 000000000..82b607648 --- /dev/null +++ b/extended/shadow/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$PKG_BASE/$DISTRO/files/*" +TIS_PATCH_VER=4 diff --git a/extended/shadow/centos/files/clear_shadow_locks.service b/extended/shadow/centos/files/clear_shadow_locks.service new file mode 100644 index 000000000..db004c1d3 --- /dev/null +++ b/extended/shadow/centos/files/clear_shadow_locks.service @@ -0,0 +1,11 @@ +[Unit] +Description=Remove stale shadow lockfiles +After=local-fs.target systemd-tmpfiles-setup.service +Before=sysinit.target shutdown.target + +[Service] +Type=simple +ExecStart=/usr/bin/rm -f /etc/gshadow.lock /etc/shadow.lock /etc/passwd.lock /etc/group.lock + +[Install] +WantedBy=multi-user.target diff --git a/extended/shadow/centos/files/login.defs.cgcs b/extended/shadow/centos/files/login.defs.cgcs new file mode 100644 index 000000000..9cf8ac4cf --- /dev/null +++ b/extended/shadow/centos/files/login.defs.cgcs @@ -0,0 +1,386 @@ +# +# /etc/login.defs - Configuration control definitions for the shadow package. +# +# $Id: login.defs 3038 2009-07-23 20:41:35Z nekral-guest $ +# + +# +# Delay in seconds before being allowed another attempt after a login failure +# Note: When PAM is used, some modules may enfore a minimal delay (e.g. +# pam_unix enforces a 2s delay) +# +FAIL_DELAY 3 + +# +# Enable logging and display of /var/log/faillog login failure info. +# +#FAILLOG_ENAB yes + +# +# Enable display of unknown usernames when login failures are recorded. +# +LOG_UNKFAIL_ENAB no + +# +# Enable logging of successful logins +# +LOG_OK_LOGINS no + +# +# Enable logging and display of /var/log/lastlog login time info. +# +#LASTLOG_ENAB yes + +# +# Enable checking and display of mailbox status upon login. +# +# Disable if the shell startup files already check for mail +# ("mailx -e" or equivalent). +# +#MAIL_CHECK_ENAB yes + +# +# Enable additional checks upon password changes. +# +#OBSCURE_CHECKS_ENAB yes + +# +# Enable checking of time restrictions specified in /etc/porttime. +# +#PORTTIME_CHECKS_ENAB yes + +# +# Enable setting of ulimit, umask, and niceness from passwd gecos field. +# +#QUOTAS_ENAB yes + +# +# Enable "syslog" logging of su activity - in addition to sulog file logging. +# SYSLOG_SG_ENAB does the same for newgrp and sg. +# +SYSLOG_SU_ENAB yes +SYSLOG_SG_ENAB yes + +# +# If defined, either full pathname of a file containing device names or +# a ":" delimited list of device names. Root logins will be allowed only +# upon these devices. +# +CONSOLE /etc/securetty +#CONSOLE console:tty01:tty02:tty03:tty04 + +# +# If defined, all su activity is logged to this file. +# +#SULOG_FILE /var/log/sulog + +# +# If defined, ":" delimited list of "message of the day" files to +# be displayed upon login. +# +#MOTD_FILE /etc/motd +#MOTD_FILE /etc/motd:/usr/lib/news/news-motd + +# +# If defined, this file will be output before each login prompt. +# +#ISSUE_FILE /etc/issue + +# +# If defined, file which maps tty line to TERM environment parameter. +# Each line of the file is in a format something like "vt100 tty01". +# +#TTYTYPE_FILE /etc/ttytype + +# +# If defined, login failures will be logged here in a utmp format. +# last, when invoked as lastb, will read /var/log/btmp, so... +# +#FTMP_FILE /var/log/btmp + +# +# If defined, name of file whose presence which will inhibit non-root +# logins. The contents of this file should be a message indicating +# why logins are inhibited. +# +#NOLOGINS_FILE /etc/nologin + +# +# If defined, the command name to display when running "su -". For +# example, if this is defined as "su" then a "ps" will display the +# command is "-su". If not defined, then "ps" would display the +# name of the shell actually being run, e.g. something like "-sh". +# +SU_NAME su + +# +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, #MAIL_DIR takes precedence. +# +#MAIL_DIR /var/spool/mail +MAIL_FILE .mail + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# +# If defined, either a TZ environment parameter spec or the +# fully-rooted pathname of a file containing such a spec. +# +#ENV_TZ TZ=CST6CDT +#ENV_TZ /etc/tzname + +# +# If defined, an HZ environment parameter spec. +# +# for Linux/x86 +#ENV_HZ HZ=100 +# For Linux/Alpha... +#ENV_HZ HZ=1024 + +# +# *REQUIRED* The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +ENV_PATH PATH=/bin:/usr/bin + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a "write" program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP to the group number and +# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign +# TTYPERM to either 622 or 600. +# +TTYGROUP tty +TTYPERM 0600 + +# +# Login configuration initializations: +# +# ERASECHAR Terminal ERASE character ('\010' = backspace). +# KILLCHAR Terminal KILL character ('\025' = CTRL/U). +# ULIMIT Default "ulimit" value. +# +# The ERASECHAR and KILLCHAR are used only on System V machines. +# The ULIMIT is used only if the system supports it. +# (now it works with setrlimit too; ulimit is in 512-byte units) +# +# Prefix these values with "0" to get octal, "0x" to get hexadecimal. +# +ERASECHAR 0177 +KILLCHAR 025 +#ULIMIT 2097152 + +# Default initial "umask" value for non-PAM enabled systems. +# UMASK is also used by useradd and newusers to set the mode of new home +# directories. +# 022 is the default value, but 027, or even 077, could be considered +# better for privacy. There is no One True Answer here: each sysadmin +# must make up her mind. +UMASK 022 + +# +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_MIN_LEN Minimum acceptable password length. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +#PASS_MIN_LEN 5 +PASS_WARN_AGE 7 + +# +# If "yes", the user must be listed as a member of the first gid 0 group +# in /etc/group (called "root" on most Linux systems) to be able to "su" +# to uid 0 accounts. If the group doesn't exist or is empty, no one +# will be able to "su" to uid 0. +# +#SU_WHEEL_ONLY no + +# +# If compiled with cracklib support, where are the dictionaries +# +#CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +SYS_UID_MIN 101 +SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +SYS_GID_MIN 101 +SYS_GID_MAX 999 + +# +# Max number of login retries if password is bad +# +LOGIN_RETRIES 5 + +# +# Max time in seconds for login +# +LOGIN_TIMEOUT 60 + +# +# Maximum number of attempts to change password if rejected (too easy) +# +#PASS_CHANGE_TRIES 5 + +# +# Warn about weak passwords (but still allow them) if you are root. +# +#PASS_ALWAYS_WARN yes + +# +# Number of significant characters in the password for crypt(). +# Default is 8, don't change unless your crypt() is better. +# Ignored if MD5_CRYPT_ENAB set to "yes". +# +#PASS_MAX_LEN 8 + +# +# Require password before chfn/chsh can make any changes. +# +#CHFN_AUTH yes + +# +# Which fields may be changed by regular users using chfn - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +CHFN_RESTRICT rwh + +# +# Password prompt (%s will be replaced by user name). +# +# XXX - it doesn't work correctly yet, for now leave it commented out +# to use the default which is just "Password: ". +#LOGIN_STRING "%s's Password: " + +# +# Only works if compiled with MD5_CRYPT defined: +# If set to "yes", new passwords will be encrypted using the MD5-based +# algorithm compatible with the one used by recent releases of FreeBSD. +# It supports passwords of unlimited length and longer salt strings. +# Set to "no" if you need to copy encrypted passwords to other systems +# which don't understand the new algorithm. Default is "no". +# +# Note: If you use PAM, it is recommended to use a value consistent with +# the PAM modules configuration. +# +# This variable is deprecated. You should use ENCRYPT_METHOD. +# +#MD5_CRYPT_ENAB no + +# +# Only works if compiled with ENCRYPTMETHOD_SELECT defined: +# If set to MD5 , MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# Overrides the MD5_CRYPT_ENAB option +# +# Note: If you use PAM, it is recommended to use a value consistent with +# the PAM modules configuration. +# +#ENCRYPT_METHOD DES + +# +# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute forcing the password. +# But note also that it more CPU resources will be needed to authenticate +# users. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be inside the 1000-999999999 range. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +# SHA_CRYPT_MIN_ROUNDS 5000 +# SHA_CRYPT_MAX_ROUNDS 5000 + +# +# List of groups to add to the user's supplementary group set +# when logging in on the console (as determined by the CONSOLE +# setting). Default is none. +# +# Use with caution - it is possible for users to gain permanent +# access to these groups, even when not logged in on the console. +# How to do it is left as an exercise for the reader... +# +#CONSOLE_GROUPS floppy:audio:cdrom + +# +# Should login be allowed if we can't cd to the home directory? +# Default in no. +# +DEFAULT_HOME yes + +# +# If this file exists and is readable, login environment will be +# read from it. Every line should be in the form name=value. +# +#ENVIRON_FILE /etc/environment + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# Enable setting of the umask group bits to be the same as owner bits +# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is +# the same as gid, and username is the same as the primary group name. +# +# This also enables userdel to remove user groups if no members exist. +# +USERGROUPS_ENAB yes + +# +# If set to a non-nul number, the shadow utilities will make sure that +# groups never have more than this number of users on one line. +# This permit to support split groups (groups split into multiple lines, +# with the same group ID, to avoid limitation of the line length in the +# group file). +# +# 0 is the default value and disables this feature. +# +#MAX_MEMBERS_PER_GROUP 0 + +# +# If useradd should create home directories for users by default (non +# system users only) +# This option is overridden with the -M or -m flags on the useradd command +# line. +# +CREATE_HOME yes + diff --git a/extended/shadow/centos/meta_patches/0001-Further-parallelize-shadow-utils-build.patch b/extended/shadow/centos/meta_patches/0001-Further-parallelize-shadow-utils-build.patch new file mode 100644 index 000000000..ffc5b52c1 --- /dev/null +++ b/extended/shadow/centos/meta_patches/0001-Further-parallelize-shadow-utils-build.patch @@ -0,0 +1,25 @@ +From d43499ba2cdd43110e3f689243aecc7acce8a6b8 Mon Sep 17 00:00:00 2001 +From: Ryan Tryhorn +Date: Wed, 26 Apr 2017 17:43:43 -0400 +Subject: [PATCH 1/1] Further parallelize shadow-utils build + +--- + SPECS/shadow-utils.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/shadow-utils.spec b/SPECS/shadow-utils.spec +index dde526c..607247d 100644 +--- a/SPECS/shadow-utils.spec ++++ b/SPECS/shadow-utils.spec +@@ -133,7 +133,7 @@ export LC_ALL=C + --with-group-name-max-length=32 + # update the japanese translation + (cd po; make ja.gmo) +-make ++make -j"%(nproc)" + + %install + rm -rf $RPM_BUILD_ROOT +-- +1.8.3.1 + diff --git a/extended/shadow/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/shadow/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..d02737ca0 --- /dev/null +++ b/extended/shadow/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 6cb96c430ee1b3bb97450d16f3dee57331be8242 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 27 Sep 2016 10:52:27 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/shadow-utils.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/shadow-utils.spec b/SPECS/shadow-utils.spec +index d7e2ba9..1aacd11 100644 +--- a/SPECS/shadow-utils.spec ++++ b/SPECS/shadow-utils.spec +@@ -1,7 +1,7 @@ + Summary: Utilities for managing accounts and shadow password files + Name: shadow-utils + Version: 4.1.5.1 +-Release: 24%{?dist} ++Release: 24.el7%{?_tis_dist}.%{tis_patch_ver} + Epoch: 2 + URL: http://pkg-shadow.alioth.debian.org/ + Source0: http://pkg-shadow.alioth.debian.org/releases/shadow-%{version}.tar.bz2 +-- +1.8.3.1 + diff --git a/extended/shadow/centos/meta_patches/PATCH_ORDER b/extended/shadow/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..6514b9467 --- /dev/null +++ b/extended/shadow/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,4 @@ +add-clear-shadow-locs-service-in-spec.patch +0001-Update-package-versioning-for-TIS-format.patch +add-BuildRequires-systemd.patch +0001-Further-parallelize-shadow-utils-build.patch diff --git a/extended/shadow/centos/meta_patches/add-BuildRequires-systemd.patch b/extended/shadow/centos/meta_patches/add-BuildRequires-systemd.patch new file mode 100644 index 000000000..11a374fb8 --- /dev/null +++ b/extended/shadow/centos/meta_patches/add-BuildRequires-systemd.patch @@ -0,0 +1,27 @@ +From aa9e9fcaa006d87e706ed8fcd445108ab48bd479 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 21 Nov 2016 13:35:26 -0500 +Subject: [PATCH 1/1] shadow-utils: add BuildRequires systemd to provide macro + +--- + SPECS/shadow-utils.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/shadow-utils.spec b/SPECS/shadow-utils.spec +index 1aacd11..dde526c 100644 +--- a/SPECS/shadow-utils.spec ++++ b/SPECS/shadow-utils.spec +@@ -46,6 +46,10 @@ BuildRequires: libsemanage-devel + BuildRequires: libacl-devel libattr-devel + BuildRequires: gnome-doc-utils docbook-style-xsl gettext + #BuildRequires: autoconf, automake, libtool, gettext-devel ++ ++# systemd provides %{_unitdir} ++BuildRequires: systemd ++ + Requires: libselinux >= 1.25.2-1 + Requires: audit-libs >= 1.6.5 + Requires: setup +-- +1.8.3.1 + diff --git a/extended/shadow/centos/meta_patches/add-clear-shadow-locs-service-in-spec.patch b/extended/shadow/centos/meta_patches/add-clear-shadow-locs-service-in-spec.patch new file mode 100644 index 000000000..03e1669e5 --- /dev/null +++ b/extended/shadow/centos/meta_patches/add-clear-shadow-locs-service-in-spec.patch @@ -0,0 +1,63 @@ +shadow-utils: add additional service into spec + +clear_shadow_locks.service service is ported from clear_shadow_lock +systemv init script. + +--- + SPECS/shadow-utils.spec | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/SPECS/shadow-utils.spec b/SPECS/shadow-utils.spec +index e7f98da..d7e2ba9 100644 +--- a/SPECS/shadow-utils.spec ++++ b/SPECS/shadow-utils.spec +@@ -8,6 +8,8 @@ Source0: http://pkg-shadow.alioth.debian.org/releases/shadow-%{version}.tar.bz2 + Source3: http://pkg-shadow.alioth.debian.org/releases/shadow-%{version}.tar.bz2.sig + Source1: shadow-utils.login.defs + Source2: shadow-utils.useradd ++Source4: login.defs.cgcs ++Source5: clear_shadow_locks.service + Patch0: shadow-4.1.5-redhat.patch + Patch1: shadow-4.1.5.1-goodname.patch + Patch2: shadow-4.1.5.1-info-parent-dir.patch +@@ -133,9 +135,11 @@ make + rm -rf $RPM_BUILD_ROOT + make install DESTDIR=$RPM_BUILD_ROOT gnulocaledir=$RPM_BUILD_ROOT/%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs + install -d -m 755 $RPM_BUILD_ROOT/%{_sysconfdir}/default +-install -p -c -m 0644 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/login.defs ++install -p -c -m 0644 %{SOURCE4} $RPM_BUILD_ROOT/%{_sysconfdir}/login.defs + install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/default/useradd + ++install -d -m 755 $RPM_BUILD_ROOT/%{_sysconfdir}/init.d ++install -D -m644 %{SOURCE5} $RPM_BUILD_ROOT/%{_unitdir}/clear_shadow_locks.service + + ln -s useradd $RPM_BUILD_ROOT%{_sbindir}/adduser + #ln -s %{_mandir}/man8/useradd.8 $RPM_BUILD_ROOT/%{_mandir}/man8/adduser.8 +@@ -221,6 +225,8 @@ rm -rf $RPM_BUILD_ROOT + %{_sbindir}/adduser + %attr(0750,root,root) %{_sbindir}/user* + %attr(0750,root,root) %{_sbindir}/group* ++%{_unitdir}/clear_shadow_locks.service ++ + %{_sbindir}/grpck + %{_sbindir}/pwck + %{_sbindir}/*conv +@@ -248,6 +254,15 @@ rm -rf $RPM_BUILD_ROOT + %{_mandir}/man8/vipw.8* + %{_mandir}/man8/vigr.8* + ++%post ++%systemd_post clear_shadow_locks.service ++ ++%preun ++%systemd_preun clear_shadow_locks.service ++ ++%postun ++%systemd_postun_with_restart clear_shadow_locks.service ++ + %changelog + * Tue Jun 28 2016 Tomáš Mráz - 2:4.1.5.1-24 + - useradd: fix typo in japanese translation (#1202629) +-- +1.8.3.1 + diff --git a/extended/shadow/centos/srpm_path b/extended/shadow/centos/srpm_path new file mode 100644 index 000000000..7279c7ef5 --- /dev/null +++ b/extended/shadow/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/shadow-utils-4.1.5.1-24.el7.src.rpm diff --git a/extended/shadow/files/clear_shadow_locks b/extended/shadow/files/clear_shadow_locks new file mode 100644 index 000000000..c131170f0 --- /dev/null +++ b/extended/shadow/files/clear_shadow_locks @@ -0,0 +1,11 @@ +#!/bin/bash +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Remove stale shadow lockfiles +# + +rm -f /etc/gshadow.lock /etc/shadow.lock /etc/passwd.lock /etc/group.lock + diff --git a/extended/shadow/files/pam.d/su b/extended/shadow/files/pam.d/su new file mode 100644 index 000000000..921f56cc7 --- /dev/null +++ b/extended/shadow/files/pam.d/su @@ -0,0 +1,69 @@ +# +# The PAM configuration file for the Shadow `su' service +# + +# This allows root to su without passwords (normal operation) +auth sufficient pam_rootok.so + +# Uncomment this to force users to be a member of group root +# before they can use `su'. You can also add "group=foo" +# to the end of this line if you want to use a group other +# than the default "root" (but this may have side effect of +# denying "root" user, unless she's a member of "foo" or explicitly +# permitted earlier by e.g. "sufficient pam_rootok.so"). +# (Replaces the `SU_WHEEL_ONLY' option from login.defs) +# auth required pam_wheel.so + +# Uncomment this if you want wheel members to be able to +# su without a password. +# auth sufficient pam_wheel.so trust + +# Uncomment this if you want members of a specific group to not +# be allowed to use su at all. +# auth required pam_wheel.so deny group=nosu + +# Uncomment and edit /etc/security/time.conf if you need to set +# time restrainst on su usage. +# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs +# as well as /etc/porttime) +# account requisite pam_time.so + +# This module parses environment configuration file(s) +# and also allows you to use an extended config +# file /etc/security/pam_env.conf. +# +# parsing /etc/environment needs "readenv=1" +session required pam_env.so readenv=1 + +# Defines the MAIL environment variable +# However, userdel also needs MAIL_DIR and MAIL_FILE variables +# in /etc/login.defs to make sure that removing a user +# also removes the user's mail spool file. +# See comments in /etc/login.defs +# +# "nopen" stands to avoid reporting new mail when su'ing to another user +session optional pam_mail.so nopen + +# Sets up user limits, please uncomment and read /etc/security/limits.conf +# to enable this functionality. +# (Replaces the use of /etc/limits in old login) +# session required pam_limits.so + +# For first time login or when the user authentication +# token stack has been flushed, su will call passwd +# which will fails with "Authentication Token Error" +# since the previous token on the stack is NULL +# +# Tickle the password service to push a previous +# authentication token on the PAM stack +password optional pam_ldap.so +password optional pam_unix.so + +# The standard Unix authentication modules, used with +# NIS (man nsswitch) as well as normal /etc/passwd and +# /etc/shadow entries. +auth include common-auth +account include common-account +session include common-session + + diff --git a/extended/shim-signed/centos/build_srpm.data b/extended/shim-signed/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/extended/shim-signed/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/extended/shim-signed/centos/meta_patches/0001-Use-presigned-binary.patch b/extended/shim-signed/centos/meta_patches/0001-Use-presigned-binary.patch new file mode 100644 index 000000000..f1da0c517 --- /dev/null +++ b/extended/shim-signed/centos/meta_patches/0001-Use-presigned-binary.patch @@ -0,0 +1,66 @@ +--- a/SPECS/shim-signed.spec 2017-01-05 14:12:11.584037112 -0500 ++++ b/SPECS/shim-signed.spec 2017-01-05 14:20:57.281934890 -0500 +@@ -1,9 +1,13 @@ + Name: shim-signed + Version: 0.9 +-Release: 2%{?dist} ++Release: 2%{?_tis_dist}.%{tis_patch_ver} + Summary: First-stage UEFI bootloader + Provides: shim = %{version}-%{release} +-%define unsigned_release 1.el7.centos ++ ++# note that tis_patch_ver cannot be used in the unsigned_release definition, ++# as the variable represents the patch level of shim-signed, and we have to ++# specifiy the patch of shim-unsigned ++%define unsigned_release 1.el7%{_tis_dist}.1 + + License: BSD + URL: http://www.codon.org.uk/~mjg59/shim/ +@@ -112,25 +116,35 @@ + %define vendor_token_str %{expand:%%{nil}%%{?vendor_token_name:-t "%{vendor_token_name}"}} + %define vendor_cert_str %{expand:%%{!?vendor_cert_nickname:-c "Red Hat Test Certificate"}%%{?vendor_cert_nickname:-c "%%{vendor_cert_nickname}"}} + ++# if we already have a presigned EFI image, then do not do signing -- just ++# use the presigned one. ++ ++if [ -e %{unsigned_dir}shim-presigned.efi ]; then ++ cp %{unsigned_dir}shim-presigned.efi shim.efi ++ cp %{unsigned_dir}shim-presigned.efi shim-%{efidir}.efi ++else + %ifarch %{ca_signed_arches} +-pesign -i %{shimsrc} -h -P > shim.hash +-if ! cmp shim.hash %{unsigned_dir}shim.hash ; then +- echo Invalid signature\! > /dev/stderr +- exit 1 +-fi +-cp %{shimsrc} shim.efi ++ cp %{unsigned_dir}shim.efi shim-unsigned.efi + %endif + %ifarch %{rh_signed_arches} +-%pesign -s -i %{unsigned_dir}shim.efi -a %{SOURCE3} -c %{SOURCE3} -o shim-%{efidir}.efi ++ %pesign -s -i %{unsigned_dir}shim.efi -a %{SOURCE3} -c %{SOURCE3} -o shim-%{efidir}.efi + %endif + %ifarch %{rh_signed_arches} +-%ifnarch %{ca_signed_arches} +-cp shim-%{efidir}.efi shim.efi +-%endif ++ cp shim-%{efidir}.efi shim.efi + %endif ++fi # end "if shim-presigned.efi exists" + +-%pesign -s -i %{unsigned_dir}MokManager.efi -o MokManager.efi -a %{SOURCE3} -c %{SOURCE3} +-%pesign -s -i %{unsigned_dir}fallback.efi -o fallback.efi -a %{SOURCE3} -c %{SOURCE3} ++if [ -e %{unsigned_dir}MokManager-presigned.efi ]; then ++ cp %{unsigned_dir}MokManager-presigned.efi MokManager.efi ++else ++ %pesign -s -i %{unsigned_dir}MokManager.efi -o MokManager.efi -a %{SOURCE3} -c %{SOURCE3} ++fi ++ ++if [ -e %{unsigned_dir}fallback-presigned.efi ]; then ++ cp %{unsigned_dir}fallback-presigned.efi fallback.efi ++else ++ %pesign -s -i %{unsigned_dir}fallback.efi -o fallback.efi -a %{SOURCE3} -c %{SOURCE3} ++fi + + cd mokutil-%{mokutil_version} + ./autogen.sh diff --git a/extended/shim-signed/centos/meta_patches/0001-calculate-rather-than-hardcode-shim-unsigned-version.patch b/extended/shim-signed/centos/meta_patches/0001-calculate-rather-than-hardcode-shim-unsigned-version.patch new file mode 100644 index 000000000..0e49009bc --- /dev/null +++ b/extended/shim-signed/centos/meta_patches/0001-calculate-rather-than-hardcode-shim-unsigned-version.patch @@ -0,0 +1,55 @@ +From 1c898dfc32b11e94ad90ab76fcff2ba2b65dfa6d Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Tue, 31 Jan 2017 16:51:23 -0500 +Subject: [PATCH] calculate rather than hardcode shim-unsigned version + +--- + SPECS/shim-signed.spec | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/SPECS/shim-signed.spec b/SPECS/shim-signed.spec +index f271a05..1b00621 100644 +--- a/SPECS/shim-signed.spec ++++ b/SPECS/shim-signed.spec +@@ -4,10 +4,6 @@ Release: 2%{?_tis_dist}.%{tis_patch_ver} + Summary: First-stage UEFI bootloader + Provides: shim = %{version}-%{release} + +-# note that tis_patch_ver cannot be used in the unsigned_release definition, +-# as the variable represents the patch level of shim-signed, and we have to +-# specifiy the patch of shim-unsigned +-%define unsigned_release 1.el7%{_tis_dist}.1 + + License: BSD + URL: http://www.codon.org.uk/~mjg59/shim/ +@@ -32,14 +28,13 @@ Source5: BOOT.CSV + %global efiarchlc aa64 + %global shimsrc %{SOURCE2} + %endif +-%define unsigned_dir %{_datadir}/shim/%{efiarchlc}-%{version}-%{unsigned_release}/ ++ + + BuildRequires: git + BuildRequires: openssl-devel openssl + BuildRequires: pesign >= 0.106-5%{dist} + BuildRequires: efivar-devel +-# BuildRequires: shim-unsigned = %{version}-%{unsigned_release} +-BuildRequires: shim-unsigned = %{version}-%{unsigned_release} ++BuildRequires: shim-unsigned + + # for mokutil's configure + BuildRequires: autoconf automake +@@ -119,6 +114,10 @@ git config --unset user.name + # if we already have a presigned EFI image, then do not do signing -- just + # use the presigned one. + ++# %define unsigned_release 1.el7%{_tis_dist}.1 ++%global unsigned_release %(rpm -q --queryformat '%%{RELEASE}' shim-unsigned | sort --version-sort | tail -1) ++%define unsigned_dir %{_datadir}/shim/%{efiarchlc}-%{version}-%{unsigned_release}/ ++ + if [ -e %{unsigned_dir}shim-presigned.efi ]; then + cp %{unsigned_dir}shim-presigned.efi shim.efi + cp %{unsigned_dir}shim-presigned.efi shim-%{efidir}.efi +-- +1.8.3.1 + diff --git a/extended/shim-signed/centos/meta_patches/PATCH_ORDER b/extended/shim-signed/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..db82cf4d0 --- /dev/null +++ b/extended/shim-signed/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Use-presigned-binary.patch +0001-calculate-rather-than-hardcode-shim-unsigned-version.patch diff --git a/extended/shim-signed/centos/srpm_path b/extended/shim-signed/centos/srpm_path new file mode 100644 index 000000000..f206620ca --- /dev/null +++ b/extended/shim-signed/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/shim-signed-0.9-2.el7.src.rpm diff --git a/extended/shim-unsigned/centos/build_srpm.data b/extended/shim-unsigned/centos/build_srpm.data new file mode 100644 index 000000000..12805e870 --- /dev/null +++ b/extended/shim-unsigned/centos/build_srpm.data @@ -0,0 +1,2 @@ +TIS_PATCH_VER=2 +COPY_LIST="$PKG_BASE/files/tis-shim.crt" diff --git a/extended/shim-unsigned/centos/meta_patches/0001-Embed-TiS-cert.patch b/extended/shim-unsigned/centos/meta_patches/0001-Embed-TiS-cert.patch new file mode 100644 index 000000000..9e187490f --- /dev/null +++ b/extended/shim-unsigned/centos/meta_patches/0001-Embed-TiS-cert.patch @@ -0,0 +1,31 @@ +diff --git a/SPECS/shim.spec b/SPECS/shim.spec +index 6aa8346..a8945ab 100644 +--- a/SPECS/shim.spec ++++ b/SPECS/shim.spec +@@ -1,6 +1,6 @@ + Name: shim + Version: 0.9 +-Release: 1.el7.centos ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: First-stage UEFI bootloader + + License: BSD +@@ -10,8 +10,10 @@ Source1: centos.crt + # currently here's what's in our dbx: # nothing. + #Source2: dbx.esl + Source3: shim-find-debuginfo.sh ++Source4: tis-shim.crt + + Patch0001: 0001-Typo-on-aarch64.patch ++Patch0002: 0001-Use-TiS-cert.patch + + BuildRequires: git openssl-devel openssl + BuildRequires: pesign >= 0.106-1 +@@ -81,6 +83,7 @@ git commit -a -q -m "%{version} baseline." + git am --ignore-whitespace %{patches} = 0.106-1 diff --git a/extended/shim-unsigned/centos/meta_patches/PATCH_ORDER b/extended/shim-unsigned/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..99f110271 --- /dev/null +++ b/extended/shim-unsigned/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Embed-TiS-cert.patch +0001-Objcopy-version.patch +spec.arch.patch diff --git a/extended/shim-unsigned/centos/meta_patches/spec.arch.patch b/extended/shim-unsigned/centos/meta_patches/spec.arch.patch new file mode 100644 index 000000000..a6f333d43 --- /dev/null +++ b/extended/shim-unsigned/centos/meta_patches/spec.arch.patch @@ -0,0 +1,12 @@ +diff --git a/SPECS/shim.spec b/SPECS/shim.spec +index b6a6d0e..dcfb66e 100644 +--- a/SPECS/shim.spec ++++ b/SPECS/shim.spec +@@ -65,7 +65,6 @@ Obsoletes: shim-debuginfo < 0.9 + Summary: Debug information for package %{name} + Group: Development/Debug + AutoReqProv: 0 +-BuildArch: noarch + + %description -n shim-unsigned-%{efiarch}-debuginfo + This package provides debug information for package %{name}. diff --git a/extended/shim-unsigned/centos/patches/0001-Objcopy-version.patch b/extended/shim-unsigned/centos/patches/0001-Objcopy-version.patch new file mode 100644 index 000000000..af01cc167 --- /dev/null +++ b/extended/shim-unsigned/centos/patches/0001-Objcopy-version.patch @@ -0,0 +1,19 @@ +From 551015b9e0a7b226840ccb758d2fcbd4430d83d5 Mon Sep 17 00:00:00 2001 +From: jmckenna +Date: Thu, 19 Jan 2017 15:05:16 -0500 +Subject: [PATCH] Better parting of objcopy version + + +diff --git a/Makefile b/Makefile +index e8b291e..02388ac 100644 +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ LD = $(CROSS_COMPILE)ld + OBJCOPY = $(CROSS_COMPILE)objcopy + + ARCH = $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,) +-OBJCOPY_GTE224 = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.* //g' | cut -f1-2 -d.` \>= 2.24) ++OBJCOPY_GTE224 = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.*version //g' | cut -f1-2 -d.` \>= 2.24) + + SUBDIRS = Cryptlib lib + diff --git a/extended/shim-unsigned/centos/patches/0001-Use-TiS-cert.patch b/extended/shim-unsigned/centos/patches/0001-Use-TiS-cert.patch new file mode 100644 index 000000000..07703cc26 --- /dev/null +++ b/extended/shim-unsigned/centos/patches/0001-Use-TiS-cert.patch @@ -0,0 +1,68 @@ +From 6a0a1ea93362b7f9f2f5242e847ae1e0ef15de04 Mon Sep 17 00:00:00 2001 +From: jmckenna +Date: Thu, 5 Jan 2017 08:54:32 -0500 +Subject: [PATCH] Use Titanium Cloud certificate + + +diff --git a/Makefile b/Makefile +index 1181b8a..e8b291e 100644 +--- a/Makefile ++++ b/Makefile +@@ -34,6 +34,12 @@ CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \ + "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \ + $(EFI_INCLUDES) + ++# We compile a certificate into shim. Usually this is a one-time generated ++# certificate (make-certs script) however we want to include a custom ++# certificate for which we have the key. We use the key to sign the kernel and ++# grub down the road ++INTERNAL_CERT = tis-shim ++ + ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined) + CFLAGS += -DOVERRIDE_SECURITY_POLICY + endif +@@ -67,7 +73,7 @@ LDFLAGS = --hash-style=sysv -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsym + + TARGET = shim.efi MokManager.efi.signed fallback.efi.signed + OBJS = shim.o netboot.o cert.o replacements.o version.o +-KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer ++KEYS = shim_cert.h ocsp.* ca.* $(INTERNAL_CERT).crt $(INTERNAL_CERT).csr $(INTERNAL_CERT).p12 $(INTERNAL_CERT).pem $(INTERNAL_CERT).key $(INTERNAL_CERT).cer + SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h version.c version.h + MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o + MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h +@@ -76,13 +82,17 @@ FALLBACK_SRCS = fallback.c + + all: $(TARGET) + +-shim.crt: +- ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 $@ + hexdump -v -e '1/1 "0x%02x, "' $< >> $@ + echo "};" >> $@ +@@ -93,10 +103,10 @@ version.c : version.c.in + -e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \ + < version.c.in > version.c + +-certdb/secmod.db: shim.crt ++certdb/secmod.db: $(INTERNAL_CERT).crt + -mkdir certdb +- pk12util -d certdb/ -i shim.p12 -W "" -K "" +- certutil -d certdb/ -A -i shim.crt -n shim -t u ++ pk12util -d certdb/ -i $(INTERNAL_CERT).p12 -W "" -K "" ++ certutil -d certdb/ -A -i $(INTERNAL_CERT).crt -n shim -t u + + shim.o: $(SOURCES) shim_cert.h + diff --git a/extended/shim-unsigned/centos/srpm_path b/extended/shim-unsigned/centos/srpm_path new file mode 100644 index 000000000..738f15200 --- /dev/null +++ b/extended/shim-unsigned/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/shim-0.9-1.el7.centos.src.rpm diff --git a/extended/shim-unsigned/files/tis-shim.crt b/extended/shim-unsigned/files/tis-shim.crt new file mode 100644 index 000000000..754b03e66 --- /dev/null +++ b/extended/shim-unsigned/files/tis-shim.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAK2dlnyaByQOMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkNBMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTcwMzAxMDEzNTUwWhcNMTgwMzAxMDEzNTUwWjBF +MQswCQYDVQQGEwJDQTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA8XK4jSYD9/WgUu4uZ50fPnRkFZmfK837oCZzgezlORzR38F1frX+3Qjx +Nohg5uINP8l45mXpEMgD2tzsFGO6pcFpzzKPMAsmPJwODbGYbWr29RCd25h8IGRg +5RqAjWn2E0vUpweZbo9nVvA1vukSjeUxOoHZmAsTBFWf10HOfTOdQnJ7IcHLPtb7 +bqVPxpexVSwr5lLT8iCzisIVjHJE9G/WqEkhgbYaM8cNa1QmZFJJubHLIqlru73V +SO2dItQ89LLBi/tb2QXTz+0xhgMlD8tzcYMPeiScSwdO9GURghsqWnltnNB+R/HA +RKOip1DHRicEgBOhE2s42qBwZP67kwIDAQABo1AwTjAdBgNVHQ4EFgQU4ncd0+jE +zjXeo8yTEhEZc5kLdMwwHwYDVR0jBBgwFoAU4ncd0+jEzjXeo8yTEhEZc5kLdMww +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAc1WR6lgUM5Onz2eaA/Vt +AsEnSmjslr5pHP1UuageaLixTmYaqMl7+KiHGmhsZDjME0d3lbjebadp9t4Yjjlf +Vgx0QcvHHuI/eIFs/femJXDYUrr2JPKMF1quS4MaKiem71pHeouwyAzbzvxS3wh1 +a6ia27kuqvMyq2738kbfjmVQnc0D9etw5kaWouDMUMj5W2awxMbKBFLPmpqMGlku +Sw4uStDSlmiMrro41Tfkmh57AbYXP7i7bqbz/smnQ6YZdMcFYdlB7k2IePt6DVG+ +/zM2npEBopXi/5MWzmG0xBSEiiy9Yo+mSTh+3RvXtYxBmmwZb7wvJ6Cgp92NuA6B +Eg== +-----END CERTIFICATE----- diff --git a/extended/sudo/centos/build_srpm.data b/extended/sudo/centos/build_srpm.data new file mode 100644 index 000000000..d3f64f336 --- /dev/null +++ b/extended/sudo/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=3 diff --git a/extended/sudo/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/sudo/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..aa778d5ba --- /dev/null +++ b/extended/sudo/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 39b08b2cc4eb6d47490593a599db95703b74b754 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:50:44 -0400 +Subject: [PATCH 1/3] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/sudo.spec +--- + SPECS/sudo.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec +index c3a1a52..7d1486b 100644 +--- a/SPECS/sudo.spec ++++ b/SPECS/sudo.spec +@@ -1,7 +1,7 @@ + Summary: Allows restricted root access for specified users + Name: sudo + Version: 1.8.19p2 +-Release: 11%{?dist} ++Release: 11.el7_4%{?_tis_dist}.%{tis_patch_ver} + License: ISC + Group: Applications/System + URL: http://www.courtesan.com/sudo/ +-- +1.9.1 + diff --git a/extended/sudo/centos/meta_patches/0002-spec-include-TiS-changes.patch b/extended/sudo/centos/meta_patches/0002-spec-include-TiS-changes.patch new file mode 100644 index 000000000..2439386c2 --- /dev/null +++ b/extended/sudo/centos/meta_patches/0002-spec-include-TiS-changes.patch @@ -0,0 +1,66 @@ +From abc3ec24a957002962bb4038946291b84bea3859 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:50:44 -0400 +Subject: [PATCH 2/3] WRS: 0002-spec-include-TiS-changes.patch + +--- + SPECS/sudo.spec | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec +index 7d1486b..d731ba9 100644 +--- a/SPECS/sudo.spec ++++ b/SPECS/sudo.spec +@@ -64,6 +64,8 @@ Patch17: sudo-1.8.19p2-get_process_ttyname.patch + # 1459152 - CVE-2017-1000368: Privilege escalation via improper get_process_ttyname() parsing (insufficient fix for CVE-2017-1000367) + Patch18: sudo-1.8.19p2-CVE-2017-1000368.patch + ++# WRS patches ++ + %description + Sudo (superuser do) allows a system administrator to give certain + users (or groups of users) the ability to run some (or all) commands +@@ -106,6 +108,8 @@ plugins that use %{name}. + %patch17 -p1 -b .get_process_ttyname + %patch18 -p1 -b .CVE-2017-1000368 + ++# WRS patches ++ + %build + autoreconf -I m4 -fv --install + +@@ -132,7 +136,7 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" SHL + --with-ignore-dot \ + --with-tty-tickets \ + --with-ldap \ +- --with-ldap-conf-file="%{_sysconfdir}/sudo-ldap.conf" \ ++ --with-ldap-conf-file="%{_sysconfdir}/openldap/ldap.conf" \ + --with-selinux \ + --with-passprompt="[sudo] password for %p: " \ + --with-linux-audit \ +@@ -158,6 +162,12 @@ install -p -c -m 0440 %{SOURCE1} $RPM_BUILD_ROOT/etc/sudoers + install -p -c -m 0640 %{SOURCE3} $RPM_BUILD_ROOT/etc/sudo.conf + install -p -c -m 0640 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sudo-ldap.conf + ++install -d $RPM_BUILD_ROOT/%{_sysconfdir}/openldap/schema/ ++install -m 644 doc/schema.OpenLDAP $RPM_BUILD_ROOT/%{_sysconfdir}/openldap/schema/sudo.schema ++ ++install -d $RPM_BUILD_ROOT/%{_datadir}/sudo ++install -m 700 plugins/sudoers/sudoers2ldif $RPM_BUILD_ROOT/%{_datadir}/sudo/sudoers2ldif ++ + # Remove execute permission on this script so we don't pull in perl deps + chmod -x $RPM_BUILD_ROOT%{_docdir}/sudo-*/sudoers2ldif + +@@ -226,7 +236,8 @@ rm -rf $RPM_BUILD_ROOT + %{_mandir}/man8/visudo.8* + %dir %{_docdir}/sudo-%{version} + %{_docdir}/sudo-%{version}/* +- ++%{_sysconfdir}/openldap/schema/sudo.schema ++%{_datadir}/sudo/sudoers2ldif + + # Make sure permissions are ok even if we're updating + %post +-- +1.9.1 + diff --git a/extended/sudo/centos/meta_patches/0003-Further-parallelize-sudo-build.patch b/extended/sudo/centos/meta_patches/0003-Further-parallelize-sudo-build.patch new file mode 100644 index 000000000..db86d5ea8 --- /dev/null +++ b/extended/sudo/centos/meta_patches/0003-Further-parallelize-sudo-build.patch @@ -0,0 +1,25 @@ +From b670ce302dc1ffbb71d2a88124b843e9be12c42c Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 16:50:44 -0400 +Subject: [PATCH 3/3] WRS: 0003-Further-parallelize-sudo-build.patch + +--- + SPECS/sudo.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec +index d731ba9..713bf5f 100644 +--- a/SPECS/sudo.spec ++++ b/SPECS/sudo.spec +@@ -144,7 +144,7 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" SHL + --with-sssd + # --without-kerb5 \ + # --without-kerb4 +-make ++make -j"%(nproc)" + + make check + +-- +1.9.1 + diff --git a/extended/sudo/centos/meta_patches/0004-remove-make-check.patch b/extended/sudo/centos/meta_patches/0004-remove-make-check.patch new file mode 100644 index 000000000..912f6df5a --- /dev/null +++ b/extended/sudo/centos/meta_patches/0004-remove-make-check.patch @@ -0,0 +1,14 @@ +diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec +index 4a34dba..fcb2e05 100644 +--- a/SPECS/sudo.spec ++++ b/SPECS/sudo.spec +@@ -145,7 +145,8 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" SHL + # --without-kerb4 + make -j"%(nproc)" + +-make check ++# "make check" fails if there is no group named "bin" in the mock system ++# make check + + %install + rm -rf $RPM_BUILD_ROOT diff --git a/extended/sudo/centos/meta_patches/PATCH_ORDER b/extended/sudo/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..06cd47d68 --- /dev/null +++ b/extended/sudo/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,4 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-spec-include-TiS-changes.patch +0003-Further-parallelize-sudo-build.patch +0004-remove-make-check.patch diff --git a/extended/sudo/centos/srpm_path b/extended/sudo/centos/srpm_path new file mode 100644 index 000000000..194ad3be2 --- /dev/null +++ b/extended/sudo/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/sudo-1.8.19p2-11.el7_4.src.rpm diff --git a/extended/sudo/files/sudo-CVE-2015-5602.patch b/extended/sudo/files/sudo-CVE-2015-5602.patch new file mode 100644 index 000000000..de830dded --- /dev/null +++ b/extended/sudo/files/sudo-CVE-2015-5602.patch @@ -0,0 +1,401 @@ +sudo: CVE-2015-5602 + +the patch is based on: +https://www.sudo.ws/repos/sudo/rev/9636fd256325 +https://www.sudo.ws/repos/sudo/rev/c2e36a80a279 + +Rewritten sudoedit_checkdir support that checks all the dirs in the +path and refuses to follow symlinks in writable directories. +This is a better fix for CVE-2015-5602. +Adapted from a diff by Ben Hutchings. Bug #707 + +Signed-off-by: Li Wang +--- + plugins/sudoers/policy.c | 5 + src/sudo.c | 10 + + src/sudo.h | 3 + src/sudo_edit.c | 289 +++++++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 296 insertions(+), 11 deletions(-) + +--- a/src/sudo_edit.c ++++ b/src/sudo_edit.c +@@ -79,6 +79,267 @@ switch_user(uid_t euid, gid_t egid, int + debug_return; + } + ++static bool ++group_matches(gid_t target, gid_t gid, int ngroups, GETGROUPS_T *groups) ++{ ++ int i; ++ debug_decl(group_matches, SUDO_DEBUG_EDIT) ++ ++ if (target == gid) { ++ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, ++ "user gid %u matches directory gid %u", (unsigned int)gid, ++ (unsigned int)target); ++ debug_return_bool(true); ++ } ++ for (i = 0; i < ngroups; i++) { ++ if (target == groups[i]) { ++ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, ++ "user gid %u matches directory gid %u", (unsigned int)gid, ++ (unsigned int)target); ++ debug_return_bool(true); ++ } ++ } ++ debug_return_bool(false); ++} ++ ++#ifdef O_NOFOLLOW ++static int ++sudo_edit_openat_nofollow(int dfd, char *path, int oflags, mode_t mode) ++{ ++ debug_decl(sudo_edit_open_nofollow, SUDO_DEBUG_EDIT) ++ ++ debug_return_int(openat(dfd, path, oflags|O_NOFOLLOW, mode)); ++} ++#else ++/* ++ * Returns true if fd and path don't match or path is a symlink. ++ * Used on older systems without O_NOFOLLOW. ++ */ ++static bool ++sudo_edit_is_symlink(int fd, char *path) ++{ ++ struct stat sb1, sb2; ++ debug_decl(sudo_edit_is_symlink, SUDO_DEBUG_EDIT) ++ ++ /* ++ * Treat [fl]stat() failure like there was a symlink. ++ */ ++ if (fstat(fd, &sb1) == -1 || lstat(path, &sb2) == -1) ++ debug_return_bool(true); ++ ++ /* ++ * Make sure we did not open a link and that what we opened ++ * matches what is currently on the file system. ++ */ ++ if (S_ISLNK(sb2.st_mode) || ++ sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) { ++ debug_return_bool(true); ++ } ++ ++ debug_return_bool(false); ++} ++ ++static int ++sudo_edit_openat_nofollow(char *path, int oflags, mode_t mode) ++{ ++ struct stat sb1, sb2; ++ int fd; ++ debug_decl(sudo_edit_openat_nofollow, SUDO_DEBUG_EDIT) ++ ++ fd = openat(dfd, path, oflags, mode); ++ if (fd == -1) ++ debug_return_int(-1); ++ ++ if (sudo_edit_is_symlink(fd, path)) { ++ close(fd); ++ fd = -1; ++ errno = ELOOP; ++ } ++ ++ debug_return_int(fd); ++} ++#endif /* O_NOFOLLOW */ ++ ++/* ++ * Returns true if the directory described by sb is writable ++ * by the user. We treat directories with the sticky bit as ++ * unwritable unless they are owned by the user. ++ */ ++static bool ++dir_is_writable(struct stat *sb, uid_t uid, gid_t gid, int ngroups, ++ GETGROUPS_T *groups) ++{ ++ debug_decl(dir_is_writable, SUDO_DEBUG_EDIT) ++ ++ /* If the user owns the dir we always consider it writable. */ ++ if (sb->st_uid == uid) { ++ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, ++ "user uid %u matches directory uid %u", (unsigned int)uid, ++ (unsigned int)sb->st_uid); ++ debug_return_bool(true); ++ } ++ ++ /* Other writable? */ ++ if (ISSET(sb->st_mode, S_IWOTH)) { ++ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, ++ "directory is writable by other"); ++ debug_return_bool(true); ++ } ++ ++ /* Group writable? */ ++ if (ISSET(sb->st_mode, S_IWGRP)) { ++ if (group_matches(sb->st_gid, gid, ngroups, groups)) { ++ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, ++ "directory is writable by one of the user's groups"); ++ debug_return_bool(true); ++ } ++ } ++ ++ debug_return_bool(false); ++} ++ ++/* ++ * Directory open flags for use with openat(2) and fstat(2). ++ * Use O_PATH and O_DIRECTORY where possible. ++ */ ++#if defined(O_PATH) && defined(O_DIRECTORY) ++# define DIR_OPEN_FLAGS (O_PATH|O_DIRECTORY) ++#elif defined(O_PATH) && !defined(O_DIRECTORY) ++# define DIR_OPEN_FLAGS O_PATH ++#elif !defined(O_PATH) && defined(O_DIRECTORY) ++# define DIR_OPEN_FLAGS (O_RDONLY|O_DIRECTORY) ++#else ++# define DIR_OPEN_FLAGS (O_RDONLY|O_NONBLOCK) ++#endif ++ ++static int ++sudo_edit_open_nonwritable(char *path, int oflags, mode_t mode) ++{ ++ int dfd, fd, dflags = DIR_OPEN_FLAGS; ++#if defined(__linux__) && defined(O_PATH) ++ char *opath = path; ++#endif ++ bool is_writable; ++ struct stat sb; ++ debug_decl(sudo_edit_open_nonwritable, SUDO_DEBUG_EDIT) ++ ++#if defined(__linux__) && defined(O_PATH) ++restart: ++#endif ++ if (path[0] == '/') { ++ dfd = open("/", dflags); ++ path++; ++ } else { ++ dfd = open(".", dflags); ++ if (path[0] == '.' && path[1] == '/') ++ path += 2; ++ } ++ if (dfd == -1) ++ debug_return_int(-1); ++ ++ for (;;) { ++ char *slash; ++ int subdfd; ++ ++ /* ++ * Look up one component at a time, avoiding symbolic links in ++ * writable directories. ++ */ ++ if (fstat(dfd, &sb) == -1) { ++ close(dfd); ++#if defined(__linux__) && defined(O_PATH) ++ /* Linux prior to 3.6 can't fstat an O_PATH fd */ ++ if (ISSET(dflags, O_PATH)) { ++ CLR(dflags, O_PATH); ++ path = opath; ++ goto restart; ++ } ++#endif ++ debug_return_int(-1); ++ } ++#ifndef O_DIRECTORY ++ if (!S_ISDIR(sb.st_mode)) { ++ close(dfd); ++ errno = ENOTDIR; ++ debug_return_int(-1); ++ } ++#endif ++ is_writable = dir_is_writable(&sb, user_details.uid, user_details.gid, ++ user_details.ngroups, user_details.groups); ++ ++ while (path[0] == '/') ++ path++; ++ slash = strchr(path, '/'); ++ if (slash == NULL) ++ break; ++ *slash = '\0'; ++ if (is_writable) ++ subdfd = sudo_edit_openat_nofollow(dfd, path, dflags, 0); ++ else ++ subdfd = openat(dfd, path, dflags, 0); ++ *slash = '/'; /* restore path */ ++ close(dfd); ++ if (subdfd == -1) ++ debug_return_int(-1); ++ path = slash + 1; ++ dfd = subdfd; ++ } ++ ++ if (is_writable) { ++ close(dfd); ++ errno = EISDIR; ++ debug_return_int(-1); ++ } ++ ++ fd = openat(dfd, path, oflags, mode); ++ close(dfd); ++ debug_return_int(fd); ++} ++ ++#ifdef O_NOFOLLOW ++static int ++sudo_edit_open(char *path, int oflags, mode_t mode, int sflags) ++{ ++ int fd; ++ debug_decl(sudo_edit_open, SUDO_DEBUG_EDIT) ++ ++ if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW)) ++ oflags |= O_NOFOLLOW; ++ if (ISSET(sflags, CD_SUDOEDIT_CHECKDIR) && user_details.uid != 0) ++ fd = sudo_edit_open_nonwritable(path, oflags|O_NONBLOCK, mode); ++ else ++ fd = open(path, oflags|O_NONBLOCK, mode); ++ if (fd != -1 && !ISSET(oflags, O_NONBLOCK)) ++ (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); ++ debug_return_int(fd); ++} ++#else ++static int ++sudo_edit_open(char *path, int oflags, mode_t mode, int sflags) ++{ ++ struct stat sb1, sb2; ++ int fd; ++ debug_decl(sudo_edit_open, SUDO_DEBUG_EDIT) ++ ++ if (ISSET(sflags, CD_SUDOEDIT_CHECKDIR) && user_details.uid != 0) ++ fd = sudo_edit_open_nonwritable(path, oflags|O_NONBLOCK, mode); ++ else ++ fd = open(path, oflags|O_NONBLOCK, mode); ++ if (fd == -1) ++ debug_return_int(-1); ++ if (!ISSET(oflags, O_NONBLOCK)) ++ (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); ++ ++ if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW) && sudo_edit_is_symlink(fd, path)) { ++ close(fd); ++ fd = -1; ++ errno = ELOOP; ++ } ++ ++ debug_return_int(fd); ++} ++#endif /* O_NOFOLLOW */ ++ + /* + * Wrapper to allow users to edit privileged files with their own uid. + */ +@@ -97,8 +358,8 @@ sudo_edit(struct command_details *comman + struct tempfile { + char *tfile; + char *ofile; +- struct timeval omtim; + off_t osize; ++ struct timeval omtim; + } *tf = NULL; + debug_decl(sudo_edit, SUDO_DEBUG_EDIT) + +@@ -153,7 +414,8 @@ sudo_edit(struct command_details *comman + rc = -1; + switch_user(command_details->euid, command_details->egid, + command_details->ngroups, command_details->groups); +- if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) { ++ ofd = sudo_edit_open(files[i], O_RDONLY, 0644, command_details->flags); ++ if (ofd != -1 || errno == ENOENT) { + if (ofd == -1) { + zero_bytes(&sb, sizeof(sb)); /* new file */ + rc = 0; +@@ -163,11 +425,17 @@ sudo_edit(struct command_details *comman + } + switch_user(ROOT_UID, user_details.egid, + user_details.ngroups, user_details.groups); +- if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) { +- if (rc) +- warning("%s", files[i]); ++ if (ofd != -1 && !S_ISREG(sb.st_mode)) { ++ warningx(_("%s: not a regular file"), files[i]); ++ close(ofd); ++ continue; ++ } ++ if (rc == -1) { ++ /* open() or fstat() error. */ ++ if (ofd == -1 && errno == ELOOP) ++ warningx(_("%s: is a symbolic link"), files[i]); + else +- warningx(_("%s: not a regular file"), files[i]); ++ warning("%s", files[i]); + if (ofd != -1) + close(ofd); + continue; +@@ -258,9 +526,9 @@ sudo_edit(struct command_details *comman + rc = -1; + if (seteuid(user_details.uid) != 0) + fatal("seteuid(%d)", (int)user_details.uid); +- if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) { ++ tfd = sudo_edit_open(tf[i].tfile, O_RDONLY, 0644, 0); ++ if (tfd != -1) + rc = fstat(tfd, &sb); +- } + if (seteuid(ROOT_UID) != 0) + fatal("seteuid(ROOT_UID)"); + if (rc || !S_ISREG(sb.st_mode)) { +@@ -289,8 +557,9 @@ sudo_edit(struct command_details *comman + } + switch_user(command_details->euid, command_details->egid, + command_details->ngroups, command_details->groups); +- ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644); +- switch_user(ROOT_UID, user_details.egid, ++ ofd = sudo_edit_open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644, ++ command_details->flags); ++ switch_user(ROOT_UID, user_details.egid, + user_details.ngroups, user_details.groups); + if (ofd == -1) { + warning(_("unable to write to %s"), tf[i].ofile); +--- a/plugins/sudoers/policy.c ++++ b/plugins/sudoers/policy.c +@@ -383,8 +383,11 @@ sudoers_policy_exec_setup(char *argv[], + easprintf(&command_info[info_len++], "maxseq=%u", def_maxseq); + } + } +- if (ISSET(sudo_mode, MODE_EDIT)) ++ if (ISSET(sudo_mode, MODE_EDIT)) { + command_info[info_len++] = estrdup("sudoedit=true"); ++ command_info[info_len++] = estrdup("sudoedit_checkdir=true"); ++ command_info[info_len++] = estrdup("sudoedit_follow=true"); ++ } + if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) { + /* Set cwd to run user's homedir. */ + command_info[info_len++] = fmt_string("cwd", runas_pw->pw_dir); +--- a/src/sudo.c ++++ b/src/sudo.c +@@ -727,6 +727,16 @@ command_info_to_details(char * const inf + SET(details->flags, CD_SUDOEDIT); + break; + } ++ if (strncmp("sudoedit_checkdir=", info[i], sizeof("sudoedit_checkdir=") - 1) == 0) { ++ if (atobool(info[i] + sizeof("sudoedit_checkdir=") - 1) == true) ++ SET(details->flags, CD_SUDOEDIT_CHECKDIR); ++ break; ++ } ++ if (strncmp("sudoedit_follow=", info[i], sizeof("sudoedit_follow=") - 1) == 0) { ++ if (atobool(info[i] + sizeof("sudoedit_follow=") - 1) == true) ++ SET(details->flags, CD_SUDOEDIT_FOLLOW); ++ break; ++ } + break; + case 't': + if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) { +--- a/src/sudo.h ++++ b/src/sudo.h +@@ -129,6 +129,9 @@ struct user_details { + #define CD_USE_PTY 0x1000 + #define CD_SET_UTMP 0x2000 + #define CD_EXEC_BG 0x4000 ++#define CD_SUDOEDIT_COPY 0x08000 ++#define CD_SUDOEDIT_FOLLOW 0x10000 ++#define CD_SUDOEDIT_CHECKDIR 0x20000 + + struct command_details { + uid_t uid; diff --git a/extended/syslog-ng/centos/build_srpm.data b/extended/syslog-ng/centos/build_srpm.data new file mode 100644 index 000000000..8f6f518cd --- /dev/null +++ b/extended/syslog-ng/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$PKG_BASE/centos/files/*" +TIS_PATCH_VER=20 diff --git a/extended/syslog-ng/centos/files/fm_event_syslogger b/extended/syslog-ng/centos/files/fm_event_syslogger new file mode 100644 index 000000000..1570659b4 --- /dev/null +++ b/extended/syslog-ng/centos/files/fm_event_syslogger @@ -0,0 +1,78 @@ +#!/bin/bash +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Install a new certificate file, pushing it to both controllers +# Also allow a TPM option to install the certificate files using +# an onboard Trusted Platform Module (TPM) + +source /etc/platform/platform.conf + +processIMAAppraisal() +{ + # SAMPLE INCOMING EVENT: + # 20:43:51.000 localhost audispd: info node=localhost.localdomain + # type=INTEGRITY_DATA msg=audit(1507236231.359:4179): pid=4411 uid=0 + # auid=1875 ses=18 op="appraise_data" cause="missing-signature" + # comm=sudo name=/usr/lib64/ld-2.17.so dev=sda3 ino=262715 res=0 + event_array=($1) + _hostname=${event_array[0]} + _appraisal_msg=${event_array[@]:1} + # parse appraise specific fields from the message + for field in $_appraisal_msg; do + set -- `echo $field | tr '=' ' '` + eval _$1=$2; + done + + # sanity check (make sure its an appraisal event + if [ "${_op}" == "appraise_data" ]; then + # Fields explanation: + # + # alarm_id: 500.500 + # alarm_state: msg + # entity_type_id: system.service + # entity_instance_id: host=.service= + # severity: major + # reason_text: Host has IMA Appraisal failure for service , + # reason = + # alarm_type: integrity-violation + # probable_cause: information-modification-detected + # proposed_repair_action:free-format string providing additional details on how to + # clear the alarm. Optional. + # service_affecting: false + # suppression: false + # uuid: unique identifier of an active alarm instance, filled by FM system + # Timestamp: filled by FM system + _absol_path=`which $_comm` + [ $? -eq 0 ] || _absol_path="$_comm" +FM_EVENT_LOG="### ###500.500###msg###system.service###host=$_hostname.service=$_comm### ###major###Host $_hostname has IMA Appraisal failure for service $_absol_path when executing file $_name, reason = $_cause###integrity-violation###information-modification-detected### ### ### ###" + fmClientCli -c "\"$FM_EVENT_LOG\"" + fi +} + +while read line; do + if [ ! -z "$line" ]; then + # Before we proceed, we need to ensure that + # this node has been configured so that FM Events can + # be logged + if [ ${nodetype} == "controller" ]; then + _configuration_flag_file="/var/run/.controller_config_complete" + elif [ ${nodetype} == "compute" ]; then + _configuration_flag_file="/var/run/.compute_config_complete" + elif [ ${nodetype} == "storage" ]; then + _configuration_flag_file="/var/run/.storage_config_complete" + else + _configuration_flag_file="" + fi + + if [ -n "${_configuration_flag_file}" ] && [ -f "${_configuration_flag_file}" ]; then + # Only covers IMA appraisals at the moment, since this destination + # is only set up to IMA appraise logs in syslog-ng.conf, but this + # can be opened up to other FM Event Sysloggers + processIMAAppraisal "$line" + fi + fi +done diff --git a/extended/syslog-ng/centos/files/remotelogging.conf b/extended/syslog-ng/centos/files/remotelogging.conf new file mode 100644 index 000000000..a4db380ca --- /dev/null +++ b/extended/syslog-ng/centos/files/remotelogging.conf @@ -0,0 +1,129 @@ +################################################################################ +# Remote Logging rewrite set +# +# This file is only in use when Remote Logging is enable using: system remotelogging-modify +# The file becomes active by: @include "remotelogging.conf" in the syslog-ng.conf +# +# Note: this file must be updated when a logfile is added to syslog-ng.conf. +# +################################################################################ +rewrite r_rewrite_set{ + set("system_name aodh-api.log ${HOST}", value("HOST") condition(filter(f_aodhapi))); + set("system_name aodh-dbsync.log ${HOST}", value("HOST") condition(filter(f_aodhdbsync))); + set("system_name aodh-evaluator.log ${HOST}", value("HOST") condition(filter(f_aodhevaluator))); + set("system_name aodh-expirer.log ${HOST}", value("HOST") condition(filter(f_aodhexpirer))); + set("system_name aodh-listener.log ${HOST}", value("HOST") condition(filter(f_aodhlistener))); + set("system_name aodh-notifier.log ${HOST}", value("HOST") condition(filter(f_aodhnotifier))); + set("system_name auth.log ${HOST}", value("HOST") condition(filter(f_auth))); + set("system_name bash.log ${HOST}", value("HOST") condition(filter(f_bash))); + set("system_name ceilometer-agent-central.log ${HOST}", value("HOST") condition(filter(f_ceilometeragentcentral))); + set("system_name ceilometer-agent-notification.log ${HOST}", value("HOST") condition(filter(f_ceilometeragentnotification))); + set("system_name ceilometer-alarm-evaluator.log ${HOST}", value("HOST") condition(filter(f_ceilometeralarmevaluator))); + set("system_name ceilometer-alarm-notifier.log ${HOST}", value("HOST") condition(filter(f_ceilometeralarmnotifier))); + set("system_name ceilometer-api.log ${HOST}", value("HOST") condition(filter(f_ceilometerapi))); + set("system_name ceilometer-collector.log ${HOST}", value("HOST") condition(filter(f_ceilometercollector))); + set("system_name cinder-api.log ${HOST}", value("HOST") condition(filter(f_cinderapi))); + set("system_name cinder-scheduler.log ${HOST}", value("HOST") condition(filter(f_cinderscheduler))); + set("system_name cinder-volume.log ${HOST}", value("HOST") condition(filter(f_cindervolume))); + set("system_name cron.log ${HOST}", value("HOST") condition(filter(f_cron))); + set("system_name daemon.log ${HOST}", value("HOST") condition(filter(f_daemon))); + set("system_name daemon-ocf.log ${HOST}", value("HOST") condition(filter(f_daemon_ocf))); + set("system_name debug ${HOST}", value("HOST") condition(filter(f_err))); + set("system_name error ${HOST}", value("HOST") condition(filter(f_error))); + set("system_name fm-event.log ${HOST}", value("HOST") condition(filter(f_fm_event))); + set("system_name fm-manager.log ${HOST}", value("HOST") condition(filter(f_fm_manager))); + set("system_name ima.log ${HOST}", value("HOST") condition(filter(f_ima))); + set("system_name fsmond.log ${HOST}", value("HOST") condition(filter(f_fsmon))); + set("system_name glance-api.log ${HOST}", value("HOST") condition(filter(f_glanceapi))); + set("system_name glance-registry.log ${HOST}", value("HOST") condition(filter(f_glanceregistry))); + set("system_name glance-registry-api.log ${HOST}", value("HOST") condition(filter(f_glanceregistryrest))); + set("system_name guestAgent.log ${HOST}", value("HOST") condition(filter(f_guestagent))); + set("system_name guestServer.log ${HOST}", value("HOST") condition(filter(f_guestserver))); + set("system_name hbsAgent.log ${HOST}", value("HOST") condition(filter(f_hbsagent))); + set("system_name hbsClient.log ${HOST}", value("HOST") condition(filter(f_hbsclient))); + set("system_name heat-api-cfn.log ${HOST}", value("HOST") condition(filter(f_heatapicfn))); + set("system_name heat-api-cloudwatch.log ${HOST}", value("HOST") condition(filter(f_heatapicloud))); + set("system_name heat-api.log ${HOST}", value("HOST") condition(filter(f_heatapi))); + set("system_name heat-engine.log ${HOST}", value("HOST") condition(filter(f_heatengine))); + set("system_name horizon.log ${HOST}", value("HOST") condition(filter(f_horizon))); + set("system_name hostwd.log ${HOST}", value("HOST") condition(filter(f_hostw))); + set("system_name hwmond.log ${HOST}", value("HOST") condition(filter(f_hwmon))); + set("system_name ironic-api.log ${HOST}", value("HOST") condition(filter(f_ironicapi))); + set("system_name ironic-conductor.log ${HOST}", value("HOST") condition(filter(f_ironicconductor))); + set("system_name kern.log ${HOST}", value("HOST") condition(filter(f_kern))); + set("system_name keystone-api.log ${HOST}", value("HOST") condition(filter(f_keystoneapi))); + set("system_name keystone-all.log ${HOST}", value("HOST") condition(filter(f_keystoneall))); + set("system_name libvirtd.log ${HOST}", value("HOST") condition(filter(f_libvirtd))); + set("system_name local4.log ${HOST}", value("HOST") condition(filter(f_local4))); + set("system_name lpr.log ${HOST}", value("HOST") condition(filter(f_lpr))); + set("system_name magnum-api.log ${HOST}", value("HOST") condition(filter(f_magnumapi))); + set("system_name magnum-conductor.log ${HOST}", value("HOST") condition(filter(f_magnumconductor))); + set("system_name mail.log ${HOST}", value("HOST") condition(filter(f_mail))); + set("system_name mtcAgent_alarm.log ${HOST}", value("HOST") condition(filter(f_mtcagentalarm))); + set("system_name mtcAgent_api.log ${HOST}", value("HOST") condition(filter(f_mtcagentapi))); + set("system_name mtcAgent_event.log ${HOST}", value("HOST") condition(filter(f_mtcagentevent))); + set("system_name mtcAgent.log ${HOST}", value("HOST") condition(filter(f_mtcagent))); + set("system_name mtcClient.log ${HOST}", value("HOST") condition(filter(f_mtcclient))); + set("system_name murano-api.log ${HOST}", value("HOST") condition(filter(f_muranoapi))); + set("system_name murano-engine.log ${HOST}", value("HOST") condition(filter(f_muranoengine))); + set("system_name news.crit ${HOST}", value("HOST") condition(filter(f_newscrit))); + set("system_name news.err ${HOST}", value("HOST") condition(filter(f_newserr))); + set("system_name news.notice ${HOST}", value("HOST") condition(filter(f_newsnotice))); + set("system_name nfv-vim-api.log ${HOST}", value("HOST") condition(filter(f_vim_api))); + set("system_name nfv-vim.log ${HOST}", value("HOST") condition(filter(f_vim))); + set("system_name nfv-vim-webserver.log ${HOST}", value("HOST") condition(filter(f_vim_webserver))); + set("system_name nova-api.log ${HOST}", value("HOST") condition(filter(f_novaapi))); + set("system_name nova-compute.log ${HOST}", value("HOST") condition(filter(f_novacompute))); + set("system_name nova-conductor.log ${HOST}", value("HOST") condition(filter(f_novaconductor))); + set("system_name nova-consoleauth.log ${HOST}", value("HOST") condition(filter(f_novaconsole))); + set("system_name nova-manage.log ${HOST}", value("HOST") condition(filter(f_novamanage))); + set("system_name nova-scheduler.log ${HOST}", value("HOST") condition(filter(f_novascheduler))); + set("system_name nova-placement-api.log ${HOST}", value("HOST") condition(filter(f_novaplacementapi))); + set("system_name neutron-api.log ${HOST}", value("HOST") condition(filter(f_neutronapi))); + set("system_name openstack.log ${HOST}", value("HOST") condition(filter(f_local2))); + set("system_name panko-api.log ${HOST}", value("HOST") condition(filter(f_pankoapi))); + set("system_name panko-dbsync.log ${HOST}", value("HOST") condition(filter(f_pankodbsync))); + set("system_name panko-expirer.log ${HOST}", value("HOST") condition(filter(f_pankoexpirer))); + set("system_name platform.log ${HOST}", value("HOST") condition(filter(f_local1))); + set("system_name pmond.log ${HOST}", value("HOST") condition(filter(f_pmon))); + set("system_name postgres.log ${HOST}", value("HOST") condition(filter(f_local0))); + set("system_name rmond.log ${HOST}", value("HOST") condition(filter(f_rmon))); + set("system_name rmond_notify.log ${HOST}", value("HOST") condition(filter(f_rmon_notify))); + set("system_name sm.log ${HOST}", value("HOST") condition(filter(f_local3))); + set("system_name sysinv-api.log ${HOST}", value("HOST") condition(filter(f_sysinvapi))); + set("system_name nova-api-proxy.log ${HOST}", value("HOST") condition(filter(f_novaapiproxy))); + set("system_name sysinv.log ${HOST}", value("HOST") condition(filter(f_sysinv))); + set("system_name syslog ${HOST}", value("HOST") condition(filter(f_syslog))); + set("system_name user.log ${HOST}", value("HOST") condition(filter(f_user))); + set("system_name uucp.log ${HOST}", value("HOST") condition(filter(f_uucp))); + set("system_name snmp-api.log ${HOST}", value("HOST") condition(filter(f_snmpat))); + # Most logs write log level to the message field. some writes it to the PRIORITY field + # The priority field is not sent remotely. This is because tcp/udp destinations don't + # work well with templates, which we use to write the priority field to log files on the + # controllers. These lines append the priority/log level field before the message + # in cases where the log level is sent through the priority field as opposed to the + # message field + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_daemon))); + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_auth))); + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_cron))); + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_kern))); + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_user))); + # postgres + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_local0))); + # platform + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_local1))); + # sm + set("${PRIORITY} ${MSG}", value("MSG") condition(filter(f_local3))); +}; + +# This rewrite set is used by haproxy and 'HOST' is replaced with the hostname by packstack. +rewrite r_hap_rewrite_set{ + set("system_name haproxy.log HOST", value("HOST") condition(filter(f_local1))); +}; + +####################################################### +# Log to remote log server configured in syslog-ng.conf +####################################################### + +log { source(s_src); rewrite(r_rewrite_set); destination(remote_log_server); }; +log { source(s_udp); rewrite(r_hap_rewrite_set); destination(remote_log_server); }; diff --git a/extended/syslog-ng/centos/files/syslog-ng.conf b/extended/syslog-ng/centos/files/syslog-ng.conf new file mode 100644 index 000000000..2727eaf55 --- /dev/null +++ b/extended/syslog-ng/centos/files/syslog-ng.conf @@ -0,0 +1,582 @@ +@version: 3.4 +#@include "remotelogging.conf" +# +# Syslog-ng configuration file, compatible with default Debian syslogd +# installation. Originally written by anonymous (I can't find his name) +# Revised, and rewrited by me (SZALAY Attila ) + +# Common log format with fractional seconds, hostname, and priority +template t_log { + template("${YEAR}-${MONTH}-${DAY}T${HOUR}:${MIN}:${SEC}.${MSEC} ${HOST} ${MSGHDR}${PRIORITY} ${MSG}\n"); + template-escape(no); +}; + +template t_ocf_log { + template("${R_YEAR}-${R_MONTH}-${R_DAY}T${R_HOUR}:${R_MIN}:${R_SEC}.${R_MSEC} ${HOST} ${MSGHDR}${PRIORITY} ${MSG}\n"); + template-escape(no); +}; + +# Format for openstack logs that provide their own timestamp, priority, etc... +template t_openstack { + template("${MSG}\n"); + template-escape(no); +}; + +template t_libvirtd { + template("${YEAR}-${MONTH}-${DAY}T${HOUR}:${MIN}:${SEC}.${MSEC} ${MSG}\n"); + template-escape(no); +}; + +template t_nfv { + template("${YEAR}-${MONTH}-${DAY}T${HOUR}:${MIN}:${SEC}.${MSEC} ${HOST} ${MSG}\n"); + template-escape(no); +}; + +template t_mtc { + template("${R_YEAR}-${R_MONTH}-${R_DAY}T${R_HOUR}:${R_MIN}:${R_SEC}.${R_MSEC} ${MSG}\n"); + template-escape(no); +}; + +template t_fm { + template("${R_YEAR}-${R_MONTH}-${R_DAY}T${R_HOUR}:${R_MIN}:${R_SEC}.${R_MSEC} ${MSG}\n"); + template-escape(no); +}; + +template t_ima_appraise { + template ("${HOST} ${MSGONLY}\n"); + template-escape(no); +}; + +# First, set some global options. +options { chain_hostnames(off); flush_lines(0); use_dns(no); use_fqdn(no); + owner("root"); group("root"); perm(0644); stats_freq(0); + bad_hostname("^gconfd$"); + frac_digits(3); + log_msg_size(65535); + file-template(t_log); +}; + +######################## +# Sources +######################## +# This is the default behavior of sysklogd package +# Logs may come from unix stream, but not from another machine. +# +source s_src { unix-dgram("/dev/log" ); internal(); + file("/proc/kmsg" program_override("kernel") ); +}; + +# If you wish to get logs from remote machine you should uncomment +# this and comment the above source line. +# +#source s_net { tcp(ip(127.0.0.1) port(1000) authentication(required) encrypt(allow)); }; + +# UDP source for HAProxy +source s_udp { udp(ip(127.0.0.1) port(514)); }; + +######################## +# Destinations +######################## +# +# remote_log_server destination is added when remotelogging is enabled. +# The /etc/syslog-ng/remotelogging.conf file has the log statement to +# send messages to the remote log server. +# +# Note: remotelogging.conf must be updated when adding a logfile. +# +#destination remote_log_server {udp("10.1.2.3" port(514));}; +# +# First some standard logfile +# +destination d_auth { file("/var/log/auth.log"); }; +destination d_cron { file("/var/log/cron.log"); }; +destination d_daemon { file("/var/log/daemon.log"); }; +destination d_daemon_ocf { file("/var/log/daemon-ocf.log" template(t_ocf_log) ); }; +destination d_kern { file("/var/log/kern.log"); }; +destination d_lpr { file("/var/log/lpr.log"); }; +destination d_mail { file("/var/log/mail.log"); }; +destination d_syslog { file("/var/log/syslog"); }; +destination d_user { file("/var/log/user.log"); }; +destination d_uucp { file("/var/log/uucp.log"); }; +destination d_postgres { file("/var/log/postgres.log"); }; +destination d_platform { file("/var/log/platform.log"); }; +destination d_openstack { file("/var/log/openstack.log" template(t_openstack)); }; +destination d_sm { file("/var/log/sm.log"); }; + +# Maintenance Log destinations +destination d_rmon { file("/var/log/rmond.log" template(t_mtc)); }; +destination d_rmon_notify { file("/var/log/rmond_notify.log" template(t_mtc)); }; +destination d_pmon { file("/var/log/pmond.log" template(t_mtc)); }; +destination d_hostwd { file("/var/log/hostwd.log" template(t_mtc)); }; +destination d_fsmon { file("/var/log/fsmond.log" template(t_mtc)); }; +destination d_hwmon { file("/var/log/hwmond.log" template(t_mtc)); }; +destination d_mtclogd { file("/var/log/mtclogd.log" template(t_mtc)); }; +destination d_mtcalarmd { file("/var/log/mtcalarmd.log" template(t_mtc)); }; +destination d_mtcclient { file("/var/log/mtcClient.log" template(t_mtc)); }; +destination d_mtcagent { file("/var/log/mtcAgent.log" template(t_mtc)); }; +destination d_hbsclient { file("/var/log/hbsClient.log" template(t_mtc)); }; +destination d_hbsagent { file("/var/log/hbsAgent.log" template(t_mtc)); }; +destination d_guestagent { file("/var/log/guestAgent.log" template(t_mtc)); }; +destination d_guestserver { file("/var/log/guestServer.log" template(t_mtc)); }; +destination d_mtcagentalarm { file("/var/log/mtcAgent_alarm.log" template(t_mtc)); }; +destination d_mtcagentapi { file("/var/log/mtcAgent_api.log" template(t_mtc)); }; +destination d_mtcagentevent { file("/var/log/mtcAgent_event.log" template(t_mtc)); }; + +# HAProxy Log destination +destination d_haproxy { file("/var/log/haproxy.log"); }; + +# Fault Management Log destination +destination d_fm_event { file("/var/log/fm-event.log"); }; +destination d_fm_manager { file("/var/log/fm-manager.log" template(t_fm)); }; + +# IMA Log destination +destination d_ima { file("/var/log/ima.log"); }; +# The destination for IMA Appraisals are FM Events +destination d_ima_appraise { + program( + "/usr/sbin/fm_event_syslogger" + template(t_ima_appraise) + log-fifo-size(2Mb) + ); +}; + +# Sysinv Log destination +destination d_sysinv { file("/var/log/sysinv.log" template(t_openstack)); }; +destination d_sysinvapi { file("/var/log/sysinv-api.log" template(t_openstack)); }; + +# Distributed Cloud Log destination +destination d_dcmanager { file("/var/log/dcmanager/dcmanager.log" template(t_openstack)); }; +destination d_dcorch { file("/var/log/dcorch/dcorch.log" template(t_openstack)); }; + + +# Nova-api-proxy Log destination +destination d_novaapiproxy { file("/var/log/nova/nova-api-proxy.log"); }; + +# Openstack Log destinations +destination d_novaapi { file("/var/log/nova/nova-api.log" template(t_openstack)); }; +destination d_novascheduler { file("/var/log/nova/nova-scheduler.log" template(t_openstack)); }; +destination d_novaconductor { file("/var/log/nova/nova-conductor.log" template(t_openstack)); }; +destination d_novaconsole { file("/var/log/nova/nova-consoleauth.log" template(t_openstack)); }; +destination d_novamanage { file("/var/log/nova/nova-manage.log" template(t_openstack)); }; +destination d_novacompute { file("/var/log/nova/nova-compute.log" template(t_openstack)); }; +destination d_novaplacementapi { file("/var/log/nova/nova-placement-api.log" template(t_openstack)); }; +destination d_neutronapi { file("/var/log/neutron/neutron-api.log" template(t_openstack)); }; +destination d_horizon { file("/var/log/horizon.log" template(t_openstack)); }; +destination d_libvirtd { file("/var/log/libvirt/libvirtd.log" template(t_libvirtd)); }; +destination d_heatapi { file("/var/log/heat/heat-api.log" template(t_openstack)); }; +destination d_heatapicfn { file("/var/log/heat/heat-api-cfn.log" template(t_openstack)); }; +destination d_heatapicloud { file("/var/log/heat/heat-api-cloudwatch.log" template(t_openstack)); }; +destination d_heatengine { file("/var/log/heat/heat-engine.log" template(t_openstack)); }; +destination d_cinderapi { file("/var/log/cinder/cinder-api.log" template(t_openstack)); }; +destination d_cinderscheduler { file("/var/log/cinder/cinder-scheduler.log" template(t_openstack)); }; +destination d_cindervolume { file("/var/log/cinder/cinder-volume.log" template(t_openstack)); }; +destination d_keystoneall { file("/var/log/keystone/keystone-all.log" template(t_openstack)); }; +destination d_keystoneapi { file("/var/log/keystone/keystone-api.log" template(t_openstack)); }; +destination d_glanceapi { file("/var/log/glance/glance-api.log" template(t_openstack)); }; +destination d_glanceregistry { file("/var/log/glance/glance-registry.log" template(t_openstack)); }; +destination d_glanceregistryrest { file("/var/log/glance/glance-registry-api.log" template(t_openstack)); }; +# Ceilometer is not using oslo_log so it does not use the t_openstack template +destination d_ceilometeragentcentral { file("/var/log/ceilometer/ceilometer-agent-central.log"); }; +destination d_ceilometeragentnotification { file("/var/log/ceilometer/ceilometer-agent-notification.log"); }; +destination d_ceilometeralarmevaluator { file("/var/log/ceilometer/ceilometer-alarm-evaluator.log"); }; +destination d_ceilometeralarmnotifier { file("/var/log/ceilometer/ceilometer-alarm-notifier.log"); }; +destination d_ceilometerapi { file("/var/log/ceilometer/ceilometer-api.log"); }; +destination d_ceilometercollector { file("/var/log/ceilometer/ceilometer-collector.log"); }; +destination d_aodhapi { file("/var/log/aodh/aodh-api.log" template(t_openstack)); }; +destination d_aodhdbsync { file("/var/log/aodh/aodh-dbsync.log" template(t_openstack)); }; +destination d_aodhevaluator { file("/var/log/aodh/aodh-evaluator.log" template(t_openstack)); }; +destination d_aodhexpirer { file("/var/log/aodh/aodh-expirer.log" template(t_openstack)); }; +destination d_aodhlistener { file("/var/log/aodh/aodh-listener.log" template(t_openstack)); }; +destination d_aodhnotifier { file("/var/log/aodh/aodh-notifier.log" template(t_openstack)); }; +destination d_muranoapi { file("/var/log/murano/murano-api.log" template(t_openstack)); }; +destination d_muranoengine { file("/var/log/murano/murano-engine.log" template(t_openstack)); }; +destination d_magnumapi { file("/var/log/magnum/magnum-api.log" template(t_openstack)); }; +destination d_magnumconductor { file("/var/log/magnum/magnum-conductor.log" template(t_openstack)); }; +destination d_ironicapi { file("/var/log/ironic/ironic-api.log" template(t_openstack)); }; +destination d_ironicconductor { file("/var/log/ironic/ironic-conductor.log" template(t_openstack)); }; +destination d_pankoapi { file("/var/log/panko/panko-api.log" template(t_openstack)); }; +destination d_pankodbsync { file("/var/log/panko/panko-dbsync.log" template(t_openstack)); }; +destination d_pankoexpirer { file("/var/log/panko/panko-expirer.log" template(t_openstack)); }; + +# NFV-VIM Log destinations +destination d_vim { file("/var/log/nfv-vim.log" template(t_nfv)); }; +destination d_vim_api { file("/var/log/nfv-vim-api.log" template(t_nfv)); }; +destination d_vim_webserver { file("/var/log/nfv-vim-webserver.log" template(t_nfv)); }; + +# Local Log destinations +destination d_local4 { file("/var/log/local4.log"); }; +destination d_local5 { file("/var/log/local5.log"); }; +destination d_local6 { file("/var/log/local6.log"); }; +destination d_local7 { file("/var/log/local7.log"); }; + +# This files are the log come from the mail subsystem. +# +destination d_mailinfo { file("/var/log/mail/mail.info"); }; +destination d_mailwarn { file("/var/log/mail/mail.warn"); }; +destination d_mailerr { file("/var/log/mail/mail.err"); }; + +# Logging for INN news system +# +destination d_newscrit { file("/var/log/news/news.crit"); }; +destination d_newserr { file("/var/log/news/news.err"); }; +destination d_newsnotice { file("/var/log/news/news.notice"); }; + +# Some `catch-all' logfiles. +# +destination d_debug { file("/var/log/debug"); }; +destination d_error { file("/var/log/error"); }; +destination d_messages { file("/var/log/messages"); }; + +# The root's console. +# +destination d_console { usertty("root"); }; + +# Virtual console. +# +destination d_console_all { file("/dev/tty10"); }; + +# The named pipe /dev/xconsole is for the nsole' utility. To use it, +# you must invoke nsole' with the -file' option: +# +# $ xconsole -file /dev/xconsole [...] +# +destination d_xconsole { pipe("/dev/xconsole"); }; + +# Send the messages to an other host +# +#destination d_net { tcp("127.0.0.1" port(1000) authentication(on) encrypt(on) log_fifo_size(1000)); }; + +# Debian only +destination d_ppp { file("/var/log/ppp.log"); }; + +# Bash history. +destination d_bash { file("/var/log/bash.log" owner("root") group("root") perm(0600)); }; + +# SNMP Audit Trail +destination d_snmpat { file("/var/log/snmp-api.log"); }; + +######################## +# Filters +######################## +# Here's come the filter options. With this rules, we can set which +# message go where. + +filter f_dbg { level(debug); }; +filter f_info { level(info); }; +filter f_notice { level(notice); }; +filter f_warn { level(warn); }; +filter f_err { level(err); }; +filter f_crit { level(crit .. emerg); }; + +filter f_debug { level(debug) and not facility(auth, authpriv, news, mail); }; +filter f_error { level(err .. emerg) ; }; + +filter f_messages { level(info,notice,warn) and + not facility(auth,authpriv,cron,daemon,mail,news); }; + +filter f_auth { facility(auth, authpriv) and not program("audispd"); }; +filter f_cron { facility(cron); }; +filter f_daemon { facility(daemon) and not program("^(OCF_).") and not match("snmp-auditor" value("MESSAGE")); }; +filter f_daemon_ocf { facility(daemon) and program("^(OCF_)."); }; +filter f_kern { facility(kern); }; +filter f_lpr { facility(lpr); }; +filter f_local { facility(local0, local1, local3, local4, local5, + local6, local7); }; +filter f_mail { facility(mail); }; +#filter f_news { facility(news); }; +filter f_newscrit { facility(news) and filter(f_crit); }; +filter f_newserr { facility(news) and filter(f_err); }; +filter f_newsnotice { facility(news) and filter(f_notice); }; +#filter f_syslog3 { not facility(auth, authpriv, mail) and not filter(f_debug); }; +filter f_syslog { facility(syslog); }; +filter f_user { facility(user) and not filter(f_vim) and not filter(f_vim_api) + and not filter(f_vim_webserver) and not match("fmClientCli"); + and not program("^(-)?(ba)?(su|sh)$"); }; +filter f_uucp { facility(uucp); }; + +#filter f_cnews { level(notice, err, crit) and facility(news); }; +filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); }; + +filter f_ppp { facility(local2); }; +filter f_console { level(warn .. emerg); }; + +# Local Log Filters +filter f_local0 { facility(local0); }; +filter f_local1 { facility(local1) + and not program(fmManager); }; +filter f_local2 { facility(local2) + and not program(glance-api) + and not program(glance-registry) + and not program(ceilometer-agent-central) + and not program(ceilometer-agent-notification) + and not program(ceilometer-alarm-evaluator) + and not program(ceilometer-alarm-notifier) + and not program(ceilometer-api) + and not program(ceilometer-collector) + and not program(aodh-api) + and not program(aodh-dbsync) + and not program(aodh-evaluator) + and not program(aodh-expirer) + and not program(aodh-listener) + and not program(aodh-notifier) + and not program(panko-api) + and not program(panko-dbsync) + and not program(panko-expirer) + and not program(murano-api) + and not program(murano-engine) + and not program(magnum-api) + and not program(magnum-conductor) + and not program(ironic-api) + and not program(ironic-conductor) + and not program(cinder-api) + and not program(cinder-scheduler) + and not program(cinder-volume) + and not filter(f_keystoneall) + and not filter(f_keystoneapi) + and not filter(f_neutronapi); }; +filter f_local3 { facility(local3); }; +filter f_local4 { facility(local4); }; +filter f_local5 { facility(local5); }; +filter f_local6 { facility(local6); }; +filter f_local7 { facility(local7); }; + +# Maintenance Log Filters +filter f_rmon { facility(local5) and program(rmond); }; +filter f_rmon_notify { facility(local5) and program(rmon_resource_notify); }; +filter f_pmon { facility(local5) and program(pmond); }; +filter f_hostw { facility(local5) and program(hostwd); }; +filter f_fsmon { facility(local5) and program(fsmond); }; +filter f_hwmon { facility(local5) and program(hwmond); }; +filter f_mtclogd { facility(local5) and program(mtclogd); }; +filter f_mtcalarmd { facility(local5) and program(mtcalarmd); }; +filter f_mtcclient { facility(local5) and program(mtcClient); }; +filter f_mtcagent { facility(local5) and program(mtcAgent); }; +filter f_hbsclient { facility(local5) and program(hbsClient); }; +filter f_hbsagent { facility(local5) and program(hbsAgent); }; +filter f_guestagent { facility(local5) and program(guestAgent); }; +filter f_guestserver { facility(local5) and program(guestServer); }; +filter f_mtcagentalarm { facility(local5) and program(/var/log/mtcAgent_alarm.log); }; +filter f_mtcagentapi { facility(local5) and program(/var/log/mtcAgent_api.log); }; +filter f_mtcagentevent { facility(local5) and program(/var/log/mtcAgent_event.log); }; + +# Fault Management Filter +filter f_fm_event { facility(local5) and program(fmManager); }; +filter f_fm_manager { facility(local1) and program(fmManager); }; + +# IMA Filters +filter f_ima { facility(auth) and program(audispd) and match("type=INTEGRITY_") ; }; +filter f_ima_appraise { filter(f_ima) and match("appraise_data") ; }; + +# Nova-api-proxy Log Filter + filter f_novaapiproxy { facility(local5) and program(nova-api-proxy); }; + +# Sysinv Log Filter +filter f_sysinv { facility(local6) and program(sysinv) and not match("sysinv.api.hooks.auditor"); }; +filter f_sysinvapi { facility(local6) and program(sysinv) and match("sysinv.api.hooks.auditor"); }; + +# Distributed Cloud Log Filters +filter f_dcmanagermanager { facility(local2) and program(dcmanager-manager); }; +filter f_dcmanagerapi { facility(local2) and program(dcmanager-api); }; + +filter f_dcorchengine { facility(local2) and program(dcorch-engine); }; +filter f_dcorchsnmp { facility(local2) and program(dcorch-snmp); }; +filter f_dcorchapiproxy { facility(local2) and program(dcorch-api-proxy); }; + +# Openstack Log Filters +filter f_novaapi { facility(local6) and program(nova-api); }; +filter f_novascheduler { facility(local6) and program(nova-scheduler); }; +filter f_novaconductor { facility(local6) and program(nova-conductor); }; +filter f_novaconsole { facility(local6) and program(nova-consoleauth); }; +filter f_novamanage { facility(local6) and program(nova-manage); }; +filter f_novacompute { facility(local6) and program(nova-compute); }; +filter f_novaplacementapi { facility(local6) and program(nova-placement-api); }; +filter f_neutronapi { facility(local2) and program(neutron-server) and match("neutron.wsgi"); }; +filter f_horizon { facility(local7) }; +filter f_libvirtd { program(libvirtd) }; +filter f_heatapi { facility(local6) and program(heat-api); }; +filter f_heatapicfn { facility(local6) and program(heat-api-cfn); }; +filter f_heatapicloud { facility(local6) and program(heat-api-cloudwatch); }; +filter f_heatengine { facility(local6) and program(heat-engine); }; +filter f_cinderapi { facility(local2) and program(cinder-api); }; +filter f_cinderscheduler { facility(local2) and program(cinder-scheduler); }; +filter f_cindervolume { facility(local2) and program(cinder-volume); }; +filter f_glanceapi { facility(local2) and program(glance-api); }; +filter f_glanceregistry { facility(local2) and program(glance-registry) and not match("eventlet.wsgi.server"); }; +filter f_glanceregistryrest { facility(local2) and program(glance-registry) and match("eventlet.wsgi.server"); }; +filter f_keystoneall { facility(local2) and message("keystone.*") and not match("keystone.common.wsgi"); }; +filter f_keystoneapi { facility(local2) and match("keystone.common.wsgi"); }; +filter f_ceilometeragentcentral { facility(local2) and program(ceilometer-agent-central); }; +filter f_ceilometeragentnotification { facility(local2) and program(ceilometer-agent-notification); }; +filter f_ceilometeralarmevaluator { facility(local2) and program(ceilometer-alarm-evaluator); }; +filter f_ceilometeralarmnotifier { facility(local2) and program(ceilometer-alarm-notifier); }; +filter f_ceilometerapi { facility(local2) and program(ceilometer-api); }; +filter f_ceilometercollector { facility(local2) and program(ceilometer-collector); }; +filter f_aodhapi { facility(local2) and program(aodh-api); }; +filter f_aodhdbsync { facility(local2) and program(aodh-dbsync); }; +filter f_aodhevaluator { facility(local2) and program(aodh-evaluator); }; +filter f_aodhexpirer { facility(local2) and program(aodh-expirer); }; +filter f_aodhlistener { facility(local2) and program(aodh-listener); }; +filter f_aodhnotifier { facility(local2) and program(aodh-notifier); }; +filter f_muranoapi { facility(local2) and program(murano-api); }; +filter f_muranoengine { facility(local2) and program(murano-engine); }; +filter f_magnumapi { facility(local2) and program(magnum-api); }; +filter f_magnumconductor { facility(local2) and program(magnum-conductor); }; +filter f_pankoapi { facility(local2) and program(panko-api); }; +filter f_pankodbsync { facility(local2) and program(panko-dbsync); }; +filter f_pankoexpirer { facility(local2) and program(panko-expirer); }; +filter f_ironicapi { facility(local2) and program(ironic-api); }; +filter f_ironicconductor { facility(local2) and program(ironic-conductor); }; + +# NFV-VIM Log Filters +filter f_vim { facility(user) and program(VIM_); }; +filter f_vim_api { facility(user) and program(VIM-API_); }; +filter f_vim_webserver { facility(user) and program(VIM-WEB_); }; + +# bash Log Filter +filter f_bash { facility(user) and program("^(-)?(ba)?(su|sh)$"); }; + +# SNMP Audit Trail +filter f_snmpat { facility(daemon) and program(snmpd) and match("snmp-auditor" value("MESSAGE")); }; + +######################## +# Log paths +######################## +log { source(s_src); filter(f_auth); destination(d_auth); }; +log { source(s_src); filter(f_cron); destination(d_cron); }; +log { source(s_src); filter(f_daemon); destination(d_daemon); }; +log { source(s_src); filter(f_daemon_ocf); destination(d_daemon_ocf); }; +log { source(s_src); filter(f_kern); destination(d_kern); }; +log { source(s_src); filter(f_lpr); destination(d_lpr); }; +#log { source(s_src); filter(f_syslog3); destination(d_syslog); }; +log { source(s_src); filter(f_syslog); destination(d_syslog); }; +log { source(s_src); filter(f_user); destination(d_user); }; +log { source(s_src); filter(f_uucp); destination(d_uucp); }; +log { source(s_src); filter(f_local0); destination(d_postgres); }; +log { source(s_src); filter(f_local1); destination(d_platform); }; +log { source(s_src); filter(f_local2); destination(d_openstack); }; +log { source(s_src); filter(f_local3); destination(d_sm); }; + +# Maintenance Log Paths +log { source(s_src); filter(f_rmon); destination(d_rmon); }; +log { source(s_src); filter(f_rmon_notify); destination(d_rmon_notify); }; +log { source(s_src); filter(f_pmon); destination(d_pmon); }; +log { source(s_src); filter(f_hostw); destination(d_hostwd); }; +log { source(s_src); filter(f_fsmon); destination(d_fsmon); }; +log { source(s_src); filter(f_hwmon); destination(d_hwmon); }; +log { source(s_src); filter(f_mtclogd); destination(d_mtclogd); }; +log { source(s_src); filter(f_mtcalarmd); destination(d_mtcalarmd); }; +log { source(s_src); filter(f_mtcclient); destination(d_mtcclient); }; +log { source(s_src); filter(f_mtcagent); destination(d_mtcagent); }; +log { source(s_src); filter(f_hbsclient); destination(d_hbsclient); }; +log { source(s_src); filter(f_hbsagent); destination(d_hbsagent); }; +log { source(s_src); filter(f_guestagent); destination(d_guestagent); }; +log { source(s_src); filter(f_guestserver); destination(d_guestserver); }; +log { source(s_src); filter(f_mtcagentalarm); destination(d_mtcagentalarm); }; +log { source(s_src); filter(f_mtcagentapi); destination(d_mtcagentapi); }; +log { source(s_src); filter(f_mtcagentevent); destination(d_mtcagentevent); }; + +# HAProxy Log Path +log { source(s_udp); filter(f_local1); destination(d_haproxy); }; + +# Fault Management Log Path +log { source(s_src); filter(f_fm_event); destination(d_fm_event); }; +log { source(s_src); filter(f_fm_manager); destination(d_fm_manager); }; + +# IMA Log Path +log { source(s_src); filter(f_ima); destination(d_ima); }; +# we need to pass along IMA Appraisal failures to FM in order to +# generate FM EVENT logs +log { source(s_src); filter(f_ima_appraise); destination(d_ima_appraise); }; + +# Sysinv Log Path +log {source(s_src); filter(f_sysinv); destination(d_sysinv); }; +log {source(s_src); filter(f_sysinvapi); destination(d_sysinvapi); }; + +# Distributed Cloud Log Path +log {source(s_src); filter(f_dcmanagermanager); destination(d_dcmanager); }; +log {source(s_src); filter(f_dcmanagerapi); destination(d_dcmanager); }; +log {source(s_src); filter(f_dcorchengine); destination(d_dcorch); }; +log {source(s_src); filter(f_dcorchsnmp); destination(d_dcorch); }; +log {source(s_src); filter(f_dcorchapiproxy); destination(d_dcorch); }; + +# Nova-api-proxy Log Path +log {source(s_src); filter(f_novaapiproxy); destination(d_novaapiproxy); }; + +# Openstack Log Paths +log { source(s_src); filter(f_novaapi); destination(d_novaapi); }; +log { source(s_src); filter(f_novascheduler); destination(d_novascheduler); }; +log { source(s_src); filter(f_novaconductor); destination(d_novaconductor); }; +log { source(s_src); filter(f_novaconsole); destination(d_novaconsole); }; +log { source(s_src); filter(f_novamanage); destination(d_novamanage); }; +log { source(s_src); filter(f_novacompute); destination(d_novacompute); }; +log { source(s_src); filter(f_novaplacementapi); destination(d_novaplacementapi); }; +log { source(s_src); filter(f_neutronapi); destination(d_neutronapi); }; +log { source(s_src); filter(f_horizon); destination(d_horizon); }; +log { source(s_src); filter(f_libvirtd); destination(d_libvirtd); }; +log { source(s_src); filter(f_heatapi); destination(d_heatapi); }; +log { source(s_src); filter(f_heatapicfn); destination(d_heatapicfn); }; +log { source(s_src); filter(f_heatapicloud); destination(d_heatapicloud); }; +log { source(s_src); filter(f_heatengine); destination(d_heatengine); }; +log { source(s_src); filter(f_cinderapi); destination(d_cinderapi); }; +log { source(s_src); filter(f_cinderscheduler); destination(d_cinderscheduler); }; +log { source(s_src); filter(f_cindervolume); destination(d_cindervolume); }; +log { source(s_src); filter(f_keystoneall); destination(d_keystoneall); }; +log { source(s_src); filter(f_keystoneapi); destination(d_keystoneapi); }; +log { source(s_src); filter(f_glanceapi); destination(d_glanceapi); }; +log { source(s_src); filter(f_glanceregistry); destination(d_glanceregistry); }; +log { source(s_src); filter(f_glanceregistryrest); destination(d_glanceregistryrest); }; +log { source(s_src); filter(f_ceilometeragentcentral); destination(d_ceilometeragentcentral); }; +log { source(s_src); filter(f_ceilometeragentnotification); destination(d_ceilometeragentnotification); }; +log { source(s_src); filter(f_ceilometeralarmevaluator); destination(d_ceilometeralarmevaluator); }; +log { source(s_src); filter(f_ceilometeralarmnotifier); destination(d_ceilometeralarmnotifier); }; +log { source(s_src); filter(f_ceilometerapi); destination(d_ceilometerapi); }; +log { source(s_src); filter(f_ceilometercollector); destination(d_ceilometercollector); }; +log { source(s_src); filter(f_aodhapi); destination(d_aodhapi); }; +log { source(s_src); filter(f_aodhdbsync); destination(d_aodhdbsync); }; +log { source(s_src); filter(f_aodhevaluator); destination(d_aodhevaluator); }; +log { source(s_src); filter(f_aodhexpirer); destination(d_aodhexpirer); }; +log { source(s_src); filter(f_aodhlistener); destination(d_aodhlistener); }; +log { source(s_src); filter(f_aodhnotifier); destination(d_aodhnotifier); }; +log { source(s_src); filter(f_muranoapi); destination(d_muranoapi); }; +log { source(s_src); filter(f_muranoengine); destination(d_muranoengine); }; +log { source(s_src); filter(f_magnumapi); destination(d_magnumapi); }; +log { source(s_src); filter(f_magnumconductor); destination(d_magnumconductor); }; +log { source(s_src); filter(f_pankoapi); destination(d_pankoapi); }; +log { source(s_src); filter(f_pankodbsync); destination(d_pankodbsync); }; +log { source(s_src); filter(f_pankoexpirer); destination(d_pankoexpirer); }; +log { source(s_src); filter(f_ironicapi); destination(d_ironicapi); }; +log { source(s_src); filter(f_ironicconductor); destination(d_ironicconductor); }; + +# NFV-VIM Log Paths +log {source(s_src); filter(f_vim); destination(d_vim); }; +log {source(s_src); filter(f_vim_api); destination(d_vim_api); }; +log {source(s_src); filter(f_vim_webserver); destination(d_vim_webserver); }; + +# Local Log Paths +log { source(s_src); filter(f_local4); destination(d_local4); }; +log { source(s_src); filter(f_mail); destination(d_mail); }; +#log { source(s_src); filter(f_mail); filter(f_info); destination(d_mailinfo); }; +#log { source(s_src); filter(f_mail); filter(f_warn); destination(d_mailwarn); }; +#log { source(s_src); filter(f_mail); filter(f_err); destination(d_mailerr); }; + +log { source(s_src); filter(f_newscrit); destination(d_newscrit); }; +log { source(s_src); filter(f_newserr); destination(d_newserr); }; +log { source(s_src); filter(f_newsnotice); destination(d_newsnotice); }; +#log { source(s_src); filter(f_cnews); destination(d_console_all); }; +#log { source(s_src); filter(f_cother); destination(d_console_all); }; + +#log { source(s_src); filter(f_ppp); destination(d_ppp); }; + +log { source(s_src); filter(f_console); destination(d_console_all); + destination(d_xconsole); }; +log { source(s_src); filter(f_crit); destination(d_console); }; + +# All messages send to a remote site +# +#log { source(s_src); destination(d_net); }; + +# Bash log Path +log { source(s_src); filter(f_bash); destination(d_bash); }; + +# SNMP Audit Trail +log { source(s_src); filter(f_snmpat); destination(d_snmpat); }; diff --git a/extended/syslog-ng/centos/files/syslog-ng.logrotate b/extended/syslog-ng/centos/files/syslog-ng.logrotate new file mode 100644 index 000000000..6e9cba330 --- /dev/null +++ b/extended/syslog-ng/centos/files/syslog-ng.logrotate @@ -0,0 +1,173 @@ +# /etc/logrotate.d/syslog-ng - Provided by syslog-ng-logrotate + +/var/log/syslog +/var/log/auth.log +/var/log/cron.log +/var/log/daemon.log +/var/log/daemon-ocf.log +/var/log/kern.log +/var/log/lpr.log +/var/log/mail.log +/var/log/news.log +/var/log/user.log +/var/log/uucp.log +/var/log/local*.log +/var/log/postgres.log +/var/log/postgresql.log +/var/log/haproxy.log +/var/log/platform.log +/var/log/openstack.log +/var/log/sysinv.log +/var/log/sysinv-api.log +/var/log/nfv-vim-api.log +/var/log/nfv-vim-webserver.log +/var/log/neutron/*.log +/var/log/keystone/*.log +/var/log/aodh/*.log +/var/log/murano/*.log +/var/log/magnum/*.log +/var/log/horizon.log +/var/log/ceilometer/*.log +/var/log/panko/*.log +/var/log/ironic/*.log +/var/log/snmp-api.log +/var/log/dcmanager/*.log +/var/log/dcorch/*.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/nfv-vim.log +{ + nodateext + size 20M + start 1 + rotate 40 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/cinder/*.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/glance/*.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/heat/*.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/nova/*.log +{ + nodateext + size 50M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/collect.log +/var/log/ldapscripts.log +/var/log/tuned/tuned.log +{ + nodateext + size 10M + start 1 + rotate 20 + missingok + notifempty + compress + copytruncate +} + +/var/log/sm.log +/var/log/ima.log +{ + nodateext + size 100M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + postrotate + systemctl reload syslog-ng > /dev/null 2>&1 || true + endscript +} + +/var/log/bash.log +{ + nodateext + size 100M + start 1 + rotate 20 + missingok + notifempty + compress + sharedscripts + firstaction + /usr/bin/logmgmt_prerotate > /dev/null 2>&1 || true + endscript + # using lastaction to ensure log file compression succeeds + lastaction + service syslog-ng reload > /dev/null 2>&1 || true + /usr/bin/logmgmt_postrotate > /dev/null 2>&1 || true + endscript +} diff --git a/extended/syslog-ng/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/syslog-ng/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..9ccc4be6a --- /dev/null +++ b/extended/syslog-ng/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 79edbd7d065ea0d6f18807722d4d8bfc193c2a15 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 27 Sep 2016 10:54:33 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/syslog-ng.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/syslog-ng.spec b/SPECS/syslog-ng.spec +index 39c8d79..a9c0914 100644 +--- a/SPECS/syslog-ng.spec ++++ b/SPECS/syslog-ng.spec +@@ -3,7 +3,7 @@ + + Name: syslog-ng + Version: 3.5.6 +-Release: 3%{?dist} ++Release: 3.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Next-generation syslog server + + Group: System Environment/Daemons +-- +1.8.3.1 + diff --git a/extended/syslog-ng/centos/meta_patches/0002-Add-TIS-content.patch b/extended/syslog-ng/centos/meta_patches/0002-Add-TIS-content.patch new file mode 100644 index 000000000..6a1247dbf --- /dev/null +++ b/extended/syslog-ng/centos/meta_patches/0002-Add-TIS-content.patch @@ -0,0 +1,53 @@ +From cb258865db8bd9c37e22e45181b5dd3c9b3fee85 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 7 Mar 2017 13:38:12 -0500 +Subject: [PATCH] Add TIS content + +--- + SPECS/syslog-ng.spec | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/SPECS/syslog-ng.spec b/SPECS/syslog-ng.spec +index b54632c..a6d3f68 100644 +--- a/SPECS/syslog-ng.spec ++++ b/SPECS/syslog-ng.spec +@@ -12,10 +12,12 @@ URL: http://www.balabit.com/network-security/syslog-ng + Source0: http://www.balabit.com/downloads/files/syslog-ng/open-source-edition/%{version}/source/%{name}_%{version}.tar.gz + Source1: syslog-ng.conf + Source2: syslog-ng.logrotate ++Source3: remotelogging.conf + + Patch0: syslog-ng-3.5.0-syslog-ng.service.patch + Patch1: syslog-ng-3.4.0beta1-tests-functional-control.py.patch + Patch2: syslog-ng-3.3.6-tests-functional-sql-test.patch ++Patch3: syslog-ng-service-pid-file-pmond.patch + + BuildRequires: systemd-units + BuildRequires: pkgconfig +@@ -148,6 +150,7 @@ developing applications that use %{name}. + %patch0 -p1 + %patch1 -p1 + %patch2 -p1 ++%patch3 -p1 + + # fix perl path + %{__sed} -i 's|^#!/usr/local/bin/perl|#!%{__perl}|' contrib/relogger.pl +@@ -203,6 +206,7 @@ make DESTDIR=%{buildroot} install + + %{__install} -d -m 755 %{buildroot}%{_sysconfdir}/%{name}/conf.d + %{__install} -p -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/%{name}/syslog-ng.conf ++%{__install} -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/%{name}/remotelogging.conf + + %{__install} -d -m 755 %{buildroot}%{_sysconfdir}/logrotate.d + %{__install} -p -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/logrotate.d/syslog +@@ -284,6 +288,7 @@ fi + %dir %{_sysconfdir}/%{name}/conf.d + %dir %{_sysconfdir}/%{name}/patterndb.d + %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf ++%config(noreplace) %{_sysconfdir}/%{name}/remotelogging.conf + %config(noreplace) %{_sysconfdir}/%{name}/scl.conf + %config(noreplace) %{_sysconfdir}/logrotate.d/syslog + %{_unitdir}/%{name}.service +-- +1.8.3.1 + diff --git a/extended/syslog-ng/centos/meta_patches/0003-add-fm-event-syslogger.patch b/extended/syslog-ng/centos/meta_patches/0003-add-fm-event-syslogger.patch new file mode 100644 index 000000000..635dd51d3 --- /dev/null +++ b/extended/syslog-ng/centos/meta_patches/0003-add-fm-event-syslogger.patch @@ -0,0 +1,43 @@ +From e361372a2eb4f61f19c59f641b26dc9f109bf800 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 13 Oct 2017 12:18:48 -0400 +Subject: [PATCH] add FM Event Syslogger to be called from as a "program" + destination from syslog-ng + +--- + SPECS/syslog-ng.spec | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/SPECS/syslog-ng.spec b/SPECS/syslog-ng.spec +index a6d3f68..a75e393 100644 +--- a/SPECS/syslog-ng.spec ++++ b/SPECS/syslog-ng.spec +@@ -13,6 +13,7 @@ Source0: http://www.balabit.com/downloads/files/syslog-ng/open-source-edition/%{ + Source1: syslog-ng.conf + Source2: syslog-ng.logrotate + Source3: remotelogging.conf ++Source4: fm_event_syslogger + + Patch0: syslog-ng-3.5.0-syslog-ng.service.patch + Patch1: syslog-ng-3.4.0beta1-tests-functional-control.py.patch +@@ -208,6 +209,9 @@ make DESTDIR=%{buildroot} install + %{__install} -p -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/%{name}/syslog-ng.conf + %{__install} -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/%{name}/remotelogging.conf + ++%{__install} -d %{buildroot}%{_sbindir} ++%{__install} -p -m 0700 %{SOURCE4} %{buildroot}%{_sbindir}/fm_event_syslogger ++ + %{__install} -d -m 755 %{buildroot}%{_sysconfdir}/logrotate.d + %{__install} -p -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/logrotate.d/syslog + +@@ -296,6 +300,7 @@ fi + %dir %{_sharedstatedir}/%{name} + %{_sbindir}/%{name} + %{_sbindir}/syslog-ng-ctl ++%{_sbindir}/fm_event_syslogger + %{_bindir}/loggen + %{_bindir}/pdbtool + %{_bindir}/update-patterndb +-- +1.8.3.1 + diff --git a/extended/syslog-ng/centos/meta_patches/PATCH_ORDER b/extended/syslog-ng/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..c91c03f96 --- /dev/null +++ b/extended/syslog-ng/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-Add-TIS-content.patch +0003-add-fm-event-syslogger.patch diff --git a/extended/syslog-ng/centos/patches/syslog-ng-service-pid-file-pmond.patch b/extended/syslog-ng/centos/patches/syslog-ng-service-pid-file-pmond.patch new file mode 100644 index 000000000..8dd3b91f0 --- /dev/null +++ b/extended/syslog-ng/centos/patches/syslog-ng-service-pid-file-pmond.patch @@ -0,0 +1,19 @@ +syslog-ng.service: pid file location to match pmon.d + +pmon.d expects syslog-ng pid file to be at location +/var/run/syslog-ng/syslog-ng.pid. + +diff --git a/contrib/systemd/syslog-ng.service b/contrib/systemd/syslog-ng.service +index e724363..606a967 100644 +--- a/contrib/systemd/syslog-ng.service ++++ b/contrib/systemd/syslog-ng.service +@@ -5,7 +5,8 @@ Documentation=man:syslog-ng(8) + [Service] + Type=notify + Sockets=syslog.socket +-ExecStart=/usr/sbin/syslog-ng -F -p /var/run/syslogd.pid ++ExecStartPre=-/usr/bin/mkdir -p /var/run/syslog-ng/ ++ExecStart=/usr/sbin/syslog-ng -F -p /var/run/syslog-ng/syslog-ng.pid + ExecReload=/bin/kill -HUP $MAINPID + StandardOutput=null + Restart=on-failure diff --git a/extended/syslog-ng/centos/srpm_path b/extended/syslog-ng/centos/srpm_path new file mode 100644 index 000000000..6385d0f73 --- /dev/null +++ b/extended/syslog-ng/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/syslog-ng-3.5.6-3.el7.src.rpm diff --git a/extended/systemd/centos/build_srpm.data b/extended/systemd/centos/build_srpm.data new file mode 100644 index 000000000..6484153d7 --- /dev/null +++ b/extended/systemd/centos/build_srpm.data @@ -0,0 +1,2 @@ +TIS_PATCH_VER=10 +BUILD_IS_SLOW=7 diff --git a/extended/systemd/centos/meta_patches/0001-update-package-versioning-for-TIS-format.patch b/extended/systemd/centos/meta_patches/0001-update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..2a7231c17 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0001-update-package-versioning-for-TIS-format.patch @@ -0,0 +1,28 @@ +From 844630caa811b9fb1a2944385ce31726aff1df00 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 01/10] WRS: + 0001-update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/systemd.spec +--- + SPECS/systemd.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 4dce0a3..955cc4b 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -7,7 +7,7 @@ + Name: systemd + Url: http://www.freedesktop.org/wiki/Software/systemd + Version: 219 +-Release: 42%{?dist}.1 ++Release: 42.el7_4.1%{?_tis_dist}.%{tis_patch_ver} + # For a breakdown of the licensing, see README + License: LGPLv2+ and MIT and GPLv2+ + Summary: A System and Service Manager +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0003-spec-expand-_udevrulesdir-macro.patch b/extended/systemd/centos/meta_patches/0003-spec-expand-_udevrulesdir-macro.patch new file mode 100644 index 000000000..96cbb4c30 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0003-spec-expand-_udevrulesdir-macro.patch @@ -0,0 +1,27 @@ +From 23df5b4d09b03dd32ac8b38d9b6d42d9fb91977f Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 02/10] WRS: 0003-spec-expand-_udevrulesdir-macro.patch + +Conflicts: + SPECS/systemd.spec +--- + SPECS/systemd.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 955cc4b..5474181 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -912,7 +912,7 @@ rm -f %{buildroot}%{_prefix}/lib/systemd/network/* + rm -f %{buildroot}%{_mandir}/man5/sysusers.d.5.gz + rm -f %{buildroot}%{_mandir}/man8/systemd-sysusers.* + +-install -m 0644 %{SOURCE5} $RPM_BUILD_ROOT/%{_udevrulesdir}/ ++install -m 0644 %{SOURCE5} $RPM_BUILD_ROOT/usr/lib/udev/rules.d/ + + %pre + getent group cdrom >/dev/null 2>&1 || groupadd -r -g 11 cdrom >/dev/null 2>&1 || : +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0004-Protect-sections-of-systemd-post-from-running-on-pat.patch b/extended/systemd/centos/meta_patches/0004-Protect-sections-of-systemd-post-from-running-on-pat.patch new file mode 100644 index 000000000..9638973b0 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0004-Protect-sections-of-systemd-post-from-running-on-pat.patch @@ -0,0 +1,49 @@ +From 573c0da6014e782b5b598c054e8b6fc90e3cb780 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 03/10] WRS: + 0004-Protect-sections-of-systemd-post-from-running-on-pat.patch + +--- + SPECS/systemd.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 5474181..912d31e 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -1041,6 +1041,7 @@ fi + rm -f /etc/sysconfig/i18n >/dev/null 2>&1 || : + rm -f /etc/sysconfig/keyboard >/dev/null 2>&1 || : + ++if [ $1 -eq 1 ]; then + # Migrate HOSTNAME= from /etc/sysconfig/network + if [ -e /etc/sysconfig/network -a ! -e /etc/hostname ]; then + unset HOSTNAME +@@ -1048,6 +1049,7 @@ if [ -e /etc/sysconfig/network -a ! -e /etc/hostname ]; then + [ -n "$HOSTNAME" ] && echo $HOSTNAME > /etc/hostname 2>&1 || : + fi + sed -i '/^HOSTNAME=/d' /etc/sysconfig/network >/dev/null 2>&1 || : ++fi + + # Migrate the old systemd-setup-keyboard X11 configuration fragment + if [ ! -e /etc/X11/xorg.conf.d/00-keyboard.conf ] ; then +@@ -1056,6 +1058,7 @@ else + rm -f /etc/X11/xorg.conf.d/00-system-setup-keyboard.conf >/dev/null 2>&1 || : + fi + ++if [ 1 -eq 0 ] ; then # TIS: Skip this. We don't want myhostname in nsswitch.conf + # sed-fu to add myhostname to the hosts line of /etc/nsswitch.conf + # Only do that when installing, not when updating. + if [ $1 -eq 1 -a -f /etc/nsswitch.conf ] ; then +@@ -1065,6 +1068,7 @@ if [ $1 -eq 1 -a -f /etc/nsswitch.conf ] ; then + s/[[:blank:]]*$/ myhostname/ + ' /etc/nsswitch.conf >/dev/null 2>&1 || : + fi ++fi + + %posttrans + # Convert old /etc/sysconfig/desktop settings +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0005-spec-millisec-in-syslog-date.patch b/extended/systemd/centos/meta_patches/0005-spec-millisec-in-syslog-date.patch new file mode 100644 index 000000000..7eca30dda --- /dev/null +++ b/extended/systemd/centos/meta_patches/0005-spec-millisec-in-syslog-date.patch @@ -0,0 +1,28 @@ +From aa4dff1eedf5e685c83de9b4d996d8106e27c3b7 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 04/10] WRS: 0005-spec-millisec-in-syslog-date.patch + +Conflicts: + SPECS/systemd.spec +--- + SPECS/systemd.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 912d31e..d7a20d5 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -539,6 +539,9 @@ Patch0497: 0497-rules-move-cpu-hotplug-rule-to-separate-file.patch + Patch0498: 0498-Revert-rules-move-cpu-hotplug-rule-to-separate-file.patch + Patch0499: 0499-Revert-udev-net_id-add-support-for-phys_port_name-at.patch + ++#WRS Patches ++Patch0501: 0501-inject-millisec-in-syslog-date.patch ++ + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + + BuildRequires: libcap-devel +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0007-Add-patch-for-journald-config.patch b/extended/systemd/centos/meta_patches/0007-Add-patch-for-journald-config.patch new file mode 100644 index 000000000..e0bf3dd35 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0007-Add-patch-for-journald-config.patch @@ -0,0 +1,24 @@ +From 0691fdfd899f5af3be9e74dfd33b728ba45cd778 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 06/10] WRS: 0007-Add-patch-for-journald-config.patch + +--- + SPECS/systemd.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 93a4b72..48ac1bb 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -541,6 +541,7 @@ Patch0499: 0499-Revert-udev-net_id-add-support-for-phys_port_name-at.patch + + #WRS Patches + Patch0501: 0501-inject-millisec-in-syslog-date.patch ++Patch0503: 0503-Configure-journald-to-forward-to-syslog.patch + + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0008-Add-patch-for-journald-config-rate-limit.patch b/extended/systemd/centos/meta_patches/0008-Add-patch-for-journald-config-rate-limit.patch new file mode 100644 index 000000000..02e28bf3c --- /dev/null +++ b/extended/systemd/centos/meta_patches/0008-Add-patch-for-journald-config-rate-limit.patch @@ -0,0 +1,27 @@ +From e41bc69bcbf880196212524803e96521f5aa7c66 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 07/10] WRS: + 0008-Add-patch-for-journald-config-rate-limit.patch + +Conflicts: + SPECS/systemd.spec +--- + SPECS/systemd.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 48ac1bb..332514c 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -542,6 +542,7 @@ Patch0499: 0499-Revert-udev-net_id-add-support-for-phys_port_name-at.patch + #WRS Patches + Patch0501: 0501-inject-millisec-in-syslog-date.patch + Patch0503: 0503-Configure-journald-to-forward-to-syslog.patch ++Patch0504: 0504-Configure-journald-rate-limit.patch + + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0009-Add-patch-to-remove-ID_SAS_PATH-rule.patch b/extended/systemd/centos/meta_patches/0009-Add-patch-to-remove-ID_SAS_PATH-rule.patch new file mode 100644 index 000000000..90303a588 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0009-Add-patch-to-remove-ID_SAS_PATH-rule.patch @@ -0,0 +1,24 @@ +From 022b18e4db4116905207c0603b60e932e4a7dacb Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 08/10] WRS: 0009-Add-patch-to-remove-ID_SAS_PATH-rule.patch + +--- + SPECS/systemd.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 332514c..33f3128 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -543,6 +543,7 @@ Patch0501: 0501-inject-millisec-in-syslog-date.patch + Patch0501: 0501-inject-millisec-in-syslog-date.patch + Patch0503: 0503-Configure-journald-to-forward-to-syslog.patch + Patch0504: 0504-Configure-journald-rate-limit.patch ++Patch0505: 0505-remove-id-sas-path-symlink.patch + + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0010-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch b/extended/systemd/centos/meta_patches/0010-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch new file mode 100644 index 000000000..7e2c3dff8 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0010-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch @@ -0,0 +1,25 @@ +From e188f1148982166624ae72f8fac70775a2bc8d73 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 09/10] WRS: + 0010-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch + +--- + SPECS/systemd.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 33f3128..a8e1846 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -544,6 +544,7 @@ Patch0502: 0502-udev-path_id-introduce-support-for-NVMe-devices-4169.patch + Patch0503: 0503-Configure-journald-to-forward-to-syslog.patch + Patch0504: 0504-Configure-journald-rate-limit.patch + Patch0505: 0505-remove-id-sas-path-symlink.patch ++Patch0506: 0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch + + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0011-Add-patch-for-moving-vartmp-to-tmpfs.patch b/extended/systemd/centos/meta_patches/0011-Add-patch-for-moving-vartmp-to-tmpfs.patch new file mode 100644 index 000000000..108b616b0 --- /dev/null +++ b/extended/systemd/centos/meta_patches/0011-Add-patch-for-moving-vartmp-to-tmpfs.patch @@ -0,0 +1,24 @@ +From 4457eecec7e750c2e60f2bc33a0f7c4c70955a86 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:53:00 -0400 +Subject: [PATCH 10/10] WRS: 0011-Add-patch-for-moving-vartmp-to-tmpfs.patch + +--- + SPECS/systemd.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index a8e1846..e36e410 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -545,6 +545,7 @@ Patch0503: 0503-Configure-journald-to-forward-to-syslog.patch + Patch0504: 0504-Configure-journald-rate-limit.patch + Patch0505: 0505-remove-id-sas-path-symlink.patch + Patch0506: 0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch ++Patch0507: 0507-move-vartmp-to-tmpfs.patch + + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + +-- +1.9.1 + diff --git a/extended/systemd/centos/meta_patches/0012-Add-patch-for-restricting-tmpfs-size.patch b/extended/systemd/centos/meta_patches/0012-Add-patch-for-restricting-tmpfs-size.patch new file mode 100644 index 000000000..9b89c3b5c --- /dev/null +++ b/extended/systemd/centos/meta_patches/0012-Add-patch-for-restricting-tmpfs-size.patch @@ -0,0 +1,24 @@ +From 508f3f3f6b114fe081cc2c0594912fd6451d1045 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Thu, 12 Oct 2017 18:22:33 -0400 +Subject: [PATCH] meta patch for restricting tmpfs size + +--- + SPECS/systemd.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec +index 9e5ac92..66df00b 100644 +--- a/SPECS/systemd.spec ++++ b/SPECS/systemd.spec +@@ -462,6 +462,7 @@ Patch0504: 0504-Configure-journald-rate-limit.patch + Patch0505: 0505-remove-id-sas-path-symlink.patch + Patch0506: 0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch + Patch0507: 0507-move-vartmp-to-tmpfs.patch ++Patch0508: 0508-set-a-1GB-size-restriction-on-tpmfs.patch + + %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} + +-- +1.8.3.1 + diff --git a/extended/systemd/centos/meta_patches/PATCH_ORDER b/extended/systemd/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..092239b06 --- /dev/null +++ b/extended/systemd/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,10 @@ +0001-update-package-versioning-for-TIS-format.patch +0003-spec-expand-_udevrulesdir-macro.patch +0004-Protect-sections-of-systemd-post-from-running-on-pat.patch +0005-spec-millisec-in-syslog-date.patch +0007-Add-patch-for-journald-config.patch +0008-Add-patch-for-journald-config-rate-limit.patch +0009-Add-patch-to-remove-ID_SAS_PATH-rule.patch +0010-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch +0011-Add-patch-for-moving-vartmp-to-tmpfs.patch +0012-Add-patch-for-restricting-tmpfs-size.patch diff --git a/extended/systemd/centos/patches/0501-inject-millisec-in-syslog-date.patch b/extended/systemd/centos/patches/0501-inject-millisec-in-syslog-date.patch new file mode 100644 index 000000000..5ac344023 --- /dev/null +++ b/extended/systemd/centos/patches/0501-inject-millisec-in-syslog-date.patch @@ -0,0 +1,79 @@ +From 08353c7cc596d2d09fd7f22a9bfde4d83bd9ebda Mon Sep 17 00:00:00 2001 +From: systemd team +Date: Tue, 8 Nov 2016 17:06:01 -0500 +Subject: [PATCH 1/1] inject millisec in syslog date + +--- + src/journal/journald-syslog.c | 48 +++++++++++++++++++++++++++++++++++++------ + 1 file changed, 42 insertions(+), 6 deletions(-) + +diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c +index 4e118aa..85cdeb9 100644 +--- a/src/journal/journald-syslog.c ++++ b/src/journal/journald-syslog.c +@@ -35,6 +35,44 @@ + /* Warn once every 30s if we missed syslog message */ + #define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC) + ++/* internal function that builds a formatted time str of the ++ * tv parameter into the passed buffer. (ie Nov 7 16:28:38.109) ++ * If tv is NULL, then the clock function is used to build the formatted time ++ * returns (same as snprintf) - number of characters written to buffer. ++ */ ++static int formatSyslogDate(char * buffer, int bufLen, const struct timeval *tv) { ++ struct timeval tv_tmp; ++ long int millisec; ++ char tmpbuf[64]; ++ struct tm *tm; ++ time_t t; ++ ++ if (!tv) { ++ // no timeval input so get time data from clock ++ usec_t now_usec = now(CLOCK_REALTIME); ++ time_t now_sec = ((time_t) now_usec / USEC_PER_SEC); ++ long int now_fraction_secs = now_usec % USEC_PER_SEC; ++ tv_tmp.tv_sec = now_sec; ++ tv_tmp.tv_usec = now_fraction_secs; ++ tv = &tv_tmp; ++ } ++ ++ t = tv->tv_sec; ++ tm = localtime(&t); ++ if (!tm) ++ return 0; ++ ++ // format time to the second granularity - ie Nov 7 16:28:38 ++ if (strftime(tmpbuf,sizeof(tmpbuf),"%h %e %T", tm) <= 0) ++ return 0; ++ ++ millisec = tv->tv_usec / 1000; ++ // now append millisecond granularity (ie Nov 7 16:28:38.109) to ++ // the formatted string. ++ return snprintf(buffer, bufLen, "%s.%03lu", tmpbuf, millisec); ++} ++ ++ + static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, const struct ucred *ucred, const struct timeval *tv) { + + static const union sockaddr_union sa = { +@@ -143,13 +181,11 @@ void server_forward_syslog(Server *s, int priority, const char *identifier, cons + xsprintf(header_priority, "<%i>", priority); + IOVEC_SET_STRING(iovec[n++], header_priority); + ++ + /* Second: timestamp */ +- t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC)); +- tm = localtime(&t); +- if (!tm) +- return; +- if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0) +- return; ++ if (formatSyslogDate(header_time, sizeof(header_time), tv) <=0 ) ++ return; ++ + IOVEC_SET_STRING(iovec[n++], header_time); + + /* Third: identifier and PID */ +-- +1.9.1 + diff --git a/extended/systemd/centos/patches/0503-Configure-journald-to-forward-to-syslog.patch b/extended/systemd/centos/patches/0503-Configure-journald-to-forward-to-syslog.patch new file mode 100644 index 000000000..f5b313ecc --- /dev/null +++ b/extended/systemd/centos/patches/0503-Configure-journald-to-forward-to-syslog.patch @@ -0,0 +1,34 @@ +From b628fac8eec011503e5f86f17d9e68b7a2cc1e56 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 7 Mar 2017 13:17:56 -0500 +Subject: [PATCH] Configure journald to forward to syslog + +--- + src/journal/journald.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald.conf b/src/journal/journald.conf +index 3907dfb..ef86ffe 100644 +--- a/src/journal/journald.conf ++++ b/src/journal/journald.conf +@@ -12,7 +12,7 @@ + # See journald.conf(5) for details. + + [Journal] +-#Storage=auto ++Storage=none + #Compress=yes + #Seal=yes + #SplitMode=uid +@@ -27,7 +27,7 @@ + #RuntimeMaxFileSize= + #MaxRetentionSec= + #MaxFileSec=1month +-#ForwardToSyslog=yes ++ForwardToSyslog=yes + #ForwardToKMsg=no + #ForwardToConsole=no + #ForwardToWall=yes +-- +1.8.3.1 + diff --git a/extended/systemd/centos/patches/0504-Configure-journald-rate-limit.patch b/extended/systemd/centos/patches/0504-Configure-journald-rate-limit.patch new file mode 100644 index 000000000..87b55cdad --- /dev/null +++ b/extended/systemd/centos/patches/0504-Configure-journald-rate-limit.patch @@ -0,0 +1,29 @@ +From e5057bed6636f4ba4ec3d72ed5966e8dcd17200b Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Mon, 15 May 2017 16:46:28 -0500 +Subject: [PATCH 1/1] CGTS-6814: syslog occasionally dropping logs Configure + Configure the journald rate limit to 5000 messages within 30 seconds. + This limit is required to support SM managed processes that share the limit. + +--- + src/journal/journald.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald.conf b/src/journal/journald.conf +index ef86ffe..2e7180e 100644 +--- a/src/journal/journald.conf ++++ b/src/journal/journald.conf +@@ -17,8 +17,8 @@ Storage=none + #Seal=yes + #SplitMode=uid + #SyncIntervalSec=5m +-#RateLimitInterval=30s +-#RateLimitBurst=1000 ++RateLimitInterval=30s ++RateLimitBurst=5000 + #SystemMaxUse= + #SystemKeepFree= + #SystemMaxFileSize= +-- +1.8.3.1 + diff --git a/extended/systemd/centos/patches/0505-remove-id-sas-path-symlink.patch b/extended/systemd/centos/patches/0505-remove-id-sas-path-symlink.patch new file mode 100644 index 000000000..48a38b79c --- /dev/null +++ b/extended/systemd/centos/patches/0505-remove-id-sas-path-symlink.patch @@ -0,0 +1,26 @@ +From f322cd1a7678c6e50ac1a842b887ea1fc3e21627 Mon Sep 17 00:00:00 2001 +From: Irina Mihai +Date: Mon, 15 May 2017 18:58:48 +0000 +Subject: [PATCH] Remove ID_SAS_PATH rule + +--- + rules/60-persistent-storage.rules | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules +index 06e3329..3f2c1c1 100644 +--- a/rules/60-persistent-storage.rules ++++ b/rules/60-persistent-storage.rules +@@ -64,9 +64,7 @@ KERNEL=="mspblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+= + # by-path (parent device path) + ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id" + ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}" +-ENV{DEVTYPE}=="disk", ENV{ID_SAS_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_SAS_PATH}" + ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" +-ENV{DEVTYPE}=="partition", ENV{ID_SAS_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_SAS_PATH}-part%n" + + # skip unpartitioned removable media devices from drivers which do not send "change" events + ENV{DEVTYPE}=="disk", KERNEL!="sd*|sr*", ATTR{removable}=="1", GOTO="persistent_storage_end" +-- +1.8.3.1 + diff --git a/extended/systemd/centos/patches/0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch b/extended/systemd/centos/patches/0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch new file mode 100644 index 000000000..2238eb2b4 --- /dev/null +++ b/extended/systemd/centos/patches/0506-CGTS-7466-fix-ACL-warnings-from-systemd-tmpfiles-set.patch @@ -0,0 +1,38 @@ +From 65c3c74fd119db0309d68430ed89652666c884d5 Mon Sep 17 00:00:00 2001 +From: systemd team +Date: Tue, 10 Oct 2017 17:06:10 -0400 +Subject: [PATCH] CGTS-7466 fix ACL warnings from systemd tmpfiles set + +--- + tmpfiles.d/systemd.conf.m4 | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tmpfiles.d/systemd.conf.m4 b/tmpfiles.d/systemd.conf.m4 +index 0575408..d984912 100644 +--- a/tmpfiles.d/systemd.conf.m4 ++++ b/tmpfiles.d/systemd.conf.m4 +@@ -27,8 +27,8 @@ d /run/log 0755 root root - + z /run/log/journal 2755 root systemd-journal - - + Z /run/log/journal/%m ~2750 root systemd-journal - - + m4_ifdef(`HAVE_ACL',`` +-a+ /run/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x +-A+ /run/log/journal/%m - - - - group:adm:r-x,group:wheel:r-x ++a+ /run/log/journal/%m - - - - d:group:wrs_protected:r-x,d:group:wheel:r-x ++A+ /run/log/journal/%m - - - - group:wrs_protected:r-x,group:wheel:r-x + '')m4_dnl + + z /var/log/journal 2755 root systemd-journal - - +@@ -37,8 +37,8 @@ z /var/log/journal/%m/system.journal 0640 root systemd-journal - - + m4_ifdef(`HAVE_ACL',`` + a+ /var/log/journal - - - - d:group:adm:r-x,d:group:wheel:r-x + a+ /var/log/journal - - - - group:adm:r-x,group:wheel:r-x +-a+ /var/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x +-a+ /var/log/journal/%m - - - - group:adm:r-x,group:wheel:r-x ++a+ /var/log/journal/%m - - - - d:group:wrs_protected:r-x,d:group:wheel:r-x ++a+ /var/log/journal/%m - - - - group:wrs_protected:r-x,group:wheel:r-x + a+ /var/log/journal/%m/system.journal - - - - group:adm:r--,group:wheel:r-- + '')m4_dnl + +-- +1.9.1 + diff --git a/extended/systemd/centos/patches/0507-move-vartmp-to-tmpfs.patch b/extended/systemd/centos/patches/0507-move-vartmp-to-tmpfs.patch new file mode 100644 index 000000000..8ef269603 --- /dev/null +++ b/extended/systemd/centos/patches/0507-move-vartmp-to-tmpfs.patch @@ -0,0 +1,33 @@ +From e73dc9f146c7f29e7b08ddcbae3b89c6b573760f Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Mon, 25 Sep 2017 16:26:54 -0400 +Subject: [PATCH] US103091: IMA System Configuration + +Since /tmp is now mounted on tmpfs, we will make /var/tmp as a simlink +on /tmp. Ensure that the var.tmp subdir (within /tmp), to which /var/tmp +is similinked, does not get clobbered during cleanup +--- + tmpfiles.d/tmp.conf | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf +index ffdd82f..530866b 100644 +--- a/tmpfiles.d/tmp.conf ++++ b/tmpfiles.d/tmp.conf +@@ -9,10 +9,12 @@ + + # Clear tmp directories separately, to make them easier to override + v /tmp 1777 root root 10d +-v /var/tmp 1777 root root 30d ++v /tmp/var.tmp 1777 root root 30d ++L+ /var/tmp - - - - /tmp/var.tmp + + # Exclude namespace mountpoints created with PrivateTmp=yes + x /tmp/systemd-private-%b-* + X /tmp/systemd-private-%b-*/tmp + x /var/tmp/systemd-private-%b-* + X /var/tmp/systemd-private-%b-*/tmp ++X /tmp/var.tmp +-- +1.8.3.1 + diff --git a/extended/systemd/centos/patches/0508-set-a-1GB-size-restriction-on-tpmfs.patch b/extended/systemd/centos/patches/0508-set-a-1GB-size-restriction-on-tpmfs.patch new file mode 100644 index 000000000..c69dd7cee --- /dev/null +++ b/extended/systemd/centos/patches/0508-set-a-1GB-size-restriction-on-tpmfs.patch @@ -0,0 +1,26 @@ +From e7b8b0d6308c2afcdbd17733226e7aaf7f876b09 Mon Sep 17 00:00:00 2001 +From: systemd team +Date: Thu, 12 Oct 2017 18:06:58 -0400 +Subject: [PATCH] set a 1GB size restriction on tpmfs, to prevent OOM Kernel + failures + +--- + units/tmp.mount | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/tmp.mount b/units/tmp.mount +index af0cf4a..eda2334 100644 +--- a/units/tmp.mount ++++ b/units/tmp.mount +@@ -18,7 +18,7 @@ Before=local-fs.target umount.target + What=tmpfs + Where=/tmp + Type=tmpfs +-Options=mode=1777,strictatime ++Options=mode=1777,strictatime,size=1G + + # Make 'systemctl enable tmp.mount' work: + [Install] +-- +1.8.3.1 + diff --git a/extended/systemd/centos/srpm_path b/extended/systemd/centos/srpm_path new file mode 100644 index 000000000..d64706487 --- /dev/null +++ b/extended/systemd/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/systemd-219-42.el7_4.1.src.rpm diff --git a/extended/tboot/centos/build_srpm.data b/extended/tboot/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/extended/tboot/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/extended/tboot/centos/meta_patches/0001-tboot-Update-package-versioning-for-TIS-format.patch b/extended/tboot/centos/meta_patches/0001-tboot-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..3c686a96b --- /dev/null +++ b/extended/tboot/centos/meta_patches/0001-tboot-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,32 @@ +From f7ac0c586ee46b67c7b5a541ee823f459e19c5c6 Mon Sep 17 00:00:00 2001 +From: Bin Qian +Date: Mon, 27 Nov 2017 08:35:10 -0500 +Subject: [PATCH 1/1] WRS: 8000-TiS-tboot.patch + +--- + SPECS/tboot.spec | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/SPECS/tboot.spec b/SPECS/tboot.spec +index 5827214..9ae8f9b 100644 +--- a/SPECS/tboot.spec ++++ b/SPECS/tboot.spec +@@ -1,13 +1,14 @@ + Summary: Performs a verified launch using Intel TXT + Name: tboot + Version: 1.9.5 +-Release: 1%{?dist} ++Release: 1.e17%{?_tis_dist}.%{tis_patch_ver} + Epoch: 1 + + Group: System Environment/Base + License: BSD + URL: http://sourceforge.net/projects/tboot/ + Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz ++ + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + + BuildRequires: trousers-devel +-- +1.8.3.1 + diff --git a/extended/tboot/centos/meta_patches/0002-TiS-tboot.patch b/extended/tboot/centos/meta_patches/0002-TiS-tboot.patch new file mode 100644 index 000000000..b7b52858b --- /dev/null +++ b/extended/tboot/centos/meta_patches/0002-TiS-tboot.patch @@ -0,0 +1,43 @@ +From 16a82ea84332a117c4524caaa4209b912e18e888 Mon Sep 17 00:00:00 2001 +From: Bin Qian +Date: Wed, 6 Dec 2017 08:47:12 -0500 +Subject: [PATCH 1/1] TiS tboot + +--- + SPECS/tboot.spec | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/SPECS/tboot.spec b/SPECS/tboot.spec +index 9ae8f9b..4c479ad 100644 +--- a/SPECS/tboot.spec ++++ b/SPECS/tboot.spec +@@ -8,11 +8,12 @@ Group: System Environment/Base + License: BSD + URL: http://sourceforge.net/projects/tboot/ + Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz ++Patch999: 1000-tboot-for-tis.patch + + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + + BuildRequires: trousers-devel +-BuildRequires: openssl-devel ++BuildRequires: openssl-devel git + ExclusiveArch: x86_64 + + %description +@@ -22,6 +23,12 @@ and verified launch of an OS kernel/VMM. + + %prep + %setup -q ++git init ++git config user.email "example@example.com" ++git config user.name "RHEL example" ++git add . ++git commit -a -q -m "baseline." ++git am %{patches} + + %build + CFLAGS="$RPM_OPT_FLAGS"; export CFLAGS +-- +1.8.3.1 + diff --git a/extended/tboot/centos/meta_patches/0003-security-set-immutable-attribute.patch b/extended/tboot/centos/meta_patches/0003-security-set-immutable-attribute.patch new file mode 100644 index 000000000..20a4cbd5e --- /dev/null +++ b/extended/tboot/centos/meta_patches/0003-security-set-immutable-attribute.patch @@ -0,0 +1,56 @@ +From 15d8e3a327bc4ee96845163f962837cfcb4699bb Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Tue, 6 Feb 2018 15:25:00 -0500 +Subject: [PATCH] CGTS-8849: Security: Set immutable attribute and permissions + +--- + SPECS/tboot.spec | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/SPECS/tboot.spec b/SPECS/tboot.spec +index 4c479ad..d0039d4 100644 +--- a/SPECS/tboot.spec ++++ b/SPECS/tboot.spec +@@ -43,8 +43,14 @@ if [ -e "/sys/firmware/efi" ]; then + putk "WARNING: tboot is not supported on UEFI-based systems." + putk " Please see https://access.redhat.com/articles/2217041." + putk " and https://access.redhat.com/articles/2464721" +- exit 0; + fi ++# On updating this package, we want to clear the immutable ++# attribute so that the module files can get overwritten ++if [ $1 -gt 1 ]; then ++ chattr -i /boot/tboot.gz /boot/tboot-syms ++fi ++exit 0 ++ + + %install + rm -rf $RPM_BUILD_ROOT +@@ -53,6 +59,12 @@ make debug=y DISTDIR=$RPM_BUILD_ROOT install + %clean + rm -rf $RPM_BUILD_ROOT + ++%post ++# Set immutable attribute on tboot modules ++chattr +i /boot/tboot.gz /boot/tboot-syms ++exit 0 ++ ++ + %files + %defattr(-,root,root,-) + %doc README COPYING docs/* lcptools/lcptools2.txt lcptools/Linux_LCP_Tools_User_Manual.pdf +@@ -89,8 +101,8 @@ rm -rf $RPM_BUILD_ROOT + %{_mandir}/man8/lcp_writepol.8.gz + %{_mandir}/man8/tb_polgen.8.gz + %{_mandir}/man8/txt-stat.8.gz +-/boot/tboot.gz +-/boot/tboot-syms ++%attr(0400,root,root) /boot/tboot.gz ++%attr(0400,root,root) /boot/tboot-syms + + %changelog + * Fri Jan 27 2017 Tony Camuso - 1:1.9.5-1 +-- +1.8.3.1 + diff --git a/extended/tboot/centos/meta_patches/PATCH_ORDER b/extended/tboot/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..41c6a11d7 --- /dev/null +++ b/extended/tboot/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +0001-tboot-Update-package-versioning-for-TIS-format.patch +0002-TiS-tboot.patch +0003-security-set-immutable-attribute.patch diff --git a/extended/tboot/centos/patches/1000-tboot-for-tis.patch b/extended/tboot/centos/patches/1000-tboot-for-tis.patch new file mode 100644 index 000000000..104211d62 --- /dev/null +++ b/extended/tboot/centos/patches/1000-tboot-for-tis.patch @@ -0,0 +1,188 @@ +From c2edea1ff347242a70075808652fa1ad4c86037a Mon Sep 17 00:00:00 2001 +From: Bin Qian +Date: Mon, 27 Nov 2017 08:35:11 -0500 +Subject: [PATCH 1/1] WRS: Patch1: 9000-tboot-for-tis.patch + +--- + tboot/20_linux_tboot | 21 ++++++++++++--------- + tboot/20_linux_xen_tboot | 2 +- + tboot/common/policy.c | 16 +++++++++++----- + tboot/common/tpm_20.c | 7 ++++--- + 4 files changed, 28 insertions(+), 18 deletions(-) + +diff --git a/tboot/20_linux_tboot b/tboot/20_linux_tboot +index 7c25181..e4fd557 100644 +--- a/tboot/20_linux_tboot ++++ b/tboot/20_linux_tboot +@@ -22,6 +22,13 @@ exec_prefix=${prefix} + bindir=${exec_prefix}/bin + libdir=${exec_prefix}/lib + sysconfdir=/etc ++ ++ ++tboot=`cat /proc/cmdline | xargs -n1 | grep '^tboot=true$'` || true ++if [ -z "$tboot" ]; then ++ exit 0 ++fi ++ + if test -e /usr/share/grub/grub-mkconfig_lib; then + . /usr/share/grub/grub-mkconfig_lib + elif test -e ${libdir}/grub/grub-mkconfig_lib; then +@@ -38,7 +45,7 @@ fi + [ -z "${GRUB_CMDLINE_LINUX_TBOOT}" ] && unset GRUB_CMDLINE_LINUX_TBOOT + [ -z "${GRUB_TBOOT_POLICY_DATA}" ] && unset GRUB_TBOOT_POLICY_DATA + # Command line for tboot itself +-: ${GRUB_CMDLINE_TBOOT='logging=serial,memory,vga'} ++: ${GRUB_CMDLINE_TBOOT='logging=serial,memory,vga extpol=sha256'} + # Linux kernel parameters to append for tboot + : ${GRUB_CMDLINE_LINUX_TBOOT='intel_iommu=on'} + # Base name of LCP policy data file for list policy +@@ -67,10 +74,8 @@ export TEXTDOMAINDIR=${prefix}/share/locale + + CLASS="--class gnu-linux --class gnu --class os --class tboot" + +-if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux +-else +- OS="${GRUB_DISTRIBUTOR} GNU/Linux" ++OS="CentOS GNU/Linux" ++if [ -n "${GRUB_DISTRIBUTOR}" ] ; then + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" + fi + +@@ -107,9 +112,9 @@ linux_entry () + iommu_args="$7" + + if ${recovery} ; then +- title="$(gettext_quoted "%s, with tboot %s and Linux %s (recovery mode)")" ++ title="$(gettext_quoted "%s, w/ tboot %s & Linux %s (recovery mode)")" + else +- title="$(gettext_quoted "%s, with tboot %s and Linux %s")" ++ title="$(gettext_quoted "%s, w/ tboot %s & Linux %s")" + fi + + if [ -d /sys/firmware/efi ] ; then +@@ -200,7 +205,6 @@ while [ "x${tboot_list}" != "x" ] && [ "x$linux_list" != "x" ] ; do + rel_tboot_dirname=`make_system_path_relative_to_its_root $tboot_dirname` + # tboot_version=`echo $tboot_basename | sed -e "s,.gz$,,g;s,^tboot-,,g"` + tboot_version="1.9.5" +- echo "submenu \"tboot ${tboot_version}\" {" + while [ "x$list" != "x" ] ; do + linux=`version_find_latest $list` + echo "Found linux image: $linux" >&2 +@@ -241,6 +245,5 @@ while [ "x${tboot_list}" != "x" ] && [ "x$linux_list" != "x" ] ; do + + list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` + done +- echo "}" + tboot_list=`echo $tboot_list | tr ' ' '\n' | grep -vx $current_tboot | tr '\n' ' '` + done +diff --git a/tboot/20_linux_xen_tboot b/tboot/20_linux_xen_tboot +index b674834..4dc8d68 100644 +--- a/tboot/20_linux_xen_tboot ++++ b/tboot/20_linux_xen_tboot +@@ -39,7 +39,7 @@ fi + [ -z "${GRUB_CMDLINE_LINUX_XEN_TBOOT}" ] && unset GRUB_CMDLINE_LINUX_XEN_TBOOT + [ -z "${GRUB_TBOOT_POLICY_DATA}" ] && unset GRUB_TBOOT_POLICY_DATA + # Command line for tboot itself +-: ${GRUB_CMDLINE_TBOOT='logging=serial,memory,vga'} ++: ${GRUB_CMDLINE_TBOOT='logging=serial,memory,vga extpol=sha256'} + # Xen parameters to append for tboot + : ${GRUB_CMDLINE_XEN_TBOOT=''} + # Linux kernel parameters to append for tboot + Xen +diff --git a/tboot/common/policy.c b/tboot/common/policy.c +index b30d299..9ec02be 100644 +--- a/tboot/common/policy.c ++++ b/tboot/common/policy.c +@@ -347,6 +347,7 @@ tb_error_t set_policy(void) + * type is LCP_POLTYPE_LIST (since we could have been give a policy data + * file even though the policy was not a LIST */ + printk(TBOOT_INFO"reading Launch Control Policy from TPM NV...\n"); ++ + if ( read_policy_from_tpm(g_tpm->lcp_own_index, + _policy_index_buf, &policy_index_size) ) { + printk(TBOOT_DETA"\t:%lu bytes read\n", policy_index_size); +@@ -406,6 +407,7 @@ bool hash_policy(tb_hash_t *hash, uint16_t hash_alg) + + /* generate hash by hashing cmdline and module image */ + static bool hash_module(hash_list_t *hl, ++ u16 cur_alg, + const char* cmdline, void *base, + size_t size) + { +@@ -414,6 +416,7 @@ static bool hash_module(hash_list_t *hl, + return false; + } + ++ printk(TBOOT_INFO"Using hash algorithm %d\n", cur_alg); + /* final hash is SHA-1( SHA-1(cmdline) | SHA-1(image) ) */ + /* where cmdline is first stripped of leading spaces, file name, then */ + /* any spaces until the next non-space char */ +@@ -428,16 +431,17 @@ static bool hash_module(hash_list_t *hl, + switch (g_tpm->extpol) { + case TB_EXTPOL_FIXED: + hl->count = 1; +- hl->entries[0].alg = g_tpm->cur_alg; ++ // hl->entries[0].alg = g_tpm->cur_alg; ++ hl->entries[0].alg = cur_alg; + + if ( !hash_buffer((const unsigned char *)cmdline, strlen(cmdline), +- &hl->entries[0].hash, g_tpm->cur_alg) ) ++ &hl->entries[0].hash, cur_alg) ) + return false; + /* hash image and extend into cmdline hash */ + tb_hash_t img_hash; +- if ( !hash_buffer(base, size, &img_hash, g_tpm->cur_alg) ) ++ if ( !hash_buffer(base, size, &img_hash, cur_alg) ) + return false; +- if ( !extend_hash(&hl->entries[0].hash, &img_hash, g_tpm->cur_alg) ) ++ if ( !extend_hash(&hl->entries[0].hash, &img_hash, cur_alg) ) + return false; + + break; +@@ -633,7 +637,7 @@ static tb_error_t verify_module(module_t *module, tb_policy_entry_t *pol_entry, + } + + hash_list_t hl; +- if ( !hash_module(&hl, cmdline, base, size) ) { ++ if ( !hash_module(&hl, hash_alg, cmdline, base, size) ) { + printk(TBOOT_ERR"\t hash cannot be generated.\n"); + return TB_ERR_MODULE_VERIFICATION_FAILED; + } +@@ -657,6 +661,8 @@ static tb_error_t verify_module(module_t *module, tb_policy_entry_t *pol_entry, + if ( pol_entry != NULL && + !is_hash_in_policy_entry(pol_entry, &hl.entries[0].hash, hash_alg) ) { + printk(TBOOT_ERR"\t verification failed\n"); ++ print_hash(&hl.entries[0].hash, hash_alg); ++ print_hash(&pol_entry->hashes[0], hash_alg); + return TB_ERR_MODULE_VERIFICATION_FAILED; + } + +diff --git a/tboot/common/tpm_20.c b/tboot/common/tpm_20.c +index 678a3d2..63ca9dd 100644 +--- a/tboot/common/tpm_20.c ++++ b/tboot/common/tpm_20.c +@@ -1933,7 +1933,7 @@ static bool tpm20_nv_read(struct tpm_if *ti, uint32_t locality, + + ret = _tpm20_nv_read(locality, &read_in, &read_out); + if ( ret != TPM_RC_SUCCESS ) { +- printk(TBOOT_WARN"TPM: read NV index %08x from offset %08x, return value = %08X\n", ++ printk(TBOOT_WARN"TPM 2.0: read NV index %08x from offset %08x, return value = %08X\n", + index, offset, ret); + ti->error = ret; + return false; +@@ -2273,8 +2273,9 @@ static bool tpm20_init(struct tpm_if *ti) + get_tboot_extpol(); + if (info_list->capabilities.tpm_nv_index_set == 0){ + /* init NV index */ +- ti->tb_policy_index = 0x1200001; +- ti->lcp_own_index = 0x1400001; ++ ti->tb_policy_index = 0x1800001; ++ // ti->lcp_own_index = 0x1400001; ++ ti->lcp_own_index = 0x1c10131; + ti->tb_err_index = 0x1200002; + ti->sgx_svn_index = 0x01800004; + } +-- +1.8.3.1 + diff --git a/extended/tboot/centos/srpm_path b/extended/tboot/centos/srpm_path new file mode 100644 index 000000000..824a4a4bd --- /dev/null +++ b/extended/tboot/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/tboot-1.9.5-1.el7.src.rpm diff --git a/extended/watchdog/centos/build_srpm.data b/extended/watchdog/centos/build_srpm.data new file mode 100644 index 000000000..112ca54f4 --- /dev/null +++ b/extended/watchdog/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=2 diff --git a/extended/watchdog/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/extended/watchdog/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..4e3359b40 --- /dev/null +++ b/extended/watchdog/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 061c8b4c1db3fcb4a9e60eb826d1ac474067aae3 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 27 Sep 2016 10:55:15 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/watchdog.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/watchdog.spec b/SPECS/watchdog.spec +index 75ce3dd..88c4245 100644 +--- a/SPECS/watchdog.spec ++++ b/SPECS/watchdog.spec +@@ -1,7 +1,7 @@ + Summary: Software and/or Hardware watchdog daemon + Name: watchdog + Version: 5.13 +-Release: 11%{?dist} ++Release: 11.el7%{?_tis_dist}.%{tis_patch_ver} + License: GPLv2+ + + URL: http://sourceforge.net/projects/watchdog/ +-- +1.8.3.1 + diff --git a/extended/watchdog/centos/meta_patches/PATCH_ORDER b/extended/watchdog/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..f51d71338 --- /dev/null +++ b/extended/watchdog/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +spec-TiS-changes.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/extended/watchdog/centos/meta_patches/spec-TiS-changes.patch b/extended/watchdog/centos/meta_patches/spec-TiS-changes.patch new file mode 100644 index 000000000..13f2e7161 --- /dev/null +++ b/extended/watchdog/centos/meta_patches/spec-TiS-changes.patch @@ -0,0 +1,35 @@ +From 06d8868ea3f8eefa2627732ca606a66e847a79ec Mon Sep 17 00:00:00 2001 +From: Nam Ninh +Date: Wed, 1 Jun 2016 11:38:56 -0400 +Subject: [PATCH] watchdog: include TIS changes + +Add fix-ping-failure patch from OVP6. + +Signed-off-by: Nam Ninh +--- + SPECS/watchdog.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/watchdog.spec b/SPECS/watchdog.spec +index 7eeacc9..75ce3dd 100644 +--- a/SPECS/watchdog.spec ++++ b/SPECS/watchdog.spec +@@ -18,6 +18,7 @@ Patch1: 0001-watchdog-Clearer-help-output.patch + Patch2: 0002-wd_identify-wd_keepalive-Document-c-config-file-in-h.patch + Patch3: 0003-watchdog-5.13-rhsel.patch + Patch4: 0004-watchdog-5.13-rhseldoc.patch ++Patch5: fix-ping-failure.patch + + BuildRequires: systemd-units + +@@ -49,6 +50,7 @@ expiration) initiated by the BMC. + %patch2 -p1 -b .keepalive + %patch3 -p1 -b .rhsel + %patch4 -p1 -b .rhseldoc ++%patch5 -p1 -b .ping-failure + + cp %{SOURCE2} . + cp %{SOURCE3} . +-- +1.8.3.1 + diff --git a/extended/watchdog/centos/srpm_path b/extended/watchdog/centos/srpm_path new file mode 100644 index 000000000..dbfb5a496 --- /dev/null +++ b/extended/watchdog/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/watchdog-5.13-11.el7.src.rpm diff --git a/extended/watchdog/files/fix-ping-failure.patch b/extended/watchdog/files/fix-ping-failure.patch new file mode 100644 index 000000000..230e1731d --- /dev/null +++ b/extended/watchdog/files/fix-ping-failure.patch @@ -0,0 +1,70 @@ +From 4233b90d468bc9e0eb975d96eb69a72ec30cabda Mon Sep 17 00:00:00 2001 +From: Roy.Li +Date: Wed, 1 Jun 2016 11:12:48 -0400 +Subject: watchdog: Fix ping mode failure + +Upstream-Status: Pending + +When watchdog works on ping mode, the system will be rebooted since +watchdog can not receive the expected ECOREPLY on a setting interval. + +Ping mode uses a raw socket to send a ECO packet, then uses select() +to wait and recvfrom() to receive the ECOREPLY packet, if select() +shows the data is ready, and the data is not the expected ECOREPLY, +and waiting time is not overdue, it will continue use select() and +recvfrom(). + +Problem is that the raw socket can receive any icmp packets, if we do +not set filters, and there are many icmp packets on socket, this +program will not find its interested ECOREPLY packet in a special +interval, which makes the ping mode fail. + +Other program is that watchdog sometime can not reach the call of +recvfrom to try to receive packets since tv_sec of struct timeval +of select parameter is 0. + +The timeout of select() is the result of ping interval minusing the +time of calling gettimeofday spending, when ping interval is 1 second, +and the call of gettimeofday() spends several useconds, the tv_sec of +struct timeval of select parameter must be 0, at that condition, we +should it is valid of tv_sec of struct timeval of select parameter be 0 + +Signed-off-by: Roy.Li +Signed-off-by: Nam Ninh +--- + src/watchdog.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/watchdog.c b/src/watchdog.c +index 6f93de8..33ba528 100644 +--- a/src/watchdog.c ++++ b/src/watchdog.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -567,6 +568,8 @@ int main(int argc, char *const argv[]) + pid_t child_pid; + int oom_adjusted = 0; + struct stat s; ++ struct icmp_filter filt; ++ filt.data = ~(1<sock_fp, SOL_RAW, ICMP_FILTER, (char*)&filt, sizeof(filt)); + /* this is necessary for broadcast pings to work */ + (void) setsockopt(net->sock_fp, SOL_SOCKET, SO_BROADCAST, (char *)&hold, sizeof(hold)); + +-- +1.8.3.1 + diff --git a/kernel-rt/centos/build_srpm.data b/kernel-rt/centos/build_srpm.data new file mode 100644 index 000000000..fef27a241 --- /dev/null +++ b/kernel-rt/centos/build_srpm.data @@ -0,0 +1,4 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=39 +BUILD_IS_BIG=10 +BUILD_IS_SLOW=12 diff --git a/kernel-rt/centos/meta_patches/Add-patch-for-missing-ifdef-in-tracing.patch b/kernel-rt/centos/meta_patches/Add-patch-for-missing-ifdef-in-tracing.patch new file mode 100644 index 000000000..7a2fee85b --- /dev/null +++ b/kernel-rt/centos/meta_patches/Add-patch-for-missing-ifdef-in-tracing.patch @@ -0,0 +1,36 @@ +From 6f763c9f49dbb0089159939911fb6e396b14e6eb Mon Sep 17 00:00:00 2001 +Message-Id: <6f763c9f49dbb0089159939911fb6e396b14e6eb.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 14/29] Add patch for missing ifdef in tracing + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index d11d8fe..fd9ed82 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -407,6 +407,7 @@ Patch1009: memblock-introduce-memblock_alloc_range.patch + Patch1010: Notification-of-death-of-arbitrary-processes.patch + Patch1011: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + Patch1012: x86-enable-DMA-CMA-with-swiotlb.patch ++Patch1013: Add-missing-ifdef-around-max-latency-variable.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -775,6 +776,7 @@ ApplyPatch memblock-introduce-memblock_alloc_range.patch + ApplyPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + ApplyPatch Notification-of-death-of-arbitrary-processes.patch + ApplyPatch x86-enable-DMA-CMA-with-swiotlb.patch ++ApplyPatch Add-missing-ifdef-around-max-latency-variable.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch b/kernel-rt/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch new file mode 100644 index 000000000..12f76370c --- /dev/null +++ b/kernel-rt/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch @@ -0,0 +1,35 @@ +From 7aea53f8899c77d59c5022334c64e785f32af406 Mon Sep 17 00:00:00 2001 +Message-Id: <7aea53f8899c77d59c5022334c64e785f32af406.1517518486.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 19 Dec 2017 17:53:28 -0500 +Subject: [PATCH 1/1] CVE mqueue fix a use after free in sys_mq_notify + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 30a7e08..a56e051 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -423,6 +423,8 @@ Patch1028: timer-Minimize-nohz-off-overhead.patch + Patch1029: aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + Patch1030: dpt_i2o-fix-build-warning.patch + Patch1031: KVM-x86-Fix-potential-preemption-when-get-the-curren.patch ++# CVE-2017-11176: kernel: Use-after-free in sys_mq_notify() ++Patch1032: mqueue-fix-a-use-after-free-in-sys_mq_notify.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -817,6 +819,7 @@ ApplyPatch timer-Minimize-nohz-off-overhead.patch + ApplyPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + ApplyPatch dpt_i2o-fix-build-warning.patch + ApplyPatch KVM-x86-Fix-potential-preemption-when-get-the-curren.patch ++ApplyPatch mqueue-fix-a-use-after-free-in-sys_mq_notify.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Change-name-of-source-tarball-drop-el7.patch b/kernel-rt/centos/meta_patches/Change-name-of-source-tarball-drop-el7.patch new file mode 100644 index 000000000..e1b7794cc --- /dev/null +++ b/kernel-rt/centos/meta_patches/Change-name-of-source-tarball-drop-el7.patch @@ -0,0 +1,27 @@ +From 473c53bbcbf2fc491f32484733e2d459a8730ab0 Mon Sep 17 00:00:00 2001 +Message-Id: <473c53bbcbf2fc491f32484733e2d459a8730ab0.1507921416.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Fri, 13 Oct 2017 14:59:37 -0400 +Subject: [PATCH 1/1] Change name of source tarball drop el7 + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index ae044c2..cbeb4cd 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -334,7 +334,7 @@ BuildRequires: rpm-build >= 4.9.0-1, elfutils >= 0.153-1 + %define debuginfo_args --strict-build-id -r + %endif + +-Source0: %{name}-%{rpmversion}-%{pkg_release_simple}%{?dist}.tar.xz ++Source0: %{name}-%{rpmversion}-%{pkg_release_simple}.tar.xz + + Source10: sign-modules + %define modsign_cmd %{SOURCE10} +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Check-for-oversized-nfs-arguments.patch b/kernel-rt/centos/meta_patches/Check-for-oversized-nfs-arguments.patch new file mode 100644 index 000000000..1d2f7d2ce --- /dev/null +++ b/kernel-rt/centos/meta_patches/Check-for-oversized-nfs-arguments.patch @@ -0,0 +1,36 @@ +From 2771619e5d72c19e52d27ba949a81e4dff451e1a Mon Sep 17 00:00:00 2001 +Message-Id: <2771619e5d72c19e52d27ba949a81e4dff451e1a.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 22 Aug 2017 17:26:15 -0400 +Subject: [PATCH 25/29] Check for oversized nfs arguments + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index dc30da0..e53f906 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -426,6 +426,7 @@ Patch1028: stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch + Patch1029: add-per-cpu-pm-qos-resume-latency-consideration.patch + Patch1030: expose-pm_qos_resume_latency-for-cpus.patch + Patch1031: avoid-taking-spinlock-for-accessing-qos-values.patch ++Patch1032: nfsd-check-for-oversized-NFSv2-v3-arguments.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -820,6 +821,7 @@ ApplyPatch stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch + ApplyPatch add-per-cpu-pm-qos-resume-latency-consideration.patch + ApplyPatch expose-pm_qos_resume_latency-for-cpus.patch + ApplyPatch avoid-taking-spinlock-for-accessing-qos-values.patch ++ApplyPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch b/kernel-rt/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch new file mode 100644 index 000000000..d3f160605 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch @@ -0,0 +1,110 @@ +From 6b5a0a906aa6e78b38d019847020a419987218e8 Mon Sep 17 00:00:00 2001 +Message-Id: <6b5a0a906aa6e78b38d019847020a419987218e8.1507923089.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Fri, 13 Oct 2017 12:48:00 -0400 +Subject: [PATCH 1/1] Cleanup TIC patch list for CentOS 7.4 port + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 62 +++++++++++++++------------------------------------- + 1 file changed, 18 insertions(+), 44 deletions(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 636a68e..ad92b9b 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -389,9 +389,6 @@ Source30002: kernel-3.10.0-x86_64-rt-trace.config.tis_extra + # Commit 32b3809 was reverted and the new solution will be applying + # those changes at the %build section of the specfile. + Patch001: avoid-debuginfo-hash-collision-scripts.patch +-Patch1000: debrand-single-cpu.patch +-Patch1001: debrand-rh_taint.patch +-Patch1002: debrand-rh-i686-cpu.patch + + # Empty final patch file to facilitate testing of kernel patches + Patch999999: linux-kernel-test.patch +@@ -414,26 +411,16 @@ Patch1015: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + Patch1016: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + Patch1017: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + Patch1018: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch +-Patch1019: mm-larger-stack-guard-gap-between-vmas.patch +-Patch1020: mm-fix-new-crash-in-unmapped_area_topdown.patch +-Patch1021: Allow-stack-to-grow-up-to-address-space-limit.patch +-Patch1022: kernfs-porting-original-3.15-version.patch +-Patch1023: kernfs-fixing-compilation-issues-on-3.10.patch +-Patch1024: cacheinfo-porting-original-4.10.17-version.patch +-Patch1025: cacheinfo-fixing-compilation-issues-on-3.10.patch +-Patch1026: intel-rdt-porting-original-4.10.17-version.patch +-Patch1027: intel-rdt-fixing-compilation-issues-on-3.10.patch +-Patch1028: stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch +-Patch1029: add-per-cpu-pm-qos-resume-latency-consideration.patch +-Patch1030: expose-pm_qos_resume_latency-for-cpus.patch +-Patch1031: avoid-taking-spinlock-for-accessing-qos-values.patch +-Patch1032: nfsd-check-for-oversized-NFSv2-v3-arguments.patch +-Patch1033: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch +-Patch1034: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch +-Patch1035: US101216-IMA-support-in-Titanium-kernel.patch +-Patch1036: timer-reduce-timer-migration-overhead-if-disabled.patch +-Patch1037: timer-minimize-nohz-off-overhead.patch +-Patch1038: US103091-IMA-System-Configuration.patch ++Patch1019: Porting-Cacheinfo-from-Kernel-4.10.17.patch ++Patch1020: Fix-cacheinfo-compilation-issues-for-3.10.patch ++Patch1021: cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch ++Patch1022: cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch ++Patch1023: CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch ++Patch1024: cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch ++Patch1025: US101216-IMA-support-in-Titanium-kernel.patch ++Patch1026: US103091-IMA-System-Configuration.patch ++Patch1027: timer-Reduce-timer-migration-overhead-if-disabled.patch ++Patch1028: timer-Minimize-nohz-off-overhead.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -795,9 +782,6 @@ cp $RPM_SOURCE_DIR/kernel-%{version}-*.config.tis_extra . + cp %{SOURCE38} . + + ## Apply Patches here +-ApplyPatch debrand-single-cpu.patch +-ApplyPatch debrand-rh_taint.patch +-ApplyPatch debrand-rh-i686-cpu.patch + ApplyPatch linux-kernel-test.patch + ApplyPatch debrand-single-cpu.patch + ApplyPatch debrand-rh_taint.patch +@@ -818,26 +802,16 @@ ApplyPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + ApplyPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + ApplyPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + ApplyPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch +-ApplyPatch mm-larger-stack-guard-gap-between-vmas.patch +-ApplyPatch mm-fix-new-crash-in-unmapped_area_topdown.patch +-ApplyPatch Allow-stack-to-grow-up-to-address-space-limit.patch +-ApplyPatch kernfs-porting-original-3.15-version.patch +-ApplyPatch kernfs-fixing-compilation-issues-on-3.10.patch +-ApplyPatch cacheinfo-porting-original-4.10.17-version.patch +-ApplyPatch cacheinfo-fixing-compilation-issues-on-3.10.patch +-ApplyPatch intel-rdt-porting-original-4.10.17-version.patch +-ApplyPatch intel-rdt-fixing-compilation-issues-on-3.10.patch +-ApplyPatch stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch +-ApplyPatch add-per-cpu-pm-qos-resume-latency-consideration.patch +-ApplyPatch expose-pm_qos_resume_latency-for-cpus.patch +-ApplyPatch avoid-taking-spinlock-for-accessing-qos-values.patch +-ApplyPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch +-ApplyPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch +-ApplyPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch ++ApplyPatch Porting-Cacheinfo-from-Kernel-4.10.17.patch ++ApplyPatch Fix-cacheinfo-compilation-issues-for-3.10.patch ++ApplyPatch cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch ++ApplyPatch cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch ++ApplyPatch CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch ++ApplyPatch cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch + ApplyPatch US101216-IMA-support-in-Titanium-kernel.patch +-ApplyPatch timer-reduce-timer-migration-overhead-if-disabled.patch +-ApplyPatch timer-minimize-nohz-off-overhead.patch + ApplyPatch US103091-IMA-System-Configuration.patch ++ApplyPatch timer-Reduce-timer-migration-overhead-if-disabled.patch ++ApplyPatch timer-Minimize-nohz-off-overhead.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Correct-the-source-tarball-name.patch b/kernel-rt/centos/meta_patches/Correct-the-source-tarball-name.patch new file mode 100644 index 000000000..b19c7c930 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Correct-the-source-tarball-name.patch @@ -0,0 +1,29 @@ +From 337cc13e27df929f2f6cd9dac68057ac08649534 Mon Sep 17 00:00:00 2001 +Message-Id: <337cc13e27df929f2f6cd9dac68057ac08649534.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 11/29] Correct the source tarball name + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 7ab7c45..5d1308b 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -334,7 +334,7 @@ BuildRequires: rpm-build >= 4.9.0-1, elfutils >= 0.153-1 + %define debuginfo_args --strict-build-id -r + %endif + +-Source0: %{name}-%{rpmversion}-%{pkg_release_simple}.tar.xz ++Source0: %{name}-%{rpmversion}-%{rhel_build}.%{rttag}.%{rtbuild}%{?buildid}%{?dist}.tar.xz + + Source10: sign-modules + %define modsign_cmd %{SOURCE10} +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Disable-debug.patch b/kernel-rt/centos/meta_patches/Disable-debug.patch new file mode 100644 index 000000000..2c72dc977 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Disable-debug.patch @@ -0,0 +1,131 @@ +From 8ef6f25a8c785433a91cf4abd53a1e7f013598fc Mon Sep 17 00:00:00 2001 +Message-Id: <8ef6f25a8c785433a91cf4abd53a1e7f013598fc.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 04/29] Disable debug + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 29 ++++++++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index dd642c1..0964ca4 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -31,13 +31,13 @@ Summary: The Linux Realtime kernel + # Likewise a bcond_with implies the variable is off by default (turned on by --with) + %bcond_without rt + %bcond_without doc +-%bcond_without debug +-%bcond_with headers ++%bcond_with debug ++%bcond_without headers + %bcond_with vanilla + %bcond_with trace + %bcond_with perf + %bcond_with firmware +-%bcond_without debuginfo ++%bcond_with debuginfo + + # What parts do we want to build? We must build at least one kernel. + # These are the kernels that are built IF the architecture allows it. +@@ -410,6 +410,7 @@ Summary: Header files for the Linux kernel for use by glibc + Group: Development/System + Obsoletes: glibc-kernheaders < 3.0-46 + Provides: glibc-kernheaders = 3.0-46 ++Provides: kernel-headers + %description headers + Kernel-headers includes the C header files that specify the interface + between the Linux kernel and userspace libraries and programs. The +@@ -469,6 +470,7 @@ AutoReq: no\ + This package provides KVM modules for package %{name}%{?1:-%{1}}.\ + %{nil} + ++%if %{builddebuginfo} + # + # This macro creates a kernel-rt--kvm-debuginfo package. + # %%kernel_kvm_debuginfo_package +@@ -484,7 +486,9 @@ This package provides debug information for package %{name}%{?1:-%{1}}.\ + This is required to use SystemTap with %{name}%{?1:%{1}}-%{KVERREL}.\ + %{expand:%%global debuginfo_args %{?debuginfo_args} -p '/.*/%%{KVERREL}%{?1:\.%{1}}/.*|/.*%%{KVERREL}%{?1:\.%{1}}(\.debug)?' -o debuginfo%{?1}-kvm.list}\ + %{nil} ++%endif + ++%if %{builddebuginfo} + # + # This macro creates a kernel--debuginfo package. + # %%kernel_debuginfo_package +@@ -501,6 +505,7 @@ This package provides debug information for package %{name}%{?1:-%{1}}.\ + This is required to use SystemTap with %{name}%{?1:%{1}}-%{KVERREL}.\ + %{expand:%%global debuginfo_args %{?debuginfo_args} -p '/.*/%%{KVERREL}%{?1:\.%{1}}/.*|/.*%%{KVERREL}%{?1:\.%{1}}(\.debug)?' -o debuginfo%{?1}.list}\ + %{nil} ++%endif + + # + # This macro creates a kernel--devel package. +@@ -514,6 +519,7 @@ Provides: installonlypkg(kernel-rt-devel) = %{version}-%{release}%{?1:.%{1}}\ + Provides: kernel-rt%{?1:-%{1}}-devel-%{_target_cpu} = %{version}-%{release}\ + Provides: kernel-rt-devel-%{_target_cpu} = %{version}-%{release}%{?1:.%{1}}\ + Provides: kernel-rt-devel-uname-r = %{KVERREL}%{?1:.%{1}}\ ++Provides: kernel-devel = %{version}-%{release}%{?1:.%{1}}\ + AutoReqProv: no\ + Requires(pre): /usr/bin/find\ + %description -n kernel-rt%{?variant}%{?1:-%{1}}-devel\ +@@ -526,6 +532,7 @@ against the %{?2:%{2} }kernel package.\ + # %%define variant_summary The Linux kernel compiled for + # %%kernel_variant_package [-n ] + # ++%if %{builddebuginfo} + %define kernel_variant_package(n:) \ + %package %1\ + Summary: %{variant_summary}\ +@@ -536,15 +543,29 @@ Group: System Environment/Kernel\ + %{expand:%%kernel_kvm_package %1}\ + %{expand:%%kernel_kvm_debuginfo_package %1}\ + %{nil} ++%else ++%define kernel_variant_package(n:) \ ++%package %1\ ++Summary: %{variant_summary}\ ++Group: System Environment/Kernel\ ++%kernel_reqprovconf\ ++%{expand:%%kernel_devel_package %1 %{!?-n:%1}%{?-n:%{-n*}}}\ ++%{expand:%%kernel_kvm_package %1}\ ++%{nil} ++%endif + + + # First the auxiliary packages of the main kernel package. + %kernel_devel_package ++%if %{builddebuginfo} + %kernel_debuginfo_package ++%endif + + # create the production kvm module package + %kernel_kvm_package ++%if %{builddebuginfo} + %kernel_kvm_debuginfo_package ++%endif + + # Now, each variant package. + +@@ -1425,11 +1446,13 @@ fi + /lib/modules/%{KVERREL}%{?2:.%{2}}/modules.kvm\ + /lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/arch/x86/kvm\ + /lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/drivers/gpu/drm/i915/gvt\ ++%if %{builddebuginfo}\ + %{expand:%%files %{?2:%{2}-}kvm-debuginfo}\ + %dir %{debuginfodir}/lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/arch/x86/kvm\ + %{debuginfodir}/lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/arch/x86/kvm\ + %{debuginfodir}/lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/drivers/gpu/drm/i915/gvt\ + %endif\ ++%endif\ + %{nil} + + %kernel_variant_files %{buildrt} +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch b/kernel-rt/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch new file mode 100644 index 000000000..98807097e --- /dev/null +++ b/kernel-rt/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch @@ -0,0 +1,36 @@ +From 229ce04fde143e5b0e22d89dba36e2ab5f7a0274 Mon Sep 17 00:00:00 2001 +Message-Id: <229ce04fde143e5b0e22d89dba36e2ab5f7a0274.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:13 -0400 +Subject: [PATCH 17/29] Enable building kernel with CONFIG_BLK_DEV_NBD + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index a613703..d5216f4 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -409,6 +409,7 @@ Patch1011: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + Patch1012: x86-enable-DMA-CMA-with-swiotlb.patch + Patch1013: Add-missing-ifdef-around-max-latency-variable.patch + Patch1014: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch ++Patch1015: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -786,6 +787,7 @@ ApplyPatch Notification-of-death-of-arbitrary-processes.patch + ApplyPatch x86-enable-DMA-CMA-with-swiotlb.patch + ApplyPatch Add-missing-ifdef-around-max-latency-variable.patch + ApplyPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch ++ApplyPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Enable-symvers.patch b/kernel-rt/centos/meta_patches/Enable-symvers.patch new file mode 100644 index 000000000..f67372401 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Enable-symvers.patch @@ -0,0 +1,44 @@ +From 3423b1e7966868a7de8baa2ceedfa8b93f5420d5 Mon Sep 17 00:00:00 2001 +Message-Id: <3423b1e7966868a7de8baa2ceedfa8b93f5420d5.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 06/29] Enable symvers + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 0b91d79..c35efae 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -997,6 +997,15 @@ BuildKernel() { + # copy Module.symvers + cp Module.symvers $RPM_BUILD_ROOT/$DevelDir + ++ # create the kABI metadata for use in packaging ++ # NOTENOTE: the name symvers is used by the rpm backend ++ # NOTENOTE: to discover and run the /usr/lib/rpm/fileattrs/kabi.attr ++ # NOTENOTE: script which dynamically adds exported kernel symbol ++ # NOTENOTE: checksums to the rpm metadata provides list. ++ # NOTENOTE: if you change the symvers name, update the backend too ++ echo "**** GENERATING kernel ABI metadata ****" ++ gzip -c9 < Module.symvers > $RPM_BUILD_ROOT/boot/symvers-$KernelVer.gz ++ + # prune junk from kernel-devel + find $RPM_BUILD_ROOT/usr/src/kernels -name ".*.cmd" -exec rm -f {} \; + } +@@ -1397,6 +1406,7 @@ fi + /%{image_install_path}/%{?-k:%{-k*}}%{!?-k:vmlinuz}-%{KVERREL}%{?2:.%{2}}\ + /%{image_install_path}/.vmlinuz-%{KVERREL}%{?2:.%{2}}.hmac\ + /boot/System.map-%{KVERREL}%{?2:.%{2}}\ ++/boot/symvers-%{KVERREL}%{?2:.%{2}}.gz\ + /boot/config-%{KVERREL}%{?2:.%{2}}\ + %exclude /lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/arch/x86/kvm\ + %exclude /lib/modules/%{KVERREL}%{?2:.%{2}}/kernel/drivers/gpu/drm/i915/gvt\ +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Exclude-package-defs-for-unbuilt-firmware-and-doc-pk.patch b/kernel-rt/centos/meta_patches/Exclude-package-defs-for-unbuilt-firmware-and-doc-pk.patch new file mode 100644 index 000000000..b02f5deb7 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Exclude-package-defs-for-unbuilt-firmware-and-doc-pk.patch @@ -0,0 +1,53 @@ +From 2e1c32f4c2d4d7e6afa769886a220c471fa73b98 Mon Sep 17 00:00:00 2001 +Message-Id: <2e1c32f4c2d4d7e6afa769886a220c471fa73b98.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 05/29] Exclude package defs for unbuilt firmware and doc pkg + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 0964ca4..0b91d79 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -392,6 +392,7 @@ This kernel has been compiled with the RT patch applied and is intended + for use in deterministic response-time situations + + ++%if %{builddoc} + %package doc + Summary: Various documentation bits found in the kernel source + Group: Documentation +@@ -403,7 +404,7 @@ device drivers shipped with it are documented in these files. + + You will want to install this package if you need a reference to the + options that can be passed to Linux kernel modules at load time. +- ++%endif + + %package headers + Summary: Header files for the Linux kernel for use by glibc +@@ -418,6 +419,7 @@ header files define structures and constants that are needed for + building most standard programs and are also needed for rebuilding the + glibc package. + ++%if %{buildfirmware} + %package firmware + Summary: Firmware files used by the Linux kernel + Group: Development/System +@@ -429,6 +431,7 @@ Provides: kernel-rt-firmware = %{rpmversion}-%{pkg_release} + %description firmware + Kernel-firmware includes firmware files required for some devices to + operate. ++%endif + + %if %{builddebuginfo} + %package debuginfo-common-%{_target_cpu} +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch b/kernel-rt/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch new file mode 100644 index 000000000..a416104ae --- /dev/null +++ b/kernel-rt/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch @@ -0,0 +1,39 @@ +From 0b645d407391f0791df1d77596f09f9a41795775 Mon Sep 17 00:00:00 2001 +Message-Id: <0b645d407391f0791df1d77596f09f9a41795775.1510335500.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Thu, 9 Nov 2017 15:53:41 -0500 +Subject: [PATCH 1/1] Fix compile warnings in scsi drivers + +They get turned into errors and thus break the build. + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 779f3ce..c8c7f22 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -419,6 +419,9 @@ Patch1025: US101216-IMA-support-in-Titanium-kernel.patch + Patch1026: US103091-IMA-System-Configuration.patch + Patch1027: timer-Reduce-timer-migration-overhead-if-disabled.patch + Patch1028: timer-Minimize-nohz-off-overhead.patch ++# Fix compile warnings that break the build ++Patch1029: aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch ++Patch1030: dpt_i2o-fix-build-warning.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -810,6 +813,8 @@ ApplyPatch US101216-IMA-support-in-Titanium-kernel.patch + ApplyPatch US103091-IMA-System-Configuration.patch + ApplyPatch timer-Reduce-timer-migration-overhead-if-disabled.patch + ApplyPatch timer-Minimize-nohz-off-overhead.patch ++ApplyPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch ++ApplyPatch dpt_i2o-fix-build-warning.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Fix-stack-clash.patch b/kernel-rt/centos/meta_patches/Fix-stack-clash.patch new file mode 100644 index 000000000..1503141e8 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Fix-stack-clash.patch @@ -0,0 +1,51 @@ +From 399ce0dc1ad71eefe6d61f3e9370829103316487 Mon Sep 17 00:00:00 2001 +Message-Id: <399ce0dc1ad71eefe6d61f3e9370829103316487.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 18 Jul 2017 15:52:25 -0400 +Subject: [PATCH 20/29] Fix stack clash + +Consists of 3 patches taken from the linux-3.10.y branch of the +linux-stable tree. + +The first (main) patch applied fairly cleanly with offsets, +requiring a small amount of wiggle and a bit of manual work +due to some affected code residing in mm/gup.c . +The other 2 patches applied cleanly. + +This fix here is only temporary and won't be needed once we +move to a newer released CentOS kernel that includes it. + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 93dee4e..8458a68 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -413,6 +413,9 @@ Patch1015: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + Patch1016: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + Patch1017: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + Patch1018: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch ++Patch1019: mm-larger-stack-guard-gap-between-vmas.patch ++Patch1020: mm-fix-new-crash-in-unmapped_area_topdown.patch ++Patch1021: Allow-stack-to-grow-up-to-address-space-limit.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -794,6 +797,9 @@ ApplyPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + ApplyPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + ApplyPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + ApplyPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch ++ApplyPatch mm-larger-stack-guard-gap-between-vmas.patch ++ApplyPatch mm-fix-new-crash-in-unmapped_area_topdown.patch ++ApplyPatch Allow-stack-to-grow-up-to-address-space-limit.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/PATCH_ORDER b/kernel-rt/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..6b2dded99 --- /dev/null +++ b/kernel-rt/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,37 @@ +tis-debrand-and-add-centos-certificate.patch +tis-remove-trace.patch +Update-package-versioning-for-TIS-format.patch +Disable-debug.patch +Exclude-package-defs-for-unbuilt-firmware-and-doc-pk.patch +Enable-symvers.patch +tis-remove-signing.patch +tis-apply-patches.patch +tis-handle-tis-config-customizations.patch +tis-add-tools.patch +Correct-the-source-tarball-name.patch +Rework-pkg-release-naming.patch +lose-the-memblock-reorder-parms-patch.patch +Add-patch-for-missing-ifdef-in-tracing.patch +tis-build-unsigned-package.patch +enable-building-mpt2sas-mpt3sas-as-builtin.patch +Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch +x86-dma_alloc_coherent-fix.patch +rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch +Fix-stack-clash.patch +Porting-Kernfs-from-Kernel-3.10.patch +Porting-Cacheinfo-from-Kernel-4.10.17.patch +Porting-Resource-Director-Technology-from-Kernel-4.1.patch +PM-introduce-per-cpu-power-management.patch +Check-for-oversized-nfs-arguments.patch +Stricter-decoding-of-NFS-ops.patch +meta-patch-for-Kernel-IMA-changes.patch +fix-high-latency-reported-by-cyclictest.patch +meta-patch-for-Kernel-IMA-keyring-changes.patch +Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch +Change-name-of-source-tarball-drop-el7.patch +Update-package-versioning-for-TIS-format-revised.patch +Fix-compile-warnings-in-scsi-drivers.patch +Resolve-hard-lockup-in-get_kvmclock_ns.patch +export-module-signing-key-in-kernel-devel.patch +CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch +fix-drbd-by-turning-off-write-same-in-smartpqi.patch diff --git a/kernel-rt/centos/meta_patches/PM-introduce-per-cpu-power-management.patch b/kernel-rt/centos/meta_patches/PM-introduce-per-cpu-power-management.patch new file mode 100644 index 000000000..97e1daaf5 --- /dev/null +++ b/kernel-rt/centos/meta_patches/PM-introduce-per-cpu-power-management.patch @@ -0,0 +1,47 @@ +From 7e79e79077bb451c8b28479d807b8b1d7e9e38da Mon Sep 17 00:00:00 2001 +Message-Id: <7e79e79077bb451c8b28479d807b8b1d7e9e38da.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Thu, 17 Aug 2017 12:37:41 -0400 +Subject: [PATCH 24/29] PM: introduce per-cpu power management + +Cherry-picking 4 commits from the 4.11 branch of the linux-stable tree. +All of the patches require small amount of work to apply to TiC kernel. +Fixes are temporary until we switch to CentOS kernel that includes them. + +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 7e3d65e..dc30da0 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -422,6 +422,10 @@ Patch1024: cacheinfo-porting-original-4.10.17-version.patch + Patch1025: cacheinfo-fixing-compilation-issues-on-3.10.patch + Patch1026: intel-rdt-porting-original-4.10.17-version.patch + Patch1027: intel-rdt-fixing-compilation-issues-on-3.10.patch ++Patch1028: stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch ++Patch1029: add-per-cpu-pm-qos-resume-latency-consideration.patch ++Patch1030: expose-pm_qos_resume_latency-for-cpus.patch ++Patch1031: avoid-taking-spinlock-for-accessing-qos-values.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -812,6 +816,10 @@ ApplyPatch cacheinfo-porting-original-4.10.17-version.patch + ApplyPatch cacheinfo-fixing-compilation-issues-on-3.10.patch + ApplyPatch intel-rdt-porting-original-4.10.17-version.patch + ApplyPatch intel-rdt-fixing-compilation-issues-on-3.10.patch ++ApplyPatch stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch ++ApplyPatch add-per-cpu-pm-qos-resume-latency-consideration.patch ++ApplyPatch expose-pm_qos_resume_latency-for-cpus.patch ++ApplyPatch avoid-taking-spinlock-for-accessing-qos-values.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch b/kernel-rt/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch new file mode 100644 index 000000000..f1132b62e --- /dev/null +++ b/kernel-rt/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch @@ -0,0 +1,38 @@ +From 9e609250e651cd45d637588106c7c9b907daa1ce Mon Sep 17 00:00:00 2001 +Message-Id: <9e609250e651cd45d637588106c7c9b907daa1ce.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Fri, 21 Jul 2017 11:00:10 -0500 +Subject: [PATCH 22/29] Porting Cacheinfo from Kernel 4.10.17 + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index c86ac43..b6a53d5 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -418,6 +418,8 @@ Patch1020: mm-fix-new-crash-in-unmapped_area_topdown.patch + Patch1021: Allow-stack-to-grow-up-to-address-space-limit.patch + Patch1022: kernfs-porting-original-3.15-version.patch + Patch1023: kernfs-fixing-compilation-issues-on-3.10.patch ++Patch1024: cacheinfo-porting-original-4.10.17-version.patch ++Patch1025: cacheinfo-fixing-compilation-issues-on-3.10.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -804,6 +806,8 @@ ApplyPatch mm-fix-new-crash-in-unmapped_area_topdown.patch + ApplyPatch Allow-stack-to-grow-up-to-address-space-limit.patch + ApplyPatch kernfs-porting-original-3.15-version.patch + ApplyPatch kernfs-fixing-compilation-issues-on-3.10.patch ++ApplyPatch cacheinfo-porting-original-4.10.17-version.patch ++ApplyPatch cacheinfo-fixing-compilation-issues-on-3.10.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Porting-Kernfs-from-Kernel-3.10.patch b/kernel-rt/centos/meta_patches/Porting-Kernfs-from-Kernel-3.10.patch new file mode 100644 index 000000000..70935579a --- /dev/null +++ b/kernel-rt/centos/meta_patches/Porting-Kernfs-from-Kernel-3.10.patch @@ -0,0 +1,38 @@ +From 5a14d31ab88067d1d4acd6ef5fa80f53778d281b Mon Sep 17 00:00:00 2001 +Message-Id: <5a14d31ab88067d1d4acd6ef5fa80f53778d281b.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Thu, 20 Jul 2017 15:14:39 -0500 +Subject: [PATCH 21/29] Porting Kernfs from Kernel 3.10 + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 8458a68..c86ac43 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -416,6 +416,8 @@ Patch1018: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + Patch1019: mm-larger-stack-guard-gap-between-vmas.patch + Patch1020: mm-fix-new-crash-in-unmapped_area_topdown.patch + Patch1021: Allow-stack-to-grow-up-to-address-space-limit.patch ++Patch1022: kernfs-porting-original-3.15-version.patch ++Patch1023: kernfs-fixing-compilation-issues-on-3.10.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -800,6 +802,8 @@ ApplyPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + ApplyPatch mm-larger-stack-guard-gap-between-vmas.patch + ApplyPatch mm-fix-new-crash-in-unmapped_area_topdown.patch + ApplyPatch Allow-stack-to-grow-up-to-address-space-limit.patch ++ApplyPatch kernfs-porting-original-3.15-version.patch ++ApplyPatch kernfs-fixing-compilation-issues-on-3.10.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch b/kernel-rt/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch new file mode 100644 index 000000000..bf90e3014 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch @@ -0,0 +1,39 @@ +From c11c340ff04dd65eefb834770f910cd63d727a4d Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Mon, 24 Jul 2017 15:49:37 -0500 +Subject: [PATCH 23/29] Porting Resource Director Technology from Kernel + 4.10.17 + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index b6a53d5..7e3d65e 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -420,6 +420,8 @@ Patch1022: kernfs-porting-original-3.15-version.patch + Patch1023: kernfs-fixing-compilation-issues-on-3.10.patch + Patch1024: cacheinfo-porting-original-4.10.17-version.patch + Patch1025: cacheinfo-fixing-compilation-issues-on-3.10.patch ++Patch1026: intel-rdt-porting-original-4.10.17-version.patch ++Patch1027: intel-rdt-fixing-compilation-issues-on-3.10.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -808,6 +810,8 @@ ApplyPatch kernfs-porting-original-3.15-version.patch + ApplyPatch kernfs-fixing-compilation-issues-on-3.10.patch + ApplyPatch cacheinfo-porting-original-4.10.17-version.patch + ApplyPatch cacheinfo-fixing-compilation-issues-on-3.10.patch ++ApplyPatch intel-rdt-porting-original-4.10.17-version.patch ++ApplyPatch intel-rdt-fixing-compilation-issues-on-3.10.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch b/kernel-rt/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch new file mode 100644 index 000000000..79a03b792 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch @@ -0,0 +1,32 @@ +From 8db6891fed197e4b4247b624a0079a60bbfdf3f9 Mon Sep 17 00:00:00 2001 +From: Alex Kozyrev +Date: Thu, 16 Nov 2017 11:36:56 -0500 +Subject: [PATCH 1/1] Resolve hard lockup in get_kvmclock_ns + +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index c8c7f22..7240f97 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -422,6 +422,7 @@ Patch1028: timer-Minimize-nohz-off-overhead.patch + # Fix compile warnings that break the build + Patch1029: aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + Patch1030: dpt_i2o-fix-build-warning.patch ++Patch1031: KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -815,6 +816,7 @@ ApplyPatch timer-Reduce-timer-migration-overhead-if-disabled.patch + ApplyPatch timer-Minimize-nohz-off-overhead.patch + ApplyPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + ApplyPatch dpt_i2o-fix-build-warning.patch ++ApplyPatch KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Rework-pkg-release-naming.patch b/kernel-rt/centos/meta_patches/Rework-pkg-release-naming.patch new file mode 100644 index 000000000..fcde0dd7f --- /dev/null +++ b/kernel-rt/centos/meta_patches/Rework-pkg-release-naming.patch @@ -0,0 +1,38 @@ +From 165b8ea199b36e04d35f515a6b1482ea5ce51ae5 Mon Sep 17 00:00:00 2001 +Message-Id: <165b8ea199b36e04d35f515a6b1482ea5ce51ae5.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 12/29] Rework pkg release naming + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 5d1308b..afd1ca3 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -102,7 +102,7 @@ Summary: The Linux Realtime kernel + %global with_sparse %{?_with_sparse: 1} %{?!_with_sparse: 0} + + %global pkg_release_simple %{rhel_build}.%{rttag}.%{rtbuild} +-%global pkg_release %{rhel_build}.%{rttag}.%{rtbuild}%{?buildid}%{?dist} ++%global pkg_release %{pkg_release_simple}%{?buildid}%{?dist} + + %global KVERREL %{rpmversion}-%{pkg_release}.%{_target_cpu} + +@@ -334,7 +334,7 @@ BuildRequires: rpm-build >= 4.9.0-1, elfutils >= 0.153-1 + %define debuginfo_args --strict-build-id -r + %endif + +-Source0: %{name}-%{rpmversion}-%{rhel_build}.%{rttag}.%{rtbuild}%{?buildid}%{?dist}.tar.xz ++Source0: %{name}-%{rpmversion}-%{pkg_release_simple}%{?dist}.tar.xz + + Source10: sign-modules + %define modsign_cmd %{SOURCE10} +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch b/kernel-rt/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch new file mode 100644 index 000000000..b9b40fc52 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch @@ -0,0 +1,38 @@ +From acd5a71f8758b872a8741f08be4ca0e99fefa268 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 22 Aug 2017 17:30:01 -0400 +Subject: [PATCH 26/29] Stricter decoding of NFS ops + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index e53f906..f831609 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -427,6 +427,8 @@ Patch1029: add-per-cpu-pm-qos-resume-latency-consideration.patch + Patch1030: expose-pm_qos_resume_latency-for-cpus.patch + Patch1031: avoid-taking-spinlock-for-accessing-qos-values.patch + Patch1032: nfsd-check-for-oversized-NFSv2-v3-arguments.patch ++Patch1033: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch ++Patch1034: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -822,6 +824,8 @@ ApplyPatch add-per-cpu-pm-qos-resume-latency-consideration.patch + ApplyPatch expose-pm_qos_resume_latency-for-cpus.patch + ApplyPatch avoid-taking-spinlock-for-accessing-qos-values.patch + ApplyPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch ++ApplyPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch ++ApplyPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format-revised.patch b/kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format-revised.patch new file mode 100644 index 000000000..161565162 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format-revised.patch @@ -0,0 +1,35 @@ +From f4d36cf99a55bae14d6a3590a9d8bdd5f29ee4f9 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Tue, 24 Oct 2017 22:15:44 -0400 +Subject: [PATCH] foo + +--- + SPECS/kernel-rt.spec | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index b4a9826..cb56b2d 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -4,9 +4,7 @@ + Summary: The Linux Realtime kernel + + # catch building on Fedora +-%if "%{?dist}" == "" || "0%{?fedora}" != "0" + %global dist .el7 +-%endif + + # realtimeN + %global rtbuild 623 +@@ -102,7 +100,7 @@ Summary: The Linux Realtime kernel + %global with_sparse %{?_with_sparse: 1} %{?!_with_sparse: 0} + + %global pkg_release_simple %{rhel_build}.%{rttag}.%{rtbuild} +-%global pkg_release %{pkg_release_simple}%{?buildid}%{?dist} ++%global pkg_release %{pkg_release_simple}%{?dist}%{?buildid} + + %global KVERREL %{rpmversion}-%{pkg_release}.%{_target_cpu} + +-- +1.9.1 + diff --git a/kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format.patch b/kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..85b111d17 --- /dev/null +++ b/kernel-rt/centos/meta_patches/Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,28 @@ +From b485ba56b70bc19f5cf223c31402d7b723b7e9a6 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 03/29] Update package versioning for TIS format + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index ffbdbff..dd642c1 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -19,6 +19,7 @@ Summary: The Linux Realtime kernel + + # The Build ID + # %%define buildid .local ++%define buildid .tis.%{tis_patch_ver} + + # For a kernel released for public testing, released_kernel should be 1. + # For internal testing builds during development, it should be 0. +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch b/kernel-rt/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch new file mode 100644 index 000000000..3cf4934b5 --- /dev/null +++ b/kernel-rt/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch @@ -0,0 +1,36 @@ +From 072f3b48d291c020d6d7ce4cb6396316932a08e5 Mon Sep 17 00:00:00 2001 +Message-Id: <072f3b48d291c020d6d7ce4cb6396316932a08e5.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:13 -0400 +Subject: [PATCH 16/29] enable building mpt2sas mpt3sas as builtin + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index cd127ac..a613703 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -408,6 +408,7 @@ Patch1010: Notification-of-death-of-arbitrary-processes.patch + Patch1011: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + Patch1012: x86-enable-DMA-CMA-with-swiotlb.patch + Patch1013: Add-missing-ifdef-around-max-latency-variable.patch ++Patch1014: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -784,6 +785,7 @@ ApplyPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + ApplyPatch Notification-of-death-of-arbitrary-processes.patch + ApplyPatch x86-enable-DMA-CMA-with-swiotlb.patch + ApplyPatch Add-missing-ifdef-around-max-latency-variable.patch ++ApplyPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch b/kernel-rt/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch new file mode 100644 index 000000000..9bfd618d2 --- /dev/null +++ b/kernel-rt/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch @@ -0,0 +1,29 @@ +From bea6513a83c05acdd4d5947b43f34e499923130e Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 12 Jan 2018 11:44:29 -0500 +Subject: [PATCH] export module signing key in kernel devel + +--- + SPECS/kernel-rt.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 298ce17..4935d51 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -1131,6 +1131,12 @@ BuildKernel() { + cp signing_key.priv signing_key.priv.sign${Flavour:+.${Flavour}} + cp signing_key.x509 signing_key.x509.sign${Flavour:+.${Flavour}} + ++ # WRS: Copy these keys as part of the devel package ++ # The Module signing keys are to ensure that only Out-of-tree ++ # built against the Titanium Kernel get signed and loaded sans warnings ++ cp signing_key.priv ${RPM_BUILD_ROOT}/lib/modules/${KernelVer}/build/ ++ cp signing_key.x509 ${RPM_BUILD_ROOT}/lib/modules/${KernelVer}/build/ ++ + # remove files that will be auto generated by depmod at rpm -i time + for i in alias alias.bin builtin.bin ccwmap dep dep.bin ieee1394map inputmap isapnpmap ofmap pcimap seriomap symbols symbols.bin usbmap softdep devname + do +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch b/kernel-rt/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch new file mode 100644 index 000000000..e4ade8d1f --- /dev/null +++ b/kernel-rt/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch @@ -0,0 +1,35 @@ +From 69fe6756d51b21e909f228042ca301e88f0ef184 Mon Sep 17 00:00:00 2001 +Message-Id: <69fe6756d51b21e909f228042ca301e88f0ef184.1520371020.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 6 Mar 2018 16:16:54 -0500 +Subject: [PATCH 1/1] fix drbd by turning off write same in smartpqi + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index a56e051..bd5d93f 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -425,6 +425,8 @@ Patch1030: dpt_i2o-fix-build-warning.patch + Patch1031: KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + # CVE-2017-11176: kernel: Use-after-free in sys_mq_notify() + Patch1032: mqueue-fix-a-use-after-free-in-sys_mq_notify.patch ++# DRBD was choking on write same ++Patch1033: turn-off-write-same-in-smartqpi-driver.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -820,6 +822,7 @@ ApplyPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + ApplyPatch dpt_i2o-fix-build-warning.patch + ApplyPatch KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + ApplyPatch mqueue-fix-a-use-after-free-in-sys_mq_notify.patch ++ApplyPatch turn-off-write-same-in-smartqpi-driver.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/fix-high-latency-reported-by-cyclictest.patch b/kernel-rt/centos/meta_patches/fix-high-latency-reported-by-cyclictest.patch new file mode 100644 index 000000000..bafa1b339 --- /dev/null +++ b/kernel-rt/centos/meta_patches/fix-high-latency-reported-by-cyclictest.patch @@ -0,0 +1,49 @@ +From 78376ed0fad7d6ea82975693642445b69d4c2011 Mon Sep 17 00:00:00 2001 +Message-Id: <78376ed0fad7d6ea82975693642445b69d4c2011.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Mon, 11 Sep 2017 17:05:22 -0400 +Subject: [PATCH 28/29] fix high latency reported by cyclictest + +CGTS-7179 reported cyclictest latency spikes on low-latency compute profile. +The issue was injected into TC during kernel rebase to 3.10.0-514.16.1.el7. +Latency has been hurt by addition of the timer_migration sysctl. +To cure the issue we need to port back two patches from latest stable kernel: +bc7a34b8b9ebfb0f4b8a35a72a0b134fd6c5ef50 +timer: Reduce timer migration overhead if disabled +683be13a284720205228e29207ef11a1c3c322b9 +timer: Minimize nohz off overhead +Little modification were required to apply these patches nicely. + +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 2eb90d7..f4987fb 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -430,6 +430,8 @@ Patch1032: nfsd-check-for-oversized-NFSv2-v3-arguments.patch + Patch1033: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + Patch1034: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + Patch1035: US101216-IMA-support-in-Titanium-kernel.patch ++Patch1036: timer-reduce-timer-migration-overhead-if-disabled.patch ++Patch1037: timer-minimize-nohz-off-overhead.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -828,6 +830,8 @@ ApplyPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch + ApplyPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + ApplyPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + ApplyPatch US101216-IMA-support-in-Titanium-kernel.patch ++ApplyPatch timer-reduce-timer-migration-overhead-if-disabled.patch ++ApplyPatch timer-minimize-nohz-off-overhead.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/lose-the-memblock-reorder-parms-patch.patch b/kernel-rt/centos/meta_patches/lose-the-memblock-reorder-parms-patch.patch new file mode 100644 index 000000000..3051c5bc9 --- /dev/null +++ b/kernel-rt/centos/meta_patches/lose-the-memblock-reorder-parms-patch.patch @@ -0,0 +1,42 @@ +From b1d0bf9cd7913823157a680e39161c8f02b252c2 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 13/29] lose the memblock reorder parms patch + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index afd1ca3..d11d8fe 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -404,10 +404,9 @@ Patch1006: cma-add-placement-specifier-for-cma-kernel-parameter.patch + Patch1007: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + Patch1008: Make-kernel-start-eth-devices-at-offset.patch + Patch1009: memblock-introduce-memblock_alloc_range.patch +-Patch1010: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch +-Patch1011: Notification-of-death-of-arbitrary-processes.patch +-Patch1012: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch +-Patch1013: x86-enable-DMA-CMA-with-swiotlb.patch ++Patch1010: Notification-of-death-of-arbitrary-processes.patch ++Patch1011: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++Patch1012: x86-enable-DMA-CMA-with-swiotlb.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -772,7 +771,6 @@ ApplyPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch + ApplyPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch + ApplyPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + ApplyPatch Make-kernel-start-eth-devices-at-offset.patch +-ApplyPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch + ApplyPatch memblock-introduce-memblock_alloc_range.patch + ApplyPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + ApplyPatch Notification-of-death-of-arbitrary-processes.patch +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch b/kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch new file mode 100644 index 000000000..dcf0054f2 --- /dev/null +++ b/kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch @@ -0,0 +1,36 @@ +From ac548283b0da3e13fe8dcdb1359aa3b8cfc92303 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Fri, 1 Sep 2017 14:24:02 -0400 +Subject: [PATCH 27/29] meta patch for Kernel IMA changes + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index f831609..2eb90d7 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -429,6 +429,7 @@ Patch1031: avoid-taking-spinlock-for-accessing-qos-values.patch + Patch1032: nfsd-check-for-oversized-NFSv2-v3-arguments.patch + Patch1033: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + Patch1034: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch ++Patch1035: US101216-IMA-support-in-Titanium-kernel.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -826,6 +827,7 @@ ApplyPatch avoid-taking-spinlock-for-accessing-qos-values.patch + ApplyPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch + ApplyPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + ApplyPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch ++ApplyPatch US101216-IMA-support-in-Titanium-kernel.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch b/kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch new file mode 100644 index 000000000..6c59b7a6b --- /dev/null +++ b/kernel-rt/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch @@ -0,0 +1,54 @@ +From 1260d1d47badcb7ad62a999e4a9ef901fe68c30a Mon Sep 17 00:00:00 2001 +Message-Id: <1260d1d47badcb7ad62a999e4a9ef901fe68c30a.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Mon, 25 Sep 2017 17:30:33 -0400 +Subject: [PATCH 29/29] meta patch for Kernel IMA keyring changes + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index f4987fb..636a68e 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -360,6 +360,7 @@ Source27: sanity_check.py + Source29: extrakeys.pub + + Source37: centos.cer ++Source38: ima_signing_key.pub + %if %{?released_kernel} + %define pesign_name redhatsecureboot301 + %else +@@ -432,6 +433,7 @@ Patch1034: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + Patch1035: US101216-IMA-support-in-Titanium-kernel.patch + Patch1036: timer-reduce-timer-migration-overhead-if-disabled.patch + Patch1037: timer-minimize-nohz-off-overhead.patch ++Patch1038: US103091-IMA-System-Configuration.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -789,6 +791,9 @@ cd linux-%{kversion}.%{_target_cpu} + # Copy any TiS-specific config changes + cp $RPM_SOURCE_DIR/kernel-%{version}-*.config.tis_extra . + ++# Copy TiS specific IMA public key ++cp %{SOURCE38} . ++ + ## Apply Patches here + ApplyPatch debrand-single-cpu.patch + ApplyPatch debrand-rh_taint.patch +@@ -832,6 +837,7 @@ ApplyPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + ApplyPatch US101216-IMA-support-in-Titanium-kernel.patch + ApplyPatch timer-reduce-timer-migration-overhead-if-disabled.patch + ApplyPatch timer-minimize-nohz-off-overhead.patch ++ApplyPatch US103091-IMA-System-Configuration.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch b/kernel-rt/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch new file mode 100644 index 000000000..95d6e978a --- /dev/null +++ b/kernel-rt/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch @@ -0,0 +1,36 @@ +From a998c3291fe980792bffe65add5ab579fbfe5af3 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:13 -0400 +Subject: [PATCH 19/29] rcu Don't wake rcuc-X-kthreads on NOCB CPUs + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 3554ef3..93dee4e 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -412,6 +412,7 @@ Patch1014: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + Patch1015: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + Patch1016: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + Patch1017: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch ++Patch1018: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -792,6 +793,7 @@ ApplyPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + ApplyPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + ApplyPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + ApplyPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch ++ApplyPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-add-tools.patch b/kernel-rt/centos/meta_patches/tis-add-tools.patch new file mode 100644 index 000000000..61fc53f69 --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-add-tools.patch @@ -0,0 +1,241 @@ +From c6c5f512db8d2e06758333f17dec7960ab7e34d9 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 10/29] tis add tools + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 157 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index aff01a7..7ab7c45 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -42,6 +42,11 @@ Summary: The Linux Realtime kernel + %bcond_with perf + %bcond_with firmware + %bcond_with debuginfo ++%bcond_without tools ++ ++# Architectures we build tools/cpupower on ++%define cpupowerarchs x86_64 ppc64 ppc64le ++ + + # What parts do we want to build? We must build at least one kernel. + # These are the kernels that are built IF the architecture allows it. +@@ -305,6 +310,9 @@ BuildRequires: python-devel, newt-devel, perl(ExtUtils::Embed) + BuildRequires: pesign >= 0.109-4 + %endif + %endif ++%if %{with_tools} ++BuildRequires: pciutils-devel gettext ncurses-devel ++%endif + %if %{with_sparse} + BuildRequires: sparse >= 0.4.1 + %endif +@@ -362,6 +370,11 @@ Source37: centos.cer + Source50: kernel-%{version}-x86_64-rt.config + Source51: kernel-%{version}-x86_64-rt-trace.config + Source52: kernel-%{version}-x86_64-rt-debug.config ++ ++# Sources for kernel-rt-tools ++Source2000: cpupower.service ++Source2001: cpupower.config ++ + Source30000: kernel-3.10.0-x86_64-rt.config.tis_extra + Source30001: kernel-3.10.0-x86_64-rt-debug.config.tis_extra + Source30002: kernel-3.10.0-x86_64-rt-trace.config.tis_extra +@@ -641,6 +654,47 @@ It should only be installed when trying to gather additional information + on kernel bugs. + %endif + ++%if %{with_tools} ++ ++%package -n kernel-rt-tools ++Summary: Assortment of tools for the Linux kernel ++Group: Development/System ++License: GPLv2 ++Provides: cpupowerutils-rt = 1:009-0.6.p1 ++Obsoletes: cpupowerutils-rt < 1:009-0.6.p1 ++Provides: cpufreq-utils-rt = 1:009-0.6.p1 ++Provides: cpufrequtils-rt = 1:009-0.6.p1 ++Obsoletes: cpufreq-utils-rt < 1:009-0.6.p1 ++Obsoletes: cpufrequtils-rt < 1:009-0.6.p1 ++Obsoletes: cpuspeed-rt < 1:2.0 ++Requires: kernel-rt-tools-libs = %{version}-%{release} ++%description -n kernel-rt-tools ++This package contains the tools/ directory from the kernel source ++and the supporting documentation. ++ ++%package -n kernel-rt-tools-libs ++Summary: Libraries for the kernels-tools ++Group: Development/System ++License: GPLv2 ++%description -n kernel-rt-tools-libs ++This package contains the libraries built from the tools/ directory ++from the kernel source. ++ ++%package -n kernel-rt-tools-libs-devel ++Summary: Assortment of tools for the Linux kernel ++Group: Development/System ++License: GPLv2 ++Requires: kernel-rt-tools = %{version}-%{release} ++Provides: cpupowerutils-devel = 1:009-0.6.p1.1 ++Obsoletes: cpupowerutils-devel <= 1:009-0.6.p1 ++Requires: kernel-rt-tools-libs = %{version}-%{release} ++Provides: kernel-rt-tools-devel ++%description -n kernel-rt-tools-libs-devel ++This package contains the development files for the tools/ directory from ++the kernel source. ++ ++%endif # with_tools ++ + %prep + ## ApplyPatch routine + patch_command='patch -p1 -F1 -s' +@@ -1097,6 +1151,31 @@ BuildKernel %make_target %kernel_image vanilla + BuildKernel %make_target %kernel_image + %endif + ++%if %{with_tools} ++%ifarch %{cpupowerarchs} ++# cpupower ++# make sure version-gen.sh is executable. ++chmod +x tools/power/cpupower/utils/version-gen.sh ++make %{?cross_opts} %{?_smp_mflags} -C tools/power/cpupower CPUFREQ_BENCH=false ++%ifarch x86_64 ++ pushd tools/power/cpupower/debug/x86_64 ++ make %{?_smp_mflags} centrino-decode powernow-k8-decode ++ popd ++%endif ++%ifarch x86_64 ++ pushd tools/power/x86/x86_energy_perf_policy/ ++ make ++ popd ++ pushd tools/power/x86/turbostat ++ make ++ popd ++%endif #turbostat/x86_energy_perf_policy ++%endif ++pushd tools ++make tmon ++popd ++%endif ++ + %if %{builddoc} + # Make the HTML and man pages. + make -j1 htmldocs mandocs || %{doc_build_fail} +@@ -1229,7 +1308,6 @@ find Documentation/DocBook/man -name '*.9.gz' -print0 | + xargs -0 --no-run-if-empty %{__install} -m 444 -t $man9dir $m + ls $man9dir | grep -q '' || > $man9dir/BROKEN + %endif # builddoc +- + # perf docs + %if %{buildrt} + %if %{buildperf} +@@ -1255,6 +1333,39 @@ mkdir -p $RPM_BUILD_ROOT%{_datadir}/doc/perf + %endif # buildperf + %endif + ++%if %{with_tools} ++%ifarch %{cpupowerarchs} ++make -C tools/power/cpupower DESTDIR=$RPM_BUILD_ROOT libdir=%{_libdir} mandir=%{_mandir} CPUFREQ_BENCH=false install ++rm -f %{buildroot}%{_libdir}/*.{a,la} ++%find_lang cpupower ++mv cpupower.lang ../ ++%ifarch x86_64 ++ pushd tools/power/cpupower/debug/x86_64 ++ install -m755 centrino-decode %{buildroot}%{_bindir}/centrino-decode ++ install -m755 powernow-k8-decode %{buildroot}%{_bindir}/powernow-k8-decode ++ popd ++%endif ++chmod 0755 %{buildroot}%{_libdir}/libcpupower.so* ++mkdir -p %{buildroot}%{_unitdir} %{buildroot}%{_sysconfdir}/sysconfig ++install -m644 %{SOURCE2000} %{buildroot}%{_unitdir}/cpupower.service ++install -m644 %{SOURCE2001} %{buildroot}%{_sysconfdir}/sysconfig/cpupower ++%ifarch %{ix86} x86_64 ++ mkdir -p %{buildroot}%{_mandir}/man8 ++ pushd tools/power/x86/x86_energy_perf_policy ++ make DESTDIR=%{buildroot} install ++ popd ++ pushd tools/power/x86/turbostat ++ make DESTDIR=%{buildroot} install ++ popd ++%endif #turbostat/x86_energy_perf_policy ++pushd tools/thermal/tmon ++make INSTALL_ROOT=%{buildroot} install ++popd ++%endif ++ ++%endif ++ ++ + %if %{buildheaders} + # Install kernel headers + make ARCH=%{hdrarch} INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr headers_install +@@ -1303,6 +1414,14 @@ rm -rf $RPM_BUILD_ROOT + ### scripts + ### + ++%if %{with_tools} ++%post -n kernel-rt-tools ++/sbin/ldconfig ++ ++%postun -n kernel-rt-tools ++/sbin/ldconfig ++%endif ++ + # + # This macro defines a %%post script for a kernel*-devel package. + # %%kernel_devel_post [] +@@ -1460,6 +1579,43 @@ fi + %endif + %endif + ++ ++%if %{with_tools} ++%files -n kernel-rt-tools -f cpupower.lang ++%defattr(-,root,root) ++%ifarch %{cpupowerarchs} ++%{_bindir}/cpupower ++%ifarch x86_64 ++%{_bindir}/centrino-decode ++%{_bindir}/powernow-k8-decode ++%endif ++%{_unitdir}/cpupower.service ++%{_mandir}/man[1-8]/cpupower* ++%config(noreplace) %{_sysconfdir}/sysconfig/cpupower ++%ifarch %{ix86} x86_64 ++%{_bindir}/x86_energy_perf_policy ++%{_mandir}/man8/x86_energy_perf_policy* ++%{_bindir}/turbostat ++%{_mandir}/man8/turbostat* ++%endif ++%endif ++%{_bindir}/tmon ++ ++%ifarch %{cpupowerarchs} ++%files -n kernel-rt-tools-libs ++%defattr(-,root,root) ++%{_libdir}/libcpupower.so.0 ++%{_libdir}/libcpupower.so.0.0.0 ++ ++%files -n kernel-rt-tools-libs-devel ++%defattr(-,root,root) ++%{_libdir}/libcpupower.so ++%{_includedir}/cpufreq.h ++%endif ++ ++%endif # with_tools ++ ++ + # This is %{image_install_path} on an arch where that includes ELF files, + # or empty otherwise. + %global elf_image_install_path %{?kernel_image_elf:%{image_install_path}} +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-apply-patches.patch b/kernel-rt/centos/meta_patches/tis-apply-patches.patch new file mode 100644 index 000000000..8491b6c74 --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-apply-patches.patch @@ -0,0 +1,59 @@ +From 03cf09d820042573781332e8257124cced9c8dcc Mon Sep 17 00:00:00 2001 +Message-Id: <03cf09d820042573781332e8257124cced9c8dcc.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 08/29] tis apply patches + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index 726669d..ae0d7e3 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -382,6 +382,17 @@ Patch999999: linux-kernel-test.patch + Patch1000: debrand-single-cpu.patch + Patch1001: debrand-rh_taint.patch + Patch1002: debrand-rh-i686-cpu.patch ++Patch1003: affine-compute-kernel-threads.patch ++Patch1004: Affine-irqs-and-workqueues-with-kthread_cpus.patch ++Patch1005: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++Patch1006: cma-add-placement-specifier-for-cma-kernel-parameter.patch ++Patch1007: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++Patch1008: Make-kernel-start-eth-devices-at-offset.patch ++Patch1009: memblock-introduce-memblock_alloc_range.patch ++Patch1010: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch ++Patch1011: Notification-of-death-of-arbitrary-processes.patch ++Patch1012: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++Patch1013: x86-enable-DMA-CMA-with-swiotlb.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -693,6 +704,20 @@ ApplyPatch debrand-single-cpu.patch + ApplyPatch debrand-rh_taint.patch + ApplyPatch debrand-rh-i686-cpu.patch + ApplyPatch linux-kernel-test.patch ++ApplyPatch debrand-single-cpu.patch ++ApplyPatch debrand-rh_taint.patch ++ApplyPatch debrand-rh-i686-cpu.patch ++ApplyPatch affine-compute-kernel-threads.patch ++ApplyPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch ++ApplyPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++ApplyPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch ++ApplyPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++ApplyPatch Make-kernel-start-eth-devices-at-offset.patch ++ApplyPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch ++ApplyPatch memblock-introduce-memblock_alloc_range.patch ++ApplyPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++ApplyPatch Notification-of-death-of-arbitrary-processes.patch ++ApplyPatch x86-enable-DMA-CMA-with-swiotlb.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-build-unsigned-package.patch b/kernel-rt/centos/meta_patches/tis-build-unsigned-package.patch new file mode 100644 index 000000000..640569061 --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-build-unsigned-package.patch @@ -0,0 +1,64 @@ +From fed04855a35224e248e541b754b015df832503ba Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:13 -0400 +Subject: [PATCH 15/29] tis build unsigned package + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index fd9ed82..cd127ac 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -27,7 +27,7 @@ Summary: The Linux Realtime kernel + + # If we want to sign the kernel and modules, do_sign should be 1. + # To speed up builds (don't sign) use 0. +-%global do_sign 0 ++%global do_sign 1 + + # conditional with/without variables + # Note that the logic here is inverted; a bcond_without implies +@@ -695,6 +695,13 @@ the kernel source. + + %endif # with_tools + ++%if %{do_sign} ++%package unsigned ++Summary: Unsigned build of the Linux kernel ++%description unsigned ++Contains an unsigned version of the Linux kernel ++%endif # do_sign ++ + %prep + ## ApplyPatch routine + patch_command='patch -p1 -F1 -s' +@@ -942,6 +949,8 @@ BuildKernel() { + fi + # EFI SecureBoot signing, x86_64-only + %if %{do_sign} ++ cp $KernelImage vmlinuz.unsigned ++ $CopyKernel vmlinuz.unsigned $RPM_BUILD_ROOT/%{image_install_path}/vmlinuz.unsigned + %ifarch x86_64 + %pesign -s -i $KernelImage -o $KernelImage.signed -a %{SOURCE37} -c %{SOURCE37} -n %{pesign_name} + mv $KernelImage.signed $KernelImage +@@ -1708,6 +1717,11 @@ fi + %kernel_variant_files %{buildvanilla} vanilla + %endif + ++%if %{do_sign} ++%files unsigned ++/boot/vmlinuz.unsigned ++%endif # do_sign ++ + %changelog + * Wed Sep 13 2017 Johnny Hughes [3.10.0-693.2.2.rt56.623.el7] + - Manual CentOS Debranding +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-debrand-and-add-centos-certificate.patch b/kernel-rt/centos/meta_patches/tis-debrand-and-add-centos-certificate.patch new file mode 100644 index 000000000..06cbc15b9 --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-debrand-and-add-centos-certificate.patch @@ -0,0 +1,50 @@ +From 9c07167bbe02febf5402665f4a907a0edd21c1fd Mon Sep 17 00:00:00 2001 +Message-Id: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 01/29] tis debrand and add centos certificate + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index b433031..f7f4ead 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -340,6 +340,12 @@ Source25: merge.pl + Source27: sanity_check.py + Source29: extrakeys.pub + ++Source37: centos.cer ++%if %{?released_kernel} ++%define pesign_name redhatsecureboot301 ++%else ++%define pesign_name redhatsecureboot003 ++%endif + + ### Configuration files + Source50: kernel-%{version}-x86_64-rt.config +@@ -362,6 +368,9 @@ Patch1002: debrand-rh-i686-cpu.patch + + # Empty final patch file to facilitate testing of kernel patches + Patch999999: linux-kernel-test.patch ++Patch1000: debrand-single-cpu.patch ++Patch1001: debrand-rh_taint.patch ++Patch1002: debrand-rh-i686-cpu.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -805,7 +814,7 @@ BuildKernel() { + fi + # EFI SecureBoot signing, x86_64-only + %ifarch x86_64 +- %pesign -s -i $KernelImage -o $KernelImage.signed -a %{SOURCE13} -c %{SOURCE13} ++ %pesign -s -i $KernelImage -o $KernelImage.signed -a %{SOURCE37} -c %{SOURCE37} -n %{pesign_name} + mv $KernelImage.signed $KernelImage + %endif + $CopyKernel $KernelImage $RPM_BUILD_ROOT/%{image_install_path}/$InstallName-$KernelVer +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-handle-tis-config-customizations.patch b/kernel-rt/centos/meta_patches/tis-handle-tis-config-customizations.patch new file mode 100644 index 000000000..76eca951b --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-handle-tis-config-customizations.patch @@ -0,0 +1,57 @@ +From 18d55409c48176c1af22c21033755a7aa4eaac8f Mon Sep 17 00:00:00 2001 +Message-Id: <18d55409c48176c1af22c21033755a7aa4eaac8f.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 09/29] tis handle tis config customizations + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index ae0d7e3..aff01a7 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -362,7 +362,9 @@ Source37: centos.cer + Source50: kernel-%{version}-x86_64-rt.config + Source51: kernel-%{version}-x86_64-rt-trace.config + Source52: kernel-%{version}-x86_64-rt-debug.config +- ++Source30000: kernel-3.10.0-x86_64-rt.config.tis_extra ++Source30001: kernel-3.10.0-x86_64-rt-debug.config.tis_extra ++Source30002: kernel-3.10.0-x86_64-rt-trace.config.tis_extra + ### Started using a unified SRPM + + # Bugzilla: 1209952 +@@ -699,6 +701,9 @@ cp -rl vanilla-%{kversion} linux-%{kversion}.%{_target_cpu} + + cd linux-%{kversion}.%{_target_cpu} + ++# Copy any TiS-specific config changes ++cp $RPM_SOURCE_DIR/kernel-%{version}-*.config.tis_extra . ++ + ## Apply Patches here + ApplyPatch debrand-single-cpu.patch + ApplyPatch debrand-rh_taint.patch +@@ -739,6 +744,15 @@ for i in *.config + do + mv $i .config + Arch=`head -1 .config | cut -b 3-` ++ ++ # Handle Titanium Cloud customizations. Use -n to match oldnoconfig below. We want this before ++ # the make line below so that the one below removes any dependencies of ones that we ++ # turn off here. We also want it before "make listnewconfig" so that we can set the ++ # config option for new configs introduced in the Titanium Cloud patches. ++ if [ -f ${i}.tis_extra ]; then ++ scripts/kconfig/merge_config.sh -m -n .config ${i}.tis_extra ++ fi ++ + make %{?cross_opts} ARCH=$Arch listnewconfig | grep -E '^CONFIG_' >.newoptions || true + %if %{listnewconfig_fail} + if [ -s .newoptions ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-remove-signing.patch b/kernel-rt/centos/meta_patches/tis-remove-signing.patch new file mode 100644 index 000000000..03aa46008 --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-remove-signing.patch @@ -0,0 +1,101 @@ +From 06ec75f66757a2cb7a16ce72a634e750d3d9ec4e Mon Sep 17 00:00:00 2001 +Message-Id: <06ec75f66757a2cb7a16ce72a634e750d3d9ec4e.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 07/29] tis remove signing + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index c35efae..726669d 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -25,6 +25,10 @@ Summary: The Linux Realtime kernel + # For internal testing builds during development, it should be 0. + %global released_kernel 0 + ++# If we want to sign the kernel and modules, do_sign should be 1. ++# To speed up builds (don't sign) use 0. ++%global do_sign 0 ++ + # conditional with/without variables + # Note that the logic here is inverted; a bcond_without implies + # that the variable is on by default (since you use --without to turn it off) +@@ -58,7 +62,11 @@ Summary: The Linux Realtime kernel + # Verbose output? + # %%global verbose V=1 + ++%if %{do_sign} + %global signmodules 1 ++%else ++%global signmodules 0 ++%endif + + # if patch fuzzy patch applying will be forbidden + %global with_fuzzy_patches 0 +@@ -292,9 +300,11 @@ BuildRequires: openssl + BuildRequires: hmaccalc + BuildRequires: elfutils-libelf-devel + BuildRequires: python-devel, newt-devel, perl(ExtUtils::Embed) ++%if %{do_sign} + %ifarch x86_64 + BuildRequires: pesign >= 0.109-4 + %endif ++%endif + %if %{with_sparse} + BuildRequires: sparse >= 0.4.1 + %endif +@@ -838,10 +848,12 @@ BuildKernel() { + cp arch/$Arch/boot/zImage.stub $RPM_BUILD_ROOT/%{image_install_path}/zImage.stub-$KernelVer || : + fi + # EFI SecureBoot signing, x86_64-only ++%if %{do_sign} + %ifarch x86_64 + %pesign -s -i $KernelImage -o $KernelImage.signed -a %{SOURCE37} -c %{SOURCE37} -n %{pesign_name} + mv $KernelImage.signed $KernelImage + %endif ++%endif + $CopyKernel $KernelImage $RPM_BUILD_ROOT/%{image_install_path}/$InstallName-$KernelVer + chmod 755 $RPM_BUILD_ROOT/%{image_install_path}/$InstallName-$KernelVer + +@@ -1078,6 +1090,7 @@ popd + # if it isn't. + + %ifnarch noarch ++%if %{do_sign} + %define __modsign_install_post \ + if [ "%{with_rt}" -ne "0" ]; then \ + Arch=`head -1 configs/kernel-%{version}-%{_target_cpu}-rt.config | cut -b 3-` \ +@@ -1096,6 +1109,24 @@ popd + %{modsign_cmd} $RPM_BUILD_ROOT/lib/modules/%{KVERREL}.${AAA} || exit 1 \ + done \ + %{nil} ++%else ++%define __modsign_install_post \ ++ if [ "%{with_rt}" -ne "0" ]; then \ ++ Arch=`head -1 configs/kernel-%{version}-%{_target_cpu}-rt.config | cut -b 3-` \ ++ rm -rf .tmp_versions \ ++ mv .tmp_versions.sign .tmp_versions \ ++ mv signing_key.priv.sign signing_key.priv \ ++ mv signing_key.x509.sign signing_key.x509 \ ++ fi\ ++ for AAA in %{?with_trace:trace} %{?with_debug:debug} %{?with_vanilla:vanilla}; do \ ++ Arch=`head -1 configs/kernel-%{version}-%{_target_cpu}-rt-${AAA}.config | cut -b 3-` \ ++ rm -rf .tmp_versions \ ++ mv .tmp_versions.sign.${AAA} .tmp_versions \ ++ mv signing_key.priv.sign.${AAA} signing_key.priv \ ++ mv signing_key.x509.sign.${AAA} signing_key.x509 \ ++ done \ ++%{nil} ++%endif + %endif + + ### +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/tis-remove-trace.patch b/kernel-rt/centos/meta_patches/tis-remove-trace.patch new file mode 100644 index 000000000..ac8059fea --- /dev/null +++ b/kernel-rt/centos/meta_patches/tis-remove-trace.patch @@ -0,0 +1,29 @@ +From 134b18065f3e083407ddb9ad8f574a22c3bc194e Mon Sep 17 00:00:00 2001 +Message-Id: <134b18065f3e083407ddb9ad8f574a22c3bc194e.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:12 -0400 +Subject: [PATCH 02/29] tis remove trace + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index f7f4ead..ffbdbff 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -33,7 +33,7 @@ Summary: The Linux Realtime kernel + %bcond_without debug + %bcond_with headers + %bcond_with vanilla +-%bcond_without trace ++%bcond_with trace + %bcond_with perf + %bcond_with firmware + %bcond_without debuginfo +-- +1.8.3.1 + diff --git a/kernel-rt/centos/meta_patches/x86-dma_alloc_coherent-fix.patch b/kernel-rt/centos/meta_patches/x86-dma_alloc_coherent-fix.patch new file mode 100644 index 000000000..90a90720f --- /dev/null +++ b/kernel-rt/centos/meta_patches/x86-dma_alloc_coherent-fix.patch @@ -0,0 +1,38 @@ +From 4aab9c0f96b173dc91a60c0a332c26d2564ad57a Mon Sep 17 00:00:00 2001 +Message-Id: <4aab9c0f96b173dc91a60c0a332c26d2564ad57a.1507842722.git.Jim.Somerville@windriver.com> +In-Reply-To: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +References: <9c07167bbe02febf5402665f4a907a0edd21c1fd.1507842722.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:00:13 -0400 +Subject: [PATCH 18/29] x86 dma_alloc_coherent fix + +Signed-off-by: Jim Somerville +--- + SPECS/kernel-rt.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel-rt.spec b/SPECS/kernel-rt.spec +index d5216f4..3554ef3 100644 +--- a/SPECS/kernel-rt.spec ++++ b/SPECS/kernel-rt.spec +@@ -410,6 +410,8 @@ Patch1012: x86-enable-DMA-CMA-with-swiotlb.patch + Patch1013: Add-missing-ifdef-around-max-latency-variable.patch + Patch1014: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + Patch1015: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch ++Patch1016: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch ++Patch1017: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + + BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root + +@@ -788,6 +790,8 @@ ApplyPatch x86-enable-DMA-CMA-with-swiotlb.patch + ApplyPatch Add-missing-ifdef-around-max-latency-variable.patch + ApplyPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + ApplyPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch ++ApplyPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch ++ApplyPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + + # move off upstream version mechanism + if [ -e localversion-rt ]; then +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Add-missing-ifdef-around-max-latency-variable.patch b/kernel-rt/centos/patches/Add-missing-ifdef-around-max-latency-variable.patch new file mode 100644 index 000000000..9b71596a3 --- /dev/null +++ b/kernel-rt/centos/patches/Add-missing-ifdef-around-max-latency-variable.patch @@ -0,0 +1,50 @@ +From fbc8904ee75e751956cbe0f7e038073e4020fa27 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jim Somerville +Date: Thu, 22 Dec 2016 17:54:11 -0500 +Subject: [PATCH 1/1] Add missing ifdef around max latency variable + +Signed-off-by: Jim Somerville +--- + kernel/trace/trace_hwlat.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c +index 4b30d8b..1bb578c 100644 +--- a/kernel/trace/trace_hwlat.c ++++ b/kernel/trace/trace_hwlat.c +@@ -167,7 +167,9 @@ void trace_hwlat_callback(bool enter) + */ + static int get_sample(void) + { ++#ifdef CONFIG_TRACER_MAX_TRACE + struct trace_array *tr = hwlat_trace; ++#endif + time_type start, t1, t2, last_t2; + s64 diff, total, last_total = 0; + u64 sample = 0; +@@ -254,9 +256,11 @@ static int get_sample(void) + s.nmi_count = nmi_count; + trace_hwlat_sample(&s); + ++#ifdef CONFIG_TRACER_MAX_TRACE + /* Keep a running maximum ever recorded hardware latency */ + if (sample > tr->max_latency) + tr->max_latency = sample; ++#endif + } + + out: +@@ -582,7 +586,9 @@ static int hwlat_tracer_init(struct trace_array *tr) + + disable_migrate = false; + hwlat_data.count = 0; ++#ifdef CONFIG_TRACER_MAX_TRACE + tr->max_latency = 0; ++#endif + save_tracing_thresh = tracing_thresh; + + /* tracing_thresh is in nsecs, we speak in usecs */ +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch b/kernel-rt/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch new file mode 100644 index 000000000..8e3f614d3 --- /dev/null +++ b/kernel-rt/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch @@ -0,0 +1,73 @@ +From e90cbe249f37ec1c93f1b3674a725bf4c16abf60 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Tue, 24 Nov 2015 16:27:29 -0500 +Subject: [PATCH 02/26] Affine irqs and workqueues with kthread_cpus + +If the kthread_cpus boot arg is set it means we want to affine +kernel threads to the specified CPU mask as much as possible +in order to avoid doing work on other CPUs. + +In this commit we extend the meaning of that boot arg to also +apply to the CPU affinity of unbound and ordered workqueues. + +We also use the kthread_cpus value to determine the default irq +affinity. Specifically, as long as the previously-calculated +irq affinity intersects with the kthread_cpus affinity then we'll +use the intersection of the two as the default irq affinity. + +Signed-off-by: Chris Friesen +[VT: replacing spaces with tabs. Performed tests] +Signed-off-by: Vu Tran + +Signed-off-by: Jim Somerville +--- + kernel/irq/manage.c | 7 +++++++ + kernel/workqueue.c | 4 ++++ + 2 files changed, 11 insertions(+) + +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 768093b..c704ea6 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -386,6 +386,13 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) + if (cpumask_intersects(mask, nodemask)) + cpumask_and(mask, mask, nodemask); + } ++ ++ /* This will narrow down the affinity further if we've specified ++ * a reduced cpu_kthread_mask in the boot args. ++ */ ++ if (cpumask_intersects(mask, cpu_kthread_mask)) ++ cpumask_and(mask, mask, cpu_kthread_mask); ++ + irq_do_set_affinity(&desc->irq_data, mask, false); + return 0; + } +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index fabea26..07f66aa 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5459,6 +5459,8 @@ static int __init init_workqueues(void) + + BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL))); + attrs->nice = std_nice[i]; ++ /* If we've specified a kthread mask apply it here too. */ ++ cpumask_copy(attrs->cpumask, cpu_kthread_mask); + unbound_std_wq_attrs[i] = attrs; + + /* +@@ -5469,6 +5471,8 @@ static int __init init_workqueues(void) + BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL))); + attrs->nice = std_nice[i]; + attrs->no_numa = true; ++ /* If we've specified a kthread mask apply it here too. */ ++ cpumask_copy(attrs->cpumask, cpu_kthread_mask); + ordered_wq_attrs[i] = attrs; + } + +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch b/kernel-rt/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch new file mode 100644 index 000000000..901d1cde4 --- /dev/null +++ b/kernel-rt/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch @@ -0,0 +1,58 @@ +From b078d369b8f0505c9a87cc7001dd1c8b34893a43 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Allain Legacy +Date: Fri, 29 Jan 2016 12:13:40 -0500 +Subject: [PATCH 03/26] CGTS-3744: route: do not cache fib route info on local + routes with oif + +For local routes that require a particular output interface we do not want to +cache the result. Caching the result causes incorrect behaviour when there are +multiple source addresses on the interface. The end result being that if the +intended recipient is waiting on that interface for the packet he won't receive +it because it will be delivered on the loopback interface and the IP_PKTINFO +ipi_ifindex will be set to the loopback interface as well. + +This can be tested by running a program such as "dhcp_release" which attempts +to inject a packet on a particular interface so that it is received by another +program on the same board. The receiving process should see an IP_PKTINFO +ipi_ifndex value of the source interface (e.g., eth1) instead of the loopback +interface (e.g., lo). The packet will still appear on the loopback interface +in tcpdump but the important aspect is that the CMSG info is correct. + +Sample dhcp_release command line: + + dhcp_release eth1 192.168.204.222 02:11:33:22:44:66 + +Signed-off-by: Allain Legacy +Signed-off-by: Jim Somerville +--- + net/ipv4/route.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index e9a2b06..66a2a89 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2044,6 +2044,17 @@ static struct rtable *__mkroute_output(const struct fib_result *res, + */ + if (fi && res->prefixlen < 4) + fi = NULL; ++ } else if ((type == RTN_LOCAL) && (orig_oif != 0)) { ++ /* ++ * For local routes that require a particular output interface we do ++ * not want to cache the result. Caching the result causes incorrect ++ * behaviour when there are multiple source addresses on the interface. ++ * The end result being that if the intended recipient is waiting on ++ * that interface for the packet he won't receive it because it will be ++ * delivered on the loopback interface and the IP_PKTINFO ipi_ifindex ++ * will be set to the loopback interface as well. ++ */ ++ fi = NULL; + } + + fnhe = NULL; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch b/kernel-rt/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch new file mode 100644 index 000000000..540aec90a --- /dev/null +++ b/kernel-rt/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch @@ -0,0 +1,63 @@ +From c227e9a864d4f2567c9ebfdae0f8da703d447fe4 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Alex Shi +Date: Thu, 12 Jan 2017 21:27:03 +0800 +Subject: [PATCH 21/26] CPU / PM: expose pm_qos_resume_latency for CPUs + +[ commit 37efa4b41ffb31dcdfc3beb97d47992bb2a083e5 from linux-stable ] + +The cpu-dma PM QoS constraint impacts all the cpus in the system. There is no way +to let the user to choose a PM QoS constraint per cpu. + +The following patch exposes to the userspace a per cpu based sysfs file +in order to let the userspace to change the value of the PM QoS latency +constraint. + +This change is inoperative in its form and the cpuidle governors have to +take into account the per cpu latency constraint in addition to the +global cpu-dma latency constraint in order to operate properly. + +BTW +The pm_qos_resume_latency usage defined in +Documentation/ABI/testing/sysfs-devices-power +The /sys/devices/.../power/pm_qos_resume_latency_us attribute +contains the PM QoS resume latency limit for the given device, +which is the maximum allowed time it can take to resume the +device, after it has been suspended at run time, from a resume +request to the moment the device will be ready to process I/O, +in microseconds. If it is equal to 0, however, this means that +the PM QoS resume latency may be arbitrary. + +Signed-off-by: Alex Shi +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + drivers/base/cpu.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index 0ff0eff..e5a5de3 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "base.h" + +@@ -318,6 +319,7 @@ int register_cpu(struct cpu *cpu, int num) + per_cpu(cpu_sys_devices, num) = &cpu->dev; + if (!error) + register_cpu_under_node(num, cpu_to_node(num)); ++ dev_pm_qos_expose_latency_limit(&cpu->dev, 0); + + #ifdef CONFIG_KEXEC + if (!error) +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch b/kernel-rt/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch new file mode 100644 index 000000000..57281516d --- /dev/null +++ b/kernel-rt/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch @@ -0,0 +1,36 @@ +From dffbc3e34d7080dc2fce05b9c16565e6374572bf Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Wed, 11 Jan 2017 13:38:37 -0500 +Subject: [PATCH 13/26] Enable building kernel with CONFIG_BLK_DEV_NBD + +By default, the CentOS 7.3 kernel will fail to build if +CONFIG_BLK_DEV_NBD is enabled, either as module or builtin. + +The issue seems to be due to the use of REQ_TYPE_SPECIAL in the +NBD code. Switching it to use REQ_TYPE_DRV_PRIV instead makes the +problem go away. + +Signed-off-by: Jim Somerville +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index a40a4f0..e0c6b62 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -616,7 +616,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + fsync_bdev(bdev); + mutex_lock(&nbd->tx_lock); + blk_rq_init(NULL, &sreq); +- sreq.cmd_type = REQ_TYPE_SPECIAL; ++ sreq.cmd_type = REQ_TYPE_DRV_PRIV; + nbd_cmd(&sreq) = NBD_CMD_DISC; + + /* Check again after getting mutex back. */ +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch b/kernel-rt/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch new file mode 100644 index 000000000..83fd082bf --- /dev/null +++ b/kernel-rt/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch @@ -0,0 +1,34236 @@ +From 02ec2a87997e5cfff64bdee145a4dc0e0b46d577 Mon Sep 17 00:00:00 2001 +Message-Id: <02ec2a87997e5cfff64bdee145a4dc0e0b46d577.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Mon, 9 Jan 2017 15:03:00 -0500 +Subject: [PATCH 12/26] Enable building mpt2sas and mpt3sas as builtin for + CentOS 7.3 + +In CentOS 7.3 the upstream mpt2sas/mpt3sas drivers are built from +essentially the same codebase with a flag defined to give the mpt2sas +behaviour. This is purely a problem in 7.3 due to how they have mangled +the drivers. More recently in the Linux kernel these have been merged +into a single driver, while previously in 7.2 they were two totally +separate drivers. + +The 7.3 code works fine when building as modules, but when building as +builtin it gives problems because KBUILD_MODNAME is not defined for files +that are included in multiple drivers. + +The workaround is to move the mpt2sas driver into its own directory, +copying the whole mpt3sas codebase into it. This required a number of +changes after duplicating the codebase: + +1) Add knowledge of the new "mpt2sas" directory to from drivers/scsi/Kconfig +and drivers/scsi/Makefile. + +2) Remove mention of mpt2sas from drivers/scsi/mpt3sas/Kconfig and +drivers/scsi/mpt3sas/Makefile. + +3) Remove mention of mpt3sas from drivers/scsi/mpt2sas/Kconfig and +drivers/scsi/mpt2sas/Makefile. + +4) In the mpt2sas directory, all functions/variables with "mpt3sas" in +the name which did not already have an mpt2sas equivalent were renamed +to instead use "mpt2sas". Thus "_mpt3sas_init" became "_mpt2sas_init". + +5) All other symbols that collided between the two modules were renamed +in the mpt2sas driver by appending "_mpt2sas". This included ones with +"mpt2sas" already in the name, so "mpt2sas_raid_template" became +"mpt2sas_raid_template_mpt2sas". (While the version in the mpt3sas +driver remained "mpt2sas_raid_template".) + +Signed-off-by: Jim Somerville +--- + drivers/scsi/Kconfig | 1 + + drivers/scsi/Makefile | 1 + + drivers/scsi/mpt2sas/Kconfig | 61 + + drivers/scsi/mpt2sas/Makefile | 12 + + drivers/scsi/mpt2sas/mpi/mpi2.h | 1243 ++++ + drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 3493 ++++++++++ + drivers/scsi/mpt2sas/mpi/mpi2_init.h | 581 ++ + drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 1860 +++++ + drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 355 + + drivers/scsi/mpt2sas/mpi/mpi2_sas.h | 303 + + drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 483 ++ + drivers/scsi/mpt2sas/mpi/mpi2_type.h | 57 + + drivers/scsi/mpt2sas/mpt3sas_base.c | 5713 ++++++++++++++++ + drivers/scsi/mpt2sas/mpt3sas_base.h | 1462 ++++ + drivers/scsi/mpt2sas/mpt3sas_config.c | 1716 +++++ + drivers/scsi/mpt2sas/mpt3sas_ctl.c | 3483 ++++++++++ + drivers/scsi/mpt2sas/mpt3sas_ctl.h | 423 ++ + drivers/scsi/mpt2sas/mpt3sas_debug.h | 206 + + drivers/scsi/mpt2sas/mpt3sas_scsih.c | 9356 ++++++++++++++++++++++++++ + drivers/scsi/mpt2sas/mpt3sas_transport.c | 2138 ++++++ + drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c | 434 ++ + drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h | 194 + + drivers/scsi/mpt2sas/mpt3sas_warpdrive.c | 344 + + drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c | 4 + + drivers/scsi/mpt3sas/Kconfig | 20 - + drivers/scsi/mpt3sas/Makefile | 9 - + 26 files changed, 33923 insertions(+), 29 deletions(-) + create mode 100644 drivers/scsi/mpt2sas/Kconfig + create mode 100644 drivers/scsi/mpt2sas/Makefile + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_init.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_ioc.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_raid.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_sas.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_tool.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_type.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_base.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_base.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_config.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_ctl.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_ctl.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_debug.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_scsih.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_transport.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_warpdrive.c + create mode 100644 drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c + +diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig +index d1293c0..1c9fc44 100644 +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -599,6 +599,7 @@ config SCSI_ARCMSR + module will be called arcmsr (modprobe arcmsr). + + source "drivers/scsi/megaraid/Kconfig.megaraid" ++source "drivers/scsi/mpt2sas/Kconfig" + source "drivers/scsi/mpt3sas/Kconfig" + source "drivers/scsi/smartpqi/Kconfig" + source "drivers/scsi/ufs/Kconfig" +diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile +index 95aed68..1a08fca 100644 +--- a/drivers/scsi/Makefile ++++ b/drivers/scsi/Makefile +@@ -109,6 +109,7 @@ obj-$(CONFIG_CXLFLASH) += cxlflash/ + obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o + obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ + obj-$(CONFIG_MEGARAID_SAS) += megaraid/ ++obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/ + obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/ + obj-$(CONFIG_SCSI_UFSHCD) += ufs/ + obj-$(CONFIG_SCSI_ACARD) += atp870u.o +diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig +new file mode 100644 +index 0000000..a53ee73 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/Kconfig +@@ -0,0 +1,61 @@ ++# ++# Kernel configuration file for the MPT2SAS ++# ++# This code is based on drivers/scsi/mpt3sas/Kconfig ++# Copyright (C) 2012-2014 LSI Corporation ++# (mailto:DL-MPTFusionLinux@lsi.com) ++ ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version 2 ++# of the License, or (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# NO WARRANTY ++# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++# solely responsible for determining the appropriateness of using and ++# distributing the Program and assumes all risks associated with its ++# exercise of rights under this Agreement, including but not limited to ++# the risks and costs of program errors, damage to or loss of data, ++# programs or equipment, and unavailability or interruption of operations. ++ ++# DISCLAIMER OF LIABILITY ++# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++# USA. ++ ++config SCSI_MPT2SAS ++ tristate "LSI MPT Fusion SAS 2.0 Device Driver" ++ depends on PCI && SCSI ++ select SCSI_SAS_ATTRS ++ select RAID_ATTRS ++ ---help--- ++ This driver supports PCI-Express SAS 6Gb/s Host Adapters. ++ ++config SCSI_MPT2SAS_MAX_SGE ++ int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)" ++ depends on PCI && SCSI && SCSI_MPT2SAS ++ default "128" ++ range 16 256 ++ ---help--- ++ This option allows you to specify the maximum number of scatter- ++ gather entries per I/O. The driver default is 128, which matches ++ MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this ++ can be 256. However, it may decreased down to 16. Decreasing this ++ parameter will reduce memory requirements on a per controller instance. +diff --git a/drivers/scsi/mpt2sas/Makefile b/drivers/scsi/mpt2sas/Makefile +new file mode 100644 +index 0000000..5706ea4 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/Makefile +@@ -0,0 +1,12 @@ ++# mpt2-3sas makefile ++ ++obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o ++ ++obj-m += mpt2sas.o ++mpt2sas-y += mpt3sas_base.o \ ++ mpt3sas_config.o \ ++ wrapper_mpt3sas_scsih.o \ ++ mpt3sas_transport.o \ ++ mpt3sas_ctl.o \ ++ mpt3sas_trigger_diag.o \ ++ mpt3sas_warpdrive.o +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h +new file mode 100644 +index 0000000..a9a659f +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2.h +@@ -0,0 +1,1243 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2.h ++ * Title: MPI Message independent structures and definitions ++ * including System Interface Register Set and ++ * scatter/gather formats. ++ * Creation Date: June 21, 2006 ++ * ++ * mpi2.h Version: 02.00.42 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-04-07 02.00.01 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 06-26-07 02.00.02 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-31-07 02.00.03 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Moved ReplyPostHostIndex register to offset 0x6C of the ++ * MPI2_SYSTEM_INTERFACE_REGS and modified the define for ++ * MPI2_REPLY_POST_HOST_INDEX_OFFSET. ++ * Added union of request descriptors. ++ * Added union of reply descriptors. ++ * 10-31-07 02.00.04 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added define for MPI2_VERSION_02_00. ++ * Fixed the size of the FunctionDependent5 field in the ++ * MPI2_DEFAULT_REPLY structure. ++ * 12-18-07 02.00.05 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Removed the MPI-defined Fault Codes and extended the ++ * product specific codes up to 0xEFFF. ++ * Added a sixth key value for the WriteSequence register ++ * and changed the flush value to 0x0. ++ * Added message function codes for Diagnostic Buffer Post ++ * and Diagnsotic Release. ++ * New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED ++ * Moved MPI2_VERSION_UNION from mpi2_ioc.h. ++ * 02-29-08 02.00.06 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 03-03-08 02.00.07 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-21-08 02.00.08 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added #defines for marking a reply descriptor as unused. ++ * 06-27-08 02.00.09 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Moved LUN field defines from mpi2_init.h. ++ * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT. ++ * In all request and reply descriptors, replaced VF_ID ++ * field with MSIxIndex field. ++ * Removed DevHandle field from ++ * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those ++ * bytes reserved. ++ * Added RAID Accelerator functionality. ++ * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MSI-x index mask and shift for Reply Post Host ++ * Index register. ++ * Added function code for Host Based Discovery Action. ++ * 02-10-10 02.00.15 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL. ++ * Added defines for product-specific range of message ++ * function codes, 0xF0 to 0xFF. ++ * 05-12-10 02.00.16 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added alternative defines for the SGE Direction bit. ++ * 08-11-10 02.00.17 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-10-10 02.00.18 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define. ++ * 02-23-11 02.00.19 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MPI2_FUNCTION_SEND_HOST_MESSAGE. ++ * 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-25-11 02.00.21 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-24-11 02.00.22 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-18-11 02.00.23 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Incorporating additions for MPI v2.5. ++ * 02-06-12 02.00.24 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added Hard Reset delay timings. ++ * 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-27-12 02.00.28 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 12-20-12 02.00.29 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. ++ * 04-09-13 02.00.30 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 12-05-13 02.00.33 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 01-08-14 02.00.34 Bumped MPI2_HEADER_VERSION_UNIT ++ * 06-13-14 02.00.35 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-18-14 02.00.36 Updated copyright information. ++ * Bumped MPI2_HEADER_VERSION_UNIT. ++ * 03-16-15 02.00.37 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added Scratchpad registers to ++ * MPI2_SYSTEM_INTERFACE_REGS. ++ * Added MPI2_DIAG_SBR_RELOAD. ++ * 03-19-15 02.00.38 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-25-15 02.00.39 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-25-15 02.00.40 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT ++ * 01-01-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_H ++#define MPI2_H ++ ++/***************************************************************************** ++* ++* MPI Version Definitions ++* ++*****************************************************************************/ ++ ++#define MPI2_VERSION_MAJOR_MASK (0xFF00) ++#define MPI2_VERSION_MAJOR_SHIFT (8) ++#define MPI2_VERSION_MINOR_MASK (0x00FF) ++#define MPI2_VERSION_MINOR_SHIFT (0) ++ ++/*major version for all MPI v2.x */ ++#define MPI2_VERSION_MAJOR (0x02) ++ ++/*minor version for MPI v2.0 compatible products */ ++#define MPI2_VERSION_MINOR (0x00) ++#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ ++ MPI2_VERSION_MINOR) ++#define MPI2_VERSION_02_00 (0x0200) ++ ++/*minor version for MPI v2.5 compatible products */ ++#define MPI25_VERSION_MINOR (0x05) ++#define MPI25_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ ++ MPI25_VERSION_MINOR) ++#define MPI2_VERSION_02_05 (0x0205) ++ ++/*minor version for MPI v2.6 compatible products */ ++#define MPI26_VERSION_MINOR (0x06) ++#define MPI26_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ ++ MPI26_VERSION_MINOR) ++#define MPI2_VERSION_02_06 (0x0206) ++ ++/*Unit and Dev versioning for this MPI header set */ ++#define MPI2_HEADER_VERSION_UNIT (0x2A) ++#define MPI2_HEADER_VERSION_DEV (0x00) ++#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) ++#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) ++#define MPI2_HEADER_VERSION_DEV_MASK (0x00FF) ++#define MPI2_HEADER_VERSION_DEV_SHIFT (0) ++#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | \ ++ MPI2_HEADER_VERSION_DEV) ++ ++/***************************************************************************** ++* ++* IOC State Definitions ++* ++*****************************************************************************/ ++ ++#define MPI2_IOC_STATE_RESET (0x00000000) ++#define MPI2_IOC_STATE_READY (0x10000000) ++#define MPI2_IOC_STATE_OPERATIONAL (0x20000000) ++#define MPI2_IOC_STATE_FAULT (0x40000000) ++ ++#define MPI2_IOC_STATE_MASK (0xF0000000) ++#define MPI2_IOC_STATE_SHIFT (28) ++ ++/*Fault state range for prodcut specific codes */ ++#define MPI2_FAULT_PRODUCT_SPECIFIC_MIN (0x0000) ++#define MPI2_FAULT_PRODUCT_SPECIFIC_MAX (0xEFFF) ++ ++/***************************************************************************** ++* ++* System Interface Register Definitions ++* ++*****************************************************************************/ ++ ++typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS { ++ U32 Doorbell; /*0x00 */ ++ U32 WriteSequence; /*0x04 */ ++ U32 HostDiagnostic; /*0x08 */ ++ U32 Reserved1; /*0x0C */ ++ U32 DiagRWData; /*0x10 */ ++ U32 DiagRWAddressLow; /*0x14 */ ++ U32 DiagRWAddressHigh; /*0x18 */ ++ U32 Reserved2[5]; /*0x1C */ ++ U32 HostInterruptStatus; /*0x30 */ ++ U32 HostInterruptMask; /*0x34 */ ++ U32 DCRData; /*0x38 */ ++ U32 DCRAddress; /*0x3C */ ++ U32 Reserved3[2]; /*0x40 */ ++ U32 ReplyFreeHostIndex; /*0x48 */ ++ U32 Reserved4[8]; /*0x4C */ ++ U32 ReplyPostHostIndex; /*0x6C */ ++ U32 Reserved5; /*0x70 */ ++ U32 HCBSize; /*0x74 */ ++ U32 HCBAddressLow; /*0x78 */ ++ U32 HCBAddressHigh; /*0x7C */ ++ U32 Reserved6[12]; /*0x80 */ ++ U32 Scratchpad[4]; /*0xB0 */ ++ U32 RequestDescriptorPostLow; /*0xC0 */ ++ U32 RequestDescriptorPostHigh; /*0xC4 */ ++ U32 AtomicRequestDescriptorPost;/*0xC8 */ ++ U32 Reserved7[13]; /*0xCC */ ++} MPI2_SYSTEM_INTERFACE_REGS, ++ *PTR_MPI2_SYSTEM_INTERFACE_REGS, ++ Mpi2SystemInterfaceRegs_t, ++ *pMpi2SystemInterfaceRegs_t; ++ ++/* ++ *Defines for working with the Doorbell register. ++ */ ++#define MPI2_DOORBELL_OFFSET (0x00000000) ++ ++/*IOC --> System values */ ++#define MPI2_DOORBELL_USED (0x08000000) ++#define MPI2_DOORBELL_WHO_INIT_MASK (0x07000000) ++#define MPI2_DOORBELL_WHO_INIT_SHIFT (24) ++#define MPI2_DOORBELL_FAULT_CODE_MASK (0x0000FFFF) ++#define MPI2_DOORBELL_DATA_MASK (0x0000FFFF) ++ ++/*System --> IOC values */ ++#define MPI2_DOORBELL_FUNCTION_MASK (0xFF000000) ++#define MPI2_DOORBELL_FUNCTION_SHIFT (24) ++#define MPI2_DOORBELL_ADD_DWORDS_MASK (0x00FF0000) ++#define MPI2_DOORBELL_ADD_DWORDS_SHIFT (16) ++ ++/* ++ *Defines for the WriteSequence register ++ */ ++#define MPI2_WRITE_SEQUENCE_OFFSET (0x00000004) ++#define MPI2_WRSEQ_KEY_VALUE_MASK (0x0000000F) ++#define MPI2_WRSEQ_FLUSH_KEY_VALUE (0x0) ++#define MPI2_WRSEQ_1ST_KEY_VALUE (0xF) ++#define MPI2_WRSEQ_2ND_KEY_VALUE (0x4) ++#define MPI2_WRSEQ_3RD_KEY_VALUE (0xB) ++#define MPI2_WRSEQ_4TH_KEY_VALUE (0x2) ++#define MPI2_WRSEQ_5TH_KEY_VALUE (0x7) ++#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD) ++ ++/* ++ *Defines for the HostDiagnostic register ++ */ ++#define MPI2_HOST_DIAGNOSTIC_OFFSET (0x00000008) ++ ++#define MPI2_DIAG_SBR_RELOAD (0x00002000) ++ ++#define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK (0x00001800) ++#define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT (0x00000000) ++#define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW (0x00000800) ++ ++#define MPI2_DIAG_CLEAR_FLASH_BAD_SIG (0x00000400) ++#define MPI2_DIAG_FORCE_HCB_ON_RESET (0x00000200) ++#define MPI2_DIAG_HCB_MODE (0x00000100) ++#define MPI2_DIAG_DIAG_WRITE_ENABLE (0x00000080) ++#define MPI2_DIAG_FLASH_BAD_SIG (0x00000040) ++#define MPI2_DIAG_RESET_HISTORY (0x00000020) ++#define MPI2_DIAG_DIAG_RW_ENABLE (0x00000010) ++#define MPI2_DIAG_RESET_ADAPTER (0x00000004) ++#define MPI2_DIAG_HOLD_IOC_RESET (0x00000002) ++ ++/* ++ *Offsets for DiagRWData and address ++ */ ++#define MPI2_DIAG_RW_DATA_OFFSET (0x00000010) ++#define MPI2_DIAG_RW_ADDRESS_LOW_OFFSET (0x00000014) ++#define MPI2_DIAG_RW_ADDRESS_HIGH_OFFSET (0x00000018) ++ ++/* ++ *Defines for the HostInterruptStatus register ++ */ ++#define MPI2_HOST_INTERRUPT_STATUS_OFFSET (0x00000030) ++#define MPI2_HIS_SYS2IOC_DB_STATUS (0x80000000) ++#define MPI2_HIS_IOP_DOORBELL_STATUS MPI2_HIS_SYS2IOC_DB_STATUS ++#define MPI2_HIS_RESET_IRQ_STATUS (0x40000000) ++#define MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT (0x00000008) ++#define MPI2_HIS_IOC2SYS_DB_STATUS (0x00000001) ++#define MPI2_HIS_DOORBELL_INTERRUPT MPI2_HIS_IOC2SYS_DB_STATUS ++ ++/* ++ *Defines for the HostInterruptMask register ++ */ ++#define MPI2_HOST_INTERRUPT_MASK_OFFSET (0x00000034) ++#define MPI2_HIM_RESET_IRQ_MASK (0x40000000) ++#define MPI2_HIM_REPLY_INT_MASK (0x00000008) ++#define MPI2_HIM_RIM MPI2_HIM_REPLY_INT_MASK ++#define MPI2_HIM_IOC2SYS_DB_MASK (0x00000001) ++#define MPI2_HIM_DIM MPI2_HIM_IOC2SYS_DB_MASK ++ ++/* ++ *Offsets for DCRData and address ++ */ ++#define MPI2_DCR_DATA_OFFSET (0x00000038) ++#define MPI2_DCR_ADDRESS_OFFSET (0x0000003C) ++ ++/* ++ *Offset for the Reply Free Queue ++ */ ++#define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048) ++ ++/* ++ *Defines for the Reply Descriptor Post Queue ++ */ ++#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) ++#define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF) ++#define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000) ++#define MPI2_RPHI_MSIX_INDEX_SHIFT (24) ++#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) /*MPI v2.5 only*/ ++ ++ ++/* ++ *Defines for the HCBSize and address ++ */ ++#define MPI2_HCB_SIZE_OFFSET (0x00000074) ++#define MPI2_HCB_SIZE_SIZE_MASK (0xFFFFF000) ++#define MPI2_HCB_SIZE_HCB_ENABLE (0x00000001) ++ ++#define MPI2_HCB_ADDRESS_LOW_OFFSET (0x00000078) ++#define MPI2_HCB_ADDRESS_HIGH_OFFSET (0x0000007C) ++ ++/* ++ *Offsets for the Scratchpad registers ++ */ ++#define MPI26_SCRATCHPAD0_OFFSET (0x000000B0) ++#define MPI26_SCRATCHPAD1_OFFSET (0x000000B4) ++#define MPI26_SCRATCHPAD2_OFFSET (0x000000B8) ++#define MPI26_SCRATCHPAD3_OFFSET (0x000000BC) ++ ++/* ++ *Offsets for the Request Descriptor Post Queue ++ */ ++#define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET (0x000000C0) ++#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4) ++#define MPI26_ATOMIC_REQUEST_DESCRIPTOR_POST_OFFSET (0x000000C8) ++ ++/*Hard Reset delay timings */ ++#define MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC (50000) ++#define MPI2_HARD_RESET_PCIE_RESET_READ_WINDOW_MICRO_SEC (255000) ++#define MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC (256000) ++ ++/***************************************************************************** ++* ++* Message Descriptors ++* ++*****************************************************************************/ ++ ++/*Request Descriptors */ ++ ++/*Default Request Descriptor */ ++typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 DescriptorTypeDependent; /*0x06 */ ++} MPI2_DEFAULT_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_DEFAULT_REQUEST_DESCRIPTOR, ++ Mpi2DefaultRequestDescriptor_t, ++ *pMpi2DefaultRequestDescriptor_t; ++ ++/*defines for the RequestFlags field */ ++#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x1E) ++#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_RSHIFT (1) ++#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00) ++#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02) ++#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06) ++#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08) ++#define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR (0x0A) ++#define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO (0x0C) ++ ++#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01) ++ ++/*High Priority Request Descriptor */ ++typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++} MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR, ++ Mpi2HighPriorityRequestDescriptor_t, ++ *pMpi2HighPriorityRequestDescriptor_t; ++ ++/*SCSI IO Request Descriptor */ ++typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 DevHandle; /*0x06 */ ++} MPI2_SCSI_IO_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_SCSI_IO_REQUEST_DESCRIPTOR, ++ Mpi2SCSIIORequestDescriptor_t, ++ *pMpi2SCSIIORequestDescriptor_t; ++ ++/*SCSI Target Request Descriptor */ ++typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 IoIndex; /*0x06 */ ++} MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR, ++ Mpi2SCSITargetRequestDescriptor_t, ++ *pMpi2SCSITargetRequestDescriptor_t; ++ ++/*RAID Accelerator Request Descriptor */ ++typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 Reserved; /*0x06 */ ++} MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, ++ Mpi2RAIDAcceleratorRequestDescriptor_t, ++ *pMpi2RAIDAcceleratorRequestDescriptor_t; ++ ++/*Fast Path SCSI IO Request Descriptor */ ++typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR ++ MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR, ++ *PTR_MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR, ++ Mpi25FastPathSCSIIORequestDescriptor_t, ++ *pMpi25FastPathSCSIIORequestDescriptor_t; ++ ++/*union of Request Descriptors */ ++typedef union _MPI2_REQUEST_DESCRIPTOR_UNION { ++ MPI2_DEFAULT_REQUEST_DESCRIPTOR Default; ++ MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority; ++ MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO; ++ MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget; ++ MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator; ++ MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO; ++ U64 Words; ++} MPI2_REQUEST_DESCRIPTOR_UNION, ++ *PTR_MPI2_REQUEST_DESCRIPTOR_UNION, ++ Mpi2RequestDescriptorUnion_t, ++ *pMpi2RequestDescriptorUnion_t; ++ ++/*Atomic Request Descriptors */ ++ ++/* ++ * All Atomic Request Descriptors have the same format, so the following ++ * structure is used for all Atomic Request Descriptors: ++ * Atomic Default Request Descriptor ++ * Atomic High Priority Request Descriptor ++ * Atomic SCSI IO Request Descriptor ++ * Atomic SCSI Target Request Descriptor ++ * Atomic RAID Accelerator Request Descriptor ++ * Atomic Fast Path SCSI IO Request Descriptor ++ */ ++ ++/*Atomic Request Descriptor */ ++typedef struct _MPI26_ATOMIC_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /* 0x00 */ ++ U8 MSIxIndex; /* 0x01 */ ++ U16 SMID; /* 0x02 */ ++} MPI26_ATOMIC_REQUEST_DESCRIPTOR, ++ *PTR_MPI26_ATOMIC_REQUEST_DESCRIPTOR, ++ Mpi26AtomicRequestDescriptor_t, ++ *pMpi26AtomicRequestDescriptor_t; ++ ++/*for the RequestFlags field, use the same ++ *defines as MPI2_DEFAULT_REQUEST_DESCRIPTOR ++ */ ++ ++/*Reply Descriptors */ ++ ++/*Default Reply Descriptor */ ++typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 DescriptorTypeDependent1; /*0x02 */ ++ U32 DescriptorTypeDependent2; /*0x04 */ ++} MPI2_DEFAULT_REPLY_DESCRIPTOR, ++ *PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR, ++ Mpi2DefaultReplyDescriptor_t, ++ *pMpi2DefaultReplyDescriptor_t; ++ ++/*defines for the ReplyFlags field */ ++#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F) ++#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00) ++#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01) ++#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02) ++#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03) ++#define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS (0x05) ++#define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS (0x06) ++#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F) ++ ++/*values for marking a reply descriptor as unused */ ++#define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF) ++#define MPI2_RPY_DESCRIPT_UNUSED_WORD1_MARK (0xFFFFFFFF) ++ ++/*Address Reply Descriptor */ ++typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U32 ReplyFrameAddress; /*0x04 */ ++} MPI2_ADDRESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR, ++ Mpi2AddressReplyDescriptor_t, ++ *pMpi2AddressReplyDescriptor_t; ++ ++#define MPI2_ADDRESS_REPLY_SMID_INVALID (0x00) ++ ++/*SCSI IO Success Reply Descriptor */ ++typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 TaskTag; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi2SCSIIOSuccessReplyDescriptor_t, ++ *pMpi2SCSIIOSuccessReplyDescriptor_t; ++ ++/*TargetAssist Success Reply Descriptor */ ++typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U8 SequenceNumber; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 IoIndex; /*0x06 */ ++} MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi2TargetAssistSuccessReplyDescriptor_t, ++ *pMpi2TargetAssistSuccessReplyDescriptor_t; ++ ++/*Target Command Buffer Reply Descriptor */ ++typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U8 VP_ID; /*0x02 */ ++ U8 Flags; /*0x03 */ ++ U16 InitiatorDevHandle; /*0x04 */ ++ U16 IoIndex; /*0x06 */ ++} MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR, ++ *PTR_MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR, ++ Mpi2TargetCommandBufferReplyDescriptor_t, ++ *pMpi2TargetCommandBufferReplyDescriptor_t; ++ ++/*defines for Flags field */ ++#define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F) ++ ++/*RAID Accelerator Success Reply Descriptor */ ++typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U32 Reserved; /*0x04 */ ++} MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi2RAIDAcceleratorSuccessReplyDescriptor_t, ++ *pMpi2RAIDAcceleratorSuccessReplyDescriptor_t; ++ ++/*Fast Path SCSI IO Success Reply Descriptor */ ++typedef MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR ++ MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi25FastPathSCSIIOSuccessReplyDescriptor_t, ++ *pMpi25FastPathSCSIIOSuccessReplyDescriptor_t; ++ ++/*union of Reply Descriptors */ ++typedef union _MPI2_REPLY_DESCRIPTORS_UNION { ++ MPI2_DEFAULT_REPLY_DESCRIPTOR Default; ++ MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply; ++ MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess; ++ MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess; ++ MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer; ++ MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess; ++ MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR FastPathSCSIIOSuccess; ++ U64 Words; ++} MPI2_REPLY_DESCRIPTORS_UNION, ++ *PTR_MPI2_REPLY_DESCRIPTORS_UNION, ++ Mpi2ReplyDescriptorsUnion_t, ++ *pMpi2ReplyDescriptorsUnion_t; ++ ++/***************************************************************************** ++* ++* Message Functions ++* ++*****************************************************************************/ ++ ++#define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) ++#define MPI2_FUNCTION_SCSI_TASK_MGMT (0x01) ++#define MPI2_FUNCTION_IOC_INIT (0x02) ++#define MPI2_FUNCTION_IOC_FACTS (0x03) ++#define MPI2_FUNCTION_CONFIG (0x04) ++#define MPI2_FUNCTION_PORT_FACTS (0x05) ++#define MPI2_FUNCTION_PORT_ENABLE (0x06) ++#define MPI2_FUNCTION_EVENT_NOTIFICATION (0x07) ++#define MPI2_FUNCTION_EVENT_ACK (0x08) ++#define MPI2_FUNCTION_FW_DOWNLOAD (0x09) ++#define MPI2_FUNCTION_TARGET_ASSIST (0x0B) ++#define MPI2_FUNCTION_TARGET_STATUS_SEND (0x0C) ++#define MPI2_FUNCTION_TARGET_MODE_ABORT (0x0D) ++#define MPI2_FUNCTION_FW_UPLOAD (0x12) ++#define MPI2_FUNCTION_RAID_ACTION (0x15) ++#define MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH (0x16) ++#define MPI2_FUNCTION_TOOLBOX (0x17) ++#define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR (0x18) ++#define MPI2_FUNCTION_SMP_PASSTHROUGH (0x1A) ++#define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) ++#define MPI2_FUNCTION_IO_UNIT_CONTROL (0x1B) ++#define MPI2_FUNCTION_SATA_PASSTHROUGH (0x1C) ++#define MPI2_FUNCTION_DIAG_BUFFER_POST (0x1D) ++#define MPI2_FUNCTION_DIAG_RELEASE (0x1E) ++#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) ++#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) ++#define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) ++#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F) ++#define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30) ++#define MPI2_FUNCTION_SEND_HOST_MESSAGE (0x31) ++#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0) ++#define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++/*Doorbell functions */ ++#define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) ++#define MPI2_FUNCTION_HANDSHAKE (0x42) ++ ++/***************************************************************************** ++* ++* IOC Status Values ++* ++*****************************************************************************/ ++ ++/*mask for IOCStatus status value */ ++#define MPI2_IOCSTATUS_MASK (0x7FFF) ++ ++/**************************************************************************** ++* Common IOCStatus values for all replies ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_SUCCESS (0x0000) ++#define MPI2_IOCSTATUS_INVALID_FUNCTION (0x0001) ++#define MPI2_IOCSTATUS_BUSY (0x0002) ++#define MPI2_IOCSTATUS_INVALID_SGL (0x0003) ++#define MPI2_IOCSTATUS_INTERNAL_ERROR (0x0004) ++#define MPI2_IOCSTATUS_INVALID_VPID (0x0005) ++#define MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006) ++#define MPI2_IOCSTATUS_INVALID_FIELD (0x0007) ++#define MPI2_IOCSTATUS_INVALID_STATE (0x0008) ++#define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009) ++#define MPI2_IOCSTATUS_INSUFFICIENT_POWER (0x000A) ++ ++/**************************************************************************** ++* Config IOCStatus values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020) ++#define MPI2_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021) ++#define MPI2_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022) ++#define MPI2_IOCSTATUS_CONFIG_INVALID_DATA (0x0023) ++#define MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024) ++#define MPI2_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025) ++ ++/**************************************************************************** ++* SCSI IO Reply ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR (0x0040) ++#define MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE (0x0042) ++#define MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE (0x0043) ++#define MPI2_IOCSTATUS_SCSI_DATA_OVERRUN (0x0044) ++#define MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN (0x0045) ++#define MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR (0x0046) ++#define MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR (0x0047) ++#define MPI2_IOCSTATUS_SCSI_TASK_TERMINATED (0x0048) ++#define MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH (0x0049) ++#define MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED (0x004A) ++#define MPI2_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B) ++#define MPI2_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) ++ ++/**************************************************************************** ++* For use by SCSI Initiator and SCSI Target end-to-end data protection ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_EEDP_GUARD_ERROR (0x004D) ++#define MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E) ++#define MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F) ++ ++/**************************************************************************** ++* SCSI Target values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) ++#define MPI2_IOCSTATUS_TARGET_ABORTED (0x0063) ++#define MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) ++#define MPI2_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) ++#define MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A) ++#define MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D) ++#define MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E) ++#define MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F) ++#define MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT (0x0070) ++#define MPI2_IOCSTATUS_TARGET_NAK_RECEIVED (0x0071) ++ ++/**************************************************************************** ++* Serial Attached SCSI values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) ++#define MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN (0x0091) ++ ++/**************************************************************************** ++* Diagnostic Buffer Post / Diagnostic Release values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0) ++ ++/**************************************************************************** ++* RAID Accelerator values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_RAID_ACCEL_ERROR (0x00B0) ++ ++/**************************************************************************** ++* IOCStatus flag to indicate that log info is available ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000) ++ ++/**************************************************************************** ++* IOCLogInfo Types ++****************************************************************************/ ++ ++#define MPI2_IOCLOGINFO_TYPE_MASK (0xF0000000) ++#define MPI2_IOCLOGINFO_TYPE_SHIFT (28) ++#define MPI2_IOCLOGINFO_TYPE_NONE (0x0) ++#define MPI2_IOCLOGINFO_TYPE_SCSI (0x1) ++#define MPI2_IOCLOGINFO_TYPE_FC (0x2) ++#define MPI2_IOCLOGINFO_TYPE_SAS (0x3) ++#define MPI2_IOCLOGINFO_TYPE_ISCSI (0x4) ++#define MPI2_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF) ++ ++/***************************************************************************** ++* ++* Standard Message Structures ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++*Request Message Header for all request messages ++****************************************************************************/ ++ ++typedef struct _MPI2_REQUEST_HEADER { ++ U16 FunctionDependent1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 FunctionDependent2; /*0x04 */ ++ U8 FunctionDependent3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++} MPI2_REQUEST_HEADER, *PTR_MPI2_REQUEST_HEADER, ++ MPI2RequestHeader_t, *pMPI2RequestHeader_t; ++ ++/**************************************************************************** ++* Default Reply ++****************************************************************************/ ++ ++typedef struct _MPI2_DEFAULT_REPLY { ++ U16 FunctionDependent1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 FunctionDependent2; /*0x04 */ ++ U8 FunctionDependent3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U16 FunctionDependent5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_DEFAULT_REPLY, *PTR_MPI2_DEFAULT_REPLY, ++ MPI2DefaultReply_t, *pMPI2DefaultReply_t; ++ ++/*common version structure/union used in messages and configuration pages */ ++ ++typedef struct _MPI2_VERSION_STRUCT { ++ U8 Dev; /*0x00 */ ++ U8 Unit; /*0x01 */ ++ U8 Minor; /*0x02 */ ++ U8 Major; /*0x03 */ ++} MPI2_VERSION_STRUCT; ++ ++typedef union _MPI2_VERSION_UNION { ++ MPI2_VERSION_STRUCT Struct; ++ U32 Word; ++} MPI2_VERSION_UNION; ++ ++/*LUN field defines, common to many structures */ ++#define MPI2_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF) ++#define MPI2_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000) ++#define MPI2_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF) ++#define MPI2_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000) ++#define MPI2_LUN_LEVEL_1_WORD (0xFF00) ++#define MPI2_LUN_LEVEL_1_DWORD (0x0000FF00) ++ ++/***************************************************************************** ++* ++* Fusion-MPT MPI Scatter Gather Elements ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* MPI Simple Element structures ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_SIMPLE32 { ++ U32 FlagsLength; ++ U32 Address; ++} MPI2_SGE_SIMPLE32, *PTR_MPI2_SGE_SIMPLE32, ++ Mpi2SGESimple32_t, *pMpi2SGESimple32_t; ++ ++typedef struct _MPI2_SGE_SIMPLE64 { ++ U32 FlagsLength; ++ U64 Address; ++} MPI2_SGE_SIMPLE64, *PTR_MPI2_SGE_SIMPLE64, ++ Mpi2SGESimple64_t, *pMpi2SGESimple64_t; ++ ++typedef struct _MPI2_SGE_SIMPLE_UNION { ++ U32 FlagsLength; ++ union { ++ U32 Address32; ++ U64 Address64; ++ } u; ++} MPI2_SGE_SIMPLE_UNION, ++ *PTR_MPI2_SGE_SIMPLE_UNION, ++ Mpi2SGESimpleUnion_t, ++ *pMpi2SGESimpleUnion_t; ++ ++/**************************************************************************** ++* MPI Chain Element structures - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_CHAIN32 { ++ U16 Length; ++ U8 NextChainOffset; ++ U8 Flags; ++ U32 Address; ++} MPI2_SGE_CHAIN32, *PTR_MPI2_SGE_CHAIN32, ++ Mpi2SGEChain32_t, *pMpi2SGEChain32_t; ++ ++typedef struct _MPI2_SGE_CHAIN64 { ++ U16 Length; ++ U8 NextChainOffset; ++ U8 Flags; ++ U64 Address; ++} MPI2_SGE_CHAIN64, *PTR_MPI2_SGE_CHAIN64, ++ Mpi2SGEChain64_t, *pMpi2SGEChain64_t; ++ ++typedef struct _MPI2_SGE_CHAIN_UNION { ++ U16 Length; ++ U8 NextChainOffset; ++ U8 Flags; ++ union { ++ U32 Address32; ++ U64 Address64; ++ } u; ++} MPI2_SGE_CHAIN_UNION, ++ *PTR_MPI2_SGE_CHAIN_UNION, ++ Mpi2SGEChainUnion_t, ++ *pMpi2SGEChainUnion_t; ++ ++/**************************************************************************** ++* MPI Transaction Context Element structures - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_TRANSACTION32 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[1]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION32, ++ *PTR_MPI2_SGE_TRANSACTION32, ++ Mpi2SGETransaction32_t, ++ *pMpi2SGETransaction32_t; ++ ++typedef struct _MPI2_SGE_TRANSACTION64 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[2]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION64, ++ *PTR_MPI2_SGE_TRANSACTION64, ++ Mpi2SGETransaction64_t, ++ *pMpi2SGETransaction64_t; ++ ++typedef struct _MPI2_SGE_TRANSACTION96 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[3]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION96, *PTR_MPI2_SGE_TRANSACTION96, ++ Mpi2SGETransaction96_t, *pMpi2SGETransaction96_t; ++ ++typedef struct _MPI2_SGE_TRANSACTION128 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[4]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION128, *PTR_MPI2_SGE_TRANSACTION128, ++ Mpi2SGETransaction_t128, *pMpi2SGETransaction_t128; ++ ++typedef struct _MPI2_SGE_TRANSACTION_UNION { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ union { ++ U32 TransactionContext32[1]; ++ U32 TransactionContext64[2]; ++ U32 TransactionContext96[3]; ++ U32 TransactionContext128[4]; ++ } u; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION_UNION, ++ *PTR_MPI2_SGE_TRANSACTION_UNION, ++ Mpi2SGETransactionUnion_t, ++ *pMpi2SGETransactionUnion_t; ++ ++/**************************************************************************** ++* MPI SGE union for IO SGL's - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_MPI_SGE_IO_UNION { ++ union { ++ MPI2_SGE_SIMPLE_UNION Simple; ++ MPI2_SGE_CHAIN_UNION Chain; ++ } u; ++} MPI2_MPI_SGE_IO_UNION, *PTR_MPI2_MPI_SGE_IO_UNION, ++ Mpi2MpiSGEIOUnion_t, *pMpi2MpiSGEIOUnion_t; ++ ++/**************************************************************************** ++* MPI SGE union for SGL's with Simple and Transaction elements - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_TRANS_SIMPLE_UNION { ++ union { ++ MPI2_SGE_SIMPLE_UNION Simple; ++ MPI2_SGE_TRANSACTION_UNION Transaction; ++ } u; ++} MPI2_SGE_TRANS_SIMPLE_UNION, ++ *PTR_MPI2_SGE_TRANS_SIMPLE_UNION, ++ Mpi2SGETransSimpleUnion_t, ++ *pMpi2SGETransSimpleUnion_t; ++ ++/**************************************************************************** ++* All MPI SGE types union ++****************************************************************************/ ++ ++typedef struct _MPI2_MPI_SGE_UNION { ++ union { ++ MPI2_SGE_SIMPLE_UNION Simple; ++ MPI2_SGE_CHAIN_UNION Chain; ++ MPI2_SGE_TRANSACTION_UNION Transaction; ++ } u; ++} MPI2_MPI_SGE_UNION, *PTR_MPI2_MPI_SGE_UNION, ++ Mpi2MpiSgeUnion_t, *pMpi2MpiSgeUnion_t; ++ ++/**************************************************************************** ++* MPI SGE field definition and masks ++****************************************************************************/ ++ ++/*Flags field bit definitions */ ++ ++#define MPI2_SGE_FLAGS_LAST_ELEMENT (0x80) ++#define MPI2_SGE_FLAGS_END_OF_BUFFER (0x40) ++#define MPI2_SGE_FLAGS_ELEMENT_TYPE_MASK (0x30) ++#define MPI2_SGE_FLAGS_LOCAL_ADDRESS (0x08) ++#define MPI2_SGE_FLAGS_DIRECTION (0x04) ++#define MPI2_SGE_FLAGS_ADDRESS_SIZE (0x02) ++#define MPI2_SGE_FLAGS_END_OF_LIST (0x01) ++ ++#define MPI2_SGE_FLAGS_SHIFT (24) ++ ++#define MPI2_SGE_LENGTH_MASK (0x00FFFFFF) ++#define MPI2_SGE_CHAIN_LENGTH_MASK (0x0000FFFF) ++ ++/*Element Type */ ++ ++#define MPI2_SGE_FLAGS_TRANSACTION_ELEMENT (0x00) ++#define MPI2_SGE_FLAGS_SIMPLE_ELEMENT (0x10) ++#define MPI2_SGE_FLAGS_CHAIN_ELEMENT (0x30) ++#define MPI2_SGE_FLAGS_ELEMENT_MASK (0x30) ++ ++/*Address location */ ++ ++#define MPI2_SGE_FLAGS_SYSTEM_ADDRESS (0x00) ++ ++/*Direction */ ++ ++#define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00) ++#define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04) ++ ++#define MPI2_SGE_FLAGS_DEST (MPI2_SGE_FLAGS_IOC_TO_HOST) ++#define MPI2_SGE_FLAGS_SOURCE (MPI2_SGE_FLAGS_HOST_TO_IOC) ++ ++/*Address Size */ ++ ++#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00) ++#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING (0x02) ++ ++/*Context Size */ ++ ++#define MPI2_SGE_FLAGS_32_BIT_CONTEXT (0x00) ++#define MPI2_SGE_FLAGS_64_BIT_CONTEXT (0x02) ++#define MPI2_SGE_FLAGS_96_BIT_CONTEXT (0x04) ++#define MPI2_SGE_FLAGS_128_BIT_CONTEXT (0x06) ++ ++#define MPI2_SGE_CHAIN_OFFSET_MASK (0x00FF0000) ++#define MPI2_SGE_CHAIN_OFFSET_SHIFT (16) ++ ++/**************************************************************************** ++* MPI SGE operation Macros ++****************************************************************************/ ++ ++/*SIMPLE FlagsLength manipulations... */ ++#define MPI2_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_SGE_FLAGS_SHIFT) ++#define MPI2_SGE_GET_FLAGS(f) (((f) & ~MPI2_SGE_LENGTH_MASK) >> \ ++ MPI2_SGE_FLAGS_SHIFT) ++#define MPI2_SGE_LENGTH(f) ((f) & MPI2_SGE_LENGTH_MASK) ++#define MPI2_SGE_CHAIN_LENGTH(f) ((f) & MPI2_SGE_CHAIN_LENGTH_MASK) ++ ++#define MPI2_SGE_SET_FLAGS_LENGTH(f, l) (MPI2_SGE_SET_FLAGS(f) | \ ++ MPI2_SGE_LENGTH(l)) ++ ++#define MPI2_pSGE_GET_FLAGS(psg) MPI2_SGE_GET_FLAGS((psg)->FlagsLength) ++#define MPI2_pSGE_GET_LENGTH(psg) MPI2_SGE_LENGTH((psg)->FlagsLength) ++#define MPI2_pSGE_SET_FLAGS_LENGTH(psg, f, l) ((psg)->FlagsLength = \ ++ MPI2_SGE_SET_FLAGS_LENGTH(f, l)) ++ ++/*CAUTION - The following are READ-MODIFY-WRITE! */ ++#define MPI2_pSGE_SET_FLAGS(psg, f) ((psg)->FlagsLength |= \ ++ MPI2_SGE_SET_FLAGS(f)) ++#define MPI2_pSGE_SET_LENGTH(psg, l) ((psg)->FlagsLength |= \ ++ MPI2_SGE_LENGTH(l)) ++ ++#define MPI2_GET_CHAIN_OFFSET(x) ((x & MPI2_SGE_CHAIN_OFFSET_MASK) >> \ ++ MPI2_SGE_CHAIN_OFFSET_SHIFT) ++ ++/***************************************************************************** ++* ++* Fusion-MPT IEEE Scatter Gather Elements ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* IEEE Simple Element structures ++****************************************************************************/ ++ ++/*MPI2_IEEE_SGE_SIMPLE32 is for MPI v2.0 products only */ ++typedef struct _MPI2_IEEE_SGE_SIMPLE32 { ++ U32 Address; ++ U32 FlagsLength; ++} MPI2_IEEE_SGE_SIMPLE32, *PTR_MPI2_IEEE_SGE_SIMPLE32, ++ Mpi2IeeeSgeSimple32_t, *pMpi2IeeeSgeSimple32_t; ++ ++typedef struct _MPI2_IEEE_SGE_SIMPLE64 { ++ U64 Address; ++ U32 Length; ++ U16 Reserved1; ++ U8 Reserved2; ++ U8 Flags; ++} MPI2_IEEE_SGE_SIMPLE64, *PTR_MPI2_IEEE_SGE_SIMPLE64, ++ Mpi2IeeeSgeSimple64_t, *pMpi2IeeeSgeSimple64_t; ++ ++typedef union _MPI2_IEEE_SGE_SIMPLE_UNION { ++ MPI2_IEEE_SGE_SIMPLE32 Simple32; ++ MPI2_IEEE_SGE_SIMPLE64 Simple64; ++} MPI2_IEEE_SGE_SIMPLE_UNION, ++ *PTR_MPI2_IEEE_SGE_SIMPLE_UNION, ++ Mpi2IeeeSgeSimpleUnion_t, ++ *pMpi2IeeeSgeSimpleUnion_t; ++ ++/**************************************************************************** ++* IEEE Chain Element structures ++****************************************************************************/ ++ ++/*MPI2_IEEE_SGE_CHAIN32 is for MPI v2.0 products only */ ++typedef MPI2_IEEE_SGE_SIMPLE32 MPI2_IEEE_SGE_CHAIN32; ++ ++/*MPI2_IEEE_SGE_CHAIN64 is for MPI v2.0 products only */ ++typedef MPI2_IEEE_SGE_SIMPLE64 MPI2_IEEE_SGE_CHAIN64; ++ ++typedef union _MPI2_IEEE_SGE_CHAIN_UNION { ++ MPI2_IEEE_SGE_CHAIN32 Chain32; ++ MPI2_IEEE_SGE_CHAIN64 Chain64; ++} MPI2_IEEE_SGE_CHAIN_UNION, ++ *PTR_MPI2_IEEE_SGE_CHAIN_UNION, ++ Mpi2IeeeSgeChainUnion_t, ++ *pMpi2IeeeSgeChainUnion_t; ++ ++/*MPI25_IEEE_SGE_CHAIN64 is for MPI v2.5 and later */ ++typedef struct _MPI25_IEEE_SGE_CHAIN64 { ++ U64 Address; ++ U32 Length; ++ U16 Reserved1; ++ U8 NextChainOffset; ++ U8 Flags; ++} MPI25_IEEE_SGE_CHAIN64, ++ *PTR_MPI25_IEEE_SGE_CHAIN64, ++ Mpi25IeeeSgeChain64_t, ++ *pMpi25IeeeSgeChain64_t; ++ ++/**************************************************************************** ++* All IEEE SGE types union ++****************************************************************************/ ++ ++/*MPI2_IEEE_SGE_UNION is for MPI v2.0 products only */ ++typedef struct _MPI2_IEEE_SGE_UNION { ++ union { ++ MPI2_IEEE_SGE_SIMPLE_UNION Simple; ++ MPI2_IEEE_SGE_CHAIN_UNION Chain; ++ } u; ++} MPI2_IEEE_SGE_UNION, *PTR_MPI2_IEEE_SGE_UNION, ++ Mpi2IeeeSgeUnion_t, *pMpi2IeeeSgeUnion_t; ++ ++/**************************************************************************** ++* IEEE SGE union for IO SGL's ++****************************************************************************/ ++ ++typedef union _MPI25_SGE_IO_UNION { ++ MPI2_IEEE_SGE_SIMPLE64 IeeeSimple; ++ MPI25_IEEE_SGE_CHAIN64 IeeeChain; ++} MPI25_SGE_IO_UNION, *PTR_MPI25_SGE_IO_UNION, ++ Mpi25SGEIOUnion_t, *pMpi25SGEIOUnion_t; ++ ++/**************************************************************************** ++* IEEE SGE field definitions and masks ++****************************************************************************/ ++ ++/*Flags field bit definitions */ ++ ++#define MPI2_IEEE_SGE_FLAGS_ELEMENT_TYPE_MASK (0x80) ++#define MPI25_IEEE_SGE_FLAGS_END_OF_LIST (0x40) ++ ++#define MPI2_IEEE32_SGE_FLAGS_SHIFT (24) ++ ++#define MPI2_IEEE32_SGE_LENGTH_MASK (0x00FFFFFF) ++ ++/*Element Type */ ++ ++#define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT (0x00) ++#define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80) ++ ++/*Next Segment Format */ ++ ++#define MPI26_IEEE_SGE_FLAGS_NSF_MASK (0x1C) ++#define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE (0x00) ++ ++/*Data Location Address Space */ ++ ++#define MPI2_IEEE_SGE_FLAGS_ADDR_MASK (0x03) ++#define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00) ++#define MPI2_IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01) ++#define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02) ++#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03) ++#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR (0x03) ++#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR \ ++ (MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR) ++#define MPI26_IEEE_SGE_FLAGS_IOCCTL_ADDR (0x02) ++ ++/**************************************************************************** ++* IEEE SGE operation Macros ++****************************************************************************/ ++ ++/*SIMPLE FlagsLength manipulations... */ ++#define MPI2_IEEE32_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_IEEE32_SGE_FLAGS_SHIFT) ++#define MPI2_IEEE32_SGE_GET_FLAGS(f) (((f) & ~MPI2_IEEE32_SGE_LENGTH_MASK) \ ++ >> MPI2_IEEE32_SGE_FLAGS_SHIFT) ++#define MPI2_IEEE32_SGE_LENGTH(f) ((f) & MPI2_IEEE32_SGE_LENGTH_MASK) ++ ++#define MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l) (MPI2_IEEE32_SGE_SET_FLAGS(f) |\ ++ MPI2_IEEE32_SGE_LENGTH(l)) ++ ++#define MPI2_IEEE32_pSGE_GET_FLAGS(psg) \ ++ MPI2_IEEE32_SGE_GET_FLAGS((psg)->FlagsLength) ++#define MPI2_IEEE32_pSGE_GET_LENGTH(psg) \ ++ MPI2_IEEE32_SGE_LENGTH((psg)->FlagsLength) ++#define MPI2_IEEE32_pSGE_SET_FLAGS_LENGTH(psg, f, l) ((psg)->FlagsLength = \ ++ MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l)) ++ ++/*CAUTION - The following are READ-MODIFY-WRITE! */ ++#define MPI2_IEEE32_pSGE_SET_FLAGS(psg, f) ((psg)->FlagsLength |= \ ++ MPI2_IEEE32_SGE_SET_FLAGS(f)) ++#define MPI2_IEEE32_pSGE_SET_LENGTH(psg, l) ((psg)->FlagsLength |= \ ++ MPI2_IEEE32_SGE_LENGTH(l)) ++ ++/***************************************************************************** ++* ++* Fusion-MPT MPI/IEEE Scatter Gather Unions ++* ++*****************************************************************************/ ++ ++typedef union _MPI2_SIMPLE_SGE_UNION { ++ MPI2_SGE_SIMPLE_UNION MpiSimple; ++ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; ++} MPI2_SIMPLE_SGE_UNION, *PTR_MPI2_SIMPLE_SGE_UNION, ++ Mpi2SimpleSgeUntion_t, *pMpi2SimpleSgeUntion_t; ++ ++typedef union _MPI2_SGE_IO_UNION { ++ MPI2_SGE_SIMPLE_UNION MpiSimple; ++ MPI2_SGE_CHAIN_UNION MpiChain; ++ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; ++ MPI2_IEEE_SGE_CHAIN_UNION IeeeChain; ++} MPI2_SGE_IO_UNION, *PTR_MPI2_SGE_IO_UNION, ++ Mpi2SGEIOUnion_t, *pMpi2SGEIOUnion_t; ++ ++/**************************************************************************** ++* ++* Values for SGLFlags field, used in many request messages with an SGL ++* ++****************************************************************************/ ++ ++/*values for MPI SGL Data Location Address Space subfield */ ++#define MPI2_SGLFLAGS_ADDRESS_SPACE_MASK (0x0C) ++#define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE (0x00) ++#define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE (0x04) ++#define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) ++#define MPI26_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) ++#define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE (0x0C) ++/*values for SGL Type subfield */ ++#define MPI2_SGLFLAGS_SGL_TYPE_MASK (0x03) ++#define MPI2_SGLFLAGS_SGL_TYPE_MPI (0x00) ++#define MPI2_SGLFLAGS_SGL_TYPE_IEEE32 (0x01) ++#define MPI2_SGLFLAGS_SGL_TYPE_IEEE64 (0x02) ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +new file mode 100644 +index 0000000..95356a8 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +@@ -0,0 +1,3493 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_cnfg.h ++ * Title: MPI Configuration messages and pages ++ * Creation Date: November 10, 2006 ++ * ++ * mpi2_cnfg.h Version: 02.00.35 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-04-07 02.00.01 Added defines for SAS IO Unit Page 2 PhyFlags. ++ * Added Manufacturing Page 11. ++ * Added MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE ++ * define. ++ * 06-26-07 02.00.02 Adding generic structure for product-specific ++ * Manufacturing pages: MPI2_CONFIG_PAGE_MANUFACTURING_PS. ++ * Rework of BIOS Page 2 configuration page. ++ * Fixed MPI2_BIOSPAGE2_BOOT_DEVICE to be a union of the ++ * forms. ++ * Added configuration pages IOC Page 8 and Driver ++ * Persistent Mapping Page 0. ++ * 08-31-07 02.00.03 Modified configuration pages dealing with Integrated ++ * RAID (Manufacturing Page 4, RAID Volume Pages 0 and 1, ++ * RAID Physical Disk Pages 0 and 1, RAID Configuration ++ * Page 0). ++ * Added new value for AccessStatus field of SAS Device ++ * Page 0 (_SATA_NEEDS_INITIALIZATION). ++ * 10-31-07 02.00.04 Added missing SEPDevHandle field to ++ * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. ++ * 12-18-07 02.00.05 Modified IO Unit Page 0 to use 32-bit version fields for ++ * NVDATA. ++ * Modified IOC Page 7 to use masks and added field for ++ * SASBroadcastPrimitiveMasks. ++ * Added MPI2_CONFIG_PAGE_BIOS_4. ++ * Added MPI2_CONFIG_PAGE_LOG_0. ++ * 02-29-08 02.00.06 Modified various names to make them 32-character unique. ++ * Added SAS Device IDs. ++ * Updated Integrated RAID configuration pages including ++ * Manufacturing Page 4, IOC Page 6, and RAID Configuration ++ * Page 0. ++ * 05-21-08 02.00.07 Added define MPI2_MANPAGE4_MIX_SSD_SAS_SATA. ++ * Added define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION. ++ * Fixed define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING. ++ * Added missing MaxNumRoutedSasAddresses field to ++ * MPI2_CONFIG_PAGE_EXPANDER_0. ++ * Added SAS Port Page 0. ++ * Modified structure layout for ++ * MPI2_CONFIG_PAGE_DRIVER_MAPPING_0. ++ * 06-27-08 02.00.08 Changed MPI2_CONFIG_PAGE_RD_PDISK_1 to use ++ * MPI2_RAID_PHYS_DISK1_PATH_MAX to size the array. ++ * 10-02-08 02.00.09 Changed MPI2_RAID_PGAD_CONFIGNUM_MASK from 0x0000FFFF ++ * to 0x000000FF. ++ * Added two new values for the Physical Disk Coercion Size ++ * bits in the Flags field of Manufacturing Page 4. ++ * Added product-specific Manufacturing pages 16 to 31. ++ * Modified Flags bits for controlling write cache on SATA ++ * drives in IO Unit Page 1. ++ * Added new bit to AdditionalControlFlags of SAS IO Unit ++ * Page 1 to control Invalid Topology Correction. ++ * Added additional defines for RAID Volume Page 0 ++ * VolumeStatusFlags field. ++ * Modified meaning of RAID Volume Page 0 VolumeSettings ++ * define for auto-configure of hot-swap drives. ++ * Added SupportedPhysDisks field to RAID Volume Page 1 and ++ * added related defines. ++ * Added PhysDiskAttributes field (and related defines) to ++ * RAID Physical Disk Page 0. ++ * Added MPI2_SAS_PHYINFO_PHY_VACANT define. ++ * Added three new DiscoveryStatus bits for SAS IO Unit ++ * Page 0 and SAS Expander Page 0. ++ * Removed multiplexing information from SAS IO Unit pages. ++ * Added BootDeviceWaitTime field to SAS IO Unit Page 4. ++ * Removed Zone Address Resolved bit from PhyInfo and from ++ * Expander Page 0 Flags field. ++ * Added two new AccessStatus values to SAS Device Page 0 ++ * for indicating routing problems. Added 3 reserved words ++ * to this page. ++ * 01-19-09 02.00.10 Fixed defines for GPIOVal field of IO Unit Page 3. ++ * Inserted missing reserved field into structure for IOC ++ * Page 6. ++ * Added more pending task bits to RAID Volume Page 0 ++ * VolumeStatusFlags defines. ++ * Added MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED define. ++ * Added a new DiscoveryStatus bit for SAS IO Unit Page 0 ++ * and SAS Expander Page 0 to flag a downstream initiator ++ * when in simplified routing mode. ++ * Removed SATA Init Failure defines for DiscoveryStatus ++ * fields of SAS IO Unit Page 0 and SAS Expander Page 0. ++ * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define. ++ * Added PortGroups, DmaGroup, and ControlGroup fields to ++ * SAS Device Page 0. ++ * 05-06-09 02.00.11 Added structures and defines for IO Unit Page 5 and IO ++ * Unit Page 6. ++ * Added expander reduced functionality data to SAS ++ * Expander Page 0. ++ * Added SAS PHY Page 2 and SAS PHY Page 3. ++ * 07-30-09 02.00.12 Added IO Unit Page 7. ++ * Added new device ids. ++ * Added SAS IO Unit Page 5. ++ * Added partial and slumber power management capable flags ++ * to SAS Device Page 0 Flags field. ++ * Added PhyInfo defines for power condition. ++ * Added Ethernet configuration pages. ++ * 10-28-09 02.00.13 Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY. ++ * Added SAS PHY Page 4 structure and defines. ++ * 02-10-10 02.00.14 Modified the comments for the configuration page ++ * structures that contain an array of data. The host ++ * should use the "count" field in the page data (e.g. the ++ * NumPhys field) to determine the number of valid elements ++ * in the array. ++ * Added/modified some MPI2_MFGPAGE_DEVID_SAS defines. ++ * Added PowerManagementCapabilities to IO Unit Page 7. ++ * Added PortWidthModGroup field to ++ * MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS. ++ * Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines. ++ * Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines. ++ * Added MPI2_CONFIG_PAGE_SASIOUNIT_8 and related defines. ++ * 05-12-10 02.00.15 Added MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT ++ * define. ++ * Added MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE define. ++ * Added MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY define. ++ * 08-11-10 02.00.16 Removed IO Unit Page 1 device path (multi-pathing) ++ * defines. ++ * 11-10-10 02.00.17 Added ReceptacleID field (replacing Reserved1) to ++ * MPI2_MANPAGE7_CONNECTOR_INFO and reworked defines for ++ * the Pinout field. ++ * Added BoardTemperature and BoardTemperatureUnits fields ++ * to MPI2_CONFIG_PAGE_IO_UNIT_7. ++ * Added MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING define ++ * and MPI2_CONFIG_PAGE_EXT_MAN_PS structure. ++ * 02-23-11 02.00.18 Added ProxyVF_ID field to MPI2_CONFIG_REQUEST. ++ * Added IO Unit Page 8, IO Unit Page 9, ++ * and IO Unit Page 10. ++ * Added SASNotifyPrimitiveMasks field to ++ * MPI2_CONFIG_PAGE_IOC_7. ++ * 03-09-11 02.00.19 Fixed IO Unit Page 10 (to match the spec). ++ * 05-25-11 02.00.20 Cleaned up a few comments. ++ * 08-24-11 02.00.21 Marked the IO Unit Page 7 PowerManagementCapabilities ++ * for PCIe link as obsolete. ++ * Added SpinupFlags field containing a Disable Spin-up bit ++ * to the MPI2_SAS_IOUNIT4_SPINUP_GROUP fields of SAS IO ++ * Unit Page 4. ++ * 11-18-11 02.00.22 Added define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT. ++ * Added UEFIVersion field to BIOS Page 1 and defined new ++ * BiosOptions bits. ++ * Incorporating additions for MPI v2.5. ++ * 11-27-12 02.00.23 Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER. ++ * Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID. ++ * 12-20-12 02.00.24 Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as ++ * obsolete for MPI v2.5 and later. ++ * Added some defines for 12G SAS speeds. ++ * 04-09-13 02.00.25 Added MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK. ++ * Fixed MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS to ++ * match the specification. ++ * 08-19-13 02.00.26 Added reserved words to MPI2_CONFIG_PAGE_IO_UNIT_7 for ++ * future use. ++ * 12-05-13 02.00.27 Added MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL for ++ * MPI2_CONFIG_PAGE_MAN_7. ++ * Added EnclosureLevel and ConnectorName fields to ++ * MPI2_CONFIG_PAGE_SAS_DEV_0. ++ * Added MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID for ++ * MPI2_CONFIG_PAGE_SAS_DEV_0. ++ * Added EnclosureLevel field to ++ * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. ++ * Added MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID for ++ * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. ++ * 01-08-14 02.00.28 Added more defines for the BiosOptions field of ++ * MPI2_CONFIG_PAGE_BIOS_1. ++ * 06-13-14 02.00.29 Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and ++ * more defines for the BiosOptions field. ++ * 11-18-14 02.00.30 Updated copyright information. ++ * Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG. ++ * Added AdapterOrderAux fields to BIOS Page 3. ++ * 03-16-15 02.00.31 Updated for MPI v2.6. ++ * Added Flags field to IO Unit Page 7. ++ * Added new SAS Phy Event codes ++ * 05-25-15 02.00.33 Added more defines for the BiosOptions field of ++ * MPI2_CONFIG_PAGE_BIOS_1. ++ * 08-25-15 02.00.34 Bumped Header Version. ++ * 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_CNFG_H ++#define MPI2_CNFG_H ++ ++/***************************************************************************** ++* Configuration Page Header and defines ++*****************************************************************************/ ++ ++/*Config Page Header */ ++typedef struct _MPI2_CONFIG_PAGE_HEADER { ++ U8 PageVersion; /*0x00 */ ++ U8 PageLength; /*0x01 */ ++ U8 PageNumber; /*0x02 */ ++ U8 PageType; /*0x03 */ ++} MPI2_CONFIG_PAGE_HEADER, *PTR_MPI2_CONFIG_PAGE_HEADER, ++ Mpi2ConfigPageHeader_t, *pMpi2ConfigPageHeader_t; ++ ++typedef union _MPI2_CONFIG_PAGE_HEADER_UNION { ++ MPI2_CONFIG_PAGE_HEADER Struct; ++ U8 Bytes[4]; ++ U16 Word16[2]; ++ U32 Word32; ++} MPI2_CONFIG_PAGE_HEADER_UNION, *PTR_MPI2_CONFIG_PAGE_HEADER_UNION, ++ Mpi2ConfigPageHeaderUnion, *pMpi2ConfigPageHeaderUnion; ++ ++/*Extended Config Page Header */ ++typedef struct _MPI2_CONFIG_EXTENDED_PAGE_HEADER { ++ U8 PageVersion; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 PageNumber; /*0x02 */ ++ U8 PageType; /*0x03 */ ++ U16 ExtPageLength; /*0x04 */ ++ U8 ExtPageType; /*0x06 */ ++ U8 Reserved2; /*0x07 */ ++} MPI2_CONFIG_EXTENDED_PAGE_HEADER, ++ *PTR_MPI2_CONFIG_EXTENDED_PAGE_HEADER, ++ Mpi2ConfigExtendedPageHeader_t, ++ *pMpi2ConfigExtendedPageHeader_t; ++ ++typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION { ++ MPI2_CONFIG_PAGE_HEADER Struct; ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Ext; ++ U8 Bytes[8]; ++ U16 Word16[4]; ++ U32 Word32[2]; ++} MPI2_CONFIG_EXT_PAGE_HEADER_UNION, ++ *PTR_MPI2_CONFIG_EXT_PAGE_HEADER_UNION, ++ Mpi2ConfigPageExtendedHeaderUnion, ++ *pMpi2ConfigPageExtendedHeaderUnion; ++ ++ ++/*PageType field values */ ++#define MPI2_CONFIG_PAGEATTR_READ_ONLY (0x00) ++#define MPI2_CONFIG_PAGEATTR_CHANGEABLE (0x10) ++#define MPI2_CONFIG_PAGEATTR_PERSISTENT (0x20) ++#define MPI2_CONFIG_PAGEATTR_MASK (0xF0) ++ ++#define MPI2_CONFIG_PAGETYPE_IO_UNIT (0x00) ++#define MPI2_CONFIG_PAGETYPE_IOC (0x01) ++#define MPI2_CONFIG_PAGETYPE_BIOS (0x02) ++#define MPI2_CONFIG_PAGETYPE_RAID_VOLUME (0x08) ++#define MPI2_CONFIG_PAGETYPE_MANUFACTURING (0x09) ++#define MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A) ++#define MPI2_CONFIG_PAGETYPE_EXTENDED (0x0F) ++#define MPI2_CONFIG_PAGETYPE_MASK (0x0F) ++ ++#define MPI2_CONFIG_TYPENUM_MASK (0x0FFF) ++ ++ ++/*ExtPageType field values */ ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT (0x10) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER (0x11) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE (0x12) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_PHY (0x13) ++#define MPI2_CONFIG_EXTPAGETYPE_LOG (0x14) ++#define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE (0x15) ++#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16) ++#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18) ++#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET (0x19) ++#define MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING (0x1A) ++ ++ ++/***************************************************************************** ++* PageAddress defines ++*****************************************************************************/ ++ ++/*RAID Volume PageAddress format */ ++#define MPI2_RAID_VOLUME_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) ++#define MPI2_RAID_VOLUME_PGAD_FORM_HANDLE (0x10000000) ++ ++#define MPI2_RAID_VOLUME_PGAD_HANDLE_MASK (0x0000FFFF) ++ ++ ++/*RAID Physical Disk PageAddress format */ ++#define MPI2_PHYSDISK_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM (0x00000000) ++#define MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM (0x10000000) ++#define MPI2_PHYSDISK_PGAD_FORM_DEVHANDLE (0x20000000) ++ ++#define MPI2_PHYSDISK_PGAD_PHYSDISKNUM_MASK (0x000000FF) ++#define MPI2_PHYSDISK_PGAD_DEVHANDLE_MASK (0x0000FFFF) ++ ++ ++/*SAS Expander PageAddress format */ ++#define MPI2_SAS_EXPAND_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL (0x00000000) ++#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM (0x10000000) ++#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL (0x20000000) ++ ++#define MPI2_SAS_EXPAND_PGAD_HANDLE_MASK (0x0000FFFF) ++#define MPI2_SAS_EXPAND_PGAD_PHYNUM_MASK (0x00FF0000) ++#define MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT (16) ++ ++ ++/*SAS Device PageAddress format */ ++#define MPI2_SAS_DEVICE_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) ++#define MPI2_SAS_DEVICE_PGAD_FORM_HANDLE (0x20000000) ++ ++#define MPI2_SAS_DEVICE_PGAD_HANDLE_MASK (0x0000FFFF) ++ ++ ++/*SAS PHY PageAddress format */ ++#define MPI2_SAS_PHY_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER (0x00000000) ++#define MPI2_SAS_PHY_PGAD_FORM_PHY_TBL_INDEX (0x10000000) ++ ++#define MPI2_SAS_PHY_PGAD_PHY_NUMBER_MASK (0x000000FF) ++#define MPI2_SAS_PHY_PGAD_PHY_TBL_INDEX_MASK (0x0000FFFF) ++ ++ ++/*SAS Port PageAddress format */ ++#define MPI2_SASPORT_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SASPORT_PGAD_FORM_GET_NEXT_PORT (0x00000000) ++#define MPI2_SASPORT_PGAD_FORM_PORT_NUM (0x10000000) ++ ++#define MPI2_SASPORT_PGAD_PORTNUMBER_MASK (0x00000FFF) ++ ++ ++/*SAS Enclosure PageAddress format */ ++#define MPI2_SAS_ENCLOS_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) ++#define MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE (0x10000000) ++ ++#define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK (0x0000FFFF) ++ ++ ++/*RAID Configuration PageAddress format */ ++#define MPI2_RAID_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM (0x00000000) ++#define MPI2_RAID_PGAD_FORM_CONFIGNUM (0x10000000) ++#define MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG (0x20000000) ++ ++#define MPI2_RAID_PGAD_CONFIGNUM_MASK (0x000000FF) ++ ++ ++/*Driver Persistent Mapping PageAddress format */ ++#define MPI2_DPM_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_DPM_PGAD_FORM_ENTRY_RANGE (0x00000000) ++ ++#define MPI2_DPM_PGAD_ENTRY_COUNT_MASK (0x0FFF0000) ++#define MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT (16) ++#define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF) ++ ++ ++/*Ethernet PageAddress format */ ++#define MPI2_ETHERNET_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_ETHERNET_PGAD_FORM_IF_NUM (0x00000000) ++ ++#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF) ++ ++ ++/**************************************************************************** ++* Configuration messages ++****************************************************************************/ ++ ++/*Configuration Request Message */ ++typedef struct _MPI2_CONFIG_REQUEST { ++ U8 Action; /*0x00 */ ++ U8 SGLFlags; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 ExtPageLength; /*0x04 */ ++ U8 ExtPageType; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U8 Reserved2; /*0x0C */ ++ U8 ProxyVF_ID; /*0x0D */ ++ U16 Reserved4; /*0x0E */ ++ U32 Reserved3; /*0x10 */ ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x14 */ ++ U32 PageAddress; /*0x18 */ ++ MPI2_SGE_IO_UNION PageBufferSGE; /*0x1C */ ++} MPI2_CONFIG_REQUEST, *PTR_MPI2_CONFIG_REQUEST, ++ Mpi2ConfigRequest_t, *pMpi2ConfigRequest_t; ++ ++/*values for the Action field */ ++#define MPI2_CONFIG_ACTION_PAGE_HEADER (0x00) ++#define MPI2_CONFIG_ACTION_PAGE_READ_CURRENT (0x01) ++#define MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT (0x02) ++#define MPI2_CONFIG_ACTION_PAGE_DEFAULT (0x03) ++#define MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM (0x04) ++#define MPI2_CONFIG_ACTION_PAGE_READ_DEFAULT (0x05) ++#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06) ++#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07) ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++ ++/*Config Reply Message */ ++typedef struct _MPI2_CONFIG_REPLY { ++ U8 Action; /*0x00 */ ++ U8 SGLFlags; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 ExtPageLength; /*0x04 */ ++ U8 ExtPageType; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U16 Reserved2; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x14 */ ++} MPI2_CONFIG_REPLY, *PTR_MPI2_CONFIG_REPLY, ++ Mpi2ConfigReply_t, *pMpi2ConfigReply_t; ++ ++ ++ ++/***************************************************************************** ++* ++* C o n f i g u r a t i o n P a g e s ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* Manufacturing Config pages ++****************************************************************************/ ++ ++#define MPI2_MFGPAGE_VENDORID_LSI (0x1000) ++ ++/*MPI v2.0 SAS products */ ++#define MPI2_MFGPAGE_DEVID_SAS2004 (0x0070) ++#define MPI2_MFGPAGE_DEVID_SAS2008 (0x0072) ++#define MPI2_MFGPAGE_DEVID_SAS2108_1 (0x0074) ++#define MPI2_MFGPAGE_DEVID_SAS2108_2 (0x0076) ++#define MPI2_MFGPAGE_DEVID_SAS2108_3 (0x0077) ++#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) ++#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) ++ ++#define MPI2_MFGPAGE_DEVID_SSS6200 (0x007E) ++ ++#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) ++#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) ++#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) ++#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083) ++#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084) ++#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085) ++#define MPI2_MFGPAGE_DEVID_SAS2308_1 (0x0086) ++#define MPI2_MFGPAGE_DEVID_SAS2308_2 (0x0087) ++#define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E) ++ ++/*MPI v2.5 SAS products */ ++#define MPI25_MFGPAGE_DEVID_SAS3004 (0x0096) ++#define MPI25_MFGPAGE_DEVID_SAS3008 (0x0097) ++#define MPI25_MFGPAGE_DEVID_SAS3108_1 (0x0090) ++#define MPI25_MFGPAGE_DEVID_SAS3108_2 (0x0091) ++#define MPI25_MFGPAGE_DEVID_SAS3108_5 (0x0094) ++#define MPI25_MFGPAGE_DEVID_SAS3108_6 (0x0095) ++ ++/* MPI v2.6 SAS Products */ ++#define MPI26_MFGPAGE_DEVID_SAS3216 (0x00C9) ++#define MPI26_MFGPAGE_DEVID_SAS3224 (0x00C4) ++#define MPI26_MFGPAGE_DEVID_SAS3316_1 (0x00C5) ++#define MPI26_MFGPAGE_DEVID_SAS3316_2 (0x00C6) ++#define MPI26_MFGPAGE_DEVID_SAS3316_3 (0x00C7) ++#define MPI26_MFGPAGE_DEVID_SAS3316_4 (0x00C8) ++#define MPI26_MFGPAGE_DEVID_SAS3324_1 (0x00C0) ++#define MPI26_MFGPAGE_DEVID_SAS3324_2 (0x00C1) ++#define MPI26_MFGPAGE_DEVID_SAS3324_3 (0x00C2) ++#define MPI26_MFGPAGE_DEVID_SAS3324_4 (0x00C3) ++ ++/*Manufacturing Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 ChipName[16]; /*0x04 */ ++ U8 ChipRevision[8]; /*0x14 */ ++ U8 BoardName[16]; /*0x1C */ ++ U8 BoardAssembly[16]; /*0x2C */ ++ U8 BoardTracerNumber[16]; /*0x3C */ ++} MPI2_CONFIG_PAGE_MAN_0, ++ *PTR_MPI2_CONFIG_PAGE_MAN_0, ++ Mpi2ManufacturingPage0_t, ++ *pMpi2ManufacturingPage0_t; ++ ++#define MPI2_MANUFACTURING0_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 VPD[256]; /*0x04 */ ++} MPI2_CONFIG_PAGE_MAN_1, ++ *PTR_MPI2_CONFIG_PAGE_MAN_1, ++ Mpi2ManufacturingPage1_t, ++ *pMpi2ManufacturingPage1_t; ++ ++#define MPI2_MANUFACTURING1_PAGEVERSION (0x00) ++ ++ ++typedef struct _MPI2_CHIP_REVISION_ID { ++ U16 DeviceID; /*0x00 */ ++ U8 PCIRevisionID; /*0x02 */ ++ U8 Reserved; /*0x03 */ ++} MPI2_CHIP_REVISION_ID, *PTR_MPI2_CHIP_REVISION_ID, ++ Mpi2ChipRevisionId_t, *pMpi2ChipRevisionId_t; ++ ++ ++/*Manufacturing Page 2 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check Header.PageLength at runtime. ++ */ ++#ifndef MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS ++#define MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_2 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ MPI2_CHIP_REVISION_ID ChipId; /*0x04 */ ++ U32 ++ HwSettings[MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS];/*0x08 */ ++} MPI2_CONFIG_PAGE_MAN_2, ++ *PTR_MPI2_CONFIG_PAGE_MAN_2, ++ Mpi2ManufacturingPage2_t, ++ *pMpi2ManufacturingPage2_t; ++ ++#define MPI2_MANUFACTURING2_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 3 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check Header.PageLength at runtime. ++ */ ++#ifndef MPI2_MAN_PAGE_3_INFO_WORDS ++#define MPI2_MAN_PAGE_3_INFO_WORDS (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_3 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ MPI2_CHIP_REVISION_ID ChipId; /*0x04 */ ++ U32 ++ Info[MPI2_MAN_PAGE_3_INFO_WORDS];/*0x08 */ ++} MPI2_CONFIG_PAGE_MAN_3, ++ *PTR_MPI2_CONFIG_PAGE_MAN_3, ++ Mpi2ManufacturingPage3_t, ++ *pMpi2ManufacturingPage3_t; ++ ++#define MPI2_MANUFACTURING3_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 4 */ ++ ++typedef struct _MPI2_MANPAGE4_PWR_SAVE_SETTINGS { ++ U8 PowerSaveFlags; /*0x00 */ ++ U8 InternalOperationsSleepTime; /*0x01 */ ++ U8 InternalOperationsRunTime; /*0x02 */ ++ U8 HostIdleTime; /*0x03 */ ++} MPI2_MANPAGE4_PWR_SAVE_SETTINGS, ++ *PTR_MPI2_MANPAGE4_PWR_SAVE_SETTINGS, ++ Mpi2ManPage4PwrSaveSettings_t, ++ *pMpi2ManPage4PwrSaveSettings_t; ++ ++/*defines for the PowerSaveFlags field */ ++#define MPI2_MANPAGE4_MASK_POWERSAVE_MODE (0x03) ++#define MPI2_MANPAGE4_POWERSAVE_MODE_DISABLED (0x00) ++#define MPI2_MANPAGE4_CUSTOM_POWERSAVE_MODE (0x01) ++#define MPI2_MANPAGE4_FULL_POWERSAVE_MODE (0x02) ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_4 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Flags; /*0x08 */ ++ U8 InquirySize; /*0x0C */ ++ U8 Reserved2; /*0x0D */ ++ U16 Reserved3; /*0x0E */ ++ U8 InquiryData[56]; /*0x10 */ ++ U32 RAID0VolumeSettings; /*0x48 */ ++ U32 RAID1EVolumeSettings; /*0x4C */ ++ U32 RAID1VolumeSettings; /*0x50 */ ++ U32 RAID10VolumeSettings; /*0x54 */ ++ U32 Reserved4; /*0x58 */ ++ U32 Reserved5; /*0x5C */ ++ MPI2_MANPAGE4_PWR_SAVE_SETTINGS PowerSaveSettings; /*0x60 */ ++ U8 MaxOCEDisks; /*0x64 */ ++ U8 ResyncRate; /*0x65 */ ++ U16 DataScrubDuration; /*0x66 */ ++ U8 MaxHotSpares; /*0x68 */ ++ U8 MaxPhysDisksPerVol; /*0x69 */ ++ U8 MaxPhysDisks; /*0x6A */ ++ U8 MaxVolumes; /*0x6B */ ++} MPI2_CONFIG_PAGE_MAN_4, ++ *PTR_MPI2_CONFIG_PAGE_MAN_4, ++ Mpi2ManufacturingPage4_t, ++ *pMpi2ManufacturingPage4_t; ++ ++#define MPI2_MANUFACTURING4_PAGEVERSION (0x0A) ++ ++/*Manufacturing Page 4 Flags field */ ++#define MPI2_MANPAGE4_METADATA_SIZE_MASK (0x00030000) ++#define MPI2_MANPAGE4_METADATA_512MB (0x00000000) ++ ++#define MPI2_MANPAGE4_MIX_SSD_SAS_SATA (0x00008000) ++#define MPI2_MANPAGE4_MIX_SSD_AND_NON_SSD (0x00004000) ++#define MPI2_MANPAGE4_HIDE_PHYSDISK_NON_IR (0x00002000) ++ ++#define MPI2_MANPAGE4_MASK_PHYSDISK_COERCION (0x00001C00) ++#define MPI2_MANPAGE4_PHYSDISK_COERCION_1GB (0x00000000) ++#define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION (0x00000400) ++#define MPI2_MANPAGE4_PHYSDISK_ADAPTIVE_COERCION (0x00000800) ++#define MPI2_MANPAGE4_PHYSDISK_ZERO_COERCION (0x00000C00) ++ ++#define MPI2_MANPAGE4_MASK_BAD_BLOCK_MARKING (0x00000300) ++#define MPI2_MANPAGE4_DEFAULT_BAD_BLOCK_MARKING (0x00000000) ++#define MPI2_MANPAGE4_TABLE_BAD_BLOCK_MARKING (0x00000100) ++#define MPI2_MANPAGE4_WRITE_LONG_BAD_BLOCK_MARKING (0x00000200) ++ ++#define MPI2_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x00000080) ++#define MPI2_MANPAGE4_RAID10_DISABLE (0x00000040) ++#define MPI2_MANPAGE4_RAID1E_DISABLE (0x00000020) ++#define MPI2_MANPAGE4_RAID1_DISABLE (0x00000010) ++#define MPI2_MANPAGE4_RAID0_DISABLE (0x00000008) ++#define MPI2_MANPAGE4_IR_MODEPAGE8_DISABLE (0x00000004) ++#define MPI2_MANPAGE4_IM_RESYNC_CACHE_ENABLE (0x00000002) ++#define MPI2_MANPAGE4_IR_NO_MIX_SAS_SATA (0x00000001) ++ ++ ++/*Manufacturing Page 5 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_MAN_PAGE_5_PHY_ENTRIES ++#define MPI2_MAN_PAGE_5_PHY_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_MANUFACTURING5_ENTRY { ++ U64 WWID; /*0x00 */ ++ U64 DeviceName; /*0x08 */ ++} MPI2_MANUFACTURING5_ENTRY, ++ *PTR_MPI2_MANUFACTURING5_ENTRY, ++ Mpi2Manufacturing5Entry_t, ++ *pMpi2Manufacturing5Entry_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_5 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhys; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++ MPI2_MANUFACTURING5_ENTRY ++ Phy[MPI2_MAN_PAGE_5_PHY_ENTRIES];/*0x08 */ ++} MPI2_CONFIG_PAGE_MAN_5, ++ *PTR_MPI2_CONFIG_PAGE_MAN_5, ++ Mpi2ManufacturingPage5_t, ++ *pMpi2ManufacturingPage5_t; ++ ++#define MPI2_MANUFACTURING5_PAGEVERSION (0x03) ++ ++ ++/*Manufacturing Page 6 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_6 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 ProductSpecificInfo;/*0x04 */ ++} MPI2_CONFIG_PAGE_MAN_6, ++ *PTR_MPI2_CONFIG_PAGE_MAN_6, ++ Mpi2ManufacturingPage6_t, ++ *pMpi2ManufacturingPage6_t; ++ ++#define MPI2_MANUFACTURING6_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 7 */ ++ ++typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO { ++ U32 Pinout; /*0x00 */ ++ U8 Connector[16]; /*0x04 */ ++ U8 Location; /*0x14 */ ++ U8 ReceptacleID; /*0x15 */ ++ U16 Slot; /*0x16 */ ++ U32 Reserved2; /*0x18 */ ++} MPI2_MANPAGE7_CONNECTOR_INFO, ++ *PTR_MPI2_MANPAGE7_CONNECTOR_INFO, ++ Mpi2ManPage7ConnectorInfo_t, ++ *pMpi2ManPage7ConnectorInfo_t; ++ ++/*defines for the Pinout field */ ++#define MPI2_MANPAGE7_PINOUT_LANE_MASK (0x0000FF00) ++#define MPI2_MANPAGE7_PINOUT_LANE_SHIFT (8) ++ ++#define MPI2_MANPAGE7_PINOUT_TYPE_MASK (0x000000FF) ++#define MPI2_MANPAGE7_PINOUT_TYPE_UNKNOWN (0x00) ++#define MPI2_MANPAGE7_PINOUT_SATA_SINGLE (0x01) ++#define MPI2_MANPAGE7_PINOUT_SFF_8482 (0x02) ++#define MPI2_MANPAGE7_PINOUT_SFF_8486 (0x03) ++#define MPI2_MANPAGE7_PINOUT_SFF_8484 (0x04) ++#define MPI2_MANPAGE7_PINOUT_SFF_8087 (0x05) ++#define MPI2_MANPAGE7_PINOUT_SFF_8643_4I (0x06) ++#define MPI2_MANPAGE7_PINOUT_SFF_8643_8I (0x07) ++#define MPI2_MANPAGE7_PINOUT_SFF_8470 (0x08) ++#define MPI2_MANPAGE7_PINOUT_SFF_8088 (0x09) ++#define MPI2_MANPAGE7_PINOUT_SFF_8644_4X (0x0A) ++#define MPI2_MANPAGE7_PINOUT_SFF_8644_8X (0x0B) ++#define MPI2_MANPAGE7_PINOUT_SFF_8644_16X (0x0C) ++#define MPI2_MANPAGE7_PINOUT_SFF_8436 (0x0D) ++ ++/*defines for the Location field */ ++#define MPI2_MANPAGE7_LOCATION_UNKNOWN (0x01) ++#define MPI2_MANPAGE7_LOCATION_INTERNAL (0x02) ++#define MPI2_MANPAGE7_LOCATION_EXTERNAL (0x04) ++#define MPI2_MANPAGE7_LOCATION_SWITCHABLE (0x08) ++#define MPI2_MANPAGE7_LOCATION_AUTO (0x10) ++#define MPI2_MANPAGE7_LOCATION_NOT_PRESENT (0x20) ++#define MPI2_MANPAGE7_LOCATION_NOT_CONNECTED (0x80) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_MANPAGE7_CONNECTOR_INFO_MAX ++#define MPI2_MANPAGE7_CONNECTOR_INFO_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_7 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U32 Flags; /*0x0C */ ++ U8 EnclosureName[16]; /*0x10 */ ++ U8 NumPhys; /*0x20 */ ++ U8 Reserved3; /*0x21 */ ++ U16 Reserved4; /*0x22 */ ++ MPI2_MANPAGE7_CONNECTOR_INFO ++ ConnectorInfo[MPI2_MANPAGE7_CONNECTOR_INFO_MAX]; /*0x24 */ ++} MPI2_CONFIG_PAGE_MAN_7, ++ *PTR_MPI2_CONFIG_PAGE_MAN_7, ++ Mpi2ManufacturingPage7_t, ++ *pMpi2ManufacturingPage7_t; ++ ++#define MPI2_MANUFACTURING7_PAGEVERSION (0x01) ++ ++/*defines for the Flags field */ ++#define MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL (0x00000008) ++#define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002) ++#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) ++ ++ ++/* ++ *Generic structure to use for product-specific manufacturing pages ++ *(currently Manufacturing Page 8 through Manufacturing Page 31). ++ */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_PS { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 ProductSpecificInfo;/*0x04 */ ++} MPI2_CONFIG_PAGE_MAN_PS, ++ *PTR_MPI2_CONFIG_PAGE_MAN_PS, ++ Mpi2ManufacturingPagePS_t, ++ *pMpi2ManufacturingPagePS_t; ++ ++#define MPI2_MANUFACTURING8_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING9_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING10_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING11_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING12_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING13_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING14_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING15_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING16_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING17_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING18_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING19_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING20_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING21_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING22_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING23_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING24_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING25_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING26_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING27_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING28_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING29_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING30_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING31_PAGEVERSION (0x00) ++ ++ ++/**************************************************************************** ++* IO Unit Config Pages ++****************************************************************************/ ++ ++/*IO Unit Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U64 UniqueValue; /*0x04 */ ++ MPI2_VERSION_UNION NvdataVersionDefault; /*0x08 */ ++ MPI2_VERSION_UNION NvdataVersionPersistent; /*0x0A */ ++} MPI2_CONFIG_PAGE_IO_UNIT_0, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_0, ++ Mpi2IOUnitPage0_t, *pMpi2IOUnitPage0_t; ++ ++#define MPI2_IOUNITPAGE0_PAGEVERSION (0x02) ++ ++ ++/*IO Unit Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Flags; /*0x04 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_1, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_1, ++ Mpi2IOUnitPage1_t, *pMpi2IOUnitPage1_t; ++ ++#define MPI2_IOUNITPAGE1_PAGEVERSION (0x04) ++ ++/*IO Unit Page 1 Flags defines */ ++#define MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK (0x00004000) ++#define MPI25_IOUNITPAGE1_NEW_DEVICE_FAST_PATH_DISABLE (0x00002000) ++#define MPI25_IOUNITPAGE1_DISABLE_FAST_PATH (0x00001000) ++#define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800) ++#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) ++#define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT (9) ++#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) ++#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) ++#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400) ++#define MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100) ++#define MPI2_IOUNITPAGE1_DISABLE_IR (0x00000040) ++#define MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING (0x00000020) ++#define MPI2_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) ++ ++ ++/*IO Unit Page 3 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for GPIOCount at runtime. ++ */ ++#ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX ++#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 GPIOCount; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U16 ++ GPIOVal[MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX];/*0x08 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_3, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_3, ++ Mpi2IOUnitPage3_t, *pMpi2IOUnitPage3_t; ++ ++#define MPI2_IOUNITPAGE3_PAGEVERSION (0x01) ++ ++/*defines for IO Unit Page 3 GPIOVal field */ ++#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_MASK (0xFFFC) ++#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_SHIFT (2) ++#define MPI2_IOUNITPAGE3_GPIO_SETTING_OFF (0x0000) ++#define MPI2_IOUNITPAGE3_GPIO_SETTING_ON (0x0001) ++ ++ ++/*IO Unit Page 5 */ ++ ++/* ++ *Upper layer code (drivers, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumDmaEngines at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES ++#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_5 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U64 ++ RaidAcceleratorBufferBaseAddress; /*0x04 */ ++ U64 ++ RaidAcceleratorBufferSize; /*0x0C */ ++ U64 ++ RaidAcceleratorControlBaseAddress; /*0x14 */ ++ U8 RAControlSize; /*0x1C */ ++ U8 NumDmaEngines; /*0x1D */ ++ U8 RAMinControlSize; /*0x1E */ ++ U8 RAMaxControlSize; /*0x1F */ ++ U32 Reserved1; /*0x20 */ ++ U32 Reserved2; /*0x24 */ ++ U32 Reserved3; /*0x28 */ ++ U32 ++ DmaEngineCapabilities[MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES]; /*0x2C */ ++} MPI2_CONFIG_PAGE_IO_UNIT_5, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_5, ++ Mpi2IOUnitPage5_t, *pMpi2IOUnitPage5_t; ++ ++#define MPI2_IOUNITPAGE5_PAGEVERSION (0x00) ++ ++/*defines for IO Unit Page 5 DmaEngineCapabilities field */ ++#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS (0xFFFF0000) ++#define MPI2_IOUNITPAGE5_DMA_CAP_SHIFT_MAX_REQUESTS (16) ++ ++#define MPI2_IOUNITPAGE5_DMA_CAP_EEDP (0x0008) ++#define MPI2_IOUNITPAGE5_DMA_CAP_PARITY_GENERATION (0x0004) ++#define MPI2_IOUNITPAGE5_DMA_CAP_HASHING (0x0002) ++#define MPI2_IOUNITPAGE5_DMA_CAP_ENCRYPTION (0x0001) ++ ++ ++/*IO Unit Page 6 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 Flags; /*0x04 */ ++ U8 RAHostControlSize; /*0x06 */ ++ U8 Reserved0; /*0x07 */ ++ U64 ++ RaidAcceleratorHostControlBaseAddress; /*0x08 */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++ U32 Reserved3; /*0x18 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_6, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_6, ++ Mpi2IOUnitPage6_t, *pMpi2IOUnitPage6_t; ++ ++#define MPI2_IOUNITPAGE6_PAGEVERSION (0x00) ++ ++/*defines for IO Unit Page 6 Flags field */ ++#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001) ++ ++ ++/*IO Unit Page 7 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 CurrentPowerMode; /*0x04 */ ++ U8 PreviousPowerMode; /*0x05 */ ++ U8 PCIeWidth; /*0x06 */ ++ U8 PCIeSpeed; /*0x07 */ ++ U32 ProcessorState; /*0x08 */ ++ U32 ++ PowerManagementCapabilities; /*0x0C */ ++ U16 IOCTemperature; /*0x10 */ ++ U8 ++ IOCTemperatureUnits; /*0x12 */ ++ U8 IOCSpeed; /*0x13 */ ++ U16 BoardTemperature; /*0x14 */ ++ U8 ++ BoardTemperatureUnits; /*0x16 */ ++ U8 Reserved3; /*0x17 */ ++ U32 BoardPowerRequirement; /*0x18 */ ++ U32 PCISlotPowerAllocation; /*0x1C */ ++/* reserved prior to MPI v2.6 */ ++ U8 Flags; /* 0x20 */ ++ U8 Reserved6; /* 0x21 */ ++ U16 Reserved7; /* 0x22 */ ++ U32 Reserved8; /* 0x24 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_7, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_7, ++ Mpi2IOUnitPage7_t, *pMpi2IOUnitPage7_t; ++ ++#define MPI2_IOUNITPAGE7_PAGEVERSION (0x05) ++ ++/*defines for IO Unit Page 7 CurrentPowerMode and PreviousPowerMode fields */ ++#define MPI25_IOUNITPAGE7_PM_INIT_MASK (0xC0) ++#define MPI25_IOUNITPAGE7_PM_INIT_UNAVAILABLE (0x00) ++#define MPI25_IOUNITPAGE7_PM_INIT_HOST (0x40) ++#define MPI25_IOUNITPAGE7_PM_INIT_IO_UNIT (0x80) ++#define MPI25_IOUNITPAGE7_PM_INIT_PCIE_DPA (0xC0) ++ ++#define MPI25_IOUNITPAGE7_PM_MODE_MASK (0x07) ++#define MPI25_IOUNITPAGE7_PM_MODE_UNAVAILABLE (0x00) ++#define MPI25_IOUNITPAGE7_PM_MODE_UNKNOWN (0x01) ++#define MPI25_IOUNITPAGE7_PM_MODE_FULL_POWER (0x04) ++#define MPI25_IOUNITPAGE7_PM_MODE_REDUCED_POWER (0x05) ++#define MPI25_IOUNITPAGE7_PM_MODE_STANDBY (0x06) ++ ++ ++/*defines for IO Unit Page 7 PCIeWidth field */ ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01) ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2 (0x02) ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4 (0x04) ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8 (0x08) ++ ++/*defines for IO Unit Page 7 PCIeSpeed field */ ++#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS (0x00) ++#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01) ++#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02) ++ ++/*defines for IO Unit Page 7 ProcessorState field */ ++#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F) ++#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND (0) ++ ++#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT (0x00) ++#define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01) ++#define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02) ++ ++/*defines for IO Unit Page 7 PowerManagementCapabilities field */ ++#define MPI25_IOUNITPAGE7_PMCAP_DPA_FULL_PWR_MODE (0x00400000) ++#define MPI25_IOUNITPAGE7_PMCAP_DPA_REDUCED_PWR_MODE (0x00200000) ++#define MPI25_IOUNITPAGE7_PMCAP_DPA_STANDBY_MODE (0x00100000) ++#define MPI25_IOUNITPAGE7_PMCAP_HOST_FULL_PWR_MODE (0x00040000) ++#define MPI25_IOUNITPAGE7_PMCAP_HOST_REDUCED_PWR_MODE (0x00020000) ++#define MPI25_IOUNITPAGE7_PMCAP_HOST_STANDBY_MODE (0x00010000) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_FULL_PWR_MODE (0x00004000) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_REDUCED_PWR_MODE (0x00002000) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_STANDBY_MODE (0x00001000) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_12_5_PCT_IOCSPEED (0x00000400) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_25_0_PCT_IOCSPEED (0x00000200) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_50_0_PCT_IOCSPEED (0x00000100) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_12_5_PCT_IOCSPEED (0x00000040) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_25_0_PCT_IOCSPEED (0x00000020) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_50_0_PCT_IOCSPEED (0x00000010) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_WIDTH_CHANGE_PCIE (0x00000008) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_SPEED_CHANGE_PCIE (0x00000004) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_WIDTH_CHANGE_PCIE (0x00000002) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_SPEED_CHANGE_PCIE (0x00000001) ++ ++/*obsolete names for the PowerManagementCapabilities bits (above) */ ++#define MPI2_IOUNITPAGE7_PMCAP_12_5_PCT_IOCSPEED (0x00000400) ++#define MPI2_IOUNITPAGE7_PMCAP_25_0_PCT_IOCSPEED (0x00000200) ++#define MPI2_IOUNITPAGE7_PMCAP_50_0_PCT_IOCSPEED (0x00000100) ++#define MPI2_IOUNITPAGE7_PMCAP_PCIE_WIDTH_CHANGE (0x00000008) /*obsolete */ ++#define MPI2_IOUNITPAGE7_PMCAP_PCIE_SPEED_CHANGE (0x00000004) /*obsolete */ ++ ++ ++/*defines for IO Unit Page 7 IOCTemperatureUnits field */ ++#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00) ++#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01) ++#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS (0x02) ++ ++/*defines for IO Unit Page 7 IOCSpeed field */ ++#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL (0x01) ++#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF (0x02) ++#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER (0x04) ++#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH (0x08) ++ ++/*defines for IO Unit Page 7 BoardTemperatureUnits field */ ++#define MPI2_IOUNITPAGE7_BOARD_TEMP_NOT_PRESENT (0x00) ++#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT (0x01) ++#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02) ++ ++/* defines for IO Unit Page 7 Flags field */ ++#define MPI2_IOUNITPAGE7_FLAG_CABLE_POWER_EXC (0x01) ++ ++/*IO Unit Page 8 */ ++ ++#define MPI2_IOUNIT8_NUM_THRESHOLDS (4) ++ ++typedef struct _MPI2_IOUNIT8_SENSOR { ++ U16 Flags; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U16 ++ Threshold[MPI2_IOUNIT8_NUM_THRESHOLDS]; /*0x04 */ ++ U32 Reserved2; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U32 Reserved4; /*0x14 */ ++} MPI2_IOUNIT8_SENSOR, *PTR_MPI2_IOUNIT8_SENSOR, ++ Mpi2IOUnit8Sensor_t, *pMpi2IOUnit8Sensor_t; ++ ++/*defines for IO Unit Page 8 Sensor Flags field */ ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T3_ENABLE (0x0008) ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T2_ENABLE (0x0004) ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T1_ENABLE (0x0002) ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T0_ENABLE (0x0001) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumSensors at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE8_SENSOR_ENTRIES ++#define MPI2_IOUNITPAGE8_SENSOR_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_8 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U8 NumSensors; /*0x0C */ ++ U8 PollingInterval; /*0x0D */ ++ U16 Reserved3; /*0x0E */ ++ MPI2_IOUNIT8_SENSOR ++ Sensor[MPI2_IOUNITPAGE8_SENSOR_ENTRIES];/*0x10 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_8, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_8, ++ Mpi2IOUnitPage8_t, *pMpi2IOUnitPage8_t; ++ ++#define MPI2_IOUNITPAGE8_PAGEVERSION (0x00) ++ ++ ++/*IO Unit Page 9 */ ++ ++typedef struct _MPI2_IOUNIT9_SENSOR { ++ U16 CurrentTemperature; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U8 Flags; /*0x04 */ ++ U8 Reserved2; /*0x05 */ ++ U16 Reserved3; /*0x06 */ ++ U32 Reserved4; /*0x08 */ ++ U32 Reserved5; /*0x0C */ ++} MPI2_IOUNIT9_SENSOR, *PTR_MPI2_IOUNIT9_SENSOR, ++ Mpi2IOUnit9Sensor_t, *pMpi2IOUnit9Sensor_t; ++ ++/*defines for IO Unit Page 9 Sensor Flags field */ ++#define MPI2_IOUNIT9_SENSOR_FLAGS_TEMP_VALID (0x01) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumSensors at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE9_SENSOR_ENTRIES ++#define MPI2_IOUNITPAGE9_SENSOR_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_9 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U8 NumSensors; /*0x0C */ ++ U8 Reserved4; /*0x0D */ ++ U16 Reserved3; /*0x0E */ ++ MPI2_IOUNIT9_SENSOR ++ Sensor[MPI2_IOUNITPAGE9_SENSOR_ENTRIES];/*0x10 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_9, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_9, ++ Mpi2IOUnitPage9_t, *pMpi2IOUnitPage9_t; ++ ++#define MPI2_IOUNITPAGE9_PAGEVERSION (0x00) ++ ++ ++/*IO Unit Page 10 */ ++ ++typedef struct _MPI2_IOUNIT10_FUNCTION { ++ U8 CreditPercent; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++} MPI2_IOUNIT10_FUNCTION, ++ *PTR_MPI2_IOUNIT10_FUNCTION, ++ Mpi2IOUnit10Function_t, ++ *pMpi2IOUnit10Function_t; ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumFunctions at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE10_FUNCTION_ENTRIES ++#define MPI2_IOUNITPAGE10_FUNCTION_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_10 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumFunctions; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++ MPI2_IOUNIT10_FUNCTION ++ Function[MPI2_IOUNITPAGE10_FUNCTION_ENTRIES];/*0x10 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_10, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_10, ++ Mpi2IOUnitPage10_t, *pMpi2IOUnitPage10_t; ++ ++#define MPI2_IOUNITPAGE10_PAGEVERSION (0x01) ++ ++ ++/* IO Unit Page 11 (for MPI v2.6 and later) */ ++ ++typedef struct _MPI26_IOUNIT11_SPINUP_GROUP { ++ U8 MaxTargetSpinup; /* 0x00 */ ++ U8 SpinupDelay; /* 0x01 */ ++ U8 SpinupFlags; /* 0x02 */ ++ U8 Reserved1; /* 0x03 */ ++} MPI26_IOUNIT11_SPINUP_GROUP, ++ *PTR_MPI26_IOUNIT11_SPINUP_GROUP, ++ Mpi26IOUnit11SpinupGroup_t, ++ *pMpi26IOUnit11SpinupGroup_t; ++ ++/* defines for IO Unit Page 11 SpinupFlags */ ++#define MPI26_IOUNITPAGE11_SPINUP_DISABLE_FLAG (0x01) ++ ++ ++/* ++ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ * four and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI26_IOUNITPAGE11_PHY_MAX ++#define MPI26_IOUNITPAGE11_PHY_MAX (4) ++#endif ++ ++typedef struct _MPI26_CONFIG_PAGE_IO_UNIT_11 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ MPI26_IOUNIT11_SPINUP_GROUP SpinupGroupParameters[4]; /*0x08 */ ++ U32 Reserved2; /*0x18 */ ++ U32 Reserved3; /*0x1C */ ++ U32 Reserved4; /*0x20 */ ++ U8 BootDeviceWaitTime; /*0x24 */ ++ U8 Reserved5; /*0x25 */ ++ U16 Reserved6; /*0x26 */ ++ U8 NumPhys; /*0x28 */ ++ U8 PEInitialSpinupDelay; /*0x29 */ ++ U8 PEReplyDelay; /*0x2A */ ++ U8 Flags; /*0x2B */ ++ U8 PHY[MPI26_IOUNITPAGE11_PHY_MAX];/*0x2C */ ++} MPI26_CONFIG_PAGE_IO_UNIT_11, ++ *PTR_MPI26_CONFIG_PAGE_IO_UNIT_11, ++ Mpi26IOUnitPage11_t, ++ *pMpi26IOUnitPage11_t; ++ ++#define MPI26_IOUNITPAGE11_PAGEVERSION (0x00) ++ ++/* defines for Flags field */ ++#define MPI26_IOUNITPAGE11_FLAGS_AUTO_PORTENABLE (0x01) ++ ++/* defines for PHY field */ ++#define MPI26_IOUNITPAGE11_PHY_SPINUP_GROUP_MASK (0x03) ++ ++ ++ ++ ++ ++ ++/**************************************************************************** ++* IOC Config Pages ++****************************************************************************/ ++ ++/*IOC Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U16 VendorID; /*0x0C */ ++ U16 DeviceID; /*0x0E */ ++ U8 RevisionID; /*0x10 */ ++ U8 Reserved3; /*0x11 */ ++ U16 Reserved4; /*0x12 */ ++ U32 ClassCode; /*0x14 */ ++ U16 SubsystemVendorID; /*0x18 */ ++ U16 SubsystemID; /*0x1A */ ++} MPI2_CONFIG_PAGE_IOC_0, ++ *PTR_MPI2_CONFIG_PAGE_IOC_0, ++ Mpi2IOCPage0_t, *pMpi2IOCPage0_t; ++ ++#define MPI2_IOCPAGE0_PAGEVERSION (0x02) ++ ++ ++/*IOC Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Flags; /*0x04 */ ++ U32 CoalescingTimeout; /*0x08 */ ++ U8 CoalescingDepth; /*0x0C */ ++ U8 PCISlotNum; /*0x0D */ ++ U8 PCIBusNum; /*0x0E */ ++ U8 PCIDomainSegment; /*0x0F */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++} MPI2_CONFIG_PAGE_IOC_1, ++ *PTR_MPI2_CONFIG_PAGE_IOC_1, ++ Mpi2IOCPage1_t, *pMpi2IOCPage1_t; ++ ++#define MPI2_IOCPAGE1_PAGEVERSION (0x05) ++ ++/*defines for IOC Page 1 Flags field */ ++#define MPI2_IOCPAGE1_REPLY_COALESCING (0x00000001) ++ ++#define MPI2_IOCPAGE1_PCISLOTNUM_UNKNOWN (0xFF) ++#define MPI2_IOCPAGE1_PCIBUSNUM_UNKNOWN (0xFF) ++#define MPI2_IOCPAGE1_PCIDOMAIN_UNKNOWN (0xFF) ++ ++/*IOC Page 6 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_6 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 ++ CapabilitiesFlags; /*0x04 */ ++ U8 MaxDrivesRAID0; /*0x08 */ ++ U8 MaxDrivesRAID1; /*0x09 */ ++ U8 ++ MaxDrivesRAID1E; /*0x0A */ ++ U8 ++ MaxDrivesRAID10; /*0x0B */ ++ U8 MinDrivesRAID0; /*0x0C */ ++ U8 MinDrivesRAID1; /*0x0D */ ++ U8 ++ MinDrivesRAID1E; /*0x0E */ ++ U8 ++ MinDrivesRAID10; /*0x0F */ ++ U32 Reserved1; /*0x10 */ ++ U8 ++ MaxGlobalHotSpares; /*0x14 */ ++ U8 MaxPhysDisks; /*0x15 */ ++ U8 MaxVolumes; /*0x16 */ ++ U8 MaxConfigs; /*0x17 */ ++ U8 MaxOCEDisks; /*0x18 */ ++ U8 Reserved2; /*0x19 */ ++ U16 Reserved3; /*0x1A */ ++ U32 ++ SupportedStripeSizeMapRAID0; /*0x1C */ ++ U32 ++ SupportedStripeSizeMapRAID1E; /*0x20 */ ++ U32 ++ SupportedStripeSizeMapRAID10; /*0x24 */ ++ U32 Reserved4; /*0x28 */ ++ U32 Reserved5; /*0x2C */ ++ U16 ++ DefaultMetadataSize; /*0x30 */ ++ U16 Reserved6; /*0x32 */ ++ U16 ++ MaxBadBlockTableEntries; /*0x34 */ ++ U16 Reserved7; /*0x36 */ ++ U32 ++ IRNvsramVersion; /*0x38 */ ++} MPI2_CONFIG_PAGE_IOC_6, ++ *PTR_MPI2_CONFIG_PAGE_IOC_6, ++ Mpi2IOCPage6_t, *pMpi2IOCPage6_t; ++ ++#define MPI2_IOCPAGE6_PAGEVERSION (0x05) ++ ++/*defines for IOC Page 6 CapabilitiesFlags */ ++#define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT (0x00000020) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID10_SUPPORT (0x00000010) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1_SUPPORT (0x00000008) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1E_SUPPORT (0x00000004) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID0_SUPPORT (0x00000002) ++#define MPI2_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) ++ ++ ++/*IOC Page 7 */ ++ ++#define MPI2_IOCPAGE7_EVENTMASK_WORDS (4) ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_7 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 ++ EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/*0x08 */ ++ U16 SASBroadcastPrimitiveMasks; /*0x18 */ ++ U16 SASNotifyPrimitiveMasks; /*0x1A */ ++ U32 Reserved3; /*0x1C */ ++} MPI2_CONFIG_PAGE_IOC_7, ++ *PTR_MPI2_CONFIG_PAGE_IOC_7, ++ Mpi2IOCPage7_t, *pMpi2IOCPage7_t; ++ ++#define MPI2_IOCPAGE7_PAGEVERSION (0x02) ++ ++ ++/*IOC Page 8 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_8 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumDevsPerEnclosure; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U16 MaxPersistentEntries; /*0x08 */ ++ U16 MaxNumPhysicalMappedIDs; /*0x0A */ ++ U16 Flags; /*0x0C */ ++ U16 Reserved3; /*0x0E */ ++ U16 IRVolumeMappingFlags; /*0x10 */ ++ U16 Reserved4; /*0x12 */ ++ U32 Reserved5; /*0x14 */ ++} MPI2_CONFIG_PAGE_IOC_8, ++ *PTR_MPI2_CONFIG_PAGE_IOC_8, ++ Mpi2IOCPage8_t, *pMpi2IOCPage8_t; ++ ++#define MPI2_IOCPAGE8_PAGEVERSION (0x00) ++ ++/*defines for IOC Page 8 Flags field */ ++#define MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1 (0x00000020) ++#define MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0 (0x00000010) ++ ++#define MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE (0x0000000E) ++#define MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING (0x00000000) ++#define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING (0x00000002) ++ ++#define MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING (0x00000001) ++#define MPI2_IOCPAGE8_FLAGS_ENABLE_PERSISTENT_MAPPING (0x00000000) ++ ++/*defines for IOC Page 8 IRVolumeMappingFlags */ ++#define MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE (0x00000003) ++#define MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING (0x00000000) ++#define MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING (0x00000001) ++ ++ ++/**************************************************************************** ++* BIOS Config Pages ++****************************************************************************/ ++ ++/*BIOS Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 BiosOptions; /*0x04 */ ++ U32 IOCSettings; /*0x08 */ ++ U8 SSUTimeout; /*0x0C */ ++ U8 Reserved1; /*0x0D */ ++ U16 Reserved2; /*0x0E */ ++ U32 DeviceSettings; /*0x10 */ ++ U16 NumberOfDevices; /*0x14 */ ++ U16 UEFIVersion; /*0x16 */ ++ U16 IOTimeoutBlockDevicesNonRM; /*0x18 */ ++ U16 IOTimeoutSequential; /*0x1A */ ++ U16 IOTimeoutOther; /*0x1C */ ++ U16 IOTimeoutBlockDevicesRM; /*0x1E */ ++} MPI2_CONFIG_PAGE_BIOS_1, ++ *PTR_MPI2_CONFIG_PAGE_BIOS_1, ++ Mpi2BiosPage1_t, *pMpi2BiosPage1_t; ++ ++#define MPI2_BIOSPAGE1_PAGEVERSION (0x07) ++ ++/*values for BIOS Page 1 BiosOptions field */ ++#define MPI2_BIOSPAGE1_OPTIONS_BOOT_LIST_ADD_ALT_BOOT_DEVICE (0x00008000) ++#define MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG (0x00004000) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK (0x00003800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK (0x00003800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_PBDHL (0x00000000) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_ENCSLOSURE (0x00000800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_LWWID (0x00001000) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_PSENS (0x00001800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_ESPHY (0x00002000) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_X86_DISABLE_BIOS (0x00000400) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_MASK_REGISTRATION_UEFI_BSD (0x00000300) ++#define MPI2_BIOSPAGE1_OPTIONS_USE_BIT0_REGISTRATION_UEFI_BSD (0x00000000) ++#define MPI2_BIOSPAGE1_OPTIONS_FULL_REGISTRATION_UEFI_BSD (0x00000100) ++#define MPI2_BIOSPAGE1_OPTIONS_ADAPTER_REGISTRATION_UEFI_BSD (0x00000200) ++#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_REGISTRATION_UEFI_BSD (0x00000300) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0) ++#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006) ++#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000) ++#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002) ++#define MPI2_BIOSPAGE1_OPTIONS_VERSION_CHECK_UEFI_HII (0x00000004) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) ++ ++/*values for BIOS Page 1 IOCSettings field */ ++#define MPI2_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) ++#define MPI2_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000) ++#define MPI2_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000) ++ ++#define MPI2_BIOSPAGE1_IOCSET_MASK_RM_SETTING (0x000000C0) ++#define MPI2_BIOSPAGE1_IOCSET_NONE_RM_SETTING (0x00000000) ++#define MPI2_BIOSPAGE1_IOCSET_BOOT_RM_SETTING (0x00000040) ++#define MPI2_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING (0x00000080) ++ ++#define MPI2_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT (0x00000030) ++#define MPI2_BIOSPAGE1_IOCSET_NO_SUPPORT (0x00000000) ++#define MPI2_BIOSPAGE1_IOCSET_BIOS_SUPPORT (0x00000010) ++#define MPI2_BIOSPAGE1_IOCSET_OS_SUPPORT (0x00000020) ++#define MPI2_BIOSPAGE1_IOCSET_ALL_SUPPORT (0x00000030) ++ ++#define MPI2_BIOSPAGE1_IOCSET_ALTERNATE_CHS (0x00000008) ++ ++/*values for BIOS Page 1 DeviceSettings field */ ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SMART_POLLING (0x00000010) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN (0x00000008) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_RM_LUN (0x00000004) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001) ++ ++/*defines for BIOS Page 1 UEFIVersion field */ ++#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_MASK (0xFF00) ++#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_SHIFT (8) ++#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_MASK (0x00FF) ++#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_SHIFT (0) ++ ++ ++ ++/*BIOS Page 2 */ ++ ++typedef struct _MPI2_BOOT_DEVICE_ADAPTER_ORDER { ++ U32 Reserved1; /*0x00 */ ++ U32 Reserved2; /*0x04 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++ U32 Reserved5; /*0x10 */ ++ U32 Reserved6; /*0x14 */ ++} MPI2_BOOT_DEVICE_ADAPTER_ORDER, ++ *PTR_MPI2_BOOT_DEVICE_ADAPTER_ORDER, ++ Mpi2BootDeviceAdapterOrder_t, ++ *pMpi2BootDeviceAdapterOrder_t; ++ ++typedef struct _MPI2_BOOT_DEVICE_SAS_WWID { ++ U64 SASAddress; /*0x00 */ ++ U8 LUN[8]; /*0x08 */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++} MPI2_BOOT_DEVICE_SAS_WWID, ++ *PTR_MPI2_BOOT_DEVICE_SAS_WWID, ++ Mpi2BootDeviceSasWwid_t, ++ *pMpi2BootDeviceSasWwid_t; ++ ++typedef struct _MPI2_BOOT_DEVICE_ENCLOSURE_SLOT { ++ U64 EnclosureLogicalID; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ U16 SlotNumber; /*0x10 */ ++ U16 Reserved3; /*0x12 */ ++ U32 Reserved4; /*0x14 */ ++} MPI2_BOOT_DEVICE_ENCLOSURE_SLOT, ++ *PTR_MPI2_BOOT_DEVICE_ENCLOSURE_SLOT, ++ Mpi2BootDeviceEnclosureSlot_t, ++ *pMpi2BootDeviceEnclosureSlot_t; ++ ++typedef struct _MPI2_BOOT_DEVICE_DEVICE_NAME { ++ U64 DeviceName; /*0x00 */ ++ U8 LUN[8]; /*0x08 */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++} MPI2_BOOT_DEVICE_DEVICE_NAME, ++ *PTR_MPI2_BOOT_DEVICE_DEVICE_NAME, ++ Mpi2BootDeviceDeviceName_t, ++ *pMpi2BootDeviceDeviceName_t; ++ ++typedef union _MPI2_MPI2_BIOSPAGE2_BOOT_DEVICE { ++ MPI2_BOOT_DEVICE_ADAPTER_ORDER AdapterOrder; ++ MPI2_BOOT_DEVICE_SAS_WWID SasWwid; ++ MPI2_BOOT_DEVICE_ENCLOSURE_SLOT EnclosureSlot; ++ MPI2_BOOT_DEVICE_DEVICE_NAME DeviceName; ++} MPI2_BIOSPAGE2_BOOT_DEVICE, ++ *PTR_MPI2_BIOSPAGE2_BOOT_DEVICE, ++ Mpi2BiosPage2BootDevice_t, ++ *pMpi2BiosPage2BootDevice_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_2 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++ U32 Reserved4; /*0x10 */ ++ U32 Reserved5; /*0x14 */ ++ U32 Reserved6; /*0x18 */ ++ U8 ReqBootDeviceForm; /*0x1C */ ++ U8 Reserved7; /*0x1D */ ++ U16 Reserved8; /*0x1E */ ++ MPI2_BIOSPAGE2_BOOT_DEVICE RequestedBootDevice; /*0x20 */ ++ U8 ReqAltBootDeviceForm; /*0x38 */ ++ U8 Reserved9; /*0x39 */ ++ U16 Reserved10; /*0x3A */ ++ MPI2_BIOSPAGE2_BOOT_DEVICE RequestedAltBootDevice; /*0x3C */ ++ U8 CurrentBootDeviceForm; /*0x58 */ ++ U8 Reserved11; /*0x59 */ ++ U16 Reserved12; /*0x5A */ ++ MPI2_BIOSPAGE2_BOOT_DEVICE CurrentBootDevice; /*0x58 */ ++} MPI2_CONFIG_PAGE_BIOS_2, *PTR_MPI2_CONFIG_PAGE_BIOS_2, ++ Mpi2BiosPage2_t, *pMpi2BiosPage2_t; ++ ++#define MPI2_BIOSPAGE2_PAGEVERSION (0x04) ++ ++/*values for BIOS Page 2 BootDeviceForm fields */ ++#define MPI2_BIOSPAGE2_FORM_MASK (0x0F) ++#define MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED (0x00) ++#define MPI2_BIOSPAGE2_FORM_SAS_WWID (0x05) ++#define MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06) ++#define MPI2_BIOSPAGE2_FORM_DEVICE_NAME (0x07) ++ ++ ++/*BIOS Page 3 */ ++ ++#define MPI2_BIOSPAGE3_NUM_ADAPTER (4) ++ ++typedef struct _MPI2_ADAPTER_INFO { ++ U8 PciBusNumber; /*0x00 */ ++ U8 PciDeviceAndFunctionNumber; /*0x01 */ ++ U16 AdapterFlags; /*0x02 */ ++} MPI2_ADAPTER_INFO, *PTR_MPI2_ADAPTER_INFO, ++ Mpi2AdapterInfo_t, *pMpi2AdapterInfo_t; ++ ++#define MPI2_ADAPTER_INFO_FLAGS_EMBEDDED (0x0001) ++#define MPI2_ADAPTER_INFO_FLAGS_INIT_STATUS (0x0002) ++ ++typedef struct _MPI2_ADAPTER_ORDER_AUX { ++ U64 WWID; /* 0x00 */ ++ U32 Reserved1; /* 0x08 */ ++ U32 Reserved2; /* 0x0C */ ++} MPI2_ADAPTER_ORDER_AUX, *PTR_MPI2_ADAPTER_ORDER_AUX, ++ Mpi2AdapterOrderAux_t, *pMpi2AdapterOrderAux_t; ++ ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_3 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 GlobalFlags; /*0x04 */ ++ U32 BiosVersion; /*0x08 */ ++ MPI2_ADAPTER_INFO AdapterOrder[MPI2_BIOSPAGE3_NUM_ADAPTER]; ++ U32 Reserved1; /*0x1C */ ++ MPI2_ADAPTER_ORDER_AUX AdapterOrderAux[MPI2_BIOSPAGE3_NUM_ADAPTER]; ++} MPI2_CONFIG_PAGE_BIOS_3, ++ *PTR_MPI2_CONFIG_PAGE_BIOS_3, ++ Mpi2BiosPage3_t, *pMpi2BiosPage3_t; ++ ++#define MPI2_BIOSPAGE3_PAGEVERSION (0x01) ++ ++/*values for BIOS Page 3 GlobalFlags */ ++#define MPI2_BIOSPAGE3_FLAGS_PAUSE_ON_ERROR (0x00000002) ++#define MPI2_BIOSPAGE3_FLAGS_VERBOSE_ENABLE (0x00000004) ++#define MPI2_BIOSPAGE3_FLAGS_HOOK_INT_40_DISABLE (0x00000010) ++ ++#define MPI2_BIOSPAGE3_FLAGS_DEV_LIST_DISPLAY_MASK (0x000000E0) ++#define MPI2_BIOSPAGE3_FLAGS_INSTALLED_DEV_DISPLAY (0x00000000) ++#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DISPLAY (0x00000020) ++#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DEV_DISPLAY (0x00000040) ++ ++ ++/*BIOS Page 4 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_BIOS_PAGE_4_PHY_ENTRIES ++#define MPI2_BIOS_PAGE_4_PHY_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_BIOS4_ENTRY { ++ U64 ReassignmentWWID; /*0x00 */ ++ U64 ReassignmentDeviceName; /*0x08 */ ++} MPI2_BIOS4_ENTRY, *PTR_MPI2_BIOS4_ENTRY, ++ Mpi2MBios4Entry_t, *pMpi2Bios4Entry_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_4 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhys; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ MPI2_BIOS4_ENTRY ++ Phy[MPI2_BIOS_PAGE_4_PHY_ENTRIES]; /*0x08 */ ++} MPI2_CONFIG_PAGE_BIOS_4, *PTR_MPI2_CONFIG_PAGE_BIOS_4, ++ Mpi2BiosPage4_t, *pMpi2BiosPage4_t; ++ ++#define MPI2_BIOSPAGE4_PAGEVERSION (0x01) ++ ++ ++/**************************************************************************** ++* RAID Volume Config Pages ++****************************************************************************/ ++ ++/*RAID Volume Page 0 */ ++ ++typedef struct _MPI2_RAIDVOL0_PHYS_DISK { ++ U8 RAIDSetNum; /*0x00 */ ++ U8 PhysDiskMap; /*0x01 */ ++ U8 PhysDiskNum; /*0x02 */ ++ U8 Reserved; /*0x03 */ ++} MPI2_RAIDVOL0_PHYS_DISK, *PTR_MPI2_RAIDVOL0_PHYS_DISK, ++ Mpi2RaidVol0PhysDisk_t, *pMpi2RaidVol0PhysDisk_t; ++ ++/*defines for the PhysDiskMap field */ ++#define MPI2_RAIDVOL0_PHYSDISK_PRIMARY (0x01) ++#define MPI2_RAIDVOL0_PHYSDISK_SECONDARY (0x02) ++ ++typedef struct _MPI2_RAIDVOL0_SETTINGS { ++ U16 Settings; /*0x00 */ ++ U8 HotSparePool; /*0x01 */ ++ U8 Reserved; /*0x02 */ ++} MPI2_RAIDVOL0_SETTINGS, *PTR_MPI2_RAIDVOL0_SETTINGS, ++ Mpi2RaidVol0Settings_t, ++ *pMpi2RaidVol0Settings_t; ++ ++/*RAID Volume Page 0 HotSparePool defines, also used in RAID Physical Disk */ ++#define MPI2_RAID_HOT_SPARE_POOL_0 (0x01) ++#define MPI2_RAID_HOT_SPARE_POOL_1 (0x02) ++#define MPI2_RAID_HOT_SPARE_POOL_2 (0x04) ++#define MPI2_RAID_HOT_SPARE_POOL_3 (0x08) ++#define MPI2_RAID_HOT_SPARE_POOL_4 (0x10) ++#define MPI2_RAID_HOT_SPARE_POOL_5 (0x20) ++#define MPI2_RAID_HOT_SPARE_POOL_6 (0x40) ++#define MPI2_RAID_HOT_SPARE_POOL_7 (0x80) ++ ++/*RAID Volume Page 0 VolumeSettings defines */ ++#define MPI2_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0008) ++#define MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE (0x0004) ++ ++#define MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING (0x0003) ++#define MPI2_RAIDVOL0_SETTING_UNCHANGED (0x0000) ++#define MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING (0x0001) ++#define MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING (0x0002) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhysDisks at runtime. ++ */ ++#ifndef MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX ++#define MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 DevHandle; /*0x04 */ ++ U8 VolumeState; /*0x06 */ ++ U8 VolumeType; /*0x07 */ ++ U32 VolumeStatusFlags; /*0x08 */ ++ MPI2_RAIDVOL0_SETTINGS VolumeSettings; /*0x0C */ ++ U64 MaxLBA; /*0x10 */ ++ U32 StripeSize; /*0x18 */ ++ U16 BlockSize; /*0x1C */ ++ U16 Reserved1; /*0x1E */ ++ U8 SupportedPhysDisks;/*0x20 */ ++ U8 ResyncRate; /*0x21 */ ++ U16 DataScrubDuration; /*0x22 */ ++ U8 NumPhysDisks; /*0x24 */ ++ U8 Reserved2; /*0x25 */ ++ U8 Reserved3; /*0x26 */ ++ U8 InactiveStatus; /*0x27 */ ++ MPI2_RAIDVOL0_PHYS_DISK ++ PhysDisk[MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX]; /*0x28 */ ++} MPI2_CONFIG_PAGE_RAID_VOL_0, ++ *PTR_MPI2_CONFIG_PAGE_RAID_VOL_0, ++ Mpi2RaidVolPage0_t, *pMpi2RaidVolPage0_t; ++ ++#define MPI2_RAIDVOLPAGE0_PAGEVERSION (0x0A) ++ ++/*values for RAID VolumeState */ ++#define MPI2_RAID_VOL_STATE_MISSING (0x00) ++#define MPI2_RAID_VOL_STATE_FAILED (0x01) ++#define MPI2_RAID_VOL_STATE_INITIALIZING (0x02) ++#define MPI2_RAID_VOL_STATE_ONLINE (0x03) ++#define MPI2_RAID_VOL_STATE_DEGRADED (0x04) ++#define MPI2_RAID_VOL_STATE_OPTIMAL (0x05) ++ ++/*values for RAID VolumeType */ ++#define MPI2_RAID_VOL_TYPE_RAID0 (0x00) ++#define MPI2_RAID_VOL_TYPE_RAID1E (0x01) ++#define MPI2_RAID_VOL_TYPE_RAID1 (0x02) ++#define MPI2_RAID_VOL_TYPE_RAID10 (0x05) ++#define MPI2_RAID_VOL_TYPE_UNKNOWN (0xFF) ++ ++/*values for RAID Volume Page 0 VolumeStatusFlags field */ ++#define MPI2_RAIDVOL0_STATUS_FLAG_PENDING_RESYNC (0x02000000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BACKG_INIT_PENDING (0x01000000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_MDC_PENDING (0x00800000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_USER_CONSIST_PENDING (0x00400000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_MAKE_DATA_CONSISTENT (0x00200000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB (0x00100000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK (0x00080000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x00010000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT (0x00000080) ++#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020) ++#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_1E_ADJACENT_MIRROR (0x00000010) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x00000008) ++#define MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x00000004) ++#define MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED (0x00000002) ++#define MPI2_RAIDVOL0_STATUS_FLAG_ENABLED (0x00000001) ++ ++/*values for RAID Volume Page 0 SupportedPhysDisks field */ ++#define MPI2_RAIDVOL0_SUPPORT_SOLID_STATE_DISKS (0x08) ++#define MPI2_RAIDVOL0_SUPPORT_HARD_DISKS (0x04) ++#define MPI2_RAIDVOL0_SUPPORT_SAS_PROTOCOL (0x02) ++#define MPI2_RAIDVOL0_SUPPORT_SATA_PROTOCOL (0x01) ++ ++/*values for RAID Volume Page 0 InactiveStatus field */ ++#define MPI2_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) ++#define MPI2_RAIDVOLPAGE0_STALE_METADATA_INACTIVE (0x01) ++#define MPI2_RAIDVOLPAGE0_FOREIGN_VOLUME_INACTIVE (0x02) ++#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_RESOURCE_INACTIVE (0x03) ++#define MPI2_RAIDVOLPAGE0_CLONE_VOLUME_INACTIVE (0x04) ++#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_METADATA_INACTIVE (0x05) ++#define MPI2_RAIDVOLPAGE0_PREVIOUSLY_DELETED (0x06) ++ ++ ++/*RAID Volume Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 DevHandle; /*0x04 */ ++ U16 Reserved0; /*0x06 */ ++ U8 GUID[24]; /*0x08 */ ++ U8 Name[16]; /*0x20 */ ++ U64 WWID; /*0x30 */ ++ U32 Reserved1; /*0x38 */ ++ U32 Reserved2; /*0x3C */ ++} MPI2_CONFIG_PAGE_RAID_VOL_1, ++ *PTR_MPI2_CONFIG_PAGE_RAID_VOL_1, ++ Mpi2RaidVolPage1_t, *pMpi2RaidVolPage1_t; ++ ++#define MPI2_RAIDVOLPAGE1_PAGEVERSION (0x03) ++ ++ ++/**************************************************************************** ++* RAID Physical Disk Config Pages ++****************************************************************************/ ++ ++/*RAID Physical Disk Page 0 */ ++ ++typedef struct _MPI2_RAIDPHYSDISK0_SETTINGS { ++ U16 Reserved1; /*0x00 */ ++ U8 HotSparePool; /*0x02 */ ++ U8 Reserved2; /*0x03 */ ++} MPI2_RAIDPHYSDISK0_SETTINGS, ++ *PTR_MPI2_RAIDPHYSDISK0_SETTINGS, ++ Mpi2RaidPhysDisk0Settings_t, ++ *pMpi2RaidPhysDisk0Settings_t; ++ ++/*use MPI2_RAID_HOT_SPARE_POOL_ defines for the HotSparePool field */ ++ ++typedef struct _MPI2_RAIDPHYSDISK0_INQUIRY_DATA { ++ U8 VendorID[8]; /*0x00 */ ++ U8 ProductID[16]; /*0x08 */ ++ U8 ProductRevLevel[4]; /*0x18 */ ++ U8 SerialNum[32]; /*0x1C */ ++} MPI2_RAIDPHYSDISK0_INQUIRY_DATA, ++ *PTR_MPI2_RAIDPHYSDISK0_INQUIRY_DATA, ++ Mpi2RaidPhysDisk0InquiryData_t, ++ *pMpi2RaidPhysDisk0InquiryData_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 DevHandle; /*0x04 */ ++ U8 Reserved1; /*0x06 */ ++ U8 PhysDiskNum; /*0x07 */ ++ MPI2_RAIDPHYSDISK0_SETTINGS PhysDiskSettings; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ MPI2_RAIDPHYSDISK0_INQUIRY_DATA InquiryData; /*0x10 */ ++ U32 Reserved3; /*0x4C */ ++ U8 PhysDiskState; /*0x50 */ ++ U8 OfflineReason; /*0x51 */ ++ U8 IncompatibleReason; /*0x52 */ ++ U8 PhysDiskAttributes; /*0x53 */ ++ U32 PhysDiskStatusFlags;/*0x54 */ ++ U64 DeviceMaxLBA; /*0x58 */ ++ U64 HostMaxLBA; /*0x60 */ ++ U64 CoercedMaxLBA; /*0x68 */ ++ U16 BlockSize; /*0x70 */ ++ U16 Reserved5; /*0x72 */ ++ U32 Reserved6; /*0x74 */ ++} MPI2_CONFIG_PAGE_RD_PDISK_0, ++ *PTR_MPI2_CONFIG_PAGE_RD_PDISK_0, ++ Mpi2RaidPhysDiskPage0_t, ++ *pMpi2RaidPhysDiskPage0_t; ++ ++#define MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION (0x05) ++ ++/*PhysDiskState defines */ ++#define MPI2_RAID_PD_STATE_NOT_CONFIGURED (0x00) ++#define MPI2_RAID_PD_STATE_NOT_COMPATIBLE (0x01) ++#define MPI2_RAID_PD_STATE_OFFLINE (0x02) ++#define MPI2_RAID_PD_STATE_ONLINE (0x03) ++#define MPI2_RAID_PD_STATE_HOT_SPARE (0x04) ++#define MPI2_RAID_PD_STATE_DEGRADED (0x05) ++#define MPI2_RAID_PD_STATE_REBUILDING (0x06) ++#define MPI2_RAID_PD_STATE_OPTIMAL (0x07) ++ ++/*OfflineReason defines */ ++#define MPI2_PHYSDISK0_ONLINE (0x00) ++#define MPI2_PHYSDISK0_OFFLINE_MISSING (0x01) ++#define MPI2_PHYSDISK0_OFFLINE_FAILED (0x03) ++#define MPI2_PHYSDISK0_OFFLINE_INITIALIZING (0x04) ++#define MPI2_PHYSDISK0_OFFLINE_REQUESTED (0x05) ++#define MPI2_PHYSDISK0_OFFLINE_FAILED_REQUESTED (0x06) ++#define MPI2_PHYSDISK0_OFFLINE_OTHER (0xFF) ++ ++/*IncompatibleReason defines */ ++#define MPI2_PHYSDISK0_COMPATIBLE (0x00) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_PROTOCOL (0x01) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_BLOCKSIZE (0x02) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE (0x06) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF) ++ ++/*PhysDiskAttributes defines */ ++#define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK (0x0C) ++#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08) ++#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE (0x04) ++ ++#define MPI2_PHYSDISK0_ATTRIB_PROTOCOL_MASK (0x03) ++#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02) ++#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01) ++ ++/*PhysDiskStatusFlags defines */ ++#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED (0x00000040) ++#define MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET (0x00000020) ++#define MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED (0x00000010) ++#define MPI2_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00000000) ++#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x00000008) ++#define MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x00000004) ++#define MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED (0x00000002) ++#define MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x00000001) ++ ++ ++/*RAID Physical Disk Page 1 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhysDiskPaths at runtime. ++ */ ++#ifndef MPI2_RAID_PHYS_DISK1_PATH_MAX ++#define MPI2_RAID_PHYS_DISK1_PATH_MAX (1) ++#endif ++ ++typedef struct _MPI2_RAIDPHYSDISK1_PATH { ++ U16 DevHandle; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U64 WWID; /*0x04 */ ++ U64 OwnerWWID; /*0x0C */ ++ U8 OwnerIdentifier; /*0x14 */ ++ U8 Reserved2; /*0x15 */ ++ U16 Flags; /*0x16 */ ++} MPI2_RAIDPHYSDISK1_PATH, *PTR_MPI2_RAIDPHYSDISK1_PATH, ++ Mpi2RaidPhysDisk1Path_t, ++ *pMpi2RaidPhysDisk1Path_t; ++ ++/*RAID Physical Disk Page 1 Physical Disk Path Flags field defines */ ++#define MPI2_RAID_PHYSDISK1_FLAG_PRIMARY (0x0004) ++#define MPI2_RAID_PHYSDISK1_FLAG_BROKEN (0x0002) ++#define MPI2_RAID_PHYSDISK1_FLAG_INVALID (0x0001) ++ ++typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhysDiskPaths; /*0x04 */ ++ U8 PhysDiskNum; /*0x05 */ ++ U16 Reserved1; /*0x06 */ ++ U32 Reserved2; /*0x08 */ ++ MPI2_RAIDPHYSDISK1_PATH ++ PhysicalDiskPath[MPI2_RAID_PHYS_DISK1_PATH_MAX];/*0x0C */ ++} MPI2_CONFIG_PAGE_RD_PDISK_1, ++ *PTR_MPI2_CONFIG_PAGE_RD_PDISK_1, ++ Mpi2RaidPhysDiskPage1_t, ++ *pMpi2RaidPhysDiskPage1_t; ++ ++#define MPI2_RAIDPHYSDISKPAGE1_PAGEVERSION (0x02) ++ ++ ++/**************************************************************************** ++* values for fields used by several types of SAS Config Pages ++****************************************************************************/ ++ ++/*values for NegotiatedLinkRates fields */ ++#define MPI2_SAS_NEG_LINK_RATE_MASK_LOGICAL (0xF0) ++#define MPI2_SAS_NEG_LINK_RATE_SHIFT_LOGICAL (4) ++#define MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL (0x0F) ++/*link rates used for Negotiated Physical and Logical Link Rate */ ++#define MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE (0x00) ++#define MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED (0x01) ++#define MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED (0x02) ++#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03) ++#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04) ++#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS (0x05) ++#define MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY (0x06) ++#define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08) ++#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09) ++#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A) ++#define MPI25_SAS_NEG_LINK_RATE_12_0 (0x0B) ++ ++ ++/*values for AttachedPhyInfo fields */ ++#define MPI2_SAS_APHYINFO_INSIDE_ZPSDS_PERSISTENT (0x00000040) ++#define MPI2_SAS_APHYINFO_REQUESTED_INSIDE_ZPSDS (0x00000020) ++#define MPI2_SAS_APHYINFO_BREAK_REPLY_CAPABLE (0x00000010) ++ ++#define MPI2_SAS_APHYINFO_REASON_MASK (0x0000000F) ++#define MPI2_SAS_APHYINFO_REASON_UNKNOWN (0x00000000) ++#define MPI2_SAS_APHYINFO_REASON_POWER_ON (0x00000001) ++#define MPI2_SAS_APHYINFO_REASON_HARD_RESET (0x00000002) ++#define MPI2_SAS_APHYINFO_REASON_SMP_PHY_CONTROL (0x00000003) ++#define MPI2_SAS_APHYINFO_REASON_LOSS_OF_SYNC (0x00000004) ++#define MPI2_SAS_APHYINFO_REASON_MULTIPLEXING_SEQ (0x00000005) ++#define MPI2_SAS_APHYINFO_REASON_IT_NEXUS_LOSS_TIMER (0x00000006) ++#define MPI2_SAS_APHYINFO_REASON_BREAK_TIMEOUT (0x00000007) ++#define MPI2_SAS_APHYINFO_REASON_PHY_TEST_STOPPED (0x00000008) ++ ++ ++/*values for PhyInfo fields */ ++#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) ++ ++#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000) ++#define MPI2_SAS_PHYINFO_SHIFT_PHY_POWER_CONDITION (27) ++#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) ++#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) ++#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) ++ ++#define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000) ++#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000) ++#define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000) ++#define MPI2_SAS_PHYINFO_ZONE_GROUP_PERSISTENT (0x00400000) ++#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS (0x00200000) ++#define MPI2_SAS_PHYINFO_ZONING_ENABLED (0x00100000) ++ ++#define MPI2_SAS_PHYINFO_REASON_MASK (0x000F0000) ++#define MPI2_SAS_PHYINFO_REASON_UNKNOWN (0x00000000) ++#define MPI2_SAS_PHYINFO_REASON_POWER_ON (0x00010000) ++#define MPI2_SAS_PHYINFO_REASON_HARD_RESET (0x00020000) ++#define MPI2_SAS_PHYINFO_REASON_SMP_PHY_CONTROL (0x00030000) ++#define MPI2_SAS_PHYINFO_REASON_LOSS_OF_SYNC (0x00040000) ++#define MPI2_SAS_PHYINFO_REASON_MULTIPLEXING_SEQ (0x00050000) ++#define MPI2_SAS_PHYINFO_REASON_IT_NEXUS_LOSS_TIMER (0x00060000) ++#define MPI2_SAS_PHYINFO_REASON_BREAK_TIMEOUT (0x00070000) ++#define MPI2_SAS_PHYINFO_REASON_PHY_TEST_STOPPED (0x00080000) ++ ++#define MPI2_SAS_PHYINFO_MULTIPLEXING_SUPPORTED (0x00008000) ++#define MPI2_SAS_PHYINFO_SATA_PORT_ACTIVE (0x00004000) ++#define MPI2_SAS_PHYINFO_SATA_PORT_SELECTOR_PRESENT (0x00002000) ++#define MPI2_SAS_PHYINFO_VIRTUAL_PHY (0x00001000) ++ ++#define MPI2_SAS_PHYINFO_MASK_PARTIAL_PATHWAY_TIME (0x00000F00) ++#define MPI2_SAS_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME (8) ++ ++#define MPI2_SAS_PHYINFO_MASK_ROUTING_ATTRIBUTE (0x000000F0) ++#define MPI2_SAS_PHYINFO_DIRECT_ROUTING (0x00000000) ++#define MPI2_SAS_PHYINFO_SUBTRACTIVE_ROUTING (0x00000010) ++#define MPI2_SAS_PHYINFO_TABLE_ROUTING (0x00000020) ++ ++ ++/*values for SAS ProgrammedLinkRate fields */ ++#define MPI2_SAS_PRATE_MAX_RATE_MASK (0xF0) ++#define MPI2_SAS_PRATE_MAX_RATE_NOT_PROGRAMMABLE (0x00) ++#define MPI2_SAS_PRATE_MAX_RATE_1_5 (0x80) ++#define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90) ++#define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0) ++#define MPI25_SAS_PRATE_MAX_RATE_12_0 (0xB0) ++#define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F) ++#define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00) ++#define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08) ++#define MPI2_SAS_PRATE_MIN_RATE_3_0 (0x09) ++#define MPI2_SAS_PRATE_MIN_RATE_6_0 (0x0A) ++#define MPI25_SAS_PRATE_MIN_RATE_12_0 (0x0B) ++ ++ ++/*values for SAS HwLinkRate fields */ ++#define MPI2_SAS_HWRATE_MAX_RATE_MASK (0xF0) ++#define MPI2_SAS_HWRATE_MAX_RATE_1_5 (0x80) ++#define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90) ++#define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0) ++#define MPI25_SAS_HWRATE_MAX_RATE_12_0 (0xB0) ++#define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F) ++#define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08) ++#define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09) ++#define MPI2_SAS_HWRATE_MIN_RATE_6_0 (0x0A) ++#define MPI25_SAS_HWRATE_MIN_RATE_12_0 (0x0B) ++ ++ ++ ++/**************************************************************************** ++* SAS IO Unit Config Pages ++****************************************************************************/ ++ ++/*SAS IO Unit Page 0 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT0_PHY_DATA { ++ U8 Port; /*0x00 */ ++ U8 PortFlags; /*0x01 */ ++ U8 PhyFlags; /*0x02 */ ++ U8 NegotiatedLinkRate; /*0x03 */ ++ U32 ControllerPhyDeviceInfo;/*0x04 */ ++ U16 AttachedDevHandle; /*0x08 */ ++ U16 ControllerDevHandle; /*0x0A */ ++ U32 DiscoveryStatus; /*0x0C */ ++ U32 Reserved; /*0x10 */ ++} MPI2_SAS_IO_UNIT0_PHY_DATA, ++ *PTR_MPI2_SAS_IO_UNIT0_PHY_DATA, ++ Mpi2SasIOUnit0PhyData_t, ++ *pMpi2SasIOUnit0PhyData_t; ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT0_PHY_MAX ++#define MPI2_SAS_IOUNIT0_PHY_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1;/*0x08 */ ++ U8 NumPhys; /*0x0C */ ++ U8 Reserved2;/*0x0D */ ++ U16 Reserved3;/*0x0E */ ++ MPI2_SAS_IO_UNIT0_PHY_DATA ++ PhyData[MPI2_SAS_IOUNIT0_PHY_MAX]; /*0x10 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_0, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_0, ++ Mpi2SasIOUnitPage0_t, *pMpi2SasIOUnitPage0_t; ++ ++#define MPI2_SASIOUNITPAGE0_PAGEVERSION (0x05) ++ ++/*values for SAS IO Unit Page 0 PortFlags */ ++#define MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS (0x08) ++#define MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG (0x01) ++ ++/*values for SAS IO Unit Page 0 PhyFlags */ ++#define MPI2_SASIOUNIT0_PHYFLAGS_INIT_PERSIST_CONNECT (0x40) ++#define MPI2_SASIOUNIT0_PHYFLAGS_TARG_PERSIST_CONNECT (0x20) ++#define MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED (0x10) ++#define MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED (0x08) ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ ++ ++/*see mpi2_sas.h for values for ++ *SAS IO Unit Page 0 ControllerPhyDeviceInfo values */ ++ ++/*values for SAS IO Unit Page 0 DiscoveryStatus */ ++#define MPI2_SASIOUNIT0_DS_MAX_ENCLOSURES_EXCEED (0x80000000) ++#define MPI2_SASIOUNIT0_DS_MAX_EXPANDERS_EXCEED (0x40000000) ++#define MPI2_SASIOUNIT0_DS_MAX_DEVICES_EXCEED (0x20000000) ++#define MPI2_SASIOUNIT0_DS_MAX_TOPO_PHYS_EXCEED (0x10000000) ++#define MPI2_SASIOUNIT0_DS_DOWNSTREAM_INITIATOR (0x08000000) ++#define MPI2_SASIOUNIT0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000) ++#define MPI2_SASIOUNIT0_DS_EXP_MULTI_SUBTRACTIVE (0x00004000) ++#define MPI2_SASIOUNIT0_DS_MULTI_PORT_DOMAIN (0x00002000) ++#define MPI2_SASIOUNIT0_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000) ++#define MPI2_SASIOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800) ++#define MPI2_SASIOUNIT0_DS_TABLE_LINK (0x00000400) ++#define MPI2_SASIOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200) ++#define MPI2_SASIOUNIT0_DS_SMP_CRC_ERROR (0x00000100) ++#define MPI2_SASIOUNIT0_DS_SMP_FUNCTION_FAILED (0x00000080) ++#define MPI2_SASIOUNIT0_DS_INDEX_NOT_EXIST (0x00000040) ++#define MPI2_SASIOUNIT0_DS_OUT_ROUTE_ENTRIES (0x00000020) ++#define MPI2_SASIOUNIT0_DS_SMP_TIMEOUT (0x00000010) ++#define MPI2_SASIOUNIT0_DS_MULTIPLE_PORTS (0x00000004) ++#define MPI2_SASIOUNIT0_DS_UNADDRESSABLE_DEVICE (0x00000002) ++#define MPI2_SASIOUNIT0_DS_LOOP_DETECTED (0x00000001) ++ ++ ++/*SAS IO Unit Page 1 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT1_PHY_DATA { ++ U8 Port; /*0x00 */ ++ U8 PortFlags; /*0x01 */ ++ U8 PhyFlags; /*0x02 */ ++ U8 MaxMinLinkRate; /*0x03 */ ++ U32 ControllerPhyDeviceInfo; /*0x04 */ ++ U16 MaxTargetPortConnectTime; /*0x08 */ ++ U16 Reserved1; /*0x0A */ ++} MPI2_SAS_IO_UNIT1_PHY_DATA, ++ *PTR_MPI2_SAS_IO_UNIT1_PHY_DATA, ++ Mpi2SasIOUnit1PhyData_t, ++ *pMpi2SasIOUnit1PhyData_t; ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT1_PHY_MAX ++#define MPI2_SAS_IOUNIT1_PHY_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U16 ++ ControlFlags; /*0x08 */ ++ U16 ++ SASNarrowMaxQueueDepth; /*0x0A */ ++ U16 ++ AdditionalControlFlags; /*0x0C */ ++ U16 ++ SASWideMaxQueueDepth; /*0x0E */ ++ U8 ++ NumPhys; /*0x10 */ ++ U8 ++ SATAMaxQDepth; /*0x11 */ ++ U8 ++ ReportDeviceMissingDelay; /*0x12 */ ++ U8 ++ IODeviceMissingDelay; /*0x13 */ ++ MPI2_SAS_IO_UNIT1_PHY_DATA ++ PhyData[MPI2_SAS_IOUNIT1_PHY_MAX]; /*0x14 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_1, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_1, ++ Mpi2SasIOUnitPage1_t, *pMpi2SasIOUnitPage1_t; ++ ++#define MPI2_SASIOUNITPAGE1_PAGEVERSION (0x09) ++ ++/*values for SAS IO Unit Page 1 ControlFlags */ ++#define MPI2_SASIOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_3_0_MAX (0x4000) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_1_5_MAX (0x2000) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000) ++ ++#define MPI2_SASIOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600) ++#define MPI2_SASIOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9) ++#define MPI2_SASIOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x0) ++#define MPI2_SASIOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x1) ++#define MPI2_SASIOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x2) ++ ++#define MPI2_SASIOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010) ++#define MPI2_SASIOUNIT1_CONTROL_TABLE_SUBTRACTIVE_ILLEGAL (0x0008) ++#define MPI2_SASIOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004) ++#define MPI2_SASIOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) ++#define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) ++ ++/*values for SAS IO Unit Page 1 AdditionalControlFlags */ ++#define MPI2_SASIOUNIT1_ACONTROL_DA_PERSIST_CONNECT (0x0100) ++#define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL (0x0080) ++#define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040) ++#define MPI2_SASIOUNIT1_ACONTROL_INVALID_TOPOLOGY_CORRECTION (0x0020) ++#define MPI2_SASIOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET (0x0010) ++#define MPI2_SASIOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET (0x0008) ++#define MPI2_SASIOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET (0x0004) ++#define MPI2_SASIOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET (0x0002) ++#define MPI2_SASIOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) ++ ++/*defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ ++#define MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) ++#define MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16 (0x80) ++ ++/*values for SAS IO Unit Page 1 PortFlags */ ++#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) ++ ++/*values for SAS IO Unit Page 1 PhyFlags */ ++#define MPI2_SASIOUNIT1_PHYFLAGS_INIT_PERSIST_CONNECT (0x40) ++#define MPI2_SASIOUNIT1_PHYFLAGS_TARG_PERSIST_CONNECT (0x20) ++#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10) ++#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08) ++ ++/*values for SAS IO Unit Page 1 MaxMinLinkRate */ ++#define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0) ++#define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80) ++#define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90) ++#define MPI2_SASIOUNIT1_MAX_RATE_6_0 (0xA0) ++#define MPI25_SASIOUNIT1_MAX_RATE_12_0 (0xB0) ++#define MPI2_SASIOUNIT1_MIN_RATE_MASK (0x0F) ++#define MPI2_SASIOUNIT1_MIN_RATE_1_5 (0x08) ++#define MPI2_SASIOUNIT1_MIN_RATE_3_0 (0x09) ++#define MPI2_SASIOUNIT1_MIN_RATE_6_0 (0x0A) ++#define MPI25_SASIOUNIT1_MIN_RATE_12_0 (0x0B) ++ ++/*see mpi2_sas.h for values for ++ *SAS IO Unit Page 1 ControllerPhyDeviceInfo values */ ++ ++ ++/*SAS IO Unit Page 4 (for MPI v2.5 and earlier) */ ++ ++typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP { ++ U8 MaxTargetSpinup; /*0x00 */ ++ U8 SpinupDelay; /*0x01 */ ++ U8 SpinupFlags; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++} MPI2_SAS_IOUNIT4_SPINUP_GROUP, ++ *PTR_MPI2_SAS_IOUNIT4_SPINUP_GROUP, ++ Mpi2SasIOUnit4SpinupGroup_t, ++ *pMpi2SasIOUnit4SpinupGroup_t; ++/*defines for SAS IO Unit Page 4 SpinupFlags */ ++#define MPI2_SASIOUNIT4_SPINUP_DISABLE_FLAG (0x01) ++ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT4_PHY_MAX ++#define MPI2_SAS_IOUNIT4_PHY_MAX (4) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header;/*0x00 */ ++ MPI2_SAS_IOUNIT4_SPINUP_GROUP ++ SpinupGroupParameters[4]; /*0x08 */ ++ U32 ++ Reserved1; /*0x18 */ ++ U32 ++ Reserved2; /*0x1C */ ++ U32 ++ Reserved3; /*0x20 */ ++ U8 ++ BootDeviceWaitTime; /*0x24 */ ++ U8 ++ SATADeviceWaitTime; /*0x25 */ ++ U16 ++ Reserved5; /*0x26 */ ++ U8 ++ NumPhys; /*0x28 */ ++ U8 ++ PEInitialSpinupDelay; /*0x29 */ ++ U8 ++ PEReplyDelay; /*0x2A */ ++ U8 ++ Flags; /*0x2B */ ++ U8 ++ PHY[MPI2_SAS_IOUNIT4_PHY_MAX]; /*0x2C */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_4, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_4, ++ Mpi2SasIOUnitPage4_t, *pMpi2SasIOUnitPage4_t; ++ ++#define MPI2_SASIOUNITPAGE4_PAGEVERSION (0x02) ++ ++/*defines for Flags field */ ++#define MPI2_SASIOUNIT4_FLAGS_AUTO_PORTENABLE (0x01) ++ ++/*defines for PHY field */ ++#define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03) ++ ++ ++/*SAS IO Unit Page 5 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS { ++ U8 ControlFlags; /*0x00 */ ++ U8 PortWidthModGroup; /*0x01 */ ++ U16 InactivityTimerExponent; /*0x02 */ ++ U8 SATAPartialTimeout; /*0x04 */ ++ U8 Reserved2; /*0x05 */ ++ U8 SATASlumberTimeout; /*0x06 */ ++ U8 Reserved3; /*0x07 */ ++ U8 SASPartialTimeout; /*0x08 */ ++ U8 Reserved4; /*0x09 */ ++ U8 SASSlumberTimeout; /*0x0A */ ++ U8 Reserved5; /*0x0B */ ++} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, ++ *PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, ++ Mpi2SasIOUnit5PhyPmSettings_t, ++ *pMpi2SasIOUnit5PhyPmSettings_t; ++ ++/*defines for ControlFlags field */ ++#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE (0x08) ++#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE (0x04) ++#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02) ++#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01) ++ ++/*defines for PortWidthModeGroup field */ ++#define MPI2_SASIOUNIT5_PWMG_DISABLE (0xFF) ++ ++/*defines for InactivityTimerExponent field */ ++#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12) ++#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL (0x0700) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL (8) ++#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER (0x0070) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER (4) ++#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL (0x0007) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL (0) ++ ++#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS (7) ++#define MPI2_SASIOUNIT5_ITE_ONE_SECOND (6) ++#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS (5) ++#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS (4) ++#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND (3) ++#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS (2) ++#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS (1) ++#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND (0) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT5_PHY_MAX ++#define MPI2_SAS_IOUNIT5_PHY_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhys; /*0x08 */ ++ U8 Reserved1;/*0x09 */ ++ U16 Reserved2;/*0x0A */ ++ U32 Reserved3;/*0x0C */ ++ MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS ++ SASPhyPowerManagementSettings[MPI2_SAS_IOUNIT5_PHY_MAX];/*0x10 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_5, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5, ++ Mpi2SasIOUnitPage5_t, *pMpi2SasIOUnitPage5_t; ++ ++#define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x01) ++ ++ ++/*SAS IO Unit Page 6 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS { ++ U8 CurrentStatus; /*0x00 */ ++ U8 CurrentModulation; /*0x01 */ ++ U8 CurrentUtilization; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U32 Reserved2; /*0x04 */ ++} MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS, ++ *PTR_MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS, ++ Mpi2SasIOUnit6PortWidthModGroupStatus_t, ++ *pMpi2SasIOUnit6PortWidthModGroupStatus_t; ++ ++/*defines for CurrentStatus field */ ++#define MPI2_SASIOUNIT6_STATUS_UNAVAILABLE (0x00) ++#define MPI2_SASIOUNIT6_STATUS_UNCONFIGURED (0x01) ++#define MPI2_SASIOUNIT6_STATUS_INVALID_CONFIG (0x02) ++#define MPI2_SASIOUNIT6_STATUS_LINK_DOWN (0x03) ++#define MPI2_SASIOUNIT6_STATUS_OBSERVATION_ONLY (0x04) ++#define MPI2_SASIOUNIT6_STATUS_INACTIVE (0x05) ++#define MPI2_SASIOUNIT6_STATUS_ACTIVE_IOUNIT (0x06) ++#define MPI2_SASIOUNIT6_STATUS_ACTIVE_HOST (0x07) ++ ++/*defines for CurrentModulation field */ ++#define MPI2_SASIOUNIT6_MODULATION_25_PERCENT (0x00) ++#define MPI2_SASIOUNIT6_MODULATION_50_PERCENT (0x01) ++#define MPI2_SASIOUNIT6_MODULATION_75_PERCENT (0x02) ++#define MPI2_SASIOUNIT6_MODULATION_100_PERCENT (0x03) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumGroups at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT6_GROUP_MAX ++#define MPI2_SAS_IOUNIT6_GROUP_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_6 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ U8 NumGroups; /*0x10 */ ++ U8 Reserved3; /*0x11 */ ++ U16 Reserved4; /*0x12 */ ++ MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS ++ PortWidthModulationGroupStatus[MPI2_SAS_IOUNIT6_GROUP_MAX]; /*0x14 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_6, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_6, ++ Mpi2SasIOUnitPage6_t, *pMpi2SasIOUnitPage6_t; ++ ++#define MPI2_SASIOUNITPAGE6_PAGEVERSION (0x00) ++ ++ ++/*SAS IO Unit Page 7 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS { ++ U8 Flags; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U8 Threshold75Pct; /*0x04 */ ++ U8 Threshold50Pct; /*0x05 */ ++ U8 Threshold25Pct; /*0x06 */ ++ U8 Reserved3; /*0x07 */ ++} MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS, ++ *PTR_MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS, ++ Mpi2SasIOUnit7PortWidthModGroupSettings_t, ++ *pMpi2SasIOUnit7PortWidthModGroupSettings_t; ++ ++/*defines for Flags field */ ++#define MPI2_SASIOUNIT7_FLAGS_ENABLE_PORT_WIDTH_MODULATION (0x01) ++ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumGroups at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT7_GROUP_MAX ++#define MPI2_SAS_IOUNIT7_GROUP_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_7 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 SamplingInterval; /*0x08 */ ++ U8 WindowLength; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Reserved2; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U8 NumGroups; /*0x14 */ ++ U8 Reserved4; /*0x15 */ ++ U16 Reserved5; /*0x16 */ ++ MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS ++ PortWidthModulationGroupSettings[MPI2_SAS_IOUNIT7_GROUP_MAX];/*0x18 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_7, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_7, ++ Mpi2SasIOUnitPage7_t, *pMpi2SasIOUnitPage7_t; ++ ++#define MPI2_SASIOUNITPAGE7_PAGEVERSION (0x00) ++ ++ ++/*SAS IO Unit Page 8 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U32 ++ PowerManagementCapabilities; /*0x0C */ ++ U8 ++ TxRxSleepStatus; /*0x10 */ ++ U8 ++ Reserved2; /*0x11 */ ++ U16 ++ Reserved3; /*0x12 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_8, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_8, ++ Mpi2SasIOUnitPage8_t, *pMpi2SasIOUnitPage8_t; ++ ++#define MPI2_SASIOUNITPAGE8_PAGEVERSION (0x00) ++ ++/*defines for PowerManagementCapabilities field */ ++#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD (0x00001000) ++#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE (0x00000800) ++#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE (0x00000400) ++#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE (0x00000200) ++#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE (0x00000100) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD (0x00000010) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE (0x00000008) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE (0x00000004) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE (0x00000002) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE (0x00000001) ++ ++/*defines for TxRxSleepStatus field */ ++#define MPI25_SASIOUNIT8_TXRXSLEEP_UNSUPPORTED (0x00) ++#define MPI25_SASIOUNIT8_TXRXSLEEP_DISENGAGED (0x01) ++#define MPI25_SASIOUNIT8_TXRXSLEEP_ACTIVE (0x02) ++#define MPI25_SASIOUNIT8_TXRXSLEEP_SHUTDOWN (0x03) ++ ++ ++ ++/*SAS IO Unit Page 16 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT16 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U64 ++ TimeStamp; /*0x08 */ ++ U32 ++ Reserved1; /*0x10 */ ++ U32 ++ Reserved2; /*0x14 */ ++ U32 ++ FastPathPendedRequests; /*0x18 */ ++ U32 ++ FastPathUnPendedRequests; /*0x1C */ ++ U32 ++ FastPathHostRequestStarts; /*0x20 */ ++ U32 ++ FastPathFirmwareRequestStarts; /*0x24 */ ++ U32 ++ FastPathHostCompletions; /*0x28 */ ++ U32 ++ FastPathFirmwareCompletions; /*0x2C */ ++ U32 ++ NonFastPathRequestStarts; /*0x30 */ ++ U32 ++ NonFastPathHostCompletions; /*0x30 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT16, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT16, ++ Mpi2SasIOUnitPage16_t, *pMpi2SasIOUnitPage16_t; ++ ++#define MPI2_SASIOUNITPAGE16_PAGEVERSION (0x00) ++ ++ ++/**************************************************************************** ++* SAS Expander Config Pages ++****************************************************************************/ ++ ++/*SAS Expander Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_EXPANDER_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U8 ++ PhysicalPort; /*0x08 */ ++ U8 ++ ReportGenLength; /*0x09 */ ++ U16 ++ EnclosureHandle; /*0x0A */ ++ U64 ++ SASAddress; /*0x0C */ ++ U32 ++ DiscoveryStatus; /*0x14 */ ++ U16 ++ DevHandle; /*0x18 */ ++ U16 ++ ParentDevHandle; /*0x1A */ ++ U16 ++ ExpanderChangeCount; /*0x1C */ ++ U16 ++ ExpanderRouteIndexes; /*0x1E */ ++ U8 ++ NumPhys; /*0x20 */ ++ U8 ++ SASLevel; /*0x21 */ ++ U16 ++ Flags; /*0x22 */ ++ U16 ++ STPBusInactivityTimeLimit; /*0x24 */ ++ U16 ++ STPMaxConnectTimeLimit; /*0x26 */ ++ U16 ++ STP_SMP_NexusLossTime; /*0x28 */ ++ U16 ++ MaxNumRoutedSasAddresses; /*0x2A */ ++ U64 ++ ActiveZoneManagerSASAddress;/*0x2C */ ++ U16 ++ ZoneLockInactivityLimit; /*0x34 */ ++ U16 ++ Reserved1; /*0x36 */ ++ U8 ++ TimeToReducedFunc; /*0x38 */ ++ U8 ++ InitialTimeToReducedFunc; /*0x39 */ ++ U8 ++ MaxReducedFuncTime; /*0x3A */ ++ U8 ++ Reserved2; /*0x3B */ ++} MPI2_CONFIG_PAGE_EXPANDER_0, ++ *PTR_MPI2_CONFIG_PAGE_EXPANDER_0, ++ Mpi2ExpanderPage0_t, *pMpi2ExpanderPage0_t; ++ ++#define MPI2_SASEXPANDER0_PAGEVERSION (0x06) ++ ++/*values for SAS Expander Page 0 DiscoveryStatus field */ ++#define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED (0x80000000) ++#define MPI2_SAS_EXPANDER0_DS_MAX_EXPANDERS_EXCEED (0x40000000) ++#define MPI2_SAS_EXPANDER0_DS_MAX_DEVICES_EXCEED (0x20000000) ++#define MPI2_SAS_EXPANDER0_DS_MAX_TOPO_PHYS_EXCEED (0x10000000) ++#define MPI2_SAS_EXPANDER0_DS_DOWNSTREAM_INITIATOR (0x08000000) ++#define MPI2_SAS_EXPANDER0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000) ++#define MPI2_SAS_EXPANDER0_DS_EXP_MULTI_SUBTRACTIVE (0x00004000) ++#define MPI2_SAS_EXPANDER0_DS_MULTI_PORT_DOMAIN (0x00002000) ++#define MPI2_SAS_EXPANDER0_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000) ++#define MPI2_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE (0x00000800) ++#define MPI2_SAS_EXPANDER0_DS_TABLE_LINK (0x00000400) ++#define MPI2_SAS_EXPANDER0_DS_SUBTRACTIVE_LINK (0x00000200) ++#define MPI2_SAS_EXPANDER0_DS_SMP_CRC_ERROR (0x00000100) ++#define MPI2_SAS_EXPANDER0_DS_SMP_FUNCTION_FAILED (0x00000080) ++#define MPI2_SAS_EXPANDER0_DS_INDEX_NOT_EXIST (0x00000040) ++#define MPI2_SAS_EXPANDER0_DS_OUT_ROUTE_ENTRIES (0x00000020) ++#define MPI2_SAS_EXPANDER0_DS_SMP_TIMEOUT (0x00000010) ++#define MPI2_SAS_EXPANDER0_DS_MULTIPLE_PORTS (0x00000004) ++#define MPI2_SAS_EXPANDER0_DS_UNADDRESSABLE_DEVICE (0x00000002) ++#define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001) ++ ++/*values for SAS Expander Page 0 Flags field */ ++#define MPI2_SAS_EXPANDER0_FLAGS_REDUCED_FUNCTIONALITY (0x2000) ++#define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED (0x1000) ++#define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES (0x0800) ++#define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES (0x0400) ++#define MPI2_SAS_EXPANDER0_FLAGS_ZONING_SUPPORT (0x0200) ++#define MPI2_SAS_EXPANDER0_FLAGS_ENABLED_ZONING (0x0100) ++#define MPI2_SAS_EXPANDER0_FLAGS_TABLE_TO_TABLE_SUPPORT (0x0080) ++#define MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE (0x0010) ++#define MPI2_SAS_EXPANDER0_FLAGS_OTHERS_CONFIG (0x0004) ++#define MPI2_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS (0x0002) ++#define MPI2_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG (0x0001) ++ ++ ++/*SAS Expander Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_EXPANDER_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U8 ++ PhysicalPort; /*0x08 */ ++ U8 ++ Reserved1; /*0x09 */ ++ U16 ++ Reserved2; /*0x0A */ ++ U8 ++ NumPhys; /*0x0C */ ++ U8 ++ Phy; /*0x0D */ ++ U16 ++ NumTableEntriesProgrammed; /*0x0E */ ++ U8 ++ ProgrammedLinkRate; /*0x10 */ ++ U8 ++ HwLinkRate; /*0x11 */ ++ U16 ++ AttachedDevHandle; /*0x12 */ ++ U32 ++ PhyInfo; /*0x14 */ ++ U32 ++ AttachedDeviceInfo; /*0x18 */ ++ U16 ++ ExpanderDevHandle; /*0x1C */ ++ U8 ++ ChangeCount; /*0x1E */ ++ U8 ++ NegotiatedLinkRate; /*0x1F */ ++ U8 ++ PhyIdentifier; /*0x20 */ ++ U8 ++ AttachedPhyIdentifier; /*0x21 */ ++ U8 ++ Reserved3; /*0x22 */ ++ U8 ++ DiscoveryInfo; /*0x23 */ ++ U32 ++ AttachedPhyInfo; /*0x24 */ ++ U8 ++ ZoneGroup; /*0x28 */ ++ U8 ++ SelfConfigStatus; /*0x29 */ ++ U16 ++ Reserved4; /*0x2A */ ++} MPI2_CONFIG_PAGE_EXPANDER_1, ++ *PTR_MPI2_CONFIG_PAGE_EXPANDER_1, ++ Mpi2ExpanderPage1_t, *pMpi2ExpanderPage1_t; ++ ++#define MPI2_SASEXPANDER1_PAGEVERSION (0x02) ++ ++/*use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */ ++ ++/*use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */ ++ ++/*use MPI2_SAS_PHYINFO_ for the PhyInfo field */ ++ ++/*see mpi2_sas.h for the MPI2_SAS_DEVICE_INFO_ defines ++ *used for the AttachedDeviceInfo field */ ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ ++ ++/*values for SAS Expander Page 1 DiscoveryInfo field */ ++#define MPI2_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED (0x04) ++#define MPI2_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE (0x02) ++#define MPI2_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES (0x01) ++ ++/*use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */ ++ ++ ++/**************************************************************************** ++* SAS Device Config Pages ++****************************************************************************/ ++ ++/*SAS Device Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U16 ++ Slot; /*0x08 */ ++ U16 ++ EnclosureHandle; /*0x0A */ ++ U64 ++ SASAddress; /*0x0C */ ++ U16 ++ ParentDevHandle; /*0x14 */ ++ U8 ++ PhyNum; /*0x16 */ ++ U8 ++ AccessStatus; /*0x17 */ ++ U16 ++ DevHandle; /*0x18 */ ++ U8 ++ AttachedPhyIdentifier; /*0x1A */ ++ U8 ++ ZoneGroup; /*0x1B */ ++ U32 ++ DeviceInfo; /*0x1C */ ++ U16 ++ Flags; /*0x20 */ ++ U8 ++ PhysicalPort; /*0x22 */ ++ U8 ++ MaxPortConnections; /*0x23 */ ++ U64 ++ DeviceName; /*0x24 */ ++ U8 ++ PortGroups; /*0x2C */ ++ U8 ++ DmaGroup; /*0x2D */ ++ U8 ++ ControlGroup; /*0x2E */ ++ U8 ++ EnclosureLevel; /*0x2F */ ++ U32 ++ ConnectorName[4]; /*0x30 */ ++ U32 ++ Reserved3; /*0x34 */ ++} MPI2_CONFIG_PAGE_SAS_DEV_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_DEV_0, ++ Mpi2SasDevicePage0_t, ++ *pMpi2SasDevicePage0_t; ++ ++#define MPI2_SASDEVICE0_PAGEVERSION (0x09) ++ ++/*values for SAS Device Page 0 AccessStatus field */ ++#define MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION (0x04) ++#define MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE (0x05) ++#define MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE (0x06) ++#define MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED (0x07) ++/*specific values for SATA Init failures */ ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG (0x12) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION (0x13) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER (0x14) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN (0x15) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN (0x16) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN (0x17) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION (0x18) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE (0x19) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX (0x1F) ++ ++/*see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ ++ ++/*values for SAS Device Page 0 Flags field */ ++#define MPI2_SAS_DEVICE0_FLAGS_UNAUTHORIZED_DEVICE (0x8000) ++#define MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH (0x4000) ++#define MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE (0x2000) ++#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000) ++#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) ++#define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) ++#define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) ++#define MPI2_SAS_DEVICE0_FLAGS_PERSIST_CAPABLE (0x0004) ++#define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID (0x0002) ++#define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) ++ ++ ++/*SAS Device Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U64 ++ SASAddress; /*0x0C */ ++ U32 ++ Reserved2; /*0x14 */ ++ U16 ++ DevHandle; /*0x18 */ ++ U16 ++ Reserved3; /*0x1A */ ++ U8 ++ InitialRegDeviceFIS[20];/*0x1C */ ++} MPI2_CONFIG_PAGE_SAS_DEV_1, ++ *PTR_MPI2_CONFIG_PAGE_SAS_DEV_1, ++ Mpi2SasDevicePage1_t, ++ *pMpi2SasDevicePage1_t; ++ ++#define MPI2_SASDEVICE1_PAGEVERSION (0x01) ++ ++ ++/**************************************************************************** ++* SAS PHY Config Pages ++****************************************************************************/ ++ ++/*SAS PHY Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U16 ++ OwnerDevHandle; /*0x08 */ ++ U16 ++ Reserved1; /*0x0A */ ++ U16 ++ AttachedDevHandle; /*0x0C */ ++ U8 ++ AttachedPhyIdentifier; /*0x0E */ ++ U8 ++ Reserved2; /*0x0F */ ++ U32 ++ AttachedPhyInfo; /*0x10 */ ++ U8 ++ ProgrammedLinkRate; /*0x14 */ ++ U8 ++ HwLinkRate; /*0x15 */ ++ U8 ++ ChangeCount; /*0x16 */ ++ U8 ++ Flags; /*0x17 */ ++ U32 ++ PhyInfo; /*0x18 */ ++ U8 ++ NegotiatedLinkRate; /*0x1C */ ++ U8 ++ Reserved3; /*0x1D */ ++ U16 ++ Reserved4; /*0x1E */ ++} MPI2_CONFIG_PAGE_SAS_PHY_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_0, ++ Mpi2SasPhyPage0_t, *pMpi2SasPhyPage0_t; ++ ++#define MPI2_SASPHY0_PAGEVERSION (0x03) ++ ++/*use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */ ++ ++/*use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */ ++ ++/*use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */ ++ ++/*values for SAS PHY Page 0 Flags field */ ++#define MPI2_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01) ++ ++/*use MPI2_SAS_PHYINFO_ for the PhyInfo field */ ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ ++ ++ ++/*SAS PHY Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U32 ++ InvalidDwordCount; /*0x0C */ ++ U32 ++ RunningDisparityErrorCount; /*0x10 */ ++ U32 ++ LossDwordSynchCount; /*0x14 */ ++ U32 ++ PhyResetProblemCount; /*0x18 */ ++} MPI2_CONFIG_PAGE_SAS_PHY_1, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_1, ++ Mpi2SasPhyPage1_t, *pMpi2SasPhyPage1_t; ++ ++#define MPI2_SASPHY1_PAGEVERSION (0x01) ++ ++ ++/*SAS PHY Page 2 */ ++ ++typedef struct _MPI2_SASPHY2_PHY_EVENT { ++ U8 PhyEventCode; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 PhyEventInfo; /*0x04 */ ++} MPI2_SASPHY2_PHY_EVENT, *PTR_MPI2_SASPHY2_PHY_EVENT, ++ Mpi2SasPhy2PhyEvent_t, *pMpi2SasPhy2PhyEvent_t; ++ ++/*use MPI2_SASPHY3_EVENT_CODE_ for the PhyEventCode field */ ++ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhyEvents at runtime. ++ */ ++#ifndef MPI2_SASPHY2_PHY_EVENT_MAX ++#define MPI2_SASPHY2_PHY_EVENT_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_2 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U8 ++ NumPhyEvents; /*0x0C */ ++ U8 ++ Reserved2; /*0x0D */ ++ U16 ++ Reserved3; /*0x0E */ ++ MPI2_SASPHY2_PHY_EVENT ++ PhyEvent[MPI2_SASPHY2_PHY_EVENT_MAX]; /*0x10 */ ++} MPI2_CONFIG_PAGE_SAS_PHY_2, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_2, ++ Mpi2SasPhyPage2_t, ++ *pMpi2SasPhyPage2_t; ++ ++#define MPI2_SASPHY2_PAGEVERSION (0x00) ++ ++ ++/*SAS PHY Page 3 */ ++ ++typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG { ++ U8 PhyEventCode; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U8 CounterType; /*0x04 */ ++ U8 ThresholdWindow; /*0x05 */ ++ U8 TimeUnits; /*0x06 */ ++ U8 Reserved3; /*0x07 */ ++ U32 EventThreshold; /*0x08 */ ++ U16 ThresholdFlags; /*0x0C */ ++ U16 Reserved4; /*0x0E */ ++} MPI2_SASPHY3_PHY_EVENT_CONFIG, ++ *PTR_MPI2_SASPHY3_PHY_EVENT_CONFIG, ++ Mpi2SasPhy3PhyEventConfig_t, ++ *pMpi2SasPhy3PhyEventConfig_t; ++ ++/*values for PhyEventCode field */ ++#define MPI2_SASPHY3_EVENT_CODE_NO_EVENT (0x00) ++#define MPI2_SASPHY3_EVENT_CODE_INVALID_DWORD (0x01) ++#define MPI2_SASPHY3_EVENT_CODE_RUNNING_DISPARITY_ERROR (0x02) ++#define MPI2_SASPHY3_EVENT_CODE_LOSS_DWORD_SYNC (0x03) ++#define MPI2_SASPHY3_EVENT_CODE_PHY_RESET_PROBLEM (0x04) ++#define MPI2_SASPHY3_EVENT_CODE_ELASTICITY_BUF_OVERFLOW (0x05) ++#define MPI2_SASPHY3_EVENT_CODE_RX_ERROR (0x06) ++#define MPI2_SASPHY3_EVENT_CODE_RX_ADDR_FRAME_ERROR (0x20) ++#define MPI2_SASPHY3_EVENT_CODE_TX_AC_OPEN_REJECT (0x21) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AC_OPEN_REJECT (0x22) ++#define MPI2_SASPHY3_EVENT_CODE_TX_RC_OPEN_REJECT (0x23) ++#define MPI2_SASPHY3_EVENT_CODE_RX_RC_OPEN_REJECT (0x24) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_PARTIAL_WAITING_ON (0x25) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_CONNECT_WAITING_ON (0x26) ++#define MPI2_SASPHY3_EVENT_CODE_TX_BREAK (0x27) ++#define MPI2_SASPHY3_EVENT_CODE_RX_BREAK (0x28) ++#define MPI2_SASPHY3_EVENT_CODE_BREAK_TIMEOUT (0x29) ++#define MPI2_SASPHY3_EVENT_CODE_CONNECTION (0x2A) ++#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_PATHWAY_BLOCKED (0x2B) ++#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_ARB_WAIT_TIME (0x2C) ++#define MPI2_SASPHY3_EVENT_CODE_PEAK_ARB_WAIT_TIME (0x2D) ++#define MPI2_SASPHY3_EVENT_CODE_PEAK_CONNECT_TIME (0x2E) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_FRAMES (0x40) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_FRAMES (0x41) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_ERROR_FRAMES (0x42) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_ERROR_FRAMES (0x43) ++#define MPI2_SASPHY3_EVENT_CODE_TX_CREDIT_BLOCKED (0x44) ++#define MPI2_SASPHY3_EVENT_CODE_RX_CREDIT_BLOCKED (0x45) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SATA_FRAMES (0x50) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SATA_FRAMES (0x51) ++#define MPI2_SASPHY3_EVENT_CODE_SATA_OVERFLOW (0x52) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_FRAMES (0x60) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_FRAMES (0x61) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_ERROR_FRAMES (0x63) ++#define MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT (0xD0) ++#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE (0xD1) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AIP (0xD2) ++ ++/*Following codes are product specific and in MPI v2.6 and later */ ++#define MPI2_SASPHY3_EVENT_CODE_LCARB_WAIT_TIME (0xD3) ++#define MPI2_SASPHY3_EVENT_CODE_RCVD_CONN_RESP_WAIT_TIME (0xD4) ++#define MPI2_SASPHY3_EVENT_CODE_LCCONN_TIME (0xD5) ++#define MPI2_SASPHY3_EVENT_CODE_SSP_TX_START_TRANSMIT (0xD6) ++#define MPI2_SASPHY3_EVENT_CODE_SATA_TX_START (0xD7) ++#define MPI2_SASPHY3_EVENT_CODE_SMP_TX_START_TRANSMT (0xD8) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_BREAK_CONN (0xD9) ++#define MPI2_SASPHY3_EVENT_CODE_SSP_RX_START_RECEIVE (0xDA) ++#define MPI2_SASPHY3_EVENT_CODE_SATA_RX_START_RECEIVE (0xDB) ++#define MPI2_SASPHY3_EVENT_CODE_SMP_RX_START_RECEIVE (0xDC) ++ ++ ++/*values for the CounterType field */ ++#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING (0x00) ++#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING (0x01) ++#define MPI2_SASPHY3_COUNTER_TYPE_PEAK_VALUE (0x02) ++ ++/*values for the TimeUnits field */ ++#define MPI2_SASPHY3_TIME_UNITS_10_MICROSECONDS (0x00) ++#define MPI2_SASPHY3_TIME_UNITS_100_MICROSECONDS (0x01) ++#define MPI2_SASPHY3_TIME_UNITS_1_MILLISECOND (0x02) ++#define MPI2_SASPHY3_TIME_UNITS_10_MILLISECONDS (0x03) ++ ++/*values for the ThresholdFlags field */ ++#define MPI2_SASPHY3_TFLAGS_PHY_RESET (0x0002) ++#define MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY (0x0001) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhyEvents at runtime. ++ */ ++#ifndef MPI2_SASPHY3_PHY_EVENT_MAX ++#define MPI2_SASPHY3_PHY_EVENT_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U8 ++ NumPhyEvents; /*0x0C */ ++ U8 ++ Reserved2; /*0x0D */ ++ U16 ++ Reserved3; /*0x0E */ ++ MPI2_SASPHY3_PHY_EVENT_CONFIG ++ PhyEventConfig[MPI2_SASPHY3_PHY_EVENT_MAX]; /*0x10 */ ++} MPI2_CONFIG_PAGE_SAS_PHY_3, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_3, ++ Mpi2SasPhyPage3_t, *pMpi2SasPhyPage3_t; ++ ++#define MPI2_SASPHY3_PAGEVERSION (0x00) ++ ++ ++/*SAS PHY Page 4 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_4 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U16 ++ Reserved1; /*0x08 */ ++ U8 ++ Reserved2; /*0x0A */ ++ U8 ++ Flags; /*0x0B */ ++ U8 ++ InitialFrame[28]; /*0x0C */ ++} MPI2_CONFIG_PAGE_SAS_PHY_4, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_4, ++ Mpi2SasPhyPage4_t, *pMpi2SasPhyPage4_t; ++ ++#define MPI2_SASPHY4_PAGEVERSION (0x00) ++ ++/*values for the Flags field */ ++#define MPI2_SASPHY4_FLAGS_FRAME_VALID (0x02) ++#define MPI2_SASPHY4_FLAGS_SATA_FRAME (0x01) ++ ++ ++ ++ ++/**************************************************************************** ++* SAS Port Config Pages ++****************************************************************************/ ++ ++/*SAS Port Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PORT_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U8 ++ PortNumber; /*0x08 */ ++ U8 ++ PhysicalPort; /*0x09 */ ++ U8 ++ PortWidth; /*0x0A */ ++ U8 ++ PhysicalPortWidth; /*0x0B */ ++ U8 ++ ZoneGroup; /*0x0C */ ++ U8 ++ Reserved1; /*0x0D */ ++ U16 ++ Reserved2; /*0x0E */ ++ U64 ++ SASAddress; /*0x10 */ ++ U32 ++ DeviceInfo; /*0x18 */ ++ U32 ++ Reserved3; /*0x1C */ ++ U32 ++ Reserved4; /*0x20 */ ++} MPI2_CONFIG_PAGE_SAS_PORT_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PORT_0, ++ Mpi2SasPortPage0_t, *pMpi2SasPortPage0_t; ++ ++#define MPI2_SASPORT0_PAGEVERSION (0x00) ++ ++/*see mpi2_sas.h for values for SAS Port Page 0 DeviceInfo values */ ++ ++ ++/**************************************************************************** ++* SAS Enclosure Config Pages ++****************************************************************************/ ++ ++/*SAS Enclosure Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U64 ++ EnclosureLogicalID; /*0x0C */ ++ U16 ++ Flags; /*0x14 */ ++ U16 ++ EnclosureHandle; /*0x16 */ ++ U16 ++ NumSlots; /*0x18 */ ++ U16 ++ StartSlot; /*0x1A */ ++ U8 ++ Reserved2; /*0x1C */ ++ U8 ++ EnclosureLevel; /*0x1D */ ++ U16 ++ SEPDevHandle; /*0x1E */ ++ U32 ++ Reserved3; /*0x20 */ ++ U32 ++ Reserved4; /*0x24 */ ++} MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0, ++ Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t; ++ ++#define MPI2_SASENCLOSURE0_PAGEVERSION (0x04) ++ ++/*values for SAS Enclosure Page 0 Flags field */ ++#define MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID (0x0010) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK (0x000F) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN (0x0000) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES (0x0001) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005) ++ ++ ++/**************************************************************************** ++* Log Config Page ++****************************************************************************/ ++ ++/*Log Page 0 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumLogEntries at runtime. ++ */ ++#ifndef MPI2_LOG_0_NUM_LOG_ENTRIES ++#define MPI2_LOG_0_NUM_LOG_ENTRIES (1) ++#endif ++ ++#define MPI2_LOG_0_LOG_DATA_LENGTH (0x1C) ++ ++typedef struct _MPI2_LOG_0_ENTRY { ++ U64 TimeStamp; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U16 LogSequence; /*0x0C */ ++ U16 LogEntryQualifier; /*0x0E */ ++ U8 VP_ID; /*0x10 */ ++ U8 VF_ID; /*0x11 */ ++ U16 Reserved2; /*0x12 */ ++ U8 ++ LogData[MPI2_LOG_0_LOG_DATA_LENGTH];/*0x14 */ ++} MPI2_LOG_0_ENTRY, *PTR_MPI2_LOG_0_ENTRY, ++ Mpi2Log0Entry_t, *pMpi2Log0Entry_t; ++ ++/*values for Log Page 0 LogEntry LogEntryQualifier field */ ++#define MPI2_LOG_0_ENTRY_QUAL_ENTRY_UNUSED (0x0000) ++#define MPI2_LOG_0_ENTRY_QUAL_POWER_ON_RESET (0x0001) ++#define MPI2_LOG_0_ENTRY_QUAL_TIMESTAMP_UPDATE (0x0002) ++#define MPI2_LOG_0_ENTRY_QUAL_MIN_IMPLEMENT_SPEC (0x8000) ++#define MPI2_LOG_0_ENTRY_QUAL_MAX_IMPLEMENT_SPEC (0xFFFF) ++ ++typedef struct _MPI2_CONFIG_PAGE_LOG_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ U16 NumLogEntries;/*0x10 */ ++ U16 Reserved3; /*0x12 */ ++ MPI2_LOG_0_ENTRY ++ LogEntry[MPI2_LOG_0_NUM_LOG_ENTRIES]; /*0x14 */ ++} MPI2_CONFIG_PAGE_LOG_0, *PTR_MPI2_CONFIG_PAGE_LOG_0, ++ Mpi2LogPage0_t, *pMpi2LogPage0_t; ++ ++#define MPI2_LOG_0_PAGEVERSION (0x02) ++ ++ ++/**************************************************************************** ++* RAID Config Page ++****************************************************************************/ ++ ++/*RAID Page 0 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumElements at runtime. ++ */ ++#ifndef MPI2_RAIDCONFIG0_MAX_ELEMENTS ++#define MPI2_RAIDCONFIG0_MAX_ELEMENTS (1) ++#endif ++ ++typedef struct _MPI2_RAIDCONFIG0_CONFIG_ELEMENT { ++ U16 ElementFlags; /*0x00 */ ++ U16 VolDevHandle; /*0x02 */ ++ U8 HotSparePool; /*0x04 */ ++ U8 PhysDiskNum; /*0x05 */ ++ U16 PhysDiskDevHandle; /*0x06 */ ++} MPI2_RAIDCONFIG0_CONFIG_ELEMENT, ++ *PTR_MPI2_RAIDCONFIG0_CONFIG_ELEMENT, ++ Mpi2RaidConfig0ConfigElement_t, ++ *pMpi2RaidConfig0ConfigElement_t; ++ ++/*values for the ElementFlags field */ ++#define MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE (0x000F) ++#define MPI2_RAIDCONFIG0_EFLAGS_VOLUME_ELEMENT (0x0000) ++#define MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT (0x0001) ++#define MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT (0x0002) ++#define MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT (0x0003) ++ ++ ++typedef struct _MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 NumHotSpares; /*0x08 */ ++ U8 NumPhysDisks; /*0x09 */ ++ U8 NumVolumes; /*0x0A */ ++ U8 ConfigNum; /*0x0B */ ++ U32 Flags; /*0x0C */ ++ U8 ConfigGUID[24]; /*0x10 */ ++ U32 Reserved1; /*0x28 */ ++ U8 NumElements; /*0x2C */ ++ U8 Reserved2; /*0x2D */ ++ U16 Reserved3; /*0x2E */ ++ MPI2_RAIDCONFIG0_CONFIG_ELEMENT ++ ConfigElement[MPI2_RAIDCONFIG0_MAX_ELEMENTS]; /*0x30 */ ++} MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0, ++ *PTR_MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0, ++ Mpi2RaidConfigurationPage0_t, ++ *pMpi2RaidConfigurationPage0_t; ++ ++#define MPI2_RAIDCONFIG0_PAGEVERSION (0x00) ++ ++/*values for RAID Configuration Page 0 Flags field */ ++#define MPI2_RAIDCONFIG0_FLAG_FOREIGN_CONFIG (0x00000001) ++ ++ ++/**************************************************************************** ++* Driver Persistent Mapping Config Pages ++****************************************************************************/ ++ ++/*Driver Persistent Mapping Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY { ++ U64 PhysicalIdentifier; /*0x00 */ ++ U16 MappingInformation; /*0x08 */ ++ U16 DeviceIndex; /*0x0A */ ++ U32 PhysicalBitsMapping; /*0x0C */ ++ U32 Reserved1; /*0x10 */ ++} MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY, ++ *PTR_MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY, ++ Mpi2DriverMap0Entry_t, *pMpi2DriverMap0Entry_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY Entry; /*0x08 */ ++} MPI2_CONFIG_PAGE_DRIVER_MAPPING_0, ++ *PTR_MPI2_CONFIG_PAGE_DRIVER_MAPPING_0, ++ Mpi2DriverMappingPage0_t, *pMpi2DriverMappingPage0_t; ++ ++#define MPI2_DRIVERMAPPING0_PAGEVERSION (0x00) ++ ++/*values for Driver Persistent Mapping Page 0 MappingInformation field */ ++#define MPI2_DRVMAP0_MAPINFO_SLOT_MASK (0x07F0) ++#define MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT (4) ++#define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F) ++ ++ ++/**************************************************************************** ++* Ethernet Config Pages ++****************************************************************************/ ++ ++/*Ethernet Page 0 */ ++ ++/*IP address (union of IPv4 and IPv6) */ ++typedef union _MPI2_ETHERNET_IP_ADDR { ++ U32 IPv4Addr; ++ U32 IPv6Addr[4]; ++} MPI2_ETHERNET_IP_ADDR, *PTR_MPI2_ETHERNET_IP_ADDR, ++ Mpi2EthernetIpAddr_t, *pMpi2EthernetIpAddr_t; ++ ++#define MPI2_ETHERNET_HOST_NAME_LENGTH (32) ++ ++typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 NumInterfaces; /*0x08 */ ++ U8 Reserved0; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Status; /*0x0C */ ++ U8 MediaState; /*0x10 */ ++ U8 Reserved2; /*0x11 */ ++ U16 Reserved3; /*0x12 */ ++ U8 MacAddress[6]; /*0x14 */ ++ U8 Reserved4; /*0x1A */ ++ U8 Reserved5; /*0x1B */ ++ MPI2_ETHERNET_IP_ADDR IpAddress; /*0x1C */ ++ MPI2_ETHERNET_IP_ADDR SubnetMask; /*0x2C */ ++ MPI2_ETHERNET_IP_ADDR GatewayIpAddress;/*0x3C */ ++ MPI2_ETHERNET_IP_ADDR DNS1IpAddress; /*0x4C */ ++ MPI2_ETHERNET_IP_ADDR DNS2IpAddress; /*0x5C */ ++ MPI2_ETHERNET_IP_ADDR DhcpIpAddress; /*0x6C */ ++ U8 ++ HostName[MPI2_ETHERNET_HOST_NAME_LENGTH];/*0x7C */ ++} MPI2_CONFIG_PAGE_ETHERNET_0, ++ *PTR_MPI2_CONFIG_PAGE_ETHERNET_0, ++ Mpi2EthernetPage0_t, *pMpi2EthernetPage0_t; ++ ++#define MPI2_ETHERNETPAGE0_PAGEVERSION (0x00) ++ ++/*values for Ethernet Page 0 Status field */ ++#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE (0x80000000) ++#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE (0x40000000) ++#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED (0x20000000) ++#define MPI2_ETHPG0_STATUS_DEFAULT_IF (0x00000100) ++#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED (0x00000080) ++#define MPI2_ETHPG0_STATUS_TELNET_ENABLED (0x00000040) ++#define MPI2_ETHPG0_STATUS_SSH2_ENABLED (0x00000020) ++#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED (0x00000010) ++#define MPI2_ETHPG0_STATUS_IPV6_ENABLED (0x00000008) ++#define MPI2_ETHPG0_STATUS_IPV4_ENABLED (0x00000004) ++#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES (0x00000002) ++#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED (0x00000001) ++ ++/*values for Ethernet Page 0 MediaState field */ ++#define MPI2_ETHPG0_MS_DUPLEX_MASK (0x80) ++#define MPI2_ETHPG0_MS_HALF_DUPLEX (0x00) ++#define MPI2_ETHPG0_MS_FULL_DUPLEX (0x80) ++ ++#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK (0x07) ++#define MPI2_ETHPG0_MS_NOT_CONNECTED (0x00) ++#define MPI2_ETHPG0_MS_10MBIT (0x01) ++#define MPI2_ETHPG0_MS_100MBIT (0x02) ++#define MPI2_ETHPG0_MS_1GBIT (0x03) ++ ++ ++/*Ethernet Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved0; /*0x08 */ ++ U32 ++ Flags; /*0x0C */ ++ U8 ++ MediaState; /*0x10 */ ++ U8 ++ Reserved1; /*0x11 */ ++ U16 ++ Reserved2; /*0x12 */ ++ U8 ++ MacAddress[6]; /*0x14 */ ++ U8 ++ Reserved3; /*0x1A */ ++ U8 ++ Reserved4; /*0x1B */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticIpAddress; /*0x1C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticSubnetMask; /*0x2C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticGatewayIpAddress; /*0x3C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticDNS1IpAddress; /*0x4C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticDNS2IpAddress; /*0x5C */ ++ U32 ++ Reserved5; /*0x6C */ ++ U32 ++ Reserved6; /*0x70 */ ++ U32 ++ Reserved7; /*0x74 */ ++ U32 ++ Reserved8; /*0x78 */ ++ U8 ++ HostName[MPI2_ETHERNET_HOST_NAME_LENGTH];/*0x7C */ ++} MPI2_CONFIG_PAGE_ETHERNET_1, ++ *PTR_MPI2_CONFIG_PAGE_ETHERNET_1, ++ Mpi2EthernetPage1_t, *pMpi2EthernetPage1_t; ++ ++#define MPI2_ETHERNETPAGE1_PAGEVERSION (0x00) ++ ++/*values for Ethernet Page 1 Flags field */ ++#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF (0x00000100) ++#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD (0x00000080) ++#define MPI2_ETHPG1_FLAG_ENABLE_TELNET (0x00000040) ++#define MPI2_ETHPG1_FLAG_ENABLE_SSH2 (0x00000020) ++#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT (0x00000010) ++#define MPI2_ETHPG1_FLAG_ENABLE_IPV6 (0x00000008) ++#define MPI2_ETHPG1_FLAG_ENABLE_IPV4 (0x00000004) ++#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES (0x00000002) ++#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF (0x00000001) ++ ++/*values for Ethernet Page 1 MediaState field */ ++#define MPI2_ETHPG1_MS_DUPLEX_MASK (0x80) ++#define MPI2_ETHPG1_MS_HALF_DUPLEX (0x00) ++#define MPI2_ETHPG1_MS_FULL_DUPLEX (0x80) ++ ++#define MPI2_ETHPG1_MS_DATA_RATE_MASK (0x07) ++#define MPI2_ETHPG1_MS_DATA_RATE_AUTO (0x00) ++#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT (0x01) ++#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT (0x02) ++#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT (0x03) ++ ++ ++/**************************************************************************** ++* Extended Manufacturing Config Pages ++****************************************************************************/ ++ ++/* ++ *Generic structure to use for product-specific extended manufacturing pages ++ *(currently Extended Manufacturing Page 40 through Extended Manufacturing ++ *Page 60). ++ */ ++ ++typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ ProductSpecificInfo; /*0x08 */ ++} MPI2_CONFIG_PAGE_EXT_MAN_PS, ++ *PTR_MPI2_CONFIG_PAGE_EXT_MAN_PS, ++ Mpi2ExtManufacturingPagePS_t, ++ *pMpi2ExtManufacturingPagePS_t; ++ ++/*PageVersion should be provided by product-specific code */ ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h +new file mode 100644 +index 0000000..bba56b6 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h +@@ -0,0 +1,581 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_init.h ++ * Title: MPI SCSI initiator mode messages and structures ++ * Creation Date: June 23, 2006 ++ * ++ * mpi2_init.h Version: 02.00.20 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t. ++ * 12-18-07 02.00.02 Modified Task Management Target Reset Method defines. ++ * 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention. ++ * 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY. ++ * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. ++ * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO ++ * Control field Task Attribute flags. ++ * Moved LUN field defines to mpi2.h becasue they are ++ * common to many structures. ++ * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to ++ * Query Asynchronous Event. ++ * Defined two new bits in the SlotStatus field of the SCSI ++ * Enclosure Processor Request and Reply. ++ * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for ++ * both SCSI IO Error Reply and SCSI Task Management Reply. ++ * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. ++ * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define. ++ * 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it. ++ * 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request. ++ * 11-10-10 02.00.11 Added MPI2_SCSIIO_NUM_SGLOFFSETS define. ++ * 11-18-11 02.00.12 Incorporating additions for MPI v2.5. ++ * 02-06-12 02.00.13 Added alternate defines for Task Priority / Command ++ * Priority to match SAM-4. ++ * Added EEDPErrorOffset to MPI2_SCSI_IO_REPLY. ++ * 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION. ++ * 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY, ++ * replacing the Reserved4 field. ++ * 11-18-14 02.00.16 Updated copyright information. ++ * 03-16-15 02.00.17 Updated for MPI v2.6. ++ * Added MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH. ++ * Added MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF and ++ * MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF. ++ * 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset. ++ * 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message. ++ * 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_INIT_H ++#define MPI2_INIT_H ++ ++/***************************************************************************** ++* ++* SCSI Initiator Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* SCSI IO messages and associated structures ++****************************************************************************/ ++ ++typedef struct _MPI2_SCSI_IO_CDB_EEDP32 { ++ U8 CDB[20]; /*0x00 */ ++ U32 PrimaryReferenceTag; /*0x14 */ ++ U16 PrimaryApplicationTag; /*0x18 */ ++ U16 PrimaryApplicationTagMask; /*0x1A */ ++ U32 TransferLength; /*0x1C */ ++} MPI2_SCSI_IO_CDB_EEDP32, *PTR_MPI2_SCSI_IO_CDB_EEDP32, ++ Mpi2ScsiIoCdbEedp32_t, *pMpi2ScsiIoCdbEedp32_t; ++ ++/*MPI v2.0 CDB field */ ++typedef union _MPI2_SCSI_IO_CDB_UNION { ++ U8 CDB32[32]; ++ MPI2_SCSI_IO_CDB_EEDP32 EEDP32; ++ MPI2_SGE_SIMPLE_UNION SGE; ++} MPI2_SCSI_IO_CDB_UNION, *PTR_MPI2_SCSI_IO_CDB_UNION, ++ Mpi2ScsiIoCdb_t, *pMpi2ScsiIoCdb_t; ++ ++/*MPI v2.0 SCSI IO Request Message */ ++typedef struct _MPI2_SCSI_IO_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U32 SenseBufferLowAddress; /*0x0C */ ++ U16 SGLFlags; /*0x10 */ ++ U8 SenseBufferLength; /*0x12 */ ++ U8 Reserved4; /*0x13 */ ++ U8 SGLOffset0; /*0x14 */ ++ U8 SGLOffset1; /*0x15 */ ++ U8 SGLOffset2; /*0x16 */ ++ U8 SGLOffset3; /*0x17 */ ++ U32 SkipCount; /*0x18 */ ++ U32 DataLength; /*0x1C */ ++ U32 BidirectionalDataLength; /*0x20 */ ++ U16 IoFlags; /*0x24 */ ++ U16 EEDPFlags; /*0x26 */ ++ U32 EEDPBlockSize; /*0x28 */ ++ U32 SecondaryReferenceTag; /*0x2C */ ++ U16 SecondaryApplicationTag; /*0x30 */ ++ U16 ApplicationTagTranslationMask; /*0x32 */ ++ U8 LUN[8]; /*0x34 */ ++ U32 Control; /*0x3C */ ++ MPI2_SCSI_IO_CDB_UNION CDB; /*0x40 */ ++ ++#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /*typically this is left undefined */ ++ MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion; ++#endif ++ ++ MPI2_SGE_IO_UNION SGL; /*0x60 */ ++ ++} MPI2_SCSI_IO_REQUEST, *PTR_MPI2_SCSI_IO_REQUEST, ++ Mpi2SCSIIORequest_t, *pMpi2SCSIIORequest_t; ++ ++/*SCSI IO MsgFlags bits */ ++ ++/*MsgFlags for SenseBufferAddressSpace */ ++#define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR (0x0C) ++#define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR (0x00) ++#define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR (0x04) ++#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08) ++#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C) ++#define MPI26_SCSIIO_MSGFLAGS_IOCCTL_SENSE_ADDR (0x08) ++ ++/*SCSI IO SGLFlags bits */ ++ ++/*base values for Data Location Address Space */ ++#define MPI2_SCSIIO_SGLFLAGS_ADDR_MASK (0x0C) ++#define MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR (0x00) ++#define MPI2_SCSIIO_SGLFLAGS_IOCDDR_ADDR (0x04) ++#define MPI2_SCSIIO_SGLFLAGS_IOCPLB_ADDR (0x08) ++#define MPI2_SCSIIO_SGLFLAGS_IOCPLBNTA_ADDR (0x0C) ++ ++/*base values for Type */ ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_MASK (0x03) ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_MPI (0x00) ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE32 (0x01) ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE64 (0x02) ++ ++/*shift values for each sub-field */ ++#define MPI2_SCSIIO_SGLFLAGS_SGL3_SHIFT (12) ++#define MPI2_SCSIIO_SGLFLAGS_SGL2_SHIFT (8) ++#define MPI2_SCSIIO_SGLFLAGS_SGL1_SHIFT (4) ++#define MPI2_SCSIIO_SGLFLAGS_SGL0_SHIFT (0) ++ ++/*number of SGLOffset fields */ ++#define MPI2_SCSIIO_NUM_SGLOFFSETS (4) ++ ++/*SCSI IO IoFlags bits */ ++ ++/*Large CDB Address Space */ ++#define MPI2_SCSIIO_CDB_ADDR_MASK (0x6000) ++#define MPI2_SCSIIO_CDB_ADDR_SYSTEM (0x0000) ++#define MPI2_SCSIIO_CDB_ADDR_IOCDDR (0x2000) ++#define MPI2_SCSIIO_CDB_ADDR_IOCPLB (0x4000) ++#define MPI2_SCSIIO_CDB_ADDR_IOCPLBNTA (0x6000) ++ ++#define MPI2_SCSIIO_IOFLAGS_LARGE_CDB (0x1000) ++#define MPI2_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800) ++#define MPI2_SCSIIO_IOFLAGS_MULTICAST (0x0400) ++#define MPI2_SCSIIO_IOFLAGS_CMD_DETERMINES_DATA_DIR (0x0200) ++#define MPI2_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF) ++ ++/*SCSI IO EEDPFlags bits */ ++ ++#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000) ++#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_REFTAG (0x4000) ++#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_APPTAG (0x2000) ++#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_APPTAG (0x1000) ++ ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100) ++ ++#define MPI2_SCSIIO_EEDPFLAGS_PASSTHRU_REFTAG (0x0008) ++ ++#define MPI2_SCSIIO_EEDPFLAGS_MASK_OP (0x0007) ++#define MPI2_SCSIIO_EEDPFLAGS_NOOP_OP (0x0000) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_OP (0x0001) ++#define MPI2_SCSIIO_EEDPFLAGS_STRIP_OP (0x0002) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003) ++#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004) ++#define MPI2_SCSIIO_EEDPFLAGS_REPLACE_OP (0x0006) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REGEN_OP (0x0007) ++ ++/*SCSI IO LUN fields: use MPI2_LUN_ from mpi2.h */ ++ ++/*SCSI IO Control bits */ ++#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_MASK (0xFC000000) ++#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT (26) ++ ++#define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK (0x03000000) ++#define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24) ++#define MPI2_SCSIIO_CONTROL_NODATATRANSFER (0x00000000) ++#define MPI2_SCSIIO_CONTROL_WRITE (0x01000000) ++#define MPI2_SCSIIO_CONTROL_READ (0x02000000) ++#define MPI2_SCSIIO_CONTROL_BIDIRECTIONAL (0x03000000) ++ ++#define MPI2_SCSIIO_CONTROL_TASKPRI_MASK (0x00007800) ++#define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT (11) ++/*alternate name for the previous field; called Command Priority in SAM-4 */ ++#define MPI2_SCSIIO_CONTROL_CMDPRI_MASK (0x00007800) ++#define MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT (11) ++ ++#define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK (0x00000700) ++#define MPI2_SCSIIO_CONTROL_SIMPLEQ (0x00000000) ++#define MPI2_SCSIIO_CONTROL_HEADOFQ (0x00000100) ++#define MPI2_SCSIIO_CONTROL_ORDEREDQ (0x00000200) ++#define MPI2_SCSIIO_CONTROL_ACAQ (0x00000400) ++ ++#define MPI2_SCSIIO_CONTROL_TLR_MASK (0x000000C0) ++#define MPI2_SCSIIO_CONTROL_NO_TLR (0x00000000) ++#define MPI2_SCSIIO_CONTROL_TLR_ON (0x00000040) ++#define MPI2_SCSIIO_CONTROL_TLR_OFF (0x00000080) ++ ++/*MPI v2.5 CDB field */ ++typedef union _MPI25_SCSI_IO_CDB_UNION { ++ U8 CDB32[32]; ++ MPI2_SCSI_IO_CDB_EEDP32 EEDP32; ++ MPI2_IEEE_SGE_SIMPLE64 SGE; ++} MPI25_SCSI_IO_CDB_UNION, *PTR_MPI25_SCSI_IO_CDB_UNION, ++ Mpi25ScsiIoCdb_t, *pMpi25ScsiIoCdb_t; ++ ++/*MPI v2.5/2.6 SCSI IO Request Message */ ++typedef struct _MPI25_SCSI_IO_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U32 SenseBufferLowAddress; /*0x0C */ ++ U8 DMAFlags; /*0x10 */ ++ U8 Reserved5; /*0x11 */ ++ U8 SenseBufferLength; /*0x12 */ ++ U8 Reserved4; /*0x13 */ ++ U8 SGLOffset0; /*0x14 */ ++ U8 SGLOffset1; /*0x15 */ ++ U8 SGLOffset2; /*0x16 */ ++ U8 SGLOffset3; /*0x17 */ ++ U32 SkipCount; /*0x18 */ ++ U32 DataLength; /*0x1C */ ++ U32 BidirectionalDataLength; /*0x20 */ ++ U16 IoFlags; /*0x24 */ ++ U16 EEDPFlags; /*0x26 */ ++ U16 EEDPBlockSize; /*0x28 */ ++ U16 Reserved6; /*0x2A */ ++ U32 SecondaryReferenceTag; /*0x2C */ ++ U16 SecondaryApplicationTag; /*0x30 */ ++ U16 ApplicationTagTranslationMask; /*0x32 */ ++ U8 LUN[8]; /*0x34 */ ++ U32 Control; /*0x3C */ ++ MPI25_SCSI_IO_CDB_UNION CDB; /*0x40 */ ++ ++#ifdef MPI25_SCSI_IO_VENDOR_UNIQUE_REGION /*typically this is left undefined */ ++ MPI25_SCSI_IO_VENDOR_UNIQUE VendorRegion; ++#endif ++ ++ MPI25_SGE_IO_UNION SGL; /*0x60 */ ++ ++} MPI25_SCSI_IO_REQUEST, *PTR_MPI25_SCSI_IO_REQUEST, ++ Mpi25SCSIIORequest_t, *pMpi25SCSIIORequest_t; ++ ++/*use MPI2_SCSIIO_MSGFLAGS_ defines for the MsgFlags field */ ++ ++/*Defines for the DMAFlags field ++ * Each setting affects 4 SGLS, from SGL0 to SGL3. ++ * D = Data ++ * C = Cache DIF ++ * I = Interleaved ++ * H = Host DIF ++ */ ++#define MPI25_SCSIIO_DMAFLAGS_OP_MASK (0x0F) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_D_D (0x00) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_D_C (0x01) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_D_I (0x02) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_C_C (0x03) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_C_I (0x04) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_I_I (0x05) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_C_C_C (0x06) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_C_C_I (0x07) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_C_I_I (0x08) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_I_I_I (0x09) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_D_D (0x0A) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_D_C (0x0B) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_D_I (0x0C) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_C_C (0x0D) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_C_I (0x0E) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_I_I (0x0F) ++ ++/*number of SGLOffset fields */ ++#define MPI25_SCSIIO_NUM_SGLOFFSETS (4) ++ ++/*defines for the IoFlags field */ ++#define MPI25_SCSIIO_IOFLAGS_IO_PATH_MASK (0xC000) ++#define MPI25_SCSIIO_IOFLAGS_NORMAL_PATH (0x0000) ++#define MPI25_SCSIIO_IOFLAGS_FAST_PATH (0x4000) ++ ++#define MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH (0x2000) ++#define MPI25_SCSIIO_IOFLAGS_LARGE_CDB (0x1000) ++#define MPI25_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800) ++#define MPI26_SCSIIO_IOFLAGS_PORT_REQUEST (0x0400) ++#define MPI25_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF) ++ ++/*MPI v2.5 defines for the EEDPFlags bits */ ++/*use MPI2_SCSIIO_EEDPFLAGS_ defines for the other EEDPFlags bits */ ++#define MPI25_SCSIIO_EEDPFLAGS_ESCAPE_MODE_MASK (0x00C0) ++#define MPI25_SCSIIO_EEDPFLAGS_COMPATIBLE_MODE (0x0000) ++#define MPI25_SCSIIO_EEDPFLAGS_DO_NOT_DISABLE_MODE (0x0040) ++#define MPI25_SCSIIO_EEDPFLAGS_APPTAG_DISABLE_MODE (0x0080) ++#define MPI25_SCSIIO_EEDPFLAGS_APPTAG_REFTAG_DISABLE_MODE (0x00C0) ++ ++#define MPI25_SCSIIO_EEDPFLAGS_HOST_GUARD_METHOD_MASK (0x0030) ++#define MPI25_SCSIIO_EEDPFLAGS_T10_CRC_HOST_GUARD (0x0000) ++#define MPI25_SCSIIO_EEDPFLAGS_IP_CHKSUM_HOST_GUARD (0x0010) ++ ++/*use MPI2_LUN_ defines from mpi2.h for the LUN field */ ++ ++/*use MPI2_SCSIIO_CONTROL_ defines for the Control field */ ++ ++/*NOTE: The SCSI IO Reply is nearly the same for MPI 2.0 and MPI 2.5, so ++ * MPI2_SCSI_IO_REPLY is used for both. ++ */ ++ ++/*SCSI IO Error Reply Message */ ++typedef struct _MPI2_SCSI_IO_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U8 SCSIStatus; /*0x0C */ ++ U8 SCSIState; /*0x0D */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 TransferCount; /*0x14 */ ++ U32 SenseCount; /*0x18 */ ++ U32 ResponseInfo; /*0x1C */ ++ U16 TaskTag; /*0x20 */ ++ U16 SCSIStatusQualifier; /* 0x22 */ ++ U32 BidirectionalTransferCount; /*0x24 */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U32 EEDPErrorOffset; /* 0x28 */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U16 EEDPObservedAppTag; /* 0x2C */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U16 EEDPObservedGuard; /* 0x2E */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U32 EEDPObservedRefTag; /* 0x30 */ ++} MPI2_SCSI_IO_REPLY, *PTR_MPI2_SCSI_IO_REPLY, ++ Mpi2SCSIIOReply_t, *pMpi2SCSIIOReply_t; ++ ++/*SCSI IO Reply SCSIStatus values (SAM-4 status codes) */ ++ ++#define MPI2_SCSI_STATUS_GOOD (0x00) ++#define MPI2_SCSI_STATUS_CHECK_CONDITION (0x02) ++#define MPI2_SCSI_STATUS_CONDITION_MET (0x04) ++#define MPI2_SCSI_STATUS_BUSY (0x08) ++#define MPI2_SCSI_STATUS_INTERMEDIATE (0x10) ++#define MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET (0x14) ++#define MPI2_SCSI_STATUS_RESERVATION_CONFLICT (0x18) ++#define MPI2_SCSI_STATUS_COMMAND_TERMINATED (0x22) /*obsolete */ ++#define MPI2_SCSI_STATUS_TASK_SET_FULL (0x28) ++#define MPI2_SCSI_STATUS_ACA_ACTIVE (0x30) ++#define MPI2_SCSI_STATUS_TASK_ABORTED (0x40) ++ ++/*SCSI IO Reply SCSIState flags */ ++ ++#define MPI2_SCSI_STATE_RESPONSE_INFO_VALID (0x10) ++#define MPI2_SCSI_STATE_TERMINATED (0x08) ++#define MPI2_SCSI_STATE_NO_SCSI_STATUS (0x04) ++#define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02) ++#define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01) ++ ++/*masks and shifts for the ResponseInfo field */ ++ ++#define MPI2_SCSI_RI_MASK_REASONCODE (0x000000FF) ++#define MPI2_SCSI_RI_SHIFT_REASONCODE (0) ++ ++#define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF) ++ ++/**************************************************************************** ++* SCSI Task Management messages ++****************************************************************************/ ++ ++/*SCSI Task Management Request Message */ ++typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Reserved1; /*0x04 */ ++ U8 TaskType; /*0x05 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U8 LUN[8]; /*0x0C */ ++ U32 Reserved4[7]; /*0x14 */ ++ U16 TaskMID; /*0x30 */ ++ U16 Reserved5; /*0x32 */ ++} MPI2_SCSI_TASK_MANAGE_REQUEST, ++ *PTR_MPI2_SCSI_TASK_MANAGE_REQUEST, ++ Mpi2SCSITaskManagementRequest_t, ++ *pMpi2SCSITaskManagementRequest_t; ++ ++/*TaskType values */ ++ ++#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01) ++#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02) ++#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) ++#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) ++#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) ++#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) ++#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08) ++#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09) ++#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A) ++ ++/*obsolete TaskType name */ ++#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION \ ++ (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT) ++ ++/*MsgFlags bits */ ++ ++#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18) ++#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00) ++#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08) ++#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10) ++ ++#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01) ++ ++/*SCSI Task Management Reply Message */ ++typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 ResponseCode; /*0x04 */ ++ U8 TaskType; /*0x05 */ ++ U8 Reserved1; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 TerminationCount; /*0x14 */ ++ U32 ResponseInfo; /*0x18 */ ++} MPI2_SCSI_TASK_MANAGE_REPLY, ++ *PTR_MPI2_SCSI_TASK_MANAGE_REPLY, ++ Mpi2SCSITaskManagementReply_t, *pMpi2SCSIManagementReply_t; ++ ++/*ResponseCode values */ ++ ++#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE (0x00) ++#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME (0x02) ++#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04) ++#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05) ++#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08) ++#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09) ++#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A) ++#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80) ++ ++/*masks and shifts for the ResponseInfo field */ ++ ++#define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE (0x000000FF) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE (0) ++#define MPI2_SCSITASKMGMT_RI_MASK_ARI2 (0x0000FF00) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2 (8) ++#define MPI2_SCSITASKMGMT_RI_MASK_ARI1 (0x00FF0000) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1 (16) ++#define MPI2_SCSITASKMGMT_RI_MASK_ARI0 (0xFF000000) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0 (24) ++ ++/**************************************************************************** ++* SCSI Enclosure Processor messages ++****************************************************************************/ ++ ++/*SCSI Enclosure Processor Request Message */ ++typedef struct _MPI2_SEP_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Action; /*0x04 */ ++ U8 Flags; /*0x05 */ ++ U8 Reserved1; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U32 SlotStatus; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U32 Reserved4; /*0x14 */ ++ U32 Reserved5; /*0x18 */ ++ U16 Slot; /*0x1C */ ++ U16 EnclosureHandle; /*0x1E */ ++} MPI2_SEP_REQUEST, *PTR_MPI2_SEP_REQUEST, ++ Mpi2SepRequest_t, *pMpi2SepRequest_t; ++ ++/*Action defines */ ++#define MPI2_SEP_REQ_ACTION_WRITE_STATUS (0x00) ++#define MPI2_SEP_REQ_ACTION_READ_STATUS (0x01) ++ ++/*Flags defines */ ++#define MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS (0x00) ++#define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01) ++ ++/*SlotStatus defines */ ++#define MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF (0x00080000) ++#define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000) ++#define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) ++#define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200) ++#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) ++#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) ++#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040) ++#define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) ++#define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) ++#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004) ++#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002) ++#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001) ++ ++/*SCSI Enclosure Processor Reply Message */ ++typedef struct _MPI2_SEP_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Action; /*0x04 */ ++ U8 Flags; /*0x05 */ ++ U8 Reserved1; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 SlotStatus; /*0x14 */ ++ U32 Reserved4; /*0x18 */ ++ U16 Slot; /*0x1C */ ++ U16 EnclosureHandle; /*0x1E */ ++} MPI2_SEP_REPLY, *PTR_MPI2_SEP_REPLY, ++ Mpi2SepReply_t, *pMpi2SepReply_t; ++ ++/*SlotStatus defines */ ++#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF (0x00080000) ++#define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000) ++#define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) ++#define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200) ++#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) ++#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) ++#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040) ++#define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) ++#define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) ++#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004) ++#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002) ++#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001) ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +new file mode 100644 +index 0000000..8bae305 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +@@ -0,0 +1,1860 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_ioc.h ++ * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages ++ * Creation Date: October 11, 2006 ++ * ++ * mpi2_ioc.h Version: 02.00.27 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-04-07 02.00.01 In IOCFacts Reply structure, renamed MaxDevices to ++ * MaxTargets. ++ * Added TotalImageSize field to FWDownload Request. ++ * Added reserved words to FWUpload Request. ++ * 06-26-07 02.00.02 Added IR Configuration Change List Event. ++ * 08-31-07 02.00.03 Removed SystemReplyQueueDepth field from the IOCInit ++ * request and replaced it with ++ * ReplyDescriptorPostQueueDepth and ReplyFreeQueueDepth. ++ * Replaced the MinReplyQueueDepth field of the IOCFacts ++ * reply with MaxReplyDescriptorPostQueueDepth. ++ * Added MPI2_RDPQ_DEPTH_MIN define to specify the minimum ++ * depth for the Reply Descriptor Post Queue. ++ * Added SASAddress field to Initiator Device Table ++ * Overflow Event data. ++ * 10-31-07 02.00.04 Added ReasonCode MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING ++ * for SAS Initiator Device Status Change Event data. ++ * Modified Reason Code defines for SAS Topology Change ++ * List Event data, including adding a bit for PHY Vacant ++ * status, and adding a mask for the Reason Code. ++ * Added define for ++ * MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING. ++ * Added define for MPI2_EXT_IMAGE_TYPE_MEGARAID. ++ * 12-18-07 02.00.05 Added Boot Status defines for the IOCExceptions field of ++ * the IOCFacts Reply. ++ * Removed MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. ++ * Moved MPI2_VERSION_UNION to mpi2.h. ++ * Changed MPI2_EVENT_NOTIFICATION_REQUEST to use masks ++ * instead of enables, and added SASBroadcastPrimitiveMasks ++ * field. ++ * Added Log Entry Added Event and related structure. ++ * 02-29-08 02.00.06 Added define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID. ++ * Removed define MPI2_IOCFACTS_PROTOCOL_SMP_TARGET. ++ * Added MaxVolumes and MaxPersistentEntries fields to ++ * IOCFacts reply. ++ * Added ProtocalFlags and IOCCapabilities fields to ++ * MPI2_FW_IMAGE_HEADER. ++ * Removed MPI2_PORTENABLE_FLAGS_ENABLE_SINGLE_PORT. ++ * 03-03-08 02.00.07 Fixed MPI2_FW_IMAGE_HEADER by changing Reserved26 to ++ * a U16 (from a U32). ++ * Removed extra 's' from EventMasks name. ++ * 06-27-08 02.00.08 Fixed an offset in a comment. ++ * 10-02-08 02.00.09 Removed SystemReplyFrameSize from MPI2_IOC_INIT_REQUEST. ++ * Removed CurReplyFrameSize from MPI2_IOC_FACTS_REPLY and ++ * renamed MinReplyFrameSize to ReplyFrameSize. ++ * Added MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX. ++ * Added two new RAIDOperation values for Integrated RAID ++ * Operations Status Event data. ++ * Added four new IR Configuration Change List Event data ++ * ReasonCode values. ++ * Added two new ReasonCode defines for SAS Device Status ++ * Change Event data. ++ * Added three new DiscoveryStatus bits for the SAS ++ * Discovery event data. ++ * Added Multiplexing Status Change bit to the PhyStatus ++ * field of the SAS Topology Change List event data. ++ * Removed define for MPI2_INIT_IMAGE_BOOTFLAGS_XMEMCOPY. ++ * BootFlags are now product-specific. ++ * Added defines for the indivdual signature bytes ++ * for MPI2_INIT_IMAGE_FOOTER. ++ * 01-19-09 02.00.10 Added MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY define. ++ * Added MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR ++ * define. ++ * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE ++ * define. ++ * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define. ++ * 05-06-09 02.00.11 Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define. ++ * Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define. ++ * Added two new reason codes for SAS Device Status Change ++ * Event. ++ * Added new event: SAS PHY Counter. ++ * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure. ++ * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. ++ * Added new product id family for 2208. ++ * 10-28-09 02.00.13 Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST. ++ * Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY. ++ * Added MinDevHandle field to MPI2_IOC_FACTS_REPLY. ++ * Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY. ++ * Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define. ++ * Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define. ++ * Added Host Based Discovery Phy Event data. ++ * Added defines for ProductID Product field ++ * (MPI2_FW_HEADER_PID_). ++ * Modified values for SAS ProductID Family ++ * (MPI2_FW_HEADER_PID_FAMILY_). ++ * 02-10-10 02.00.14 Added SAS Quiesce Event structure and defines. ++ * Added PowerManagementControl Request structures and ++ * defines. ++ * 05-12-10 02.00.15 Marked Task Set Full Event as obsolete. ++ * Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define. ++ * 11-10-10 02.00.16 Added MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC. ++ * 02-23-11 02.00.17 Added SAS NOTIFY Primitive event, and added ++ * SASNotifyPrimitiveMasks field to ++ * MPI2_EVENT_NOTIFICATION_REQUEST. ++ * Added Temperature Threshold Event. ++ * Added Host Message Event. ++ * Added Send Host Message request and reply. ++ * 05-25-11 02.00.18 For Extended Image Header, added ++ * MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC and ++ * MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC defines. ++ * Deprecated MPI2_EXT_IMAGE_TYPE_MAX define. ++ * 08-24-11 02.00.19 Added PhysicalPort field to ++ * MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure. ++ * Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete. ++ * 11-18-11 02.00.20 Incorporating additions for MPI v2.5. ++ * 03-29-12 02.00.21 Added a product specific range to event values. ++ * 07-26-12 02.00.22 Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE. ++ * Added ElapsedSeconds field to ++ * MPI2_EVENT_DATA_IR_OPERATION_STATUS. ++ * 08-19-13 02.00.23 For IOCInit, added MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE ++ * and MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY. ++ * Added MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE. ++ * Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY. ++ * Added Encrypted Hash Extended Image. ++ * 12-05-13 02.00.24 Added MPI25_HASH_IMAGE_TYPE_BIOS. ++ * 11-18-14 02.00.25 Updated copyright information. ++ * 03-16-15 02.00.26 Updated for MPI v2.6. ++ * Added MPI2_EVENT_ACTIVE_CABLE_EXCEPTION and ++ * MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT. ++ * Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and ++ * MPI26_FW_HEADER_PID_FAMILY_3516_SAS. ++ * Added MPI26_CTRL_OP_SHUTDOWN. ++ * 08-25-15 02.00.27 Added IC ARCH Class based signature defines ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_IOC_H ++#define MPI2_IOC_H ++ ++/***************************************************************************** ++* ++* IOC Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* IOCInit message ++****************************************************************************/ ++ ++/*IOCInit Request message */ ++typedef struct _MPI2_IOC_INIT_REQUEST { ++ U8 WhoInit; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 MsgVersion; /*0x0C */ ++ U16 HeaderVersion; /*0x0E */ ++ U32 Reserved5; /*0x10 */ ++ U16 ConfigurationFlags; /* 0x14 */ ++ U8 HostPageSize; /*0x16 */ ++ U8 HostMSIxVectors; /*0x17 */ ++ U16 Reserved8; /*0x18 */ ++ U16 SystemRequestFrameSize; /*0x1A */ ++ U16 ReplyDescriptorPostQueueDepth; /*0x1C */ ++ U16 ReplyFreeQueueDepth; /*0x1E */ ++ U32 SenseBufferAddressHigh; /*0x20 */ ++ U32 SystemReplyAddressHigh; /*0x24 */ ++ U64 SystemRequestFrameBaseAddress; /*0x28 */ ++ U64 ReplyDescriptorPostQueueAddress; /*0x30 */ ++ U64 ReplyFreeQueueAddress; /*0x38 */ ++ U64 TimeStamp; /*0x40 */ ++} MPI2_IOC_INIT_REQUEST, *PTR_MPI2_IOC_INIT_REQUEST, ++ Mpi2IOCInitRequest_t, *pMpi2IOCInitRequest_t; ++ ++/*WhoInit values */ ++#define MPI2_WHOINIT_NOT_INITIALIZED (0x00) ++#define MPI2_WHOINIT_SYSTEM_BIOS (0x01) ++#define MPI2_WHOINIT_ROM_BIOS (0x02) ++#define MPI2_WHOINIT_PCI_PEER (0x03) ++#define MPI2_WHOINIT_HOST_DRIVER (0x04) ++#define MPI2_WHOINIT_MANUFACTURER (0x05) ++ ++/* MsgFlags */ ++#define MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE (0x01) ++ ++ ++/*MsgVersion */ ++#define MPI2_IOCINIT_MSGVERSION_MAJOR_MASK (0xFF00) ++#define MPI2_IOCINIT_MSGVERSION_MAJOR_SHIFT (8) ++#define MPI2_IOCINIT_MSGVERSION_MINOR_MASK (0x00FF) ++#define MPI2_IOCINIT_MSGVERSION_MINOR_SHIFT (0) ++ ++/*HeaderVersion */ ++#define MPI2_IOCINIT_HDRVERSION_UNIT_MASK (0xFF00) ++#define MPI2_IOCINIT_HDRVERSION_UNIT_SHIFT (8) ++#define MPI2_IOCINIT_HDRVERSION_DEV_MASK (0x00FF) ++#define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT (0) ++ ++/*minimum depth for a Reply Descriptor Post Queue */ ++#define MPI2_RDPQ_DEPTH_MIN (16) ++ ++/* Reply Descriptor Post Queue Array Entry */ ++typedef struct _MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY { ++ U64 RDPQBaseAddress; /* 0x00 */ ++ U32 Reserved1; /* 0x08 */ ++ U32 Reserved2; /* 0x0C */ ++} MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY, ++*PTR_MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY, ++Mpi2IOCInitRDPQArrayEntry, *pMpi2IOCInitRDPQArrayEntry; ++ ++ ++/*IOCInit Reply message */ ++typedef struct _MPI2_IOC_INIT_REPLY { ++ U8 WhoInit; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_IOC_INIT_REPLY, *PTR_MPI2_IOC_INIT_REPLY, ++ Mpi2IOCInitReply_t, *pMpi2IOCInitReply_t; ++ ++/**************************************************************************** ++* IOCFacts message ++****************************************************************************/ ++ ++/*IOCFacts Request message */ ++typedef struct _MPI2_IOC_FACTS_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++} MPI2_IOC_FACTS_REQUEST, *PTR_MPI2_IOC_FACTS_REQUEST, ++ Mpi2IOCFactsRequest_t, *pMpi2IOCFactsRequest_t; ++ ++/*IOCFacts Reply message */ ++typedef struct _MPI2_IOC_FACTS_REPLY { ++ U16 MsgVersion; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 HeaderVersion; /*0x04 */ ++ U8 IOCNumber; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U16 IOCExceptions; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 MaxChainDepth; /*0x14 */ ++ U8 WhoInit; /*0x15 */ ++ U8 NumberOfPorts; /*0x16 */ ++ U8 MaxMSIxVectors; /*0x17 */ ++ U16 RequestCredit; /*0x18 */ ++ U16 ProductID; /*0x1A */ ++ U32 IOCCapabilities; /*0x1C */ ++ MPI2_VERSION_UNION FWVersion; /*0x20 */ ++ U16 IOCRequestFrameSize; /*0x24 */ ++ U16 IOCMaxChainSegmentSize; /*0x26 */ ++ U16 MaxInitiators; /*0x28 */ ++ U16 MaxTargets; /*0x2A */ ++ U16 MaxSasExpanders; /*0x2C */ ++ U16 MaxEnclosures; /*0x2E */ ++ U16 ProtocolFlags; /*0x30 */ ++ U16 HighPriorityCredit; /*0x32 */ ++ U16 MaxReplyDescriptorPostQueueDepth; /*0x34 */ ++ U8 ReplyFrameSize; /*0x36 */ ++ U8 MaxVolumes; /*0x37 */ ++ U16 MaxDevHandle; /*0x38 */ ++ U16 MaxPersistentEntries; /*0x3A */ ++ U16 MinDevHandle; /*0x3C */ ++ U8 CurrentHostPageSize; /* 0x3E */ ++ U8 Reserved4; /* 0x3F */ ++} MPI2_IOC_FACTS_REPLY, *PTR_MPI2_IOC_FACTS_REPLY, ++ Mpi2IOCFactsReply_t, *pMpi2IOCFactsReply_t; ++ ++/*MsgVersion */ ++#define MPI2_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00) ++#define MPI2_IOCFACTS_MSGVERSION_MAJOR_SHIFT (8) ++#define MPI2_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF) ++#define MPI2_IOCFACTS_MSGVERSION_MINOR_SHIFT (0) ++ ++/*HeaderVersion */ ++#define MPI2_IOCFACTS_HDRVERSION_UNIT_MASK (0xFF00) ++#define MPI2_IOCFACTS_HDRVERSION_UNIT_SHIFT (8) ++#define MPI2_IOCFACTS_HDRVERSION_DEV_MASK (0x00FF) ++#define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0) ++ ++/*IOCExceptions */ ++#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE (0x0200) ++#define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100) ++ ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK (0x00E0) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_GOOD (0x0000) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_BACKUP (0x0020) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_RESTORED (0x0040) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_CORRUPT_BACKUP (0x0060) ++ ++#define MPI2_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED (0x0010) ++#define MPI2_IOCFACTS_EXCEPT_MANUFACT_CHECKSUM_FAIL (0x0008) ++#define MPI2_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004) ++#define MPI2_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002) ++#define MPI2_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001) ++ ++/*defines for WhoInit field are after the IOCInit Request */ ++ ++/*ProductID field uses MPI2_FW_HEADER_PID_ */ ++ ++/*IOCCapabilities */ ++#define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000) ++#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000) ++#define MPI25_IOCFACTS_CAPABILITY_FAST_PATH_CAPABLE (0x00020000) ++#define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY (0x00010000) ++#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) ++#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) ++#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) ++#define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID (0x00001000) ++#define MPI2_IOCFACTS_CAPABILITY_TLR (0x00000800) ++#define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) ++#define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080) ++#define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040) ++#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) ++#define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) ++#define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) ++#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004) ++ ++/*ProtocolFlags */ ++#define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR (0x0002) ++#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET (0x0001) ++ ++/**************************************************************************** ++* PortFacts message ++****************************************************************************/ ++ ++/*PortFacts Request message */ ++typedef struct _MPI2_PORT_FACTS_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 PortNumber; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++} MPI2_PORT_FACTS_REQUEST, *PTR_MPI2_PORT_FACTS_REQUEST, ++ Mpi2PortFactsRequest_t, *pMpi2PortFactsRequest_t; ++ ++/*PortFacts Reply message */ ++typedef struct _MPI2_PORT_FACTS_REPLY { ++ U16 Reserved1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 PortNumber; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 Reserved5; /*0x14 */ ++ U8 PortType; /*0x15 */ ++ U16 Reserved6; /*0x16 */ ++ U16 MaxPostedCmdBuffers; /*0x18 */ ++ U16 Reserved7; /*0x1A */ ++} MPI2_PORT_FACTS_REPLY, *PTR_MPI2_PORT_FACTS_REPLY, ++ Mpi2PortFactsReply_t, *pMpi2PortFactsReply_t; ++ ++/*PortType values */ ++#define MPI2_PORTFACTS_PORTTYPE_INACTIVE (0x00) ++#define MPI2_PORTFACTS_PORTTYPE_FC (0x10) ++#define MPI2_PORTFACTS_PORTTYPE_ISCSI (0x20) ++#define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL (0x30) ++#define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL (0x31) ++ ++/**************************************************************************** ++* PortEnable message ++****************************************************************************/ ++ ++/*PortEnable Request message */ ++typedef struct _MPI2_PORT_ENABLE_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Reserved2; /*0x04 */ ++ U8 PortFlags; /*0x05 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++} MPI2_PORT_ENABLE_REQUEST, *PTR_MPI2_PORT_ENABLE_REQUEST, ++ Mpi2PortEnableRequest_t, *pMpi2PortEnableRequest_t; ++ ++/*PortEnable Reply message */ ++typedef struct _MPI2_PORT_ENABLE_REPLY { ++ U16 Reserved1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Reserved2; /*0x04 */ ++ U8 PortFlags; /*0x05 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_PORT_ENABLE_REPLY, *PTR_MPI2_PORT_ENABLE_REPLY, ++ Mpi2PortEnableReply_t, *pMpi2PortEnableReply_t; ++ ++/**************************************************************************** ++* EventNotification message ++****************************************************************************/ ++ ++/*EventNotification Request message */ ++#define MPI2_EVENT_NOTIFY_EVENTMASK_WORDS (4) ++ ++typedef struct _MPI2_EVENT_NOTIFICATION_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ U32 EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; /*0x14 */ ++ U16 SASBroadcastPrimitiveMasks; /*0x24 */ ++ U16 SASNotifyPrimitiveMasks; /*0x26 */ ++ U32 Reserved8; /*0x28 */ ++} MPI2_EVENT_NOTIFICATION_REQUEST, ++ *PTR_MPI2_EVENT_NOTIFICATION_REQUEST, ++ Mpi2EventNotificationRequest_t, ++ *pMpi2EventNotificationRequest_t; ++ ++/*EventNotification Reply message */ ++typedef struct _MPI2_EVENT_NOTIFICATION_REPLY { ++ U16 EventDataLength; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 AckRequired; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U16 Event; /*0x14 */ ++ U16 Reserved4; /*0x16 */ ++ U32 EventContext; /*0x18 */ ++ U32 EventData[1]; /*0x1C */ ++} MPI2_EVENT_NOTIFICATION_REPLY, *PTR_MPI2_EVENT_NOTIFICATION_REPLY, ++ Mpi2EventNotificationReply_t, ++ *pMpi2EventNotificationReply_t; ++ ++/*AckRequired */ ++#define MPI2_EVENT_NOTIFICATION_ACK_NOT_REQUIRED (0x00) ++#define MPI2_EVENT_NOTIFICATION_ACK_REQUIRED (0x01) ++ ++/*Event */ ++#define MPI2_EVENT_LOG_DATA (0x0001) ++#define MPI2_EVENT_STATE_CHANGE (0x0002) ++#define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005) ++#define MPI2_EVENT_EVENT_CHANGE (0x000A) ++#define MPI2_EVENT_TASK_SET_FULL (0x000E) /*obsolete */ ++#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F) ++#define MPI2_EVENT_IR_OPERATION_STATUS (0x0014) ++#define MPI2_EVENT_SAS_DISCOVERY (0x0016) ++#define MPI2_EVENT_SAS_BROADCAST_PRIMITIVE (0x0017) ++#define MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x0018) ++#define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW (0x0019) ++#define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST (0x001C) ++#define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE (0x001D) ++#define MPI2_EVENT_IR_VOLUME (0x001E) ++#define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F) ++#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) ++#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) ++#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) ++#define MPI2_EVENT_GPIO_INTERRUPT (0x0023) ++#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY (0x0024) ++#define MPI2_EVENT_SAS_QUIESCE (0x0025) ++#define MPI2_EVENT_SAS_NOTIFY_PRIMITIVE (0x0026) ++#define MPI2_EVENT_TEMP_THRESHOLD (0x0027) ++#define MPI2_EVENT_HOST_MESSAGE (0x0028) ++#define MPI2_EVENT_POWER_PERFORMANCE_CHANGE (0x0029) ++#define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION (0x0034) ++#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC (0x006E) ++#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC (0x007F) ++ ++/*Log Entry Added Event data */ ++ ++/*the following structure matches MPI2_LOG_0_ENTRY in mpi2_cnfg.h */ ++#define MPI2_EVENT_DATA_LOG_DATA_LENGTH (0x1C) ++ ++typedef struct _MPI2_EVENT_DATA_LOG_ENTRY_ADDED { ++ U64 TimeStamp; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U16 LogSequence; /*0x0C */ ++ U16 LogEntryQualifier; /*0x0E */ ++ U8 VP_ID; /*0x10 */ ++ U8 VF_ID; /*0x11 */ ++ U16 Reserved2; /*0x12 */ ++ U8 LogData[MPI2_EVENT_DATA_LOG_DATA_LENGTH]; /*0x14 */ ++} MPI2_EVENT_DATA_LOG_ENTRY_ADDED, ++ *PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED, ++ Mpi2EventDataLogEntryAdded_t, ++ *pMpi2EventDataLogEntryAdded_t; ++ ++/*GPIO Interrupt Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT { ++ U8 GPIONum; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++} MPI2_EVENT_DATA_GPIO_INTERRUPT, ++ *PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT, ++ Mpi2EventDataGpioInterrupt_t, ++ *pMpi2EventDataGpioInterrupt_t; ++ ++/*Temperature Threshold Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_TEMPERATURE { ++ U16 Status; /*0x00 */ ++ U8 SensorNum; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U16 CurrentTemperature; /*0x04 */ ++ U16 Reserved2; /*0x06 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++} MPI2_EVENT_DATA_TEMPERATURE, ++ *PTR_MPI2_EVENT_DATA_TEMPERATURE, ++ Mpi2EventDataTemperature_t, *pMpi2EventDataTemperature_t; ++ ++/*Temperature Threshold Event data Status bits */ ++#define MPI2_EVENT_TEMPERATURE3_EXCEEDED (0x0008) ++#define MPI2_EVENT_TEMPERATURE2_EXCEEDED (0x0004) ++#define MPI2_EVENT_TEMPERATURE1_EXCEEDED (0x0002) ++#define MPI2_EVENT_TEMPERATURE0_EXCEEDED (0x0001) ++ ++/*Host Message Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE { ++ U8 SourceVF_ID; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Reserved3; /*0x04 */ ++ U32 HostData[1]; /*0x08 */ ++} MPI2_EVENT_DATA_HOST_MESSAGE, *PTR_MPI2_EVENT_DATA_HOST_MESSAGE, ++ Mpi2EventDataHostMessage_t, *pMpi2EventDataHostMessage_t; ++ ++/*Power Performance Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_POWER_PERF_CHANGE { ++ U8 CurrentPowerMode; /*0x00 */ ++ U8 PreviousPowerMode; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_EVENT_DATA_POWER_PERF_CHANGE, ++ *PTR_MPI2_EVENT_DATA_POWER_PERF_CHANGE, ++ Mpi2EventDataPowerPerfChange_t, ++ *pMpi2EventDataPowerPerfChange_t; ++ ++/*defines for CurrentPowerMode and PreviousPowerMode fields */ ++#define MPI2_EVENT_PM_INIT_MASK (0xC0) ++#define MPI2_EVENT_PM_INIT_UNAVAILABLE (0x00) ++#define MPI2_EVENT_PM_INIT_HOST (0x40) ++#define MPI2_EVENT_PM_INIT_IO_UNIT (0x80) ++#define MPI2_EVENT_PM_INIT_PCIE_DPA (0xC0) ++ ++#define MPI2_EVENT_PM_MODE_MASK (0x07) ++#define MPI2_EVENT_PM_MODE_UNAVAILABLE (0x00) ++#define MPI2_EVENT_PM_MODE_UNKNOWN (0x01) ++#define MPI2_EVENT_PM_MODE_FULL_POWER (0x04) ++#define MPI2_EVENT_PM_MODE_REDUCED_POWER (0x05) ++#define MPI2_EVENT_PM_MODE_STANDBY (0x06) ++ ++/* Active Cable Exception Event data */ ++ ++typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT { ++ U32 ActiveCablePowerRequirement; /* 0x00 */ ++ U8 ReasonCode; /* 0x04 */ ++ U8 ReceptacleID; /* 0x05 */ ++ U16 Reserved1; /* 0x06 */ ++} MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT, ++ *PTR_MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT, ++ Mpi26EventDataActiveCableExcept_t, ++ *pMpi26EventDataActiveCableExcept_t; ++ ++/* defines for ReasonCode field */ ++#define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00) ++ ++/*Hard Reset Received Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED { ++ U8 Reserved1; /*0x00 */ ++ U8 Port; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++} MPI2_EVENT_DATA_HARD_RESET_RECEIVED, ++ *PTR_MPI2_EVENT_DATA_HARD_RESET_RECEIVED, ++ Mpi2EventDataHardResetReceived_t, ++ *pMpi2EventDataHardResetReceived_t; ++ ++/*Task Set Full Event data */ ++/* this event is obsolete */ ++ ++typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL { ++ U16 DevHandle; /*0x00 */ ++ U16 CurrentDepth; /*0x02 */ ++} MPI2_EVENT_DATA_TASK_SET_FULL, *PTR_MPI2_EVENT_DATA_TASK_SET_FULL, ++ Mpi2EventDataTaskSetFull_t, *pMpi2EventDataTaskSetFull_t; ++ ++/*SAS Device Status Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE { ++ U16 TaskTag; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 PhysicalPort; /*0x03 */ ++ U8 ASC; /*0x04 */ ++ U8 ASCQ; /*0x05 */ ++ U16 DevHandle; /*0x06 */ ++ U32 Reserved2; /*0x08 */ ++ U64 SASAddress; /*0x0C */ ++ U8 LUN[8]; /*0x14 */ ++} MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, ++ *PTR_MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, ++ Mpi2EventDataSasDeviceStatusChange_t, ++ *pMpi2EventDataSasDeviceStatusChange_t; ++ ++/*SAS Device Status Change Event data ReasonCode values */ ++#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY (0x11) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY (0x12) ++ ++/*Integrated RAID Operation Status Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS { ++ U16 VolDevHandle; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U8 RAIDOperation; /*0x04 */ ++ U8 PercentComplete; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U32 ElapsedSeconds; /*0x08 */ ++} MPI2_EVENT_DATA_IR_OPERATION_STATUS, ++ *PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS, ++ Mpi2EventDataIrOperationStatus_t, ++ *pMpi2EventDataIrOperationStatus_t; ++ ++/*Integrated RAID Operation Status Event data RAIDOperation values */ ++#define MPI2_EVENT_IR_RAIDOP_RESYNC (0x00) ++#define MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION (0x01) ++#define MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK (0x02) ++#define MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT (0x03) ++#define MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT (0x04) ++ ++/*Integrated RAID Volume Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_IR_VOLUME { ++ U16 VolDevHandle; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U32 NewValue; /*0x04 */ ++ U32 PreviousValue; /*0x08 */ ++} MPI2_EVENT_DATA_IR_VOLUME, *PTR_MPI2_EVENT_DATA_IR_VOLUME, ++ Mpi2EventDataIrVolume_t, *pMpi2EventDataIrVolume_t; ++ ++/*Integrated RAID Volume Event data ReasonCode values */ ++#define MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED (0x01) ++#define MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED (0x02) ++#define MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED (0x03) ++ ++/*Integrated RAID Physical Disk Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_IR_PHYSICAL_DISK { ++ U16 Reserved1; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 PhysDiskNum; /*0x03 */ ++ U16 PhysDiskDevHandle; /*0x04 */ ++ U16 Reserved2; /*0x06 */ ++ U16 Slot; /*0x08 */ ++ U16 EnclosureHandle; /*0x0A */ ++ U32 NewValue; /*0x0C */ ++ U32 PreviousValue; /*0x10 */ ++} MPI2_EVENT_DATA_IR_PHYSICAL_DISK, ++ *PTR_MPI2_EVENT_DATA_IR_PHYSICAL_DISK, ++ Mpi2EventDataIrPhysicalDisk_t, ++ *pMpi2EventDataIrPhysicalDisk_t; ++ ++/*Integrated RAID Physical Disk Event data ReasonCode values */ ++#define MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED (0x01) ++#define MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED (0x02) ++#define MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED (0x03) ++ ++/*Integrated RAID Configuration Change List Event data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumElements at runtime. ++ */ ++#ifndef MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT ++#define MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT (1) ++#endif ++ ++typedef struct _MPI2_EVENT_IR_CONFIG_ELEMENT { ++ U16 ElementFlags; /*0x00 */ ++ U16 VolDevHandle; /*0x02 */ ++ U8 ReasonCode; /*0x04 */ ++ U8 PhysDiskNum; /*0x05 */ ++ U16 PhysDiskDevHandle; /*0x06 */ ++} MPI2_EVENT_IR_CONFIG_ELEMENT, *PTR_MPI2_EVENT_IR_CONFIG_ELEMENT, ++ Mpi2EventIrConfigElement_t, *pMpi2EventIrConfigElement_t; ++ ++/*IR Configuration Change List Event data ElementFlags values */ ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK (0x000F) ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT (0x0000) ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT (0x0001) ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT (0x0002) ++ ++/*IR Configuration Change List Event data ReasonCode values */ ++#define MPI2_EVENT_IR_CHANGE_RC_ADDED (0x01) ++#define MPI2_EVENT_IR_CHANGE_RC_REMOVED (0x02) ++#define MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE (0x03) ++#define MPI2_EVENT_IR_CHANGE_RC_HIDE (0x04) ++#define MPI2_EVENT_IR_CHANGE_RC_UNHIDE (0x05) ++#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED (0x06) ++#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED (0x07) ++#define MPI2_EVENT_IR_CHANGE_RC_PD_CREATED (0x08) ++#define MPI2_EVENT_IR_CHANGE_RC_PD_DELETED (0x09) ++ ++typedef struct _MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST { ++ U8 NumElements; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 Reserved2; /*0x02 */ ++ U8 ConfigNum; /*0x03 */ ++ U32 Flags; /*0x04 */ ++ MPI2_EVENT_IR_CONFIG_ELEMENT ++ ConfigElement[MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT];/*0x08 */ ++} MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST, ++ *PTR_MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST, ++ Mpi2EventDataIrConfigChangeList_t, ++ *pMpi2EventDataIrConfigChangeList_t; ++ ++/*IR Configuration Change List Event data Flags values */ ++#define MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG (0x00000001) ++ ++/*SAS Discovery Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_DISCOVERY { ++ U8 Flags; /*0x00 */ ++ U8 ReasonCode; /*0x01 */ ++ U8 PhysicalPort; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U32 DiscoveryStatus; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_DISCOVERY, ++ *PTR_MPI2_EVENT_DATA_SAS_DISCOVERY, ++ Mpi2EventDataSasDiscovery_t, *pMpi2EventDataSasDiscovery_t; ++ ++/*SAS Discovery Event data Flags values */ ++#define MPI2_EVENT_SAS_DISC_DEVICE_CHANGE (0x02) ++#define MPI2_EVENT_SAS_DISC_IN_PROGRESS (0x01) ++ ++/*SAS Discovery Event data ReasonCode values */ ++#define MPI2_EVENT_SAS_DISC_RC_STARTED (0x01) ++#define MPI2_EVENT_SAS_DISC_RC_COMPLETED (0x02) ++ ++/*SAS Discovery Event data DiscoveryStatus values */ ++#define MPI2_EVENT_SAS_DISC_DS_MAX_ENCLOSURES_EXCEED (0x80000000) ++#define MPI2_EVENT_SAS_DISC_DS_MAX_EXPANDERS_EXCEED (0x40000000) ++#define MPI2_EVENT_SAS_DISC_DS_MAX_DEVICES_EXCEED (0x20000000) ++#define MPI2_EVENT_SAS_DISC_DS_MAX_TOPO_PHYS_EXCEED (0x10000000) ++#define MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR (0x08000000) ++#define MPI2_EVENT_SAS_DISC_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000) ++#define MPI2_EVENT_SAS_DISC_DS_EXP_MULTI_SUBTRACTIVE (0x00004000) ++#define MPI2_EVENT_SAS_DISC_DS_MULTI_PORT_DOMAIN (0x00002000) ++#define MPI2_EVENT_SAS_DISC_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000) ++#define MPI2_EVENT_SAS_DISC_DS_UNSUPPORTED_DEVICE (0x00000800) ++#define MPI2_EVENT_SAS_DISC_DS_TABLE_LINK (0x00000400) ++#define MPI2_EVENT_SAS_DISC_DS_SUBTRACTIVE_LINK (0x00000200) ++#define MPI2_EVENT_SAS_DISC_DS_SMP_CRC_ERROR (0x00000100) ++#define MPI2_EVENT_SAS_DISC_DS_SMP_FUNCTION_FAILED (0x00000080) ++#define MPI2_EVENT_SAS_DISC_DS_INDEX_NOT_EXIST (0x00000040) ++#define MPI2_EVENT_SAS_DISC_DS_OUT_ROUTE_ENTRIES (0x00000020) ++#define MPI2_EVENT_SAS_DISC_DS_SMP_TIMEOUT (0x00000010) ++#define MPI2_EVENT_SAS_DISC_DS_MULTIPLE_PORTS (0x00000004) ++#define MPI2_EVENT_SAS_DISC_DS_UNADDRESSABLE_DEVICE (0x00000002) ++#define MPI2_EVENT_SAS_DISC_DS_LOOP_DETECTED (0x00000001) ++ ++/*SAS Broadcast Primitive Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE { ++ U8 PhyNum; /*0x00 */ ++ U8 Port; /*0x01 */ ++ U8 PortWidth; /*0x02 */ ++ U8 Primitive; /*0x03 */ ++} MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, ++ *PTR_MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, ++ Mpi2EventDataSasBroadcastPrimitive_t, ++ *pMpi2EventDataSasBroadcastPrimitive_t; ++ ++/*defines for the Primitive field */ ++#define MPI2_EVENT_PRIMITIVE_CHANGE (0x01) ++#define MPI2_EVENT_PRIMITIVE_SES (0x02) ++#define MPI2_EVENT_PRIMITIVE_EXPANDER (0x03) ++#define MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT (0x04) ++#define MPI2_EVENT_PRIMITIVE_RESERVED3 (0x05) ++#define MPI2_EVENT_PRIMITIVE_RESERVED4 (0x06) ++#define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07) ++#define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08) ++ ++/*SAS Notify Primitive Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE { ++ U8 PhyNum; /*0x00 */ ++ U8 Port; /*0x01 */ ++ U8 Reserved1; /*0x02 */ ++ U8 Primitive; /*0x03 */ ++} MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE, ++ *PTR_MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE, ++ Mpi2EventDataSasNotifyPrimitive_t, ++ *pMpi2EventDataSasNotifyPrimitive_t; ++ ++/*defines for the Primitive field */ ++#define MPI2_EVENT_NOTIFY_ENABLE_SPINUP (0x01) ++#define MPI2_EVENT_NOTIFY_POWER_LOSS_EXPECTED (0x02) ++#define MPI2_EVENT_NOTIFY_RESERVED1 (0x03) ++#define MPI2_EVENT_NOTIFY_RESERVED2 (0x04) ++ ++/*SAS Initiator Device Status Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE { ++ U8 ReasonCode; /*0x00 */ ++ U8 PhysicalPort; /*0x01 */ ++ U16 DevHandle; /*0x02 */ ++ U64 SASAddress; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, ++ *PTR_MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, ++ Mpi2EventDataSasInitDevStatusChange_t, ++ *pMpi2EventDataSasInitDevStatusChange_t; ++ ++/*SAS Initiator Device Status Change event ReasonCode values */ ++#define MPI2_EVENT_SAS_INIT_RC_ADDED (0x01) ++#define MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING (0x02) ++ ++/*SAS Initiator Device Table Overflow Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW { ++ U16 MaxInit; /*0x00 */ ++ U16 CurrentInit; /*0x02 */ ++ U64 SASAddress; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, ++ *PTR_MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, ++ Mpi2EventDataSasInitTableOverflow_t, ++ *pMpi2EventDataSasInitTableOverflow_t; ++ ++/*SAS Topology Change List Event data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumEntries at runtime. ++ */ ++#ifndef MPI2_EVENT_SAS_TOPO_PHY_COUNT ++#define MPI2_EVENT_SAS_TOPO_PHY_COUNT (1) ++#endif ++ ++typedef struct _MPI2_EVENT_SAS_TOPO_PHY_ENTRY { ++ U16 AttachedDevHandle; /*0x00 */ ++ U8 LinkRate; /*0x02 */ ++ U8 PhyStatus; /*0x03 */ ++} MPI2_EVENT_SAS_TOPO_PHY_ENTRY, *PTR_MPI2_EVENT_SAS_TOPO_PHY_ENTRY, ++ Mpi2EventSasTopoPhyEntry_t, *pMpi2EventSasTopoPhyEntry_t; ++ ++typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST { ++ U16 EnclosureHandle; /*0x00 */ ++ U16 ExpanderDevHandle; /*0x02 */ ++ U8 NumPhys; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U8 NumEntries; /*0x08 */ ++ U8 StartPhyNum; /*0x09 */ ++ U8 ExpStatus; /*0x0A */ ++ U8 PhysicalPort; /*0x0B */ ++ MPI2_EVENT_SAS_TOPO_PHY_ENTRY ++ PHY[MPI2_EVENT_SAS_TOPO_PHY_COUNT]; /*0x0C */ ++} MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST, ++ *PTR_MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST, ++ Mpi2EventDataSasTopologyChangeList_t, ++ *pMpi2EventDataSasTopologyChangeList_t; ++ ++/*values for the ExpStatus field */ ++#define MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER (0x00) ++#define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01) ++#define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02) ++#define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03) ++#define MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING (0x04) ++ ++/*defines for the LinkRate field */ ++#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK (0xF0) ++#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT (4) ++#define MPI2_EVENT_SAS_TOPO_LR_PREV_MASK (0x0F) ++#define MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT (0) ++ ++#define MPI2_EVENT_SAS_TOPO_LR_UNKNOWN_LINK_RATE (0x00) ++#define MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED (0x01) ++#define MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED (0x02) ++#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03) ++#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04) ++#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS (0x05) ++#define MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY (0x06) ++#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08) ++#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09) ++#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A) ++#define MPI25_EVENT_SAS_TOPO_LR_RATE_12_0 (0x0B) ++ ++/*values for the PhyStatus field */ ++#define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT (0x80) ++#define MPI2_EVENT_SAS_TOPO_PS_MULTIPLEX_CHANGE (0x10) ++/*values for the PhyStatus ReasonCode sub-field */ ++#define MPI2_EVENT_SAS_TOPO_RC_MASK (0x0F) ++#define MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED (0x01) ++#define MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING (0x02) ++#define MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED (0x03) ++#define MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE (0x04) ++#define MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING (0x05) ++ ++/*SAS Enclosure Device Status Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE { ++ U16 EnclosureHandle; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 PhysicalPort; /*0x03 */ ++ U64 EnclosureLogicalID; /*0x04 */ ++ U16 NumSlots; /*0x0C */ ++ U16 StartSlot; /*0x0E */ ++ U32 PhyBits; /*0x10 */ ++} MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE, ++ *PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE, ++ Mpi2EventDataSasEnclDevStatusChange_t, ++ *pMpi2EventDataSasEnclDevStatusChange_t; ++ ++/*SAS Enclosure Device Status Change event ReasonCode values */ ++#define MPI2_EVENT_SAS_ENCL_RC_ADDED (0x01) ++#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02) ++ ++/*SAS PHY Counter Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER { ++ U64 TimeStamp; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U8 PhyEventCode; /*0x0C */ ++ U8 PhyNum; /*0x0D */ ++ U16 Reserved2; /*0x0E */ ++ U32 PhyEventInfo; /*0x10 */ ++ U8 CounterType; /*0x14 */ ++ U8 ThresholdWindow; /*0x15 */ ++ U8 TimeUnits; /*0x16 */ ++ U8 Reserved3; /*0x17 */ ++ U32 EventThreshold; /*0x18 */ ++ U16 ThresholdFlags; /*0x1C */ ++ U16 Reserved4; /*0x1E */ ++} MPI2_EVENT_DATA_SAS_PHY_COUNTER, ++ *PTR_MPI2_EVENT_DATA_SAS_PHY_COUNTER, ++ Mpi2EventDataSasPhyCounter_t, ++ *pMpi2EventDataSasPhyCounter_t; ++ ++/*use MPI2_SASPHY3_EVENT_CODE_ values from mpi2_cnfg.h ++ *for the PhyEventCode field */ ++ ++/*use MPI2_SASPHY3_COUNTER_TYPE_ values from mpi2_cnfg.h ++ *for the CounterType field */ ++ ++/*use MPI2_SASPHY3_TIME_UNITS_ values from mpi2_cnfg.h ++ *for the TimeUnits field */ ++ ++/*use MPI2_SASPHY3_TFLAGS_ values from mpi2_cnfg.h ++ *for the ThresholdFlags field */ ++ ++/*SAS Quiesce Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_QUIESCE { ++ U8 ReasonCode; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Reserved3; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_QUIESCE, ++ *PTR_MPI2_EVENT_DATA_SAS_QUIESCE, ++ Mpi2EventDataSasQuiesce_t, *pMpi2EventDataSasQuiesce_t; ++ ++/*SAS Quiesce Event data ReasonCode values */ ++#define MPI2_EVENT_SAS_QUIESCE_RC_STARTED (0x01) ++#define MPI2_EVENT_SAS_QUIESCE_RC_COMPLETED (0x02) ++ ++/*Host Based Discovery Phy Event data */ ++ ++typedef struct _MPI2_EVENT_HBD_PHY_SAS { ++ U8 Flags; /*0x00 */ ++ U8 NegotiatedLinkRate; /*0x01 */ ++ U8 PhyNum; /*0x02 */ ++ U8 PhysicalPort; /*0x03 */ ++ U32 Reserved1; /*0x04 */ ++ U8 InitialFrame[28]; /*0x08 */ ++} MPI2_EVENT_HBD_PHY_SAS, *PTR_MPI2_EVENT_HBD_PHY_SAS, ++ Mpi2EventHbdPhySas_t, *pMpi2EventHbdPhySas_t; ++ ++/*values for the Flags field */ ++#define MPI2_EVENT_HBD_SAS_FLAGS_FRAME_VALID (0x02) ++#define MPI2_EVENT_HBD_SAS_FLAGS_SATA_FRAME (0x01) ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines from mpi2_cnfg.h ++ *for the NegotiatedLinkRate field */ ++ ++typedef union _MPI2_EVENT_HBD_DESCRIPTOR { ++ MPI2_EVENT_HBD_PHY_SAS Sas; ++} MPI2_EVENT_HBD_DESCRIPTOR, *PTR_MPI2_EVENT_HBD_DESCRIPTOR, ++ Mpi2EventHbdDescriptor_t, *pMpi2EventHbdDescriptor_t; ++ ++typedef struct _MPI2_EVENT_DATA_HBD_PHY { ++ U8 DescriptorType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Reserved3; /*0x04 */ ++ MPI2_EVENT_HBD_DESCRIPTOR Descriptor; /*0x08 */ ++} MPI2_EVENT_DATA_HBD_PHY, *PTR_MPI2_EVENT_DATA_HBD_PHY, ++ Mpi2EventDataHbdPhy_t, ++ *pMpi2EventDataMpi2EventDataHbdPhy_t; ++ ++/*values for the DescriptorType field */ ++#define MPI2_EVENT_HBD_DT_SAS (0x01) ++ ++/**************************************************************************** ++* EventAck message ++****************************************************************************/ ++ ++/*EventAck Request message */ ++typedef struct _MPI2_EVENT_ACK_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Event; /*0x0C */ ++ U16 Reserved5; /*0x0E */ ++ U32 EventContext; /*0x10 */ ++} MPI2_EVENT_ACK_REQUEST, *PTR_MPI2_EVENT_ACK_REQUEST, ++ Mpi2EventAckRequest_t, *pMpi2EventAckRequest_t; ++ ++/*EventAck Reply message */ ++typedef struct _MPI2_EVENT_ACK_REPLY { ++ U16 Reserved1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_EVENT_ACK_REPLY, *PTR_MPI2_EVENT_ACK_REPLY, ++ Mpi2EventAckReply_t, *pMpi2EventAckReply_t; ++ ++/**************************************************************************** ++* SendHostMessage message ++****************************************************************************/ ++ ++/*SendHostMessage Request message */ ++typedef struct _MPI2_SEND_HOST_MESSAGE_REQUEST { ++ U16 HostDataLength; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U8 Reserved4; /*0x0C */ ++ U8 DestVF_ID; /*0x0D */ ++ U16 Reserved5; /*0x0E */ ++ U32 Reserved6; /*0x10 */ ++ U32 Reserved7; /*0x14 */ ++ U32 Reserved8; /*0x18 */ ++ U32 Reserved9; /*0x1C */ ++ U32 Reserved10; /*0x20 */ ++ U32 HostData[1]; /*0x24 */ ++} MPI2_SEND_HOST_MESSAGE_REQUEST, ++ *PTR_MPI2_SEND_HOST_MESSAGE_REQUEST, ++ Mpi2SendHostMessageRequest_t, ++ *pMpi2SendHostMessageRequest_t; ++ ++/*SendHostMessage Reply message */ ++typedef struct _MPI2_SEND_HOST_MESSAGE_REPLY { ++ U16 HostDataLength; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_SEND_HOST_MESSAGE_REPLY, *PTR_MPI2_SEND_HOST_MESSAGE_REPLY, ++ Mpi2SendHostMessageReply_t, *pMpi2SendHostMessageReply_t; ++ ++/**************************************************************************** ++* FWDownload message ++****************************************************************************/ ++ ++/*MPI v2.0 FWDownload Request message */ ++typedef struct _MPI2_FW_DOWNLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 TotalImageSize; /*0x0C */ ++ U32 Reserved5; /*0x10 */ ++ MPI2_MPI_SGE_UNION SGL; /*0x14 */ ++} MPI2_FW_DOWNLOAD_REQUEST, *PTR_MPI2_FW_DOWNLOAD_REQUEST, ++ Mpi2FWDownloadRequest, *pMpi2FWDownloadRequest; ++ ++#define MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT (0x01) ++ ++#define MPI2_FW_DOWNLOAD_ITYPE_FW (0x01) ++#define MPI2_FW_DOWNLOAD_ITYPE_BIOS (0x02) ++#define MPI2_FW_DOWNLOAD_ITYPE_MANUFACTURING (0x06) ++#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07) ++#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08) ++#define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID (0x09) ++#define MPI2_FW_DOWNLOAD_ITYPE_COMPLETE (0x0A) ++#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B) ++#define MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY (0x0C) ++#define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0) ++ ++/*MPI v2.0 FWDownload TransactionContext Element */ ++typedef struct _MPI2_FW_DOWNLOAD_TCSGE { ++ U8 Reserved1; /*0x00 */ ++ U8 ContextSize; /*0x01 */ ++ U8 DetailsLength; /*0x02 */ ++ U8 Flags; /*0x03 */ ++ U32 Reserved2; /*0x04 */ ++ U32 ImageOffset; /*0x08 */ ++ U32 ImageSize; /*0x0C */ ++} MPI2_FW_DOWNLOAD_TCSGE, *PTR_MPI2_FW_DOWNLOAD_TCSGE, ++ Mpi2FWDownloadTCSGE_t, *pMpi2FWDownloadTCSGE_t; ++ ++/*MPI v2.5 FWDownload Request message */ ++typedef struct _MPI25_FW_DOWNLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 TotalImageSize; /*0x0C */ ++ U32 Reserved5; /*0x10 */ ++ U32 Reserved6; /*0x14 */ ++ U32 ImageOffset; /*0x18 */ ++ U32 ImageSize; /*0x1C */ ++ MPI25_SGE_IO_UNION SGL; /*0x20 */ ++} MPI25_FW_DOWNLOAD_REQUEST, *PTR_MPI25_FW_DOWNLOAD_REQUEST, ++ Mpi25FWDownloadRequest, *pMpi25FWDownloadRequest; ++ ++/*FWDownload Reply message */ ++typedef struct _MPI2_FW_DOWNLOAD_REPLY { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_FW_DOWNLOAD_REPLY, *PTR_MPI2_FW_DOWNLOAD_REPLY, ++ Mpi2FWDownloadReply_t, *pMpi2FWDownloadReply_t; ++ ++/**************************************************************************** ++* FWUpload message ++****************************************************************************/ ++ ++/*MPI v2.0 FWUpload Request message */ ++typedef struct _MPI2_FW_UPLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ MPI2_MPI_SGE_UNION SGL; /*0x14 */ ++} MPI2_FW_UPLOAD_REQUEST, *PTR_MPI2_FW_UPLOAD_REQUEST, ++ Mpi2FWUploadRequest_t, *pMpi2FWUploadRequest_t; ++ ++#define MPI2_FW_UPLOAD_ITYPE_FW_CURRENT (0x00) ++#define MPI2_FW_UPLOAD_ITYPE_FW_FLASH (0x01) ++#define MPI2_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02) ++#define MPI2_FW_UPLOAD_ITYPE_FW_BACKUP (0x05) ++#define MPI2_FW_UPLOAD_ITYPE_MANUFACTURING (0x06) ++#define MPI2_FW_UPLOAD_ITYPE_CONFIG_1 (0x07) ++#define MPI2_FW_UPLOAD_ITYPE_CONFIG_2 (0x08) ++#define MPI2_FW_UPLOAD_ITYPE_MEGARAID (0x09) ++#define MPI2_FW_UPLOAD_ITYPE_COMPLETE (0x0A) ++#define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B) ++#define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP (0x0D) ++ ++/*MPI v2.0 FWUpload TransactionContext Element */ ++typedef struct _MPI2_FW_UPLOAD_TCSGE { ++ U8 Reserved1; /*0x00 */ ++ U8 ContextSize; /*0x01 */ ++ U8 DetailsLength; /*0x02 */ ++ U8 Flags; /*0x03 */ ++ U32 Reserved2; /*0x04 */ ++ U32 ImageOffset; /*0x08 */ ++ U32 ImageSize; /*0x0C */ ++} MPI2_FW_UPLOAD_TCSGE, *PTR_MPI2_FW_UPLOAD_TCSGE, ++ Mpi2FWUploadTCSGE_t, *pMpi2FWUploadTCSGE_t; ++ ++/*MPI v2.5 FWUpload Request message */ ++typedef struct _MPI25_FW_UPLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ U32 Reserved7; /*0x14 */ ++ U32 ImageOffset; /*0x18 */ ++ U32 ImageSize; /*0x1C */ ++ MPI25_SGE_IO_UNION SGL; /*0x20 */ ++} MPI25_FW_UPLOAD_REQUEST, *PTR_MPI25_FW_UPLOAD_REQUEST, ++ Mpi25FWUploadRequest_t, *pMpi25FWUploadRequest_t; ++ ++/*FWUpload Reply message */ ++typedef struct _MPI2_FW_UPLOAD_REPLY { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 ActualImageSize; /*0x14 */ ++} MPI2_FW_UPLOAD_REPLY, *PTR_MPI2_FW_UPLOAD_REPLY, ++ Mpi2FWUploadReply_t, *pMPi2FWUploadReply_t; ++ ++/*FW Image Header */ ++typedef struct _MPI2_FW_IMAGE_HEADER { ++ U32 Signature; /*0x00 */ ++ U32 Signature0; /*0x04 */ ++ U32 Signature1; /*0x08 */ ++ U32 Signature2; /*0x0C */ ++ MPI2_VERSION_UNION MPIVersion; /*0x10 */ ++ MPI2_VERSION_UNION FWVersion; /*0x14 */ ++ MPI2_VERSION_UNION NVDATAVersion; /*0x18 */ ++ MPI2_VERSION_UNION PackageVersion; /*0x1C */ ++ U16 VendorID; /*0x20 */ ++ U16 ProductID; /*0x22 */ ++ U16 ProtocolFlags; /*0x24 */ ++ U16 Reserved26; /*0x26 */ ++ U32 IOCCapabilities; /*0x28 */ ++ U32 ImageSize; /*0x2C */ ++ U32 NextImageHeaderOffset; /*0x30 */ ++ U32 Checksum; /*0x34 */ ++ U32 Reserved38; /*0x38 */ ++ U32 Reserved3C; /*0x3C */ ++ U32 Reserved40; /*0x40 */ ++ U32 Reserved44; /*0x44 */ ++ U32 Reserved48; /*0x48 */ ++ U32 Reserved4C; /*0x4C */ ++ U32 Reserved50; /*0x50 */ ++ U32 Reserved54; /*0x54 */ ++ U32 Reserved58; /*0x58 */ ++ U32 Reserved5C; /*0x5C */ ++ U32 BootFlags; /*0x60 */ ++ U32 FirmwareVersionNameWhat; /*0x64 */ ++ U8 FirmwareVersionName[32]; /*0x68 */ ++ U32 VendorNameWhat; /*0x88 */ ++ U8 VendorName[32]; /*0x8C */ ++ U32 PackageNameWhat; /*0x88 */ ++ U8 PackageName[32]; /*0x8C */ ++ U32 ReservedD0; /*0xD0 */ ++ U32 ReservedD4; /*0xD4 */ ++ U32 ReservedD8; /*0xD8 */ ++ U32 ReservedDC; /*0xDC */ ++ U32 ReservedE0; /*0xE0 */ ++ U32 ReservedE4; /*0xE4 */ ++ U32 ReservedE8; /*0xE8 */ ++ U32 ReservedEC; /*0xEC */ ++ U32 ReservedF0; /*0xF0 */ ++ U32 ReservedF4; /*0xF4 */ ++ U32 ReservedF8; /*0xF8 */ ++ U32 ReservedFC; /*0xFC */ ++} MPI2_FW_IMAGE_HEADER, *PTR_MPI2_FW_IMAGE_HEADER, ++ Mpi2FWImageHeader_t, *pMpi2FWImageHeader_t; ++ ++/*Signature field */ ++#define MPI2_FW_HEADER_SIGNATURE_OFFSET (0x00) ++#define MPI2_FW_HEADER_SIGNATURE_MASK (0xFF000000) ++#define MPI2_FW_HEADER_SIGNATURE (0xEA000000) ++#define MPI26_FW_HEADER_SIGNATURE (0xEB000000) ++ ++/*Signature0 field */ ++#define MPI2_FW_HEADER_SIGNATURE0_OFFSET (0x04) ++#define MPI2_FW_HEADER_SIGNATURE0 (0x5AFAA55A) ++/* Last byte is defined by architecture */ ++#define MPI26_FW_HEADER_SIGNATURE0_BASE (0x5AEAA500) ++#define MPI26_FW_HEADER_SIGNATURE0_ARC_0 (0x5A) ++#define MPI26_FW_HEADER_SIGNATURE0_ARC_1 (0x00) ++#define MPI26_FW_HEADER_SIGNATURE0_ARC_2 (0x01) ++/* legacy (0x5AEAA55A) */ ++#define MPI26_FW_HEADER_SIGNATURE0 \ ++ (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0) ++#define MPI26_FW_HEADER_SIGNATURE0_3516 \ ++ (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1) ++ ++/*Signature1 field */ ++#define MPI2_FW_HEADER_SIGNATURE1_OFFSET (0x08) ++#define MPI2_FW_HEADER_SIGNATURE1 (0xA55AFAA5) ++#define MPI26_FW_HEADER_SIGNATURE1 (0xA55AEAA5) ++ ++/*Signature2 field */ ++#define MPI2_FW_HEADER_SIGNATURE2_OFFSET (0x0C) ++#define MPI2_FW_HEADER_SIGNATURE2 (0x5AA55AFA) ++#define MPI26_FW_HEADER_SIGNATURE2 (0x5AA55AEA) ++ ++/*defines for using the ProductID field */ ++#define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000) ++#define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000) ++ ++#define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00) ++#define MPI2_FW_HEADER_PID_PROD_A (0x0000) ++#define MPI2_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200) ++#define MPI2_FW_HEADER_PID_PROD_IR_SCSI (0x0700) ++ ++#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) ++/*SAS ProductID Family bits */ ++#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0013) ++#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0014) ++#define MPI25_FW_HEADER_PID_FAMILY_3108_SAS (0x0021) ++#define MPI26_FW_HEADER_PID_FAMILY_3324_SAS (0x0028) ++#define MPI26_FW_HEADER_PID_FAMILY_3516_SAS (0x0031) ++ ++/*use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */ ++ ++/*use MPI2_IOCFACTS_CAPABILITY_ defines for IOCCapabilities field */ ++ ++#define MPI2_FW_HEADER_IMAGESIZE_OFFSET (0x2C) ++#define MPI2_FW_HEADER_NEXTIMAGE_OFFSET (0x30) ++#define MPI26_FW_HEADER_BOOTFLAGS_OFFSET (0x60) ++#define MPI2_FW_HEADER_VERNMHWAT_OFFSET (0x64) ++ ++#define MPI2_FW_HEADER_WHAT_SIGNATURE (0x29232840) ++ ++#define MPI2_FW_HEADER_SIZE (0x100) ++ ++/*Extended Image Header */ ++typedef struct _MPI2_EXT_IMAGE_HEADER { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Checksum; /*0x04 */ ++ U32 ImageSize; /*0x08 */ ++ U32 NextImageHeaderOffset; /*0x0C */ ++ U32 PackageVersion; /*0x10 */ ++ U32 Reserved3; /*0x14 */ ++ U32 Reserved4; /*0x18 */ ++ U32 Reserved5; /*0x1C */ ++ U8 IdentifyString[32]; /*0x20 */ ++} MPI2_EXT_IMAGE_HEADER, *PTR_MPI2_EXT_IMAGE_HEADER, ++ Mpi2ExtImageHeader_t, *pMpi2ExtImageHeader_t; ++ ++/*useful offsets */ ++#define MPI2_EXT_IMAGE_IMAGETYPE_OFFSET (0x00) ++#define MPI2_EXT_IMAGE_IMAGESIZE_OFFSET (0x08) ++#define MPI2_EXT_IMAGE_NEXTIMAGE_OFFSET (0x0C) ++ ++#define MPI2_EXT_IMAGE_HEADER_SIZE (0x40) ++ ++/*defines for the ImageType field */ ++#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00) ++#define MPI2_EXT_IMAGE_TYPE_FW (0x01) ++#define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03) ++#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04) ++#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05) ++#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06) ++#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07) ++#define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08) ++#define MPI2_EXT_IMAGE_TYPE_ENCRYPTED_HASH (0x09) ++#define MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC (0x80) ++#define MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++#define MPI2_EXT_IMAGE_TYPE_MAX (MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC) ++ ++/*FLASH Layout Extended Image Data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check RegionsPerLayout at runtime. ++ */ ++#ifndef MPI2_FLASH_NUMBER_OF_REGIONS ++#define MPI2_FLASH_NUMBER_OF_REGIONS (1) ++#endif ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumberOfLayouts at runtime. ++ */ ++#ifndef MPI2_FLASH_NUMBER_OF_LAYOUTS ++#define MPI2_FLASH_NUMBER_OF_LAYOUTS (1) ++#endif ++ ++typedef struct _MPI2_FLASH_REGION { ++ U8 RegionType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 RegionOffset; /*0x04 */ ++ U32 RegionSize; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++} MPI2_FLASH_REGION, *PTR_MPI2_FLASH_REGION, ++ Mpi2FlashRegion_t, *pMpi2FlashRegion_t; ++ ++typedef struct _MPI2_FLASH_LAYOUT { ++ U32 FlashSize; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++ MPI2_FLASH_REGION Region[MPI2_FLASH_NUMBER_OF_REGIONS]; /*0x10 */ ++} MPI2_FLASH_LAYOUT, *PTR_MPI2_FLASH_LAYOUT, ++ Mpi2FlashLayout_t, *pMpi2FlashLayout_t; ++ ++typedef struct _MPI2_FLASH_LAYOUT_DATA { ++ U8 ImageRevision; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 SizeOfRegion; /*0x02 */ ++ U8 Reserved2; /*0x03 */ ++ U16 NumberOfLayouts; /*0x04 */ ++ U16 RegionsPerLayout; /*0x06 */ ++ U16 MinimumSectorAlignment; /*0x08 */ ++ U16 Reserved3; /*0x0A */ ++ U32 Reserved4; /*0x0C */ ++ MPI2_FLASH_LAYOUT Layout[MPI2_FLASH_NUMBER_OF_LAYOUTS]; /*0x10 */ ++} MPI2_FLASH_LAYOUT_DATA, *PTR_MPI2_FLASH_LAYOUT_DATA, ++ Mpi2FlashLayoutData_t, *pMpi2FlashLayoutData_t; ++ ++/*defines for the RegionType field */ ++#define MPI2_FLASH_REGION_UNUSED (0x00) ++#define MPI2_FLASH_REGION_FIRMWARE (0x01) ++#define MPI2_FLASH_REGION_BIOS (0x02) ++#define MPI2_FLASH_REGION_NVDATA (0x03) ++#define MPI2_FLASH_REGION_FIRMWARE_BACKUP (0x05) ++#define MPI2_FLASH_REGION_MFG_INFORMATION (0x06) ++#define MPI2_FLASH_REGION_CONFIG_1 (0x07) ++#define MPI2_FLASH_REGION_CONFIG_2 (0x08) ++#define MPI2_FLASH_REGION_MEGARAID (0x09) ++#define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK (0x0A) ++#define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK) ++#define MPI2_FLASH_REGION_CBB_BACKUP (0x0D) ++ ++/*ImageRevision */ ++#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00) ++ ++/*Supported Devices Extended Image Data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumberOfDevices at runtime. ++ */ ++#ifndef MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES ++#define MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES (1) ++#endif ++ ++typedef struct _MPI2_SUPPORTED_DEVICE { ++ U16 DeviceID; /*0x00 */ ++ U16 VendorID; /*0x02 */ ++ U16 DeviceIDMask; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++ U8 LowPCIRev; /*0x08 */ ++ U8 HighPCIRev; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U32 Reserved3; /*0x0C */ ++} MPI2_SUPPORTED_DEVICE, *PTR_MPI2_SUPPORTED_DEVICE, ++ Mpi2SupportedDevice_t, *pMpi2SupportedDevice_t; ++ ++typedef struct _MPI2_SUPPORTED_DEVICES_DATA { ++ U8 ImageRevision; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 NumberOfDevices; /*0x02 */ ++ U8 Reserved2; /*0x03 */ ++ U32 Reserved3; /*0x04 */ ++ MPI2_SUPPORTED_DEVICE ++ SupportedDevice[MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES];/*0x08 */ ++} MPI2_SUPPORTED_DEVICES_DATA, *PTR_MPI2_SUPPORTED_DEVICES_DATA, ++ Mpi2SupportedDevicesData_t, *pMpi2SupportedDevicesData_t; ++ ++/*ImageRevision */ ++#define MPI2_SUPPORTED_DEVICES_IMAGE_REVISION (0x00) ++ ++/*Init Extended Image Data */ ++ ++typedef struct _MPI2_INIT_IMAGE_FOOTER { ++ U32 BootFlags; /*0x00 */ ++ U32 ImageSize; /*0x04 */ ++ U32 Signature0; /*0x08 */ ++ U32 Signature1; /*0x0C */ ++ U32 Signature2; /*0x10 */ ++ U32 ResetVector; /*0x14 */ ++} MPI2_INIT_IMAGE_FOOTER, *PTR_MPI2_INIT_IMAGE_FOOTER, ++ Mpi2InitImageFooter_t, *pMpi2InitImageFooter_t; ++ ++/*defines for the BootFlags field */ ++#define MPI2_INIT_IMAGE_BOOTFLAGS_OFFSET (0x00) ++ ++/*defines for the ImageSize field */ ++#define MPI2_INIT_IMAGE_IMAGESIZE_OFFSET (0x04) ++ ++/*defines for the Signature0 field */ ++#define MPI2_INIT_IMAGE_SIGNATURE0_OFFSET (0x08) ++#define MPI2_INIT_IMAGE_SIGNATURE0 (0x5AA55AEA) ++ ++/*defines for the Signature1 field */ ++#define MPI2_INIT_IMAGE_SIGNATURE1_OFFSET (0x0C) ++#define MPI2_INIT_IMAGE_SIGNATURE1 (0xA55AEAA5) ++ ++/*defines for the Signature2 field */ ++#define MPI2_INIT_IMAGE_SIGNATURE2_OFFSET (0x10) ++#define MPI2_INIT_IMAGE_SIGNATURE2 (0x5AEAA55A) ++ ++/*Signature fields as individual bytes */ ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_0 (0xEA) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_1 (0x5A) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_2 (0xA5) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_3 (0x5A) ++ ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_4 (0xA5) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_5 (0xEA) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_6 (0x5A) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_7 (0xA5) ++ ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_8 (0x5A) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_9 (0xA5) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_A (0xEA) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_B (0x5A) ++ ++/*defines for the ResetVector field */ ++#define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET (0x14) ++ ++ ++/* Encrypted Hash Extended Image Data */ ++ ++typedef struct _MPI25_ENCRYPTED_HASH_ENTRY { ++ U8 HashImageType; /* 0x00 */ ++ U8 HashAlgorithm; /* 0x01 */ ++ U8 EncryptionAlgorithm; /* 0x02 */ ++ U8 Reserved1; /* 0x03 */ ++ U32 Reserved2; /* 0x04 */ ++ U32 EncryptedHash[1]; /* 0x08 */ /* variable length */ ++} MPI25_ENCRYPTED_HASH_ENTRY, *PTR_MPI25_ENCRYPTED_HASH_ENTRY, ++Mpi25EncryptedHashEntry_t, *pMpi25EncryptedHashEntry_t; ++ ++/* values for HashImageType */ ++#define MPI25_HASH_IMAGE_TYPE_UNUSED (0x00) ++#define MPI25_HASH_IMAGE_TYPE_FIRMWARE (0x01) ++#define MPI25_HASH_IMAGE_TYPE_BIOS (0x02) ++ ++/* values for HashAlgorithm */ ++#define MPI25_HASH_ALGORITHM_UNUSED (0x00) ++#define MPI25_HASH_ALGORITHM_SHA256 (0x01) ++ ++/* values for EncryptionAlgorithm */ ++#define MPI25_ENCRYPTION_ALG_UNUSED (0x00) ++#define MPI25_ENCRYPTION_ALG_RSA256 (0x01) ++ ++typedef struct _MPI25_ENCRYPTED_HASH_DATA { ++ U8 ImageVersion; /* 0x00 */ ++ U8 NumHash; /* 0x01 */ ++ U16 Reserved1; /* 0x02 */ ++ U32 Reserved2; /* 0x04 */ ++ MPI25_ENCRYPTED_HASH_ENTRY EncryptedHashEntry[1]; /* 0x08 */ ++} MPI25_ENCRYPTED_HASH_DATA, *PTR_MPI25_ENCRYPTED_HASH_DATA, ++Mpi25EncryptedHashData_t, *pMpi25EncryptedHashData_t; ++ ++ ++/**************************************************************************** ++* PowerManagementControl message ++****************************************************************************/ ++ ++/*PowerManagementControl Request message */ ++typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST { ++ U8 Feature; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 Parameter1; /*0x0C */ ++ U8 Parameter2; /*0x0D */ ++ U8 Parameter3; /*0x0E */ ++ U8 Parameter4; /*0x0F */ ++ U32 Reserved5; /*0x10 */ ++ U32 Reserved6; /*0x14 */ ++} MPI2_PWR_MGMT_CONTROL_REQUEST, *PTR_MPI2_PWR_MGMT_CONTROL_REQUEST, ++ Mpi2PwrMgmtControlRequest_t, *pMpi2PwrMgmtControlRequest_t; ++ ++/*defines for the Feature field */ ++#define MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND (0x01) ++#define MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION (0x02) ++#define MPI2_PM_CONTROL_FEATURE_PCIE_LINK (0x03) /*obsolete */ ++#define MPI2_PM_CONTROL_FEATURE_IOC_SPEED (0x04) ++#define MPI2_PM_CONTROL_FEATURE_GLOBAL_PWR_MGMT_MODE (0x05) ++#define MPI2_PM_CONTROL_FEATURE_MIN_PRODUCT_SPECIFIC (0x80) ++#define MPI2_PM_CONTROL_FEATURE_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND Feature */ ++/*Parameter1 contains a PHY number */ ++/*Parameter2 indicates power condition action using these defines */ ++#define MPI2_PM_CONTROL_PARAM2_PARTIAL (0x01) ++#define MPI2_PM_CONTROL_PARAM2_SLUMBER (0x02) ++#define MPI2_PM_CONTROL_PARAM2_EXIT_PWR_MGMT (0x03) ++/*Parameter3 and Parameter4 are reserved */ ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION ++ * Feature */ ++/*Parameter1 contains SAS port width modulation group number */ ++/*Parameter2 indicates IOC action using these defines */ ++#define MPI2_PM_CONTROL_PARAM2_REQUEST_OWNERSHIP (0x01) ++#define MPI2_PM_CONTROL_PARAM2_CHANGE_MODULATION (0x02) ++#define MPI2_PM_CONTROL_PARAM2_RELINQUISH_OWNERSHIP (0x03) ++/*Parameter3 indicates desired modulation level using these defines */ ++#define MPI2_PM_CONTROL_PARAM3_25_PERCENT (0x00) ++#define MPI2_PM_CONTROL_PARAM3_50_PERCENT (0x01) ++#define MPI2_PM_CONTROL_PARAM3_75_PERCENT (0x02) ++#define MPI2_PM_CONTROL_PARAM3_100_PERCENT (0x03) ++/*Parameter4 is reserved */ ++ ++/*this next set (_PCIE_LINK) is obsolete */ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_PCIE_LINK Feature */ ++/*Parameter1 indicates desired PCIe link speed using these defines */ ++#define MPI2_PM_CONTROL_PARAM1_PCIE_2_5_GBPS (0x00) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM1_PCIE_5_0_GBPS (0x01) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM1_PCIE_8_0_GBPS (0x02) /*obsolete */ ++/*Parameter2 indicates desired PCIe link width using these defines */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X1 (0x01) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X2 (0x02) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X4 (0x04) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X8 (0x08) /*obsolete */ ++/*Parameter3 and Parameter4 are reserved */ ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_IOC_SPEED Feature */ ++/*Parameter1 indicates desired IOC hardware clock speed using these defines */ ++#define MPI2_PM_CONTROL_PARAM1_FULL_IOC_SPEED (0x01) ++#define MPI2_PM_CONTROL_PARAM1_HALF_IOC_SPEED (0x02) ++#define MPI2_PM_CONTROL_PARAM1_QUARTER_IOC_SPEED (0x04) ++#define MPI2_PM_CONTROL_PARAM1_EIGHTH_IOC_SPEED (0x08) ++/*Parameter2, Parameter3, and Parameter4 are reserved */ ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_GLOBAL_PWR_MGMT_MODE Feature*/ ++/*Parameter1 indicates host action regarding global power management mode */ ++#define MPI2_PM_CONTROL_PARAM1_TAKE_CONTROL (0x01) ++#define MPI2_PM_CONTROL_PARAM1_CHANGE_GLOBAL_MODE (0x02) ++#define MPI2_PM_CONTROL_PARAM1_RELEASE_CONTROL (0x03) ++/*Parameter2 indicates the requested global power management mode */ ++#define MPI2_PM_CONTROL_PARAM2_FULL_PWR_PERF (0x01) ++#define MPI2_PM_CONTROL_PARAM2_REDUCED_PWR_PERF (0x08) ++#define MPI2_PM_CONTROL_PARAM2_STANDBY (0x40) ++/*Parameter3 and Parameter4 are reserved */ ++ ++/*PowerManagementControl Reply message */ ++typedef struct _MPI2_PWR_MGMT_CONTROL_REPLY { ++ U8 Feature; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_PWR_MGMT_CONTROL_REPLY, *PTR_MPI2_PWR_MGMT_CONTROL_REPLY, ++ Mpi2PwrMgmtControlReply_t, *pMpi2PwrMgmtControlReply_t; ++ ++/**************************************************************************** ++* IO Unit Control messages (MPI v2.6 and later only.) ++****************************************************************************/ ++ ++/* IO Unit Control Request Message */ ++typedef struct _MPI26_IOUNIT_CONTROL_REQUEST { ++ U8 Operation; /* 0x00 */ ++ U8 Reserved1; /* 0x01 */ ++ U8 ChainOffset; /* 0x02 */ ++ U8 Function; /* 0x03 */ ++ U16 DevHandle; /* 0x04 */ ++ U8 IOCParameter; /* 0x06 */ ++ U8 MsgFlags; /* 0x07 */ ++ U8 VP_ID; /* 0x08 */ ++ U8 VF_ID; /* 0x09 */ ++ U16 Reserved3; /* 0x0A */ ++ U16 Reserved4; /* 0x0C */ ++ U8 PhyNum; /* 0x0E */ ++ U8 PrimFlags; /* 0x0F */ ++ U32 Primitive; /* 0x10 */ ++ U8 LookupMethod; /* 0x14 */ ++ U8 Reserved5; /* 0x15 */ ++ U16 SlotNumber; /* 0x16 */ ++ U64 LookupAddress; /* 0x18 */ ++ U32 IOCParameterValue; /* 0x20 */ ++ U32 Reserved7; /* 0x24 */ ++ U32 Reserved8; /* 0x28 */ ++} MPI26_IOUNIT_CONTROL_REQUEST, ++ *PTR_MPI26_IOUNIT_CONTROL_REQUEST, ++ Mpi26IoUnitControlRequest_t, ++ *pMpi26IoUnitControlRequest_t; ++ ++/* values for the Operation field */ ++#define MPI26_CTRL_OP_CLEAR_ALL_PERSISTENT (0x02) ++#define MPI26_CTRL_OP_SAS_PHY_LINK_RESET (0x06) ++#define MPI26_CTRL_OP_SAS_PHY_HARD_RESET (0x07) ++#define MPI26_CTRL_OP_PHY_CLEAR_ERROR_LOG (0x08) ++#define MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG (0x09) ++#define MPI26_CTRL_OP_SAS_SEND_PRIMITIVE (0x0A) ++#define MPI26_CTRL_OP_FORCE_FULL_DISCOVERY (0x0B) ++#define MPI26_CTRL_OP_REMOVE_DEVICE (0x0D) ++#define MPI26_CTRL_OP_LOOKUP_MAPPING (0x0E) ++#define MPI26_CTRL_OP_SET_IOC_PARAMETER (0x0F) ++#define MPI26_CTRL_OP_ENABLE_FP_DEVICE (0x10) ++#define MPI26_CTRL_OP_DISABLE_FP_DEVICE (0x11) ++#define MPI26_CTRL_OP_ENABLE_FP_ALL (0x12) ++#define MPI26_CTRL_OP_DISABLE_FP_ALL (0x13) ++#define MPI26_CTRL_OP_DEV_ENABLE_NCQ (0x14) ++#define MPI26_CTRL_OP_DEV_DISABLE_NCQ (0x15) ++#define MPI26_CTRL_OP_SHUTDOWN (0x16) ++#define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION (0x17) ++#define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION (0x18) ++#define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION (0x19) ++#define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN (0x80) ++ ++/* values for the PrimFlags field */ ++#define MPI26_CTRL_PRIMFLAGS_SINGLE (0x08) ++#define MPI26_CTRL_PRIMFLAGS_TRIPLE (0x02) ++#define MPI26_CTRL_PRIMFLAGS_REDUNDANT (0x01) ++ ++/* values for the LookupMethod field */ ++#define MPI26_CTRL_LOOKUP_METHOD_WWID_ADDRESS (0x01) ++#define MPI26_CTRL_LOOKUP_METHOD_ENCLOSURE_SLOT (0x02) ++#define MPI26_CTRL_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03) ++ ++ ++/* IO Unit Control Reply Message */ ++typedef struct _MPI26_IOUNIT_CONTROL_REPLY { ++ U8 Operation; /* 0x00 */ ++ U8 Reserved1; /* 0x01 */ ++ U8 MsgLength; /* 0x02 */ ++ U8 Function; /* 0x03 */ ++ U16 DevHandle; /* 0x04 */ ++ U8 IOCParameter; /* 0x06 */ ++ U8 MsgFlags; /* 0x07 */ ++ U8 VP_ID; /* 0x08 */ ++ U8 VF_ID; /* 0x09 */ ++ U16 Reserved3; /* 0x0A */ ++ U16 Reserved4; /* 0x0C */ ++ U16 IOCStatus; /* 0x0E */ ++ U32 IOCLogInfo; /* 0x10 */ ++} MPI26_IOUNIT_CONTROL_REPLY, ++ *PTR_MPI26_IOUNIT_CONTROL_REPLY, ++ Mpi26IoUnitControlReply_t, ++ *pMpi26IoUnitControlReply_t; ++ ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h +new file mode 100644 +index 0000000..1c0eeee +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h +@@ -0,0 +1,355 @@ ++/* ++ * Copyright 2000-2014 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_raid.h ++ * Title: MPI Integrated RAID messages and structures ++ * Creation Date: April 26, 2007 ++ * ++ * mpi2_raid.h Version: 02.00.11 ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 08-31-07 02.00.01 Modifications to RAID Action request and reply, ++ * including the Actions and ActionData. ++ * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD. ++ * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that ++ * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT ++ * can be sized by the build environment. ++ * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of ++ * VolumeCreationFlags and marked the old one as obsolete. ++ * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define. ++ * 08-24-10 02.00.06 Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with ++ * related structures and defines. ++ * Added product-specific range to RAID Action values. ++ * 11-18-11 02.00.07 Incorporating additions for MPI v2.5. ++ * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN. ++ * 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR. ++ * Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define. ++ * 04-17-13 02.00.10 Added MPI25_RAID_ACTION_ADATA_ALLOW_PI. ++ * 11-18-14 02.00.11 Updated copyright information. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_RAID_H ++#define MPI2_RAID_H ++ ++/***************************************************************************** ++* ++* Integrated RAID Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* RAID Action messages ++****************************************************************************/ ++ ++/* ActionDataWord defines for use with MPI2_RAID_ACTION_CREATE_VOLUME action */ ++#define MPI25_RAID_ACTION_ADATA_ALLOW_PI (0x80000000) ++ ++/*ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */ ++#define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) ++#define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001) ++ ++/*use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for ++ *MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ ++ ++/*ActionDataWord defines for use with ++ *MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */ ++#define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD (0x00000001) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */ ++typedef struct _MPI2_RAID_ACTION_RATE_DATA { ++ U8 RateToChange; /*0x00 */ ++ U8 RateOrMode; /*0x01 */ ++ U16 DataScrubDuration; /*0x02 */ ++} MPI2_RAID_ACTION_RATE_DATA, *PTR_MPI2_RAID_ACTION_RATE_DATA, ++ Mpi2RaidActionRateData_t, *pMpi2RaidActionRateData_t; ++ ++#define MPI2_RAID_ACTION_SET_RATE_RESYNC (0x00) ++#define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB (0x01) ++#define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE (0x02) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */ ++typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION { ++ U8 RAIDFunction; /*0x00 */ ++ U8 Flags; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_RAID_ACTION_START_RAID_FUNCTION, ++ *PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION, ++ Mpi2RaidActionStartRaidFunction_t, ++ *pMpi2RaidActionStartRaidFunction_t; ++ ++/*defines for the RAIDFunction field */ ++#define MPI2_RAID_ACTION_START_BACKGROUND_INIT (0x00) ++#define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01) ++#define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK (0x02) ++ ++/*defines for the Flags field */ ++#define MPI2_RAID_ACTION_START_NEW (0x00) ++#define MPI2_RAID_ACTION_START_RESUME (0x01) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */ ++typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION { ++ U8 RAIDFunction; /*0x00 */ ++ U8 Flags; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_RAID_ACTION_STOP_RAID_FUNCTION, ++ *PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION, ++ Mpi2RaidActionStopRaidFunction_t, ++ *pMpi2RaidActionStopRaidFunction_t; ++ ++/*defines for the RAIDFunction field */ ++#define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT (0x00) ++#define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION (0x01) ++#define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK (0x02) ++ ++/*defines for the Flags field */ ++#define MPI2_RAID_ACTION_STOP_ABORT (0x00) ++#define MPI2_RAID_ACTION_STOP_PAUSE (0x01) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */ ++typedef struct _MPI2_RAID_ACTION_HOT_SPARE { ++ U8 HotSparePool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 DevHandle; /*0x02 */ ++} MPI2_RAID_ACTION_HOT_SPARE, *PTR_MPI2_RAID_ACTION_HOT_SPARE, ++ Mpi2RaidActionHotSpare_t, *pMpi2RaidActionHotSpare_t; ++ ++/*ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */ ++typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE { ++ U8 Flags; /*0x00 */ ++ U8 DeviceFirmwareUpdateModeTimeout; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_RAID_ACTION_FW_UPDATE_MODE, ++ *PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE, ++ Mpi2RaidActionFwUpdateMode_t, ++ *pMpi2RaidActionFwUpdateMode_t; ++ ++/*ActionDataWord defines for use with ++ *MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */ ++#define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE (0x00) ++#define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE (0x01) ++ ++typedef union _MPI2_RAID_ACTION_DATA { ++ U32 Word; ++ MPI2_RAID_ACTION_RATE_DATA Rates; ++ MPI2_RAID_ACTION_START_RAID_FUNCTION StartRaidFunction; ++ MPI2_RAID_ACTION_STOP_RAID_FUNCTION StopRaidFunction; ++ MPI2_RAID_ACTION_HOT_SPARE HotSpare; ++ MPI2_RAID_ACTION_FW_UPDATE_MODE FwUpdateMode; ++} MPI2_RAID_ACTION_DATA, *PTR_MPI2_RAID_ACTION_DATA, ++ Mpi2RaidActionData_t, *pMpi2RaidActionData_t; ++ ++/*RAID Action Request Message */ ++typedef struct _MPI2_RAID_ACTION_REQUEST { ++ U8 Action; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 VolDevHandle; /*0x04 */ ++ U8 PhysDiskNum; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U32 Reserved3; /*0x0C */ ++ MPI2_RAID_ACTION_DATA ActionDataWord; /*0x10 */ ++ MPI2_SGE_SIMPLE_UNION ActionDataSGE; /*0x14 */ ++} MPI2_RAID_ACTION_REQUEST, *PTR_MPI2_RAID_ACTION_REQUEST, ++ Mpi2RaidActionRequest_t, *pMpi2RaidActionRequest_t; ++ ++/*RAID Action request Action values */ ++ ++#define MPI2_RAID_ACTION_INDICATOR_STRUCT (0x01) ++#define MPI2_RAID_ACTION_CREATE_VOLUME (0x02) ++#define MPI2_RAID_ACTION_DELETE_VOLUME (0x03) ++#define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES (0x04) ++#define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES (0x05) ++#define MPI2_RAID_ACTION_PHYSDISK_OFFLINE (0x0A) ++#define MPI2_RAID_ACTION_PHYSDISK_ONLINE (0x0B) ++#define MPI2_RAID_ACTION_FAIL_PHYSDISK (0x0F) ++#define MPI2_RAID_ACTION_ACTIVATE_VOLUME (0x11) ++#define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15) ++#define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE (0x17) ++#define MPI2_RAID_ACTION_SET_VOLUME_NAME (0x18) ++#define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE (0x19) ++#define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME (0x1C) ++#define MPI2_RAID_ACTION_CREATE_HOT_SPARE (0x1D) ++#define MPI2_RAID_ACTION_DELETE_HOT_SPARE (0x1E) ++#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20) ++#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21) ++#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22) ++#define MPI2_RAID_ACTION_COMPATIBILITY_CHECK (0x23) ++#define MPI2_RAID_ACTION_PHYSDISK_HIDDEN (0x24) ++#define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC (0x80) ++#define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++/*RAID Volume Creation Structure */ ++ ++/* ++ *The following define can be customized for the targeted product. ++ */ ++#ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS ++#define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS (1) ++#endif ++ ++typedef struct _MPI2_RAID_VOLUME_PHYSDISK { ++ U8 RAIDSetNum; /*0x00 */ ++ U8 PhysDiskMap; /*0x01 */ ++ U16 PhysDiskDevHandle; /*0x02 */ ++} MPI2_RAID_VOLUME_PHYSDISK, *PTR_MPI2_RAID_VOLUME_PHYSDISK, ++ Mpi2RaidVolumePhysDisk_t, *pMpi2RaidVolumePhysDisk_t; ++ ++/*defines for the PhysDiskMap field */ ++#define MPI2_RAIDACTION_PHYSDISK_PRIMARY (0x01) ++#define MPI2_RAIDACTION_PHYSDISK_SECONDARY (0x02) ++ ++typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT { ++ U8 NumPhysDisks; /*0x00 */ ++ U8 VolumeType; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++ U32 VolumeCreationFlags; /*0x04 */ ++ U32 VolumeSettings; /*0x08 */ ++ U8 Reserved2; /*0x0C */ ++ U8 ResyncRate; /*0x0D */ ++ U16 DataScrubDuration; /*0x0E */ ++ U64 VolumeMaxLBA; /*0x10 */ ++ U32 StripeSize; /*0x18 */ ++ U8 Name[16]; /*0x1C */ ++ MPI2_RAID_VOLUME_PHYSDISK ++ PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS]; /*0x2C */ ++} MPI2_RAID_VOLUME_CREATION_STRUCT, ++ *PTR_MPI2_RAID_VOLUME_CREATION_STRUCT, ++ Mpi2RaidVolumeCreationStruct_t, ++ *pMpi2RaidVolumeCreationStruct_t; ++ ++/*use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */ ++ ++/*defines for the VolumeCreationFlags field */ ++#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS (0x80000000) ++#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x00000004) ++#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x00000002) ++#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x00000001) ++/*The following is an obsolete define. ++ *It must be shifted left 24 bits in order to set the proper bit. ++ */ ++#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80) ++ ++/*RAID Online Capacity Expansion Structure */ ++ ++typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION { ++ U32 Flags; /*0x00 */ ++ U16 DevHandle0; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++ U16 DevHandle1; /*0x08 */ ++ U16 Reserved2; /*0x0A */ ++} MPI2_RAID_ONLINE_CAPACITY_EXPANSION, ++ *PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION, ++ Mpi2RaidOnlineCapacityExpansion_t, ++ *pMpi2RaidOnlineCapacityExpansion_t; ++ ++/*RAID Compatibility Input Structure */ ++ ++typedef struct _MPI2_RAID_COMPATIBILITY_INPUT_STRUCT { ++ U16 SourceDevHandle; /*0x00 */ ++ U16 CandidateDevHandle; /*0x02 */ ++ U32 Flags; /*0x04 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++} MPI2_RAID_COMPATIBILITY_INPUT_STRUCT, ++ *PTR_MPI2_RAID_COMPATIBILITY_INPUT_STRUCT, ++ Mpi2RaidCompatibilityInputStruct_t, ++ *pMpi2RaidCompatibilityInputStruct_t; ++ ++/*defines for RAID Compatibility Structure Flags field */ ++#define MPI2_RAID_COMPAT_SOURCE_IS_VOLUME_FLAG (0x00000002) ++#define MPI2_RAID_COMPAT_REPORT_SOURCE_INFO_FLAG (0x00000001) ++ ++/*RAID Volume Indicator Structure */ ++ ++typedef struct _MPI2_RAID_VOL_INDICATOR { ++ U64 TotalBlocks; /*0x00 */ ++ U64 BlocksRemaining; /*0x08 */ ++ U32 Flags; /*0x10 */ ++ U32 ElapsedSeconds; /* 0x14 */ ++} MPI2_RAID_VOL_INDICATOR, *PTR_MPI2_RAID_VOL_INDICATOR, ++ Mpi2RaidVolIndicator_t, *pMpi2RaidVolIndicator_t; ++ ++/*defines for RAID Volume Indicator Flags field */ ++#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000) ++#define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F) ++#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000) ++#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) ++#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002) ++#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003) ++#define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004) ++ ++/*RAID Compatibility Result Structure */ ++ ++typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT { ++ U8 State; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 GenericAttributes; /*0x04 */ ++ U32 OEMSpecificAttributes; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++ U32 Reserved4; /*0x10 */ ++} MPI2_RAID_COMPATIBILITY_RESULT_STRUCT, ++ *PTR_MPI2_RAID_COMPATIBILITY_RESULT_STRUCT, ++ Mpi2RaidCompatibilityResultStruct_t, ++ *pMpi2RaidCompatibilityResultStruct_t; ++ ++/*defines for RAID Compatibility Result Structure State field */ ++#define MPI2_RAID_COMPAT_STATE_COMPATIBLE (0x00) ++#define MPI2_RAID_COMPAT_STATE_NOT_COMPATIBLE (0x01) ++ ++/*defines for RAID Compatibility Result Structure GenericAttributes field */ ++#define MPI2_RAID_COMPAT_GENATTRIB_4K_SECTOR (0x00000010) ++ ++#define MPI2_RAID_COMPAT_GENATTRIB_MEDIA_MASK (0x0000000C) ++#define MPI2_RAID_COMPAT_GENATTRIB_SOLID_STATE_DRIVE (0x00000008) ++#define MPI2_RAID_COMPAT_GENATTRIB_HARD_DISK_DRIVE (0x00000004) ++ ++#define MPI2_RAID_COMPAT_GENATTRIB_PROTOCOL_MASK (0x00000003) ++#define MPI2_RAID_COMPAT_GENATTRIB_SAS_PROTOCOL (0x00000002) ++#define MPI2_RAID_COMPAT_GENATTRIB_SATA_PROTOCOL (0x00000001) ++ ++/*RAID Action Reply ActionData union */ ++typedef union _MPI2_RAID_ACTION_REPLY_DATA { ++ U32 Word[6]; ++ MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; ++ U16 VolDevHandle; ++ U8 VolumeState; ++ U8 PhysDiskNum; ++ MPI2_RAID_COMPATIBILITY_RESULT_STRUCT RaidCompatibilityResult; ++} MPI2_RAID_ACTION_REPLY_DATA, *PTR_MPI2_RAID_ACTION_REPLY_DATA, ++ Mpi2RaidActionReplyData_t, *pMpi2RaidActionReplyData_t; ++ ++/*use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for ++ *MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ ++ ++/*RAID Action Reply Message */ ++typedef struct _MPI2_RAID_ACTION_REPLY { ++ U8 Action; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 VolDevHandle; /*0x04 */ ++ U8 PhysDiskNum; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ MPI2_RAID_ACTION_REPLY_DATA ActionData; /*0x14 */ ++} MPI2_RAID_ACTION_REPLY, *PTR_MPI2_RAID_ACTION_REPLY, ++ Mpi2RaidActionReply_t, *pMpi2RaidActionReply_t; ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h +new file mode 100644 +index 0000000..c10c2c0 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h +@@ -0,0 +1,303 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_sas.h ++ * Title: MPI Serial Attached SCSI structures and definitions ++ * Creation Date: February 9, 2007 ++ * ++ * mpi2_sas.h Version: 02.00.10 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit ++ * Control Request. ++ * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control ++ * Request. ++ * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST ++ * to MPI2_SGE_IO_UNION since it supports chained SGLs. ++ * 05-12-10 02.00.04 Modified some comments. ++ * 08-11-10 02.00.05 Added NCQ operations to SAS IO Unit Control. ++ * 11-18-11 02.00.06 Incorporating additions for MPI v2.5. ++ * 07-10-12 02.00.07 Added MPI2_SATA_PT_SGE_UNION for use in the SATA ++ * Passthrough Request message. ++ * 08-19-13 02.00.08 Made MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL obsolete ++ * for anything newer than MPI v2.0. ++ * 11-18-14 02.00.09 Updated copyright information. ++ * 03-16-15 02.00.10 Updated for MPI v2.6. ++ * Added MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_SAS_H ++#define MPI2_SAS_H ++ ++/* ++ *Values for SASStatus. ++ */ ++#define MPI2_SASSTATUS_SUCCESS (0x00) ++#define MPI2_SASSTATUS_UNKNOWN_ERROR (0x01) ++#define MPI2_SASSTATUS_INVALID_FRAME (0x02) ++#define MPI2_SASSTATUS_UTC_BAD_DEST (0x03) ++#define MPI2_SASSTATUS_UTC_BREAK_RECEIVED (0x04) ++#define MPI2_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05) ++#define MPI2_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06) ++#define MPI2_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07) ++#define MPI2_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08) ++#define MPI2_SASSTATUS_UTC_WRONG_DESTINATION (0x09) ++#define MPI2_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A) ++#define MPI2_SASSTATUS_LONG_INFORMATION_UNIT (0x0B) ++#define MPI2_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C) ++#define MPI2_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D) ++#define MPI2_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E) ++#define MPI2_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F) ++#define MPI2_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10) ++#define MPI2_SASSTATUS_DATA_OFFSET_ERROR (0x11) ++#define MPI2_SASSTATUS_SDSF_NAK_RECEIVED (0x12) ++#define MPI2_SASSTATUS_SDSF_CONNECTION_FAILED (0x13) ++#define MPI2_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14) ++ ++/* ++ *Values for the SAS DeviceInfo field used in SAS Device Status Change Event ++ *data and SAS Configuration pages. ++ */ ++#define MPI2_SAS_DEVICE_INFO_SEP (0x00004000) ++#define MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) ++#define MPI2_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) ++#define MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800) ++#define MPI2_SAS_DEVICE_INFO_SSP_TARGET (0x00000400) ++#define MPI2_SAS_DEVICE_INFO_STP_TARGET (0x00000200) ++#define MPI2_SAS_DEVICE_INFO_SMP_TARGET (0x00000100) ++#define MPI2_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080) ++#define MPI2_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040) ++#define MPI2_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020) ++#define MPI2_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010) ++#define MPI2_SAS_DEVICE_INFO_SATA_HOST (0x00000008) ++ ++#define MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007) ++#define MPI2_SAS_DEVICE_INFO_NO_DEVICE (0x00000000) ++#define MPI2_SAS_DEVICE_INFO_END_DEVICE (0x00000001) ++#define MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002) ++#define MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003) ++ ++/***************************************************************************** ++* ++* SAS Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* SMP Passthrough messages ++****************************************************************************/ ++ ++/*SMP Passthrough Request Message */ ++typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST { ++ U8 PassthroughFlags; /*0x00 */ ++ U8 PhysicalPort; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 RequestDataLength; /*0x04 */ ++ U8 SGLFlags; /*0x06*//*MPI v2.0 only. Reserved on MPI v2.5*/ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Reserved2; /*0x0C */ ++ U64 SASAddress; /*0x10 */ ++ U32 Reserved3; /*0x18 */ ++ U32 Reserved4; /*0x1C */ ++ MPI2_SIMPLE_SGE_UNION SGL;/*0x20 */ ++} MPI2_SMP_PASSTHROUGH_REQUEST, *PTR_MPI2_SMP_PASSTHROUGH_REQUEST, ++ Mpi2SmpPassthroughRequest_t, *pMpi2SmpPassthroughRequest_t; ++ ++/*values for PassthroughFlags field */ ++#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) ++ ++/*MPI v2.0: use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*SMP Passthrough Reply Message */ ++typedef struct _MPI2_SMP_PASSTHROUGH_REPLY { ++ U8 PassthroughFlags; /*0x00 */ ++ U8 PhysicalPort; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 ResponseDataLength; /*0x04 */ ++ U8 SGLFlags; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U8 Reserved2; /*0x0C */ ++ U8 SASStatus; /*0x0D */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 Reserved3; /*0x14 */ ++ U8 ResponseData[4]; /*0x18 */ ++} MPI2_SMP_PASSTHROUGH_REPLY, *PTR_MPI2_SMP_PASSTHROUGH_REPLY, ++ Mpi2SmpPassthroughReply_t, *pMpi2SmpPassthroughReply_t; ++ ++/*values for PassthroughFlags field */ ++#define MPI2_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80) ++ ++/*values for SASStatus field are at the top of this file */ ++ ++/**************************************************************************** ++* SATA Passthrough messages ++****************************************************************************/ ++ ++typedef union _MPI2_SATA_PT_SGE_UNION { ++ MPI2_SGE_SIMPLE_UNION MpiSimple; /*MPI v2.0 only */ ++ MPI2_SGE_CHAIN_UNION MpiChain; /*MPI v2.0 only */ ++ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; ++ MPI2_IEEE_SGE_CHAIN_UNION IeeeChain; /*MPI v2.0 only */ ++ MPI25_IEEE_SGE_CHAIN64 IeeeChain64; /*MPI v2.5 only */ ++} MPI2_SATA_PT_SGE_UNION, *PTR_MPI2_SATA_PT_SGE_UNION, ++ Mpi2SataPTSGEUnion_t, *pMpi2SataPTSGEUnion_t; ++ ++/*SATA Passthrough Request Message */ ++typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 PassthroughFlags; /*0x04 */ ++ U8 SGLFlags; /*0x06*//*MPI v2.0 only. Reserved on MPI v2.5*/ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Reserved2; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U32 Reserved4; /*0x14 */ ++ U32 DataLength; /*0x18 */ ++ U8 CommandFIS[20]; /*0x1C */ ++ MPI2_SATA_PT_SGE_UNION SGL;/*0x30*//*MPI v2.5: IEEE 64 elements only*/ ++} MPI2_SATA_PASSTHROUGH_REQUEST, *PTR_MPI2_SATA_PASSTHROUGH_REQUEST, ++ Mpi2SataPassthroughRequest_t, ++ *pMpi2SataPassthroughRequest_t; ++ ++/*values for PassthroughFlags field */ ++#define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA (0x0040) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_DMA (0x0020) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_PIO (0x0010) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001) ++ ++/*MPI v2.0: use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*SATA Passthrough Reply Message */ ++typedef struct _MPI2_SATA_PASSTHROUGH_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 PassthroughFlags; /*0x04 */ ++ U8 SGLFlags; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U8 Reserved2; /*0x0C */ ++ U8 SASStatus; /*0x0D */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 StatusFIS[20]; /*0x14 */ ++ U32 StatusControlRegisters; /*0x28 */ ++ U32 TransferCount; /*0x2C */ ++} MPI2_SATA_PASSTHROUGH_REPLY, *PTR_MPI2_SATA_PASSTHROUGH_REPLY, ++ Mpi2SataPassthroughReply_t, *pMpi2SataPassthroughReply_t; ++ ++/*values for SASStatus field are at the top of this file */ ++ ++/**************************************************************************** ++* SAS IO Unit Control messages ++* (MPI v2.5 and earlier only. ++* Replaced by IO Unit Control messages in MPI v2.6 and later.) ++****************************************************************************/ ++ ++/*SAS IO Unit Control Request Message */ ++typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST { ++ U8 Operation; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 DevHandle; /*0x04 */ ++ U8 IOCParameter; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U8 PhyNum; /*0x0E */ ++ U8 PrimFlags; /*0x0F */ ++ U32 Primitive; /*0x10 */ ++ U8 LookupMethod; /*0x14 */ ++ U8 Reserved5; /*0x15 */ ++ U16 SlotNumber; /*0x16 */ ++ U64 LookupAddress; /*0x18 */ ++ U32 IOCParameterValue; /*0x20 */ ++ U32 Reserved7; /*0x24 */ ++ U32 Reserved8; /*0x28 */ ++} MPI2_SAS_IOUNIT_CONTROL_REQUEST, ++ *PTR_MPI2_SAS_IOUNIT_CONTROL_REQUEST, ++ Mpi2SasIoUnitControlRequest_t, ++ *pMpi2SasIoUnitControlRequest_t; ++ ++/*values for the Operation field */ ++#define MPI2_SAS_OP_CLEAR_ALL_PERSISTENT (0x02) ++#define MPI2_SAS_OP_PHY_LINK_RESET (0x06) ++#define MPI2_SAS_OP_PHY_HARD_RESET (0x07) ++#define MPI2_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) ++#define MPI2_SAS_OP_SEND_PRIMITIVE (0x0A) ++#define MPI2_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) ++#define MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) /* MPI v2.0 only */ ++#define MPI2_SAS_OP_REMOVE_DEVICE (0x0D) ++#define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E) ++#define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F) ++#define MPI25_SAS_OP_ENABLE_FP_DEVICE (0x10) ++#define MPI25_SAS_OP_DISABLE_FP_DEVICE (0x11) ++#define MPI25_SAS_OP_ENABLE_FP_ALL (0x12) ++#define MPI25_SAS_OP_DISABLE_FP_ALL (0x13) ++#define MPI2_SAS_OP_DEV_ENABLE_NCQ (0x14) ++#define MPI2_SAS_OP_DEV_DISABLE_NCQ (0x15) ++#define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80) ++ ++/*values for the PrimFlags field */ ++#define MPI2_SAS_PRIMFLAGS_SINGLE (0x08) ++#define MPI2_SAS_PRIMFLAGS_TRIPLE (0x02) ++#define MPI2_SAS_PRIMFLAGS_REDUNDANT (0x01) ++ ++/*values for the LookupMethod field */ ++#define MPI2_SAS_LOOKUP_METHOD_SAS_ADDRESS (0x01) ++#define MPI2_SAS_LOOKUP_METHOD_SAS_ENCLOSURE_SLOT (0x02) ++#define MPI2_SAS_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03) ++ ++/*SAS IO Unit Control Reply Message */ ++typedef struct _MPI2_SAS_IOUNIT_CONTROL_REPLY { ++ U8 Operation; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 DevHandle; /*0x04 */ ++ U8 IOCParameter; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_SAS_IOUNIT_CONTROL_REPLY, ++ *PTR_MPI2_SAS_IOUNIT_CONTROL_REPLY, ++ Mpi2SasIoUnitControlReply_t, *pMpi2SasIoUnitControlReply_t; ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +new file mode 100644 +index 0000000..5f9289a +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +@@ -0,0 +1,483 @@ ++/* ++ * Copyright 2000-2014 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_tool.h ++ * Title: MPI diagnostic tool structures and definitions ++ * Creation Date: March 26, 2007 ++ * ++ * mpi2_tool.h Version: 02.00.13 ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release ++ * structures and defines. ++ * 02-29-08 02.00.02 Modified various names to make them 32-character unique. ++ * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. ++ * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request ++ * and reply messages. ++ * Added MPI2_DIAG_BUF_TYPE_EXTENDED. ++ * Incremented MPI2_DIAG_BUF_TYPE_COUNT. ++ * 05-12-10 02.00.05 Added Diagnostic Data Upload tool. ++ * 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer ++ * Post Request. ++ * 05-25-11 02.00.07 Added Flags field and related defines to ++ * MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST. ++ * 11-18-11 02.00.08 Incorporating additions for MPI v2.5. ++ * 07-10-12 02.00.09 Add MPI v2.5 Toolbox Diagnostic CLI Tool Request ++ * message. ++ * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that ++ * it uses MPI Chain SGE as well as MPI Simple SGE. ++ * 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info. ++ * 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC. ++ * 11-18-14 02.00.13 Updated copyright information. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_TOOL_H ++#define MPI2_TOOL_H ++ ++/***************************************************************************** ++* ++* Toolbox Messages ++* ++*****************************************************************************/ ++ ++/*defines for the Tools */ ++#define MPI2_TOOLBOX_CLEAN_TOOL (0x00) ++#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) ++#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) ++#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) ++#define MPI2_TOOLBOX_BEACON_TOOL (0x05) ++#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) ++#define MPI2_TOOLBOX_TEXT_DISPLAY_TOOL (0x07) ++ ++/**************************************************************************** ++* Toolbox reply ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_REPLY { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_TOOLBOX_REPLY, *PTR_MPI2_TOOLBOX_REPLY, ++ Mpi2ToolboxReply_t, *pMpi2ToolboxReply_t; ++ ++/**************************************************************************** ++* Toolbox Clean Tool request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Flags; /*0x0C */ ++} MPI2_TOOLBOX_CLEAN_REQUEST, *PTR_MPI2_TOOLBOX_CLEAN_REQUEST, ++ Mpi2ToolboxCleanRequest_t, *pMpi2ToolboxCleanRequest_t; ++ ++/*values for the Flags field */ ++#define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000) ++#define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000) ++#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) ++#define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) ++#define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) ++#define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000) ++#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000) ++#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000) ++#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004) ++#define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002) ++#define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001) ++ ++/**************************************************************************** ++* Toolbox Memory Move request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ MPI2_SGE_SIMPLE_UNION SGL; /*0x0C */ ++} MPI2_TOOLBOX_MEM_MOVE_REQUEST, *PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST, ++ Mpi2ToolboxMemMoveRequest_t, *pMpi2ToolboxMemMoveRequest_t; ++ ++/**************************************************************************** ++* Toolbox Diagnostic Data Upload request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 SGLFlags; /*0x0C */ ++ U8 Reserved5; /*0x0D */ ++ U16 Reserved6; /*0x0E */ ++ U32 Flags; /*0x10 */ ++ U32 DataLength; /*0x14 */ ++ MPI2_SGE_SIMPLE_UNION SGL; /*0x18 */ ++} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, ++ *PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, ++ Mpi2ToolboxDiagDataUploadRequest_t, ++ *pMpi2ToolboxDiagDataUploadRequest_t; ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER { ++ U32 DiagDataLength; /*00h */ ++ U8 FormatCode; /*04h */ ++ U8 Reserved1; /*05h */ ++ U16 Reserved2; /*06h */ ++} MPI2_DIAG_DATA_UPLOAD_HEADER, *PTR_MPI2_DIAG_DATA_UPLOAD_HEADER, ++ Mpi2DiagDataUploadHeader_t, *pMpi2DiagDataUploadHeader_t; ++ ++/**************************************************************************** ++* Toolbox ISTWI Read Write Tool ++****************************************************************************/ ++ ++/*Toolbox ISTWI Read Write Tool request message */ ++typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ U8 DevIndex; /*0x14 */ ++ U8 Action; /*0x15 */ ++ U8 SGLFlags; /*0x16 */ ++ U8 Flags; /*0x17 */ ++ U16 TxDataLength; /*0x18 */ ++ U16 RxDataLength; /*0x1A */ ++ U32 Reserved8; /*0x1C */ ++ U32 Reserved9; /*0x20 */ ++ U32 Reserved10; /*0x24 */ ++ U32 Reserved11; /*0x28 */ ++ U32 Reserved12; /*0x2C */ ++ MPI2_SGE_SIMPLE_UNION SGL; /*0x30 */ ++} MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, ++ *PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, ++ Mpi2ToolboxIstwiReadWriteRequest_t, ++ *pMpi2ToolboxIstwiReadWriteRequest_t; ++ ++/*values for the Action field */ ++#define MPI2_TOOL_ISTWI_ACTION_READ_DATA (0x01) ++#define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA (0x02) ++#define MPI2_TOOL_ISTWI_ACTION_SEQUENCE (0x03) ++#define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS (0x10) ++#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) ++#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*values for the Flags field */ ++#define MPI2_TOOL_ISTWI_FLAG_AUTO_RESERVE_RELEASE (0x80) ++#define MPI2_TOOL_ISTWI_FLAG_PAGE_ADDR_MASK (0x07) ++ ++/*Toolbox ISTWI Read Write Tool reply message */ ++typedef struct _MPI2_TOOLBOX_ISTWI_REPLY { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 DevIndex; /*0x14 */ ++ U8 Action; /*0x15 */ ++ U8 IstwiStatus; /*0x16 */ ++ U8 Reserved6; /*0x17 */ ++ U16 TxDataCount; /*0x18 */ ++ U16 RxDataCount; /*0x1A */ ++} MPI2_TOOLBOX_ISTWI_REPLY, *PTR_MPI2_TOOLBOX_ISTWI_REPLY, ++ Mpi2ToolboxIstwiReply_t, *pMpi2ToolboxIstwiReply_t; ++ ++/**************************************************************************** ++* Toolbox Beacon Tool request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_BEACON_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 Reserved5; /*0x0C */ ++ U8 PhysicalPort; /*0x0D */ ++ U8 Reserved6; /*0x0E */ ++ U8 Flags; /*0x0F */ ++} MPI2_TOOLBOX_BEACON_REQUEST, *PTR_MPI2_TOOLBOX_BEACON_REQUEST, ++ Mpi2ToolboxBeaconRequest_t, *pMpi2ToolboxBeaconRequest_t; ++ ++/*values for the Flags field */ ++#define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF (0x00) ++#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01) ++ ++/**************************************************************************** ++* Toolbox Diagnostic CLI Tool ++****************************************************************************/ ++ ++#define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C) ++ ++/*MPI v2.0 Toolbox Diagnostic CLI Tool request message */ ++typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 SGLFlags; /*0x0C */ ++ U8 Reserved5; /*0x0D */ ++ U16 Reserved6; /*0x0E */ ++ U32 DataLength; /*0x10 */ ++ U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */ ++ MPI2_MPI_SGE_IO_UNION SGL; /*0x70 */ ++} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ *PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ Mpi2ToolboxDiagnosticCliRequest_t, ++ *pMpi2ToolboxDiagnosticCliRequest_t; ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*MPI v2.5 Toolbox Diagnostic CLI Tool request message */ ++typedef struct _MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 DataLength; /*0x10 */ ++ U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */ ++ MPI25_SGE_IO_UNION SGL; /* 0x70 */ ++} MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ *PTR_MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ Mpi25ToolboxDiagnosticCliRequest_t, ++ *pMpi25ToolboxDiagnosticCliRequest_t; ++ ++/*Toolbox Diagnostic CLI Tool reply message */ ++typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 ReturnedDataLength; /*0x14 */ ++} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY, ++ *PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY, ++ Mpi2ToolboxDiagnosticCliReply_t, ++ *pMpi2ToolboxDiagnosticCliReply_t; ++ ++ ++/**************************************************************************** ++* Toolbox Console Text Display Tool ++****************************************************************************/ ++ ++/* Toolbox Console Text Display Tool request message */ ++typedef struct _MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST { ++ U8 Tool; /* 0x00 */ ++ U8 Reserved1; /* 0x01 */ ++ U8 ChainOffset; /* 0x02 */ ++ U8 Function; /* 0x03 */ ++ U16 Reserved2; /* 0x04 */ ++ U8 Reserved3; /* 0x06 */ ++ U8 MsgFlags; /* 0x07 */ ++ U8 VP_ID; /* 0x08 */ ++ U8 VF_ID; /* 0x09 */ ++ U16 Reserved4; /* 0x0A */ ++ U8 Console; /* 0x0C */ ++ U8 Flags; /* 0x0D */ ++ U16 Reserved6; /* 0x0E */ ++ U8 TextToDisplay[4]; /* 0x10 */ ++} MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, ++*PTR_MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, ++Mpi2ToolboxTextDisplayRequest_t, ++*pMpi2ToolboxTextDisplayRequest_t; ++ ++/* defines for the Console field */ ++#define MPI2_TOOLBOX_CONSOLE_TYPE_MASK (0xF0) ++#define MPI2_TOOLBOX_CONSOLE_TYPE_DEFAULT (0x00) ++#define MPI2_TOOLBOX_CONSOLE_TYPE_UART (0x10) ++#define MPI2_TOOLBOX_CONSOLE_TYPE_ETHERNET (0x20) ++ ++#define MPI2_TOOLBOX_CONSOLE_NUMBER_MASK (0x0F) ++ ++/* defines for the Flags field */ ++#define MPI2_TOOLBOX_CONSOLE_FLAG_TIMESTAMP (0x01) ++ ++ ++ ++/***************************************************************************** ++* ++* Diagnostic Buffer Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* Diagnostic Buffer Post request ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST { ++ U8 ExtendedType; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U64 BufferAddress; /*0x0C */ ++ U32 BufferLength; /*0x14 */ ++ U32 Reserved5; /*0x18 */ ++ U32 Reserved6; /*0x1C */ ++ U32 Flags; /*0x20 */ ++ U32 ProductSpecific[23]; /*0x24 */ ++} MPI2_DIAG_BUFFER_POST_REQUEST, *PTR_MPI2_DIAG_BUFFER_POST_REQUEST, ++ Mpi2DiagBufferPostRequest_t, *pMpi2DiagBufferPostRequest_t; ++ ++/*values for the ExtendedType field */ ++#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02) ++ ++/*values for the BufferType field */ ++#define MPI2_DIAG_BUF_TYPE_TRACE (0x00) ++#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01) ++#define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02) ++/*count of the number of buffer types */ ++#define MPI2_DIAG_BUF_TYPE_COUNT (0x03) ++ ++/*values for the Flags field */ ++#define MPI2_DIAG_BUF_FLAG_RELEASE_ON_FULL (0x00000002) ++#define MPI2_DIAG_BUF_FLAG_IMMEDIATE_RELEASE (0x00000001) ++ ++/**************************************************************************** ++* Diagnostic Buffer Post reply ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_BUFFER_POST_REPLY { ++ U8 ExtendedType; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 TransferLength; /*0x14 */ ++} MPI2_DIAG_BUFFER_POST_REPLY, *PTR_MPI2_DIAG_BUFFER_POST_REPLY, ++ Mpi2DiagBufferPostReply_t, *pMpi2DiagBufferPostReply_t; ++ ++/**************************************************************************** ++* Diagnostic Release request ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_RELEASE_REQUEST { ++ U8 Reserved1; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++} MPI2_DIAG_RELEASE_REQUEST, *PTR_MPI2_DIAG_RELEASE_REQUEST, ++ Mpi2DiagReleaseRequest_t, *pMpi2DiagReleaseRequest_t; ++ ++/**************************************************************************** ++* Diagnostic Buffer Post reply ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_RELEASE_REPLY { ++ U8 Reserved1; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_DIAG_RELEASE_REPLY, *PTR_MPI2_DIAG_RELEASE_REPLY, ++ Mpi2DiagReleaseReply_t, *pMpi2DiagReleaseReply_t; ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_type.h b/drivers/scsi/mpt2sas/mpi/mpi2_type.h +new file mode 100644 +index 0000000..92a81ab +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_type.h +@@ -0,0 +1,57 @@ ++/* ++ * Copyright 2000-2014 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_type.h ++ * Title: MPI basic type definitions ++ * Creation Date: August 16, 2006 ++ * ++ * mpi2_type.h Version: 02.00.01 ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 11-18-14 02.00.01 Updated copyright information. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_TYPE_H ++#define MPI2_TYPE_H ++ ++/******************************************************************************* ++ * Define * if it hasn't already been defined. By default ++ * * is defined to be a near pointer. MPI2_POINTER can be defined as ++ * a far pointer by defining * as "far *" before this header file is ++ * included. ++ */ ++ ++/* the basic types may have already been included by mpi_type.h */ ++#ifndef MPI_TYPE_H ++/***************************************************************************** ++* ++* Basic Types ++* ++*****************************************************************************/ ++ ++typedef u8 U8; ++typedef __le16 U16; ++typedef __le32 U32; ++typedef __le64 U64 __attribute__ ((aligned(4))); ++ ++/***************************************************************************** ++* ++* Pointer Types ++* ++*****************************************************************************/ ++ ++typedef U8 *PU8; ++typedef U16 *PU16; ++typedef U32 *PU32; ++typedef U64 *PU64; ++ ++#endif ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpt3sas_base.c b/drivers/scsi/mpt2sas/mpt3sas_base.c +new file mode 100644 +index 0000000..224bf9d +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_base.c +@@ -0,0 +1,5713 @@ ++/* ++ * This is the Fusion MPT base driver providing common API layer interface ++ * for access to MPT (Message Passing Technology) firmware. ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include "mpt3sas_base.h" ++ ++static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; ++ ++ ++#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ ++ ++ /* maximum controller queue depth */ ++#define MAX_HBA_QUEUE_DEPTH 30000 ++#define MAX_CHAIN_DEPTH 100000 ++static int max_queue_depth = -1; ++module_param(max_queue_depth, int, 0); ++MODULE_PARM_DESC(max_queue_depth, " max controller queue depth "); ++ ++static int max_sgl_entries = -1; ++module_param(max_sgl_entries, int, 0); ++MODULE_PARM_DESC(max_sgl_entries, " max sg entries "); ++ ++static int msix_disable = -1; ++module_param(msix_disable, int, 0); ++MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); ++ ++static int smp_affinity_enable = 1; ++module_param(smp_affinity_enable, int, S_IRUGO); ++MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disbale Default: enable(1)"); ++ ++static int max_msix_vectors = -1; ++module_param(max_msix_vectors, int, 0); ++MODULE_PARM_DESC(max_msix_vectors, ++ " max msix vectors"); ++ ++static int mpt2sas_fwfault_debug; ++MODULE_PARM_DESC(mpt2sas_fwfault_debug, ++ " enable detection of firmware fault and halt firmware - (default=0)"); ++ ++static int ++_base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag); ++ ++/** ++ * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. ++ * ++ */ ++static int ++_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp) ++{ ++ int ret = param_set_int(val, kp); ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (ret) ++ return ret; ++ ++ /* global ioc spinlock to protect controller list on list operations */ ++ pr_info("setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) ++ ioc->fwfault_debug = mpt2sas_fwfault_debug; ++ spin_unlock(&gioc_lock_mpt2sas); ++ return 0; ++} ++module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug, ++ param_get_int, &mpt2sas_fwfault_debug, 0644); ++ ++/** ++ * mpt2sas_remove_dead_ioc_func - kthread context to remove dead ioc ++ * @arg: input argument, used to derive ioc ++ * ++ * Return 0 if controller is removed from pci subsystem. ++ * Return -1 for other case. ++ */ ++static int mpt2sas_remove_dead_ioc_func(void *arg) ++{ ++ struct MPT3SAS_ADAPTER *ioc = (struct MPT3SAS_ADAPTER *)arg; ++ struct pci_dev *pdev; ++ ++ if ((ioc == NULL)) ++ return -1; ++ ++ pdev = ioc->pdev; ++ if ((pdev == NULL)) ++ return -1; ++ pci_stop_and_remove_bus_device_locked(pdev); ++ return 0; ++} ++ ++/** ++ * _base_fault_reset_work - workq handling ioc fault conditions ++ * @work: input argument, used to derive ioc ++ * Context: sleep. ++ * ++ * Return nothing. ++ */ ++static void ++_base_fault_reset_work(struct work_struct *work) ++{ ++ struct MPT3SAS_ADAPTER *ioc = ++ container_of(work, struct MPT3SAS_ADAPTER, fault_reset_work.work); ++ unsigned long flags; ++ u32 doorbell; ++ int rc; ++ struct task_struct *p; ++ ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ if (ioc->shost_recovery || ioc->pci_error_recovery) ++ goto rearm_timer; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ ++ doorbell = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_MASK) { ++ pr_err(MPT3SAS_FMT "SAS host is non-operational !!!!\n", ++ ioc->name); ++ ++ /* It may be possible that EEH recovery can resolve some of ++ * pci bus failure issues rather removing the dead ioc function ++ * by considering controller is in a non-operational state. So ++ * here priority is given to the EEH recovery. If it doesn't ++ * not resolve this issue, mpt3sas driver will consider this ++ * controller to non-operational state and remove the dead ioc ++ * function. ++ */ ++ if (ioc->non_operational_loop++ < 5) { ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, ++ flags); ++ goto rearm_timer; ++ } ++ ++ /* ++ * Call _scsih_flush_pending_cmds callback so that we flush all ++ * pending commands back to OS. This call is required to aovid ++ * deadlock at block layer. Dead IOC will fail to do diag reset, ++ * and this call is safe since dead ioc will never return any ++ * command back from HW. ++ */ ++ ioc->schedule_dead_ioc_flush_running_cmds(ioc); ++ /* ++ * Set remove_host flag early since kernel thread will ++ * take some time to execute. ++ */ ++ ioc->remove_host = 1; ++ /*Remove the Dead Host */ ++ p = kthread_run(mpt2sas_remove_dead_ioc_func, ioc, ++ "%s_dead_ioc_%d", ioc->driver_name, ioc->id); ++ if (IS_ERR(p)) ++ pr_err(MPT3SAS_FMT ++ "%s: Running mpt2sas_dead_ioc thread failed !!!!\n", ++ ioc->name, __func__); ++ else ++ pr_err(MPT3SAS_FMT ++ "%s: Running mpt2sas_dead_ioc thread success !!!!\n", ++ ioc->name, __func__); ++ return; /* don't rearm timer */ ++ } ++ ++ ioc->non_operational_loop = 0; ++ ++ if ((doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) { ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ pr_warn(MPT3SAS_FMT "%s: hard reset: %s\n", ioc->name, ++ __func__, (rc == 0) ? "success" : "failed"); ++ doorbell = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) ++ mpt2sas_base_fault_info(ioc, doorbell & ++ MPI2_DOORBELL_DATA_MASK); ++ if (rc && (doorbell & MPI2_IOC_STATE_MASK) != ++ MPI2_IOC_STATE_OPERATIONAL) ++ return; /* don't rearm timer */ ++ } ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ rearm_timer: ++ if (ioc->fault_reset_work_q) ++ queue_delayed_work(ioc->fault_reset_work_q, ++ &ioc->fault_reset_work, ++ msecs_to_jiffies(FAULT_POLLING_INTERVAL)); ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++} ++ ++/** ++ * mpt2sas_base_start_watchdog - start the fault_reset_work_q ++ * @ioc: per adapter object ++ * Context: sleep. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned long flags; ++ ++ if (ioc->fault_reset_work_q) ++ return; ++ ++ /* initialize fault polling */ ++ ++ INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); ++ snprintf(ioc->fault_reset_work_q_name, ++ sizeof(ioc->fault_reset_work_q_name), "poll_%s%d_status", ++ ioc->driver_name, ioc->id); ++ ioc->fault_reset_work_q = ++ create_singlethread_workqueue(ioc->fault_reset_work_q_name); ++ if (!ioc->fault_reset_work_q) { ++ pr_err(MPT3SAS_FMT "%s: failed (line=%d)\n", ++ ioc->name, __func__, __LINE__); ++ return; ++ } ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ if (ioc->fault_reset_work_q) ++ queue_delayed_work(ioc->fault_reset_work_q, ++ &ioc->fault_reset_work, ++ msecs_to_jiffies(FAULT_POLLING_INTERVAL)); ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++} ++ ++/** ++ * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q ++ * @ioc: per adapter object ++ * Context: sleep. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned long flags; ++ struct workqueue_struct *wq; ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ wq = ioc->fault_reset_work_q; ++ ioc->fault_reset_work_q = NULL; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ if (wq) { ++ if (!cancel_delayed_work_sync(&ioc->fault_reset_work)) ++ flush_workqueue(wq); ++ destroy_workqueue(wq); ++ } ++} ++ ++/** ++ * mpt2sas_base_fault_info - verbose translation of firmware FAULT code ++ * @ioc: per adapter object ++ * @fault_code: fault code ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code) ++{ ++ pr_err(MPT3SAS_FMT "fault_state(0x%04x)!\n", ++ ioc->name, fault_code); ++} ++ ++/** ++ * mpt2sas_halt_firmware - halt's mpt controller firmware ++ * @ioc: per adapter object ++ * ++ * For debugging timeout related issues. Writing 0xCOFFEE00 ++ * to the doorbell register will halt controller firmware. With ++ * the purpose to stop both driver and firmware, the enduser can ++ * obtain a ring buffer from controller UART. ++ */ ++void ++mpt2sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 doorbell; ++ ++ if (!ioc->fwfault_debug) ++ return; ++ ++ dump_stack(); ++ ++ doorbell = readl(&ioc->chip->Doorbell); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) ++ mpt2sas_base_fault_info(ioc , doorbell); ++ else { ++ writel(0xC0FFEE00, &ioc->chip->Doorbell); ++ pr_err(MPT3SAS_FMT "Firmware is halted due to command timeout\n", ++ ioc->name); ++ } ++ ++ if (ioc->fwfault_debug == 2) ++ for (;;) ++ ; ++ else ++ panic("panic in %s\n", __func__); ++} ++ ++/** ++ * _base_sas_ioc_info - verbose translation of the ioc status ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @request_hdr: request mf ++ * ++ * Return nothing. ++ */ ++static void ++_base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply, ++ MPI2RequestHeader_t *request_hdr) ++{ ++ u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ char *desc = NULL; ++ u16 frame_sz; ++ char *func_str = NULL; ++ ++ /* SCSI_IO, RAID_PASS are handled from _scsih_scsi_ioc_info */ ++ if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ request_hdr->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || ++ request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION) ++ return; ++ ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ return; ++ ++ switch (ioc_status) { ++ ++/**************************************************************************** ++* Common IOCStatus values for all replies ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_INVALID_FUNCTION: ++ desc = "invalid function"; ++ break; ++ case MPI2_IOCSTATUS_BUSY: ++ desc = "busy"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_SGL: ++ desc = "invalid sgl"; ++ break; ++ case MPI2_IOCSTATUS_INTERNAL_ERROR: ++ desc = "internal error"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_VPID: ++ desc = "invalid vpid"; ++ break; ++ case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: ++ desc = "insufficient resources"; ++ break; ++ case MPI2_IOCSTATUS_INSUFFICIENT_POWER: ++ desc = "insufficient power"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_FIELD: ++ desc = "invalid field"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_STATE: ++ desc = "invalid state"; ++ break; ++ case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED: ++ desc = "op state not supported"; ++ break; ++ ++/**************************************************************************** ++* Config IOCStatus values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION: ++ desc = "config invalid action"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE: ++ desc = "config invalid type"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE: ++ desc = "config invalid page"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_INVALID_DATA: ++ desc = "config invalid data"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS: ++ desc = "config no defaults"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT: ++ desc = "config cant commit"; ++ break; ++ ++/**************************************************************************** ++* SCSI IO Reply ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: ++ case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE: ++ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: ++ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: ++ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: ++ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: ++ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: ++ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: ++ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: ++ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED: ++ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: ++ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: ++ break; ++ ++/**************************************************************************** ++* For use by SCSI Initiator and SCSI Target end-to-end data protection ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ desc = "eedp guard error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ desc = "eedp ref tag error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ desc = "eedp app tag error"; ++ break; ++ ++/**************************************************************************** ++* SCSI Target values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX: ++ desc = "target invalid io index"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_ABORTED: ++ desc = "target aborted"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: ++ desc = "target no conn retryable"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_NO_CONNECTION: ++ desc = "target no connection"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: ++ desc = "target xfer count mismatch"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: ++ desc = "target data offset error"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: ++ desc = "target too much write data"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT: ++ desc = "target iu too short"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: ++ desc = "target ack nak timeout"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_NAK_RECEIVED: ++ desc = "target nak received"; ++ break; ++ ++/**************************************************************************** ++* Serial Attached SCSI values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: ++ desc = "smp request failed"; ++ break; ++ case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: ++ desc = "smp data overrun"; ++ break; ++ ++/**************************************************************************** ++* Diagnostic Buffer Post / Diagnostic Release values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED: ++ desc = "diagnostic released"; ++ break; ++ default: ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ switch (request_hdr->Function) { ++ case MPI2_FUNCTION_CONFIG: ++ frame_sz = sizeof(Mpi2ConfigRequest_t) + ioc->sge_size; ++ func_str = "config_page"; ++ break; ++ case MPI2_FUNCTION_SCSI_TASK_MGMT: ++ frame_sz = sizeof(Mpi2SCSITaskManagementRequest_t); ++ func_str = "task_mgmt"; ++ break; ++ case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: ++ frame_sz = sizeof(Mpi2SasIoUnitControlRequest_t); ++ func_str = "sas_iounit_ctl"; ++ break; ++ case MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: ++ frame_sz = sizeof(Mpi2SepRequest_t); ++ func_str = "enclosure"; ++ break; ++ case MPI2_FUNCTION_IOC_INIT: ++ frame_sz = sizeof(Mpi2IOCInitRequest_t); ++ func_str = "ioc_init"; ++ break; ++ case MPI2_FUNCTION_PORT_ENABLE: ++ frame_sz = sizeof(Mpi2PortEnableRequest_t); ++ func_str = "port_enable"; ++ break; ++ case MPI2_FUNCTION_SMP_PASSTHROUGH: ++ frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size; ++ func_str = "smp_passthru"; ++ break; ++ default: ++ frame_sz = 32; ++ func_str = "unknown"; ++ break; ++ } ++ ++ pr_warn(MPT3SAS_FMT "ioc_status: %s(0x%04x), request(0x%p),(%s)\n", ++ ioc->name, desc, ioc_status, request_hdr, func_str); ++ ++ _debug_dump_mf(request_hdr, frame_sz/4); ++} ++ ++/** ++ * _base_display_event_data - verbose translation of firmware asyn events ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_event_data(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventNotificationReply_t *mpi_reply) ++{ ++ char *desc = NULL; ++ u16 event; ++ ++ if (!(ioc->logging_level & MPT_DEBUG_EVENTS)) ++ return; ++ ++ event = le16_to_cpu(mpi_reply->Event); ++ ++ switch (event) { ++ case MPI2_EVENT_LOG_DATA: ++ desc = "Log Data"; ++ break; ++ case MPI2_EVENT_STATE_CHANGE: ++ desc = "Status Change"; ++ break; ++ case MPI2_EVENT_HARD_RESET_RECEIVED: ++ desc = "Hard Reset Received"; ++ break; ++ case MPI2_EVENT_EVENT_CHANGE: ++ desc = "Event Change"; ++ break; ++ case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: ++ desc = "Device Status Change"; ++ break; ++ case MPI2_EVENT_IR_OPERATION_STATUS: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Operation Status"; ++ break; ++ case MPI2_EVENT_SAS_DISCOVERY: ++ { ++ Mpi2EventDataSasDiscovery_t *event_data = ++ (Mpi2EventDataSasDiscovery_t *)mpi_reply->EventData; ++ pr_info(MPT3SAS_FMT "Discovery: (%s)", ioc->name, ++ (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? ++ "start" : "stop"); ++ if (event_data->DiscoveryStatus) ++ pr_info("discovery_status(0x%08x)", ++ le32_to_cpu(event_data->DiscoveryStatus)); ++ pr_info("\n"); ++ return; ++ } ++ case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: ++ desc = "SAS Broadcast Primitive"; ++ break; ++ case MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: ++ desc = "SAS Init Device Status Change"; ++ break; ++ case MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW: ++ desc = "SAS Init Table Overflow"; ++ break; ++ case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: ++ desc = "SAS Topology Change List"; ++ break; ++ case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: ++ desc = "SAS Enclosure Device Status Change"; ++ break; ++ case MPI2_EVENT_IR_VOLUME: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Volume"; ++ break; ++ case MPI2_EVENT_IR_PHYSICAL_DISK: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Physical Disk"; ++ break; ++ case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Configuration Change List"; ++ break; ++ case MPI2_EVENT_LOG_ENTRY_ADDED: ++ if (!ioc->hide_ir_msg) ++ desc = "Log Entry Added"; ++ break; ++ case MPI2_EVENT_TEMP_THRESHOLD: ++ desc = "Temperature Threshold"; ++ break; ++ case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION: ++ desc = "Active cable exception"; ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, desc); ++} ++ ++/** ++ * _base_sas_log_info - verbose translation of firmware log info ++ * @ioc: per adapter object ++ * @log_info: log info ++ * ++ * Return nothing. ++ */ ++static void ++_base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info) ++{ ++ union loginfo_type { ++ u32 loginfo; ++ struct { ++ u32 subcode:16; ++ u32 code:8; ++ u32 originator:4; ++ u32 bus_type:4; ++ } dw; ++ }; ++ union loginfo_type sas_loginfo; ++ char *originator_str = NULL; ++ ++ sas_loginfo.loginfo = log_info; ++ if (sas_loginfo.dw.bus_type != 3 /*SAS*/) ++ return; ++ ++ /* each nexus loss loginfo */ ++ if (log_info == 0x31170000) ++ return; ++ ++ /* eat the loginfos associated with task aborts */ ++ if (ioc->ignore_loginfos && (log_info == 0x30050000 || log_info == ++ 0x31140000 || log_info == 0x31130000)) ++ return; ++ ++ switch (sas_loginfo.dw.originator) { ++ case 0: ++ originator_str = "IOP"; ++ break; ++ case 1: ++ originator_str = "PL"; ++ break; ++ case 2: ++ if (!ioc->hide_ir_msg) ++ originator_str = "IR"; ++ else ++ originator_str = "WarpDrive"; ++ break; ++ } ++ ++ pr_warn(MPT3SAS_FMT ++ "log_info(0x%08x): originator(%s), code(0x%02x), sub_code(0x%04x)\n", ++ ioc->name, log_info, ++ originator_str, sas_loginfo.dw.code, ++ sas_loginfo.dw.subcode); ++} ++ ++/** ++ * _base_display_reply_info - ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_reply_info(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ u16 ioc_status; ++ u32 loginfo = 0; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus); ++ ++ if ((ioc_status & MPI2_IOCSTATUS_MASK) && ++ (ioc->logging_level & MPT_DEBUG_REPLY)) { ++ _base_sas_ioc_info(ioc , mpi_reply, ++ mpt2sas_base_get_msg_frame(ioc, smid)); ++ } ++ ++ if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { ++ loginfo = le32_to_cpu(mpi_reply->IOCLogInfo); ++ _base_sas_log_info(ioc, loginfo); ++ } ++ ++ if (ioc_status || loginfo) { ++ ioc_status &= MPI2_IOCSTATUS_MASK; ++ mpt2sas_trigger_mpi(ioc, ioc_status, loginfo); ++ } ++} ++ ++/** ++ * mpt2sas_base_done - base internal command completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_base_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK) ++ return mpt2sas_check_for_pending_internal_cmds(ioc, smid); ++ ++ if (ioc->base_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ ++ ioc->base_cmds.status |= MPT3_CMD_COMPLETE; ++ if (mpi_reply) { ++ ioc->base_cmds.status |= MPT3_CMD_REPLY_VALID; ++ memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ } ++ ioc->base_cmds.status &= ~MPT3_CMD_PENDING; ++ ++ complete(&ioc->base_cmds.done); ++ return 1; ++} ++ ++/** ++ * _base_async_event - main callback handler for firmware asyn events ++ * @ioc: per adapter object ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply) ++{ ++ Mpi2EventNotificationReply_t *mpi_reply; ++ Mpi2EventAckRequest_t *ack_request; ++ u16 smid; ++ struct _event_ack_list *delayed_event_ack; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (!mpi_reply) ++ return 1; ++ if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION) ++ return 1; ++ ++ _base_display_event_data(ioc, mpi_reply); ++ ++ if (!(mpi_reply->AckRequired & MPI2_EVENT_NOTIFICATION_ACK_REQUIRED)) ++ goto out; ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ delayed_event_ack = kzalloc(sizeof(*delayed_event_ack), ++ GFP_ATOMIC); ++ if (!delayed_event_ack) ++ goto out; ++ INIT_LIST_HEAD(&delayed_event_ack->list); ++ delayed_event_ack->Event = mpi_reply->Event; ++ delayed_event_ack->EventContext = mpi_reply->EventContext; ++ list_add_tail(&delayed_event_ack->list, ++ &ioc->delayed_event_ack_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED: EVENT ACK: event (0x%04x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->Event))); ++ goto out; ++ } ++ ++ ack_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t)); ++ ack_request->Function = MPI2_FUNCTION_EVENT_ACK; ++ ack_request->Event = mpi_reply->Event; ++ ack_request->EventContext = mpi_reply->EventContext; ++ ack_request->VF_ID = 0; /* TODO */ ++ ack_request->VP_ID = 0; ++ mpt2sas_base_put_smid_default(ioc, smid); ++ ++ out: ++ ++ /* scsih callback handler */ ++ mpt2sas_scsih_event_callback(ioc, msix_index, reply); ++ ++ /* ctl callback handler */ ++ mpt2sas_ctl_event_callback(ioc, msix_index, reply); ++ ++ return 1; ++} ++ ++/** ++ * _base_get_cb_idx - obtain the callback index ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return callback index. ++ */ ++static u8 ++_base_get_cb_idx(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ int i; ++ u8 cb_idx; ++ ++ if (smid < ioc->hi_priority_smid) { ++ i = smid - 1; ++ cb_idx = ioc->scsi_lookup[i].cb_idx; ++ } else if (smid < ioc->internal_smid) { ++ i = smid - ioc->hi_priority_smid; ++ cb_idx = ioc->hpr_lookup[i].cb_idx; ++ } else if (smid <= ioc->hba_queue_depth) { ++ i = smid - ioc->internal_smid; ++ cb_idx = ioc->internal_lookup[i].cb_idx; ++ } else ++ cb_idx = 0xFF; ++ return cb_idx; ++} ++ ++/** ++ * _base_mask_interrupts - disable interrupts ++ * @ioc: per adapter object ++ * ++ * Disabling ResetIRQ, Reply and Doorbell Interrupts ++ * ++ * Return nothing. ++ */ ++static void ++_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 him_register; ++ ++ ioc->mask_interrupts = 1; ++ him_register = readl(&ioc->chip->HostInterruptMask); ++ him_register |= MPI2_HIM_DIM + MPI2_HIM_RIM + MPI2_HIM_RESET_IRQ_MASK; ++ writel(him_register, &ioc->chip->HostInterruptMask); ++ readl(&ioc->chip->HostInterruptMask); ++} ++ ++/** ++ * _base_unmask_interrupts - enable interrupts ++ * @ioc: per adapter object ++ * ++ * Enabling only Reply Interrupts ++ * ++ * Return nothing. ++ */ ++static void ++_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 him_register; ++ ++ him_register = readl(&ioc->chip->HostInterruptMask); ++ him_register &= ~MPI2_HIM_RIM; ++ writel(him_register, &ioc->chip->HostInterruptMask); ++ ioc->mask_interrupts = 0; ++} ++ ++union reply_descriptor { ++ u64 word; ++ struct { ++ u32 low; ++ u32 high; ++ } u; ++}; ++ ++/** ++ * _base_interrupt - MPT adapter (IOC) specific interrupt handler. ++ * @irq: irq number (not used) ++ * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure ++ * @r: pt_regs pointer (not used) ++ * ++ * Return IRQ_HANDLE if processed, else IRQ_NONE. ++ */ ++static irqreturn_t ++_base_interrupt(int irq, void *bus_id) ++{ ++ struct adapter_reply_queue *reply_q = bus_id; ++ union reply_descriptor rd; ++ u32 completed_cmds; ++ u8 request_desript_type; ++ u16 smid; ++ u8 cb_idx; ++ u32 reply; ++ u8 msix_index = reply_q->msix_index; ++ struct MPT3SAS_ADAPTER *ioc = reply_q->ioc; ++ Mpi2ReplyDescriptorsUnion_t *rpf; ++ u8 rc; ++ ++ if (ioc->mask_interrupts) ++ return IRQ_NONE; ++ ++ if (!atomic_add_unless(&reply_q->busy, 1, 1)) ++ return IRQ_NONE; ++ ++ rpf = &reply_q->reply_post_free[reply_q->reply_post_host_index]; ++ request_desript_type = rpf->Default.ReplyFlags ++ & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; ++ if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { ++ atomic_dec(&reply_q->busy); ++ return IRQ_NONE; ++ } ++ ++ completed_cmds = 0; ++ cb_idx = 0xFF; ++ do { ++ rd.word = le64_to_cpu(rpf->Words); ++ if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) ++ goto out; ++ reply = 0; ++ smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); ++ if (request_desript_type == ++ MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS || ++ request_desript_type == ++ MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { ++ cb_idx = _base_get_cb_idx(ioc, smid); ++ if ((likely(cb_idx < MPT_MAX_CALLBACKS)) && ++ (likely(mpt_callbacks[cb_idx] != NULL))) { ++ rc = mpt_callbacks[cb_idx](ioc, smid, ++ msix_index, 0); ++ if (rc) ++ mpt2sas_base_free_smid(ioc, smid); ++ } ++ } else if (request_desript_type == ++ MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { ++ reply = le32_to_cpu( ++ rpf->AddressReply.ReplyFrameAddress); ++ if (reply > ioc->reply_dma_max_address || ++ reply < ioc->reply_dma_min_address) ++ reply = 0; ++ if (smid) { ++ cb_idx = _base_get_cb_idx(ioc, smid); ++ if ((likely(cb_idx < MPT_MAX_CALLBACKS)) && ++ (likely(mpt_callbacks[cb_idx] != NULL))) { ++ rc = mpt_callbacks[cb_idx](ioc, smid, ++ msix_index, reply); ++ if (reply) ++ _base_display_reply_info(ioc, ++ smid, msix_index, reply); ++ if (rc) ++ mpt2sas_base_free_smid(ioc, ++ smid); ++ } ++ } else { ++ _base_async_event(ioc, msix_index, reply); ++ } ++ ++ /* reply free queue handling */ ++ if (reply) { ++ ioc->reply_free_host_index = ++ (ioc->reply_free_host_index == ++ (ioc->reply_free_queue_depth - 1)) ? ++ 0 : ioc->reply_free_host_index + 1; ++ ioc->reply_free[ioc->reply_free_host_index] = ++ cpu_to_le32(reply); ++ wmb(); ++ writel(ioc->reply_free_host_index, ++ &ioc->chip->ReplyFreeHostIndex); ++ } ++ } ++ ++ rpf->Words = cpu_to_le64(ULLONG_MAX); ++ reply_q->reply_post_host_index = ++ (reply_q->reply_post_host_index == ++ (ioc->reply_post_queue_depth - 1)) ? 0 : ++ reply_q->reply_post_host_index + 1; ++ request_desript_type = ++ reply_q->reply_post_free[reply_q->reply_post_host_index]. ++ Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; ++ completed_cmds++; ++ if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) ++ goto out; ++ if (!reply_q->reply_post_host_index) ++ rpf = reply_q->reply_post_free; ++ else ++ rpf++; ++ } while (1); ++ ++ out: ++ ++ if (!completed_cmds) { ++ atomic_dec(&reply_q->busy); ++ return IRQ_NONE; ++ } ++ ++ wmb(); ++ if (ioc->is_warpdrive) { ++ writel(reply_q->reply_post_host_index, ++ ioc->reply_post_host_index[msix_index]); ++ atomic_dec(&reply_q->busy); ++ return IRQ_HANDLED; ++ } ++ ++ /* Update Reply Post Host Index. ++ * For those HBA's which support combined reply queue feature ++ * 1. Get the correct Supplemental Reply Post Host Index Register. ++ * i.e. (msix_index / 8)th entry from Supplemental Reply Post Host ++ * Index Register address bank i.e replyPostRegisterIndex[], ++ * 2. Then update this register with new reply host index value ++ * in ReplyPostIndex field and the MSIxIndex field with ++ * msix_index value reduced to a value between 0 and 7, ++ * using a modulo 8 operation. Since each Supplemental Reply Post ++ * Host Index Register supports 8 MSI-X vectors. ++ * ++ * For other HBA's just update the Reply Post Host Index register with ++ * new reply host index value in ReplyPostIndex Field and msix_index ++ * value in MSIxIndex field. ++ */ ++ if (ioc->msix96_vector) ++ writel(reply_q->reply_post_host_index | ((msix_index & 7) << ++ MPI2_RPHI_MSIX_INDEX_SHIFT), ++ ioc->replyPostRegisterIndex[msix_index/8]); ++ else ++ writel(reply_q->reply_post_host_index | (msix_index << ++ MPI2_RPHI_MSIX_INDEX_SHIFT), ++ &ioc->chip->ReplyPostHostIndex); ++ atomic_dec(&reply_q->busy); ++ return IRQ_HANDLED; ++} ++ ++/** ++ * _base_is_controller_msix_enabled - is controller support muli-reply queues ++ * @ioc: per adapter object ++ * ++ */ ++static inline int ++_base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc) ++{ ++ return (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable; ++} ++ ++/** ++ * mpt2sas_base_sync_reply_irqs - flush pending MSIX interrupts ++ * @ioc: per adapter object ++ * Context: non ISR conext ++ * ++ * Called when a Task Management request has completed. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct adapter_reply_queue *reply_q; ++ ++ /* If MSIX capability is turned off ++ * then multi-queues are not enabled ++ */ ++ if (!_base_is_controller_msix_enabled(ioc)) ++ return; ++ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) ++ return; ++ /* TMs are on msix_index == 0 */ ++ if (reply_q->msix_index == 0) ++ continue; ++ synchronize_irq(reply_q->vector); ++ } ++} ++ ++/** ++ * mpt2sas_base_release_callback_handler - clear interrupt callback handler ++ * @cb_idx: callback index ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_release_callback_handler(u8 cb_idx) ++{ ++ mpt_callbacks[cb_idx] = NULL; ++} ++ ++/** ++ * mpt2sas_base_register_callback_handler - obtain index for the interrupt callback handler ++ * @cb_func: callback function ++ * ++ * Returns cb_func. ++ */ ++u8 ++mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func) ++{ ++ u8 cb_idx; ++ ++ for (cb_idx = MPT_MAX_CALLBACKS-1; cb_idx; cb_idx--) ++ if (mpt_callbacks[cb_idx] == NULL) ++ break; ++ ++ mpt_callbacks[cb_idx] = cb_func; ++ return cb_idx; ++} ++ ++/** ++ * mpt2sas_base_initialize_callback_handler - initialize the interrupt callback handler ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_initialize_callback_handler(void) ++{ ++ u8 cb_idx; ++ ++ for (cb_idx = 0; cb_idx < MPT_MAX_CALLBACKS; cb_idx++) ++ mpt2sas_base_release_callback_handler(cb_idx); ++} ++ ++ ++/** ++ * _base_build_zero_len_sge - build zero length sg entry ++ * @ioc: per adapter object ++ * @paddr: virtual address for SGE ++ * ++ * Create a zero length scatter gather entry to insure the IOCs hardware has ++ * something to use if the target device goes brain dead and tries ++ * to send data even when none is asked for. ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_zero_len_sge(struct MPT3SAS_ADAPTER *ioc, void *paddr) ++{ ++ u32 flags_length = (u32)((MPI2_SGE_FLAGS_LAST_ELEMENT | ++ MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST | ++ MPI2_SGE_FLAGS_SIMPLE_ELEMENT) << ++ MPI2_SGE_FLAGS_SHIFT); ++ ioc->base_add_sg_single(paddr, flags_length, -1); ++} ++ ++/** ++ * _base_add_sg_single_32 - Place a simple 32 bit SGE at address pAddr. ++ * @paddr: virtual address for SGE ++ * @flags_length: SGE flags and data transfer length ++ * @dma_addr: Physical address ++ * ++ * Return nothing. ++ */ ++static void ++_base_add_sg_single_32(void *paddr, u32 flags_length, dma_addr_t dma_addr) ++{ ++ Mpi2SGESimple32_t *sgel = paddr; ++ ++ flags_length |= (MPI2_SGE_FLAGS_32_BIT_ADDRESSING | ++ MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT; ++ sgel->FlagsLength = cpu_to_le32(flags_length); ++ sgel->Address = cpu_to_le32(dma_addr); ++} ++ ++ ++/** ++ * _base_add_sg_single_64 - Place a simple 64 bit SGE at address pAddr. ++ * @paddr: virtual address for SGE ++ * @flags_length: SGE flags and data transfer length ++ * @dma_addr: Physical address ++ * ++ * Return nothing. ++ */ ++static void ++_base_add_sg_single_64(void *paddr, u32 flags_length, dma_addr_t dma_addr) ++{ ++ Mpi2SGESimple64_t *sgel = paddr; ++ ++ flags_length |= (MPI2_SGE_FLAGS_64_BIT_ADDRESSING | ++ MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT; ++ sgel->FlagsLength = cpu_to_le32(flags_length); ++ sgel->Address = cpu_to_le64(dma_addr); ++} ++ ++/** ++ * _base_get_chain_buffer_tracker - obtain chain tracker ++ * @ioc: per adapter object ++ * @smid: smid associated to an IO request ++ * ++ * Returns chain tracker(from ioc->free_chain_list) ++ */ ++static struct chain_tracker * ++_base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ struct chain_tracker *chain_req; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->free_chain_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "chain buffers not available\n", ioc->name)); ++ return NULL; ++ } ++ chain_req = list_entry(ioc->free_chain_list.next, ++ struct chain_tracker, tracker_list); ++ list_del_init(&chain_req->tracker_list); ++ list_add_tail(&chain_req->tracker_list, ++ &ioc->scsi_lookup[smid - 1].chain_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return chain_req; ++} ++ ++ ++/** ++ * _base_build_sg - build generic sg ++ * @ioc: per adapter object ++ * @psge: virtual address for SGE ++ * @data_out_dma: physical address for WRITES ++ * @data_out_sz: data xfer size for WRITES ++ * @data_in_dma: physical address for READS ++ * @data_in_sz: data xfer size for READS ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge, ++ dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma, ++ size_t data_in_sz) ++{ ++ u32 sgl_flags; ++ ++ if (!data_out_sz && !data_in_sz) { ++ _base_build_zero_len_sge(ioc, psge); ++ return; ++ } ++ ++ if (data_out_sz && data_in_sz) { ++ /* WRITE sgel first */ ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_out_sz, data_out_dma); ++ ++ /* incr sgel */ ++ psge += ioc->sge_size; ++ ++ /* READ sgel last */ ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | ++ MPI2_SGE_FLAGS_END_OF_LIST); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_in_sz, data_in_dma); ++ } else if (data_out_sz) /* WRITE */ { ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | ++ MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_out_sz, data_out_dma); ++ } else if (data_in_sz) /* READ */ { ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | ++ MPI2_SGE_FLAGS_END_OF_LIST); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_in_sz, data_in_dma); ++ } ++} ++ ++/* IEEE format sgls */ ++ ++/** ++ * _base_add_sg_single_ieee - add sg element for IEEE format ++ * @paddr: virtual address for SGE ++ * @flags: SGE flags ++ * @chain_offset: number of 128 byte elements from start of segment ++ * @length: data transfer length ++ * @dma_addr: Physical address ++ * ++ * Return nothing. ++ */ ++static void ++_base_add_sg_single_ieee(void *paddr, u8 flags, u8 chain_offset, u32 length, ++ dma_addr_t dma_addr) ++{ ++ Mpi25IeeeSgeChain64_t *sgel = paddr; ++ ++ sgel->Flags = flags; ++ sgel->NextChainOffset = chain_offset; ++ sgel->Length = cpu_to_le32(length); ++ sgel->Address = cpu_to_le64(dma_addr); ++} ++ ++/** ++ * _base_build_zero_len_sge_ieee - build zero length sg entry for IEEE format ++ * @ioc: per adapter object ++ * @paddr: virtual address for SGE ++ * ++ * Create a zero length scatter gather entry to insure the IOCs hardware has ++ * something to use if the target device goes brain dead and tries ++ * to send data even when none is asked for. ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr) ++{ ++ u8 sgl_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST); ++ ++ _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); ++} ++ ++/** ++ * _base_build_sg_scmd - main sg creation routine ++ * @ioc: per adapter object ++ * @scmd: scsi command ++ * @smid: system request message index ++ * Context: none. ++ * ++ * The main routine that builds scatter gather table from a given ++ * scsi request sent via the .queuecommand main handler. ++ * ++ * Returns 0 success, anything else error ++ */ ++static int ++_base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_cmnd *scmd, u16 smid) ++{ ++ Mpi2SCSIIORequest_t *mpi_request; ++ dma_addr_t chain_dma; ++ struct scatterlist *sg_scmd; ++ void *sg_local, *chain; ++ u32 chain_offset; ++ u32 chain_length; ++ u32 chain_flags; ++ int sges_left; ++ u32 sges_in_segment; ++ u32 sgl_flags; ++ u32 sgl_flags_last_element; ++ u32 sgl_flags_end_buffer; ++ struct chain_tracker *chain_req; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ++ /* init scatter gather flags */ ++ sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT; ++ if (scmd->sc_data_direction == DMA_TO_DEVICE) ++ sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC; ++ sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT) ++ << MPI2_SGE_FLAGS_SHIFT; ++ sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT | ++ MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST) ++ << MPI2_SGE_FLAGS_SHIFT; ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ++ sg_scmd = scsi_sglist(scmd); ++ sges_left = scsi_dma_map(scmd); ++ if (sges_left < 0) { ++ sdev_printk(KERN_ERR, scmd->device, ++ "pci_map_sg failed: request for %d bytes!\n", ++ scsi_bufflen(scmd)); ++ return -ENOMEM; ++ } ++ ++ sg_local = &mpi_request->SGL; ++ sges_in_segment = ioc->max_sges_in_main_message; ++ if (sges_left <= sges_in_segment) ++ goto fill_in_last_segment; ++ ++ mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) + ++ (sges_in_segment * ioc->sge_size))/4; ++ ++ /* fill in main message segment when there is a chain following */ ++ while (sges_in_segment) { ++ if (sges_in_segment == 1) ++ ioc->base_add_sg_single(sg_local, ++ sgl_flags_last_element | sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ else ++ ioc->base_add_sg_single(sg_local, sgl_flags | ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ /* initializing the chain flags and pointers */ ++ chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT; ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ do { ++ sges_in_segment = (sges_left <= ++ ioc->max_sges_in_chain_message) ? sges_left : ++ ioc->max_sges_in_chain_message; ++ chain_offset = (sges_left == sges_in_segment) ? ++ 0 : (sges_in_segment * ioc->sge_size)/4; ++ chain_length = sges_in_segment * ioc->sge_size; ++ if (chain_offset) { ++ chain_offset = chain_offset << ++ MPI2_SGE_CHAIN_OFFSET_SHIFT; ++ chain_length += ioc->sge_size; ++ } ++ ioc->base_add_sg_single(sg_local, chain_flags | chain_offset | ++ chain_length, chain_dma); ++ sg_local = chain; ++ if (!chain_offset) ++ goto fill_in_last_segment; ++ ++ /* fill in chain segments */ ++ while (sges_in_segment) { ++ if (sges_in_segment == 1) ++ ioc->base_add_sg_single(sg_local, ++ sgl_flags_last_element | ++ sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ else ++ ioc->base_add_sg_single(sg_local, sgl_flags | ++ sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ } while (1); ++ ++ ++ fill_in_last_segment: ++ ++ /* fill the last segment */ ++ while (sges_left) { ++ if (sges_left == 1) ++ ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer | ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ else ++ ioc->base_add_sg_single(sg_local, sgl_flags | ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size; ++ sges_left--; ++ } ++ ++ return 0; ++} ++ ++/** ++ * _base_build_sg_scmd_ieee - main sg creation routine for IEEE format ++ * @ioc: per adapter object ++ * @scmd: scsi command ++ * @smid: system request message index ++ * Context: none. ++ * ++ * The main routine that builds scatter gather table from a given ++ * scsi request sent via the .queuecommand main handler. ++ * ++ * Returns 0 success, anything else error ++ */ ++static int ++_base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_cmnd *scmd, u16 smid) ++{ ++ Mpi2SCSIIORequest_t *mpi_request; ++ dma_addr_t chain_dma; ++ struct scatterlist *sg_scmd; ++ void *sg_local, *chain; ++ u32 chain_offset; ++ u32 chain_length; ++ int sges_left; ++ u32 sges_in_segment; ++ u8 simple_sgl_flags; ++ u8 simple_sgl_flags_last; ++ u8 chain_sgl_flags; ++ struct chain_tracker *chain_req; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ++ /* init scatter gather flags */ ++ simple_sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ simple_sgl_flags_last = simple_sgl_flags | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST; ++ chain_sgl_flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ ++ sg_scmd = scsi_sglist(scmd); ++ sges_left = scsi_dma_map(scmd); ++ if (sges_left < 0) { ++ sdev_printk(KERN_ERR, scmd->device, ++ "pci_map_sg failed: request for %d bytes!\n", ++ scsi_bufflen(scmd)); ++ return -ENOMEM; ++ } ++ ++ sg_local = &mpi_request->SGL; ++ sges_in_segment = (ioc->request_sz - ++ offsetof(Mpi2SCSIIORequest_t, SGL))/ioc->sge_size_ieee; ++ if (sges_left <= sges_in_segment) ++ goto fill_in_last_segment; ++ ++ mpi_request->ChainOffset = (sges_in_segment - 1 /* chain element */) + ++ (offsetof(Mpi2SCSIIORequest_t, SGL)/ioc->sge_size_ieee); ++ ++ /* fill in main message segment when there is a chain following */ ++ while (sges_in_segment > 1) { ++ _base_add_sg_single_ieee(sg_local, simple_sgl_flags, 0, ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size_ieee; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ /* initializing the pointers */ ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ do { ++ sges_in_segment = (sges_left <= ++ ioc->max_sges_in_chain_message) ? sges_left : ++ ioc->max_sges_in_chain_message; ++ chain_offset = (sges_left == sges_in_segment) ? ++ 0 : sges_in_segment; ++ chain_length = sges_in_segment * ioc->sge_size_ieee; ++ if (chain_offset) ++ chain_length += ioc->sge_size_ieee; ++ _base_add_sg_single_ieee(sg_local, chain_sgl_flags, ++ chain_offset, chain_length, chain_dma); ++ ++ sg_local = chain; ++ if (!chain_offset) ++ goto fill_in_last_segment; ++ ++ /* fill in chain segments */ ++ while (sges_in_segment) { ++ _base_add_sg_single_ieee(sg_local, simple_sgl_flags, 0, ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size_ieee; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ } while (1); ++ ++ ++ fill_in_last_segment: ++ ++ /* fill the last segment */ ++ while (sges_left > 0) { ++ if (sges_left == 1) ++ _base_add_sg_single_ieee(sg_local, ++ simple_sgl_flags_last, 0, sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ else ++ _base_add_sg_single_ieee(sg_local, simple_sgl_flags, 0, ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size_ieee; ++ sges_left--; ++ } ++ ++ return 0; ++} ++ ++/** ++ * _base_build_sg_ieee - build generic sg for IEEE format ++ * @ioc: per adapter object ++ * @psge: virtual address for SGE ++ * @data_out_dma: physical address for WRITES ++ * @data_out_sz: data xfer size for WRITES ++ * @data_in_dma: physical address for READS ++ * @data_in_sz: data xfer size for READS ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_sg_ieee(struct MPT3SAS_ADAPTER *ioc, void *psge, ++ dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma, ++ size_t data_in_sz) ++{ ++ u8 sgl_flags; ++ ++ if (!data_out_sz && !data_in_sz) { ++ _base_build_zero_len_sge_ieee(ioc, psge); ++ return; ++ } ++ ++ if (data_out_sz && data_in_sz) { ++ /* WRITE sgel first */ ++ sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_out_sz, ++ data_out_dma); ++ ++ /* incr sgel */ ++ psge += ioc->sge_size_ieee; ++ ++ /* READ sgel last */ ++ sgl_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_in_sz, ++ data_in_dma); ++ } else if (data_out_sz) /* WRITE */ { ++ sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_out_sz, ++ data_out_dma); ++ } else if (data_in_sz) /* READ */ { ++ sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_in_sz, ++ data_in_dma); ++ } ++} ++ ++#define convert_to_kb(x) ((x) << (PAGE_SHIFT - 10)) ++ ++/** ++ * _base_config_dma_addressing - set dma addressing ++ * @ioc: per adapter object ++ * @pdev: PCI device struct ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) ++{ ++ struct sysinfo s; ++ u64 consistent_dma_mask; ++ ++ if (ioc->dma_mask) ++ consistent_dma_mask = DMA_BIT_MASK(64); ++ else ++ consistent_dma_mask = DMA_BIT_MASK(32); ++ ++ if (sizeof(dma_addr_t) > 4) { ++ const uint64_t required_mask = ++ dma_get_required_mask(&pdev->dev); ++ if ((required_mask > DMA_BIT_MASK(32)) && ++ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && ++ !pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) { ++ ioc->base_add_sg_single = &_base_add_sg_single_64; ++ ioc->sge_size = sizeof(Mpi2SGESimple64_t); ++ ioc->dma_mask = 64; ++ goto out; ++ } ++ } ++ ++ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ++ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { ++ ioc->base_add_sg_single = &_base_add_sg_single_32; ++ ioc->sge_size = sizeof(Mpi2SGESimple32_t); ++ ioc->dma_mask = 32; ++ } else ++ return -ENODEV; ++ ++ out: ++ si_meminfo(&s); ++ pr_info(MPT3SAS_FMT ++ "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", ++ ioc->name, ioc->dma_mask, convert_to_kb(s.totalram)); ++ ++ return 0; ++} ++ ++static int ++_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc, ++ struct pci_dev *pdev) ++{ ++ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { ++ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++/** ++ * _base_check_enable_msix - checks MSIX capabable. ++ * @ioc: per adapter object ++ * ++ * Check to see if card is capable of MSIX, and set number ++ * of available msix vectors ++ */ ++static int ++_base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int base; ++ u16 message_control; ++ ++ /* Check whether controller SAS2008 B0 controller, ++ * if it is SAS2008 B0 controller use IO-APIC instead of MSIX ++ */ ++ if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 && ++ ioc->pdev->revision == SAS2_PCI_DEVICE_B0_REVISION) { ++ return -EINVAL; ++ } ++ ++ base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX); ++ if (!base) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT "msix not supported\n", ++ ioc->name)); ++ return -EINVAL; ++ } ++ ++ /* get msix vector count */ ++ /* NUMA_IO not supported for older controllers */ ++ if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2004 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_1 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_2 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_3 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_1 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_2) ++ ioc->msix_vector_count = 1; ++ else { ++ pci_read_config_word(ioc->pdev, base + 2, &message_control); ++ ioc->msix_vector_count = (message_control & 0x3FF) + 1; ++ } ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "msix is supported, vector_count(%d)\n", ++ ioc->name, ioc->msix_vector_count)); ++ return 0; ++} ++ ++/** ++ * _base_free_irq - free irq ++ * @ioc: per adapter object ++ * ++ * Freeing respective reply_queue from the list. ++ */ ++static void ++_base_free_irq(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct adapter_reply_queue *reply_q, *next; ++ ++ if (list_empty(&ioc->reply_queue_list)) ++ return; ++ ++ list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { ++ list_del(&reply_q->list); ++ if (smp_affinity_enable) { ++ irq_set_affinity_hint(reply_q->vector, NULL); ++ free_cpumask_var(reply_q->affinity_hint); ++ } ++ free_irq(reply_q->vector, reply_q); ++ kfree(reply_q); ++ } ++} ++ ++/** ++ * _base_request_irq - request irq ++ * @ioc: per adapter object ++ * @index: msix index into vector table ++ * @vector: irq vector ++ * ++ * Inserting respective reply_queue into the list. ++ */ ++static int ++_base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector) ++{ ++ struct adapter_reply_queue *reply_q; ++ int r; ++ ++ reply_q = kzalloc(sizeof(struct adapter_reply_queue), GFP_KERNEL); ++ if (!reply_q) { ++ pr_err(MPT3SAS_FMT "unable to allocate memory %d!\n", ++ ioc->name, (int)sizeof(struct adapter_reply_queue)); ++ return -ENOMEM; ++ } ++ reply_q->ioc = ioc; ++ reply_q->msix_index = index; ++ reply_q->vector = vector; ++ ++ if (smp_affinity_enable) { ++ if (!zalloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) { ++ kfree(reply_q); ++ return -ENOMEM; ++ } ++ } ++ ++ atomic_set(&reply_q->busy, 0); ++ if (ioc->msix_enable) ++ snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", ++ ioc->driver_name, ioc->id, index); ++ else ++ snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d", ++ ioc->driver_name, ioc->id); ++ r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name, ++ reply_q); ++ if (r) { ++ pr_err(MPT3SAS_FMT "unable to allocate interrupt %d!\n", ++ reply_q->name, vector); ++ free_cpumask_var(reply_q->affinity_hint); ++ kfree(reply_q); ++ return -EBUSY; ++ } ++ ++ INIT_LIST_HEAD(&reply_q->list); ++ list_add_tail(&reply_q->list, &ioc->reply_queue_list); ++ return 0; ++} ++ ++/** ++ * _base_assign_reply_queues - assigning msix index for each cpu ++ * @ioc: per adapter object ++ * ++ * The enduser would need to set the affinity via /proc/irq/#/smp_affinity ++ * ++ * It would nice if we could call irq_set_affinity, however it is not ++ * an exported symbol ++ */ ++static void ++_base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned int cpu, nr_cpus, nr_msix, index = 0; ++ struct adapter_reply_queue *reply_q; ++ ++ if (!_base_is_controller_msix_enabled(ioc)) ++ return; ++ ++ memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz); ++ ++ nr_cpus = num_online_cpus(); ++ nr_msix = ioc->reply_queue_count = min(ioc->reply_queue_count, ++ ioc->facts.MaxMSIxVectors); ++ if (!nr_msix) ++ return; ++ ++ cpu = cpumask_first(cpu_online_mask); ++ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ ++ unsigned int i, group = nr_cpus / nr_msix; ++ ++ if (cpu >= nr_cpus) ++ break; ++ ++ if (index < nr_cpus % nr_msix) ++ group++; ++ ++ for (i = 0 ; i < group ; i++) { ++ ioc->cpu_msix_table[cpu] = index; ++ if (smp_affinity_enable) ++ cpumask_or(reply_q->affinity_hint, ++ reply_q->affinity_hint, get_cpu_mask(cpu)); ++ cpu = cpumask_next(cpu, cpu_online_mask); ++ } ++ if (smp_affinity_enable) ++ if (irq_set_affinity_hint(reply_q->vector, ++ reply_q->affinity_hint)) ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "Err setting affinity hint to irq vector %d\n", ++ ioc->name, reply_q->vector)); ++ index++; ++ } ++} ++ ++/** ++ * _base_disable_msix - disables msix ++ * @ioc: per adapter object ++ * ++ */ ++static void ++_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) ++{ ++ if (!ioc->msix_enable) ++ return; ++ pci_disable_msix(ioc->pdev); ++ ioc->msix_enable = 0; ++} ++ ++/** ++ * _base_enable_msix - enables msix, failback to io_apic ++ * @ioc: per adapter object ++ * ++ */ ++static int ++_base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct msix_entry *entries, *a; ++ int r; ++ int i; ++ u8 try_msix = 0; ++ ++ if (msix_disable == -1 || msix_disable == 0) ++ try_msix = 1; ++ ++ if (!try_msix) ++ goto try_ioapic; ++ ++ if (_base_check_enable_msix(ioc) != 0) ++ goto try_ioapic; ++ ++ ioc->reply_queue_count = min_t(int, ioc->cpu_count, ++ ioc->msix_vector_count); ++ ++ printk(MPT3SAS_FMT "MSI-X vectors supported: %d, no of cores" ++ ": %d, max_msix_vectors: %d\n", ioc->name, ioc->msix_vector_count, ++ ioc->cpu_count, max_msix_vectors); ++ ++ if (!ioc->rdpq_array_enable && max_msix_vectors == -1) ++ max_msix_vectors = 8; ++ ++ if (max_msix_vectors > 0) { ++ ioc->reply_queue_count = min_t(int, max_msix_vectors, ++ ioc->reply_queue_count); ++ ioc->msix_vector_count = ioc->reply_queue_count; ++ } else if (max_msix_vectors == 0) ++ goto try_ioapic; ++ ++ if (ioc->msix_vector_count < ioc->cpu_count) ++ smp_affinity_enable = 0; ++ ++ entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry), ++ GFP_KERNEL); ++ if (!entries) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT ++ "kcalloc failed @ at %s:%d/%s() !!!\n", ++ ioc->name, __FILE__, __LINE__, __func__)); ++ goto try_ioapic; ++ } ++ ++ for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) ++ a->entry = i; ++ ++ r = pci_enable_msix_exact(ioc->pdev, entries, ioc->reply_queue_count); ++ if (r) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT ++ "pci_enable_msix_exact failed (r=%d) !!!\n", ++ ioc->name, r)); ++ kfree(entries); ++ goto try_ioapic; ++ } ++ ++ ioc->msix_enable = 1; ++ for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) { ++ r = _base_request_irq(ioc, i, a->vector); ++ if (r) { ++ _base_free_irq(ioc); ++ _base_disable_msix(ioc); ++ kfree(entries); ++ goto try_ioapic; ++ } ++ } ++ ++ kfree(entries); ++ return 0; ++ ++/* failback to io_apic interrupt routing */ ++ try_ioapic: ++ ++ ioc->reply_queue_count = 1; ++ r = _base_request_irq(ioc, 0, ioc->pdev->irq); ++ ++ return r; ++} ++ ++/** ++ * mpt2sas_base_unmap_resources - free controller resources ++ * @ioc: per adapter object ++ */ ++void ++mpt2sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct pci_dev *pdev = ioc->pdev; ++ ++ dexitprintk(ioc, printk(MPT3SAS_FMT "%s\n", ++ ioc->name, __func__)); ++ ++ _base_free_irq(ioc); ++ _base_disable_msix(ioc); ++ ++ if (ioc->msix96_vector) { ++ kfree(ioc->replyPostRegisterIndex); ++ ioc->replyPostRegisterIndex = NULL; ++ } ++ ++ if (ioc->chip_phys) { ++ iounmap(ioc->chip); ++ ioc->chip_phys = 0; ++ } ++ ++ if (pci_is_enabled(pdev)) { ++ pci_release_selected_regions(ioc->pdev, ioc->bars); ++ pci_disable_pcie_error_reporting(pdev); ++ pci_disable_device(pdev); ++ } ++} ++ ++/** ++ * mpt2sas_base_map_resources - map in controller resources (io/irq/memap) ++ * @ioc: per adapter object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct pci_dev *pdev = ioc->pdev; ++ u32 memap_sz; ++ u32 pio_sz; ++ int i, r = 0; ++ u64 pio_chip = 0; ++ u64 chip_phys = 0; ++ struct adapter_reply_queue *reply_q; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ++ ioc->name, __func__)); ++ ++ ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); ++ if (pci_enable_device_mem(pdev)) { ++ pr_warn(MPT3SAS_FMT "pci_enable_device_mem: failed\n", ++ ioc->name); ++ ioc->bars = 0; ++ return -ENODEV; ++ } ++ ++ ++ if (pci_request_selected_regions(pdev, ioc->bars, ++ ioc->driver_name)) { ++ pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n", ++ ioc->name); ++ ioc->bars = 0; ++ r = -ENODEV; ++ goto out_fail; ++ } ++ ++/* AER (Advanced Error Reporting) hooks */ ++ pci_enable_pcie_error_reporting(pdev); ++ ++ pci_set_master(pdev); ++ ++ ++ if (_base_config_dma_addressing(ioc, pdev) != 0) { ++ pr_warn(MPT3SAS_FMT "no suitable DMA mask for %s\n", ++ ioc->name, pci_name(pdev)); ++ r = -ENODEV; ++ goto out_fail; ++ } ++ ++ for (i = 0, memap_sz = 0, pio_sz = 0; (i < DEVICE_COUNT_RESOURCE) && ++ (!memap_sz || !pio_sz); i++) { ++ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { ++ if (pio_sz) ++ continue; ++ pio_chip = (u64)pci_resource_start(pdev, i); ++ pio_sz = pci_resource_len(pdev, i); ++ } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { ++ if (memap_sz) ++ continue; ++ ioc->chip_phys = pci_resource_start(pdev, i); ++ chip_phys = (u64)ioc->chip_phys; ++ memap_sz = pci_resource_len(pdev, i); ++ ioc->chip = ioremap(ioc->chip_phys, memap_sz); ++ } ++ } ++ ++ if (ioc->chip == NULL) { ++ pr_err(MPT3SAS_FMT "unable to map adapter memory! " ++ " or resource not found\n", ioc->name); ++ r = -EINVAL; ++ goto out_fail; ++ } ++ ++ _base_mask_interrupts(ioc); ++ ++ r = _base_get_ioc_facts(ioc, CAN_SLEEP); ++ if (r) ++ goto out_fail; ++ ++ if (!ioc->rdpq_array_enable_assigned) { ++ ioc->rdpq_array_enable = ioc->rdpq_array_capable; ++ ioc->rdpq_array_enable_assigned = 1; ++ } ++ ++ r = _base_enable_msix(ioc); ++ if (r) ++ goto out_fail; ++ ++ /* Use the Combined reply queue feature only for SAS3 C0 & higher ++ * revision HBAs and also only when reply queue count is greater than 8 ++ */ ++ if (ioc->msix96_vector && ioc->reply_queue_count > 8) { ++ /* Determine the Supplemental Reply Post Host Index Registers ++ * Addresse. Supplemental Reply Post Host Index Registers ++ * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and ++ * each register is at offset bytes of ++ * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one. ++ */ ++ ioc->replyPostRegisterIndex = kcalloc( ++ MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT, ++ sizeof(resource_size_t *), GFP_KERNEL); ++ if (!ioc->replyPostRegisterIndex) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "allocation for reply Post Register Index failed!!!\n", ++ ioc->name)); ++ r = -ENOMEM; ++ goto out_fail; ++ } ++ ++ for (i = 0; i < MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT; i++) { ++ ioc->replyPostRegisterIndex[i] = (resource_size_t *) ++ ((u8 *)&ioc->chip->Doorbell + ++ MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET + ++ (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET)); ++ } ++ } else ++ ioc->msix96_vector = 0; ++ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) ++ pr_info(MPT3SAS_FMT "%s: IRQ %d\n", ++ reply_q->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : ++ "IO-APIC enabled"), reply_q->vector); ++ ++ pr_info(MPT3SAS_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n", ++ ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz); ++ pr_info(MPT3SAS_FMT "ioport(0x%016llx), size(%d)\n", ++ ioc->name, (unsigned long long)pio_chip, pio_sz); ++ ++ /* Save PCI configuration state for recovery from PCI AER/EEH errors */ ++ pci_save_state(pdev); ++ return 0; ++ ++ out_fail: ++ mpt2sas_base_unmap_resources(ioc); ++ return r; ++} ++ ++/** ++ * mpt2sas_base_get_msg_frame - obtain request mf pointer ++ * @ioc: per adapter object ++ * @smid: system request message index(smid zero is invalid) ++ * ++ * Returns virt pointer to message frame. ++ */ ++void * ++mpt2sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return (void *)(ioc->request + (smid * ioc->request_sz)); ++} ++ ++/** ++ * mpt2sas_base_get_sense_buffer - obtain a sense buffer virt addr ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns virt pointer to sense buffer. ++ */ ++void * ++mpt2sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return (void *)(ioc->sense + ((smid - 1) * SCSI_SENSE_BUFFERSIZE)); ++} ++ ++/** ++ * mpt2sas_base_get_sense_buffer_dma - obtain a sense buffer dma addr ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns phys pointer to the low 32bit address of the sense buffer. ++ */ ++__le32 ++mpt2sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return cpu_to_le32(ioc->sense_dma + ((smid - 1) * ++ SCSI_SENSE_BUFFERSIZE)); ++} ++ ++/** ++ * mpt2sas_base_get_reply_virt_addr - obtain reply frames virt address ++ * @ioc: per adapter object ++ * @phys_addr: lower 32 physical addr of the reply ++ * ++ * Converts 32bit lower physical addr into a virt address. ++ */ ++void * ++mpt2sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr) ++{ ++ if (!phys_addr) ++ return NULL; ++ return ioc->reply + (phys_addr - (u32)ioc->reply_dma); ++} ++ ++static inline u8 ++_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc) ++{ ++ return ioc->cpu_msix_table[raw_smp_processor_id()]; ++} ++ ++/** ++ * mpt2sas_base_get_smid - obtain a free smid from internal queue ++ * @ioc: per adapter object ++ * @cb_idx: callback index ++ * ++ * Returns smid (zero is invalid) ++ */ ++u16 ++mpt2sas_base_get_smid(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx) ++{ ++ unsigned long flags; ++ struct request_tracker *request; ++ u16 smid; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->internal_free_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ pr_err(MPT3SAS_FMT "%s: smid not available\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ request = list_entry(ioc->internal_free_list.next, ++ struct request_tracker, tracker_list); ++ request->cb_idx = cb_idx; ++ smid = request->smid; ++ list_del(&request->tracker_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * mpt2sas_base_get_smid_scsiio - obtain a free smid from scsiio queue ++ * @ioc: per adapter object ++ * @cb_idx: callback index ++ * @scmd: pointer to scsi command object ++ * ++ * Returns smid (zero is invalid) ++ */ ++u16 ++mpt2sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, ++ struct scsi_cmnd *scmd) ++{ ++ unsigned long flags; ++ struct scsiio_tracker *request; ++ u16 smid; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->free_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ pr_err(MPT3SAS_FMT "%s: smid not available\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ request = list_entry(ioc->free_list.next, ++ struct scsiio_tracker, tracker_list); ++ request->scmd = scmd; ++ request->cb_idx = cb_idx; ++ smid = request->smid; ++ request->msix_io = _base_get_msix_index(ioc); ++ list_del(&request->tracker_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * mpt2sas_base_get_smid_hpr - obtain a free smid from hi-priority queue ++ * @ioc: per adapter object ++ * @cb_idx: callback index ++ * ++ * Returns smid (zero is invalid) ++ */ ++u16 ++mpt2sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx) ++{ ++ unsigned long flags; ++ struct request_tracker *request; ++ u16 smid; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->hpr_free_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return 0; ++ } ++ ++ request = list_entry(ioc->hpr_free_list.next, ++ struct request_tracker, tracker_list); ++ request->cb_idx = cb_idx; ++ smid = request->smid; ++ list_del(&request->tracker_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * mpt2sas_base_free_smid - put smid back on free_list ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ unsigned long flags; ++ int i; ++ struct chain_tracker *chain_req, *next; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (smid < ioc->hi_priority_smid) { ++ /* scsiio queue */ ++ i = smid - 1; ++ if (!list_empty(&ioc->scsi_lookup[i].chain_list)) { ++ list_for_each_entry_safe(chain_req, next, ++ &ioc->scsi_lookup[i].chain_list, tracker_list) { ++ list_del_init(&chain_req->tracker_list); ++ list_add(&chain_req->tracker_list, ++ &ioc->free_chain_list); ++ } ++ } ++ ioc->scsi_lookup[i].cb_idx = 0xFF; ++ ioc->scsi_lookup[i].scmd = NULL; ++ ioc->scsi_lookup[i].direct_io = 0; ++ list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ /* ++ * See _wait_for_commands_to_complete() call with regards ++ * to this code. ++ */ ++ if (ioc->shost_recovery && ioc->pending_io_count) { ++ if (ioc->pending_io_count == 1) ++ wake_up(&ioc->reset_wq); ++ ioc->pending_io_count--; ++ } ++ return; ++ } else if (smid < ioc->internal_smid) { ++ /* hi-priority */ ++ i = smid - ioc->hi_priority_smid; ++ ioc->hpr_lookup[i].cb_idx = 0xFF; ++ list_add(&ioc->hpr_lookup[i].tracker_list, &ioc->hpr_free_list); ++ } else if (smid <= ioc->hba_queue_depth) { ++ /* internal queue */ ++ i = smid - ioc->internal_smid; ++ ioc->internal_lookup[i].cb_idx = 0xFF; ++ list_add(&ioc->internal_lookup[i].tracker_list, ++ &ioc->internal_free_list); ++ } ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++} ++ ++/** ++ * _base_writeq - 64 bit write to MMIO ++ * @ioc: per adapter object ++ * @b: data payload ++ * @addr: address in MMIO space ++ * @writeq_lock: spin lock ++ * ++ * Glue for handling an atomic 64 bit word to MMIO. This special handling takes ++ * care of 32 bit environment where its not quarenteed to send the entire word ++ * in one transfer. ++ */ ++#if defined(writeq) && defined(CONFIG_64BIT) ++static inline void ++_base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) ++{ ++ writeq(cpu_to_le64(b), addr); ++} ++#else ++static inline void ++_base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) ++{ ++ unsigned long flags; ++ __u64 data_out = cpu_to_le64(b); ++ ++ spin_lock_irqsave(writeq_lock, flags); ++ writel((u32)(data_out), addr); ++ writel((u32)(data_out >> 32), (addr + 4)); ++ spin_unlock_irqrestore(writeq_lock, flags); ++} ++#endif ++ ++/** ++ * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ ++ descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; ++ descriptor.SCSIIO.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SCSIIO.SMID = cpu_to_le16(smid); ++ descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); ++ descriptor.SCSIIO.LMID = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * mpt2sas_base_put_smid_fast_path - send fast path request to firmware ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ descriptor.SCSIIO.RequestFlags = ++ MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; ++ descriptor.SCSIIO.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SCSIIO.SMID = cpu_to_le16(smid); ++ descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); ++ descriptor.SCSIIO.LMID = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0. ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 msix_task) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ descriptor.HighPriority.RequestFlags = ++ MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; ++ descriptor.HighPriority.MSIxIndex = msix_task; ++ descriptor.HighPriority.SMID = cpu_to_le16(smid); ++ descriptor.HighPriority.LMID = 0; ++ descriptor.HighPriority.Reserved1 = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * mpt2sas_base_put_smid_default - Default, primarily used for config pages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; ++ descriptor.Default.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.Default.SMID = cpu_to_le16(smid); ++ descriptor.Default.LMID = 0; ++ descriptor.Default.DescriptorTypeDependent = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * _base_display_OEMs_branding - Display branding string ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc) ++{ ++ if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL) ++ return; ++ ++ switch (ioc->pdev->subsystem_vendor) { ++ case PCI_VENDOR_ID_INTEL: ++ switch (ioc->pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SAS2008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_INTEL_RMS2LL080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS2LL080_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS2LL040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS2LL040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_SSD910_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_SSD910_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ case MPI2_MFGPAGE_DEVID_SAS2308_2: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_INTEL_RS25GB008_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RS25GB008_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25JB080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25JB080_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25JB040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25JB040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25KB080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25KB080_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25KB040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25KB040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25LB040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25LB040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25LB080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25LB080_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_INTEL_RMS3JC080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RMS3JC080_BRANDING); ++ break; ++ ++ case MPT3SAS_INTEL_RS3GC008_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RS3GC008_BRANDING); ++ break; ++ case MPT3SAS_INTEL_RS3FC044_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RS3FC044_BRANDING); ++ break; ++ case MPT3SAS_INTEL_RS3UC080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RS3UC080_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case PCI_VENDOR_ID_DELL: ++ switch (ioc->pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SAS2008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_MODULAR_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_BRANDING); ++ break; ++ case MPT2SAS_DELL_6GBPS_SAS_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_6GBPS_SAS_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Dell 6Gbps HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_DELL_12G_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_DELL_12G_HBA_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Dell HBA: Subsystem ID: 0x%X\n", ioc->name, ++ ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case PCI_VENDOR_ID_CISCO: ++ switch (ioc->pdev->device) { ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_CISCO_12G_8E_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_8E_HBA_BRANDING); ++ break; ++ case MPT3SAS_CISCO_12G_8I_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_8I_HBA_BRANDING); ++ break; ++ case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case MPI25_MFGPAGE_DEVID_SAS3108_1: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING); ++ break; ++ case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING ++ ); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Cisco SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case MPT2SAS_HP_3PAR_SSVID: ++ switch (ioc->pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SAS2004: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ case MPI2_MFGPAGE_DEVID_SAS2308_2: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_HP_2_4_INTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_2_4_INTERNAL_BRANDING); ++ break; ++ case MPT2SAS_HP_2_4_EXTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_2_4_EXTERNAL_BRANDING); ++ break; ++ case MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING); ++ break; ++ case MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ default: ++ pr_info(MPT3SAS_FMT ++ "HP SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ default: ++ break; ++ } ++} ++ ++/** ++ * _base_display_ioc_capabilities - Disply IOC's capabilities. ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int i = 0; ++ char desc[16]; ++ u32 iounit_pg1_flags; ++ u32 bios_version; ++ ++ bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); ++ strncpy(desc, ioc->manu_pg0.ChipName, 16); ++ pr_info(MPT3SAS_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), "\ ++ "ChipRevision(0x%02x), BiosVersion(%02d.%02d.%02d.%02d)\n", ++ ioc->name, desc, ++ (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, ++ (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, ++ (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ++ ioc->facts.FWVersion.Word & 0x000000FF, ++ ioc->pdev->revision, ++ (bios_version & 0xFF000000) >> 24, ++ (bios_version & 0x00FF0000) >> 16, ++ (bios_version & 0x0000FF00) >> 8, ++ bios_version & 0x000000FF); ++ ++ _base_display_OEMs_branding(ioc); ++ ++ pr_info(MPT3SAS_FMT "Protocol=(", ioc->name); ++ ++ if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) { ++ pr_info("Initiator"); ++ i++; ++ } ++ ++ if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET) { ++ pr_info("%sTarget", i ? "," : ""); ++ i++; ++ } ++ ++ i = 0; ++ pr_info("), "); ++ pr_info("Capabilities=("); ++ ++ if (!ioc->hide_ir_msg) { ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { ++ pr_info("Raid"); ++ i++; ++ } ++ } ++ ++ if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { ++ pr_info("%sTLR", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_MULTICAST) { ++ pr_info("%sMulticast", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET) { ++ pr_info("%sBIDI Target", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP) { ++ pr_info("%sEEDP", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) { ++ pr_info("%sSnapshot Buffer", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) { ++ pr_info("%sDiag Trace Buffer", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) { ++ pr_info("%sDiag Extended Buffer", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { ++ pr_info("%sTask Set Full", i ? "," : ""); ++ i++; ++ } ++ ++ iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags); ++ if (!(iounit_pg1_flags & MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE)) { ++ pr_info("%sNCQ", i ? "," : ""); ++ i++; ++ } ++ ++ pr_info(")\n"); ++} ++ ++/** ++ * mpt2sas_base_update_missing_delay - change the missing delay timers ++ * @ioc: per adapter object ++ * @device_missing_delay: amount of time till device is reported missing ++ * @io_missing_delay: interval IO is returned when there is a missing device ++ * ++ * Return nothing. ++ * ++ * Passed on the command line, this function will modify the device missing ++ * delay, as well as the io missing delay. This should be called at driver ++ * load time. ++ */ ++void ++mpt2sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc, ++ u16 device_missing_delay, u8 io_missing_delay) ++{ ++ u16 dmd, dmd_new, dmd_orignal; ++ u8 io_missing_delay_original; ++ u16 sz; ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2ConfigReply_t mpi_reply; ++ u8 num_phys = 0; ++ u16 ioc_status; ++ ++ mpt2sas_config_get_number_hba_phys(ioc, &num_phys); ++ if (!num_phys) ++ return; ++ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ /* device missing delay */ ++ dmd = sas_iounit_pg1->ReportDeviceMissingDelay; ++ if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) ++ dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; ++ else ++ dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; ++ dmd_orignal = dmd; ++ if (device_missing_delay > 0x7F) { ++ dmd = (device_missing_delay > 0x7F0) ? 0x7F0 : ++ device_missing_delay; ++ dmd = dmd / 16; ++ dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16; ++ } else ++ dmd = device_missing_delay; ++ sas_iounit_pg1->ReportDeviceMissingDelay = dmd; ++ ++ /* io missing delay */ ++ io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay; ++ sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay; ++ ++ if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, ++ sz)) { ++ if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) ++ dmd_new = (dmd & ++ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; ++ else ++ dmd_new = ++ dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; ++ pr_info(MPT3SAS_FMT "device_missing_delay: old(%d), new(%d)\n", ++ ioc->name, dmd_orignal, dmd_new); ++ pr_info(MPT3SAS_FMT "ioc_missing_delay: old(%d), new(%d)\n", ++ ioc->name, io_missing_delay_original, ++ io_missing_delay); ++ ioc->device_missing_delay = dmd_new; ++ ioc->io_missing_delay = io_missing_delay; ++ } ++ ++out: ++ kfree(sas_iounit_pg1); ++} ++/** ++ * _base_static_config_pages - static start of day config pages ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ u32 iounit_pg1_flags; ++ ++ mpt2sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0); ++ if (ioc->ir_firmware) ++ mpt2sas_config_get_manufacturing_pg10(ioc, &mpi_reply, ++ &ioc->manu_pg10); ++ ++ /* ++ * Ensure correct T10 PI operation if vendor left EEDPTagMode ++ * flag unset in NVDATA. ++ */ ++ mpt2sas_config_get_manufacturing_pg11(ioc, &mpi_reply, &ioc->manu_pg11); ++ if (ioc->manu_pg11.EEDPTagMode == 0) { ++ pr_err("%s: overriding NVDATA EEDPTagMode setting\n", ++ ioc->name); ++ ioc->manu_pg11.EEDPTagMode &= ~0x3; ++ ioc->manu_pg11.EEDPTagMode |= 0x1; ++ mpt2sas_config_set_manufacturing_pg11(ioc, &mpi_reply, ++ &ioc->manu_pg11); ++ } ++ ++ mpt2sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2); ++ mpt2sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3); ++ mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); ++ mpt2sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0); ++ mpt2sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); ++ mpt2sas_config_get_iounit_pg8(ioc, &mpi_reply, &ioc->iounit_pg8); ++ _base_display_ioc_capabilities(ioc); ++ ++ /* ++ * Enable task_set_full handling in iounit_pg1 when the ++ * facts capabilities indicate that its supported. ++ */ ++ iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags); ++ if ((ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING)) ++ iounit_pg1_flags &= ++ ~MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; ++ else ++ iounit_pg1_flags |= ++ MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; ++ ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); ++ mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); ++ ++ if (ioc->iounit_pg8.NumSensors) ++ ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors; ++} ++ ++/** ++ * _base_release_memory_pools - release memory ++ * @ioc: per adapter object ++ * ++ * Free memory allocated from _base_allocate_memory_pools. ++ * ++ * Return nothing. ++ */ ++static void ++_base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int i = 0; ++ struct reply_post_struct *rps; ++ ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->request) { ++ pci_free_consistent(ioc->pdev, ioc->request_dma_sz, ++ ioc->request, ioc->request_dma); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "request_pool(0x%p): free\n", ++ ioc->name, ioc->request)); ++ ioc->request = NULL; ++ } ++ ++ if (ioc->sense) { ++ pci_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma); ++ if (ioc->sense_dma_pool) ++ pci_pool_destroy(ioc->sense_dma_pool); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "sense_pool(0x%p): free\n", ++ ioc->name, ioc->sense)); ++ ioc->sense = NULL; ++ } ++ ++ if (ioc->reply) { ++ pci_pool_free(ioc->reply_dma_pool, ioc->reply, ioc->reply_dma); ++ if (ioc->reply_dma_pool) ++ pci_pool_destroy(ioc->reply_dma_pool); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_pool(0x%p): free\n", ++ ioc->name, ioc->reply)); ++ ioc->reply = NULL; ++ } ++ ++ if (ioc->reply_free) { ++ pci_pool_free(ioc->reply_free_dma_pool, ioc->reply_free, ++ ioc->reply_free_dma); ++ if (ioc->reply_free_dma_pool) ++ pci_pool_destroy(ioc->reply_free_dma_pool); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_free_pool(0x%p): free\n", ++ ioc->name, ioc->reply_free)); ++ ioc->reply_free = NULL; ++ } ++ ++ if (ioc->reply_post) { ++ do { ++ rps = &ioc->reply_post[i]; ++ if (rps->reply_post_free) { ++ pci_pool_free( ++ ioc->reply_post_free_dma_pool, ++ rps->reply_post_free, ++ rps->reply_post_free_dma); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_post_free_pool(0x%p): free\n", ++ ioc->name, rps->reply_post_free)); ++ rps->reply_post_free = NULL; ++ } ++ } while (ioc->rdpq_array_enable && ++ (++i < ioc->reply_queue_count)); ++ ++ if (ioc->reply_post_free_dma_pool) ++ pci_pool_destroy(ioc->reply_post_free_dma_pool); ++ kfree(ioc->reply_post); ++ } ++ ++ if (ioc->config_page) { ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "config_page(0x%p): free\n", ioc->name, ++ ioc->config_page)); ++ pci_free_consistent(ioc->pdev, ioc->config_page_sz, ++ ioc->config_page, ioc->config_page_dma); ++ } ++ ++ if (ioc->scsi_lookup) { ++ free_pages((ulong)ioc->scsi_lookup, ioc->scsi_lookup_pages); ++ ioc->scsi_lookup = NULL; ++ } ++ kfree(ioc->hpr_lookup); ++ kfree(ioc->internal_lookup); ++ if (ioc->chain_lookup) { ++ for (i = 0; i < ioc->chain_depth; i++) { ++ if (ioc->chain_lookup[i].chain_buffer) ++ pci_pool_free(ioc->chain_dma_pool, ++ ioc->chain_lookup[i].chain_buffer, ++ ioc->chain_lookup[i].chain_buffer_dma); ++ } ++ if (ioc->chain_dma_pool) ++ pci_pool_destroy(ioc->chain_dma_pool); ++ free_pages((ulong)ioc->chain_lookup, ioc->chain_pages); ++ ioc->chain_lookup = NULL; ++ } ++} ++ ++/** ++ * _base_allocate_memory_pools - allocate start of day memory pools ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 success, anything else error ++ */ ++static int ++_base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ struct mpt2sas_facts *facts; ++ u16 max_sge_elements; ++ u16 chains_needed_per_io; ++ u32 sz, total_sz, reply_post_free_sz; ++ u32 retry_sz; ++ u16 max_request_credit; ++ unsigned short sg_tablesize; ++ u16 sge_size; ++ int i; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ ++ retry_sz = 0; ++ facts = &ioc->facts; ++ ++ /* command line tunables for max sgl entries */ ++ if (max_sgl_entries != -1) ++ sg_tablesize = max_sgl_entries; ++ else { ++ if (ioc->hba_mpi_version_belonged == MPI2_VERSION) ++ sg_tablesize = MPT2SAS_SG_DEPTH; ++ else ++ sg_tablesize = MPT3SAS_SG_DEPTH; ++ } ++ ++ if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS) ++ sg_tablesize = MPT_MIN_PHYS_SEGMENTS; ++ else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) { ++ sg_tablesize = min_t(unsigned short, sg_tablesize, ++ SCSI_MAX_SG_CHAIN_SEGMENTS); ++ pr_warn(MPT3SAS_FMT ++ "sg_tablesize(%u) is bigger than kernel" ++ " defined SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name, ++ sg_tablesize, MPT_MAX_PHYS_SEGMENTS); ++ } ++ ioc->shost->sg_tablesize = sg_tablesize; ++ ++ ioc->internal_depth = min_t(int, (facts->HighPriorityCredit + (5)), ++ (facts->RequestCredit / 4)); ++ if (ioc->internal_depth < INTERNAL_CMDS_COUNT) { ++ if (facts->RequestCredit <= (INTERNAL_CMDS_COUNT + ++ INTERNAL_SCSIIO_CMDS_COUNT)) { ++ pr_err(MPT3SAS_FMT "IOC doesn't have enough Request \ ++ Credits, it has just %d number of credits\n", ++ ioc->name, facts->RequestCredit); ++ return -ENOMEM; ++ } ++ ioc->internal_depth = 10; ++ } ++ ++ ioc->hi_priority_depth = ioc->internal_depth - (5); ++ /* command line tunables for max controller queue depth */ ++ if (max_queue_depth != -1 && max_queue_depth != 0) { ++ max_request_credit = min_t(u16, max_queue_depth + ++ ioc->internal_depth, facts->RequestCredit); ++ if (max_request_credit > MAX_HBA_QUEUE_DEPTH) ++ max_request_credit = MAX_HBA_QUEUE_DEPTH; ++ } else ++ max_request_credit = min_t(u16, facts->RequestCredit, ++ MAX_HBA_QUEUE_DEPTH); ++ ++ /* Firmware maintains additional facts->HighPriorityCredit number of ++ * credits for HiPriprity Request messages, so hba queue depth will be ++ * sum of max_request_credit and high priority queue depth. ++ */ ++ ioc->hba_queue_depth = max_request_credit + ioc->hi_priority_depth; ++ ++ /* request frame size */ ++ ioc->request_sz = facts->IOCRequestFrameSize * 4; ++ ++ /* reply frame size */ ++ ioc->reply_sz = facts->ReplyFrameSize * 4; ++ ++ /* chain segment size */ ++ if (ioc->hba_mpi_version_belonged != MPI2_VERSION) { ++ if (facts->IOCMaxChainSegmentSize) ++ ioc->chain_segment_sz = ++ facts->IOCMaxChainSegmentSize * ++ MAX_CHAIN_ELEMT_SZ; ++ else ++ /* set to 128 bytes size if IOCMaxChainSegmentSize is zero */ ++ ioc->chain_segment_sz = DEFAULT_NUM_FWCHAIN_ELEMTS * ++ MAX_CHAIN_ELEMT_SZ; ++ } else ++ ioc->chain_segment_sz = ioc->request_sz; ++ ++ /* calculate the max scatter element size */ ++ sge_size = max_t(u16, ioc->sge_size, ioc->sge_size_ieee); ++ ++ retry_allocation: ++ total_sz = 0; ++ /* calculate number of sg elements left over in the 1st frame */ ++ max_sge_elements = ioc->request_sz - ((sizeof(Mpi2SCSIIORequest_t) - ++ sizeof(Mpi2SGEIOUnion_t)) + sge_size); ++ ioc->max_sges_in_main_message = max_sge_elements/sge_size; ++ ++ /* now do the same for a chain buffer */ ++ max_sge_elements = ioc->chain_segment_sz - sge_size; ++ ioc->max_sges_in_chain_message = max_sge_elements/sge_size; ++ ++ /* ++ * MPT3SAS_SG_DEPTH = CONFIG_FUSION_MAX_SGE ++ */ ++ chains_needed_per_io = ((ioc->shost->sg_tablesize - ++ ioc->max_sges_in_main_message)/ioc->max_sges_in_chain_message) ++ + 1; ++ if (chains_needed_per_io > facts->MaxChainDepth) { ++ chains_needed_per_io = facts->MaxChainDepth; ++ ioc->shost->sg_tablesize = min_t(u16, ++ ioc->max_sges_in_main_message + (ioc->max_sges_in_chain_message ++ * chains_needed_per_io), ioc->shost->sg_tablesize); ++ } ++ ioc->chains_needed_per_io = chains_needed_per_io; ++ ++ /* reply free queue sizing - taking into account for 64 FW events */ ++ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; ++ ++ /* calculate reply descriptor post queue depth */ ++ ioc->reply_post_queue_depth = ioc->hba_queue_depth + ++ ioc->reply_free_queue_depth + 1 ; ++ /* align the reply post queue on the next 16 count boundary */ ++ if (ioc->reply_post_queue_depth % 16) ++ ioc->reply_post_queue_depth += 16 - ++ (ioc->reply_post_queue_depth % 16); ++ ++ if (ioc->reply_post_queue_depth > ++ facts->MaxReplyDescriptorPostQueueDepth) { ++ ioc->reply_post_queue_depth = ++ facts->MaxReplyDescriptorPostQueueDepth - ++ (facts->MaxReplyDescriptorPostQueueDepth % 16); ++ ioc->hba_queue_depth = ++ ((ioc->reply_post_queue_depth - 64) / 2) - 1; ++ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; ++ } ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "scatter gather: " \ ++ "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), " ++ "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message, ++ ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, ++ ioc->chains_needed_per_io)); ++ ++ /* reply post queue, 16 byte align */ ++ reply_post_free_sz = ioc->reply_post_queue_depth * ++ sizeof(Mpi2DefaultReplyDescriptor_t); ++ ++ sz = reply_post_free_sz; ++ if (_base_is_controller_msix_enabled(ioc) && !ioc->rdpq_array_enable) ++ sz *= ioc->reply_queue_count; ++ ++ ioc->reply_post = kcalloc((ioc->rdpq_array_enable) ? ++ (ioc->reply_queue_count):1, ++ sizeof(struct reply_post_struct), GFP_KERNEL); ++ ++ if (!ioc->reply_post) { ++ pr_err(MPT3SAS_FMT "reply_post_free pool: kcalloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", ++ ioc->pdev, sz, 16, 0); ++ if (!ioc->reply_post_free_dma_pool) { ++ pr_err(MPT3SAS_FMT ++ "reply_post_free pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ i = 0; ++ do { ++ ioc->reply_post[i].reply_post_free = ++ pci_pool_alloc(ioc->reply_post_free_dma_pool, ++ GFP_KERNEL, ++ &ioc->reply_post[i].reply_post_free_dma); ++ if (!ioc->reply_post[i].reply_post_free) { ++ pr_err(MPT3SAS_FMT ++ "reply_post_free pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ memset(ioc->reply_post[i].reply_post_free, 0, sz); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply post free pool (0x%p): depth(%d)," ++ "element_size(%d), pool_size(%d kB)\n", ioc->name, ++ ioc->reply_post[i].reply_post_free, ++ ioc->reply_post_queue_depth, 8, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_post_free_dma = (0x%llx)\n", ioc->name, ++ (unsigned long long) ++ ioc->reply_post[i].reply_post_free_dma)); ++ total_sz += sz; ++ } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count)); ++ ++ if (ioc->dma_mask == 64) { ++ if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) { ++ pr_warn(MPT3SAS_FMT ++ "no suitable consistent DMA mask for %s\n", ++ ioc->name, pci_name(ioc->pdev)); ++ goto out; ++ } ++ } ++ ++ ioc->scsiio_depth = ioc->hba_queue_depth - ++ ioc->hi_priority_depth - ioc->internal_depth; ++ ++ /* set the scsi host can_queue depth ++ * with some internal commands that could be outstanding ++ */ ++ ioc->shost->can_queue = ioc->scsiio_depth - INTERNAL_SCSIIO_CMDS_COUNT; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "scsi host: can_queue depth (%d)\n", ++ ioc->name, ioc->shost->can_queue)); ++ ++ ++ /* contiguous pool for request and chains, 16 byte align, one extra " ++ * "frame for smid=0 ++ */ ++ ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth; ++ sz = ((ioc->scsiio_depth + 1) * ioc->request_sz); ++ ++ /* hi-priority queue */ ++ sz += (ioc->hi_priority_depth * ioc->request_sz); ++ ++ /* internal queue */ ++ sz += (ioc->internal_depth * ioc->request_sz); ++ ++ ioc->request_dma_sz = sz; ++ ioc->request = pci_alloc_consistent(ioc->pdev, sz, &ioc->request_dma); ++ if (!ioc->request) { ++ pr_err(MPT3SAS_FMT "request pool: pci_alloc_consistent " \ ++ "failed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), " ++ "total(%d kB)\n", ioc->name, ioc->hba_queue_depth, ++ ioc->chains_needed_per_io, ioc->request_sz, sz/1024); ++ if (ioc->scsiio_depth < MPT3SAS_SAS_QUEUE_DEPTH) ++ goto out; ++ retry_sz = 64; ++ ioc->hba_queue_depth -= retry_sz; ++ _base_release_memory_pools(ioc); ++ goto retry_allocation; ++ } ++ ++ if (retry_sz) ++ pr_err(MPT3SAS_FMT "request pool: pci_alloc_consistent " \ ++ "succeed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), " ++ "total(%d kb)\n", ioc->name, ioc->hba_queue_depth, ++ ioc->chains_needed_per_io, ioc->request_sz, sz/1024); ++ ++ /* hi-priority queue */ ++ ioc->hi_priority = ioc->request + ((ioc->scsiio_depth + 1) * ++ ioc->request_sz); ++ ioc->hi_priority_dma = ioc->request_dma + ((ioc->scsiio_depth + 1) * ++ ioc->request_sz); ++ ++ /* internal queue */ ++ ioc->internal = ioc->hi_priority + (ioc->hi_priority_depth * ++ ioc->request_sz); ++ ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * ++ ioc->request_sz); ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "request pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n", ++ ioc->name, ioc->request, ioc->hba_queue_depth, ioc->request_sz, ++ (ioc->hba_queue_depth * ioc->request_sz)/1024)); ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "request pool: dma(0x%llx)\n", ++ ioc->name, (unsigned long long) ioc->request_dma)); ++ total_sz += sz; ++ ++ sz = ioc->scsiio_depth * sizeof(struct scsiio_tracker); ++ ioc->scsi_lookup_pages = get_order(sz); ++ ioc->scsi_lookup = (struct scsiio_tracker *)__get_free_pages( ++ GFP_KERNEL, ioc->scsi_lookup_pages); ++ if (!ioc->scsi_lookup) { ++ pr_err(MPT3SAS_FMT "scsi_lookup: get_free_pages failed, sz(%d)\n", ++ ioc->name, (int)sz); ++ goto out; ++ } ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "scsiio(0x%p): depth(%d)\n", ++ ioc->name, ioc->request, ioc->scsiio_depth)); ++ ++ ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH); ++ sz = ioc->chain_depth * sizeof(struct chain_tracker); ++ ioc->chain_pages = get_order(sz); ++ ioc->chain_lookup = (struct chain_tracker *)__get_free_pages( ++ GFP_KERNEL, ioc->chain_pages); ++ if (!ioc->chain_lookup) { ++ pr_err(MPT3SAS_FMT "chain_lookup: __get_free_pages failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev, ++ ioc->chain_segment_sz, 16, 0); ++ if (!ioc->chain_dma_pool) { ++ pr_err(MPT3SAS_FMT "chain_dma_pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ for (i = 0; i < ioc->chain_depth; i++) { ++ ioc->chain_lookup[i].chain_buffer = pci_pool_alloc( ++ ioc->chain_dma_pool , GFP_KERNEL, ++ &ioc->chain_lookup[i].chain_buffer_dma); ++ if (!ioc->chain_lookup[i].chain_buffer) { ++ ioc->chain_depth = i; ++ goto chain_done; ++ } ++ total_sz += ioc->chain_segment_sz; ++ } ++ chain_done: ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n", ++ ioc->name, ioc->chain_depth, ioc->chain_segment_sz, ++ ((ioc->chain_depth * ioc->chain_segment_sz))/1024)); ++ ++ /* initialize hi-priority queue smid's */ ++ ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, ++ sizeof(struct request_tracker), GFP_KERNEL); ++ if (!ioc->hpr_lookup) { ++ pr_err(MPT3SAS_FMT "hpr_lookup: kcalloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->hi_priority_smid = ioc->scsiio_depth + 1; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "hi_priority(0x%p): depth(%d), start smid(%d)\n", ++ ioc->name, ioc->hi_priority, ++ ioc->hi_priority_depth, ioc->hi_priority_smid)); ++ ++ /* initialize internal queue smid's */ ++ ioc->internal_lookup = kcalloc(ioc->internal_depth, ++ sizeof(struct request_tracker), GFP_KERNEL); ++ if (!ioc->internal_lookup) { ++ pr_err(MPT3SAS_FMT "internal_lookup: kcalloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->internal_smid = ioc->hi_priority_smid + ioc->hi_priority_depth; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "internal(0x%p): depth(%d), start smid(%d)\n", ++ ioc->name, ioc->internal, ++ ioc->internal_depth, ioc->internal_smid)); ++ ++ /* sense buffers, 4 byte align */ ++ sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE; ++ ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4, ++ 0); ++ if (!ioc->sense_dma_pool) { ++ pr_err(MPT3SAS_FMT "sense pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->sense = pci_pool_alloc(ioc->sense_dma_pool , GFP_KERNEL, ++ &ioc->sense_dma); ++ if (!ioc->sense) { ++ pr_err(MPT3SAS_FMT "sense pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "sense pool(0x%p): depth(%d), element_size(%d), pool_size" ++ "(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth, ++ SCSI_SENSE_BUFFERSIZE, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "sense_dma(0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->sense_dma)); ++ total_sz += sz; ++ ++ /* reply pool, 4 byte align */ ++ sz = ioc->reply_free_queue_depth * ioc->reply_sz; ++ ioc->reply_dma_pool = pci_pool_create("reply pool", ioc->pdev, sz, 4, ++ 0); ++ if (!ioc->reply_dma_pool) { ++ pr_err(MPT3SAS_FMT "reply pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply = pci_pool_alloc(ioc->reply_dma_pool , GFP_KERNEL, ++ &ioc->reply_dma); ++ if (!ioc->reply) { ++ pr_err(MPT3SAS_FMT "reply pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply_dma_min_address = (u32)(ioc->reply_dma); ++ ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n", ++ ioc->name, ioc->reply, ++ ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "reply_dma(0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->reply_dma)); ++ total_sz += sz; ++ ++ /* reply free queue, 16 byte align */ ++ sz = ioc->reply_free_queue_depth * 4; ++ ioc->reply_free_dma_pool = pci_pool_create("reply_free pool", ++ ioc->pdev, sz, 16, 0); ++ if (!ioc->reply_free_dma_pool) { ++ pr_err(MPT3SAS_FMT "reply_free pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply_free = pci_pool_alloc(ioc->reply_free_dma_pool , GFP_KERNEL, ++ &ioc->reply_free_dma); ++ if (!ioc->reply_free) { ++ pr_err(MPT3SAS_FMT "reply_free pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ memset(ioc->reply_free, 0, sz); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "reply_free pool(0x%p): " \ ++ "depth(%d), element_size(%d), pool_size(%d kB)\n", ioc->name, ++ ioc->reply_free, ioc->reply_free_queue_depth, 4, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_free_dma (0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->reply_free_dma)); ++ total_sz += sz; ++ ++ ioc->config_page_sz = 512; ++ ioc->config_page = pci_alloc_consistent(ioc->pdev, ++ ioc->config_page_sz, &ioc->config_page_dma); ++ if (!ioc->config_page) { ++ pr_err(MPT3SAS_FMT ++ "config page: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "config page(0x%p): size(%d)\n", ++ ioc->name, ioc->config_page, ioc->config_page_sz)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "config_page_dma(0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->config_page_dma)); ++ total_sz += ioc->config_page_sz; ++ ++ pr_info(MPT3SAS_FMT "Allocated physical memory: size(%d kB)\n", ++ ioc->name, total_sz/1024); ++ pr_info(MPT3SAS_FMT ++ "Current Controller Queue Depth(%d),Max Controller Queue Depth(%d)\n", ++ ioc->name, ioc->shost->can_queue, facts->RequestCredit); ++ pr_info(MPT3SAS_FMT "Scatter Gather Elements per IO(%d)\n", ++ ioc->name, ioc->shost->sg_tablesize); ++ return 0; ++ ++ out: ++ return -ENOMEM; ++} ++ ++/** ++ * mpt2sas_base_get_iocstate - Get the current state of a MPT adapter. ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @cooked: Request raw or cooked IOC state ++ * ++ * Returns all IOC Doorbell register bits if cooked==0, else just the ++ * Doorbell bits in MPI_IOC_STATE_MASK. ++ */ ++u32 ++mpt2sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked) ++{ ++ u32 s, sc; ++ ++ s = readl(&ioc->chip->Doorbell); ++ sc = s & MPI2_IOC_STATE_MASK; ++ return cooked ? sc : s; ++} ++ ++/** ++ * _base_wait_on_iocstate - waiting on a particular ioc state ++ * @ioc_state: controller state { READY, OPERATIONAL, or RESET } ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, u32 ioc_state, int timeout, ++ int sleep_flag) ++{ ++ u32 count, cntdn; ++ u32 current_state; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ current_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (current_state == ioc_state) ++ return 0; ++ if (count && current_state == MPI2_IOC_STATE_FAULT) ++ break; ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ return current_state; ++} ++ ++/** ++ * _base_wait_for_doorbell_int - waiting for controller interrupt(generated by ++ * a write to the doorbell) ++ * @ioc: per adapter object ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ * Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell. ++ */ ++static int ++_base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag); ++ ++static int ++_base_wait_for_doorbell_int(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 cntdn, count; ++ u32 int_status; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ int_status = readl(&ioc->chip->HostInterruptStatus); ++ if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: successful count(%d), timeout(%d)\n", ++ ioc->name, __func__, count, timeout)); ++ return 0; ++ } ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to timeout count(%d), int_status(%x)!\n", ++ ioc->name, __func__, count, int_status); ++ return -EFAULT; ++} ++ ++/** ++ * _base_wait_for_doorbell_ack - waiting for controller to read the doorbell. ++ * @ioc: per adapter object ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ * Notes: MPI2_HIS_SYS2IOC_DB_STATUS - set to one when host writes to ++ * doorbell. ++ */ ++static int ++_base_wait_for_doorbell_ack(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 cntdn, count; ++ u32 int_status; ++ u32 doorbell; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ int_status = readl(&ioc->chip->HostInterruptStatus); ++ if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: successful count(%d), timeout(%d)\n", ++ ioc->name, __func__, count, timeout)); ++ return 0; ++ } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { ++ doorbell = readl(&ioc->chip->Doorbell); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == ++ MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc , doorbell); ++ return -EFAULT; ++ } ++ } else if (int_status == 0xFFFFFFFF) ++ goto out; ++ ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ out: ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to timeout count(%d), int_status(%x)!\n", ++ ioc->name, __func__, count, int_status); ++ return -EFAULT; ++} ++ ++/** ++ * _base_wait_for_doorbell_not_used - waiting for doorbell to not be in use ++ * @ioc: per adapter object ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_base_wait_for_doorbell_not_used(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 cntdn, count; ++ u32 doorbell_reg; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ doorbell_reg = readl(&ioc->chip->Doorbell); ++ if (!(doorbell_reg & MPI2_DOORBELL_USED)) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: successful count(%d), timeout(%d)\n", ++ ioc->name, __func__, count, timeout)); ++ return 0; ++ } ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to timeout count(%d), doorbell_reg(%x)!\n", ++ ioc->name, __func__, count, doorbell_reg); ++ return -EFAULT; ++} ++ ++/** ++ * _base_send_ioc_reset - send doorbell reset ++ * @ioc: per adapter object ++ * @reset_type: currently only supports: MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_send_ioc_reset(struct MPT3SAS_ADAPTER *ioc, u8 reset_type, int timeout, ++ int sleep_flag) ++{ ++ u32 ioc_state; ++ int r = 0; ++ ++ if (reset_type != MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET) { ++ pr_err(MPT3SAS_FMT "%s: unknown reset_type\n", ++ ioc->name, __func__); ++ return -EFAULT; ++ } ++ ++ if (!(ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY)) ++ return -EFAULT; ++ ++ pr_info(MPT3SAS_FMT "sending message unit reset !!\n", ioc->name); ++ ++ writel(reset_type << MPI2_DOORBELL_FUNCTION_SHIFT, ++ &ioc->chip->Doorbell); ++ if ((_base_wait_for_doorbell_ack(ioc, 15, sleep_flag))) { ++ r = -EFAULT; ++ goto out; ++ } ++ ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, ++ timeout, sleep_flag); ++ if (ioc_state) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state); ++ r = -EFAULT; ++ goto out; ++ } ++ out: ++ pr_info(MPT3SAS_FMT "message unit reset: %s\n", ++ ioc->name, ((r == 0) ? "SUCCESS" : "FAILED")); ++ return r; ++} ++ ++/** ++ * _base_handshake_req_reply_wait - send request thru doorbell interface ++ * @ioc: per adapter object ++ * @request_bytes: request length ++ * @request: pointer having request payload ++ * @reply_bytes: reply length ++ * @reply: pointer to reply payload ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, ++ u32 *request, int reply_bytes, u16 *reply, int timeout, int sleep_flag) ++{ ++ MPI2DefaultReply_t *default_reply = (MPI2DefaultReply_t *)reply; ++ int i; ++ u8 failed; ++ u16 dummy; ++ __le32 *mfp; ++ ++ /* make sure doorbell is not in use */ ++ if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { ++ pr_err(MPT3SAS_FMT ++ "doorbell is in use (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* clear pending doorbell interrupts from previous state changes */ ++ if (readl(&ioc->chip->HostInterruptStatus) & ++ MPI2_HIS_IOC2SYS_DB_STATUS) ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ /* send message to ioc */ ++ writel(((MPI2_FUNCTION_HANDSHAKE<chip->Doorbell); ++ ++ if ((_base_wait_for_doorbell_int(ioc, 5, NO_SLEEP))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake ack failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* send message 32-bits at a time */ ++ for (i = 0, failed = 0; i < request_bytes/4 && !failed; i++) { ++ writel(cpu_to_le32(request[i]), &ioc->chip->Doorbell); ++ if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag))) ++ failed = 1; ++ } ++ ++ if (failed) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake sending request failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* now wait for the reply */ ++ if ((_base_wait_for_doorbell_int(ioc, timeout, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* read the first two 16-bits, it gives the total length of the reply */ ++ reply[0] = le16_to_cpu(readl(&ioc->chip->Doorbell) ++ & MPI2_DOORBELL_DATA_MASK); ++ writel(0, &ioc->chip->HostInterruptStatus); ++ if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ reply[1] = le16_to_cpu(readl(&ioc->chip->Doorbell) ++ & MPI2_DOORBELL_DATA_MASK); ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ for (i = 2; i < default_reply->MsgLength * 2; i++) { ++ if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ if (i >= reply_bytes/2) /* overflow case */ ++ dummy = readl(&ioc->chip->Doorbell); ++ else ++ reply[i] = le16_to_cpu(readl(&ioc->chip->Doorbell) ++ & MPI2_DOORBELL_DATA_MASK); ++ writel(0, &ioc->chip->HostInterruptStatus); ++ } ++ ++ _base_wait_for_doorbell_int(ioc, 5, sleep_flag); ++ if (_base_wait_for_doorbell_not_used(ioc, 5, sleep_flag) != 0) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "doorbell is in use (line=%d)\n", ioc->name, __LINE__)); ++ } ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ if (ioc->logging_level & MPT_DEBUG_INIT) { ++ mfp = (__le32 *)reply; ++ pr_info("\toffset:data\n"); ++ for (i = 0; i < reply_bytes/4; i++) ++ pr_info("\t[0x%02x]:%08x\n", i*4, ++ le32_to_cpu(mfp[i])); ++ } ++ return 0; ++} ++ ++/** ++ * mpt2sas_base_sas_iounit_control - send sas iounit control to FW ++ * @ioc: per adapter object ++ * @mpi_reply: the reply payload from FW ++ * @mpi_request: the request payload sent to FW ++ * ++ * The SAS IO Unit Control Request message allows the host to perform low-level ++ * operations, such as resets on the PHYs of the IO Unit, also allows the host ++ * to obtain the IOC assigned device handles for a device if it has other ++ * identifying information about the device, in addition allows the host to ++ * remove IOC resources associated with the device. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SasIoUnitControlReply_t *mpi_reply, ++ Mpi2SasIoUnitControlRequest_t *mpi_request) ++{ ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ bool issue_reset = false; ++ int rc; ++ void *request; ++ u16 wait_state_count; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mutex_lock(&ioc->base_cmds.mutex); ++ ++ if (ioc->base_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: base_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->base_cmds.status = MPT3_CMD_PENDING; ++ request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->base_cmds.smid = smid; ++ memcpy(request, mpi_request, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || ++ mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) ++ ioc->ioc_link_reset_in_progress = 1; ++ init_completion(&ioc->base_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, ++ msecs_to_jiffies(10000)); ++ if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || ++ mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) && ++ ioc->ioc_link_reset_in_progress) ++ ioc->ioc_link_reset_in_progress = 0; ++ if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SasIoUnitControlRequest_t)/4); ++ if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = true; ++ goto issue_host_reset; ++ } ++ if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) ++ memcpy(mpi_reply, ioc->base_cmds.reply, ++ sizeof(Mpi2SasIoUnitControlReply_t)); ++ else ++ memset(mpi_reply, 0, sizeof(Mpi2SasIoUnitControlReply_t)); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ goto out; ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ rc = -EFAULT; ++ out: ++ mutex_unlock(&ioc->base_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * mpt2sas_base_scsi_enclosure_processor - sending request to sep device ++ * @ioc: per adapter object ++ * @mpi_reply: the reply payload from FW ++ * @mpi_request: the request payload sent to FW ++ * ++ * The SCSI Enclosure Processor request message causes the IOC to ++ * communicate with SES devices to control LED status signals. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request) ++{ ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ bool issue_reset = false; ++ int rc; ++ void *request; ++ u16 wait_state_count; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mutex_lock(&ioc->base_cmds.mutex); ++ ++ if (ioc->base_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: base_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, ++ __func__, wait_state_count); ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->base_cmds.status = MPT3_CMD_PENDING; ++ request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->base_cmds.smid = smid; ++ memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); ++ init_completion(&ioc->base_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, ++ msecs_to_jiffies(10000)); ++ if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SepRequest_t)/4); ++ if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = false; ++ goto issue_host_reset; ++ } ++ if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) ++ memcpy(mpi_reply, ioc->base_cmds.reply, ++ sizeof(Mpi2SepReply_t)); ++ else ++ memset(mpi_reply, 0, sizeof(Mpi2SepReply_t)); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ goto out; ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ rc = -EFAULT; ++ out: ++ mutex_unlock(&ioc->base_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _base_get_port_facts - obtain port facts reply and save in ioc ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_get_port_facts(struct MPT3SAS_ADAPTER *ioc, int port, int sleep_flag) ++{ ++ Mpi2PortFactsRequest_t mpi_request; ++ Mpi2PortFactsReply_t mpi_reply; ++ struct mpt2sas_port_facts *pfacts; ++ int mpi_reply_sz, mpi_request_sz, r; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mpi_reply_sz = sizeof(Mpi2PortFactsReply_t); ++ mpi_request_sz = sizeof(Mpi2PortFactsRequest_t); ++ memset(&mpi_request, 0, mpi_request_sz); ++ mpi_request.Function = MPI2_FUNCTION_PORT_FACTS; ++ mpi_request.PortNumber = port; ++ r = _base_handshake_req_reply_wait(ioc, mpi_request_sz, ++ (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP); ++ ++ if (r != 0) { ++ pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", ++ ioc->name, __func__, r); ++ return r; ++ } ++ ++ pfacts = &ioc->pfacts[port]; ++ memset(pfacts, 0, sizeof(struct mpt2sas_port_facts)); ++ pfacts->PortNumber = mpi_reply.PortNumber; ++ pfacts->VP_ID = mpi_reply.VP_ID; ++ pfacts->VF_ID = mpi_reply.VF_ID; ++ pfacts->MaxPostedCmdBuffers = ++ le16_to_cpu(mpi_reply.MaxPostedCmdBuffers); ++ ++ return 0; ++} ++ ++/** ++ * _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL ++ * @ioc: per adapter object ++ * @timeout: ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_wait_for_iocstate(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 ioc_state; ++ int rc; ++ ++ dinitprintk(ioc, printk(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->pci_error_recovery) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "%s: host in pci error recovery\n", ioc->name, __func__)); ++ return -EFAULT; ++ } ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ dhsprintk(ioc, printk(MPT3SAS_FMT "%s: ioc_state(0x%08x)\n", ++ ioc->name, __func__, ioc_state)); ++ ++ if (((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) || ++ (ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) ++ return 0; ++ ++ if (ioc_state & MPI2_DOORBELL_USED) { ++ dhsprintk(ioc, printk(MPT3SAS_FMT ++ "unexpected doorbell active!\n", ioc->name)); ++ goto issue_diag_reset; ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc, ioc_state & ++ MPI2_DOORBELL_DATA_MASK); ++ goto issue_diag_reset; ++ } ++ ++ ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, ++ timeout, sleep_flag); ++ if (ioc_state) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state)); ++ return -EFAULT; ++ } ++ ++ issue_diag_reset: ++ rc = _base_diag_reset(ioc, sleep_flag); ++ return rc; ++} ++ ++/** ++ * _base_get_ioc_facts - obtain ioc facts reply and save in ioc ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2IOCFactsRequest_t mpi_request; ++ Mpi2IOCFactsReply_t mpi_reply; ++ struct mpt2sas_facts *facts; ++ int mpi_reply_sz, mpi_request_sz, r; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ r = _base_wait_for_iocstate(ioc, 10, sleep_flag); ++ if (r) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "%s: failed getting to correct state\n", ++ ioc->name, __func__)); ++ return r; ++ } ++ mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); ++ mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t); ++ memset(&mpi_request, 0, mpi_request_sz); ++ mpi_request.Function = MPI2_FUNCTION_IOC_FACTS; ++ r = _base_handshake_req_reply_wait(ioc, mpi_request_sz, ++ (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP); ++ ++ if (r != 0) { ++ pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", ++ ioc->name, __func__, r); ++ return r; ++ } ++ ++ facts = &ioc->facts; ++ memset(facts, 0, sizeof(struct mpt2sas_facts)); ++ facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion); ++ facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion); ++ facts->VP_ID = mpi_reply.VP_ID; ++ facts->VF_ID = mpi_reply.VF_ID; ++ facts->IOCExceptions = le16_to_cpu(mpi_reply.IOCExceptions); ++ facts->MaxChainDepth = mpi_reply.MaxChainDepth; ++ facts->WhoInit = mpi_reply.WhoInit; ++ facts->NumberOfPorts = mpi_reply.NumberOfPorts; ++ facts->MaxMSIxVectors = mpi_reply.MaxMSIxVectors; ++ facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit); ++ facts->MaxReplyDescriptorPostQueueDepth = ++ le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth); ++ facts->ProductID = le16_to_cpu(mpi_reply.ProductID); ++ facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities); ++ if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) ++ ioc->ir_firmware = 1; ++ if ((facts->IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE)) ++ ioc->rdpq_array_capable = 1; ++ facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); ++ facts->IOCRequestFrameSize = ++ le16_to_cpu(mpi_reply.IOCRequestFrameSize); ++ if (ioc->hba_mpi_version_belonged != MPI2_VERSION) { ++ facts->IOCMaxChainSegmentSize = ++ le16_to_cpu(mpi_reply.IOCMaxChainSegmentSize); ++ } ++ facts->MaxInitiators = le16_to_cpu(mpi_reply.MaxInitiators); ++ facts->MaxTargets = le16_to_cpu(mpi_reply.MaxTargets); ++ ioc->shost->max_id = -1; ++ facts->MaxSasExpanders = le16_to_cpu(mpi_reply.MaxSasExpanders); ++ facts->MaxEnclosures = le16_to_cpu(mpi_reply.MaxEnclosures); ++ facts->ProtocolFlags = le16_to_cpu(mpi_reply.ProtocolFlags); ++ facts->HighPriorityCredit = ++ le16_to_cpu(mpi_reply.HighPriorityCredit); ++ facts->ReplyFrameSize = mpi_reply.ReplyFrameSize; ++ facts->MaxDevHandle = le16_to_cpu(mpi_reply.MaxDevHandle); ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "hba queue depth(%d), max chains per io(%d)\n", ++ ioc->name, facts->RequestCredit, ++ facts->MaxChainDepth)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "request frame size(%d), reply frame size(%d)\n", ioc->name, ++ facts->IOCRequestFrameSize * 4, facts->ReplyFrameSize * 4)); ++ return 0; ++} ++ ++/** ++ * _base_send_ioc_init - send ioc_init to firmware ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2IOCInitRequest_t mpi_request; ++ Mpi2IOCInitReply_t mpi_reply; ++ int i, r = 0; ++ ktime_t current_time; ++ u16 ioc_status; ++ u32 reply_post_free_array_sz = 0; ++ Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL; ++ dma_addr_t reply_post_free_array_dma; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_IOC_INIT; ++ mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER; ++ mpi_request.VF_ID = 0; /* TODO */ ++ mpi_request.VP_ID = 0; ++ mpi_request.MsgVersion = cpu_to_le16(ioc->hba_mpi_version_belonged); ++ mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); ++ ++ if (_base_is_controller_msix_enabled(ioc)) ++ mpi_request.HostMSIxVectors = ioc->reply_queue_count; ++ mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); ++ mpi_request.ReplyDescriptorPostQueueDepth = ++ cpu_to_le16(ioc->reply_post_queue_depth); ++ mpi_request.ReplyFreeQueueDepth = ++ cpu_to_le16(ioc->reply_free_queue_depth); ++ ++ mpi_request.SenseBufferAddressHigh = ++ cpu_to_le32((u64)ioc->sense_dma >> 32); ++ mpi_request.SystemReplyAddressHigh = ++ cpu_to_le32((u64)ioc->reply_dma >> 32); ++ mpi_request.SystemRequestFrameBaseAddress = ++ cpu_to_le64((u64)ioc->request_dma); ++ mpi_request.ReplyFreeQueueAddress = ++ cpu_to_le64((u64)ioc->reply_free_dma); ++ ++ if (ioc->rdpq_array_enable) { ++ reply_post_free_array_sz = ioc->reply_queue_count * ++ sizeof(Mpi2IOCInitRDPQArrayEntry); ++ reply_post_free_array = pci_alloc_consistent(ioc->pdev, ++ reply_post_free_array_sz, &reply_post_free_array_dma); ++ if (!reply_post_free_array) { ++ pr_err(MPT3SAS_FMT ++ "reply_post_free_array: pci_alloc_consistent failed\n", ++ ioc->name); ++ r = -ENOMEM; ++ goto out; ++ } ++ memset(reply_post_free_array, 0, reply_post_free_array_sz); ++ for (i = 0; i < ioc->reply_queue_count; i++) ++ reply_post_free_array[i].RDPQBaseAddress = ++ cpu_to_le64( ++ (u64)ioc->reply_post[i].reply_post_free_dma); ++ mpi_request.MsgFlags = MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE; ++ mpi_request.ReplyDescriptorPostQueueAddress = ++ cpu_to_le64((u64)reply_post_free_array_dma); ++ } else { ++ mpi_request.ReplyDescriptorPostQueueAddress = ++ cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma); ++ } ++ ++ /* This time stamp specifies number of milliseconds ++ * since epoch ~ midnight January 1, 1970. ++ */ ++ current_time = ktime_get_real(); ++ mpi_request.TimeStamp = cpu_to_le64(ktime_to_ms(current_time)); ++ ++ if (ioc->logging_level & MPT_DEBUG_INIT) { ++ __le32 *mfp; ++ int i; ++ ++ mfp = (__le32 *)&mpi_request; ++ pr_info("\toffset:data\n"); ++ for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) ++ pr_info("\t[0x%02x]:%08x\n", i*4, ++ le32_to_cpu(mfp[i])); ++ } ++ ++ r = _base_handshake_req_reply_wait(ioc, ++ sizeof(Mpi2IOCInitRequest_t), (u32 *)&mpi_request, ++ sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 10, ++ sleep_flag); ++ ++ if (r != 0) { ++ pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", ++ ioc->name, __func__, r); ++ goto out; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS || ++ mpi_reply.IOCLogInfo) { ++ pr_err(MPT3SAS_FMT "%s: failed\n", ioc->name, __func__); ++ r = -EIO; ++ } ++ ++out: ++ if (reply_post_free_array) ++ pci_free_consistent(ioc->pdev, reply_post_free_array_sz, ++ reply_post_free_array, ++ reply_post_free_array_dma); ++ return r; ++} ++ ++/** ++ * mpt2sas_port_enable_done - command completion routine for port enable ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_port_enable_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ u16 ioc_status; ++ ++ if (ioc->port_enable_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (!mpi_reply) ++ return 1; ++ ++ if (mpi_reply->Function != MPI2_FUNCTION_PORT_ENABLE) ++ return 1; ++ ++ ioc->port_enable_cmds.status &= ~MPT3_CMD_PENDING; ++ ioc->port_enable_cmds.status |= MPT3_CMD_COMPLETE; ++ ioc->port_enable_cmds.status |= MPT3_CMD_REPLY_VALID; ++ memcpy(ioc->port_enable_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ ioc->port_enable_failed = 1; ++ ++ if (ioc->is_driver_loading) { ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ mpt2sas_port_enable_complete(ioc); ++ return 1; ++ } else { ++ ioc->start_scan_failed = ioc_status; ++ ioc->start_scan = 0; ++ return 1; ++ } ++ } ++ complete(&ioc->port_enable_cmds.done); ++ return 1; ++} ++ ++/** ++ * _base_send_port_enable - send port_enable(discovery stuff) to firmware ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_send_port_enable(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2PortEnableRequest_t *mpi_request; ++ Mpi2PortEnableReply_t *mpi_reply; ++ unsigned long timeleft; ++ int r = 0; ++ u16 smid; ++ u16 ioc_status; ++ ++ pr_info(MPT3SAS_FMT "sending port enable !!\n", ioc->name); ++ ++ if (ioc->port_enable_cmds.status & MPT3_CMD_PENDING) { ++ pr_err(MPT3SAS_FMT "%s: internal command already in use\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ ioc->port_enable_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->port_enable_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; ++ ++ init_completion(&ioc->port_enable_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done, ++ 300*HZ); ++ if (!(ioc->port_enable_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2PortEnableRequest_t)/4); ++ if (ioc->port_enable_cmds.status & MPT3_CMD_RESET) ++ r = -EFAULT; ++ else ++ r = -ETIME; ++ goto out; ++ } ++ ++ mpi_reply = ioc->port_enable_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "%s: failed with (ioc_status=0x%08x)\n", ++ ioc->name, __func__, ioc_status); ++ r = -EFAULT; ++ goto out; ++ } ++ ++ out: ++ ioc->port_enable_cmds.status = MPT3_CMD_NOT_USED; ++ pr_info(MPT3SAS_FMT "port enable: %s\n", ioc->name, ((r == 0) ? ++ "SUCCESS" : "FAILED")); ++ return r; ++} ++ ++/** ++ * mpt2sas_port_enable - initiate firmware discovery (don't wait for reply) ++ * @ioc: per adapter object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_port_enable(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2PortEnableRequest_t *mpi_request; ++ u16 smid; ++ ++ pr_info(MPT3SAS_FMT "sending port enable !!\n", ioc->name); ++ ++ if (ioc->port_enable_cmds.status & MPT3_CMD_PENDING) { ++ pr_err(MPT3SAS_FMT "%s: internal command already in use\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ ioc->port_enable_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->port_enable_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; ++ ++ mpt2sas_base_put_smid_default(ioc, smid); ++ return 0; ++} ++ ++/** ++ * _base_determine_wait_on_discovery - desposition ++ * @ioc: per adapter object ++ * ++ * Decide whether to wait on discovery to complete. Used to either ++ * locate boot device, or report volumes ahead of physical devices. ++ * ++ * Returns 1 for wait, 0 for don't wait ++ */ ++static int ++_base_determine_wait_on_discovery(struct MPT3SAS_ADAPTER *ioc) ++{ ++ /* We wait for discovery to complete if IR firmware is loaded. ++ * The sas topology events arrive before PD events, so we need time to ++ * turn on the bit in ioc->pd_handles to indicate PD ++ * Also, it maybe required to report Volumes ahead of physical ++ * devices when MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING is set. ++ */ ++ if (ioc->ir_firmware) ++ return 1; ++ ++ /* if no Bios, then we don't need to wait */ ++ if (!ioc->bios_pg3.BiosVersion) ++ return 0; ++ ++ /* Bios is present, then we drop down here. ++ * ++ * If there any entries in the Bios Page 2, then we wait ++ * for discovery to complete. ++ */ ++ ++ /* Current Boot Device */ ++ if ((ioc->bios_pg2.CurrentBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK) == ++ MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED && ++ /* Request Boot Device */ ++ (ioc->bios_pg2.ReqBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK) == ++ MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED && ++ /* Alternate Request Boot Device */ ++ (ioc->bios_pg2.ReqAltBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK) == ++ MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED) ++ return 0; ++ ++ return 1; ++} ++ ++/** ++ * _base_unmask_events - turn on notification for this event ++ * @ioc: per adapter object ++ * @event: firmware event ++ * ++ * The mask is stored in ioc->event_masks. ++ */ ++static void ++_base_unmask_events(struct MPT3SAS_ADAPTER *ioc, u16 event) ++{ ++ u32 desired_event; ++ ++ if (event >= 128) ++ return; ++ ++ desired_event = (1 << (event % 32)); ++ ++ if (event < 32) ++ ioc->event_masks[0] &= ~desired_event; ++ else if (event < 64) ++ ioc->event_masks[1] &= ~desired_event; ++ else if (event < 96) ++ ioc->event_masks[2] &= ~desired_event; ++ else if (event < 128) ++ ioc->event_masks[3] &= ~desired_event; ++} ++ ++/** ++ * _base_event_notification - send event notification ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_event_notification(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2EventNotificationRequest_t *mpi_request; ++ unsigned long timeleft; ++ u16 smid; ++ int r = 0; ++ int i; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->base_cmds.status & MPT3_CMD_PENDING) { ++ pr_err(MPT3SAS_FMT "%s: internal command already in use\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ioc->base_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->base_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2EventNotificationRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) ++ mpi_request->EventMasks[i] = ++ cpu_to_le32(ioc->event_masks[i]); ++ init_completion(&ioc->base_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); ++ if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2EventNotificationRequest_t)/4); ++ if (ioc->base_cmds.status & MPT3_CMD_RESET) ++ r = -EFAULT; ++ else ++ r = -ETIME; ++ } else ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s: complete\n", ++ ioc->name, __func__)); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ return r; ++} ++ ++/** ++ * mpt2sas_base_validate_event_type - validating event types ++ * @ioc: per adapter object ++ * @event: firmware event ++ * ++ * This will turn on firmware event notification when application ++ * ask for that event. We don't mask events that are already enabled. ++ */ ++void ++mpt2sas_base_validate_event_type(struct MPT3SAS_ADAPTER *ioc, u32 *event_type) ++{ ++ int i, j; ++ u32 event_mask, desired_event; ++ u8 send_update_to_fw; ++ ++ for (i = 0, send_update_to_fw = 0; i < ++ MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) { ++ event_mask = ~event_type[i]; ++ desired_event = 1; ++ for (j = 0; j < 32; j++) { ++ if (!(event_mask & desired_event) && ++ (ioc->event_masks[i] & desired_event)) { ++ ioc->event_masks[i] &= ~desired_event; ++ send_update_to_fw = 1; ++ } ++ desired_event = (desired_event << 1); ++ } ++ } ++ ++ if (!send_update_to_fw) ++ return; ++ ++ mutex_lock(&ioc->base_cmds.mutex); ++ _base_event_notification(ioc, CAN_SLEEP); ++ mutex_unlock(&ioc->base_cmds.mutex); ++} ++ ++/** ++ * _base_diag_reset - the "big hammer" start of day reset ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ u32 host_diagnostic; ++ u32 ioc_state; ++ u32 count; ++ u32 hcb_size; ++ ++ pr_info(MPT3SAS_FMT "sending diag reset !!\n", ioc->name); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT "clear interrupts\n", ++ ioc->name)); ++ ++ count = 0; ++ do { ++ /* Write magic sequence to WriteSequence register ++ * Loop until in diagnostic mode ++ */ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "write magic sequence\n", ioc->name)); ++ writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_2ND_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_3RD_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_4TH_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_5TH_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_6TH_KEY_VALUE, &ioc->chip->WriteSequence); ++ ++ /* wait 100 msec */ ++ if (sleep_flag == CAN_SLEEP) ++ msleep(100); ++ else ++ mdelay(100); ++ ++ if (count++ > 20) ++ goto out; ++ ++ host_diagnostic = readl(&ioc->chip->HostDiagnostic); ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "wrote magic sequence: count(%d), host_diagnostic(0x%08x)\n", ++ ioc->name, count, host_diagnostic)); ++ ++ } while ((host_diagnostic & MPI2_DIAG_DIAG_WRITE_ENABLE) == 0); ++ ++ hcb_size = readl(&ioc->chip->HCBSize); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT "diag reset: issued\n", ++ ioc->name)); ++ writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, ++ &ioc->chip->HostDiagnostic); ++ ++ /*This delay allows the chip PCIe hardware time to finish reset tasks*/ ++ if (sleep_flag == CAN_SLEEP) ++ msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); ++ else ++ mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); ++ ++ /* Approximately 300 second max wait */ ++ for (count = 0; count < (300000000 / ++ MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) { ++ ++ host_diagnostic = readl(&ioc->chip->HostDiagnostic); ++ ++ if (host_diagnostic == 0xFFFFFFFF) ++ goto out; ++ if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER)) ++ break; ++ ++ /* Wait to pass the second read delay window */ ++ if (sleep_flag == CAN_SLEEP) ++ msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC ++ / 1000); ++ else ++ mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC ++ / 1000); ++ } ++ ++ if (host_diagnostic & MPI2_DIAG_HCB_MODE) { ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "restart the adapter assuming the HCB Address points to good F/W\n", ++ ioc->name)); ++ host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK; ++ host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW; ++ writel(host_diagnostic, &ioc->chip->HostDiagnostic); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "re-enable the HCDW\n", ioc->name)); ++ writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE, ++ &ioc->chip->HCBSize); ++ } ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT "restart the adapter\n", ++ ioc->name)); ++ writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET, ++ &ioc->chip->HostDiagnostic); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "disable writes to the diagnostic register\n", ioc->name)); ++ writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "Wait for FW to go to the READY state\n", ioc->name)); ++ ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20, ++ sleep_flag); ++ if (ioc_state) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state); ++ goto out; ++ } ++ ++ pr_info(MPT3SAS_FMT "diag reset: SUCCESS\n", ioc->name); ++ return 0; ++ ++ out: ++ pr_err(MPT3SAS_FMT "diag reset: FAILED\n", ioc->name); ++ return -EFAULT; ++} ++ ++/** ++ * _base_make_ioc_ready - put controller in READY state ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * @type: FORCE_BIG_HAMMER or SOFT_RESET ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, ++ enum reset_type type) ++{ ++ u32 ioc_state; ++ int rc; ++ int count; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->pci_error_recovery) ++ return 0; ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT "%s: ioc_state(0x%08x)\n", ++ ioc->name, __func__, ioc_state)); ++ ++ /* if in RESET state, it should move to READY state shortly */ ++ count = 0; ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { ++ while ((ioc_state & MPI2_IOC_STATE_MASK) != ++ MPI2_IOC_STATE_READY) { ++ if (count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state); ++ return -EFAULT; ++ } ++ if (sleep_flag == CAN_SLEEP) ++ ssleep(1); ++ else ++ mdelay(1000); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ } ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) ++ return 0; ++ ++ if (ioc_state & MPI2_DOORBELL_USED) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "unexpected doorbell active!\n", ++ ioc->name)); ++ goto issue_diag_reset; ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc, ioc_state & ++ MPI2_DOORBELL_DATA_MASK); ++ goto issue_diag_reset; ++ } ++ ++ if (type == FORCE_BIG_HAMMER) ++ goto issue_diag_reset; ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) ++ if (!(_base_send_ioc_reset(ioc, ++ MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) { ++ return 0; ++ } ++ ++ issue_diag_reset: ++ rc = _base_diag_reset(ioc, CAN_SLEEP); ++ return rc; ++} ++ ++/** ++ * _base_make_ioc_operational - put controller in OPERATIONAL state ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ int r, i, index; ++ unsigned long flags; ++ u32 reply_address; ++ u16 smid; ++ struct _tr_list *delayed_tr, *delayed_tr_next; ++ struct _sc_list *delayed_sc, *delayed_sc_next; ++ struct _event_ack_list *delayed_event_ack, *delayed_event_ack_next; ++ u8 hide_flag; ++ struct adapter_reply_queue *reply_q; ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free_contig; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ /* clean the delayed target reset list */ ++ list_for_each_entry_safe(delayed_tr, delayed_tr_next, ++ &ioc->delayed_tr_list, list) { ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ } ++ ++ ++ list_for_each_entry_safe(delayed_tr, delayed_tr_next, ++ &ioc->delayed_tr_volume_list, list) { ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ } ++ ++ list_for_each_entry_safe(delayed_sc, delayed_sc_next, ++ &ioc->delayed_sc_list, list) { ++ list_del(&delayed_sc->list); ++ kfree(delayed_sc); ++ } ++ ++ list_for_each_entry_safe(delayed_event_ack, delayed_event_ack_next, ++ &ioc->delayed_event_ack_list, list) { ++ list_del(&delayed_event_ack->list); ++ kfree(delayed_event_ack); ++ } ++ ++ /* initialize the scsi lookup free list */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ INIT_LIST_HEAD(&ioc->free_list); ++ smid = 1; ++ for (i = 0; i < ioc->scsiio_depth; i++, smid++) { ++ INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list); ++ ioc->scsi_lookup[i].cb_idx = 0xFF; ++ ioc->scsi_lookup[i].smid = smid; ++ ioc->scsi_lookup[i].scmd = NULL; ++ ioc->scsi_lookup[i].direct_io = 0; ++ list_add_tail(&ioc->scsi_lookup[i].tracker_list, ++ &ioc->free_list); ++ } ++ ++ /* hi-priority queue */ ++ INIT_LIST_HEAD(&ioc->hpr_free_list); ++ smid = ioc->hi_priority_smid; ++ for (i = 0; i < ioc->hi_priority_depth; i++, smid++) { ++ ioc->hpr_lookup[i].cb_idx = 0xFF; ++ ioc->hpr_lookup[i].smid = smid; ++ list_add_tail(&ioc->hpr_lookup[i].tracker_list, ++ &ioc->hpr_free_list); ++ } ++ ++ /* internal queue */ ++ INIT_LIST_HEAD(&ioc->internal_free_list); ++ smid = ioc->internal_smid; ++ for (i = 0; i < ioc->internal_depth; i++, smid++) { ++ ioc->internal_lookup[i].cb_idx = 0xFF; ++ ioc->internal_lookup[i].smid = smid; ++ list_add_tail(&ioc->internal_lookup[i].tracker_list, ++ &ioc->internal_free_list); ++ } ++ ++ /* chain pool */ ++ INIT_LIST_HEAD(&ioc->free_chain_list); ++ for (i = 0; i < ioc->chain_depth; i++) ++ list_add_tail(&ioc->chain_lookup[i].tracker_list, ++ &ioc->free_chain_list); ++ ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ /* initialize Reply Free Queue */ ++ for (i = 0, reply_address = (u32)ioc->reply_dma ; ++ i < ioc->reply_free_queue_depth ; i++, reply_address += ++ ioc->reply_sz) ++ ioc->reply_free[i] = cpu_to_le32(reply_address); ++ ++ /* initialize reply queues */ ++ if (ioc->is_driver_loading) ++ _base_assign_reply_queues(ioc); ++ ++ /* initialize Reply Post Free Queue */ ++ index = 0; ++ reply_post_free_contig = ioc->reply_post[0].reply_post_free; ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ /* ++ * If RDPQ is enabled, switch to the next allocation. ++ * Otherwise advance within the contiguous region. ++ */ ++ if (ioc->rdpq_array_enable) { ++ reply_q->reply_post_free = ++ ioc->reply_post[index++].reply_post_free; ++ } else { ++ reply_q->reply_post_free = reply_post_free_contig; ++ reply_post_free_contig += ioc->reply_post_queue_depth; ++ } ++ ++ reply_q->reply_post_host_index = 0; ++ for (i = 0; i < ioc->reply_post_queue_depth; i++) ++ reply_q->reply_post_free[i].Words = ++ cpu_to_le64(ULLONG_MAX); ++ if (!_base_is_controller_msix_enabled(ioc)) ++ goto skip_init_reply_post_free_queue; ++ } ++ skip_init_reply_post_free_queue: ++ ++ r = _base_send_ioc_init(ioc, sleep_flag); ++ if (r) ++ return r; ++ ++ /* initialize reply free host index */ ++ ioc->reply_free_host_index = ioc->reply_free_queue_depth - 1; ++ writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex); ++ ++ /* initialize reply post host index */ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ if (ioc->msix96_vector) ++ writel((reply_q->msix_index & 7)<< ++ MPI2_RPHI_MSIX_INDEX_SHIFT, ++ ioc->replyPostRegisterIndex[reply_q->msix_index/8]); ++ else ++ writel(reply_q->msix_index << ++ MPI2_RPHI_MSIX_INDEX_SHIFT, ++ &ioc->chip->ReplyPostHostIndex); ++ ++ if (!_base_is_controller_msix_enabled(ioc)) ++ goto skip_init_reply_post_host_index; ++ } ++ ++ skip_init_reply_post_host_index: ++ ++ _base_unmask_interrupts(ioc); ++ r = _base_event_notification(ioc, sleep_flag); ++ if (r) ++ return r; ++ ++ if (sleep_flag == CAN_SLEEP) ++ _base_static_config_pages(ioc); ++ ++ ++ if (ioc->is_driver_loading) { ++ ++ if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier ++ == 0x80) { ++ hide_flag = (u8) ( ++ le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) & ++ MFG_PAGE10_HIDE_SSDS_MASK); ++ if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) ++ ioc->mfg_pg10_hide_flag = hide_flag; ++ } ++ ++ ioc->wait_for_discovery_to_complete = ++ _base_determine_wait_on_discovery(ioc); ++ ++ return r; /* scan_start and scan_finished support */ ++ } ++ ++ r = _base_send_port_enable(ioc, sleep_flag); ++ if (r) ++ return r; ++ ++ return r; ++} ++ ++/** ++ * mpt2sas_base_free_resources - free resources controller resources ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) ++{ ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ /* synchronizing freeing resource with pci_access_mutex lock */ ++ mutex_lock(&ioc->pci_access_mutex); ++ if (ioc->chip_phys && ioc->chip) { ++ _base_mask_interrupts(ioc); ++ ioc->shost_recovery = 1; ++ _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); ++ ioc->shost_recovery = 0; ++ } ++ ++ mpt2sas_base_unmap_resources(ioc); ++ mutex_unlock(&ioc->pci_access_mutex); ++ return; ++} ++ ++/** ++ * mpt2sas_base_attach - attach controller instance ++ * @ioc: per adapter object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int r, i; ++ int cpu_id, last_cpu_id = 0; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ /* setup cpu_msix_table */ ++ ioc->cpu_count = num_online_cpus(); ++ for_each_online_cpu(cpu_id) ++ last_cpu_id = cpu_id; ++ ioc->cpu_msix_table_sz = last_cpu_id + 1; ++ ioc->cpu_msix_table = kzalloc(ioc->cpu_msix_table_sz, GFP_KERNEL); ++ ioc->reply_queue_count = 1; ++ if (!ioc->cpu_msix_table) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT ++ "allocation for cpu_msix_table failed!!!\n", ++ ioc->name)); ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ if (ioc->is_warpdrive) { ++ ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz, ++ sizeof(resource_size_t *), GFP_KERNEL); ++ if (!ioc->reply_post_host_index) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT "allocation " ++ "for cpu_msix_table failed!!!\n", ioc->name)); ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ } ++ ++ ioc->rdpq_array_enable_assigned = 0; ++ ioc->dma_mask = 0; ++ r = mpt2sas_base_map_resources(ioc); ++ if (r) ++ goto out_free_resources; ++ ++ if (ioc->is_warpdrive) { ++ ioc->reply_post_host_index[0] = (resource_size_t __iomem *) ++ &ioc->chip->ReplyPostHostIndex; ++ ++ for (i = 1; i < ioc->cpu_msix_table_sz; i++) ++ ioc->reply_post_host_index[i] = ++ (resource_size_t __iomem *) ++ ((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1) ++ * 4))); ++ } ++ ++ pci_set_drvdata(ioc->pdev, ioc->shost); ++ r = _base_get_ioc_facts(ioc, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ ioc->build_sg_scmd = &_base_build_sg_scmd; ++ ioc->build_sg = &_base_build_sg; ++ ioc->build_zero_len_sge = &_base_build_zero_len_sge; ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ /* ++ * In SAS3.0, ++ * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and ++ * Target Status - all require the IEEE formated scatter gather ++ * elements. ++ */ ++ ioc->build_sg_scmd = &_base_build_sg_scmd_ieee; ++ ioc->build_sg = &_base_build_sg_ieee; ++ ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; ++ ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); ++ break; ++ } ++ ++ /* ++ * These function pointers for other requests that don't ++ * the require IEEE scatter gather elements. ++ * ++ * For example Configuration Pages and SAS IOUNIT Control don't. ++ */ ++ ioc->build_sg_mpi = &_base_build_sg; ++ ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge; ++ ++ r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); ++ if (r) ++ goto out_free_resources; ++ ++ ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, ++ sizeof(struct mpt2sas_port_facts), GFP_KERNEL); ++ if (!ioc->pfacts) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) { ++ r = _base_get_port_facts(ioc, i, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ } ++ ++ r = _base_allocate_memory_pools(ioc, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ ++ init_waitqueue_head(&ioc->reset_wq); ++ ++ /* allocate memory pd handle bitmask list */ ++ ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); ++ if (ioc->facts.MaxDevHandle % 8) ++ ioc->pd_handles_sz++; ++ ioc->pd_handles = kzalloc(ioc->pd_handles_sz, ++ GFP_KERNEL); ++ if (!ioc->pd_handles) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ioc->blocking_handles = kzalloc(ioc->pd_handles_sz, ++ GFP_KERNEL); ++ if (!ioc->blocking_handles) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ ioc->fwfault_debug = mpt2sas_fwfault_debug; ++ ++ /* base internal command bits */ ++ mutex_init(&ioc->base_cmds.mutex); ++ ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ ++ /* port_enable command bits */ ++ ioc->port_enable_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->port_enable_cmds.status = MPT3_CMD_NOT_USED; ++ ++ /* transport internal command bits */ ++ ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->transport_cmds.mutex); ++ ++ /* scsih internal command bits */ ++ ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->scsih_cmds.mutex); ++ ++ /* task management internal command bits */ ++ ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->tm_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->tm_cmds.mutex); ++ ++ /* config page internal command bits */ ++ ioc->config_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->config_cmds.mutex); ++ ++ /* ctl module internal command bits */ ++ ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->ctl_cmds.mutex); ++ ++ if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || ++ !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || ++ !ioc->config_cmds.reply || !ioc->ctl_cmds.reply || ++ !ioc->ctl_cmds.sense) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) ++ ioc->event_masks[i] = -1; ++ ++ /* here we enable the events we care about */ ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_DISCOVERY); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_BROADCAST_PRIMITIVE); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); ++ _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); ++ _base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD); ++ if (ioc->hba_mpi_version_belonged == MPI26_VERSION) ++ _base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION); ++ ++ r = _base_make_ioc_operational(ioc, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ ++ ioc->non_operational_loop = 0; ++ return 0; ++ ++ out_free_resources: ++ ++ ioc->remove_host = 1; ++ ++ mpt2sas_base_free_resources(ioc); ++ _base_release_memory_pools(ioc); ++ pci_set_drvdata(ioc->pdev, NULL); ++ kfree(ioc->cpu_msix_table); ++ if (ioc->is_warpdrive) ++ kfree(ioc->reply_post_host_index); ++ kfree(ioc->pd_handles); ++ kfree(ioc->blocking_handles); ++ kfree(ioc->tm_cmds.reply); ++ kfree(ioc->transport_cmds.reply); ++ kfree(ioc->scsih_cmds.reply); ++ kfree(ioc->config_cmds.reply); ++ kfree(ioc->base_cmds.reply); ++ kfree(ioc->port_enable_cmds.reply); ++ kfree(ioc->ctl_cmds.reply); ++ kfree(ioc->ctl_cmds.sense); ++ kfree(ioc->pfacts); ++ ioc->ctl_cmds.reply = NULL; ++ ioc->base_cmds.reply = NULL; ++ ioc->tm_cmds.reply = NULL; ++ ioc->scsih_cmds.reply = NULL; ++ ioc->transport_cmds.reply = NULL; ++ ioc->config_cmds.reply = NULL; ++ ioc->pfacts = NULL; ++ return r; ++} ++ ++ ++/** ++ * mpt2sas_base_detach - remove controller instance ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_detach(struct MPT3SAS_ADAPTER *ioc) ++{ ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mpt2sas_base_stop_watchdog(ioc); ++ mpt2sas_base_free_resources(ioc); ++ _base_release_memory_pools(ioc); ++ pci_set_drvdata(ioc->pdev, NULL); ++ kfree(ioc->cpu_msix_table); ++ if (ioc->is_warpdrive) ++ kfree(ioc->reply_post_host_index); ++ kfree(ioc->pd_handles); ++ kfree(ioc->blocking_handles); ++ kfree(ioc->pfacts); ++ kfree(ioc->ctl_cmds.reply); ++ kfree(ioc->ctl_cmds.sense); ++ kfree(ioc->base_cmds.reply); ++ kfree(ioc->port_enable_cmds.reply); ++ kfree(ioc->tm_cmds.reply); ++ kfree(ioc->transport_cmds.reply); ++ kfree(ioc->scsih_cmds.reply); ++ kfree(ioc->config_cmds.reply); ++} ++ ++/** ++ * _base_reset_handler - reset callback handler (for base) ++ * @ioc: per adapter object ++ * @reset_phase: phase ++ * ++ * The handler for doing any required cleanup or initialization. ++ * ++ * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET, ++ * MPT3_IOC_DONE_RESET ++ * ++ * Return nothing. ++ */ ++static void ++_base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) ++{ ++ mpt2sas_scsih_reset_handler(ioc, reset_phase); ++ mpt2sas_ctl_reset_handler(ioc, reset_phase); ++ switch (reset_phase) { ++ case MPT3_IOC_PRE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__)); ++ break; ++ case MPT3_IOC_AFTER_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__)); ++ if (ioc->transport_cmds.status & MPT3_CMD_PENDING) { ++ ioc->transport_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->transport_cmds.smid); ++ complete(&ioc->transport_cmds.done); ++ } ++ if (ioc->base_cmds.status & MPT3_CMD_PENDING) { ++ ioc->base_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid); ++ complete(&ioc->base_cmds.done); ++ } ++ if (ioc->port_enable_cmds.status & MPT3_CMD_PENDING) { ++ ioc->port_enable_failed = 1; ++ ioc->port_enable_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->port_enable_cmds.smid); ++ if (ioc->is_driver_loading) { ++ ioc->start_scan_failed = ++ MPI2_IOCSTATUS_INTERNAL_ERROR; ++ ioc->start_scan = 0; ++ ioc->port_enable_cmds.status = ++ MPT3_CMD_NOT_USED; ++ } else ++ complete(&ioc->port_enable_cmds.done); ++ } ++ if (ioc->config_cmds.status & MPT3_CMD_PENDING) { ++ ioc->config_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); ++ ioc->config_cmds.smid = USHRT_MAX; ++ complete(&ioc->config_cmds.done); ++ } ++ break; ++ case MPT3_IOC_DONE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__)); ++ break; ++ } ++} ++ ++/** ++ * _wait_for_commands_to_complete - reset controller ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * This function waiting(3s) for all pending commands to complete ++ * prior to putting controller in reset. ++ */ ++static void ++_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ u32 ioc_state; ++ unsigned long flags; ++ u16 i; ++ ++ ioc->pending_io_count = 0; ++ if (sleep_flag != CAN_SLEEP) ++ return; ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((ioc_state & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) ++ return; ++ ++ /* pending command count */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ for (i = 0; i < ioc->scsiio_depth; i++) ++ if (ioc->scsi_lookup[i].cb_idx != 0xFF) ++ ioc->pending_io_count++; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ if (!ioc->pending_io_count) ++ return; ++ ++ /* wait for pending commands to complete */ ++ wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ); ++} ++ ++/** ++ * mpt2sas_base_hard_reset_handler - reset controller ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * @type: FORCE_BIG_HAMMER or SOFT_RESET ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, ++ enum reset_type type) ++{ ++ int r; ++ unsigned long flags; ++ u32 ioc_state; ++ u8 is_fault = 0, is_trigger = 0; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ if (ioc->pci_error_recovery) { ++ pr_err(MPT3SAS_FMT "%s: pci error recovery reset\n", ++ ioc->name, __func__); ++ r = 0; ++ goto out_unlocked; ++ } ++ ++ if (mpt2sas_fwfault_debug) ++ mpt2sas_halt_firmware(ioc); ++ ++ /* TODO - What we really should be doing is pulling ++ * out all the code associated with NO_SLEEP; its never used. ++ * That is legacy code from mpt fusion driver, ported over. ++ * I will leave this BUG_ON here for now till its been resolved. ++ */ ++ BUG_ON(sleep_flag == NO_SLEEP); ++ ++ /* wait for an active reset in progress to complete */ ++ if (!mutex_trylock(&ioc->reset_in_progress_mutex)) { ++ do { ++ ssleep(1); ++ } while (ioc->shost_recovery == 1); ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++ return ioc->ioc_reset_in_progress_status; ++ } ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ ioc->shost_recovery = 1; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) && ++ (!(ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED))) { ++ is_trigger = 1; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) ++ is_fault = 1; ++ } ++ _base_reset_handler(ioc, MPT3_IOC_PRE_RESET); ++ _wait_for_commands_to_complete(ioc, sleep_flag); ++ _base_mask_interrupts(ioc); ++ r = _base_make_ioc_ready(ioc, sleep_flag, type); ++ if (r) ++ goto out; ++ _base_reset_handler(ioc, MPT3_IOC_AFTER_RESET); ++ ++ /* If this hard reset is called while port enable is active, then ++ * there is no reason to call make_ioc_operational ++ */ ++ if (ioc->is_driver_loading && ioc->port_enable_failed) { ++ ioc->remove_host = 1; ++ r = -EFAULT; ++ goto out; ++ } ++ r = _base_get_ioc_facts(ioc, CAN_SLEEP); ++ if (r) ++ goto out; ++ ++ if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable) ++ panic("%s: Issue occurred with flashing controller firmware." ++ "Please reboot the system and ensure that the correct" ++ " firmware version is running\n", ioc->name); ++ ++ r = _base_make_ioc_operational(ioc, sleep_flag); ++ if (!r) ++ _base_reset_handler(ioc, MPT3_IOC_DONE_RESET); ++ ++ out: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: %s\n", ++ ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED"))); ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ ioc->ioc_reset_in_progress_status = r; ++ ioc->shost_recovery = 0; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ ioc->ioc_reset_count++; ++ mutex_unlock(&ioc->reset_in_progress_mutex); ++ ++ out_unlocked: ++ if ((r == 0) && is_trigger) { ++ if (is_fault) ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_FW_FAULT); ++ else ++ mpt2sas_trigger_master(ioc, ++ MASTER_TRIGGER_ADAPTER_RESET); ++ } ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++ return r; ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_base.h b/drivers/scsi/mpt2sas/mpt3sas_base.h +new file mode 100644 +index 0000000..a580770 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_base.h +@@ -0,0 +1,1462 @@ ++/* ++ * This is the Fusion MPT base driver providing common API layer interface ++ * for access to MPT (Message Passing Technology) firmware. ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#ifndef MPT3SAS_BASE_H_INCLUDED ++#define MPT3SAS_BASE_H_INCLUDED ++ ++#include "mpi/mpi2_type.h" ++#include "mpi/mpi2.h" ++#include "mpi/mpi2_ioc.h" ++#include "mpi/mpi2_cnfg.h" ++#include "mpi/mpi2_init.h" ++#include "mpi/mpi2_raid.h" ++#include "mpi/mpi2_tool.h" ++#include "mpi/mpi2_sas.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_debug.h" ++#include "mpt3sas_trigger_diag.h" ++ ++/* driver versioning info */ ++#define MPT3SAS_DRIVER_NAME "mpt3sas" ++#define MPT3SAS_AUTHOR "Avago Technologies " ++#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" ++#define MPT3SAS_DRIVER_VERSION "13.100.00.00" ++#define MPT3SAS_MAJOR_VERSION 13 ++#define MPT3SAS_MINOR_VERSION 100 ++#define MPT3SAS_BUILD_VERSION 0 ++#define MPT3SAS_RELEASE_VERSION 00 ++ ++#define MPT2SAS_DRIVER_NAME "mpt2sas" ++#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" ++#define MPT2SAS_DRIVER_VERSION "20.102.00.00" ++#define MPT2SAS_MAJOR_VERSION 20 ++#define MPT2SAS_MINOR_VERSION 102 ++#define MPT2SAS_BUILD_VERSION 0 ++#define MPT2SAS_RELEASE_VERSION 00 ++ ++/* ++ * Set MPT3SAS_SG_DEPTH value based on user input. ++ */ ++#define MPT_MAX_PHYS_SEGMENTS SCSI_MAX_SG_SEGMENTS ++#define MPT_MIN_PHYS_SEGMENTS 16 ++ ++#ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE ++#define MPT3SAS_SG_DEPTH CONFIG_SCSI_MPT3SAS_MAX_SGE ++#else ++#define MPT3SAS_SG_DEPTH MPT_MAX_PHYS_SEGMENTS ++#endif ++ ++#ifdef CONFIG_SCSI_MPT2SAS_MAX_SGE ++#define MPT2SAS_SG_DEPTH CONFIG_SCSI_MPT2SAS_MAX_SGE ++#else ++#define MPT2SAS_SG_DEPTH MPT_MAX_PHYS_SEGMENTS ++#endif ++ ++/* ++ * Generic Defines ++ */ ++#define MPT3SAS_SATA_QUEUE_DEPTH 32 ++#define MPT3SAS_SAS_QUEUE_DEPTH 254 ++#define MPT3SAS_RAID_QUEUE_DEPTH 128 ++ ++#define MPT3SAS_RAID_MAX_SECTORS 8192 ++ ++#define MPT_NAME_LENGTH 32 /* generic length of strings */ ++#define MPT_STRING_LENGTH 64 ++ ++#define MPT_MAX_CALLBACKS 32 ++ ++ ++#define CAN_SLEEP 1 ++#define NO_SLEEP 0 ++ ++#define INTERNAL_CMDS_COUNT 10 /* reserved cmds */ ++/* reserved for issuing internally framed scsi io cmds */ ++#define INTERNAL_SCSIIO_CMDS_COUNT 3 ++ ++#define MPI3_HIM_MASK 0xFFFFFFFF /* mask every bit*/ ++ ++#define MPT3SAS_INVALID_DEVICE_HANDLE 0xFFFF ++ ++#define MAX_CHAIN_ELEMT_SZ 16 ++#define DEFAULT_NUM_FWCHAIN_ELEMTS 8 ++ ++/* ++ * reset phases ++ */ ++#define MPT3_IOC_PRE_RESET 1 /* prior to host reset */ ++#define MPT3_IOC_AFTER_RESET 2 /* just after host reset */ ++#define MPT3_IOC_DONE_RESET 3 /* links re-initialized */ ++ ++/* ++ * logging format ++ */ ++#define MPT3SAS_FMT "%s: " ++ ++/* ++ * WarpDrive Specific Log codes ++ */ ++ ++#define MPT2_WARPDRIVE_LOGENTRY (0x8002) ++#define MPT2_WARPDRIVE_LC_SSDT (0x41) ++#define MPT2_WARPDRIVE_LC_SSDLW (0x43) ++#define MPT2_WARPDRIVE_LC_SSDLF (0x44) ++#define MPT2_WARPDRIVE_LC_BRMF (0x4D) ++ ++/* ++ * per target private data ++ */ ++#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 ++#define MPT_TARGET_FLAGS_VOLUME 0x02 ++#define MPT_TARGET_FLAGS_DELETED 0x04 ++#define MPT_TARGET_FASTPATH_IO 0x08 ++ ++#define SAS2_PCI_DEVICE_B0_REVISION (0x01) ++#define SAS3_PCI_DEVICE_C0_REVISION (0x02) ++ ++/* ++ * Intel HBA branding ++ */ ++#define MPT2SAS_INTEL_RMS25JB080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25JB080" ++#define MPT2SAS_INTEL_RMS25JB040_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25JB040" ++#define MPT2SAS_INTEL_RMS25KB080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25KB080" ++#define MPT2SAS_INTEL_RMS25KB040_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25KB040" ++#define MPT2SAS_INTEL_RMS25LB040_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25LB040" ++#define MPT2SAS_INTEL_RMS25LB080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25LB080" ++#define MPT2SAS_INTEL_RMS2LL080_BRANDING \ ++ "Intel Integrated RAID Module RMS2LL080" ++#define MPT2SAS_INTEL_RMS2LL040_BRANDING \ ++ "Intel Integrated RAID Module RMS2LL040" ++#define MPT2SAS_INTEL_RS25GB008_BRANDING \ ++ "Intel(R) RAID Controller RS25GB008" ++#define MPT2SAS_INTEL_SSD910_BRANDING \ ++ "Intel(R) SSD 910 Series" ++ ++#define MPT3SAS_INTEL_RMS3JC080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS3JC080" ++#define MPT3SAS_INTEL_RS3GC008_BRANDING \ ++ "Intel(R) RAID Controller RS3GC008" ++#define MPT3SAS_INTEL_RS3FC044_BRANDING \ ++ "Intel(R) RAID Controller RS3FC044" ++#define MPT3SAS_INTEL_RS3UC080_BRANDING \ ++ "Intel(R) RAID Controller RS3UC080" ++ ++/* ++ * Intel HBA SSDIDs ++ */ ++#define MPT2SAS_INTEL_RMS25JB080_SSDID 0x3516 ++#define MPT2SAS_INTEL_RMS25JB040_SSDID 0x3517 ++#define MPT2SAS_INTEL_RMS25KB080_SSDID 0x3518 ++#define MPT2SAS_INTEL_RMS25KB040_SSDID 0x3519 ++#define MPT2SAS_INTEL_RMS25LB040_SSDID 0x351A ++#define MPT2SAS_INTEL_RMS25LB080_SSDID 0x351B ++#define MPT2SAS_INTEL_RMS2LL080_SSDID 0x350E ++#define MPT2SAS_INTEL_RMS2LL040_SSDID 0x350F ++#define MPT2SAS_INTEL_RS25GB008_SSDID 0x3000 ++#define MPT2SAS_INTEL_SSD910_SSDID 0x3700 ++ ++#define MPT3SAS_INTEL_RMS3JC080_SSDID 0x3521 ++#define MPT3SAS_INTEL_RS3GC008_SSDID 0x3522 ++#define MPT3SAS_INTEL_RS3FC044_SSDID 0x3523 ++#define MPT3SAS_INTEL_RS3UC080_SSDID 0x3524 ++ ++/* ++ * Dell HBA branding ++ */ ++#define MPT2SAS_DELL_BRANDING_SIZE 32 ++ ++#define MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING "Dell 6Gbps SAS HBA" ++#define MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING "Dell PERC H200 Adapter" ++#define MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING "Dell PERC H200 Integrated" ++#define MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING "Dell PERC H200 Modular" ++#define MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING "Dell PERC H200 Embedded" ++#define MPT2SAS_DELL_PERC_H200_BRANDING "Dell PERC H200" ++#define MPT2SAS_DELL_6GBPS_SAS_BRANDING "Dell 6Gbps SAS" ++ ++#define MPT3SAS_DELL_12G_HBA_BRANDING \ ++ "Dell 12Gbps HBA" ++ ++/* ++ * Dell HBA SSDIDs ++ */ ++#define MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID 0x1F1C ++#define MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID 0x1F1D ++#define MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID 0x1F1E ++#define MPT2SAS_DELL_PERC_H200_MODULAR_SSDID 0x1F1F ++#define MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID 0x1F20 ++#define MPT2SAS_DELL_PERC_H200_SSDID 0x1F21 ++#define MPT2SAS_DELL_6GBPS_SAS_SSDID 0x1F22 ++ ++#define MPT3SAS_DELL_12G_HBA_SSDID 0x1F46 ++ ++/* ++ * Cisco HBA branding ++ */ ++#define MPT3SAS_CISCO_12G_8E_HBA_BRANDING \ ++ "Cisco 9300-8E 12G SAS HBA" ++#define MPT3SAS_CISCO_12G_8I_HBA_BRANDING \ ++ "Cisco 9300-8i 12G SAS HBA" ++#define MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING \ ++ "Cisco 12G Modular SAS Pass through Controller" ++#define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING \ ++ "UCS C3X60 12G SAS Pass through Controller" ++/* ++ * Cisco HBA SSSDIDs ++ */ ++#define MPT3SAS_CISCO_12G_8E_HBA_SSDID 0x14C ++#define MPT3SAS_CISCO_12G_8I_HBA_SSDID 0x154 ++#define MPT3SAS_CISCO_12G_AVILA_HBA_SSDID 0x155 ++#define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID 0x156 ++ ++/* ++ * status bits for ioc->diag_buffer_status ++ */ ++#define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01) ++#define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) ++#define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) ++ ++/* ++ * HP HBA branding ++ */ ++#define MPT2SAS_HP_3PAR_SSVID 0x1590 ++ ++#define MPT2SAS_HP_2_4_INTERNAL_BRANDING \ ++ "HP H220 Host Bus Adapter" ++#define MPT2SAS_HP_2_4_EXTERNAL_BRANDING \ ++ "HP H221 Host Bus Adapter" ++#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING \ ++ "HP H222 Host Bus Adapter" ++#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING \ ++ "HP H220i Host Bus Adapter" ++#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING \ ++ "HP H210i Host Bus Adapter" ++ ++/* ++ * HO HBA SSDIDs ++ */ ++#define MPT2SAS_HP_2_4_INTERNAL_SSDID 0x0041 ++#define MPT2SAS_HP_2_4_EXTERNAL_SSDID 0x0042 ++#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID 0x0043 ++#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID 0x0044 ++#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 ++ ++/* ++ * Combined Reply Queue constants, ++ * There are twelve Supplemental Reply Post Host Index Registers ++ * and each register is at offset 0x10 bytes from the previous one. ++ */ ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT 12 ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10) ++ ++/* OEM Identifiers */ ++#define MFG10_OEM_ID_INVALID (0x00000000) ++#define MFG10_OEM_ID_DELL (0x00000001) ++#define MFG10_OEM_ID_FSC (0x00000002) ++#define MFG10_OEM_ID_SUN (0x00000003) ++#define MFG10_OEM_ID_IBM (0x00000004) ++ ++/* GENERIC Flags 0*/ ++#define MFG10_GF0_OCE_DISABLED (0x00000001) ++#define MFG10_GF0_R1E_DRIVE_COUNT (0x00000002) ++#define MFG10_GF0_R10_DISPLAY (0x00000004) ++#define MFG10_GF0_SSD_DATA_SCRUB_DISABLE (0x00000008) ++#define MFG10_GF0_SINGLE_DRIVE_R0 (0x00000010) ++ ++#define VIRTUAL_IO_FAILED_RETRY (0x32010081) ++ ++/* OEM Specific Flags will come from OEM specific header files */ ++struct Mpi2ManufacturingPage10_t { ++ MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ ++ U8 OEMIdentifier; /* 04h */ ++ U8 Reserved1; /* 05h */ ++ U16 Reserved2; /* 08h */ ++ U32 Reserved3; /* 0Ch */ ++ U32 GenericFlags0; /* 10h */ ++ U32 GenericFlags1; /* 14h */ ++ U32 Reserved4; /* 18h */ ++ U32 OEMSpecificFlags0; /* 1Ch */ ++ U32 OEMSpecificFlags1; /* 20h */ ++ U32 Reserved5[18]; /* 24h - 60h*/ ++}; ++ ++ ++/* Miscellaneous options */ ++struct Mpi2ManufacturingPage11_t { ++ MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ ++ __le32 Reserved1; /* 04h */ ++ u8 Reserved2; /* 08h */ ++ u8 EEDPTagMode; /* 09h */ ++ u8 Reserved3; /* 0Ah */ ++ u8 Reserved4; /* 0Bh */ ++ __le32 Reserved5[23]; /* 0Ch-60h*/ ++}; ++ ++/** ++ * struct MPT3SAS_TARGET - starget private hostdata ++ * @starget: starget object ++ * @sas_address: target sas address ++ * @raid_device: raid_device pointer to access volume data ++ * @handle: device handle ++ * @num_luns: number luns ++ * @flags: MPT_TARGET_FLAGS_XXX flags ++ * @deleted: target flaged for deletion ++ * @tm_busy: target is busy with TM request. ++ * @sdev: The sas_device associated with this target ++ */ ++struct MPT3SAS_TARGET { ++ struct scsi_target *starget; ++ u64 sas_address; ++ struct _raid_device *raid_device; ++ u16 handle; ++ int num_luns; ++ u32 flags; ++ u8 deleted; ++ u8 tm_busy; ++ struct _sas_device *sdev; ++}; ++ ++ ++/* ++ * per device private data ++ */ ++#define MPT_DEVICE_FLAGS_INIT 0x01 ++#define MPT_DEVICE_TLR_ON 0x02 ++ ++#define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003) ++#define MFG_PAGE10_HIDE_ALL_DISKS (0x00) ++#define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01) ++#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02) ++ ++/** ++ * struct MPT3SAS_DEVICE - sdev private hostdata ++ * @sas_target: starget private hostdata ++ * @lun: lun number ++ * @flags: MPT_DEVICE_XXX flags ++ * @configured_lun: lun is configured ++ * @block: device is in SDEV_BLOCK state ++ * @tlr_snoop_check: flag used in determining whether to disable TLR ++ * @eedp_enable: eedp support enable bit ++ * @eedp_type: 0(type_1), 1(type_2), 2(type_3) ++ * @eedp_block_length: block size ++ */ ++struct MPT3SAS_DEVICE { ++ struct MPT3SAS_TARGET *sas_target; ++ unsigned int lun; ++ u32 flags; ++ u8 configured_lun; ++ u8 block; ++ u8 tlr_snoop_check; ++ u8 ignore_delay_remove; ++}; ++ ++#define MPT3_CMD_NOT_USED 0x8000 /* free */ ++#define MPT3_CMD_COMPLETE 0x0001 /* completed */ ++#define MPT3_CMD_PENDING 0x0002 /* pending */ ++#define MPT3_CMD_REPLY_VALID 0x0004 /* reply is valid */ ++#define MPT3_CMD_RESET 0x0008 /* host reset dropped the command */ ++ ++/** ++ * struct _internal_cmd - internal commands struct ++ * @mutex: mutex ++ * @done: completion ++ * @reply: reply message pointer ++ * @sense: sense data ++ * @status: MPT3_CMD_XXX status ++ * @smid: system message id ++ */ ++struct _internal_cmd { ++ struct mutex mutex; ++ struct completion done; ++ void *reply; ++ void *sense; ++ u16 status; ++ u16 smid; ++}; ++ ++ ++ ++/** ++ * struct _sas_device - attached device information ++ * @list: sas device list ++ * @starget: starget object ++ * @sas_address: device sas address ++ * @device_name: retrieved from the SAS IDENTIFY frame. ++ * @handle: device handle ++ * @sas_address_parent: sas address of parent expander or sas host ++ * @enclosure_handle: enclosure handle ++ * @enclosure_logical_id: enclosure logical identifier ++ * @volume_handle: volume handle (valid when hidden raid member) ++ * @volume_wwid: volume unique identifier ++ * @device_info: bitfield provides detailed info about the device ++ * @id: target id ++ * @channel: target channel ++ * @slot: number number ++ * @phy: phy identifier provided in sas device page 0 ++ * @responding: used in _scsih_sas_device_mark_responding ++ * @fast_path: fast path feature enable bit ++ * @pfa_led_on: flag for PFA LED status ++ * @pend_sas_rphy_add: flag to check if device is in sas_rphy_add() ++ * addition routine. ++ */ ++struct _sas_device { ++ struct list_head list; ++ struct scsi_target *starget; ++ u64 sas_address; ++ u64 device_name; ++ u16 handle; ++ u64 sas_address_parent; ++ u16 enclosure_handle; ++ u64 enclosure_logical_id; ++ u16 volume_handle; ++ u64 volume_wwid; ++ u32 device_info; ++ int id; ++ int channel; ++ u16 slot; ++ u8 phy; ++ u8 responding; ++ u8 fast_path; ++ u8 pfa_led_on; ++ u8 pend_sas_rphy_add; ++ u8 enclosure_level; ++ u8 connector_name[4]; ++ struct kref refcount; ++}; ++ ++static inline void sas_device_get(struct _sas_device *s) ++{ ++ kref_get(&s->refcount); ++} ++ ++static inline void sas_device_free(struct kref *r) ++{ ++ kfree(container_of(r, struct _sas_device, refcount)); ++} ++ ++static inline void sas_device_put(struct _sas_device *s) ++{ ++ kref_put(&s->refcount, sas_device_free); ++} ++ ++/** ++ * struct _raid_device - raid volume link list ++ * @list: sas device list ++ * @starget: starget object ++ * @sdev: scsi device struct (volumes are single lun) ++ * @wwid: unique identifier for the volume ++ * @handle: device handle ++ * @block_size: Block size of the volume ++ * @id: target id ++ * @channel: target channel ++ * @volume_type: the raid level ++ * @device_info: bitfield provides detailed info about the hidden components ++ * @num_pds: number of hidden raid components ++ * @responding: used in _scsih_raid_device_mark_responding ++ * @percent_complete: resync percent complete ++ * @direct_io_enabled: Whether direct io to PDs are allowed or not ++ * @stripe_exponent: X where 2powX is the stripe sz in blocks ++ * @block_exponent: X where 2powX is the block sz in bytes ++ * @max_lba: Maximum number of LBA in the volume ++ * @stripe_sz: Stripe Size of the volume ++ * @device_info: Device info of the volume member disk ++ * @pd_handle: Array of handles of the physical drives for direct I/O in le16 ++ */ ++#define MPT_MAX_WARPDRIVE_PDS 8 ++struct _raid_device { ++ struct list_head list; ++ struct scsi_target *starget; ++ struct scsi_device *sdev; ++ u64 wwid; ++ u16 handle; ++ u16 block_sz; ++ int id; ++ int channel; ++ u8 volume_type; ++ u8 num_pds; ++ u8 responding; ++ u8 percent_complete; ++ u8 direct_io_enabled; ++ u8 stripe_exponent; ++ u8 block_exponent; ++ u64 max_lba; ++ u32 stripe_sz; ++ u32 device_info; ++ u16 pd_handle[MPT_MAX_WARPDRIVE_PDS]; ++}; ++ ++/** ++ * struct _boot_device - boot device info ++ * @is_raid: flag to indicate whether this is volume ++ * @device: holds pointer for either struct _sas_device or ++ * struct _raid_device ++ */ ++struct _boot_device { ++ u8 is_raid; ++ void *device; ++}; ++ ++/** ++ * struct _sas_port - wide/narrow sas port information ++ * @port_list: list of ports belonging to expander ++ * @num_phys: number of phys belonging to this port ++ * @remote_identify: attached device identification ++ * @rphy: sas transport rphy object ++ * @port: sas transport wide/narrow port object ++ * @phy_list: _sas_phy list objects belonging to this port ++ */ ++struct _sas_port { ++ struct list_head port_list; ++ u8 num_phys; ++ struct sas_identify remote_identify; ++ struct sas_rphy *rphy; ++ struct sas_port *port; ++ struct list_head phy_list; ++}; ++ ++/** ++ * struct _sas_phy - phy information ++ * @port_siblings: list of phys belonging to a port ++ * @identify: phy identification ++ * @remote_identify: attached device identification ++ * @phy: sas transport phy object ++ * @phy_id: unique phy id ++ * @handle: device handle for this phy ++ * @attached_handle: device handle for attached device ++ * @phy_belongs_to_port: port has been created for this phy ++ */ ++struct _sas_phy { ++ struct list_head port_siblings; ++ struct sas_identify identify; ++ struct sas_identify remote_identify; ++ struct sas_phy *phy; ++ u8 phy_id; ++ u16 handle; ++ u16 attached_handle; ++ u8 phy_belongs_to_port; ++}; ++ ++/** ++ * struct _sas_node - sas_host/expander information ++ * @list: list of expanders ++ * @parent_dev: parent device class ++ * @num_phys: number phys belonging to this sas_host/expander ++ * @sas_address: sas address of this sas_host/expander ++ * @handle: handle for this sas_host/expander ++ * @sas_address_parent: sas address of parent expander or sas host ++ * @enclosure_handle: handle for this a member of an enclosure ++ * @device_info: bitwise defining capabilities of this sas_host/expander ++ * @responding: used in _scsih_expander_device_mark_responding ++ * @phy: a list of phys that make up this sas_host/expander ++ * @sas_port_list: list of ports attached to this sas_host/expander ++ */ ++struct _sas_node { ++ struct list_head list; ++ struct device *parent_dev; ++ u8 num_phys; ++ u64 sas_address; ++ u16 handle; ++ u64 sas_address_parent; ++ u16 enclosure_handle; ++ u64 enclosure_logical_id; ++ u8 responding; ++ struct _sas_phy *phy; ++ struct list_head sas_port_list; ++}; ++ ++/** ++ * enum reset_type - reset state ++ * @FORCE_BIG_HAMMER: issue diagnostic reset ++ * @SOFT_RESET: issue message_unit_reset, if fails to to big hammer ++ */ ++enum reset_type { ++ FORCE_BIG_HAMMER, ++ SOFT_RESET, ++}; ++ ++/** ++ * struct chain_tracker - firmware chain tracker ++ * @chain_buffer: chain buffer ++ * @chain_buffer_dma: physical address ++ * @tracker_list: list of free request (ioc->free_chain_list) ++ */ ++struct chain_tracker { ++ void *chain_buffer; ++ dma_addr_t chain_buffer_dma; ++ struct list_head tracker_list; ++}; ++ ++/** ++ * struct scsiio_tracker - scsi mf request tracker ++ * @smid: system message id ++ * @scmd: scsi request pointer ++ * @cb_idx: callback index ++ * @direct_io: To indicate whether I/O is direct (WARPDRIVE) ++ * @tracker_list: list of free request (ioc->free_list) ++ * @msix_io: IO's msix ++ */ ++struct scsiio_tracker { ++ u16 smid; ++ struct scsi_cmnd *scmd; ++ u8 cb_idx; ++ u8 direct_io; ++ struct list_head chain_list; ++ struct list_head tracker_list; ++ u16 msix_io; ++}; ++ ++/** ++ * struct request_tracker - firmware request tracker ++ * @smid: system message id ++ * @cb_idx: callback index ++ * @tracker_list: list of free request (ioc->free_list) ++ */ ++struct request_tracker { ++ u16 smid; ++ u8 cb_idx; ++ struct list_head tracker_list; ++}; ++ ++/** ++ * struct _tr_list - target reset list ++ * @handle: device handle ++ * @state: state machine ++ */ ++struct _tr_list { ++ struct list_head list; ++ u16 handle; ++ u16 state; ++}; ++ ++/** ++ * struct _sc_list - delayed SAS_IO_UNIT_CONTROL message list ++ * @handle: device handle ++ */ ++struct _sc_list { ++ struct list_head list; ++ u16 handle; ++}; ++ ++/** ++ * struct _event_ack_list - delayed event acknowledgment list ++ * @Event: Event ID ++ * @EventContext: used to track the event uniquely ++ */ ++struct _event_ack_list { ++ struct list_head list; ++ u16 Event; ++ u32 EventContext; ++}; ++ ++/** ++ * struct adapter_reply_queue - the reply queue struct ++ * @ioc: per adapter object ++ * @msix_index: msix index into vector table ++ * @vector: irq vector ++ * @reply_post_host_index: head index in the pool where FW completes IO ++ * @reply_post_free: reply post base virt address ++ * @name: the name registered to request_irq() ++ * @busy: isr is actively processing replies on another cpu ++ * @list: this list ++*/ ++struct adapter_reply_queue { ++ struct MPT3SAS_ADAPTER *ioc; ++ u8 msix_index; ++ unsigned int vector; ++ u32 reply_post_host_index; ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free; ++ char name[MPT_NAME_LENGTH]; ++ atomic_t busy; ++ cpumask_var_t affinity_hint; ++ struct list_head list; ++}; ++ ++typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); ++ ++/* SAS3.0 support */ ++typedef int (*MPT_BUILD_SG_SCMD)(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_cmnd *scmd, u16 smid); ++typedef void (*MPT_BUILD_SG)(struct MPT3SAS_ADAPTER *ioc, void *psge, ++ dma_addr_t data_out_dma, size_t data_out_sz, ++ dma_addr_t data_in_dma, size_t data_in_sz); ++typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc, ++ void *paddr); ++ ++ ++ ++/* IOC Facts and Port Facts converted from little endian to cpu */ ++union mpi3_version_union { ++ MPI2_VERSION_STRUCT Struct; ++ u32 Word; ++}; ++ ++struct mpt2sas_facts { ++ u16 MsgVersion; ++ u16 HeaderVersion; ++ u8 IOCNumber; ++ u8 VP_ID; ++ u8 VF_ID; ++ u16 IOCExceptions; ++ u16 IOCStatus; ++ u32 IOCLogInfo; ++ u8 MaxChainDepth; ++ u8 WhoInit; ++ u8 NumberOfPorts; ++ u8 MaxMSIxVectors; ++ u16 RequestCredit; ++ u16 ProductID; ++ u32 IOCCapabilities; ++ union mpi3_version_union FWVersion; ++ u16 IOCRequestFrameSize; ++ u16 IOCMaxChainSegmentSize; ++ u16 MaxInitiators; ++ u16 MaxTargets; ++ u16 MaxSasExpanders; ++ u16 MaxEnclosures; ++ u16 ProtocolFlags; ++ u16 HighPriorityCredit; ++ u16 MaxReplyDescriptorPostQueueDepth; ++ u8 ReplyFrameSize; ++ u8 MaxVolumes; ++ u16 MaxDevHandle; ++ u16 MaxPersistentEntries; ++ u16 MinDevHandle; ++}; ++ ++struct mpt2sas_port_facts { ++ u8 PortNumber; ++ u8 VP_ID; ++ u8 VF_ID; ++ u8 PortType; ++ u16 MaxPostedCmdBuffers; ++}; ++ ++struct reply_post_struct { ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free; ++ dma_addr_t reply_post_free_dma; ++}; ++ ++/** ++ * enum mutex_type - task management mutex type ++ * @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it ++ * @TM_MUTEX_ON: mutex is required ++ */ ++enum mutex_type { ++ TM_MUTEX_OFF = 0, ++ TM_MUTEX_ON = 1, ++}; ++ ++typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); ++/** ++ * struct MPT3SAS_ADAPTER - per adapter struct ++ * @list: ioc_list ++ * @shost: shost object ++ * @id: unique adapter id ++ * @cpu_count: number online cpus ++ * @name: generic ioc string ++ * @tmp_string: tmp string used for logging ++ * @pdev: pci pdev object ++ * @pio_chip: physical io register space ++ * @chip: memory mapped register space ++ * @chip_phys: physical addrss prior to mapping ++ * @logging_level: see mpt3sas_debug.h ++ * @fwfault_debug: debuging FW timeouts ++ * @ir_firmware: IR firmware present ++ * @bars: bitmask of BAR's that must be configured ++ * @mask_interrupts: ignore interrupt ++ * @dma_mask: used to set the consistent dma mask ++ * @fault_reset_work_q_name: fw fault work queue ++ * @fault_reset_work_q: "" ++ * @fault_reset_work: "" ++ * @firmware_event_name: fw event work queue ++ * @firmware_event_thread: "" ++ * @fw_event_lock: ++ * @fw_event_list: list of fw events ++ * @aen_event_read_flag: event log was read ++ * @broadcast_aen_busy: broadcast aen waiting to be serviced ++ * @shost_recovery: host reset in progress ++ * @ioc_reset_in_progress_lock: ++ * @ioc_link_reset_in_progress: phy/hard reset in progress ++ * @ignore_loginfos: ignore loginfos during task management ++ * @remove_host: flag for when driver unloads, to avoid sending dev resets ++ * @pci_error_recovery: flag to prevent ioc access until slot reset completes ++ * @wait_for_discovery_to_complete: flag set at driver load time when ++ * waiting on reporting devices ++ * @is_driver_loading: flag set at driver load time ++ * @port_enable_failed: flag set when port enable has failed ++ * @start_scan: flag set from scan_start callback, cleared from _mpt2sas_fw_work ++ * @start_scan_failed: means port enable failed, return's the ioc_status ++ * @msix_enable: flag indicating msix is enabled ++ * @msix_vector_count: number msix vectors ++ * @cpu_msix_table: table for mapping cpus to msix index ++ * @cpu_msix_table_sz: table size ++ * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands ++ * @scsi_io_cb_idx: shost generated commands ++ * @tm_cb_idx: task management commands ++ * @scsih_cb_idx: scsih internal commands ++ * @transport_cb_idx: transport internal commands ++ * @ctl_cb_idx: clt internal commands ++ * @base_cb_idx: base internal commands ++ * @config_cb_idx: base internal commands ++ * @tm_tr_cb_idx : device removal target reset handshake ++ * @tm_tr_volume_cb_idx : volume removal target reset ++ * @base_cmds: ++ * @transport_cmds: ++ * @scsih_cmds: ++ * @tm_cmds: ++ * @ctl_cmds: ++ * @config_cmds: ++ * @base_add_sg_single: handler for either 32/64 bit sgl's ++ * @event_type: bits indicating which events to log ++ * @event_context: unique id for each logged event ++ * @event_log: event log pointer ++ * @event_masks: events that are masked ++ * @facts: static facts data ++ * @pfacts: static port facts data ++ * @manu_pg0: static manufacturing page 0 ++ * @manu_pg10: static manufacturing page 10 ++ * @manu_pg11: static manufacturing page 11 ++ * @bios_pg2: static bios page 2 ++ * @bios_pg3: static bios page 3 ++ * @ioc_pg8: static ioc page 8 ++ * @iounit_pg0: static iounit page 0 ++ * @iounit_pg1: static iounit page 1 ++ * @iounit_pg8: static iounit page 8 ++ * @sas_hba: sas host object ++ * @sas_expander_list: expander object list ++ * @sas_node_lock: ++ * @sas_device_list: sas device object list ++ * @sas_device_init_list: sas device object list (used only at init time) ++ * @sas_device_lock: ++ * @io_missing_delay: time for IO completed by fw when PDR enabled ++ * @device_missing_delay: time for device missing by fw when PDR enabled ++ * @sas_id : used for setting volume target IDs ++ * @blocking_handles: bitmask used to identify which devices need blocking ++ * @pd_handles : bitmask for PD handles ++ * @pd_handles_sz : size of pd_handle bitmask ++ * @config_page_sz: config page size ++ * @config_page: reserve memory for config page payload ++ * @config_page_dma: ++ * @hba_queue_depth: hba request queue depth ++ * @sge_size: sg element size for either 32/64 bit ++ * @scsiio_depth: SCSI_IO queue depth ++ * @request_sz: per request frame size ++ * @request: pool of request frames ++ * @request_dma: ++ * @request_dma_sz: ++ * @scsi_lookup: firmware request tracker list ++ * @scsi_lookup_lock: ++ * @free_list: free list of request ++ * @pending_io_count: ++ * @reset_wq: ++ * @chain: pool of chains ++ * @chain_dma: ++ * @max_sges_in_main_message: number sg elements in main message ++ * @max_sges_in_chain_message: number sg elements per chain ++ * @chains_needed_per_io: max chains per io ++ * @chain_depth: total chains allocated ++ * @chain_segment_sz: gives the max number of ++ * SGEs accommodate on single chain buffer ++ * @hi_priority_smid: ++ * @hi_priority: ++ * @hi_priority_dma: ++ * @hi_priority_depth: ++ * @hpr_lookup: ++ * @hpr_free_list: ++ * @internal_smid: ++ * @internal: ++ * @internal_dma: ++ * @internal_depth: ++ * @internal_lookup: ++ * @internal_free_list: ++ * @sense: pool of sense ++ * @sense_dma: ++ * @sense_dma_pool: ++ * @reply_depth: hba reply queue depth: ++ * @reply_sz: per reply frame size: ++ * @reply: pool of replys: ++ * @reply_dma: ++ * @reply_dma_pool: ++ * @reply_free_queue_depth: reply free depth ++ * @reply_free: pool for reply free queue (32 bit addr) ++ * @reply_free_dma: ++ * @reply_free_dma_pool: ++ * @reply_free_host_index: tail index in pool to insert free replys ++ * @reply_post_queue_depth: reply post queue depth ++ * @reply_post_struct: struct for reply_post_free physical & virt address ++ * @rdpq_array_capable: FW supports multiple reply queue addresses in ioc_init ++ * @rdpq_array_enable: rdpq_array support is enabled in the driver ++ * @rdpq_array_enable_assigned: this ensures that rdpq_array_enable flag ++ * is assigned only ones ++ * @reply_queue_count: number of reply queue's ++ * @reply_queue_list: link list contaning the reply queue info ++ * @msix96_vector: 96 MSI-X vector support ++ * @replyPostRegisterIndex: index of next position in Reply Desc Post Queue ++ * @delayed_tr_list: target reset link list ++ * @delayed_tr_volume_list: volume target reset link list ++ * @delayed_sc_list: ++ * @delayed_event_ack_list: ++ * @temp_sensors_count: flag to carry the number of temperature sensors ++ * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and ++ * pci resource handling. PCI resource freeing will lead to free ++ * vital hardware/memory resource, which might be in use by cli/sysfs ++ * path functions resulting in Null pointer reference followed by kernel ++ * crash. To avoid the above race condition we use mutex syncrhonization ++ * which ensures the syncrhonization between cli/sysfs_show path. ++ */ ++struct MPT3SAS_ADAPTER { ++ struct list_head list; ++ struct Scsi_Host *shost; ++ u8 id; ++ int cpu_count; ++ char name[MPT_NAME_LENGTH]; ++ char driver_name[MPT_NAME_LENGTH]; ++ char tmp_string[MPT_STRING_LENGTH]; ++ struct pci_dev *pdev; ++ Mpi2SystemInterfaceRegs_t __iomem *chip; ++ resource_size_t chip_phys; ++ int logging_level; ++ int fwfault_debug; ++ u8 ir_firmware; ++ int bars; ++ u8 mask_interrupts; ++ int dma_mask; ++ ++ /* fw fault handler */ ++ char fault_reset_work_q_name[20]; ++ struct workqueue_struct *fault_reset_work_q; ++ struct delayed_work fault_reset_work; ++ ++ /* fw event handler */ ++ char firmware_event_name[20]; ++ struct workqueue_struct *firmware_event_thread; ++ spinlock_t fw_event_lock; ++ struct list_head fw_event_list; ++ ++ /* misc flags */ ++ int aen_event_read_flag; ++ u8 broadcast_aen_busy; ++ u16 broadcast_aen_pending; ++ u8 shost_recovery; ++ ++ struct mutex reset_in_progress_mutex; ++ spinlock_t ioc_reset_in_progress_lock; ++ u8 ioc_link_reset_in_progress; ++ u8 ioc_reset_in_progress_status; ++ ++ u8 ignore_loginfos; ++ u8 remove_host; ++ u8 pci_error_recovery; ++ u8 wait_for_discovery_to_complete; ++ u8 is_driver_loading; ++ u8 port_enable_failed; ++ u8 start_scan; ++ u16 start_scan_failed; ++ ++ u8 msix_enable; ++ u16 msix_vector_count; ++ u8 *cpu_msix_table; ++ u16 cpu_msix_table_sz; ++ resource_size_t __iomem **reply_post_host_index; ++ u32 ioc_reset_count; ++ MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; ++ u32 non_operational_loop; ++ ++ /* internal commands, callback index */ ++ u8 scsi_io_cb_idx; ++ u8 tm_cb_idx; ++ u8 transport_cb_idx; ++ u8 scsih_cb_idx; ++ u8 ctl_cb_idx; ++ u8 base_cb_idx; ++ u8 port_enable_cb_idx; ++ u8 config_cb_idx; ++ u8 tm_tr_cb_idx; ++ u8 tm_tr_volume_cb_idx; ++ u8 tm_sas_control_cb_idx; ++ struct _internal_cmd base_cmds; ++ struct _internal_cmd port_enable_cmds; ++ struct _internal_cmd transport_cmds; ++ struct _internal_cmd scsih_cmds; ++ struct _internal_cmd tm_cmds; ++ struct _internal_cmd ctl_cmds; ++ struct _internal_cmd config_cmds; ++ ++ MPT_ADD_SGE base_add_sg_single; ++ ++ /* function ptr for either IEEE or MPI sg elements */ ++ MPT_BUILD_SG_SCMD build_sg_scmd; ++ MPT_BUILD_SG build_sg; ++ MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge; ++ u16 sge_size_ieee; ++ u16 hba_mpi_version_belonged; ++ ++ /* function ptr for MPI sg elements only */ ++ MPT_BUILD_SG build_sg_mpi; ++ MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge_mpi; ++ ++ /* event log */ ++ u32 event_type[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; ++ u32 event_context; ++ void *event_log; ++ u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; ++ ++ /* static config pages */ ++ struct mpt2sas_facts facts; ++ struct mpt2sas_port_facts *pfacts; ++ Mpi2ManufacturingPage0_t manu_pg0; ++ struct Mpi2ManufacturingPage10_t manu_pg10; ++ struct Mpi2ManufacturingPage11_t manu_pg11; ++ Mpi2BiosPage2_t bios_pg2; ++ Mpi2BiosPage3_t bios_pg3; ++ Mpi2IOCPage8_t ioc_pg8; ++ Mpi2IOUnitPage0_t iounit_pg0; ++ Mpi2IOUnitPage1_t iounit_pg1; ++ Mpi2IOUnitPage8_t iounit_pg8; ++ ++ struct _boot_device req_boot_device; ++ struct _boot_device req_alt_boot_device; ++ struct _boot_device current_boot_device; ++ ++ /* sas hba, expander, and device list */ ++ struct _sas_node sas_hba; ++ struct list_head sas_expander_list; ++ spinlock_t sas_node_lock; ++ struct list_head sas_device_list; ++ struct list_head sas_device_init_list; ++ spinlock_t sas_device_lock; ++ struct list_head raid_device_list; ++ spinlock_t raid_device_lock; ++ u8 io_missing_delay; ++ u16 device_missing_delay; ++ int sas_id; ++ ++ void *blocking_handles; ++ void *pd_handles; ++ u16 pd_handles_sz; ++ ++ /* config page */ ++ u16 config_page_sz; ++ void *config_page; ++ dma_addr_t config_page_dma; ++ ++ /* scsiio request */ ++ u16 hba_queue_depth; ++ u16 sge_size; ++ u16 scsiio_depth; ++ u16 request_sz; ++ u8 *request; ++ dma_addr_t request_dma; ++ u32 request_dma_sz; ++ struct scsiio_tracker *scsi_lookup; ++ ulong scsi_lookup_pages; ++ spinlock_t scsi_lookup_lock; ++ struct list_head free_list; ++ int pending_io_count; ++ wait_queue_head_t reset_wq; ++ ++ /* chain */ ++ struct chain_tracker *chain_lookup; ++ struct list_head free_chain_list; ++ struct dma_pool *chain_dma_pool; ++ ulong chain_pages; ++ u16 max_sges_in_main_message; ++ u16 max_sges_in_chain_message; ++ u16 chains_needed_per_io; ++ u32 chain_depth; ++ u16 chain_segment_sz; ++ ++ /* hi-priority queue */ ++ u16 hi_priority_smid; ++ u8 *hi_priority; ++ dma_addr_t hi_priority_dma; ++ u16 hi_priority_depth; ++ struct request_tracker *hpr_lookup; ++ struct list_head hpr_free_list; ++ ++ /* internal queue */ ++ u16 internal_smid; ++ u8 *internal; ++ dma_addr_t internal_dma; ++ u16 internal_depth; ++ struct request_tracker *internal_lookup; ++ struct list_head internal_free_list; ++ ++ /* sense */ ++ u8 *sense; ++ dma_addr_t sense_dma; ++ struct dma_pool *sense_dma_pool; ++ ++ /* reply */ ++ u16 reply_sz; ++ u8 *reply; ++ dma_addr_t reply_dma; ++ u32 reply_dma_max_address; ++ u32 reply_dma_min_address; ++ struct dma_pool *reply_dma_pool; ++ ++ /* reply free queue */ ++ u16 reply_free_queue_depth; ++ __le32 *reply_free; ++ dma_addr_t reply_free_dma; ++ struct dma_pool *reply_free_dma_pool; ++ u32 reply_free_host_index; ++ ++ /* reply post queue */ ++ u16 reply_post_queue_depth; ++ struct reply_post_struct *reply_post; ++ u8 rdpq_array_capable; ++ u8 rdpq_array_enable; ++ u8 rdpq_array_enable_assigned; ++ struct dma_pool *reply_post_free_dma_pool; ++ u8 reply_queue_count; ++ struct list_head reply_queue_list; ++ ++ u8 msix96_vector; ++ /* reply post register index */ ++ resource_size_t **replyPostRegisterIndex; ++ ++ struct list_head delayed_tr_list; ++ struct list_head delayed_tr_volume_list; ++ struct list_head delayed_sc_list; ++ struct list_head delayed_event_ack_list; ++ u8 temp_sensors_count; ++ struct mutex pci_access_mutex; ++ ++ /* diag buffer support */ ++ u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT]; ++ dma_addr_t diag_buffer_dma[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u8 diag_buffer_status[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 unique_id[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23]; ++ u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 ring_buffer_offset; ++ u32 ring_buffer_sz; ++ u8 is_warpdrive; ++ u8 hide_ir_msg; ++ u8 mfg_pg10_hide_flag; ++ u8 hide_drives; ++ spinlock_t diag_trigger_lock; ++ u8 diag_trigger_active; ++ struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; ++ struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event; ++ struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi; ++ struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi; ++}; ++ ++typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++ ++ ++/* base shared API */ ++extern struct list_head mpt2sas_ioc_list; ++extern char driver_name[MPT_NAME_LENGTH]; ++/* spinlock on list operations over IOCs ++ * Case: when multiple warpdrive cards(IOCs) are in use ++ * Each IOC will added to the ioc list structure on initialization. ++ * Watchdog threads run at regular intervals to check IOC for any ++ * fault conditions which will trigger the dead_ioc thread to ++ * deallocate pci resource, resulting deleting the IOC netry from list, ++ * this deletion need to protected by spinlock to enusre that ++ * ioc removal is syncrhonized, if not synchronized it might lead to ++ * list_del corruption as the ioc list is traversed in cli path. ++ */ ++extern spinlock_t gioc_lock_mpt2sas; ++ ++void mpt2sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc); ++ ++int mpt2sas_base_attach(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_base_detach(struct MPT3SAS_ADAPTER *ioc); ++int mpt2sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc); ++int mpt2sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, ++ enum reset_type type); ++ ++void *mpt2sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void *mpt2sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid); ++ ++void mpt2sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); ++ ++/* hi-priority queue */ ++u16 mpt2sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); ++u16 mpt2sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, ++ struct scsi_cmnd *scmd); ++ ++u16 mpt2sas_base_get_smid(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); ++void mpt2sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void mpt2sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle); ++void mpt2sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle); ++void mpt2sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid, u16 msix_task); ++void mpt2sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void mpt2sas_base_initialize_callback_handler(void); ++u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func); ++void mpt2sas_base_release_callback_handler(u8 cb_idx); ++ ++u8 mpt2sas_base_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++u8 mpt2sas_port_enable_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u8 msix_index, u32 reply); ++void *mpt2sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, ++ u32 phys_addr); ++ ++u32 mpt2sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked); ++ ++void mpt2sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code); ++int mpt2sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SasIoUnitControlReply_t *mpi_reply, ++ Mpi2SasIoUnitControlRequest_t *mpi_request); ++int mpt2sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request); ++ ++void mpt2sas_base_validate_event_type(struct MPT3SAS_ADAPTER *ioc, ++ u32 *event_type); ++ ++void mpt2sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc); ++ ++void mpt2sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc, ++ u16 device_missing_delay, u8 io_missing_delay); ++ ++int mpt2sas_port_enable(struct MPT3SAS_ADAPTER *ioc); ++ ++ ++/* scsih shared API */ ++u8 mpt2sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ++ u32 reply); ++void mpt2sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase); ++ ++int mpt2sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ uint channel, uint id, uint lun, u8 type, u16 smid_task, ++ ulong timeout, enum mutex_type m_type); ++void mpt2sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); ++void mpt2sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); ++void mpt2sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++void mpt2sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address); ++u8 mpt2sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid); ++ ++struct _sas_node *mpt2sas_scsih_expander_find_by_handle( ++ struct MPT3SAS_ADAPTER *ioc, u16 handle); ++struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address( ++ struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++struct _sas_device *mpt2sas_get_sdev_by_addr( ++ struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++struct _sas_device *__mpt2sas_get_sdev_by_addr( ++ struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++ ++void mpt2sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc); ++struct _raid_device * ++mpt2sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle); ++ ++/* config shared API */ ++u8 mpt2sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++int mpt2sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, ++ u8 *num_phys); ++int mpt2sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page); ++int mpt2sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, ++ u16 sz); ++int mpt2sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage10_t *config_page); ++ ++int mpt2sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page); ++int mpt2sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page); ++ ++int mpt2sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2BiosPage2_t *config_page); ++int mpt2sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2BiosPage3_t *config_page); ++int mpt2sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage0_t *config_page); ++int mpt2sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, ++ u16 sz); ++int mpt2sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage1_t *config_page); ++int mpt2sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz); ++int mpt2sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage1_t *config_page); ++int mpt2sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage8_t *config_page); ++int mpt2sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz); ++int mpt2sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz); ++int mpt2sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOCPage8_t *config_page); ++int mpt2sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ExpanderPage0_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ExpanderPage1_t *config_page, ++ u32 phy_number, u16 handle); ++int mpt2sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number); ++int mpt2sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number); ++int mpt2sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, ++ u32 handle); ++int mpt2sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u8 *num_pds); ++int mpt2sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, ++ u32 handle, u16 sz); ++int mpt2sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, ++ u32 form, u32 form_specific); ++int mpt2sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, ++ u16 *volume_handle); ++int mpt2sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, ++ u16 volume_handle, u64 *wwid); ++ ++/* ctl shared API */ ++extern struct device_attribute *mpt2sas_host_attrs[]; ++extern struct device_attribute *mpt2sas_dev_attrs[]; ++void mpt2sas_ctl_init(ushort hbas_to_enumerate); ++void mpt2sas_ctl_exit(ushort hbas_to_enumerate); ++u8 mpt2sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++void mpt2sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase); ++u8 mpt2sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, ++ u8 msix_index, u32 reply); ++void mpt2sas_ctl_add_to_event_log(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventNotificationReply_t *mpi_reply); ++ ++void mpt2sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, ++ u8 bits_to_regsiter); ++int mpt2sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, ++ u8 *issue_reset); ++ ++/* transport shared API */ ++extern struct scsi_transport_template *mpt2sas_transport_template; ++u8 mpt2sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++struct _sas_port *mpt2sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, ++ u16 handle, u64 sas_address); ++void mpt2sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u64 sas_address_parent); ++int mpt2sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy ++ *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); ++int mpt2sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_phy *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, ++ struct device *parent_dev); ++void mpt2sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); ++extern struct sas_function_template mpt2sas_transport_functions; ++extern struct scsi_transport_template *mpt2sas_transport_template; ++extern int scsi_internal_device_block(struct scsi_device *sdev); ++extern int scsi_internal_device_unblock(struct scsi_device *sdev, ++ enum scsi_device_state new_state); ++/* trigger data externs */ ++void mpt2sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); ++void mpt2sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); ++void mpt2sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, ++ u32 tigger_bitmask); ++void mpt2sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event, ++ u16 log_entry_qualifier); ++void mpt2sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, ++ u8 asc, u8 ascq); ++void mpt2sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status, ++ u32 loginfo); ++ ++/* warpdrive APIs */ ++u8 mpt2sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device); ++u8 ++mpt2sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void ++mpt2sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io); ++void ++mpt2sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, ++ u16 smid); ++ ++#endif /* MPT3SAS_BASE_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_config.c b/drivers/scsi/mpt2sas/mpt3sas_config.c +new file mode 100644 +index 0000000..0f67b2c +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_config.c +@@ -0,0 +1,1716 @@ ++/* ++ * This module provides common API for accessing firmware configuration pages ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/* local definitions */ ++ ++/* Timeout for config page request (in seconds) */ ++#define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15 ++ ++/* Common sgl flags for READING a config page. */ ++#define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ ++ | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT) ++ ++/* Common sgl flags for WRITING a config page. */ ++#define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ ++ | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \ ++ << MPI2_SGE_FLAGS_SHIFT) ++ ++/** ++ * struct config_request - obtain dma memory via routine ++ * @sz: size ++ * @page: virt pointer ++ * @page_dma: phys pointer ++ * ++ */ ++struct config_request { ++ u16 sz; ++ void *page; ++ dma_addr_t page_dma; ++}; ++ ++/** ++ * _config_display_some_debug - debug routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @calling_function_name: string pass from calling function ++ * @mpi_reply: reply message frame ++ * Context: none. ++ * ++ * Function for displaying debug info helpful when debugging issues ++ * in this module. ++ */ ++static void ++_config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ char *calling_function_name, MPI2DefaultReply_t *mpi_reply) ++{ ++ Mpi2ConfigRequest_t *mpi_request; ++ char *desc = NULL; ++ ++ if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) ++ return; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) { ++ case MPI2_CONFIG_PAGETYPE_IO_UNIT: ++ desc = "io_unit"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_IOC: ++ desc = "ioc"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_BIOS: ++ desc = "bios"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_RAID_VOLUME: ++ desc = "raid_volume"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_MANUFACTURING: ++ desc = "manufaucturing"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK: ++ desc = "physdisk"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_EXTENDED: ++ switch (mpi_request->ExtPageType) { ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT: ++ desc = "sas_io_unit"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER: ++ desc = "sas_expander"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE: ++ desc = "sas_device"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY: ++ desc = "sas_phy"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_LOG: ++ desc = "log"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE: ++ desc = "enclosure"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG: ++ desc = "raid_config"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING: ++ desc = "driver_mapping"; ++ break; ++ } ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ pr_info(MPT3SAS_FMT ++ "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n", ++ ioc->name, calling_function_name, desc, ++ mpi_request->Header.PageNumber, mpi_request->Action, ++ le32_to_cpu(mpi_request->PageAddress), smid); ++ ++ if (!mpi_reply) ++ return; ++ ++ if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "\tiocstatus(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo)); ++} ++ ++/** ++ * _config_alloc_config_dma_memory - obtain physical memory ++ * @ioc: per adapter object ++ * @mem: struct config_request ++ * ++ * A wrapper for obtaining dma-able memory for config page request. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, ++ struct config_request *mem) ++{ ++ int r = 0; ++ ++ if (mem->sz > ioc->config_page_sz) { ++ mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz, ++ &mem->page_dma, GFP_KERNEL); ++ if (!mem->page) { ++ pr_err(MPT3SAS_FMT ++ "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n", ++ ioc->name, __func__, mem->sz); ++ r = -ENOMEM; ++ } ++ } else { /* use tmp buffer if less than 512 bytes */ ++ mem->page = ioc->config_page; ++ mem->page_dma = ioc->config_page_dma; ++ } ++ return r; ++} ++ ++/** ++ * _config_free_config_dma_memory - wrapper to free the memory ++ * @ioc: per adapter object ++ * @mem: struct config_request ++ * ++ * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static void ++_config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, ++ struct config_request *mem) ++{ ++ if (mem->sz > ioc->config_page_sz) ++ dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page, ++ mem->page_dma); ++} ++ ++/** ++ * mpt2sas_config_done - config page completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: none. ++ * ++ * The callback handler when using _config_request. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ if (ioc->config_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->config_cmds.smid != smid) ++ return 1; ++ ioc->config_cmds.status |= MPT3_CMD_COMPLETE; ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) { ++ ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID; ++ memcpy(ioc->config_cmds.reply, mpi_reply, ++ mpi_reply->MsgLength*4); ++ } ++ ioc->config_cmds.status &= ~MPT3_CMD_PENDING; ++ _config_display_some_debug(ioc, smid, "config_done", mpi_reply); ++ ioc->config_cmds.smid = USHRT_MAX; ++ complete(&ioc->config_cmds.done); ++ return 1; ++} ++ ++/** ++ * _config_request - main routine for sending config page requests ++ * @ioc: per adapter object ++ * @mpi_request: request message frame ++ * @mpi_reply: reply mf payload returned from firmware ++ * @timeout: timeout in seconds ++ * @config_page: contents of the config page ++ * @config_page_sz: size of config page ++ * Context: sleep ++ * ++ * A generic API for config page requests to firmware. ++ * ++ * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling ++ * this API. ++ * ++ * The callback index is set inside `ioc->config_cb_idx. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t ++ *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout, ++ void *config_page, u16 config_page_sz) ++{ ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ Mpi2ConfigRequest_t *config_request; ++ int r; ++ u8 retry_count, issue_host_reset = 0; ++ u16 wait_state_count; ++ struct config_request mem; ++ u32 ioc_status = UINT_MAX; ++ ++ mutex_lock(&ioc->config_cmds.mutex); ++ if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: config_cmd in use\n", ++ ioc->name, __func__); ++ mutex_unlock(&ioc->config_cmds.mutex); ++ return -EAGAIN; ++ } ++ ++ retry_count = 0; ++ memset(&mem, 0, sizeof(struct config_request)); ++ ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ if (config_page) { ++ mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion; ++ mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber; ++ mpi_request->Header.PageType = mpi_reply->Header.PageType; ++ mpi_request->Header.PageLength = mpi_reply->Header.PageLength; ++ mpi_request->ExtPageLength = mpi_reply->ExtPageLength; ++ mpi_request->ExtPageType = mpi_reply->ExtPageType; ++ if (mpi_request->Header.PageLength) ++ mem.sz = mpi_request->Header.PageLength * 4; ++ else ++ mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4; ++ r = _config_alloc_config_dma_memory(ioc, &mem); ++ if (r != 0) ++ goto out; ++ if (mpi_request->Action == ++ MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT || ++ mpi_request->Action == ++ MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { ++ ioc->base_add_sg_single(&mpi_request->PageBufferSGE, ++ MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, ++ mem.page_dma); ++ memcpy(mem.page, config_page, min_t(u16, mem.sz, ++ config_page_sz)); ++ } else { ++ memset(config_page, 0, config_page_sz); ++ ioc->base_add_sg_single(&mpi_request->PageBufferSGE, ++ MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma); ++ memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz)); ++ } ++ } ++ ++ retry_config: ++ if (retry_count) { ++ if (retry_count > 2) { /* attempt only 2 retries */ ++ r = -EFAULT; ++ goto free_mem; ++ } ++ pr_info(MPT3SAS_FMT "%s: attempting retry (%d)\n", ++ ioc->name, __func__, retry_count); ++ } ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ r = -EFAULT; ++ goto free_mem; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ r = -EAGAIN; ++ goto free_mem; ++ } ++ ++ r = 0; ++ memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t)); ++ ioc->config_cmds.status = MPT3_CMD_PENDING; ++ config_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->config_cmds.smid = smid; ++ memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); ++ _config_display_some_debug(ioc, smid, "config_request", NULL); ++ init_completion(&ioc->config_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->config_cmds.done, ++ timeout*HZ); ++ if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2ConfigRequest_t)/4); ++ retry_count++; ++ if (ioc->config_cmds.smid == smid) ++ mpt2sas_base_free_smid(ioc, smid); ++ if ((ioc->shost_recovery) || (ioc->config_cmds.status & ++ MPT3_CMD_RESET) || ioc->pci_error_recovery) ++ goto retry_config; ++ issue_host_reset = 1; ++ r = -EFAULT; ++ goto free_mem; ++ } ++ ++ if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) { ++ memcpy(mpi_reply, ioc->config_cmds.reply, ++ sizeof(Mpi2ConfigReply_t)); ++ ++ /* Reply Frame Sanity Checks to workaround FW issues */ ++ if ((mpi_request->Header.PageType & 0xF) != ++ (mpi_reply->Header.PageType & 0xF)) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \ ++ " mpi_reply mismatch: Requested PageType(0x%02x)" \ ++ " Reply PageType(0x%02x)\n", \ ++ ioc->name, __func__, ++ (mpi_request->Header.PageType & 0xF), ++ (mpi_reply->Header.PageType & 0xF)); ++ } ++ ++ if (((mpi_request->Header.PageType & 0xF) == ++ MPI2_CONFIG_PAGETYPE_EXTENDED) && ++ mpi_request->ExtPageType != mpi_reply->ExtPageType) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \ ++ " mpi_reply mismatch: Requested ExtPageType(0x%02x)" ++ " Reply ExtPageType(0x%02x)\n", ++ ioc->name, __func__, mpi_request->ExtPageType, ++ mpi_reply->ExtPageType); ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) ++ & MPI2_IOCSTATUS_MASK; ++ } ++ ++ if (retry_count) ++ pr_info(MPT3SAS_FMT "%s: retry (%d) completed!!\n", \ ++ ioc->name, __func__, retry_count); ++ ++ if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) && ++ config_page && mpi_request->Action == ++ MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) { ++ u8 *p = (u8 *)mem.page; ++ ++ /* Config Page Sanity Checks to workaround FW issues */ ++ if (p) { ++ if ((mpi_request->Header.PageType & 0xF) != ++ (p[3] & 0xF)) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ _debug_dump_config(p, min_t(u16, mem.sz, ++ config_page_sz)/4); ++ panic(KERN_WARNING MPT3SAS_FMT ++ "%s: Firmware BUG:" \ ++ " config page mismatch:" ++ " Requested PageType(0x%02x)" ++ " Reply PageType(0x%02x)\n", ++ ioc->name, __func__, ++ (mpi_request->Header.PageType & 0xF), ++ (p[3] & 0xF)); ++ } ++ ++ if (((mpi_request->Header.PageType & 0xF) == ++ MPI2_CONFIG_PAGETYPE_EXTENDED) && ++ (mpi_request->ExtPageType != p[6])) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ _debug_dump_config(p, min_t(u16, mem.sz, ++ config_page_sz)/4); ++ panic(KERN_WARNING MPT3SAS_FMT ++ "%s: Firmware BUG:" \ ++ " config page mismatch:" ++ " Requested ExtPageType(0x%02x)" ++ " Reply ExtPageType(0x%02x)\n", ++ ioc->name, __func__, ++ mpi_request->ExtPageType, p[6]); ++ } ++ } ++ memcpy(config_page, mem.page, min_t(u16, mem.sz, ++ config_page_sz)); ++ } ++ ++ free_mem: ++ if (config_page) ++ _config_free_config_dma_memory(ioc, &mem); ++ out: ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->config_cmds.mutex); ++ ++ if (issue_host_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg7 - obtain manufacturing page 7 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 7; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage10_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 10; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 11; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_set_manufacturing_pg11 - set manufacturing page 11 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 11; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_bios_pg2 - obtain bios page 2 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; ++ mpi_request.Header.PageNumber = 2; ++ mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_bios_pg3 - obtain bios page 3 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2BiosPage3_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; ++ mpi_request.Header.PageNumber = 3; ++ mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_set_iounit_pg1 - set iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg3 - obtain iounit page 3 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 3; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg8 - obtain iounit page 8 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 8; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; ++ mpi_request.Header.PageNumber = 8; ++ mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: device handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, ++ u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; ++ mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; ++ mpi_request.Header.PageNumber = 0; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: device handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, ++ u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; ++ mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION; ++ mpi_request.Header.PageNumber = 1; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host ++ * @ioc: per adapter object ++ * @num_phys: pointer returned with the number of phys ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ u16 ioc_status; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t config_page; ++ ++ *num_phys = 0; ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, ++ sizeof(Mpi2SasIOUnitPage0_t)); ++ if (!r) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) ++ *num_phys = config_page.NumPhys; ++ } ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Calling function should call config_get_number_hba_phys prior to ++ * this function, so enough memory is allocated for config_page. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Calling function should call config_get_number_hba_phys prior to ++ * this function, so enough memory is allocated for config_page. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Calling function should call config_get_number_hba_phys prior to ++ * this function, so enough memory is allocated for config_page. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; ++ _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_expander_pg0 - obtain expander page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: expander handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_expander_pg1 - obtain expander page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @phy_number: phy number ++ * @handle: expander handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, ++ u16 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | ++ (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: expander handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_phy_pg0 - obtain phy page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @phy_number: phy number ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_phy_pg1 - obtain phy page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @phy_number: phy number ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: volume handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, ++ u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume ++ * @ioc: per adapter object ++ * @handle: volume handle ++ * @num_pds: returns pds count ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u8 *num_pds) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ Mpi2RaidVolPage0_t config_page; ++ Mpi2ConfigReply_t mpi_reply; ++ int r; ++ u16 ioc_status; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ *num_pds = 0; ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, ++ sizeof(Mpi2RaidVolPage0_t)); ++ if (!r) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) ++ *num_pds = config_page.NumPhysDisks; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: volume handle ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, ++ u32 handle, u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE ++ * @form_specific: specific to the form ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, ++ u32 form_specific) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | form_specific); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_volume_handle - returns volume handle for give hidden ++ * raid components ++ * @ioc: per adapter object ++ * @pd_handle: phys disk handle ++ * @volume_handle: volume handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, ++ u16 *volume_handle) ++{ ++ Mpi2RaidConfigurationPage0_t *config_page = NULL; ++ Mpi2ConfigRequest_t mpi_request; ++ Mpi2ConfigReply_t mpi_reply; ++ int r, i, config_page_sz; ++ u16 ioc_status; ++ int config_num; ++ u16 element_type; ++ u16 phys_disk_dev_handle; ++ ++ *volume_handle = 0; ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; ++ mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; ++ mpi_request.Header.PageNumber = 0; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); ++ config_page = kmalloc(config_page_sz, GFP_KERNEL); ++ if (!config_page) { ++ r = -1; ++ goto out; ++ } ++ ++ config_num = 0xff; ++ while (1) { ++ mpi_request.PageAddress = cpu_to_le32(config_num + ++ MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ config_page_sz); ++ if (r) ++ goto out; ++ r = -1; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ goto out; ++ for (i = 0; i < config_page->NumElements; i++) { ++ element_type = le16_to_cpu(config_page-> ++ ConfigElement[i].ElementFlags) & ++ MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; ++ if (element_type == ++ MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || ++ element_type == ++ MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { ++ phys_disk_dev_handle = ++ le16_to_cpu(config_page->ConfigElement[i]. ++ PhysDiskDevHandle); ++ if (phys_disk_dev_handle == pd_handle) { ++ *volume_handle = ++ le16_to_cpu(config_page-> ++ ConfigElement[i].VolDevHandle); ++ r = 0; ++ goto out; ++ } ++ } else if (element_type == ++ MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { ++ *volume_handle = 0; ++ r = 0; ++ goto out; ++ } ++ } ++ config_num = config_page->ConfigNum; ++ } ++ out: ++ kfree(config_page); ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle ++ * @ioc: per adapter object ++ * @volume_handle: volume handle ++ * @wwid: volume wwid ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, ++ u64 *wwid) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2RaidVolPage1_t raid_vol_pg1; ++ ++ *wwid = 0; ++ if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, ++ volume_handle))) { ++ *wwid = le64_to_cpu(raid_vol_pg1.WWID); ++ return 0; ++ } else ++ return -1; ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_ctl.c b/drivers/scsi/mpt2sas/mpt3sas_ctl.c +new file mode 100644 +index 0000000..5c0cc30 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_ctl.c +@@ -0,0 +1,3483 @@ ++/* ++ * Management Module Support for MPT (Message Passing Technology) based ++ * controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mpt3sas_base.h" ++#include "mpt3sas_ctl.h" ++ ++ ++static struct fasync_struct *async_queue; ++static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait); ++ ++ ++/** ++ * enum block_state - blocking state ++ * @NON_BLOCKING: non blocking ++ * @BLOCKING: blocking ++ * ++ * These states are for ioctls that need to wait for a response ++ * from firmware, so they probably require sleep. ++ */ ++enum block_state { ++ NON_BLOCKING, ++ BLOCKING, ++}; ++ ++/** ++ * _ctl_sas_device_find_by_handle - sas device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for sas_device based on sas_address, then return sas_device ++ * object. ++ */ ++static struct _sas_device * ++_ctl_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if (sas_device->handle != handle) ++ continue; ++ r = sas_device; ++ goto out; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * _ctl_display_some_debug - debug routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @calling_function_name: string pass from calling function ++ * @mpi_reply: reply message frame ++ * Context: none. ++ * ++ * Function for displaying debug info helpful when debugging issues ++ * in this module. ++ */ ++static void ++_ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ char *calling_function_name, MPI2DefaultReply_t *mpi_reply) ++{ ++ Mpi2ConfigRequest_t *mpi_request; ++ char *desc = NULL; ++ ++ if (!(ioc->logging_level & MPT_DEBUG_IOCTL)) ++ return; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ switch (mpi_request->Function) { ++ case MPI2_FUNCTION_SCSI_IO_REQUEST: ++ { ++ Mpi2SCSIIORequest_t *scsi_request = ++ (Mpi2SCSIIORequest_t *)mpi_request; ++ ++ snprintf(ioc->tmp_string, MPT_STRING_LENGTH, ++ "scsi_io, cmd(0x%02x), cdb_len(%d)", ++ scsi_request->CDB.CDB32[0], ++ le16_to_cpu(scsi_request->IoFlags) & 0xF); ++ desc = ioc->tmp_string; ++ break; ++ } ++ case MPI2_FUNCTION_SCSI_TASK_MGMT: ++ desc = "task_mgmt"; ++ break; ++ case MPI2_FUNCTION_IOC_INIT: ++ desc = "ioc_init"; ++ break; ++ case MPI2_FUNCTION_IOC_FACTS: ++ desc = "ioc_facts"; ++ break; ++ case MPI2_FUNCTION_CONFIG: ++ { ++ Mpi2ConfigRequest_t *config_request = ++ (Mpi2ConfigRequest_t *)mpi_request; ++ ++ snprintf(ioc->tmp_string, MPT_STRING_LENGTH, ++ "config, type(0x%02x), ext_type(0x%02x), number(%d)", ++ (config_request->Header.PageType & ++ MPI2_CONFIG_PAGETYPE_MASK), config_request->ExtPageType, ++ config_request->Header.PageNumber); ++ desc = ioc->tmp_string; ++ break; ++ } ++ case MPI2_FUNCTION_PORT_FACTS: ++ desc = "port_facts"; ++ break; ++ case MPI2_FUNCTION_PORT_ENABLE: ++ desc = "port_enable"; ++ break; ++ case MPI2_FUNCTION_EVENT_NOTIFICATION: ++ desc = "event_notification"; ++ break; ++ case MPI2_FUNCTION_FW_DOWNLOAD: ++ desc = "fw_download"; ++ break; ++ case MPI2_FUNCTION_FW_UPLOAD: ++ desc = "fw_upload"; ++ break; ++ case MPI2_FUNCTION_RAID_ACTION: ++ desc = "raid_action"; ++ break; ++ case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: ++ { ++ Mpi2SCSIIORequest_t *scsi_request = ++ (Mpi2SCSIIORequest_t *)mpi_request; ++ ++ snprintf(ioc->tmp_string, MPT_STRING_LENGTH, ++ "raid_pass, cmd(0x%02x), cdb_len(%d)", ++ scsi_request->CDB.CDB32[0], ++ le16_to_cpu(scsi_request->IoFlags) & 0xF); ++ desc = ioc->tmp_string; ++ break; ++ } ++ case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: ++ desc = "sas_iounit_cntl"; ++ break; ++ case MPI2_FUNCTION_SATA_PASSTHROUGH: ++ desc = "sata_pass"; ++ break; ++ case MPI2_FUNCTION_DIAG_BUFFER_POST: ++ desc = "diag_buffer_post"; ++ break; ++ case MPI2_FUNCTION_DIAG_RELEASE: ++ desc = "diag_release"; ++ break; ++ case MPI2_FUNCTION_SMP_PASSTHROUGH: ++ desc = "smp_passthrough"; ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ pr_info(MPT3SAS_FMT "%s: %s, smid(%d)\n", ++ ioc->name, calling_function_name, desc, smid); ++ ++ if (!mpi_reply) ++ return; ++ ++ if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "\tiocstatus(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo)); ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_request->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { ++ Mpi2SCSIIOReply_t *scsi_reply = ++ (Mpi2SCSIIOReply_t *)mpi_reply; ++ struct _sas_device *sas_device = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = _ctl_sas_device_find_by_handle(ioc, ++ le16_to_cpu(scsi_reply->DevHandle)); ++ if (sas_device) { ++ pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), phy(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->sas_address, sas_device->phy); ++ pr_warn(MPT3SAS_FMT ++ "\tenclosure_logical_id(0x%016llx), slot(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (scsi_reply->SCSIState || scsi_reply->SCSIStatus) ++ pr_info(MPT3SAS_FMT ++ "\tscsi_state(0x%02x), scsi_status" ++ "(0x%02x)\n", ioc->name, ++ scsi_reply->SCSIState, ++ scsi_reply->SCSIStatus); ++ } ++} ++ ++/** ++ * mpt2sas_ctl_done - ctl module completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: none. ++ * ++ * The callback handler when using ioc->ctl_cb_idx. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ Mpi2SCSIIOReply_t *scsiio_reply; ++ const void *sense_data; ++ u32 sz; ++ ++ if (ioc->ctl_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->ctl_cmds.smid != smid) ++ return 1; ++ ioc->ctl_cmds.status |= MPT3_CMD_COMPLETE; ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) { ++ memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ ioc->ctl_cmds.status |= MPT3_CMD_REPLY_VALID; ++ /* get sense data */ ++ if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_reply->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { ++ scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply; ++ if (scsiio_reply->SCSIState & ++ MPI2_SCSI_STATE_AUTOSENSE_VALID) { ++ sz = min_t(u32, SCSI_SENSE_BUFFERSIZE, ++ le32_to_cpu(scsiio_reply->SenseCount)); ++ sense_data = mpt2sas_base_get_sense_buffer(ioc, ++ smid); ++ memcpy(ioc->ctl_cmds.sense, sense_data, sz); ++ } ++ } ++ } ++ _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); ++ ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->ctl_cmds.done); ++ return 1; ++} ++ ++/** ++ * _ctl_check_event_type - determines when an event needs logging ++ * @ioc: per adapter object ++ * @event: firmware event ++ * ++ * The bitmask in ioc->event_type[] indicates which events should be ++ * be saved in the driver event_log. This bitmask is set by application. ++ * ++ * Returns 1 when event should be captured, or zero means no match. ++ */ ++static int ++_ctl_check_event_type(struct MPT3SAS_ADAPTER *ioc, u16 event) ++{ ++ u16 i; ++ u32 desired_event; ++ ++ if (event >= 128 || !event || !ioc->event_log) ++ return 0; ++ ++ desired_event = (1 << (event % 32)); ++ if (!desired_event) ++ desired_event = 1; ++ i = event / 32; ++ return desired_event & ioc->event_type[i]; ++} ++ ++/** ++ * mpt2sas_ctl_add_to_event_log - add event ++ * @ioc: per adapter object ++ * @mpi_reply: reply message frame ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_ctl_add_to_event_log(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventNotificationReply_t *mpi_reply) ++{ ++ struct MPT3_IOCTL_EVENTS *event_log; ++ u16 event; ++ int i; ++ u32 sz, event_data_sz; ++ u8 send_aen = 0; ++ ++ if (!ioc->event_log) ++ return; ++ ++ event = le16_to_cpu(mpi_reply->Event); ++ ++ if (_ctl_check_event_type(ioc, event)) { ++ ++ /* insert entry into circular event_log */ ++ i = ioc->event_context % MPT3SAS_CTL_EVENT_LOG_SIZE; ++ event_log = ioc->event_log; ++ event_log[i].event = event; ++ event_log[i].context = ioc->event_context++; ++ ++ event_data_sz = le16_to_cpu(mpi_reply->EventDataLength)*4; ++ sz = min_t(u32, event_data_sz, MPT3_EVENT_DATA_SIZE); ++ memset(event_log[i].data, 0, MPT3_EVENT_DATA_SIZE); ++ memcpy(event_log[i].data, mpi_reply->EventData, sz); ++ send_aen = 1; ++ } ++ ++ /* This aen_event_read_flag flag is set until the ++ * application has read the event log. ++ * For MPI2_EVENT_LOG_ENTRY_ADDED, we always notify. ++ */ ++ if (event == MPI2_EVENT_LOG_ENTRY_ADDED || ++ (send_aen && !ioc->aen_event_read_flag)) { ++ ioc->aen_event_read_flag = 1; ++ wake_up_interruptible(&ctl_poll_wait); ++ if (async_queue) ++ kill_fasync(&async_queue, SIGIO, POLL_IN); ++ } ++} ++ ++/** ++ * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time) ++ * @ioc: per adapter object ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt. ++ * ++ * This function merely adds a new work task into ioc->firmware_event_thread. ++ * The tasks are worked from _firmware_event_work in user context. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ++ u32 reply) ++{ ++ Mpi2EventNotificationReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) ++ mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); ++ return 1; ++} ++ ++/** ++ * _ctl_verify_adapter - validates ioc_number passed from application ++ * @ioc: per adapter object ++ * @iocpp: The ioc pointer is returned in this. ++ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device & ++ * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device. ++ * ++ * Return (-1) means error, else ioc_number. ++ */ ++static int ++_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp, ++ int mpi_version) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ int version = 0; ++ /* global ioc lock to protect controller on list operations */ ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { ++ if (ioc->id != ioc_number) ++ continue; ++ /* Check whether this ioctl command is from right ++ * ioctl device or not, if not continue the search. ++ */ ++ version = ioc->hba_mpi_version_belonged; ++ /* MPI25_VERSION and MPI26_VERSION uses same ioctl ++ * device. ++ */ ++ if (mpi_version == (MPI25_VERSION | MPI26_VERSION)) { ++ if ((version == MPI25_VERSION) || ++ (version == MPI26_VERSION)) ++ goto out; ++ else ++ continue; ++ } else { ++ if (version != mpi_version) ++ continue; ++ } ++out: ++ spin_unlock(&gioc_lock_mpt2sas); ++ *iocpp = ioc; ++ return ioc_number; ++ } ++ spin_unlock(&gioc_lock_mpt2sas); ++ *iocpp = NULL; ++ return -1; ++} ++ ++/** ++ * mpt2sas_ctl_reset_handler - reset callback handler (for ctl) ++ * @ioc: per adapter object ++ * @reset_phase: phase ++ * ++ * The handler for doing any required cleanup or initialization. ++ * ++ * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET, ++ * MPT3_IOC_DONE_RESET ++ */ ++void ++mpt2sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) ++{ ++ int i; ++ u8 issue_reset; ++ ++ switch (reset_phase) { ++ case MPT3_IOC_PRE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__)); ++ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { ++ if (!(ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED)) ++ continue; ++ if ((ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ continue; ++ mpt2sas_send_diag_release(ioc, i, &issue_reset); ++ } ++ break; ++ case MPT3_IOC_AFTER_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__)); ++ if (ioc->ctl_cmds.status & MPT3_CMD_PENDING) { ++ ioc->ctl_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->ctl_cmds.smid); ++ complete(&ioc->ctl_cmds.done); ++ } ++ break; ++ case MPT3_IOC_DONE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__)); ++ ++ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { ++ if (!(ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED)) ++ continue; ++ if ((ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ continue; ++ ioc->diag_buffer_status[i] |= ++ MPT3_DIAG_BUFFER_IS_DIAG_RESET; ++ } ++ break; ++ } ++} ++ ++/** ++ * _ctl_fasync_mpt2sas - ++ * @fd - ++ * @filep - ++ * @mode - ++ * ++ * Called when application request fasyn callback handler. ++ */ ++int ++_ctl_fasync_mpt2sas(int fd, struct file *filep, int mode) ++{ ++ return fasync_helper(fd, filep, mode, &async_queue); ++} ++ ++/** ++ * _ctl_poll_mpt2sas - ++ * @file - ++ * @wait - ++ * ++ */ ++unsigned int ++_ctl_poll_mpt2sas(struct file *filep, poll_table *wait) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ poll_wait(filep, &ctl_poll_wait, wait); ++ ++ /* global ioc lock to protect controller on list operations */ ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { ++ if (ioc->aen_event_read_flag) { ++ spin_unlock(&gioc_lock_mpt2sas); ++ return POLLIN | POLLRDNORM; ++ } ++ } ++ spin_unlock(&gioc_lock_mpt2sas); ++ return 0; ++} ++ ++/** ++ * _ctl_set_task_mid - assign an active smid to tm request ++ * @ioc: per adapter object ++ * @karg - (struct mpt3_ioctl_command) ++ * @tm_request - pointer to mf from user space ++ * ++ * Returns 0 when an smid if found, else fail. ++ * during failure, the reply frame is filled. ++ */ ++static int ++_ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command *karg, ++ Mpi2SCSITaskManagementRequest_t *tm_request) ++{ ++ u8 found = 0; ++ u16 i; ++ u16 handle; ++ struct scsi_cmnd *scmd; ++ struct MPT3SAS_DEVICE *priv_data; ++ unsigned long flags; ++ Mpi2SCSITaskManagementReply_t *tm_reply; ++ u32 sz; ++ u32 lun; ++ char *desc = NULL; ++ ++ if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) ++ desc = "abort_task"; ++ else if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) ++ desc = "query_task"; ++ else ++ return 0; ++ ++ lun = scsilun_to_int((struct scsi_lun *)tm_request->LUN); ++ ++ handle = le16_to_cpu(tm_request->DevHandle); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ for (i = ioc->scsiio_depth; i && !found; i--) { ++ scmd = ioc->scsi_lookup[i - 1].scmd; ++ if (scmd == NULL || scmd->device == NULL || ++ scmd->device->hostdata == NULL) ++ continue; ++ if (lun != scmd->device->lun) ++ continue; ++ priv_data = scmd->device->hostdata; ++ if (priv_data->sas_target == NULL) ++ continue; ++ if (priv_data->sas_target->handle != handle) ++ continue; ++ tm_request->TaskMID = cpu_to_le16(ioc->scsi_lookup[i - 1].smid); ++ found = 1; ++ } ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ if (!found) { ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), lun(%d), no active mid!!\n", ++ ioc->name, ++ desc, le16_to_cpu(tm_request->DevHandle), lun)); ++ tm_reply = ioc->ctl_cmds.reply; ++ tm_reply->DevHandle = tm_request->DevHandle; ++ tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ tm_reply->TaskType = tm_request->TaskType; ++ tm_reply->MsgLength = sizeof(Mpi2SCSITaskManagementReply_t)/4; ++ tm_reply->VP_ID = tm_request->VP_ID; ++ tm_reply->VF_ID = tm_request->VF_ID; ++ sz = min_t(u32, karg->max_reply_bytes, ioc->reply_sz); ++ if (copy_to_user(karg->reply_frame_buf_ptr, ioc->ctl_cmds.reply, ++ sz)) ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ return 1; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name, ++ desc, le16_to_cpu(tm_request->DevHandle), lun, ++ le16_to_cpu(tm_request->TaskMID))); ++ return 0; ++} ++ ++/** ++ * _ctl_do_mpt_command - main handler for MPT3COMMAND opcode ++ * @ioc: per adapter object ++ * @karg - (struct mpt3_ioctl_command) ++ * @mf - pointer to mf in user space ++ */ ++static long ++_ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ++ void __user *mf) ++{ ++ MPI2RequestHeader_t *mpi_request = NULL, *request; ++ MPI2DefaultReply_t *mpi_reply; ++ u32 ioc_state; ++ u16 ioc_status; ++ u16 smid; ++ unsigned long timeout, timeleft; ++ u8 issue_reset; ++ u32 sz; ++ void *psge; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma = 0; ++ size_t data_out_sz = 0; ++ void *data_in = NULL; ++ dma_addr_t data_in_dma = 0; ++ size_t data_in_sz = 0; ++ long ret; ++ u16 wait_state_count; ++ ++ issue_reset = 0; ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ ret = -EAGAIN; ++ goto out; ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ ret = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, ++ __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL); ++ if (!mpi_request) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed obtaining a memory for mpi_request\n", ++ ioc->name, __func__); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ /* Check for overflow and wraparound */ ++ if (karg.data_sge_offset * 4 > ioc->request_sz || ++ karg.data_sge_offset > (UINT_MAX / 4)) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ /* copy in request message frame from user */ ++ if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, __LINE__, ++ __func__); ++ ret = -EFAULT; ++ goto out; ++ } ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ret = -EAGAIN; ++ goto out; ++ } ++ } else { ++ ++ smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ret = -EAGAIN; ++ goto out; ++ } ++ } ++ ++ ret = 0; ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memcpy(request, mpi_request, karg.data_sge_offset*4); ++ ioc->ctl_cmds.smid = smid; ++ data_out_sz = karg.data_out_size; ++ data_in_sz = karg.data_in_size; ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { ++ if (!le16_to_cpu(mpi_request->FunctionDependent1) || ++ le16_to_cpu(mpi_request->FunctionDependent1) > ++ ioc->facts.MaxDevHandle) { ++ ret = -EINVAL; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ /* obtain dma-able memory for data transfer */ ++ if (data_out_sz) /* WRITE */ { ++ data_out = pci_alloc_consistent(ioc->pdev, data_out_sz, ++ &data_out_dma); ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ if (copy_from_user(data_out, karg.data_out_buf_ptr, ++ data_out_sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -EFAULT; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ if (data_in_sz) /* READ */ { ++ data_in = pci_alloc_consistent(ioc->pdev, data_in_sz, ++ &data_in_dma); ++ if (!data_in) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ psge = (void *)request + (karg.data_sge_offset*4); ++ ++ /* send command to firmware */ ++ _ctl_display_some_debug(ioc, smid, "ctl_request", NULL); ++ ++ init_completion(&ioc->ctl_cmds.done); ++ switch (mpi_request->Function) { ++ case MPI2_FUNCTION_SCSI_IO_REQUEST: ++ case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: ++ { ++ Mpi2SCSIIORequest_t *scsiio_request = ++ (Mpi2SCSIIORequest_t *)request; ++ scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; ++ scsiio_request->SenseBufferLowAddress = ++ mpt2sas_base_get_sense_buffer_dma(ioc, smid); ++ memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE); ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) ++ mpt2sas_base_put_smid_scsi_io(ioc, smid, ++ le16_to_cpu(mpi_request->FunctionDependent1)); ++ else ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_SCSI_TASK_MGMT: ++ { ++ Mpi2SCSITaskManagementRequest_t *tm_request = ++ (Mpi2SCSITaskManagementRequest_t *)request; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n", ++ ioc->name, ++ le16_to_cpu(tm_request->DevHandle), tm_request->TaskType)); ++ ++ if (tm_request->TaskType == ++ MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK || ++ tm_request->TaskType == ++ MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) { ++ if (_ctl_set_task_mid(ioc, &karg, tm_request)) { ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu( ++ tm_request->DevHandle)); ++ ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, 0); ++ break; ++ } ++ case MPI2_FUNCTION_SMP_PASSTHROUGH: ++ { ++ Mpi2SmpPassthroughRequest_t *smp_request = ++ (Mpi2SmpPassthroughRequest_t *)mpi_request; ++ u8 *data; ++ ++ /* ioc determines which port to use */ ++ smp_request->PhysicalPort = 0xFF; ++ if (smp_request->PassthroughFlags & ++ MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE) ++ data = (u8 *)&smp_request->SGL; ++ else { ++ if (unlikely(data_out == NULL)) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ mpt2sas_base_free_smid(ioc, smid); ++ ret = -EINVAL; ++ goto out; ++ } ++ data = data_out; ++ } ++ ++ if (data[1] == 0x91 && (data[10] == 1 || data[10] == 2)) { ++ ioc->ioc_link_reset_in_progress = 1; ++ ioc->ignore_loginfos = 1; ++ } ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_SATA_PASSTHROUGH: ++ case MPI2_FUNCTION_FW_DOWNLOAD: ++ case MPI2_FUNCTION_FW_UPLOAD: ++ { ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_TOOLBOX: ++ { ++ Mpi2ToolboxCleanRequest_t *toolbox_request = ++ (Mpi2ToolboxCleanRequest_t *)mpi_request; ++ ++ if (toolbox_request->Tool == MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL) { ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ } else { ++ ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ } ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: ++ { ++ Mpi2SasIoUnitControlRequest_t *sasiounit_request = ++ (Mpi2SasIoUnitControlRequest_t *)mpi_request; ++ ++ if (sasiounit_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ++ || sasiounit_request->Operation == ++ MPI2_SAS_OP_PHY_LINK_RESET) { ++ ioc->ioc_link_reset_in_progress = 1; ++ ioc->ignore_loginfos = 1; ++ } ++ /* drop to default case for posting the request */ ++ } ++ default: ++ ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ ++ if (karg.timeout < MPT3_IOCTL_DEFAULT_TIMEOUT) ++ timeout = MPT3_IOCTL_DEFAULT_TIMEOUT; ++ else ++ timeout = karg.timeout; ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ timeout*HZ); ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { ++ Mpi2SCSITaskManagementRequest_t *tm_request = ++ (Mpi2SCSITaskManagementRequest_t *)mpi_request; ++ mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu( ++ tm_request->DevHandle)); ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); ++ } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH || ++ mpi_request->Function == MPI2_FUNCTION_SAS_IO_UNIT_CONTROL) && ++ ioc->ioc_link_reset_in_progress) { ++ ioc->ioc_link_reset_in_progress = 0; ++ ioc->ignore_loginfos = 0; ++ } ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, karg.data_sge_offset); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT && ++ (ioc->logging_level & MPT_DEBUG_TM)) { ++ Mpi2SCSITaskManagementReply_t *tm_reply = ++ (Mpi2SCSITaskManagementReply_t *)mpi_reply; ++ ++ pr_info(MPT3SAS_FMT "TASK_MGMT: " \ ++ "IOCStatus(0x%04x), IOCLogInfo(0x%08x), " ++ "TerminationCount(0x%08x)\n", ioc->name, ++ le16_to_cpu(tm_reply->IOCStatus), ++ le32_to_cpu(tm_reply->IOCLogInfo), ++ le32_to_cpu(tm_reply->TerminationCount)); ++ } ++ ++ /* copy out xdata to user */ ++ if (data_in_sz) { ++ if (copy_to_user(karg.data_in_buf_ptr, data_in, ++ data_in_sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENODATA; ++ goto out; ++ } ++ } ++ ++ /* copy out reply message frame to user */ ++ if (karg.max_reply_bytes) { ++ sz = min_t(u32, karg.max_reply_bytes, ioc->reply_sz); ++ if (copy_to_user(karg.reply_frame_buf_ptr, ioc->ctl_cmds.reply, ++ sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENODATA; ++ goto out; ++ } ++ } ++ ++ /* copy out sense to user */ ++ if (karg.max_sense_bytes && (mpi_request->Function == ++ MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { ++ sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE); ++ if (copy_to_user(karg.sense_data_ptr, ioc->ctl_cmds.sense, ++ sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENODATA; ++ goto out; ++ } ++ } ++ ++ issue_host_reset: ++ if (issue_reset) { ++ ret = -ENODATA; ++ if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_request->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || ++ mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH)) { ++ pr_info(MPT3SAS_FMT "issue target reset: handle = (0x%04x)\n", ++ ioc->name, ++ le16_to_cpu(mpi_request->FunctionDependent1)); ++ mpt2sas_halt_firmware(ioc); ++ mpt2sas_scsih_issue_tm(ioc, ++ le16_to_cpu(mpi_request->FunctionDependent1), 0, 0, ++ 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30, ++ TM_MUTEX_ON); ++ } else ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ } ++ ++ out: ++ ++ /* free memory associated with sg buffers */ ++ if (data_in) ++ pci_free_consistent(ioc->pdev, data_in_sz, data_in, ++ data_in_dma); ++ ++ if (data_out) ++ pci_free_consistent(ioc->pdev, data_out_sz, data_out, ++ data_out_dma); ++ ++ kfree(mpi_request); ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return ret; ++} ++ ++/** ++ * _ctl_getiocinfo - main handler for MPT3IOCINFO opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_iocinfo karg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ memset(&karg, 0 , sizeof(karg)); ++ if (ioc->pfacts) ++ karg.port_number = ioc->pfacts[0].PortNumber; ++ karg.hw_rev = ioc->pdev->revision; ++ karg.pci_id = ioc->pdev->device; ++ karg.subsystem_device = ioc->pdev->subsystem_device; ++ karg.subsystem_vendor = ioc->pdev->subsystem_vendor; ++ karg.pci_information.u.bits.bus = ioc->pdev->bus->number; ++ karg.pci_information.u.bits.device = PCI_SLOT(ioc->pdev->devfn); ++ karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn); ++ karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus); ++ karg.firmware_version = ioc->facts.FWVersion.Word; ++ strcpy(karg.driver_version, ioc->driver_name); ++ strcat(karg.driver_version, "-"); ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ if (ioc->is_warpdrive) ++ karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200; ++ else ++ karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; ++ strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3; ++ strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION); ++ break; ++ } ++ karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); ++ ++ if (copy_to_user(arg, &karg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_eventquery - main handler for MPT3EVENTQUERY opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_eventquery(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_eventquery karg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ karg.event_entries = MPT3SAS_CTL_EVENT_LOG_SIZE; ++ memcpy(karg.event_types, ioc->event_type, ++ MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32)); ++ ++ if (copy_to_user(arg, &karg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_eventenable - main handler for MPT3EVENTENABLE opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_eventenable(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_eventenable karg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ memcpy(ioc->event_type, karg.event_types, ++ MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32)); ++ mpt2sas_base_validate_event_type(ioc, ioc->event_type); ++ ++ if (ioc->event_log) ++ return 0; ++ /* initialize event_log */ ++ ioc->event_context = 0; ++ ioc->aen_event_read_flag = 0; ++ ioc->event_log = kcalloc(MPT3SAS_CTL_EVENT_LOG_SIZE, ++ sizeof(struct MPT3_IOCTL_EVENTS), GFP_KERNEL); ++ if (!ioc->event_log) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_eventreport - main handler for MPT3EVENTREPORT opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_eventreport(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_eventreport karg; ++ u32 number_bytes, max_events, max; ++ struct mpt3_ioctl_eventreport __user *uarg = arg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ number_bytes = karg.hdr.max_data_size - ++ sizeof(struct mpt3_ioctl_header); ++ max_events = number_bytes/sizeof(struct MPT3_IOCTL_EVENTS); ++ max = min_t(u32, MPT3SAS_CTL_EVENT_LOG_SIZE, max_events); ++ ++ /* If fewer than 1 event is requested, there must have ++ * been some type of error. ++ */ ++ if (!max || !ioc->event_log) ++ return -ENODATA; ++ ++ number_bytes = max * sizeof(struct MPT3_IOCTL_EVENTS); ++ if (copy_to_user(uarg->event_data, ioc->event_log, number_bytes)) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ /* reset flag so SIGIO can restart */ ++ ioc->aen_event_read_flag = 0; ++ return 0; ++} ++ ++/** ++ * _ctl_do_reset - main handler for MPT3HARDRESET opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_diag_reset karg; ++ int retval; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery || ++ ioc->is_driver_loading) ++ return -EAGAIN; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ pr_info(MPT3SAS_FMT "host reset: %s\n", ++ ioc->name, ((!retval) ? "SUCCESS" : "FAILED")); ++ return 0; ++} ++ ++/** ++ * _ctl_btdh_search_sas_device - searching for sas device ++ * @ioc: per adapter object ++ * @btdh: btdh ioctl payload ++ */ ++static int ++_ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc, ++ struct mpt3_ioctl_btdh_mapping *btdh) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ int rc = 0; ++ ++ if (list_empty(&ioc->sas_device_list)) ++ return rc; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF && ++ btdh->handle == sas_device->handle) { ++ btdh->bus = sas_device->channel; ++ btdh->id = sas_device->id; ++ rc = 1; ++ goto out; ++ } else if (btdh->bus == sas_device->channel && btdh->id == ++ sas_device->id && btdh->handle == 0xFFFF) { ++ btdh->handle = sas_device->handle; ++ rc = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_btdh_search_raid_device - searching for raid device ++ * @ioc: per adapter object ++ * @btdh: btdh ioctl payload ++ */ ++static int ++_ctl_btdh_search_raid_device(struct MPT3SAS_ADAPTER *ioc, ++ struct mpt3_ioctl_btdh_mapping *btdh) ++{ ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ int rc = 0; ++ ++ if (list_empty(&ioc->raid_device_list)) ++ return rc; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF && ++ btdh->handle == raid_device->handle) { ++ btdh->bus = raid_device->channel; ++ btdh->id = raid_device->id; ++ rc = 1; ++ goto out; ++ } else if (btdh->bus == raid_device->channel && btdh->id == ++ raid_device->id && btdh->handle == 0xFFFF) { ++ btdh->handle = raid_device->handle; ++ rc = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_btdh_mapping - main handler for MPT3BTDHMAPPING opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_btdh_mapping(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_btdh_mapping karg; ++ int rc; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ rc = _ctl_btdh_search_sas_device(ioc, &karg); ++ if (!rc) ++ _ctl_btdh_search_raid_device(ioc, &karg); ++ ++ if (copy_to_user(arg, &karg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_diag_capability - return diag buffer capability ++ * @ioc: per adapter object ++ * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED ++ * ++ * returns 1 when diag buffer support is enabled in firmware ++ */ ++static u8 ++_ctl_diag_capability(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type) ++{ ++ u8 rc = 0; ++ ++ switch (buffer_type) { ++ case MPI2_DIAG_BUF_TYPE_TRACE: ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) ++ rc = 1; ++ break; ++ case MPI2_DIAG_BUF_TYPE_SNAPSHOT: ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) ++ rc = 1; ++ break; ++ case MPI2_DIAG_BUF_TYPE_EXTENDED: ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) ++ rc = 1; ++ } ++ ++ return rc; ++} ++ ++ ++/** ++ * _ctl_diag_register_2 - wrapper for registering diag buffer support ++ * @ioc: per adapter object ++ * @diag_register: the diag_register struct passed in from user space ++ * ++ */ ++static long ++_ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, ++ struct mpt3_diag_register *diag_register) ++{ ++ int rc, i; ++ void *request_data = NULL; ++ dma_addr_t request_data_dma; ++ u32 request_data_sz = 0; ++ Mpi2DiagBufferPostRequest_t *mpi_request; ++ Mpi2DiagBufferPostReply_t *mpi_reply; ++ u8 buffer_type; ++ unsigned long timeleft; ++ u16 smid; ++ u16 ioc_status; ++ u32 ioc_state; ++ u8 issue_reset = 0; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ buffer_type = diag_register->buffer_type; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if (ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) { ++ pr_err(MPT3SAS_FMT ++ "%s: already has a registered buffer for buffer_type(0x%02x)\n", ++ ioc->name, __func__, ++ buffer_type); ++ return -EINVAL; ++ } ++ ++ if (diag_register->requested_buffer_size % 4) { ++ pr_err(MPT3SAS_FMT ++ "%s: the requested_buffer_size is not 4 byte aligned\n", ++ ioc->name, __func__); ++ return -EINVAL; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->ctl_cmds.smid = smid; ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ request_data_sz = diag_register->requested_buffer_size; ++ ioc->unique_id[buffer_type] = diag_register->unique_id; ++ ioc->diag_buffer_status[buffer_type] = 0; ++ memcpy(ioc->product_specific[buffer_type], ++ diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS); ++ ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags; ++ ++ if (request_data) { ++ request_data_dma = ioc->diag_buffer_dma[buffer_type]; ++ if (request_data_sz != ioc->diag_buffer_sz[buffer_type]) { ++ pci_free_consistent(ioc->pdev, ++ ioc->diag_buffer_sz[buffer_type], ++ request_data, request_data_dma); ++ request_data = NULL; ++ } ++ } ++ ++ if (request_data == NULL) { ++ ioc->diag_buffer_sz[buffer_type] = 0; ++ ioc->diag_buffer_dma[buffer_type] = 0; ++ request_data = pci_alloc_consistent( ++ ioc->pdev, request_data_sz, &request_data_dma); ++ if (request_data == NULL) { ++ pr_err(MPT3SAS_FMT "%s: failed allocating memory" \ ++ " for diag buffers, requested size(%d)\n", ++ ioc->name, __func__, request_data_sz); ++ mpt2sas_base_free_smid(ioc, smid); ++ return -ENOMEM; ++ } ++ ioc->diag_buffer[buffer_type] = request_data; ++ ioc->diag_buffer_sz[buffer_type] = request_data_sz; ++ ioc->diag_buffer_dma[buffer_type] = request_data_dma; ++ } ++ ++ mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; ++ mpi_request->BufferType = diag_register->buffer_type; ++ mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags); ++ mpi_request->BufferAddress = cpu_to_le64(request_data_dma); ++ mpi_request->BufferLength = cpu_to_le32(request_data_sz); ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: diag_buffer(0x%p), dma(0x%llx), sz(%d)\n", ++ ioc->name, __func__, request_data, ++ (unsigned long long)request_data_dma, ++ le32_to_cpu(mpi_request->BufferLength))); ++ ++ for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) ++ mpi_request->ProductSpecific[i] = ++ cpu_to_le32(ioc->product_specific[buffer_type][i]); ++ ++ init_completion(&ioc->ctl_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); ++ ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2DiagBufferPostRequest_t)/4); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ /* process the completed Reply Message Frame */ ++ if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) { ++ pr_err(MPT3SAS_FMT "%s: no reply message\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_REGISTERED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: success\n", ++ ioc->name, __func__)); ++ } else { ++ pr_info(MPT3SAS_FMT ++ "%s: ioc_status(0x%04x) log_info(0x%08x)\n", ++ ioc->name, __func__, ++ ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); ++ rc = -EFAULT; ++ } ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ out: ++ ++ if (rc && request_data) ++ pci_free_consistent(ioc->pdev, request_data_sz, ++ request_data, request_data_dma); ++ ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return rc; ++} ++ ++/** ++ * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time ++ * @ioc: per adapter object ++ * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1 ++ * ++ * This is called when command line option diag_buffer_enable is enabled ++ * at driver load time. ++ */ ++void ++mpt2sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register) ++{ ++ struct mpt3_diag_register diag_register; ++ ++ memset(&diag_register, 0, sizeof(struct mpt3_diag_register)); ++ ++ if (bits_to_register & 1) { ++ pr_info(MPT3SAS_FMT "registering trace buffer support\n", ++ ioc->name); ++ ioc->diag_trigger_master.MasterData = ++ (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; ++ /* register for 2MB buffers */ ++ diag_register.requested_buffer_size = 2 * (1024 * 1024); ++ diag_register.unique_id = 0x7075900; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } ++ ++ if (bits_to_register & 2) { ++ pr_info(MPT3SAS_FMT "registering snapshot buffer support\n", ++ ioc->name); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT; ++ /* register for 2MB buffers */ ++ diag_register.requested_buffer_size = 2 * (1024 * 1024); ++ diag_register.unique_id = 0x7075901; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } ++ ++ if (bits_to_register & 4) { ++ pr_info(MPT3SAS_FMT "registering extended buffer support\n", ++ ioc->name); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED; ++ /* register for 2MB buffers */ ++ diag_register.requested_buffer_size = 2 * (1024 * 1024); ++ diag_register.unique_id = 0x7075901; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } ++} ++ ++/** ++ * _ctl_diag_register - application register with driver ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ * ++ * This will allow the driver to setup any required buffers that will be ++ * needed by firmware to communicate with the driver. ++ */ ++static long ++_ctl_diag_register(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_register karg; ++ long rc; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ rc = _ctl_diag_register_2(ioc, &karg); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_unregister - application unregister with driver ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ * ++ * This will allow the driver to cleanup any memory allocated for diag ++ * messages and to free up any resources. ++ */ ++static long ++_ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_unregister karg; ++ void *request_data; ++ dma_addr_t request_data_dma; ++ u32 request_data_sz; ++ u8 buffer_type; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ buffer_type = karg.unique_id & 0x000000ff; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is not registered\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) has not been released\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have memory allocated for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ request_data_sz = ioc->diag_buffer_sz[buffer_type]; ++ request_data_dma = ioc->diag_buffer_dma[buffer_type]; ++ pci_free_consistent(ioc->pdev, request_data_sz, ++ request_data, request_data_dma); ++ ioc->diag_buffer[buffer_type] = NULL; ++ ioc->diag_buffer_status[buffer_type] = 0; ++ return 0; ++} ++ ++/** ++ * _ctl_diag_query - query relevant info associated with diag buffers ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ * ++ * The application will send only buffer_type and unique_id. Driver will ++ * inspect unique_id first, if valid, fill in all the info. If unique_id is ++ * 0x00, the driver will return info specified by Buffer Type. ++ */ ++static long ++_ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_query karg; ++ void *request_data; ++ int i; ++ u8 buffer_type; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ karg.application_flags = 0; ++ buffer_type = karg.buffer_type; ++ ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is not registered\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ ++ if (karg.unique_id & 0xffffff00) { ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have buffer for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ if (ioc->diag_buffer_status[buffer_type] & MPT3_DIAG_BUFFER_IS_RELEASED) ++ karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | ++ MPT3_APP_FLAGS_BUFFER_VALID); ++ else ++ karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | ++ MPT3_APP_FLAGS_BUFFER_VALID | ++ MPT3_APP_FLAGS_FW_BUFFER_ACCESS); ++ ++ for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) ++ karg.product_specific[i] = ++ ioc->product_specific[buffer_type][i]; ++ ++ karg.total_buffer_size = ioc->diag_buffer_sz[buffer_type]; ++ karg.driver_added_buffer_size = 0; ++ karg.unique_id = ioc->unique_id[buffer_type]; ++ karg.diagnostic_flags = ioc->diagnostic_flags[buffer_type]; ++ ++ if (copy_to_user(arg, &karg, sizeof(struct mpt3_diag_query))) { ++ pr_err(MPT3SAS_FMT ++ "%s: unable to write mpt3_diag_query data @ %p\n", ++ ioc->name, __func__, arg); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * mpt2sas_send_diag_release - Diag Release Message ++ * @ioc: per adapter object ++ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED ++ * @issue_reset - specifies whether host reset is required. ++ * ++ */ ++int ++mpt2sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, ++ u8 *issue_reset) ++{ ++ Mpi2DiagReleaseRequest_t *mpi_request; ++ Mpi2DiagReleaseReply_t *mpi_reply; ++ u16 smid; ++ u16 ioc_status; ++ u32 ioc_state; ++ int rc; ++ unsigned long timeleft; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ rc = 0; ++ *issue_reset = 0; ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_RELEASED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: skipping due to FAULT state\n", ioc->name, ++ __func__)); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->ctl_cmds.smid = smid; ++ ++ mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE; ++ mpi_request->BufferType = buffer_type; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ init_completion(&ioc->ctl_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); ++ ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2DiagReleaseRequest_t)/4); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ *issue_reset = 1; ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ /* process the completed Reply Message Frame */ ++ if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) { ++ pr_err(MPT3SAS_FMT "%s: no reply message\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_RELEASED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: success\n", ++ ioc->name, __func__)); ++ } else { ++ pr_info(MPT3SAS_FMT ++ "%s: ioc_status(0x%04x) log_info(0x%08x)\n", ++ ioc->name, __func__, ++ ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); ++ rc = -EFAULT; ++ } ++ ++ out: ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return rc; ++} ++ ++/** ++ * _ctl_diag_release - request to send Diag Release Message to firmware ++ * @arg - user space buffer containing ioctl content ++ * ++ * This allows ownership of the specified buffer to returned to the driver, ++ * allowing an application to read the buffer without fear that firmware is ++ * overwritting information in the buffer. ++ */ ++static long ++_ctl_diag_release(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_release karg; ++ void *request_data; ++ int rc; ++ u8 buffer_type; ++ u8 issue_reset = 0; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ buffer_type = karg.unique_id & 0x000000ff; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is not registered\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ ++ if (ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is already released\n", ++ ioc->name, __func__, ++ buffer_type); ++ return 0; ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have memory allocated for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ /* buffers were released by due to host reset */ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_DIAG_RESET)) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_RELEASED; ++ ioc->diag_buffer_status[buffer_type] &= ++ ~MPT3_DIAG_BUFFER_IS_DIAG_RESET; ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) was released due to host reset\n", ++ ioc->name, __func__, buffer_type); ++ return 0; ++ } ++ ++ rc = mpt2sas_send_diag_release(ioc, buffer_type, &issue_reset); ++ ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ return rc; ++} ++ ++/** ++ * _ctl_diag_read_buffer - request for copy of the diag buffer ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_read_buffer karg; ++ struct mpt3_diag_read_buffer __user *uarg = arg; ++ void *request_data, *diag_data; ++ Mpi2DiagBufferPostRequest_t *mpi_request; ++ Mpi2DiagBufferPostReply_t *mpi_reply; ++ int rc, i; ++ u8 buffer_type; ++ unsigned long timeleft, request_size, copy_size; ++ u16 smid; ++ u16 ioc_status; ++ u8 issue_reset = 0; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ buffer_type = karg.unique_id & 0x000000ff; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have buffer for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ request_size = ioc->diag_buffer_sz[buffer_type]; ++ ++ if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { ++ pr_err(MPT3SAS_FMT "%s: either the starting_offset " \ ++ "or bytes_to_read are not 4 byte aligned\n", ioc->name, ++ __func__); ++ return -EINVAL; ++ } ++ ++ if (karg.starting_offset > request_size) ++ return -EINVAL; ++ ++ diag_data = (void *)(request_data + karg.starting_offset); ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: diag_buffer(%p), offset(%d), sz(%d)\n", ++ ioc->name, __func__, ++ diag_data, karg.starting_offset, karg.bytes_to_read)); ++ ++ /* Truncate data on requests that are too large */ ++ if ((diag_data + karg.bytes_to_read < diag_data) || ++ (diag_data + karg.bytes_to_read > request_data + request_size)) ++ copy_size = request_size - karg.starting_offset; ++ else ++ copy_size = karg.bytes_to_read; ++ ++ if (copy_to_user((void __user *)uarg->diagnostic_data, ++ diag_data, copy_size)) { ++ pr_err(MPT3SAS_FMT ++ "%s: Unable to write mpt_diag_read_buffer_t data @ %p\n", ++ ioc->name, __func__, diag_data); ++ return -EFAULT; ++ } ++ ++ if ((karg.flags & MPT3_FLAGS_REREGISTER) == 0) ++ return 0; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: Reregister buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type)); ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is still registered\n", ++ ioc->name, __func__, buffer_type)); ++ return 0; ++ } ++ /* Get a free request frame and save the message context. ++ */ ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->ctl_cmds.smid = smid; ++ ++ mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; ++ mpi_request->BufferType = buffer_type; ++ mpi_request->BufferLength = ++ cpu_to_le32(ioc->diag_buffer_sz[buffer_type]); ++ mpi_request->BufferAddress = ++ cpu_to_le64(ioc->diag_buffer_dma[buffer_type]); ++ for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) ++ mpi_request->ProductSpecific[i] = ++ cpu_to_le32(ioc->product_specific[buffer_type][i]); ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ init_completion(&ioc->ctl_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); ++ ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2DiagBufferPostRequest_t)/4); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ /* process the completed Reply Message Frame */ ++ if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) { ++ pr_err(MPT3SAS_FMT "%s: no reply message\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_REGISTERED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: success\n", ++ ioc->name, __func__)); ++ } else { ++ pr_info(MPT3SAS_FMT ++ "%s: ioc_status(0x%04x) log_info(0x%08x)\n", ++ ioc->name, __func__, ++ ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); ++ rc = -EFAULT; ++ } ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ out: ++ ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return rc; ++} ++ ++ ++ ++#ifdef CONFIG_COMPAT ++/** ++ * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. ++ * @ioc: per adapter object ++ * @cmd - ioctl opcode ++ * @arg - (struct mpt3_ioctl_command32) ++ * ++ * MPT3COMMAND32 - Handle 32bit applications running on 64bit os. ++ */ ++static long ++_ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd, ++ void __user *arg) ++{ ++ struct mpt3_ioctl_command32 karg32; ++ struct mpt3_ioctl_command32 __user *uarg; ++ struct mpt3_ioctl_command karg; ++ ++ if (_IOC_SIZE(cmd) != sizeof(struct mpt3_ioctl_command32)) ++ return -EINVAL; ++ ++ uarg = (struct mpt3_ioctl_command32 __user *) arg; ++ ++ if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ memset(&karg, 0, sizeof(struct mpt3_ioctl_command)); ++ karg.hdr.ioc_number = karg32.hdr.ioc_number; ++ karg.hdr.port_number = karg32.hdr.port_number; ++ karg.hdr.max_data_size = karg32.hdr.max_data_size; ++ karg.timeout = karg32.timeout; ++ karg.max_reply_bytes = karg32.max_reply_bytes; ++ karg.data_in_size = karg32.data_in_size; ++ karg.data_out_size = karg32.data_out_size; ++ karg.max_sense_bytes = karg32.max_sense_bytes; ++ karg.data_sge_offset = karg32.data_sge_offset; ++ karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); ++ karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); ++ karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); ++ karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); ++ return _ctl_do_mpt_command(ioc, karg, &uarg->mf); ++} ++#endif ++ ++/** ++ * _ctl_ioctl_main - main ioctl entry point ++ * @file - (struct file) ++ * @cmd - ioctl opcode ++ * @arg - user space data buffer ++ * @compat - handles 32 bit applications in 64bit os ++ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device & ++ * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device. ++ */ ++static long ++_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, ++ u8 compat, u16 mpi_version) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ struct mpt3_ioctl_header ioctl_header; ++ enum block_state state; ++ long ret = -EINVAL; ++ ++ /* get IOCTL header */ ++ if (copy_from_user(&ioctl_header, (char __user *)arg, ++ sizeof(struct mpt3_ioctl_header))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ if (_ctl_verify_adapter(ioctl_header.ioc_number, ++ &ioc, mpi_version) == -1 || !ioc) ++ return -ENODEV; ++ ++ /* pci_access_mutex lock acquired by ioctl path */ ++ mutex_lock(&ioc->pci_access_mutex); ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery || ++ ioc->is_driver_loading || ioc->remove_host) { ++ ret = -EAGAIN; ++ goto out_unlock_pciaccess; ++ } ++ ++ state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; ++ if (state == NON_BLOCKING) { ++ if (!mutex_trylock(&ioc->ctl_cmds.mutex)) { ++ ret = -EAGAIN; ++ goto out_unlock_pciaccess; ++ } ++ } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { ++ ret = -ERESTARTSYS; ++ goto out_unlock_pciaccess; ++ } ++ ++ ++ switch (cmd) { ++ case MPT3IOCINFO: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_iocinfo)) ++ ret = _ctl_getiocinfo(ioc, arg); ++ break; ++#ifdef CONFIG_COMPAT ++ case MPT3COMMAND32: ++#endif ++ case MPT3COMMAND: ++ { ++ struct mpt3_ioctl_command __user *uarg; ++ struct mpt3_ioctl_command karg; ++ ++#ifdef CONFIG_COMPAT ++ if (compat) { ++ ret = _ctl_compat_mpt_command(ioc, cmd, arg); ++ break; ++ } ++#endif ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ ret = -EFAULT; ++ break; ++ } ++ ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_command)) { ++ uarg = arg; ++ ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf); ++ } ++ break; ++ } ++ case MPT3EVENTQUERY: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_eventquery)) ++ ret = _ctl_eventquery(ioc, arg); ++ break; ++ case MPT3EVENTENABLE: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_eventenable)) ++ ret = _ctl_eventenable(ioc, arg); ++ break; ++ case MPT3EVENTREPORT: ++ ret = _ctl_eventreport(ioc, arg); ++ break; ++ case MPT3HARDRESET: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_diag_reset)) ++ ret = _ctl_do_reset(ioc, arg); ++ break; ++ case MPT3BTDHMAPPING: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_btdh_mapping)) ++ ret = _ctl_btdh_mapping(ioc, arg); ++ break; ++ case MPT3DIAGREGISTER: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_register)) ++ ret = _ctl_diag_register(ioc, arg); ++ break; ++ case MPT3DIAGUNREGISTER: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_unregister)) ++ ret = _ctl_diag_unregister(ioc, arg); ++ break; ++ case MPT3DIAGQUERY: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_query)) ++ ret = _ctl_diag_query(ioc, arg); ++ break; ++ case MPT3DIAGRELEASE: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_release)) ++ ret = _ctl_diag_release(ioc, arg); ++ break; ++ case MPT3DIAGREADBUFFER: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer)) ++ ret = _ctl_diag_read_buffer(ioc, arg); ++ break; ++ default: ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); ++ break; ++ } ++ ++ mutex_unlock(&ioc->ctl_cmds.mutex); ++out_unlock_pciaccess: ++ mutex_unlock(&ioc->pci_access_mutex); ++ return ret; ++} ++ ++/** ++ * _ctl_ioctl_mpt2sas - mpt3ctl main ioctl entry point (unlocked) ++ * @file - (struct file) ++ * @cmd - ioctl opcode ++ * @arg - ++ */ ++long ++_ctl_ioctl_mpt2sas(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ /* pass MPI25_VERSION | MPI26_VERSION value, ++ * to indicate that this ioctl cmd ++ * came from mpt3ctl ioctl device. ++ */ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, ++ MPI25_VERSION | MPI26_VERSION); ++ return ret; ++} ++ ++/** ++ * _ctl_mpt2_ioctl_mpt2sas - mpt2ctl main ioctl entry point (unlocked) ++ * @file - (struct file) ++ * @cmd - ioctl opcode ++ * @arg - ++ */ ++long ++_ctl_mpt2_ioctl_mpt2sas(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ /* pass MPI2_VERSION value, to indicate that this ioctl cmd ++ * came from mpt2ctl ioctl device. ++ */ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION); ++ return ret; ++} ++#ifdef CONFIG_COMPAT ++/** ++ *_ ctl_ioctl_compat - main ioctl entry point (compat) ++ * @file - ++ * @cmd - ++ * @arg - ++ * ++ * This routine handles 32 bit applications in 64bit os. ++ */ ++long ++_ctl_ioctl_compat_mpt2sas(struct file *file, unsigned cmd, unsigned long arg) ++{ ++ long ret; ++ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, ++ MPI25_VERSION | MPI26_VERSION); ++ return ret; ++} ++ ++/** ++ *_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat) ++ * @file - ++ * @cmd - ++ * @arg - ++ * ++ * This routine handles 32 bit applications in 64bit os. ++ */ ++long ++_ctl_mpt2_ioctl_compat_mpt2sas(struct file *file, unsigned cmd, unsigned long arg) ++{ ++ long ret; ++ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION); ++ return ret; ++} ++#endif ++ ++/* scsi host attributes */ ++/** ++ * _ctl_version_fw_show - firmware version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_fw_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n", ++ (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, ++ (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, ++ (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ++ ioc->facts.FWVersion.Word & 0x000000FF); ++} ++static DEVICE_ATTR(version_fw, S_IRUGO, _ctl_version_fw_show, NULL); ++ ++/** ++ * _ctl_version_bios_show - bios version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_bios_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ u32 version = le32_to_cpu(ioc->bios_pg3.BiosVersion); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n", ++ (version & 0xFF000000) >> 24, ++ (version & 0x00FF0000) >> 16, ++ (version & 0x0000FF00) >> 8, ++ version & 0x000000FF); ++} ++static DEVICE_ATTR(version_bios, S_IRUGO, _ctl_version_bios_show, NULL); ++ ++/** ++ * _ctl_version_mpi_show - MPI (message passing interface) version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_mpi_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%03x.%02x\n", ++ ioc->facts.MsgVersion, ioc->facts.HeaderVersion >> 8); ++} ++static DEVICE_ATTR(version_mpi, S_IRUGO, _ctl_version_mpi_show, NULL); ++ ++/** ++ * _ctl_version_product_show - product name ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_product_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.ChipName); ++} ++static DEVICE_ATTR(version_product, S_IRUGO, _ctl_version_product_show, NULL); ++ ++/** ++ * _ctl_version_nvdata_persistent_show - ndvata persistent version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_nvdata_persistent_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%08xh\n", ++ le32_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word)); ++} ++static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO, ++ _ctl_version_nvdata_persistent_show, NULL); ++ ++/** ++ * _ctl_version_nvdata_default_show - nvdata default version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_nvdata_default_show(struct device *cdev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%08xh\n", ++ le32_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word)); ++} ++static DEVICE_ATTR(version_nvdata_default, S_IRUGO, ++ _ctl_version_nvdata_default_show, NULL); ++ ++/** ++ * _ctl_board_name_show - board name ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_board_name_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardName); ++} ++static DEVICE_ATTR(board_name, S_IRUGO, _ctl_board_name_show, NULL); ++ ++/** ++ * _ctl_board_assembly_show - board assembly name ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_board_assembly_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardAssembly); ++} ++static DEVICE_ATTR(board_assembly, S_IRUGO, _ctl_board_assembly_show, NULL); ++ ++/** ++ * _ctl_board_tracer_show - board tracer number ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_board_tracer_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardTracerNumber); ++} ++static DEVICE_ATTR(board_tracer, S_IRUGO, _ctl_board_tracer_show, NULL); ++ ++/** ++ * _ctl_io_delay_show - io missing delay ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is for firmware implemention for deboucing device ++ * removal events. ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_io_delay_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay); ++} ++static DEVICE_ATTR(io_delay, S_IRUGO, _ctl_io_delay_show, NULL); ++ ++/** ++ * _ctl_device_delay_show - device missing delay ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is for firmware implemention for deboucing device ++ * removal events. ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_device_delay_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay); ++} ++static DEVICE_ATTR(device_delay, S_IRUGO, _ctl_device_delay_show, NULL); ++ ++/** ++ * _ctl_fw_queue_depth_show - global credits ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is firmware queue depth limit ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_fw_queue_depth_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->facts.RequestCredit); ++} ++static DEVICE_ATTR(fw_queue_depth, S_IRUGO, _ctl_fw_queue_depth_show, NULL); ++ ++/** ++ * _ctl_sas_address_show - sas address ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is the controller sas address ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_host_sas_address_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "0x%016llx\n", ++ (unsigned long long)ioc->sas_hba.sas_address); ++} ++static DEVICE_ATTR(host_sas_address, S_IRUGO, ++ _ctl_host_sas_address_show, NULL); ++ ++/** ++ * _ctl_logging_level_show - logging level ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_logging_level_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->logging_level); ++} ++static ssize_t ++_ctl_logging_level_store(struct device *cdev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int val = 0; ++ ++ if (sscanf(buf, "%x", &val) != 1) ++ return -EINVAL; ++ ++ ioc->logging_level = val; ++ pr_info(MPT3SAS_FMT "logging_level=%08xh\n", ioc->name, ++ ioc->logging_level); ++ return strlen(buf); ++} ++static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, _ctl_logging_level_show, ++ _ctl_logging_level_store); ++ ++/** ++ * _ctl_fwfault_debug_show - show/store fwfault_debug ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * mpt2sas_fwfault_debug is command line option ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_fwfault_debug_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug); ++} ++static ssize_t ++_ctl_fwfault_debug_store(struct device *cdev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int val = 0; ++ ++ if (sscanf(buf, "%d", &val) != 1) ++ return -EINVAL; ++ ++ ioc->fwfault_debug = val; ++ pr_info(MPT3SAS_FMT "fwfault_debug=%d\n", ioc->name, ++ ioc->fwfault_debug); ++ return strlen(buf); ++} ++static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR, ++ _ctl_fwfault_debug_show, _ctl_fwfault_debug_store); ++ ++/** ++ * _ctl_ioc_reset_count_show - ioc reset count ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is firmware queue depth limit ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", ioc->ioc_reset_count); ++} ++static DEVICE_ATTR(ioc_reset_count, S_IRUGO, _ctl_ioc_reset_count_show, NULL); ++ ++/** ++ * _ctl_ioc_reply_queue_count_show - number of reply queues ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is number of reply queues ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_ioc_reply_queue_count_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ u8 reply_queue_count; ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ if ((ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable) ++ reply_queue_count = ioc->reply_queue_count; ++ else ++ reply_queue_count = 1; ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", reply_queue_count); ++} ++static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show, ++ NULL); ++ ++/** ++ * _ctl_BRM_status_show - Backup Rail Monitor Status ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is number of reply queues ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ Mpi2IOUnitPage3_t *io_unit_pg3 = NULL; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 backup_rail_monitor_status = 0; ++ u16 ioc_status; ++ int sz; ++ ssize_t rc = 0; ++ ++ if (!ioc->is_warpdrive) { ++ pr_err(MPT3SAS_FMT "%s: BRM attribute is only for" ++ " warpdrive\n", ioc->name, __func__); ++ goto out; ++ } ++ /* pci_access_mutex lock acquired by sysfs show path */ ++ mutex_lock(&ioc->pci_access_mutex); ++ if (ioc->pci_error_recovery || ioc->remove_host) { ++ mutex_unlock(&ioc->pci_access_mutex); ++ return 0; ++ } ++ ++ /* allocate upto GPIOVal 36 entries */ ++ sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); ++ io_unit_pg3 = kzalloc(sz, GFP_KERNEL); ++ if (!io_unit_pg3) { ++ pr_err(MPT3SAS_FMT "%s: failed allocating memory " ++ "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz); ++ goto out; ++ } ++ ++ if (mpt2sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) != ++ 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed reading iounit_pg3\n", ioc->name, ++ __func__); ++ goto out; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "%s: iounit_pg3 failed with " ++ "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status); ++ goto out; ++ } ++ ++ if (io_unit_pg3->GPIOCount < 25) { ++ pr_err(MPT3SAS_FMT "%s: iounit_pg3->GPIOCount less than " ++ "25 entries, detected (%d) entries\n", ioc->name, __func__, ++ io_unit_pg3->GPIOCount); ++ goto out; ++ } ++ ++ /* BRM status is in bit zero of GPIOVal[24] */ ++ backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]); ++ rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1)); ++ ++ out: ++ kfree(io_unit_pg3); ++ mutex_unlock(&ioc->pci_access_mutex); ++ return rc; ++} ++static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); ++ ++struct DIAG_BUFFER_START { ++ __le32 Size; ++ __le32 DiagVersion; ++ u8 BufferType; ++ u8 Reserved[3]; ++ __le32 Reserved1; ++ __le32 Reserved2; ++ __le32 Reserved3; ++}; ++ ++/** ++ * _ctl_host_trace_buffer_size_show - host buffer size (trace only) ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_host_trace_buffer_size_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ u32 size = 0; ++ struct DIAG_BUFFER_START *request_data; ++ ++ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ request_data = (struct DIAG_BUFFER_START *) ++ ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]; ++ if ((le32_to_cpu(request_data->DiagVersion) == 0x00000000 || ++ le32_to_cpu(request_data->DiagVersion) == 0x01000000 || ++ le32_to_cpu(request_data->DiagVersion) == 0x01010000) && ++ le32_to_cpu(request_data->Reserved3) == 0x4742444c) ++ size = le32_to_cpu(request_data->Size); ++ ++ ioc->ring_buffer_sz = size; ++ return snprintf(buf, PAGE_SIZE, "%d\n", size); ++} ++static DEVICE_ATTR(host_trace_buffer_size, S_IRUGO, ++ _ctl_host_trace_buffer_size_show, NULL); ++ ++/** ++ * _ctl_host_trace_buffer_show - firmware ring buffer (trace only) ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ * ++ * You will only be able to read 4k bytes of ring buffer at a time. ++ * In order to read beyond 4k bytes, you will have to write out the ++ * offset to the same attribute, it will move the pointer. ++ */ ++static ssize_t ++_ctl_host_trace_buffer_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ void *request_data; ++ u32 size; ++ ++ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ if (ioc->ring_buffer_offset > ioc->ring_buffer_sz) ++ return 0; ++ ++ size = ioc->ring_buffer_sz - ioc->ring_buffer_offset; ++ size = (size >= PAGE_SIZE) ? (PAGE_SIZE - 1) : size; ++ request_data = ioc->diag_buffer[0] + ioc->ring_buffer_offset; ++ memcpy(buf, request_data, size); ++ return size; ++} ++ ++static ssize_t ++_ctl_host_trace_buffer_store(struct device *cdev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int val = 0; ++ ++ if (sscanf(buf, "%d", &val) != 1) ++ return -EINVAL; ++ ++ ioc->ring_buffer_offset = val; ++ return strlen(buf); ++} ++static DEVICE_ATTR(host_trace_buffer, S_IRUGO | S_IWUSR, ++ _ctl_host_trace_buffer_show, _ctl_host_trace_buffer_store); ++ ++ ++/*****************************************/ ++ ++/** ++ * _ctl_host_trace_buffer_enable_show - firmware ring buffer (trace only) ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ * ++ * This is a mechnism to post/release host_trace_buffers ++ */ ++static ssize_t ++_ctl_host_trace_buffer_enable_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ if ((!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) || ++ ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0)) ++ return snprintf(buf, PAGE_SIZE, "off\n"); ++ else if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ return snprintf(buf, PAGE_SIZE, "release\n"); ++ else ++ return snprintf(buf, PAGE_SIZE, "post\n"); ++} ++ ++static ssize_t ++_ctl_host_trace_buffer_enable_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ char str[10] = ""; ++ struct mpt3_diag_register diag_register; ++ u8 issue_reset = 0; ++ ++ /* don't allow post/release occurr while recovery is active */ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery || ioc->is_driver_loading) ++ return -EBUSY; ++ ++ if (sscanf(buf, "%9s", str) != 1) ++ return -EINVAL; ++ ++ if (!strcmp(str, "post")) { ++ /* exit out if host buffers are already posted */ ++ if ((ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) && ++ (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) && ++ ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0)) ++ goto out; ++ memset(&diag_register, 0, sizeof(struct mpt3_diag_register)); ++ pr_info(MPT3SAS_FMT "posting host trace buffers\n", ++ ioc->name); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; ++ diag_register.requested_buffer_size = (1024 * 1024); ++ diag_register.unique_id = 0x7075900; ++ ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } else if (!strcmp(str, "release")) { ++ /* exit out if host buffers are already released */ ++ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) ++ goto out; ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) ++ goto out; ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ goto out; ++ pr_info(MPT3SAS_FMT "releasing host trace buffer\n", ++ ioc->name); ++ mpt2sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, ++ &issue_reset); ++ } ++ ++ out: ++ return strlen(buf); ++} ++static DEVICE_ATTR(host_trace_buffer_enable, S_IRUGO | S_IWUSR, ++ _ctl_host_trace_buffer_enable_show, ++ _ctl_host_trace_buffer_enable_store); ++ ++/*********** diagnostic trigger suppport *********************************/ ++ ++/** ++ * _ctl_diag_trigger_master_show - show the diag_trigger_master attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_master_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_MASTER_TRIGGER_T); ++ memcpy(buf, &ioc->diag_trigger_master, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_master_store - store the diag_trigger_master attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_master_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = min(sizeof(struct SL_WH_MASTER_TRIGGER_T), count); ++ memset(&ioc->diag_trigger_master, 0, ++ sizeof(struct SL_WH_MASTER_TRIGGER_T)); ++ memcpy(&ioc->diag_trigger_master, buf, rc); ++ ioc->diag_trigger_master.MasterData |= ++ (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++static DEVICE_ATTR(diag_trigger_master, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_master_show, _ctl_diag_trigger_master_store); ++ ++ ++/** ++ * _ctl_diag_trigger_event_show - show the diag_trigger_event attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_event_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_EVENT_TRIGGERS_T); ++ memcpy(buf, &ioc->diag_trigger_event, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_event_store - store the diag_trigger_event attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_event_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t sz; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ sz = min(sizeof(struct SL_WH_EVENT_TRIGGERS_T), count); ++ memset(&ioc->diag_trigger_event, 0, ++ sizeof(struct SL_WH_EVENT_TRIGGERS_T)); ++ memcpy(&ioc->diag_trigger_event, buf, sz); ++ if (ioc->diag_trigger_event.ValidEntries > NUM_VALID_ENTRIES) ++ ioc->diag_trigger_event.ValidEntries = NUM_VALID_ENTRIES; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return sz; ++} ++static DEVICE_ATTR(diag_trigger_event, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_event_show, _ctl_diag_trigger_event_store); ++ ++ ++/** ++ * _ctl_diag_trigger_scsi_show - show the diag_trigger_scsi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_scsi_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_SCSI_TRIGGERS_T); ++ memcpy(buf, &ioc->diag_trigger_scsi, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_scsi_store - store the diag_trigger_scsi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_scsi_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t sz; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ sz = min(sizeof(struct SL_WH_SCSI_TRIGGERS_T), count); ++ memset(&ioc->diag_trigger_scsi, 0, ++ sizeof(struct SL_WH_EVENT_TRIGGERS_T)); ++ memcpy(&ioc->diag_trigger_scsi, buf, sz); ++ if (ioc->diag_trigger_scsi.ValidEntries > NUM_VALID_ENTRIES) ++ ioc->diag_trigger_scsi.ValidEntries = NUM_VALID_ENTRIES; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return sz; ++} ++static DEVICE_ATTR(diag_trigger_scsi, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_scsi_show, _ctl_diag_trigger_scsi_store); ++ ++ ++/** ++ * _ctl_diag_trigger_scsi_show - show the diag_trigger_mpi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_mpi_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_MPI_TRIGGERS_T); ++ memcpy(buf, &ioc->diag_trigger_mpi, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_mpi_store - store the diag_trigger_mpi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_mpi_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t sz; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ sz = min(sizeof(struct SL_WH_MPI_TRIGGERS_T), count); ++ memset(&ioc->diag_trigger_mpi, 0, ++ sizeof(ioc->diag_trigger_mpi)); ++ memcpy(&ioc->diag_trigger_mpi, buf, sz); ++ if (ioc->diag_trigger_mpi.ValidEntries > NUM_VALID_ENTRIES) ++ ioc->diag_trigger_mpi.ValidEntries = NUM_VALID_ENTRIES; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return sz; ++} ++ ++static DEVICE_ATTR(diag_trigger_mpi, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_mpi_show, _ctl_diag_trigger_mpi_store); ++ ++/*********** diagnostic trigger suppport *** END ****************************/ ++ ++ ++ ++/*****************************************/ ++ ++struct device_attribute *mpt2sas_host_attrs[] = { ++ &dev_attr_version_fw, ++ &dev_attr_version_bios, ++ &dev_attr_version_mpi, ++ &dev_attr_version_product, ++ &dev_attr_version_nvdata_persistent, ++ &dev_attr_version_nvdata_default, ++ &dev_attr_board_name, ++ &dev_attr_board_assembly, ++ &dev_attr_board_tracer, ++ &dev_attr_io_delay, ++ &dev_attr_device_delay, ++ &dev_attr_logging_level, ++ &dev_attr_fwfault_debug, ++ &dev_attr_fw_queue_depth, ++ &dev_attr_host_sas_address, ++ &dev_attr_ioc_reset_count, ++ &dev_attr_host_trace_buffer_size, ++ &dev_attr_host_trace_buffer, ++ &dev_attr_host_trace_buffer_enable, ++ &dev_attr_reply_queue_count, ++ &dev_attr_diag_trigger_master, ++ &dev_attr_diag_trigger_event, ++ &dev_attr_diag_trigger_scsi, ++ &dev_attr_diag_trigger_mpi, ++ &dev_attr_BRM_status, ++ NULL, ++}; ++ ++/* device attributes */ ++ ++/** ++ * _ctl_device_sas_address_show - sas address ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is the sas address for the target ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_device_sas_address_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; ++ ++ return snprintf(buf, PAGE_SIZE, "0x%016llx\n", ++ (unsigned long long)sas_device_priv_data->sas_target->sas_address); ++} ++static DEVICE_ATTR(sas_address, S_IRUGO, _ctl_device_sas_address_show, NULL); ++ ++/** ++ * _ctl_device_handle_show - device handle ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is the firmware assigned device handle ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_device_handle_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; ++ ++ return snprintf(buf, PAGE_SIZE, "0x%04x\n", ++ sas_device_priv_data->sas_target->handle); ++} ++static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL); ++ ++struct device_attribute *mpt2sas_dev_attrs[] = { ++ &dev_attr_sas_address, ++ &dev_attr_sas_device_handle, ++ NULL, ++}; ++ ++/* file operations table for mpt3ctl device */ ++static const struct file_operations ctl_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = _ctl_ioctl_mpt2sas, ++ .poll = _ctl_poll_mpt2sas, ++ .fasync = _ctl_fasync_mpt2sas, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = _ctl_ioctl_compat_mpt2sas, ++#endif ++}; ++ ++/* file operations table for mpt2ctl device */ ++static const struct file_operations ctl_gen2_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = _ctl_mpt2_ioctl_mpt2sas, ++ .poll = _ctl_poll_mpt2sas, ++ .fasync = _ctl_fasync_mpt2sas, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = _ctl_mpt2_ioctl_compat_mpt2sas, ++#endif ++}; ++ ++static struct miscdevice ctl_dev = { ++ .minor = MPT3SAS_MINOR, ++ .name = MPT3SAS_DEV_NAME, ++ .fops = &ctl_fops, ++}; ++ ++static struct miscdevice gen2_ctl_dev = { ++ .minor = MPT2SAS_MINOR, ++ .name = MPT2SAS_DEV_NAME, ++ .fops = &ctl_gen2_fops, ++}; ++ ++/** ++ * mpt2sas_ctl_init - main entry point for ctl. ++ * ++ */ ++void ++mpt2sas_ctl_init(ushort hbas_to_enumerate) ++{ ++ async_queue = NULL; ++ ++ /* Don't register mpt3ctl ioctl device if ++ * hbas_to_enumarate is one. ++ */ ++ if (hbas_to_enumerate != 1) ++ if (misc_register(&ctl_dev) < 0) ++ pr_err("%s can't register misc device [minor=%d]\n", ++ MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR); ++ ++ /* Don't register mpt3ctl ioctl device if ++ * hbas_to_enumarate is two. ++ */ ++ if (hbas_to_enumerate != 2) ++ if (misc_register(&gen2_ctl_dev) < 0) ++ pr_err("%s can't register misc device [minor=%d]\n", ++ MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR); ++ ++ init_waitqueue_head(&ctl_poll_wait); ++} ++ ++/** ++ * mpt2sas_ctl_exit - exit point for ctl ++ * ++ */ ++void ++mpt2sas_ctl_exit(ushort hbas_to_enumerate) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ int i; ++ ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { ++ ++ /* free memory associated to diag buffers */ ++ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { ++ if (!ioc->diag_buffer[i]) ++ continue; ++ if (!(ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED)) ++ continue; ++ if ((ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ continue; ++ pci_free_consistent(ioc->pdev, ioc->diag_buffer_sz[i], ++ ioc->diag_buffer[i], ioc->diag_buffer_dma[i]); ++ ioc->diag_buffer[i] = NULL; ++ ioc->diag_buffer_status[i] = 0; ++ } ++ ++ kfree(ioc->event_log); ++ } ++ if (hbas_to_enumerate != 1) ++ misc_deregister(&ctl_dev); ++ if (hbas_to_enumerate != 2) ++ misc_deregister(&gen2_ctl_dev); ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_ctl.h b/drivers/scsi/mpt2sas/mpt3sas_ctl.h +new file mode 100644 +index 0000000..8940835 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_ctl.h +@@ -0,0 +1,423 @@ ++/* ++ * Management Module Support for MPT (Message Passing Technology) based ++ * controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.h ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#ifndef MPT3SAS_CTL_H_INCLUDED ++#define MPT3SAS_CTL_H_INCLUDED ++ ++#ifdef __KERNEL__ ++#include ++#endif ++ ++#ifndef MPT2SAS_MINOR ++#define MPT2SAS_MINOR (MPT_MINOR + 1) ++#endif ++#ifndef MPT3SAS_MINOR ++#define MPT3SAS_MINOR (MPT_MINOR + 2) ++#endif ++#define MPT2SAS_DEV_NAME "mpt2ctl" ++#define MPT3SAS_DEV_NAME "mpt3ctl" ++#define MPT3_MAGIC_NUMBER 'L' ++#define MPT3_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */ ++ ++/** ++ * IOCTL opcodes ++ */ ++#define MPT3IOCINFO _IOWR(MPT3_MAGIC_NUMBER, 17, \ ++ struct mpt3_ioctl_iocinfo) ++#define MPT3COMMAND _IOWR(MPT3_MAGIC_NUMBER, 20, \ ++ struct mpt3_ioctl_command) ++#ifdef CONFIG_COMPAT ++#define MPT3COMMAND32 _IOWR(MPT3_MAGIC_NUMBER, 20, \ ++ struct mpt3_ioctl_command32) ++#endif ++#define MPT3EVENTQUERY _IOWR(MPT3_MAGIC_NUMBER, 21, \ ++ struct mpt3_ioctl_eventquery) ++#define MPT3EVENTENABLE _IOWR(MPT3_MAGIC_NUMBER, 22, \ ++ struct mpt3_ioctl_eventenable) ++#define MPT3EVENTREPORT _IOWR(MPT3_MAGIC_NUMBER, 23, \ ++ struct mpt3_ioctl_eventreport) ++#define MPT3HARDRESET _IOWR(MPT3_MAGIC_NUMBER, 24, \ ++ struct mpt3_ioctl_diag_reset) ++#define MPT3BTDHMAPPING _IOWR(MPT3_MAGIC_NUMBER, 31, \ ++ struct mpt3_ioctl_btdh_mapping) ++ ++/* diag buffer support */ ++#define MPT3DIAGREGISTER _IOWR(MPT3_MAGIC_NUMBER, 26, \ ++ struct mpt3_diag_register) ++#define MPT3DIAGRELEASE _IOWR(MPT3_MAGIC_NUMBER, 27, \ ++ struct mpt3_diag_release) ++#define MPT3DIAGUNREGISTER _IOWR(MPT3_MAGIC_NUMBER, 28, \ ++ struct mpt3_diag_unregister) ++#define MPT3DIAGQUERY _IOWR(MPT3_MAGIC_NUMBER, 29, \ ++ struct mpt3_diag_query) ++#define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \ ++ struct mpt3_diag_read_buffer) ++ ++/** ++ * struct mpt3_ioctl_header - main header structure ++ * @ioc_number - IOC unit number ++ * @port_number - IOC port number ++ * @max_data_size - maximum number bytes to transfer on read ++ */ ++struct mpt3_ioctl_header { ++ uint32_t ioc_number; ++ uint32_t port_number; ++ uint32_t max_data_size; ++}; ++ ++/** ++ * struct mpt3_ioctl_diag_reset - diagnostic reset ++ * @hdr - generic header ++ */ ++struct mpt3_ioctl_diag_reset { ++ struct mpt3_ioctl_header hdr; ++}; ++ ++ ++/** ++ * struct mpt3_ioctl_pci_info - pci device info ++ * @device - pci device id ++ * @function - pci function id ++ * @bus - pci bus id ++ * @segment_id - pci segment id ++ */ ++struct mpt3_ioctl_pci_info { ++ union { ++ struct { ++ uint32_t device:5; ++ uint32_t function:3; ++ uint32_t bus:24; ++ } bits; ++ uint32_t word; ++ } u; ++ uint32_t segment_id; ++}; ++ ++ ++#define MPT2_IOCTL_INTERFACE_SCSI (0x00) ++#define MPT2_IOCTL_INTERFACE_FC (0x01) ++#define MPT2_IOCTL_INTERFACE_FC_IP (0x02) ++#define MPT2_IOCTL_INTERFACE_SAS (0x03) ++#define MPT2_IOCTL_INTERFACE_SAS2 (0x04) ++#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) ++#define MPT3_IOCTL_INTERFACE_SAS3 (0x06) ++#define MPT2_IOCTL_VERSION_LENGTH (32) ++ ++/** ++ * struct mpt3_ioctl_iocinfo - generic controller info ++ * @hdr - generic header ++ * @adapter_type - type of adapter (spi, fc, sas) ++ * @port_number - port number ++ * @pci_id - PCI Id ++ * @hw_rev - hardware revision ++ * @sub_system_device - PCI subsystem Device ID ++ * @sub_system_vendor - PCI subsystem Vendor ID ++ * @rsvd0 - reserved ++ * @firmware_version - firmware version ++ * @bios_version - BIOS version ++ * @driver_version - driver version - 32 ASCII characters ++ * @rsvd1 - reserved ++ * @scsi_id - scsi id of adapter 0 ++ * @rsvd2 - reserved ++ * @pci_information - pci info (2nd revision) ++ */ ++struct mpt3_ioctl_iocinfo { ++ struct mpt3_ioctl_header hdr; ++ uint32_t adapter_type; ++ uint32_t port_number; ++ uint32_t pci_id; ++ uint32_t hw_rev; ++ uint32_t subsystem_device; ++ uint32_t subsystem_vendor; ++ uint32_t rsvd0; ++ uint32_t firmware_version; ++ uint32_t bios_version; ++ uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH]; ++ uint8_t rsvd1; ++ uint8_t scsi_id; ++ uint16_t rsvd2; ++ struct mpt3_ioctl_pci_info pci_information; ++}; ++ ++ ++/* number of event log entries */ ++#define MPT3SAS_CTL_EVENT_LOG_SIZE (50) ++ ++/** ++ * struct mpt3_ioctl_eventquery - query event count and type ++ * @hdr - generic header ++ * @event_entries - number of events returned by get_event_report ++ * @rsvd - reserved ++ * @event_types - type of events currently being captured ++ */ ++struct mpt3_ioctl_eventquery { ++ struct mpt3_ioctl_header hdr; ++ uint16_t event_entries; ++ uint16_t rsvd; ++ uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; ++}; ++ ++/** ++ * struct mpt3_ioctl_eventenable - enable/disable event capturing ++ * @hdr - generic header ++ * @event_types - toggle off/on type of events to be captured ++ */ ++struct mpt3_ioctl_eventenable { ++ struct mpt3_ioctl_header hdr; ++ uint32_t event_types[4]; ++}; ++ ++#define MPT3_EVENT_DATA_SIZE (192) ++/** ++ * struct MPT3_IOCTL_EVENTS - ++ * @event - the event that was reported ++ * @context - unique value for each event assigned by driver ++ * @data - event data returned in fw reply message ++ */ ++struct MPT3_IOCTL_EVENTS { ++ uint32_t event; ++ uint32_t context; ++ uint8_t data[MPT3_EVENT_DATA_SIZE]; ++}; ++ ++/** ++ * struct mpt3_ioctl_eventreport - returing event log ++ * @hdr - generic header ++ * @event_data - (see struct MPT3_IOCTL_EVENTS) ++ */ ++struct mpt3_ioctl_eventreport { ++ struct mpt3_ioctl_header hdr; ++ struct MPT3_IOCTL_EVENTS event_data[1]; ++}; ++ ++/** ++ * struct mpt3_ioctl_command - generic mpt firmware passthru ioctl ++ * @hdr - generic header ++ * @timeout - command timeout in seconds. (if zero then use driver default ++ * value). ++ * @reply_frame_buf_ptr - reply location ++ * @data_in_buf_ptr - destination for read ++ * @data_out_buf_ptr - data source for write ++ * @sense_data_ptr - sense data location ++ * @max_reply_bytes - maximum number of reply bytes to be sent to app. ++ * @data_in_size - number bytes for data transfer in (read) ++ * @data_out_size - number bytes for data transfer out (write) ++ * @max_sense_bytes - maximum number of bytes for auto sense buffers ++ * @data_sge_offset - offset in words from the start of the request message to ++ * the first SGL ++ * @mf[1]; ++ */ ++struct mpt3_ioctl_command { ++ struct mpt3_ioctl_header hdr; ++ uint32_t timeout; ++ void __user *reply_frame_buf_ptr; ++ void __user *data_in_buf_ptr; ++ void __user *data_out_buf_ptr; ++ void __user *sense_data_ptr; ++ uint32_t max_reply_bytes; ++ uint32_t data_in_size; ++ uint32_t data_out_size; ++ uint32_t max_sense_bytes; ++ uint32_t data_sge_offset; ++ uint8_t mf[1]; ++}; ++ ++#ifdef CONFIG_COMPAT ++struct mpt3_ioctl_command32 { ++ struct mpt3_ioctl_header hdr; ++ uint32_t timeout; ++ uint32_t reply_frame_buf_ptr; ++ uint32_t data_in_buf_ptr; ++ uint32_t data_out_buf_ptr; ++ uint32_t sense_data_ptr; ++ uint32_t max_reply_bytes; ++ uint32_t data_in_size; ++ uint32_t data_out_size; ++ uint32_t max_sense_bytes; ++ uint32_t data_sge_offset; ++ uint8_t mf[1]; ++}; ++#endif ++ ++/** ++ * struct mpt3_ioctl_btdh_mapping - mapping info ++ * @hdr - generic header ++ * @id - target device identification number ++ * @bus - SCSI bus number that the target device exists on ++ * @handle - device handle for the target device ++ * @rsvd - reserved ++ * ++ * To obtain a bus/id the application sets ++ * handle to valid handle, and bus/id to 0xFFFF. ++ * ++ * To obtain the device handle the application sets ++ * bus/id valid value, and the handle to 0xFFFF. ++ */ ++struct mpt3_ioctl_btdh_mapping { ++ struct mpt3_ioctl_header hdr; ++ uint32_t id; ++ uint32_t bus; ++ uint16_t handle; ++ uint16_t rsvd; ++}; ++ ++ ++ ++/* application flags for mpt3_diag_register, mpt3_diag_query */ ++#define MPT3_APP_FLAGS_APP_OWNED (0x0001) ++#define MPT3_APP_FLAGS_BUFFER_VALID (0x0002) ++#define MPT3_APP_FLAGS_FW_BUFFER_ACCESS (0x0004) ++ ++/* flags for mpt3_diag_read_buffer */ ++#define MPT3_FLAGS_REREGISTER (0x0001) ++ ++#define MPT3_PRODUCT_SPECIFIC_DWORDS 23 ++ ++/** ++ * struct mpt3_diag_register - application register with driver ++ * @hdr - generic header ++ * @reserved - ++ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED ++ * @application_flags - misc flags ++ * @diagnostic_flags - specifies flags affecting command processing ++ * @product_specific - product specific information ++ * @requested_buffer_size - buffers size in bytes ++ * @unique_id - tag specified by application that is used to signal ownership ++ * of the buffer. ++ * ++ * This will allow the driver to setup any required buffers that will be ++ * needed by firmware to communicate with the driver. ++ */ ++struct mpt3_diag_register { ++ struct mpt3_ioctl_header hdr; ++ uint8_t reserved; ++ uint8_t buffer_type; ++ uint16_t application_flags; ++ uint32_t diagnostic_flags; ++ uint32_t product_specific[MPT3_PRODUCT_SPECIFIC_DWORDS]; ++ uint32_t requested_buffer_size; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_unregister - application unregister with driver ++ * @hdr - generic header ++ * @unique_id - tag uniquely identifies the buffer to be unregistered ++ * ++ * This will allow the driver to cleanup any memory allocated for diag ++ * messages and to free up any resources. ++ */ ++struct mpt3_diag_unregister { ++ struct mpt3_ioctl_header hdr; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_query - query relevant info associated with diag buffers ++ * @hdr - generic header ++ * @reserved - ++ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED ++ * @application_flags - misc flags ++ * @diagnostic_flags - specifies flags affecting command processing ++ * @product_specific - product specific information ++ * @total_buffer_size - diag buffer size in bytes ++ * @driver_added_buffer_size - size of extra space appended to end of buffer ++ * @unique_id - unique id associated with this buffer. ++ * ++ * The application will send only buffer_type and unique_id. Driver will ++ * inspect unique_id first, if valid, fill in all the info. If unique_id is ++ * 0x00, the driver will return info specified by Buffer Type. ++ */ ++struct mpt3_diag_query { ++ struct mpt3_ioctl_header hdr; ++ uint8_t reserved; ++ uint8_t buffer_type; ++ uint16_t application_flags; ++ uint32_t diagnostic_flags; ++ uint32_t product_specific[MPT3_PRODUCT_SPECIFIC_DWORDS]; ++ uint32_t total_buffer_size; ++ uint32_t driver_added_buffer_size; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_release - request to send Diag Release Message to firmware ++ * @hdr - generic header ++ * @unique_id - tag uniquely identifies the buffer to be released ++ * ++ * This allows ownership of the specified buffer to returned to the driver, ++ * allowing an application to read the buffer without fear that firmware is ++ * overwritting information in the buffer. ++ */ ++struct mpt3_diag_release { ++ struct mpt3_ioctl_header hdr; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_read_buffer - request for copy of the diag buffer ++ * @hdr - generic header ++ * @status - ++ * @reserved - ++ * @flags - misc flags ++ * @starting_offset - starting offset within drivers buffer where to start ++ * reading data at into the specified application buffer ++ * @bytes_to_read - number of bytes to copy from the drivers buffer into the ++ * application buffer starting at starting_offset. ++ * @unique_id - unique id associated with this buffer. ++ * @diagnostic_data - data payload ++ */ ++struct mpt3_diag_read_buffer { ++ struct mpt3_ioctl_header hdr; ++ uint8_t status; ++ uint8_t reserved; ++ uint16_t flags; ++ uint32_t starting_offset; ++ uint32_t bytes_to_read; ++ uint32_t unique_id; ++ uint32_t diagnostic_data[1]; ++}; ++ ++#endif /* MPT3SAS_CTL_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_debug.h b/drivers/scsi/mpt2sas/mpt3sas_debug.h +new file mode 100644 +index 0000000..cceeb2c +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_debug.h +@@ -0,0 +1,206 @@ ++/* ++ * Logging Support for MPT (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_debug.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#ifndef MPT3SAS_DEBUG_H_INCLUDED ++#define MPT3SAS_DEBUG_H_INCLUDED ++ ++#define MPT_DEBUG 0x00000001 ++#define MPT_DEBUG_MSG_FRAME 0x00000002 ++#define MPT_DEBUG_SG 0x00000004 ++#define MPT_DEBUG_EVENTS 0x00000008 ++#define MPT_DEBUG_EVENT_WORK_TASK 0x00000010 ++#define MPT_DEBUG_INIT 0x00000020 ++#define MPT_DEBUG_EXIT 0x00000040 ++#define MPT_DEBUG_FAIL 0x00000080 ++#define MPT_DEBUG_TM 0x00000100 ++#define MPT_DEBUG_REPLY 0x00000200 ++#define MPT_DEBUG_HANDSHAKE 0x00000400 ++#define MPT_DEBUG_CONFIG 0x00000800 ++#define MPT_DEBUG_DL 0x00001000 ++#define MPT_DEBUG_RESET 0x00002000 ++#define MPT_DEBUG_SCSI 0x00004000 ++#define MPT_DEBUG_IOCTL 0x00008000 ++#define MPT_DEBUG_SAS 0x00020000 ++#define MPT_DEBUG_TRANSPORT 0x00040000 ++#define MPT_DEBUG_TASK_SET_FULL 0x00080000 ++ ++#define MPT_DEBUG_TRIGGER_DIAG 0x00200000 ++ ++ ++#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \ ++{ \ ++ if (IOC->logging_level & BITS) \ ++ CMD; \ ++} ++ ++/* ++ * debug macros ++ */ ++ ++#define dprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG) ++ ++#define dsgprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SG) ++ ++#define devtprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENTS) ++ ++#define dewtprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENT_WORK_TASK) ++ ++#define dinitprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_INIT) ++ ++#define dexitprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EXIT) ++ ++#define dfailprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_FAIL) ++ ++#define dtmprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TM) ++ ++#define dreplyprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_REPLY) ++ ++#define dhsprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_HANDSHAKE) ++ ++#define dcprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CONFIG) ++ ++#define ddlprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_DL) ++ ++#define drsprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_RESET) ++ ++#define dsprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SCSI) ++ ++#define dctlprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_IOCTL) ++ ++#define dsasprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS) ++ ++#define dsastransport(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE) ++ ++#define dmfprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_MSG_FRAME) ++ ++#define dtsfprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TASK_SET_FULL) ++ ++#define dtransportprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRANSPORT) ++ ++#define dTriggerDiagPrintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRIGGER_DIAG) ++ ++ ++ ++/* inline functions for dumping debug data*/ ++ ++/** ++ * _debug_dump_mf - print message frame contents ++ * @mpi_request: pointer to message frame ++ * @sz: number of dwords ++ */ ++static inline void ++_debug_dump_mf(void *mpi_request, int sz) ++{ ++ int i; ++ __le32 *mfp = (__le32 *)mpi_request; ++ ++ pr_info("mf:\n\t"); ++ for (i = 0; i < sz; i++) { ++ if (i && ((i % 8) == 0)) ++ pr_info("\n\t"); ++ pr_info("%08x ", le32_to_cpu(mfp[i])); ++ } ++ pr_info("\n"); ++} ++/** ++ * _debug_dump_reply - print message frame contents ++ * @mpi_request: pointer to message frame ++ * @sz: number of dwords ++ */ ++static inline void ++_debug_dump_reply(void *mpi_request, int sz) ++{ ++ int i; ++ __le32 *mfp = (__le32 *)mpi_request; ++ ++ pr_info("reply:\n\t"); ++ for (i = 0; i < sz; i++) { ++ if (i && ((i % 8) == 0)) ++ pr_info("\n\t"); ++ pr_info("%08x ", le32_to_cpu(mfp[i])); ++ } ++ pr_info("\n"); ++} ++/** ++ * _debug_dump_config - print config page contents ++ * @mpi_request: pointer to message frame ++ * @sz: number of dwords ++ */ ++static inline void ++_debug_dump_config(void *mpi_request, int sz) ++{ ++ int i; ++ __le32 *mfp = (__le32 *)mpi_request; ++ ++ pr_info("config:\n\t"); ++ for (i = 0; i < sz; i++) { ++ if (i && ((i % 8) == 0)) ++ pr_info("\n\t"); ++ pr_info("%08x ", le32_to_cpu(mfp[i])); ++ } ++ pr_info("\n"); ++} ++ ++#endif /* MPT3SAS_DEBUG_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_scsih.c b/drivers/scsi/mpt2sas/mpt3sas_scsih.c +new file mode 100644 +index 0000000..0a3ad2b +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_scsih.c +@@ -0,0 +1,9356 @@ ++/* ++ * Scsi Host Layer for MPT (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++#define RAID_CHANNEL 1 ++/* forward proto's */ ++static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander); ++static void _firmware_event_work(struct work_struct *work); ++ ++static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device); ++static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u8 retry_count, u8 is_pd); ++ ++static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++ ++/* global parameters */ ++LIST_HEAD(mpt2sas_ioc_list); ++/* global ioc lock for list operations */ ++DEFINE_SPINLOCK(gioc_lock_mpt2sas); ++ ++MODULE_AUTHOR(MPT3SAS_AUTHOR); ++#ifdef MPT2SAS_SCSI ++MODULE_DESCRIPTION(MPT2SAS_DESCRIPTION); ++MODULE_VERSION(MPT2SAS_DRIVER_VERSION); ++#else ++MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION); ++MODULE_VERSION(MPT3SAS_DRIVER_VERSION); ++#endif /* MPT2SAS_SCSI */ ++MODULE_LICENSE("GPL"); ++ ++/* local parameters */ ++static u8 scsi_io_cb_idx = -1; ++static u8 tm_cb_idx = -1; ++static u8 ctl_cb_idx = -1; ++static u8 base_cb_idx = -1; ++static u8 port_enable_cb_idx = -1; ++static u8 transport_cb_idx = -1; ++static u8 scsih_cb_idx = -1; ++static u8 config_cb_idx = -1; ++static int mpt2_ids; ++static int mpt3_ids; ++ ++static u8 tm_tr_cb_idx = -1 ; ++static u8 tm_tr_volume_cb_idx = -1 ; ++static u8 tm_sas_control_cb_idx = -1; ++ ++/* command line options */ ++static u32 logging_level; ++MODULE_PARM_DESC(logging_level, ++ " bits for enabling additional logging info (default=0)"); ++ ++ ++static ushort max_sectors = 0xFFFF; ++module_param(max_sectors, ushort, 0); ++MODULE_PARM_DESC(max_sectors, "max sectors, range 64 to 32767 default=32767"); ++ ++ ++static int missing_delay[2] = {-1, -1}; ++module_param_array(missing_delay, int, NULL, 0); ++MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); ++ ++/* scsi-mid layer global parmeter is max_report_luns, which is 511 */ ++#define MPT3SAS_MAX_LUN (16895) ++static int max_lun = MPT3SAS_MAX_LUN; ++module_param(max_lun, int, 0); ++MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); ++ ++/* diag_buffer_enable is bitwise ++ * bit 0 set = TRACE ++ * bit 1 set = SNAPSHOT ++ * bit 2 set = EXTENDED ++ * ++ * Either bit can be set, or both ++ */ ++static int diag_buffer_enable = -1; ++module_param(diag_buffer_enable, int, 0); ++MODULE_PARM_DESC(diag_buffer_enable, ++ " post diag buffers (TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); ++static int disable_discovery = -1; ++module_param(disable_discovery, int, 0); ++MODULE_PARM_DESC(disable_discovery, " disable discovery "); ++ ++ ++/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */ ++static int prot_mask = -1; ++module_param(prot_mask, int, 0); ++MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 "); ++ ++ ++/* raid transport support */ ++struct raid_template *mpt3sas_raid_template_mpt2sas; ++struct raid_template *mpt2sas_raid_template_mpt2sas; ++ ++ ++/** ++ * struct sense_info - common structure for obtaining sense keys ++ * @skey: sense key ++ * @asc: additional sense code ++ * @ascq: additional sense code qualifier ++ */ ++struct sense_info { ++ u8 skey; ++ u8 asc; ++ u8 ascq; ++}; ++ ++#define MPT3SAS_PROCESS_TRIGGER_DIAG (0xFFFB) ++#define MPT3SAS_TURN_ON_PFA_LED (0xFFFC) ++#define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD) ++#define MPT3SAS_ABRT_TASK_SET (0xFFFE) ++#define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) ++/** ++ * struct fw_event_work - firmware event struct ++ * @list: link list framework ++ * @work: work object (ioc->fault_reset_work_q) ++ * @ioc: per adapter object ++ * @device_handle: device handle ++ * @VF_ID: virtual function id ++ * @VP_ID: virtual port id ++ * @ignore: flag meaning this event has been marked to ignore ++ * @event: firmware event MPI2_EVENT_XXX defined in mpi2_ioc.h ++ * @refcount: kref for this event ++ * @event_data: reply event data payload follows ++ * ++ * This object stored on ioc->fw_event_list. ++ */ ++struct fw_event_work { ++ struct list_head list; ++ struct work_struct work; ++ ++ struct MPT3SAS_ADAPTER *ioc; ++ u16 device_handle; ++ u8 VF_ID; ++ u8 VP_ID; ++ u8 ignore; ++ u16 event; ++ struct kref refcount; ++ char event_data[0] __aligned(4); ++}; ++ ++static void fw_event_work_free(struct kref *r) ++{ ++ kfree(container_of(r, struct fw_event_work, refcount)); ++} ++ ++static void fw_event_work_get(struct fw_event_work *fw_work) ++{ ++ kref_get(&fw_work->refcount); ++} ++ ++static void fw_event_work_put(struct fw_event_work *fw_work) ++{ ++ kref_put(&fw_work->refcount, fw_event_work_free); ++} ++ ++static struct fw_event_work *alloc_fw_event_work(int len) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC); ++ if (!fw_event) ++ return NULL; ++ ++ kref_init(&fw_event->refcount); ++ return fw_event; ++} ++ ++/** ++ * struct _scsi_io_transfer - scsi io transfer ++ * @handle: sas device handle (assigned by firmware) ++ * @is_raid: flag set for hidden raid components ++ * @dir: DMA_TO_DEVICE, DMA_FROM_DEVICE, ++ * @data_length: data transfer length ++ * @data_dma: dma pointer to data ++ * @sense: sense data ++ * @lun: lun number ++ * @cdb_length: cdb length ++ * @cdb: cdb contents ++ * @timeout: timeout for this command ++ * @VF_ID: virtual function id ++ * @VP_ID: virtual port id ++ * @valid_reply: flag set for reply message ++ * @sense_length: sense length ++ * @ioc_status: ioc status ++ * @scsi_state: scsi state ++ * @scsi_status: scsi staus ++ * @log_info: log information ++ * @transfer_length: data length transfer when there is a reply message ++ * ++ * Used for sending internal scsi commands to devices within this module. ++ * Refer to _scsi_send_scsi_io(). ++ */ ++struct _scsi_io_transfer { ++ u16 handle; ++ u8 is_raid; ++ enum dma_data_direction dir; ++ u32 data_length; ++ dma_addr_t data_dma; ++ u8 sense[SCSI_SENSE_BUFFERSIZE]; ++ u32 lun; ++ u8 cdb_length; ++ u8 cdb[32]; ++ u8 timeout; ++ u8 VF_ID; ++ u8 VP_ID; ++ u8 valid_reply; ++ /* the following bits are only valid when 'valid_reply = 1' */ ++ u32 sense_length; ++ u16 ioc_status; ++ u8 scsi_state; ++ u8 scsi_status; ++ u32 log_info; ++ u32 transfer_length; ++}; ++ ++/** ++ * _scsih_set_debug_level - global setting of ioc->logging_level. ++ * ++ * Note: The logging levels are defined in mpt3sas_debug.h. ++ */ ++static int ++_scsih_set_debug_level(const char *val, struct kernel_param *kp) ++{ ++ int ret = param_set_int(val, kp); ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (ret) ++ return ret; ++ ++ pr_info("setting logging_level(0x%08x)\n", logging_level); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) ++ ioc->logging_level = logging_level; ++ spin_unlock(&gioc_lock_mpt2sas); ++ return 0; ++} ++module_param_call(logging_level, _scsih_set_debug_level, param_get_int, ++ &logging_level, 0644); ++ ++/** ++ * _scsih_srch_boot_sas_address - search based on sas_address ++ * @sas_address: sas address ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static inline int ++_scsih_srch_boot_sas_address(u64 sas_address, ++ Mpi2BootDeviceSasWwid_t *boot_device) ++{ ++ return (sas_address == le64_to_cpu(boot_device->SASAddress)) ? 1 : 0; ++} ++ ++/** ++ * _scsih_srch_boot_device_name - search based on device name ++ * @device_name: device name specified in INDENTIFY fram ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static inline int ++_scsih_srch_boot_device_name(u64 device_name, ++ Mpi2BootDeviceDeviceName_t *boot_device) ++{ ++ return (device_name == le64_to_cpu(boot_device->DeviceName)) ? 1 : 0; ++} ++ ++/** ++ * _scsih_srch_boot_encl_slot - search based on enclosure_logical_id/slot ++ * @enclosure_logical_id: enclosure logical id ++ * @slot_number: slot number ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static inline int ++_scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number, ++ Mpi2BootDeviceEnclosureSlot_t *boot_device) ++{ ++ return (enclosure_logical_id == le64_to_cpu(boot_device-> ++ EnclosureLogicalID) && slot_number == le16_to_cpu(boot_device-> ++ SlotNumber)) ? 1 : 0; ++} ++ ++/** ++ * _scsih_is_boot_device - search for matching boot device. ++ * @sas_address: sas address ++ * @device_name: device name specified in INDENTIFY fram ++ * @enclosure_logical_id: enclosure logical id ++ * @slot_number: slot number ++ * @form: specifies boot device form ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static int ++_scsih_is_boot_device(u64 sas_address, u64 device_name, ++ u64 enclosure_logical_id, u16 slot, u8 form, ++ Mpi2BiosPage2BootDevice_t *boot_device) ++{ ++ int rc = 0; ++ ++ switch (form) { ++ case MPI2_BIOSPAGE2_FORM_SAS_WWID: ++ if (!sas_address) ++ break; ++ rc = _scsih_srch_boot_sas_address( ++ sas_address, &boot_device->SasWwid); ++ break; ++ case MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT: ++ if (!enclosure_logical_id) ++ break; ++ rc = _scsih_srch_boot_encl_slot( ++ enclosure_logical_id, ++ slot, &boot_device->EnclosureSlot); ++ break; ++ case MPI2_BIOSPAGE2_FORM_DEVICE_NAME: ++ if (!device_name) ++ break; ++ rc = _scsih_srch_boot_device_name( ++ device_name, &boot_device->DeviceName); ++ break; ++ case MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED: ++ break; ++ } ++ ++ return rc; ++} ++ ++/** ++ * _scsih_get_sas_address - set the sas_address for given device handle ++ * @handle: device handle ++ * @sas_address: sas address ++ * ++ * Returns 0 success, non-zero when failure ++ */ ++static int ++_scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u64 *sas_address) ++{ ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 ioc_status; ++ ++ *sas_address = 0; ++ ++ if (handle <= ioc->sas_hba.num_phys) { ++ *sas_address = ioc->sas_hba.sas_address; ++ return 0; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ return 0; ++ } ++ ++ /* we hit this becuase the given parent handle doesn't exist */ ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ return -ENXIO; ++ ++ /* else error case */ ++ pr_err(MPT3SAS_FMT ++ "handle(0x%04x), ioc_status(0x%04x), failure at %s:%d/%s()!\n", ++ ioc->name, handle, ioc_status, ++ __FILE__, __LINE__, __func__); ++ return -EIO; ++} ++ ++/** ++ * _scsih_determine_boot_device - determine boot device. ++ * @ioc: per adapter object ++ * @device: either sas_device or raid_device object ++ * @is_raid: [flag] 1 = raid object, 0 = sas object ++ * ++ * Determines whether this device should be first reported device to ++ * to scsi-ml or sas transport, this purpose is for persistent boot device. ++ * There are primary, alternate, and current entries in bios page 2. The order ++ * priority is primary, alternate, then current. This routine saves ++ * the corresponding device object and is_raid flag in the ioc object. ++ * The saved data to be used later in _scsih_probe_boot_devices(). ++ */ ++static void ++_scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, ++ void *device, u8 is_raid) ++{ ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ u64 sas_address; ++ u64 device_name; ++ u64 enclosure_logical_id; ++ u16 slot; ++ ++ /* only process this function when driver loads */ ++ if (!ioc->is_driver_loading) ++ return; ++ ++ /* no Bios, return immediately */ ++ if (!ioc->bios_pg3.BiosVersion) ++ return; ++ ++ if (!is_raid) { ++ sas_device = device; ++ sas_address = sas_device->sas_address; ++ device_name = sas_device->device_name; ++ enclosure_logical_id = sas_device->enclosure_logical_id; ++ slot = sas_device->slot; ++ } else { ++ raid_device = device; ++ sas_address = raid_device->wwid; ++ device_name = 0; ++ enclosure_logical_id = 0; ++ slot = 0; ++ } ++ ++ if (!ioc->req_boot_device.device) { ++ if (_scsih_is_boot_device(sas_address, device_name, ++ enclosure_logical_id, slot, ++ (ioc->bios_pg2.ReqBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK), ++ &ioc->bios_pg2.RequestedBootDevice)) { ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: req_boot_device(0x%016llx)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_address)); ++ ioc->req_boot_device.device = device; ++ ioc->req_boot_device.is_raid = is_raid; ++ } ++ } ++ ++ if (!ioc->req_alt_boot_device.device) { ++ if (_scsih_is_boot_device(sas_address, device_name, ++ enclosure_logical_id, slot, ++ (ioc->bios_pg2.ReqAltBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK), ++ &ioc->bios_pg2.RequestedAltBootDevice)) { ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: req_alt_boot_device(0x%016llx)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_address)); ++ ioc->req_alt_boot_device.device = device; ++ ioc->req_alt_boot_device.is_raid = is_raid; ++ } ++ } ++ ++ if (!ioc->current_boot_device.device) { ++ if (_scsih_is_boot_device(sas_address, device_name, ++ enclosure_logical_id, slot, ++ (ioc->bios_pg2.CurrentBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK), ++ &ioc->bios_pg2.CurrentBootDevice)) { ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: current_boot_device(0x%016llx)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_address)); ++ ioc->current_boot_device.device = device; ++ ioc->current_boot_device.is_raid = is_raid; ++ } ++ } ++} ++ ++static struct _sas_device * ++__mpt2sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, ++ struct MPT3SAS_TARGET *tgt_priv) ++{ ++ struct _sas_device *ret; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ ret = tgt_priv->sdev; ++ if (ret) ++ sas_device_get(ret); ++ ++ return ret; ++} ++ ++static struct _sas_device * ++mpt2sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, ++ struct MPT3SAS_TARGET *tgt_priv) ++{ ++ struct _sas_device *ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ ret = __mpt2sas_get_sdev_from_target(ioc, tgt_priv); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return ret; ++} ++ ++ ++struct _sas_device * ++__mpt2sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_device *sas_device; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) ++ if (sas_device->sas_address == sas_address) ++ goto found_device; ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) ++ if (sas_device->sas_address == sas_address) ++ goto found_device; ++ ++ return NULL; ++ ++found_device: ++ sas_device_get(sas_device); ++ return sas_device; ++} ++ ++/** ++ * mpt2sas_get_sdev_by_addr - sas device search ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for sas_device based on sas_address, then return sas_device ++ * object. ++ */ ++struct _sas_device * ++mpt2sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return sas_device; ++} ++ ++static struct _sas_device * ++__mpt2sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) ++ if (sas_device->handle == handle) ++ goto found_device; ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) ++ if (sas_device->handle == handle) ++ goto found_device; ++ ++ return NULL; ++ ++found_device: ++ sas_device_get(sas_device); ++ return sas_device; ++} ++ ++/** ++ * mpt2sas_get_sdev_by_handle - sas device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for sas_device based on sas_address, then return sas_device ++ * object. ++ */ ++static struct _sas_device * ++mpt2sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return sas_device; ++} ++ ++/** ++ * _scsih_sas_device_remove - remove sas_device from list. ++ * @ioc: per adapter object ++ * @sas_device: the sas_device object ++ * Context: This function will acquire ioc->sas_device_lock. ++ * ++ * If sas_device is on the list, remove it and decrement its reference count. ++ */ ++static void ++_scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ if (!sas_device) ++ return; ++ pr_info(MPT3SAS_FMT ++ "removing handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, sas_device->handle, ++ (unsigned long long) sas_device->sas_address); ++ ++ if (sas_device->enclosure_handle != 0) ++ pr_info(MPT3SAS_FMT ++ "removing enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot); ++ ++ if (sas_device->connector_name[0] != '\0') ++ pr_info(MPT3SAS_FMT ++ "removing enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ /* ++ * The lock serializes access to the list, but we still need to verify ++ * that nobody removed the entry while we were waiting on the lock. ++ */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ if (!list_empty(&sas_device->list)) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_device_remove_by_handle - removing device object by handle ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (sas_device) { ++ _scsih_remove_device(ioc, sas_device); ++ sas_device_put(sas_device); ++ } ++} ++ ++/** ++ * mpt2sas_device_remove_by_sas_address - removing device object by sas address ++ * @ioc: per adapter object ++ * @sas_address: device sas_address ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, sas_address); ++ if (sas_device) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (sas_device) { ++ _scsih_remove_device(ioc, sas_device); ++ sas_device_put(sas_device); ++ } ++} ++ ++/** ++ * _scsih_sas_device_add - insert sas_device to the list. ++ * @ioc: per adapter object ++ * @sas_device: the sas_device object ++ * Context: This function will acquire ioc->sas_device_lock. ++ * ++ * Adding new object to the ioc->sas_device_list. ++ */ ++static void ++_scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, __func__, sas_device->handle, ++ (unsigned long long)sas_device->sas_address)); ++ ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure logical id(0x%016llx), slot( %d)\n", ++ ioc->name, __func__, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot)); ++ ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, __func__, ++ sas_device->enclosure_level, sas_device->connector_name)); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device_get(sas_device); ++ list_add_tail(&sas_device->list, &ioc->sas_device_list); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (!mpt2sas_transport_port_add(ioc, sas_device->handle, ++ sas_device->sas_address_parent)) { ++ _scsih_sas_device_remove(ioc, sas_device); ++ } else if (!sas_device->starget) { ++ /* ++ * When asyn scanning is enabled, its not possible to remove ++ * devices while scanning is turned on due to an oops in ++ * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start() ++ */ ++ if (!ioc->is_driver_loading) { ++ mpt2sas_transport_port_remove(ioc, ++ sas_device->sas_address, ++ sas_device->sas_address_parent); ++ _scsih_sas_device_remove(ioc, sas_device); ++ } ++ } ++} ++ ++/** ++ * _scsih_sas_device_init_add - insert sas_device to the list. ++ * @ioc: per adapter object ++ * @sas_device: the sas_device object ++ * Context: This function will acquire ioc->sas_device_lock. ++ * ++ * Adding new object at driver load time to the ioc->sas_device_init_list. ++ */ ++static void ++_scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ __func__, sas_device->handle, ++ (unsigned long long)sas_device->sas_address)); ++ ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure logical id(0x%016llx), slot( %d)\n", ++ ioc->name, __func__, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot)); ++ ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, __func__, sas_device->enclosure_level, ++ sas_device->connector_name)); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device_get(sas_device); ++ list_add_tail(&sas_device->list, &ioc->sas_device_init_list); ++ _scsih_determine_boot_device(ioc, sas_device, 0); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_raid_device_find_by_id - raid device search ++ * @ioc: per adapter object ++ * @id: sas device target id ++ * @channel: sas device channel ++ * Context: Calling function should acquire ioc->raid_device_lock ++ * ++ * This searches for raid_device based on target id, then return raid_device ++ * object. ++ */ ++static struct _raid_device * ++_scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel) ++{ ++ struct _raid_device *raid_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->id == id && raid_device->channel == channel) { ++ r = raid_device; ++ goto out; ++ } ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_raid_device_find_by_handle - raid device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->raid_device_lock ++ * ++ * This searches for raid_device based on handle, then return raid_device ++ * object. ++ */ ++struct _raid_device * ++mpt2sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _raid_device *raid_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->handle != handle) ++ continue; ++ r = raid_device; ++ goto out; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * _scsih_raid_device_find_by_wwid - raid device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->raid_device_lock ++ * ++ * This searches for raid_device based on wwid, then return raid_device ++ * object. ++ */ ++static struct _raid_device * ++_scsih_raid_device_find_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid) ++{ ++ struct _raid_device *raid_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->wwid != wwid) ++ continue; ++ r = raid_device; ++ goto out; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * _scsih_raid_device_add - add raid_device object ++ * @ioc: per adapter object ++ * @raid_device: raid_device object ++ * ++ * This is added to the raid_device_list link list. ++ */ ++static void ++_scsih_raid_device_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ unsigned long flags; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__, ++ raid_device->handle, (unsigned long long)raid_device->wwid)); ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_add_tail(&raid_device->list, &ioc->raid_device_list); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * _scsih_raid_device_remove - delete raid_device object ++ * @ioc: per adapter object ++ * @raid_device: raid_device object ++ * ++ */ ++static void ++_scsih_raid_device_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_del(&raid_device->list); ++ kfree(raid_device); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * mpt2sas_scsih_expander_find_by_handle - expander device search ++ * @ioc: per adapter object ++ * @handle: expander handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for expander device based on handle, then returns the ++ * sas_node object. ++ */ ++struct _sas_node * ++mpt2sas_scsih_expander_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_node *sas_expander, *r; ++ ++ r = NULL; ++ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { ++ if (sas_expander->handle != handle) ++ continue; ++ r = sas_expander; ++ goto out; ++ } ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_scsih_expander_find_by_sas_address - expander device search ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * Context: Calling function should acquire ioc->sas_node_lock. ++ * ++ * This searches for expander device based on sas_address, then returns the ++ * sas_node object. ++ */ ++struct _sas_node * ++mpt2sas_scsih_expander_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_node *sas_expander, *r; ++ ++ r = NULL; ++ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { ++ if (sas_expander->sas_address != sas_address) ++ continue; ++ r = sas_expander; ++ goto out; ++ } ++ out: ++ return r; ++} ++ ++/** ++ * _scsih_expander_node_add - insert expander device to the list. ++ * @ioc: per adapter object ++ * @sas_expander: the sas_device object ++ * Context: This function will acquire ioc->sas_node_lock. ++ * ++ * Adding new object to the ioc->sas_expander_list. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_expander_node_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_add_tail(&sas_expander->list, &ioc->sas_expander_list); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++} ++ ++/** ++ * _scsih_is_end_device - determines if device is an end device ++ * @device_info: bitfield providing information about the device. ++ * Context: none ++ * ++ * Returns 1 if end device. ++ */ ++static int ++_scsih_is_end_device(u32 device_info) ++{ ++ if (device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE && ++ ((device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) | ++ (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) | ++ (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE))) ++ return 1; ++ else ++ return 0; ++} ++ ++/** ++ * _scsih_scsi_lookup_get - returns scmd entry ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns the smid stored scmd pointer. ++ */ ++static struct scsi_cmnd * ++_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return ioc->scsi_lookup[smid - 1].scmd; ++} ++ ++/** ++ * _scsih_scsi_lookup_get_clear - returns scmd entry ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns the smid stored scmd pointer. ++ * Then will derefrence the stored scmd pointer. ++ */ ++static inline struct scsi_cmnd * ++_scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ unsigned long flags; ++ struct scsi_cmnd *scmd; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ scmd = ioc->scsi_lookup[smid - 1].scmd; ++ ioc->scsi_lookup[smid - 1].scmd = NULL; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ return scmd; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_scmd - scmd lookup ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @scmd: pointer to scsi command object ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a scmd pointer in the scsi_lookup array, ++ * returning the revelent smid. A returned value of zero means invalid. ++ */ ++static u16 ++_scsih_scsi_lookup_find_by_scmd(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd ++ *scmd) ++{ ++ u16 smid; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ smid = 0; ++ for (i = 0; i < ioc->scsiio_depth; i++) { ++ if (ioc->scsi_lookup[i].scmd == scmd) { ++ smid = ioc->scsi_lookup[i].smid; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_target - search for matching channel:id ++ * @ioc: per adapter object ++ * @id: target id ++ * @channel: channel ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a matching channel:id in the scsi_lookup array, ++ * returning 1 if found. ++ */ ++static u8 ++_scsih_scsi_lookup_find_by_target(struct MPT3SAS_ADAPTER *ioc, int id, ++ int channel) ++{ ++ u8 found; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ found = 0; ++ for (i = 0 ; i < ioc->scsiio_depth; i++) { ++ if (ioc->scsi_lookup[i].scmd && ++ (ioc->scsi_lookup[i].scmd->device->id == id && ++ ioc->scsi_lookup[i].scmd->device->channel == channel)) { ++ found = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return found; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun ++ * @ioc: per adapter object ++ * @id: target id ++ * @lun: lun number ++ * @channel: channel ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a matching channel:id:lun in the scsi_lookup array, ++ * returning 1 if found. ++ */ ++static u8 ++_scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id, ++ unsigned int lun, int channel) ++{ ++ u8 found; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ found = 0; ++ for (i = 0 ; i < ioc->scsiio_depth; i++) { ++ if (ioc->scsi_lookup[i].scmd && ++ (ioc->scsi_lookup[i].scmd->device->id == id && ++ ioc->scsi_lookup[i].scmd->device->channel == channel && ++ ioc->scsi_lookup[i].scmd->device->lun == lun)) { ++ found = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return found; ++} ++ ++static void ++_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) ++{ ++ struct Scsi_Host *shost = sdev->host; ++ int max_depth; ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ max_depth = shost->can_queue; ++ ++ /* limit max device queue for SATA to 32 */ ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ goto not_sata; ++ sas_target_priv_data = sas_device_priv_data->sas_target; ++ if (!sas_target_priv_data) ++ goto not_sata; ++ if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) ++ goto not_sata; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data); ++ if (sas_device) { ++ if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ max_depth = MPT3SAS_SATA_QUEUE_DEPTH; ++ ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ not_sata: ++ ++ if (!sdev->tagged_supported) ++ max_depth = 1; ++ if (qdepth > max_depth) ++ qdepth = max_depth; ++ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); ++} ++ ++/** ++ * scsih_change_queue_depth_mpt2sas - setting device queue depth ++ * @sdev: scsi device struct ++ * @qdepth: requested queue depth ++ * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP ++ * (see include/scsi/scsi_host.h for definition) ++ * ++ * Returns queue depth. ++ */ ++int ++scsih_change_queue_depth_mpt2sas(struct scsi_device *sdev, int qdepth, int reason) ++{ ++ if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) ++ _scsih_adjust_queue_depth(sdev, qdepth); ++ else if (reason == SCSI_QDEPTH_QFULL) ++ scsi_track_queue_full(sdev, qdepth); ++ else ++ return -EOPNOTSUPP; ++ ++ if (sdev->inquiry_len > 7) ++ sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " \ ++ "simple(%d), ordered(%d), scsi_level(%d), cmd_que(%d)\n", ++ sdev->queue_depth, sdev->tagged_supported, sdev->simple_tags, ++ sdev->ordered_tags, sdev->scsi_level, ++ (sdev->inquiry[7] & 2) >> 1); ++ ++ return sdev->queue_depth; ++} ++ ++/** ++ * _scsih_change_queue_type_mpt2sas - changing device queue tag type ++ * @sdev: scsi device struct ++ * @tag_type: requested tag type ++ * ++ * Returns queue tag type. ++ */ ++int ++_scsih_change_queue_type_mpt2sas(struct scsi_device *sdev, int tag_type) ++{ ++ if (sdev->tagged_supported) { ++ scsi_set_tag_type(sdev, tag_type); ++ if (tag_type) ++ scsi_activate_tcq(sdev, sdev->queue_depth); ++ else ++ scsi_deactivate_tcq(sdev, sdev->queue_depth); ++ } else ++ tag_type = 0; ++ ++ return tag_type; ++} ++ ++ ++/** ++ * scsih_target_alloc_mpt2sas - target add routine ++ * @starget: scsi target struct ++ * ++ * Returns 0 if ok. Any other return is assumed to be an error and ++ * the device is ignored. ++ */ ++int ++scsih_target_alloc_mpt2sas(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost = dev_to_shost(&starget->dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ struct sas_rphy *rphy; ++ ++ sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data), ++ GFP_KERNEL); ++ if (!sas_target_priv_data) ++ return -ENOMEM; ++ ++ starget->hostdata = sas_target_priv_data; ++ sas_target_priv_data->starget = starget; ++ sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; ++ ++ /* RAID volumes */ ++ if (starget->channel == RAID_CHANNEL) { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, starget->id, ++ starget->channel); ++ if (raid_device) { ++ sas_target_priv_data->handle = raid_device->handle; ++ sas_target_priv_data->sas_address = raid_device->wwid; ++ sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; ++ sas_target_priv_data->raid_device = raid_device; ++ if (ioc->is_warpdrive) ++ raid_device->starget = starget; ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ return 0; ++ } ++ ++ /* sas/sata devices */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ rphy = dev_to_rphy(starget->dev.parent); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ rphy->identify.sas_address); ++ ++ if (sas_device) { ++ sas_target_priv_data->handle = sas_device->handle; ++ sas_target_priv_data->sas_address = sas_device->sas_address; ++ sas_target_priv_data->sdev = sas_device; ++ sas_device->starget = starget; ++ sas_device->id = starget->id; ++ sas_device->channel = starget->channel; ++ if (test_bit(sas_device->handle, ioc->pd_handles)) ++ sas_target_priv_data->flags |= ++ MPT_TARGET_FLAGS_RAID_COMPONENT; ++ if (sas_device->fast_path) ++ sas_target_priv_data->flags |= MPT_TARGET_FASTPATH_IO; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return 0; ++} ++ ++/** ++ * scsih_target_destroy_mpt2sas - target destroy routine ++ * @starget: scsi target struct ++ * ++ * Returns nothing. ++ */ ++void ++scsih_target_destroy_mpt2sas(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost = dev_to_shost(&starget->dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ struct sas_rphy *rphy; ++ ++ sas_target_priv_data = starget->hostdata; ++ if (!sas_target_priv_data) ++ return; ++ ++ if (starget->channel == RAID_CHANNEL) { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, starget->id, ++ starget->channel); ++ if (raid_device) { ++ raid_device->starget = NULL; ++ raid_device->sdev = NULL; ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ goto out; ++ } ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ rphy = dev_to_rphy(starget->dev.parent); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data); ++ if (sas_device && (sas_device->starget == starget) && ++ (sas_device->id == starget->id) && ++ (sas_device->channel == starget->channel)) ++ sas_device->starget = NULL; ++ ++ if (sas_device) { ++ /* ++ * Corresponding get() is in _scsih_target_alloc_mpt2sas() ++ */ ++ sas_target_priv_data->sdev = NULL; ++ sas_device_put(sas_device); ++ ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ out: ++ kfree(sas_target_priv_data); ++ starget->hostdata = NULL; ++} ++ ++/** ++ * scsih_slave_alloc_mpt2sas - device add routine ++ * @sdev: scsi device struct ++ * ++ * Returns 0 if ok. Any other return is assumed to be an error and ++ * the device is ignored. ++ */ ++int ++scsih_slave_alloc_mpt2sas(struct scsi_device *sdev) ++{ ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_target *starget; ++ struct _raid_device *raid_device; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data), ++ GFP_KERNEL); ++ if (!sas_device_priv_data) ++ return -ENOMEM; ++ ++ sas_device_priv_data->lun = sdev->lun; ++ sas_device_priv_data->flags = MPT_DEVICE_FLAGS_INIT; ++ ++ starget = scsi_target(sdev); ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->num_luns++; ++ sas_device_priv_data->sas_target = sas_target_priv_data; ++ sdev->hostdata = sas_device_priv_data; ++ if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT)) ++ sdev->no_uld_attach = 1; ++ ++ shost = dev_to_shost(&starget->dev); ++ ioc = shost_priv(shost); ++ if (starget->channel == RAID_CHANNEL) { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, ++ starget->id, starget->channel); ++ if (raid_device) ++ raid_device->sdev = sdev; /* raid is single lun */ ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++ ++ if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_target_priv_data->sas_address); ++ if (sas_device && (sas_device->starget == NULL)) { ++ sdev_printk(KERN_INFO, sdev, ++ "%s : sas_device->starget set to starget @ %d\n", ++ __func__, __LINE__); ++ sas_device->starget = starget; ++ } ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ ++ return 0; ++} ++ ++/** ++ * scsih_slave_destroy_mpt2sas - device destroy routine ++ * @sdev: scsi device struct ++ * ++ * Returns nothing. ++ */ ++void ++scsih_slave_destroy_mpt2sas(struct scsi_device *sdev) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct scsi_target *starget; ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ if (!sdev->hostdata) ++ return; ++ ++ starget = scsi_target(sdev); ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->num_luns--; ++ ++ shost = dev_to_shost(&starget->dev); ++ ioc = shost_priv(shost); ++ ++ if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, ++ sas_target_priv_data); ++ if (sas_device && !sas_target_priv_data->num_luns) ++ sas_device->starget = NULL; ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ ++ kfree(sdev->hostdata); ++ sdev->hostdata = NULL; ++} ++ ++/** ++ * _scsih_display_sata_capabilities - sata capabilities ++ * @ioc: per adapter object ++ * @handle: device handle ++ * @sdev: scsi device struct ++ */ ++static void ++_scsih_display_sata_capabilities(struct MPT3SAS_ADAPTER *ioc, ++ u16 handle, struct scsi_device *sdev) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ u32 ioc_status; ++ u16 flags; ++ u32 device_info; ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ flags = le16_to_cpu(sas_device_pg0.Flags); ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ ++ sdev_printk(KERN_INFO, sdev, ++ "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), " ++ "sw_preserve(%s)\n", ++ (device_info & MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY) ? "y" : ++ "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n"); ++} ++ ++/* ++ * raid transport support - ++ * Enabled for SLES11 and newer, in older kernels the driver will panic when ++ * unloading the driver followed by a load - I beleive that the subroutine ++ * raid_class_release() is not cleaning up properly. ++ */ ++ ++/** ++ * scsih_is_raid_mpt2sas - return boolean indicating device is raid volume ++ * @dev the device struct object ++ */ ++int ++scsih_is_raid_mpt2sas(struct device *dev) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); ++ ++ if (ioc->is_warpdrive) ++ return 0; ++ return (sdev->channel == RAID_CHANNEL) ? 1 : 0; ++} ++ ++/** ++ * scsih_get_resync_mpt2sas - get raid volume resync percent complete ++ * @dev the device struct object ++ */ ++void ++scsih_get_resync_mpt2sas(struct device *dev) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); ++ static struct _raid_device *raid_device; ++ unsigned long flags; ++ Mpi2RaidVolPage0_t vol_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 volume_status_flags; ++ u8 percent_complete; ++ u16 handle; ++ ++ percent_complete = 0; ++ handle = 0; ++ if (ioc->is_warpdrive) ++ goto out; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, ++ sdev->channel); ++ if (raid_device) { ++ handle = raid_device->handle; ++ percent_complete = raid_device->percent_complete; ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (!handle) ++ goto out; ++ ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ percent_complete = 0; ++ goto out; ++ } ++ ++ volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); ++ if (!(volume_status_flags & ++ MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)) ++ percent_complete = 0; ++ ++ out: ++ ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ raid_set_resync(mpt2sas_raid_template_mpt2sas, dev, percent_complete); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ raid_set_resync(mpt3sas_raid_template_mpt2sas, dev, percent_complete); ++ break; ++ } ++} ++ ++/** ++ * scsih_get_state_mpt2sas - get raid volume level ++ * @dev the device struct object ++ */ ++void ++scsih_get_state_mpt2sas(struct device *dev) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); ++ static struct _raid_device *raid_device; ++ unsigned long flags; ++ Mpi2RaidVolPage0_t vol_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 volstate; ++ enum raid_state state = RAID_STATE_UNKNOWN; ++ u16 handle = 0; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, ++ sdev->channel); ++ if (raid_device) ++ handle = raid_device->handle; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (!raid_device) ++ goto out; ++ ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags); ++ if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { ++ state = RAID_STATE_RESYNCING; ++ goto out; ++ } ++ ++ switch (vol_pg0.VolumeState) { ++ case MPI2_RAID_VOL_STATE_OPTIMAL: ++ case MPI2_RAID_VOL_STATE_ONLINE: ++ state = RAID_STATE_ACTIVE; ++ break; ++ case MPI2_RAID_VOL_STATE_DEGRADED: ++ state = RAID_STATE_DEGRADED; ++ break; ++ case MPI2_RAID_VOL_STATE_FAILED: ++ case MPI2_RAID_VOL_STATE_MISSING: ++ state = RAID_STATE_OFFLINE; ++ break; ++ } ++ out: ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ raid_set_state(mpt2sas_raid_template_mpt2sas, dev, state); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ raid_set_state(mpt3sas_raid_template_mpt2sas, dev, state); ++ break; ++ } ++} ++ ++/** ++ * _scsih_set_level - set raid level ++ * @sdev: scsi device struct ++ * @volume_type: volume type ++ */ ++static void ++_scsih_set_level(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_device *sdev, u8 volume_type) ++{ ++ enum raid_level level = RAID_LEVEL_UNKNOWN; ++ ++ switch (volume_type) { ++ case MPI2_RAID_VOL_TYPE_RAID0: ++ level = RAID_LEVEL_0; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID10: ++ level = RAID_LEVEL_10; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1E: ++ level = RAID_LEVEL_1E; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1: ++ level = RAID_LEVEL_1; ++ break; ++ } ++ ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ raid_set_level(mpt2sas_raid_template_mpt2sas, ++ &sdev->sdev_gendev, level); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ raid_set_level(mpt3sas_raid_template_mpt2sas, ++ &sdev->sdev_gendev, level); ++ break; ++ } ++} ++ ++ ++/** ++ * _scsih_get_volume_capabilities - volume capabilities ++ * @ioc: per adapter object ++ * @sas_device: the raid_device object ++ * ++ * Returns 0 for success, else 1 ++ */ ++static int ++_scsih_get_volume_capabilities(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ Mpi2RaidVolPage0_t *vol_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 sz; ++ u8 num_pds; ++ ++ if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, ++ &num_pds)) || !num_pds) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ return 1; ++ } ++ ++ raid_device->num_pds = num_pds; ++ sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * ++ sizeof(Mpi2RaidVol0PhysDisk_t)); ++ vol_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!vol_pg0) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ return 1; ++ } ++ ++ if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ kfree(vol_pg0); ++ return 1; ++ } ++ ++ raid_device->volume_type = vol_pg0->VolumeType; ++ ++ /* figure out what the underlying devices are by ++ * obtaining the device_info bits for the 1st device ++ */ ++ if (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, ++ vol_pg0->PhysDisk[0].PhysDiskNum))) { ++ if (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ++ le16_to_cpu(pd_pg0.DevHandle)))) { ++ raid_device->device_info = ++ le32_to_cpu(sas_device_pg0.DeviceInfo); ++ } ++ } ++ ++ kfree(vol_pg0); ++ return 0; ++} ++ ++/** ++ * _scsih_enable_tlr - setting TLR flags ++ * @ioc: per adapter object ++ * @sdev: scsi device struct ++ * ++ * Enabling Transaction Layer Retries for tape devices when ++ * vpd page 0x90 is present ++ * ++ */ ++static void ++_scsih_enable_tlr(struct MPT3SAS_ADAPTER *ioc, struct scsi_device *sdev) ++{ ++ ++ /* only for TAPE */ ++ if (sdev->type != TYPE_TAPE) ++ return; ++ ++ if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)) ++ return; ++ ++ sas_enable_tlr(sdev); ++ sdev_printk(KERN_INFO, sdev, "TLR %s\n", ++ sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled"); ++ return; ++ ++} ++ ++/** ++ * scsih_slave_configure_mpt2sas - device configure routine. ++ * @sdev: scsi device struct ++ * ++ * Returns 0 if ok. Any other return is assumed to be an error and ++ * the device is ignored. ++ */ ++int ++scsih_slave_configure_mpt2sas(struct scsi_device *sdev) ++{ ++ struct Scsi_Host *shost = sdev->host; ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ int qdepth; ++ u8 ssp_target = 0; ++ char *ds = ""; ++ char *r_level = ""; ++ u16 handle, volume_handle = 0; ++ u64 volume_wwid = 0; ++ ++ qdepth = 1; ++ sas_device_priv_data = sdev->hostdata; ++ sas_device_priv_data->configured_lun = 1; ++ sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT; ++ sas_target_priv_data = sas_device_priv_data->sas_target; ++ handle = sas_target_priv_data->handle; ++ ++ /* raid volume handling */ ++ if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) { ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ if (!raid_device) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, ++ __LINE__, __func__)); ++ return 1; ++ } ++ ++ if (_scsih_get_volume_capabilities(ioc, raid_device)) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, ++ __LINE__, __func__)); ++ return 1; ++ } ++ ++ /* ++ * WARPDRIVE: Initialize the required data for Direct IO ++ */ ++ mpt2sas_init_warpdrive_properties(ioc, raid_device); ++ ++ /* RAID Queue Depth Support ++ * IS volume = underlying qdepth of drive type, either ++ * MPT3SAS_SAS_QUEUE_DEPTH or MPT3SAS_SATA_QUEUE_DEPTH ++ * IM/IME/R10 = 128 (MPT3SAS_RAID_QUEUE_DEPTH) ++ */ ++ if (raid_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SSP_TARGET) { ++ qdepth = MPT3SAS_SAS_QUEUE_DEPTH; ++ ds = "SSP"; ++ } else { ++ qdepth = MPT3SAS_SATA_QUEUE_DEPTH; ++ if (raid_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ ds = "SATA"; ++ else ++ ds = "STP"; ++ } ++ ++ switch (raid_device->volume_type) { ++ case MPI2_RAID_VOL_TYPE_RAID0: ++ r_level = "RAID0"; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1E: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ if (ioc->manu_pg10.OEMIdentifier && ++ (le32_to_cpu(ioc->manu_pg10.GenericFlags0) & ++ MFG10_GF0_R10_DISPLAY) && ++ !(raid_device->num_pds % 2)) ++ r_level = "RAID10"; ++ else ++ r_level = "RAID1E"; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ r_level = "RAID1"; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID10: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ r_level = "RAID10"; ++ break; ++ case MPI2_RAID_VOL_TYPE_UNKNOWN: ++ default: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ r_level = "RAIDX"; ++ break; ++ } ++ ++ if (!ioc->hide_ir_msg) ++ sdev_printk(KERN_INFO, sdev, ++ "%s: handle(0x%04x), wwid(0x%016llx)," ++ " pd_count(%d), type(%s)\n", ++ r_level, raid_device->handle, ++ (unsigned long long)raid_device->wwid, ++ raid_device->num_pds, ds); ++ ++ if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) { ++ blk_queue_max_hw_sectors(sdev->request_queue, ++ MPT3SAS_RAID_MAX_SECTORS); ++ sdev_printk(KERN_INFO, sdev, ++ "Set queue's max_sector to: %u\n", ++ MPT3SAS_RAID_MAX_SECTORS); ++ } ++ ++ scsih_change_queue_depth_mpt2sas(sdev, qdepth, SCSI_QDEPTH_DEFAULT); ++ ++ /* raid transport support */ ++ if (!ioc->is_warpdrive) ++ _scsih_set_level(ioc, sdev, raid_device->volume_type); ++ return 0; ++ } ++ ++ /* non-raid handling */ ++ if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ if (mpt2sas_config_get_volume_handle(ioc, handle, ++ &volume_handle)) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__)); ++ return 1; ++ } ++ if (volume_handle && mpt2sas_config_get_volume_wwid(ioc, ++ volume_handle, &volume_wwid)) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__)); ++ return 1; ++ } ++ } ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_device_priv_data->sas_target->sas_address); ++ if (!sas_device) { ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ return 1; ++ } ++ ++ sas_device->volume_handle = volume_handle; ++ sas_device->volume_wwid = volume_wwid; ++ if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { ++ qdepth = MPT3SAS_SAS_QUEUE_DEPTH; ++ ssp_target = 1; ++ if (sas_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SEP) { ++ sdev_printk(KERN_WARNING, sdev, ++ "set ignore_delay_remove for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle); ++ sas_device_priv_data->ignore_delay_remove = 1; ++ ds = "SES"; ++ } else ++ ds = "SSP"; ++ } else { ++ qdepth = MPT3SAS_SATA_QUEUE_DEPTH; ++ if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) ++ ds = "STP"; ++ else if (sas_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ ds = "SATA"; ++ } ++ ++ sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " \ ++ "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", ++ ds, handle, (unsigned long long)sas_device->sas_address, ++ sas_device->phy, (unsigned long long)sas_device->device_name); ++ if (sas_device->enclosure_handle != 0) ++ sdev_printk(KERN_INFO, sdev, ++ "%s: enclosure_logical_id(0x%016llx), slot(%d)\n", ++ ds, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ sdev_printk(KERN_INFO, sdev, ++ "%s: enclosure level(0x%04x), connector name( %s)\n", ++ ds, sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ sas_device_put(sas_device); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (!ssp_target) ++ _scsih_display_sata_capabilities(ioc, handle, sdev); ++ ++ ++ scsih_change_queue_depth_mpt2sas(sdev, qdepth, SCSI_QDEPTH_DEFAULT); ++ ++ if (ssp_target) { ++ sas_read_port_mode_page(sdev); ++ _scsih_enable_tlr(ioc, sdev); ++ } ++ ++ return 0; ++} ++ ++/** ++ * scsih_bios_param_mpt2sas - fetch head, sector, cylinder info for a disk ++ * @sdev: scsi device struct ++ * @bdev: pointer to block device context ++ * @capacity: device size (in 512 byte sectors) ++ * @params: three element array to place output: ++ * params[0] number of heads (max 255) ++ * params[1] number of sectors (max 63) ++ * params[2] number of cylinders ++ * ++ * Return nothing. ++ */ ++int ++scsih_bios_param_mpt2sas(struct scsi_device *sdev, struct block_device *bdev, ++ sector_t capacity, int params[]) ++{ ++ int heads; ++ int sectors; ++ sector_t cylinders; ++ ulong dummy; ++ ++ heads = 64; ++ sectors = 32; ++ ++ dummy = heads * sectors; ++ cylinders = capacity; ++ sector_div(cylinders, dummy); ++ ++ /* ++ * Handle extended translation size for logical drives ++ * > 1Gb ++ */ ++ if ((ulong)capacity >= 0x200000) { ++ heads = 255; ++ sectors = 63; ++ dummy = heads * sectors; ++ cylinders = capacity; ++ sector_div(cylinders, dummy); ++ } ++ ++ /* return result */ ++ params[0] = heads; ++ params[1] = sectors; ++ params[2] = cylinders; ++ ++ return 0; ++} ++ ++/** ++ * _scsih_response_code - translation of device response code ++ * @ioc: per adapter object ++ * @response_code: response code returned by the device ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_response_code(struct MPT3SAS_ADAPTER *ioc, u8 response_code) ++{ ++ char *desc; ++ ++ switch (response_code) { ++ case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE: ++ desc = "task management request completed"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME: ++ desc = "invalid frame"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED: ++ desc = "task management request not supported"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_FAILED: ++ desc = "task management request failed"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED: ++ desc = "task management request succeeded"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN: ++ desc = "invalid lun"; ++ break; ++ case 0xA: ++ desc = "overlapped tag attempted"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC: ++ desc = "task queued, however not sent to target"; ++ break; ++ default: ++ desc = "unknown"; ++ break; ++ } ++ pr_warn(MPT3SAS_FMT "response_code(0x%01x): %s\n", ++ ioc->name, response_code, desc); ++} ++ ++/** ++ * _scsih_tm_done - tm completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: none. ++ * ++ * The callback handler when using scsih_issue_tm. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ if (ioc->tm_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->tm_cmds.smid != smid) ++ return 1; ++ ioc->tm_cmds.status |= MPT3_CMD_COMPLETE; ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) { ++ memcpy(ioc->tm_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ ioc->tm_cmds.status |= MPT3_CMD_REPLY_VALID; ++ } ++ ioc->tm_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->tm_cmds.done); ++ return 1; ++} ++ ++/** ++ * mpt2sas_scsih_set_tm_flag - set per target tm_busy ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During taskmangement request, we need to freeze the device queue. ++ */ ++void ++mpt2sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ u8 skip = 0; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ if (skip) ++ continue; ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->handle == handle) { ++ sas_device_priv_data->sas_target->tm_busy = 1; ++ skip = 1; ++ ioc->ignore_loginfos = 1; ++ } ++ } ++} ++ ++/** ++ * mpt2sas_scsih_clear_tm_flag - clear per target tm_busy ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During taskmangement request, we need to freeze the device queue. ++ */ ++void ++mpt2sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ u8 skip = 0; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ if (skip) ++ continue; ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->handle == handle) { ++ sas_device_priv_data->sas_target->tm_busy = 0; ++ skip = 1; ++ ioc->ignore_loginfos = 0; ++ } ++ } ++} ++ ++/** ++ * mpt2sas_scsih_issue_tm - main routine for sending tm requests ++ * @ioc: per adapter struct ++ * @device_handle: device handle ++ * @channel: the channel assigned by the OS ++ * @id: the id assigned by the OS ++ * @lun: lun number ++ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) ++ * @smid_task: smid assigned to the task ++ * @timeout: timeout in seconds ++ * @m_type: TM_MUTEX_ON or TM_MUTEX_OFF ++ * Context: user ++ * ++ * A generic API for sending task management requests to firmware. ++ * ++ * The callback index is set inside `ioc->tm_cb_idx`. ++ * ++ * Return SUCCESS or FAILED. ++ */ ++int ++mpt2sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ++ uint id, uint lun, u8 type, u16 smid_task, ulong timeout, ++ enum mutex_type m_type) ++{ ++ Mpi2SCSITaskManagementRequest_t *mpi_request; ++ Mpi2SCSITaskManagementReply_t *mpi_reply; ++ u16 smid = 0; ++ u32 ioc_state; ++ unsigned long timeleft; ++ struct scsiio_tracker *scsi_lookup = NULL; ++ int rc; ++ u16 msix_task = 0; ++ ++ if (m_type == TM_MUTEX_ON) ++ mutex_lock(&ioc->tm_cmds.mutex); ++ if (ioc->tm_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_info(MPT3SAS_FMT "%s: tm_cmd busy!!!\n", ++ __func__, ioc->name); ++ rc = FAILED; ++ goto err_out; ++ } ++ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ rc = FAILED; ++ goto err_out; ++ } ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ if (ioc_state & MPI2_DOORBELL_USED) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "unexpected doorbell active!\n", ioc->name)); ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = (!rc) ? SUCCESS : FAILED; ++ goto err_out; ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc, ioc_state & ++ MPI2_DOORBELL_DATA_MASK); ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = (!rc) ? SUCCESS : FAILED; ++ goto err_out; ++ } ++ ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = FAILED; ++ goto err_out; ++ } ++ ++ if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) ++ scsi_lookup = &ioc->scsi_lookup[smid_task - 1]; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "sending tm: handle(0x%04x), task_type(0x%02x), smid(%d)\n", ++ ioc->name, handle, type, smid_task)); ++ ioc->tm_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->tm_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); ++ memset(ioc->tm_cmds.reply, 0, sizeof(Mpi2SCSITaskManagementReply_t)); ++ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->TaskType = type; ++ mpi_request->TaskMID = cpu_to_le16(smid_task); ++ int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); ++ mpt2sas_scsih_set_tm_flag(ioc, handle); ++ init_completion(&ioc->tm_cmds.done); ++ if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) && ++ (scsi_lookup->msix_io < ioc->reply_queue_count)) ++ msix_task = scsi_lookup->msix_io; ++ else ++ msix_task = 0; ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, msix_task); ++ timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); ++ if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SCSITaskManagementRequest_t)/4); ++ if (!(ioc->tm_cmds.status & MPT3_CMD_RESET)) { ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = (!rc) ? SUCCESS : FAILED; ++ ioc->tm_cmds.status = MPT3_CMD_NOT_USED; ++ mpt2sas_scsih_clear_tm_flag(ioc, handle); ++ goto err_out; ++ } ++ } ++ ++ /* sync IRQs in case those were busy during flush. */ ++ mpt2sas_base_sync_reply_irqs(ioc); ++ ++ if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); ++ mpi_reply = ioc->tm_cmds.reply; ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "complete tm: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x), term_count(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo), ++ le32_to_cpu(mpi_reply->TerminationCount))); ++ if (ioc->logging_level & MPT_DEBUG_TM) { ++ _scsih_response_code(ioc, mpi_reply->ResponseCode); ++ if (mpi_reply->IOCStatus) ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SCSITaskManagementRequest_t)/4); ++ } ++ } ++ ++ switch (type) { ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: ++ rc = SUCCESS; ++ if (scsi_lookup->scmd == NULL) ++ break; ++ rc = FAILED; ++ break; ++ ++ case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: ++ if (_scsih_scsi_lookup_find_by_target(ioc, id, channel)) ++ rc = FAILED; ++ else ++ rc = SUCCESS; ++ break; ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: ++ case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: ++ if (_scsih_scsi_lookup_find_by_lun(ioc, id, lun, channel)) ++ rc = FAILED; ++ else ++ rc = SUCCESS; ++ break; ++ case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: ++ rc = SUCCESS; ++ break; ++ default: ++ rc = FAILED; ++ break; ++ } ++ ++ mpt2sas_scsih_clear_tm_flag(ioc, handle); ++ ioc->tm_cmds.status = MPT3_CMD_NOT_USED; ++ if (m_type == TM_MUTEX_ON) ++ mutex_unlock(&ioc->tm_cmds.mutex); ++ ++ return rc; ++ ++ err_out: ++ if (m_type == TM_MUTEX_ON) ++ mutex_unlock(&ioc->tm_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _scsih_tm_display_info - displays info about the device ++ * @ioc: per adapter struct ++ * @scmd: pointer to scsi command object ++ * ++ * Called by task management callback handlers. ++ */ ++static void ++_scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) ++{ ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *priv_target = starget->hostdata; ++ struct _sas_device *sas_device = NULL; ++ unsigned long flags; ++ char *device_str = NULL; ++ ++ if (!priv_target) ++ return; ++ if (ioc->hide_ir_msg) ++ device_str = "WarpDrive"; ++ else ++ device_str = "volume"; ++ ++ scsi_print_command(scmd); ++ if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { ++ starget_printk(KERN_INFO, starget, ++ "%s handle(0x%04x), %s wwid(0x%016llx)\n", ++ device_str, priv_target->handle, ++ device_str, (unsigned long long)priv_target->sas_address); ++ } else { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, priv_target); ++ if (sas_device) { ++ if (priv_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ starget_printk(KERN_INFO, starget, ++ "volume handle(0x%04x), " ++ "volume wwid(0x%016llx)\n", ++ sas_device->volume_handle, ++ (unsigned long long)sas_device->volume_wwid); ++ } ++ starget_printk(KERN_INFO, starget, ++ "handle(0x%04x), sas_address(0x%016llx), phy(%d)\n", ++ sas_device->handle, ++ (unsigned long long)sas_device->sas_address, ++ sas_device->phy); ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, ++ "enclosure_logical_id(0x%016llx), slot(%d)\n", ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ starget_printk(KERN_INFO, starget, ++ "enclosure level(0x%04x),connector name(%s)\n", ++ sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++} ++ ++/** ++ * scsih_abort_mpt2sas - eh threads main abort routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_abort_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ u16 smid; ++ u16 handle; ++ int r; ++ ++ sdev_printk(KERN_INFO, scmd->device, ++ "attempting task abort! scmd(%p)\n", scmd); ++ _scsih_tm_display_info(ioc, scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ sdev_printk(KERN_INFO, scmd->device, ++ "device been deleted! scmd(%p)\n", scmd); ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* search for the command */ ++ smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd); ++ if (!smid) { ++ scmd->result = DID_RESET << 16; ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* for hidden raid components and volumes this is not supported */ ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT || ++ sas_device_priv_data->sas_target->flags & MPT_TARGET_FLAGS_VOLUME) { ++ scmd->result = DID_RESET << 16; ++ r = FAILED; ++ goto out; ++ } ++ ++ mpt2sas_halt_firmware(ioc); ++ ++ handle = sas_device_priv_data->sas_target->handle; ++ r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, scmd->device->lun, ++ MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON); ++ ++ out: ++ sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n", ++ ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ return r; ++} ++ ++/** ++ * scsih_dev_reset_mpt2sas - eh threads main device reset routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_dev_reset_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct _sas_device *sas_device = NULL; ++ u16 handle; ++ int r; ++ ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; ++ ++ sdev_printk(KERN_INFO, scmd->device, ++ "attempting device reset! scmd(%p)\n", scmd); ++ _scsih_tm_display_info(ioc, scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ sdev_printk(KERN_INFO, scmd->device, ++ "device been deleted! scmd(%p)\n", scmd); ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* for hidden raid components obtain the volume_handle */ ++ handle = 0; ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ sas_device = mpt2sas_get_sdev_from_target(ioc, ++ target_priv_data); ++ if (sas_device) ++ handle = sas_device->volume_handle; ++ } else ++ handle = sas_device_priv_data->sas_target->handle; ++ ++ if (!handle) { ++ scmd->result = DID_RESET << 16; ++ r = FAILED; ++ goto out; ++ } ++ ++ r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, scmd->device->lun, ++ MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON); ++ ++ out: ++ sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", ++ ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ return r; ++} ++ ++/** ++ * scsih_target_reset_mpt2sas - eh threads main target reset routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_target_reset_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct _sas_device *sas_device = NULL; ++ u16 handle; ++ int r; ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; ++ ++ starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n", ++ scmd); ++ _scsih_tm_display_info(ioc, scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", ++ scmd); ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* for hidden raid components obtain the volume_handle */ ++ handle = 0; ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ sas_device = mpt2sas_get_sdev_from_target(ioc, ++ target_priv_data); ++ if (sas_device) ++ handle = sas_device->volume_handle; ++ } else ++ handle = sas_device_priv_data->sas_target->handle; ++ ++ if (!handle) { ++ scmd->result = DID_RESET << 16; ++ r = FAILED; ++ goto out; ++ } ++ ++ r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, ++ 30, TM_MUTEX_ON); ++ ++ out: ++ starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", ++ ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ return r; ++} ++ ++ ++/** ++ * scsih_host_reset_mpt2sas - eh threads main host reset routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_host_reset_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ int r, retval; ++ ++ pr_info(MPT3SAS_FMT "attempting host reset! scmd(%p)\n", ++ ioc->name, scmd); ++ scsi_print_command(scmd); ++ ++ if (ioc->is_driver_loading) { ++ pr_info(MPT3SAS_FMT "Blocking the host reset\n", ++ ioc->name); ++ r = FAILED; ++ goto out; ++ } ++ ++ retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ r = (retval < 0) ? FAILED : SUCCESS; ++out: ++ pr_info(MPT3SAS_FMT "host reset: %s scmd(%p)\n", ++ ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ ++ return r; ++} ++ ++/** ++ * _scsih_fw_event_add - insert and queue up fw_event ++ * @ioc: per adapter object ++ * @fw_event: object describing the event ++ * Context: This function will acquire ioc->fw_event_lock. ++ * ++ * This adds the firmware event object into link list, then queues it up to ++ * be processed from user context. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_fw_event_add(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) ++{ ++ unsigned long flags; ++ ++ if (ioc->firmware_event_thread == NULL) ++ return; ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ fw_event_work_get(fw_event); ++ INIT_LIST_HEAD(&fw_event->list); ++ list_add_tail(&fw_event->list, &ioc->fw_event_list); ++ INIT_WORK(&fw_event->work, _firmware_event_work); ++ fw_event_work_get(fw_event); ++ queue_work(ioc->firmware_event_thread, &fw_event->work); ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++} ++ ++/** ++ * _scsih_fw_event_del_from_list - delete fw_event from the list ++ * @ioc: per adapter object ++ * @fw_event: object describing the event ++ * Context: This function will acquire ioc->fw_event_lock. ++ * ++ * If the fw_event is on the fw_event_list, remove it and do a put. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_fw_event_del_from_list(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work ++ *fw_event) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ if (!list_empty(&fw_event->list)) { ++ list_del_init(&fw_event->list); ++ fw_event_work_put(fw_event); ++ } ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++} ++ ++ ++ /** ++ * mpt2sas_send_trigger_data_event - send event for processing trigger data ++ * @ioc: per adapter object ++ * @event_data: trigger event data ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) ++{ ++ struct fw_event_work *fw_event; ++ u16 sz; ++ ++ if (ioc->is_driver_loading) ++ return; ++ sz = sizeof(*event_data); ++ fw_event = alloc_fw_event_work(sz); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG; ++ fw_event->ioc = ioc; ++ memcpy(fw_event->event_data, event_data, sizeof(*event_data)); ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * _scsih_error_recovery_delete_devices - remove devices not responding ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_error_recovery_delete_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct fw_event_work *fw_event; ++ ++ if (ioc->is_driver_loading) ++ return; ++ fw_event = alloc_fw_event_work(0); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * mpt2sas_port_enable_complete - port enable completed (fake event) ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = alloc_fw_event_work(0); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned long flags; ++ struct fw_event_work *fw_event = NULL; ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ if (!list_empty(&ioc->fw_event_list)) { ++ fw_event = list_first_entry(&ioc->fw_event_list, ++ struct fw_event_work, list); ++ list_del_init(&fw_event->list); ++ } ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++ ++ return fw_event; ++} ++ ++/** ++ * _scsih_fw_event_cleanup_queue - cleanup event queue ++ * @ioc: per adapter object ++ * ++ * Walk the firmware event queue, either killing timers, or waiting ++ * for outstanding events to complete ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct fw_event_work *fw_event; ++ ++ if (list_empty(&ioc->fw_event_list) || ++ !ioc->firmware_event_thread || in_interrupt()) ++ return; ++ ++ while ((fw_event = dequeue_next_fw_event(ioc))) { ++ /* ++ * Wait on the fw_event to complete. If this returns 1, then ++ * the event was never executed, and we need a put for the ++ * reference the work had on the fw_event. ++ * ++ * If it did execute, we wait for it to finish, and the put will ++ * happen from _firmware_event_work() ++ */ ++ if (cancel_work_sync(&fw_event->work)) ++ fw_event_work_put(fw_event); ++ ++ fw_event_work_put(fw_event); ++ } ++} ++ ++/** ++ * _scsih_internal_device_block - block the sdev device ++ * @sdev: per device object ++ * @sas_device_priv_data : per device driver private data ++ * ++ * make sure device is blocked without error, if not ++ * print an error ++ */ ++static void ++_scsih_internal_device_block(struct scsi_device *sdev, ++ struct MPT3SAS_DEVICE *sas_device_priv_data) ++{ ++ int r = 0; ++ ++ sdev_printk(KERN_INFO, sdev, "device_block, handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle); ++ sas_device_priv_data->block = 1; ++ ++ r = scsi_internal_device_block(sdev); ++ if (r == -EINVAL) ++ sdev_printk(KERN_WARNING, sdev, ++ "device_block failed with return(%d) for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle, r); ++} ++ ++/** ++ * _scsih_internal_device_unblock - unblock the sdev device ++ * @sdev: per device object ++ * @sas_device_priv_data : per device driver private data ++ * make sure device is unblocked without error, if not retry ++ * by blocking and then unblocking ++ */ ++ ++static void ++_scsih_internal_device_unblock(struct scsi_device *sdev, ++ struct MPT3SAS_DEVICE *sas_device_priv_data) ++{ ++ int r = 0; ++ ++ sdev_printk(KERN_WARNING, sdev, "device_unblock and setting to running, " ++ "handle(0x%04x)\n", sas_device_priv_data->sas_target->handle); ++ sas_device_priv_data->block = 0; ++ r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); ++ if (r == -EINVAL) { ++ /* The device has been set to SDEV_RUNNING by SD layer during ++ * device addition but the request queue is still stopped by ++ * our earlier block call. We need to perform a block again ++ * to get the device to SDEV_BLOCK and then to SDEV_RUNNING */ ++ ++ sdev_printk(KERN_WARNING, sdev, ++ "device_unblock failed with return(%d) for handle(0x%04x) " ++ "performing a block followed by an unblock\n", ++ sas_device_priv_data->sas_target->handle, r); ++ sas_device_priv_data->block = 1; ++ r = scsi_internal_device_block(sdev); ++ if (r) ++ sdev_printk(KERN_WARNING, sdev, "retried device_block " ++ "failed with return(%d) for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle, r); ++ ++ sas_device_priv_data->block = 0; ++ r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); ++ if (r) ++ sdev_printk(KERN_WARNING, sdev, "retried device_unblock" ++ " failed with return(%d) for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle, r); ++ } ++} ++ ++/** ++ * _scsih_ublock_io_all_device - unblock every device ++ * @ioc: per adapter object ++ * ++ * change the device state from block to running ++ */ ++static void ++_scsih_ublock_io_all_device(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (!sas_device_priv_data->block) ++ continue; ++ ++ dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, ++ "device_running, handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle)); ++ _scsih_internal_device_unblock(sdev, sas_device_priv_data); ++ } ++} ++ ++ ++/** ++ * _scsih_ublock_io_device - prepare device to be deleted ++ * @ioc: per adapter object ++ * @sas_addr: sas address ++ * ++ * unblock then put device in offline state ++ */ ++static void ++_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->sas_address ++ != sas_address) ++ continue; ++ if (sas_device_priv_data->block) ++ _scsih_internal_device_unblock(sdev, ++ sas_device_priv_data); ++ } ++} ++ ++/** ++ * _scsih_block_io_all_device - set the device state to SDEV_BLOCK ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During device pull we need to appropiately set the sdev state. ++ */ ++static void ++_scsih_block_io_all_device(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->block) ++ continue; ++ if (sas_device_priv_data->ignore_delay_remove) { ++ sdev_printk(KERN_INFO, sdev, ++ "%s skip device_block for SES handle(0x%04x)\n", ++ __func__, sas_device_priv_data->sas_target->handle); ++ continue; ++ } ++ _scsih_internal_device_block(sdev, sas_device_priv_data); ++ } ++} ++ ++/** ++ * _scsih_block_io_device - set the device state to SDEV_BLOCK ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During device pull we need to appropiately set the sdev state. ++ */ ++static void ++_scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ struct _sas_device *sas_device; ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (!sas_device) ++ return; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->handle != handle) ++ continue; ++ if (sas_device_priv_data->block) ++ continue; ++ if (sas_device->pend_sas_rphy_add) ++ continue; ++ if (sas_device_priv_data->ignore_delay_remove) { ++ sdev_printk(KERN_INFO, sdev, ++ "%s skip device_block for SES handle(0x%04x)\n", ++ __func__, sas_device_priv_data->sas_target->handle); ++ continue; ++ } ++ _scsih_internal_device_block(sdev, sas_device_priv_data); ++ } ++ ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_block_io_to_children_attached_to_ex ++ * @ioc: per adapter object ++ * @sas_expander: the sas_device object ++ * ++ * This routine set sdev state to SDEV_BLOCK for all devices ++ * attached to this expander. This function called when expander is ++ * pulled. ++ */ ++static void ++_scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander) ++{ ++ struct _sas_port *mpt2sas_port; ++ struct _sas_device *sas_device; ++ struct _sas_node *expander_sibling; ++ unsigned long flags; ++ ++ if (!sas_expander) ++ return; ++ ++ list_for_each_entry(mpt2sas_port, ++ &sas_expander->sas_port_list, port_list) { ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_END_DEVICE) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ if (sas_device) { ++ set_bit(sas_device->handle, ++ ioc->blocking_handles); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ } ++ ++ list_for_each_entry(mpt2sas_port, ++ &sas_expander->sas_port_list, port_list) { ++ ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_EDGE_EXPANDER_DEVICE || ++ mpt2sas_port->remote_identify.device_type == ++ SAS_FANOUT_EXPANDER_DEVICE) { ++ expander_sibling = ++ mpt2sas_scsih_expander_find_by_sas_address( ++ ioc, mpt2sas_port->remote_identify.sas_address); ++ _scsih_block_io_to_children_attached_to_ex(ioc, ++ expander_sibling); ++ } ++ } ++} ++ ++/** ++ * _scsih_block_io_to_children_attached_directly ++ * @ioc: per adapter object ++ * @event_data: topology change event data ++ * ++ * This routine set sdev state to SDEV_BLOCK for all devices ++ * direct attached during device pull. ++ */ ++static void ++_scsih_block_io_to_children_attached_directly(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasTopologyChangeList_t *event_data) ++{ ++ int i; ++ u16 handle; ++ u16 reason_code; ++ ++ for (i = 0; i < event_data->NumEntries; i++) { ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) ++ _scsih_block_io_device(ioc, handle); ++ } ++} ++ ++/** ++ * _scsih_tm_tr_send - send task management request ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt time. ++ * ++ * This code is to initiate the device removal handshake protocol ++ * with controller firmware. This function will issue target reset ++ * using high priority request queue. It will send a sas iounit ++ * control request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. ++ * ++ * This is designed to send muliple task management request at the same ++ * time to the fifo. If the fifo is full, we will append the request, ++ * and process it in a future completion. ++ */ ++static void ++_scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ Mpi2SCSITaskManagementRequest_t *mpi_request; ++ u16 smid; ++ struct _sas_device *sas_device = NULL; ++ struct MPT3SAS_TARGET *sas_target_priv_data = NULL; ++ u64 sas_address = 0; ++ unsigned long flags; ++ struct _tr_list *delayed_tr; ++ u32 ioc_state; ++ ++ if (ioc->remove_host) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host has been removed: handle(0x%04x)\n", ++ __func__, ioc->name, handle)); ++ return; ++ } else if (ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host in pci error recovery: handle(0x%04x)\n", ++ __func__, ioc->name, ++ handle)); ++ return; ++ } ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host is not operational: handle(0x%04x)\n", ++ __func__, ioc->name, ++ handle)); ++ return; ++ } ++ ++ /* if PD, then return */ ++ if (test_bit(handle, ioc->pd_handles)) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device && sas_device->starget && ++ sas_device->starget->hostdata) { ++ sas_target_priv_data = sas_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ sas_address = sas_device->sas_address; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (sas_target_priv_data) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, handle, ++ (unsigned long long)sas_address)); ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag:enclosure logical id(0x%016llx)," ++ " slot(%d)\n", ioc->name, (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot)); ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag: enclosure level(0x%04x)," ++ " connector name( %s)\n", ioc->name, ++ sas_device->enclosure_level, ++ sas_device->connector_name)); ++ _scsih_ublock_io_device(ioc, sas_address); ++ sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; ++ } ++ ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); ++ if (!smid) { ++ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); ++ if (!delayed_tr) ++ goto out; ++ INIT_LIST_HEAD(&delayed_tr->list); ++ delayed_tr->handle = handle; ++ list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:tr:handle(0x%04x), (open)\n", ++ ioc->name, handle)); ++ goto out; ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, handle, smid, ++ ioc->tm_tr_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, 0); ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); ++ ++out: ++ if (sas_device) ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_tm_tr_complete - ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt time. ++ * ++ * This is the target reset completion routine. ++ * This code is part of the code to initiate the device removal ++ * handshake protocol with controller firmware. ++ * It will send a sas iounit control request (MPI2_SAS_OP_REMOVE_DEVICE) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ u16 handle; ++ Mpi2SCSITaskManagementRequest_t *mpi_request_tm; ++ Mpi2SCSITaskManagementReply_t *mpi_reply = ++ mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ Mpi2SasIoUnitControlRequest_t *mpi_request; ++ u16 smid_sas_ctrl; ++ u32 ioc_state; ++ struct _sc_list *delayed_sc; ++ ++ if (ioc->remove_host) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host has been removed\n", __func__, ioc->name)); ++ return 1; ++ } else if (ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host in pci error recovery\n", __func__, ++ ioc->name)); ++ return 1; ++ } ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host is not operational\n", __func__, ioc->name)); ++ return 1; ++ } ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); ++ handle = le16_to_cpu(mpi_request_tm->DevHandle); ++ if (handle != le16_to_cpu(mpi_reply->DevHandle)) { ++ dewtprintk(ioc, pr_err(MPT3SAS_FMT ++ "spurious interrupt: handle(0x%04x:0x%04x), smid(%d)!!!\n", ++ ioc->name, handle, ++ le16_to_cpu(mpi_reply->DevHandle), smid)); ++ return 0; ++ } ++ ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), " ++ "loginfo(0x%08x), completed(%d)\n", ioc->name, ++ handle, smid, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo), ++ le32_to_cpu(mpi_reply->TerminationCount))); ++ ++ smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); ++ if (!smid_sas_ctrl) { ++ delayed_sc = kzalloc(sizeof(*delayed_sc), GFP_ATOMIC); ++ if (!delayed_sc) ++ return _scsih_check_for_pending_tm(ioc, smid); ++ INIT_LIST_HEAD(&delayed_sc->list); ++ delayed_sc->handle = mpi_request_tm->DevHandle; ++ list_add_tail(&delayed_sc->list, &ioc->delayed_sc_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:sc:handle(0x%04x), (open)\n", ++ ioc->name, handle)); ++ return _scsih_check_for_pending_tm(ioc, smid); ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, handle, smid_sas_ctrl, ++ ioc->tm_sas_control_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); ++ memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; ++ mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; ++ mpi_request->DevHandle = mpi_request_tm->DevHandle; ++ mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); ++ ++ return _scsih_check_for_pending_tm(ioc, smid); ++} ++ ++ ++/** ++ * _scsih_sas_control_complete - completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt time. ++ * ++ * This is the sas iounit control completion routine. ++ * This code is part of the code to initiate the device removal ++ * handshake protocol with controller firmware. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_sas_control_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u8 msix_index, u32 reply) ++{ ++ Mpi2SasIoUnitControlReply_t *mpi_reply = ++ mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ ++ if (likely(mpi_reply)) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "sc_complete:handle(0x%04x), (open) " ++ "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid, ++ le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo))); ++ } else { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ } ++ return mpt2sas_check_for_pending_internal_cmds(ioc, smid); ++} ++ ++/** ++ * _scsih_tm_tr_volume_send - send target reset request for volumes ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt time. ++ * ++ * This is designed to send muliple task management request at the same ++ * time to the fifo. If the fifo is full, we will append the request, ++ * and process it in a future completion. ++ */ ++static void ++_scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ Mpi2SCSITaskManagementRequest_t *mpi_request; ++ u16 smid; ++ struct _tr_list *delayed_tr; ++ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host reset in progress!\n", ++ __func__, ioc->name)); ++ return; ++ } ++ ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx); ++ if (!smid) { ++ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); ++ if (!delayed_tr) ++ return; ++ INIT_LIST_HEAD(&delayed_tr->list); ++ delayed_tr->handle = handle; ++ list_add_tail(&delayed_tr->list, &ioc->delayed_tr_volume_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:tr:handle(0x%04x), (open)\n", ++ ioc->name, handle)); ++ return; ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, handle, smid, ++ ioc->tm_tr_volume_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, 0); ++} ++ ++/** ++ * _scsih_tm_volume_tr_complete - target reset completion ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt time. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u8 msix_index, u32 reply) ++{ ++ u16 handle; ++ Mpi2SCSITaskManagementRequest_t *mpi_request_tm; ++ Mpi2SCSITaskManagementReply_t *mpi_reply = ++ mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host reset in progress!\n", ++ __func__, ioc->name)); ++ return 1; ++ } ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ ++ mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); ++ handle = le16_to_cpu(mpi_request_tm->DevHandle); ++ if (handle != le16_to_cpu(mpi_reply->DevHandle)) { ++ dewtprintk(ioc, pr_err(MPT3SAS_FMT ++ "spurious interrupt: handle(0x%04x:0x%04x), smid(%d)!!!\n", ++ ioc->name, handle, ++ le16_to_cpu(mpi_reply->DevHandle), smid)); ++ return 0; ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), " ++ "loginfo(0x%08x), completed(%d)\n", ioc->name, ++ handle, smid, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo), ++ le32_to_cpu(mpi_reply->TerminationCount))); ++ ++ return _scsih_check_for_pending_tm(ioc, smid); ++} ++ ++/** ++ * _scsih_issue_delayed_event_ack_mpt2sas - issue delayed Event ACK messages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @event: Event ID ++ * @event_context: used to track events uniquely ++ * ++ * Context - processed in interrupt context. ++ */ ++void ++_scsih_issue_delayed_event_ack_mpt2sas(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event, ++ u32 event_context) ++{ ++ Mpi2EventAckRequest_t *ack_request; ++ int i = smid - ioc->internal_smid; ++ unsigned long flags; ++ ++ /* Without releasing the smid just update the ++ * call back index and reuse the same smid for ++ * processing this delayed request ++ */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ ioc->internal_lookup[i].cb_idx = ioc->base_cb_idx; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "EVENT ACK: event(0x%04x), smid(%d), cb(%d)\n", ++ ioc->name, le16_to_cpu(event), smid, ++ ioc->base_cb_idx)); ++ ack_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t)); ++ ack_request->Function = MPI2_FUNCTION_EVENT_ACK; ++ ack_request->Event = event; ++ ack_request->EventContext = event_context; ++ ack_request->VF_ID = 0; /* TODO */ ++ ack_request->VP_ID = 0; ++ mpt2sas_base_put_smid_default(ioc, smid); ++} ++ ++/** ++ * _scsih_issue_delayed_sas_io_unit_ctrl_mpt2sas - issue delayed ++ * sas_io_unit_ctrl messages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle ++ * ++ * Context - processed in interrupt context. ++ */ ++void ++_scsih_issue_delayed_sas_io_unit_ctrl_mpt2sas(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid, u16 handle) ++ { ++ Mpi2SasIoUnitControlRequest_t *mpi_request; ++ u32 ioc_state; ++ int i = smid - ioc->internal_smid; ++ unsigned long flags; ++ ++ if (ioc->remove_host) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host has been removed\n", ++ __func__, ioc->name)); ++ return; ++ } else if (ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host in pci error recovery\n", ++ __func__, ioc->name)); ++ return; ++ } ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host is not operational\n", ++ __func__, ioc->name)); ++ return; ++ } ++ ++ /* Without releasing the smid just update the ++ * call back index and reuse the same smid for ++ * processing this delayed request ++ */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ ioc->internal_lookup[i].cb_idx = ioc->tm_sas_control_cb_idx; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, le16_to_cpu(handle), smid, ++ ioc->tm_sas_control_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; ++ mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; ++ mpi_request->DevHandle = handle; ++ mpt2sas_base_put_smid_default(ioc, smid); ++} ++ ++/** ++ * _scsih_check_for_pending_internal_cmds - check for pending internal messages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Context: Executed in interrupt context ++ * ++ * This will check delayed internal messages list, and process the ++ * next request. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ struct _sc_list *delayed_sc; ++ struct _event_ack_list *delayed_event_ack; ++ ++ if (!list_empty(&ioc->delayed_event_ack_list)) { ++ delayed_event_ack = list_entry(ioc->delayed_event_ack_list.next, ++ struct _event_ack_list, list); ++ _scsih_issue_delayed_event_ack_mpt2sas(ioc, smid, ++ delayed_event_ack->Event, delayed_event_ack->EventContext); ++ list_del(&delayed_event_ack->list); ++ kfree(delayed_event_ack); ++ return 0; ++ } ++ ++ if (!list_empty(&ioc->delayed_sc_list)) { ++ delayed_sc = list_entry(ioc->delayed_sc_list.next, ++ struct _sc_list, list); ++ _scsih_issue_delayed_sas_io_unit_ctrl_mpt2sas(ioc, smid, ++ delayed_sc->handle); ++ list_del(&delayed_sc->list); ++ kfree(delayed_sc); ++ return 0; ++ } ++ return 1; ++} ++ ++/** ++ * _scsih_check_for_pending_tm - check for pending task management ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * This will check delayed target reset list, and feed the ++ * next reqeust. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ struct _tr_list *delayed_tr; ++ ++ if (!list_empty(&ioc->delayed_tr_volume_list)) { ++ delayed_tr = list_entry(ioc->delayed_tr_volume_list.next, ++ struct _tr_list, list); ++ mpt2sas_base_free_smid(ioc, smid); ++ _scsih_tm_tr_volume_send(ioc, delayed_tr->handle); ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ return 0; ++ } ++ ++ if (!list_empty(&ioc->delayed_tr_list)) { ++ delayed_tr = list_entry(ioc->delayed_tr_list.next, ++ struct _tr_list, list); ++ mpt2sas_base_free_smid(ioc, smid); ++ _scsih_tm_tr_send(ioc, delayed_tr->handle); ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/** ++ * _scsih_check_topo_delete_events - sanity check on topo events ++ * @ioc: per adapter object ++ * @event_data: the event data payload ++ * ++ * This routine added to better handle cable breaker. ++ * ++ * This handles the case where driver receives multiple expander ++ * add and delete events in a single shot. When there is a delete event ++ * the routine will void any pending add events waiting in the event queue. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_check_topo_delete_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasTopologyChangeList_t *event_data) ++{ ++ struct fw_event_work *fw_event; ++ Mpi2EventDataSasTopologyChangeList_t *local_event_data; ++ u16 expander_handle; ++ struct _sas_node *sas_expander; ++ unsigned long flags; ++ int i, reason_code; ++ u16 handle; ++ ++ for (i = 0 ; i < event_data->NumEntries; i++) { ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING) ++ _scsih_tm_tr_send(ioc, handle); ++ } ++ ++ expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); ++ if (expander_handle < ioc->sas_hba.num_phys) { ++ _scsih_block_io_to_children_attached_directly(ioc, event_data); ++ return; ++ } ++ if (event_data->ExpStatus == ++ MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING) { ++ /* put expander attached devices into blocking state */ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, ++ expander_handle); ++ _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ do { ++ handle = find_first_bit(ioc->blocking_handles, ++ ioc->facts.MaxDevHandle); ++ if (handle < ioc->facts.MaxDevHandle) ++ _scsih_block_io_device(ioc, handle); ++ } while (test_and_clear_bit(handle, ioc->blocking_handles)); ++ } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING) ++ _scsih_block_io_to_children_attached_directly(ioc, event_data); ++ ++ if (event_data->ExpStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) ++ return; ++ ++ /* mark ignore flag for pending events */ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ list_for_each_entry(fw_event, &ioc->fw_event_list, list) { ++ if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || ++ fw_event->ignore) ++ continue; ++ local_event_data = (Mpi2EventDataSasTopologyChangeList_t *) ++ fw_event->event_data; ++ if (local_event_data->ExpStatus == ++ MPI2_EVENT_SAS_TOPO_ES_ADDED || ++ local_event_data->ExpStatus == ++ MPI2_EVENT_SAS_TOPO_ES_RESPONDING) { ++ if (le16_to_cpu(local_event_data->ExpanderDevHandle) == ++ expander_handle) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting ignoring flag\n", ioc->name)); ++ fw_event->ignore = 1; ++ } ++ } ++ } ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++} ++ ++/** ++ * _scsih_set_volume_delete_flag - setting volume delete flag ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * This returns nothing. ++ */ ++static void ++_scsih_set_volume_delete_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _raid_device *raid_device; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device && raid_device->starget && ++ raid_device->starget->hostdata) { ++ sas_target_priv_data = ++ raid_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag: handle(0x%04x), " ++ "wwid(0x%016llx)\n", ioc->name, handle, ++ (unsigned long long) raid_device->wwid)); ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * _scsih_set_volume_handle_for_tr - set handle for target reset to volume ++ * @handle: input handle ++ * @a: handle for volume a ++ * @b: handle for volume b ++ * ++ * IR firmware only supports two raid volumes. The purpose of this ++ * routine is to set the volume handle in either a or b. When the given ++ * input handle is non-zero, or when a and b have not been set before. ++ */ ++static void ++_scsih_set_volume_handle_for_tr(u16 handle, u16 *a, u16 *b) ++{ ++ if (!handle || handle == *a || handle == *b) ++ return; ++ if (!*a) ++ *a = handle; ++ else if (!*b) ++ *b = handle; ++} ++ ++/** ++ * _scsih_check_ir_config_unhide_events - check for UNHIDE events ++ * @ioc: per adapter object ++ * @event_data: the event data payload ++ * Context: interrupt time. ++ * ++ * This routine will send target reset to volume, followed by target ++ * resets to the PDs. This is called when a PD has been removed, or ++ * volume has been deleted or removed. When the target reset is sent ++ * to volume, the PD target resets need to be queued to start upon ++ * completion of the volume target reset. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrConfigChangeList_t *event_data) ++{ ++ Mpi2EventIrConfigElement_t *element; ++ int i; ++ u16 handle, volume_handle, a, b; ++ struct _tr_list *delayed_tr; ++ ++ a = 0; ++ b = 0; ++ ++ if (ioc->is_warpdrive) ++ return; ++ ++ /* Volume Resets for Deleted or Removed */ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ++ continue; ++ if (element->ReasonCode == ++ MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED || ++ element->ReasonCode == ++ MPI2_EVENT_IR_CHANGE_RC_REMOVED) { ++ volume_handle = le16_to_cpu(element->VolDevHandle); ++ _scsih_set_volume_delete_flag(ioc, volume_handle); ++ _scsih_set_volume_handle_for_tr(volume_handle, &a, &b); ++ } ++ } ++ ++ /* Volume Resets for UNHIDE events */ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ++ continue; ++ if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_UNHIDE) { ++ volume_handle = le16_to_cpu(element->VolDevHandle); ++ _scsih_set_volume_handle_for_tr(volume_handle, &a, &b); ++ } ++ } ++ ++ if (a) ++ _scsih_tm_tr_volume_send(ioc, a); ++ if (b) ++ _scsih_tm_tr_volume_send(ioc, b); ++ ++ /* PD target resets */ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_UNHIDE) ++ continue; ++ handle = le16_to_cpu(element->PhysDiskDevHandle); ++ volume_handle = le16_to_cpu(element->VolDevHandle); ++ clear_bit(handle, ioc->pd_handles); ++ if (!volume_handle) ++ _scsih_tm_tr_send(ioc, handle); ++ else if (volume_handle == a || volume_handle == b) { ++ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); ++ BUG_ON(!delayed_tr); ++ INIT_LIST_HEAD(&delayed_tr->list); ++ delayed_tr->handle = handle; ++ list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:tr:handle(0x%04x), (open)\n", ioc->name, ++ handle)); ++ } else ++ _scsih_tm_tr_send(ioc, handle); ++ } ++} ++ ++ ++/** ++ * _scsih_check_volume_delete_events - set delete flag for volumes ++ * @ioc: per adapter object ++ * @event_data: the event data payload ++ * Context: interrupt time. ++ * ++ * This will handle the case when the cable connected to entire volume is ++ * pulled. We will take care of setting the deleted flag so normal IO will ++ * not be sent. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_check_volume_delete_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrVolume_t *event_data) ++{ ++ u32 state; ++ ++ if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) ++ return; ++ state = le32_to_cpu(event_data->NewValue); ++ if (state == MPI2_RAID_VOL_STATE_MISSING || state == ++ MPI2_RAID_VOL_STATE_FAILED) ++ _scsih_set_volume_delete_flag(ioc, ++ le16_to_cpu(event_data->VolDevHandle)); ++} ++ ++/** ++ * _scsih_temp_threshold_events - display temperature threshold exceeded events ++ * @ioc: per adapter object ++ * @event_data: the temp threshold event data ++ * Context: interrupt time. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataTemperature_t *event_data) ++{ ++ if (ioc->temp_sensors_count >= event_data->SensorNum) { ++ pr_err(MPT3SAS_FMT "Temperature Threshold flags %s%s%s%s" ++ " exceeded for Sensor: %d !!!\n", ioc->name, ++ ((le16_to_cpu(event_data->Status) & 0x1) == 1) ? "0 " : " ", ++ ((le16_to_cpu(event_data->Status) & 0x2) == 2) ? "1 " : " ", ++ ((le16_to_cpu(event_data->Status) & 0x4) == 4) ? "2 " : " ", ++ ((le16_to_cpu(event_data->Status) & 0x8) == 8) ? "3 " : " ", ++ event_data->SensorNum); ++ pr_err(MPT3SAS_FMT "Current Temp In Celsius: %d\n", ++ ioc->name, event_data->CurrentTemperature); ++ } ++} ++ ++/** ++ * _scsih_flush_running_cmds - completing outstanding commands. ++ * @ioc: per adapter object ++ * ++ * The flushing out of all pending scmd commands following host reset, ++ * where all IO is dropped to the floor. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct scsi_cmnd *scmd; ++ u16 smid; ++ u16 count = 0; ++ ++ for (smid = 1; smid <= ioc->scsiio_depth; smid++) { ++ scmd = _scsih_scsi_lookup_get_clear(ioc, smid); ++ if (!scmd) ++ continue; ++ count++; ++ mpt2sas_base_free_smid(ioc, smid); ++ scsi_dma_unmap(scmd); ++ if (ioc->pci_error_recovery) ++ scmd->result = DID_NO_CONNECT << 16; ++ else ++ scmd->result = DID_RESET << 16; ++ scmd->scsi_done(scmd); ++ } ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "completing %d cmds\n", ++ ioc->name, count)); ++} ++ ++/** ++ * _scsih_setup_eedp - setup MPI request for EEDP transfer ++ * @ioc: per adapter object ++ * @scmd: pointer to scsi command object ++ * @mpi_request: pointer to the SCSI_IO reqest message frame ++ * ++ * Supporting protection 1 and 3. ++ * ++ * Returns nothing ++ */ ++static void ++_scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ Mpi2SCSIIORequest_t *mpi_request) ++{ ++ u16 eedp_flags; ++ unsigned char prot_op = scsi_get_prot_op(scmd); ++ unsigned char prot_type = scsi_get_prot_type(scmd); ++ Mpi25SCSIIORequest_t *mpi_request_3v = ++ (Mpi25SCSIIORequest_t *)mpi_request; ++ ++ if (prot_type == SCSI_PROT_DIF_TYPE0 || prot_op == SCSI_PROT_NORMAL) ++ return; ++ ++ if (prot_op == SCSI_PROT_READ_STRIP) ++ eedp_flags = MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP; ++ else if (prot_op == SCSI_PROT_WRITE_INSERT) ++ eedp_flags = MPI2_SCSIIO_EEDPFLAGS_INSERT_OP; ++ else ++ return; ++ ++ switch (prot_type) { ++ case SCSI_PROT_DIF_TYPE1: ++ case SCSI_PROT_DIF_TYPE2: ++ ++ /* ++ * enable ref/guard checking ++ * auto increment ref tag ++ */ ++ eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | ++ MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | ++ MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; ++ mpi_request->CDB.EEDP32.PrimaryReferenceTag = ++ cpu_to_be32(scsi_get_lba(scmd)); ++ break; ++ ++ case SCSI_PROT_DIF_TYPE3: ++ ++ /* ++ * enable guard checking ++ */ ++ eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; ++ ++ break; ++ } ++ ++ mpi_request_3v->EEDPBlockSize = ++ cpu_to_le16(scmd->device->sector_size); ++ mpi_request->EEDPFlags = cpu_to_le16(eedp_flags); ++} ++ ++/** ++ * _scsih_eedp_error_handling - return sense code for EEDP errors ++ * @scmd: pointer to scsi command object ++ * @ioc_status: ioc status ++ * ++ * Returns nothing ++ */ ++static void ++_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) ++{ ++ u8 ascq; ++ ++ switch (ioc_status) { ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ ascq = 0x01; ++ break; ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ ascq = 0x02; ++ break; ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ ascq = 0x03; ++ break; ++ default: ++ ascq = 0x00; ++ break; ++ } ++ scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x10, ++ ascq); ++ scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) | ++ SAM_STAT_CHECK_CONDITION; ++} ++ ++ ++ ++/** ++ * scsih_qcmd_mpt2sas - main scsi request entry point ++ * @scmd: pointer to scsi command object ++ * @done: function pointer to be invoked on completion ++ * ++ * The callback index is set inside `ioc->scsi_io_cb_idx`. ++ * ++ * Returns 0 on success. If there's a failure, return either: ++ * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or ++ * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full ++ */ ++int ++scsih_qcmd_mpt2sas(struct Scsi_Host *shost, struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _raid_device *raid_device; ++ Mpi2SCSIIORequest_t *mpi_request; ++ u32 mpi_control; ++ u16 smid; ++ u16 handle; ++ ++ if (ioc->logging_level & MPT_DEBUG_SCSI) ++ scsi_print_command(scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ ++ if (ioc->pci_error_recovery || ioc->remove_host) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ ++ sas_target_priv_data = sas_device_priv_data->sas_target; ++ ++ /* invalid device handle */ ++ handle = sas_target_priv_data->handle; ++ if (handle == MPT3SAS_INVALID_DEVICE_HANDLE) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ ++ ++ /* host recovery or link resets sent via IOCTLs */ ++ if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ ++ /* device has been deleted */ ++ else if (sas_target_priv_data->deleted) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ /* device busy with task managment */ ++ } else if (sas_target_priv_data->tm_busy || ++ sas_device_priv_data->block) ++ return SCSI_MLQUEUE_DEVICE_BUSY; ++ ++ if (scmd->sc_data_direction == DMA_FROM_DEVICE) ++ mpi_control = MPI2_SCSIIO_CONTROL_READ; ++ else if (scmd->sc_data_direction == DMA_TO_DEVICE) ++ mpi_control = MPI2_SCSIIO_CONTROL_WRITE; ++ else ++ mpi_control = MPI2_SCSIIO_CONTROL_NODATATRANSFER; ++ ++ /* set tags */ ++ if (!(sas_device_priv_data->flags & MPT_DEVICE_FLAGS_INIT)) { ++ if (scmd->device->tagged_supported) { ++ if (scmd->device->ordered_tags) ++ mpi_control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; ++ else ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; ++ } else ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; ++ } else ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; ++ ++ /* Make sure Device is not raid volume. ++ * We do not expose raid functionality to upper layer for warpdrive. ++ */ ++ if (!ioc->is_warpdrive && !scsih_is_raid_mpt2sas(&scmd->device->sdev_gendev) ++ && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) ++ mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; ++ ++ smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ goto out; ++ } ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t)); ++ _scsih_setup_eedp(ioc, scmd, mpi_request); ++ ++ if (scmd->cmd_len == 32) ++ mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT; ++ mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) ++ mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; ++ else ++ mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); ++ mpi_request->Control = cpu_to_le32(mpi_control); ++ mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len); ++ mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; ++ mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; ++ mpi_request->SenseBufferLowAddress = ++ mpt2sas_base_get_sense_buffer_dma(ioc, smid); ++ mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; ++ int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *) ++ mpi_request->LUN); ++ memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); ++ ++ if (mpi_request->DataLength) { ++ if (ioc->build_sg_scmd(ioc, scmd, smid)) { ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } else ++ ioc->build_zero_len_sge(ioc, &mpi_request->SGL); ++ ++ raid_device = sas_target_priv_data->raid_device; ++ if (raid_device && raid_device->direct_io_enabled) ++ mpt2sas_setup_direct_io(ioc, scmd, raid_device, mpi_request, ++ smid); ++ ++ if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) { ++ if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { ++ mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | ++ MPI25_SCSIIO_IOFLAGS_FAST_PATH); ++ mpt2sas_base_put_smid_fast_path(ioc, smid, handle); ++ } else ++ mpt2sas_base_put_smid_scsi_io(ioc, smid, ++ le16_to_cpu(mpi_request->DevHandle)); ++ } else ++ mpt2sas_base_put_smid_default(ioc, smid); ++ return 0; ++ ++ out: ++ return SCSI_MLQUEUE_HOST_BUSY; ++} ++ ++/** ++ * _scsih_normalize_sense - normalize descriptor and fixed format sense data ++ * @sense_buffer: sense data returned by target ++ * @data: normalized skey/asc/ascq ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_normalize_sense(char *sense_buffer, struct sense_info *data) ++{ ++ if ((sense_buffer[0] & 0x7F) >= 0x72) { ++ /* descriptor format */ ++ data->skey = sense_buffer[1] & 0x0F; ++ data->asc = sense_buffer[2]; ++ data->ascq = sense_buffer[3]; ++ } else { ++ /* fixed format */ ++ data->skey = sense_buffer[2] & 0x0F; ++ data->asc = sense_buffer[12]; ++ data->ascq = sense_buffer[13]; ++ } ++} ++ ++/** ++ * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request ++ * @ioc: per adapter object ++ * @scmd: pointer to scsi command object ++ * @mpi_reply: reply mf payload returned from firmware ++ * ++ * scsi_status - SCSI Status code returned from target device ++ * scsi_state - state info associated with SCSI_IO determined by ioc ++ * ioc_status - ioc supplied status info ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ Mpi2SCSIIOReply_t *mpi_reply, u16 smid) ++{ ++ u32 response_info; ++ u8 *response_bytes; ++ u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ u8 scsi_state = mpi_reply->SCSIState; ++ u8 scsi_status = mpi_reply->SCSIStatus; ++ char *desc_ioc_state = NULL; ++ char *desc_scsi_status = NULL; ++ char *desc_scsi_state = ioc->tmp_string; ++ u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); ++ struct _sas_device *sas_device = NULL; ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *priv_target = starget->hostdata; ++ char *device_str = NULL; ++ ++ if (!priv_target) ++ return; ++ if (ioc->hide_ir_msg) ++ device_str = "WarpDrive"; ++ else ++ device_str = "volume"; ++ ++ if (log_info == 0x31170000) ++ return; ++ ++ switch (ioc_status) { ++ case MPI2_IOCSTATUS_SUCCESS: ++ desc_ioc_state = "success"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_FUNCTION: ++ desc_ioc_state = "invalid function"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: ++ desc_ioc_state = "scsi recovered error"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE: ++ desc_ioc_state = "scsi invalid dev handle"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: ++ desc_ioc_state = "scsi device not there"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: ++ desc_ioc_state = "scsi data overrun"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: ++ desc_ioc_state = "scsi data underrun"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: ++ desc_ioc_state = "scsi io data error"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: ++ desc_ioc_state = "scsi protocol error"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: ++ desc_ioc_state = "scsi task terminated"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: ++ desc_ioc_state = "scsi residual mismatch"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED: ++ desc_ioc_state = "scsi task mgmt failed"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: ++ desc_ioc_state = "scsi ioc terminated"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: ++ desc_ioc_state = "scsi ext terminated"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ desc_ioc_state = "eedp guard error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ desc_ioc_state = "eedp ref tag error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ desc_ioc_state = "eedp app tag error"; ++ break; ++ case MPI2_IOCSTATUS_INSUFFICIENT_POWER: ++ desc_ioc_state = "insufficient power"; ++ break; ++ default: ++ desc_ioc_state = "unknown"; ++ break; ++ } ++ ++ switch (scsi_status) { ++ case MPI2_SCSI_STATUS_GOOD: ++ desc_scsi_status = "good"; ++ break; ++ case MPI2_SCSI_STATUS_CHECK_CONDITION: ++ desc_scsi_status = "check condition"; ++ break; ++ case MPI2_SCSI_STATUS_CONDITION_MET: ++ desc_scsi_status = "condition met"; ++ break; ++ case MPI2_SCSI_STATUS_BUSY: ++ desc_scsi_status = "busy"; ++ break; ++ case MPI2_SCSI_STATUS_INTERMEDIATE: ++ desc_scsi_status = "intermediate"; ++ break; ++ case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET: ++ desc_scsi_status = "intermediate condmet"; ++ break; ++ case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: ++ desc_scsi_status = "reservation conflict"; ++ break; ++ case MPI2_SCSI_STATUS_COMMAND_TERMINATED: ++ desc_scsi_status = "command terminated"; ++ break; ++ case MPI2_SCSI_STATUS_TASK_SET_FULL: ++ desc_scsi_status = "task set full"; ++ break; ++ case MPI2_SCSI_STATUS_ACA_ACTIVE: ++ desc_scsi_status = "aca active"; ++ break; ++ case MPI2_SCSI_STATUS_TASK_ABORTED: ++ desc_scsi_status = "task aborted"; ++ break; ++ default: ++ desc_scsi_status = "unknown"; ++ break; ++ } ++ ++ desc_scsi_state[0] = '\0'; ++ if (!scsi_state) ++ desc_scsi_state = " "; ++ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) ++ strcat(desc_scsi_state, "response info "); ++ if (scsi_state & MPI2_SCSI_STATE_TERMINATED) ++ strcat(desc_scsi_state, "state terminated "); ++ if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) ++ strcat(desc_scsi_state, "no status "); ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED) ++ strcat(desc_scsi_state, "autosense failed "); ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) ++ strcat(desc_scsi_state, "autosense valid "); ++ ++ scsi_print_command(scmd); ++ ++ if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { ++ pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name, ++ device_str, (unsigned long long)priv_target->sas_address); ++ } else { ++ sas_device = mpt2sas_get_sdev_from_target(ioc, priv_target); ++ if (sas_device) { ++ pr_warn(MPT3SAS_FMT ++ "\tsas_address(0x%016llx), phy(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->sas_address, sas_device->phy); ++ if (sas_device->enclosure_handle != 0) ++ pr_warn(MPT3SAS_FMT ++ "\tenclosure_logical_id(0x%016llx)," ++ "slot(%d)\n", ioc->name, ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0]) ++ pr_warn(MPT3SAS_FMT ++ "\tenclosure level(0x%04x)," ++ " connector name( %s)\n", ioc->name, ++ sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ sas_device_put(sas_device); ++ } ++ } ++ ++ pr_warn(MPT3SAS_FMT ++ "\thandle(0x%04x), ioc_status(%s)(0x%04x), smid(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->DevHandle), ++ desc_ioc_state, ioc_status, smid); ++ pr_warn(MPT3SAS_FMT ++ "\trequest_len(%d), underflow(%d), resid(%d)\n", ++ ioc->name, scsi_bufflen(scmd), scmd->underflow, ++ scsi_get_resid(scmd)); ++ pr_warn(MPT3SAS_FMT ++ "\ttag(%d), transfer_count(%d), sc->result(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->TaskTag), ++ le32_to_cpu(mpi_reply->TransferCount), scmd->result); ++ pr_warn(MPT3SAS_FMT ++ "\tscsi_status(%s)(0x%02x), scsi_state(%s)(0x%02x)\n", ++ ioc->name, desc_scsi_status, ++ scsi_status, desc_scsi_state, scsi_state); ++ ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { ++ struct sense_info data; ++ _scsih_normalize_sense(scmd->sense_buffer, &data); ++ pr_warn(MPT3SAS_FMT ++ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n", ++ ioc->name, data.skey, ++ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount)); ++ } ++ ++ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { ++ response_info = le32_to_cpu(mpi_reply->ResponseInfo); ++ response_bytes = (u8 *)&response_info; ++ _scsih_response_code(ioc, response_bytes[0]); ++ } ++} ++ ++/** ++ * _scsih_turn_on_pfa_led - illuminate PFA LED ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: process ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ Mpi2SepReply_t mpi_reply; ++ Mpi2SepRequest_t mpi_request; ++ struct _sas_device *sas_device; ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (!sas_device) ++ return; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; ++ mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; ++ mpi_request.SlotStatus = ++ cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); ++ mpi_request.DevHandle = cpu_to_le16(handle); ++ mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; ++ if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, ++ &mpi_request)) != 0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ sas_device->pfa_led_on = 1; ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo))); ++ goto out; ++ } ++out: ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_turn_off_pfa_led - turn off Fault LED ++ * @ioc: per adapter object ++ * @sas_device: sas device whose PFA LED has to turned off ++ * Context: process ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_turn_off_pfa_led(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ Mpi2SepReply_t mpi_reply; ++ Mpi2SepRequest_t mpi_request; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; ++ mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; ++ mpi_request.SlotStatus = 0; ++ mpi_request.Slot = cpu_to_le16(sas_device->slot); ++ mpi_request.DevHandle = 0; ++ mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle); ++ mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; ++ if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, ++ &mpi_request)) != 0) { ++ printk(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { ++ dewtprintk(ioc, printk(MPT3SAS_FMT ++ "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo))); ++ return; ++ } ++} ++ ++/** ++ * _scsih_send_event_to_turn_on_pfa_led - fire delayed event ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = alloc_fw_event_work(0); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_TURN_ON_PFA_LED; ++ fw_event->device_handle = handle; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * _scsih_smart_predicted_fault - process smart errors ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct scsi_target *starget; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ Mpi2EventNotificationReply_t *event_reply; ++ Mpi2EventDataSasDeviceStatusChange_t *event_data; ++ struct _sas_device *sas_device; ++ ssize_t sz; ++ unsigned long flags; ++ ++ /* only handle non-raid devices */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (!sas_device) ++ goto out_unlock; ++ ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ ++ if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) || ++ ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) ++ goto out_unlock; ++ ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, "predicted fault, " ++ "enclosure logical id(0x%016llx), slot(%d)\n", ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ starget_printk(KERN_WARNING, starget, "predicted fault, " ++ "enclosure level(0x%04x), connector name( %s)\n", ++ sas_device->enclosure_level, ++ sas_device->connector_name); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) ++ _scsih_send_event_to_turn_on_pfa_led(ioc, handle); ++ ++ /* insert into event log */ ++ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + ++ sizeof(Mpi2EventDataSasDeviceStatusChange_t); ++ event_reply = kzalloc(sz, GFP_KERNEL); ++ if (!event_reply) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; ++ event_reply->Event = ++ cpu_to_le16(MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE); ++ event_reply->MsgLength = sz/4; ++ event_reply->EventDataLength = ++ cpu_to_le16(sizeof(Mpi2EventDataSasDeviceStatusChange_t)/4); ++ event_data = (Mpi2EventDataSasDeviceStatusChange_t *) ++ event_reply->EventData; ++ event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA; ++ event_data->ASC = 0x5D; ++ event_data->DevHandle = cpu_to_le16(handle); ++ event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); ++ mpt2sas_ctl_add_to_event_log(ioc, event_reply); ++ kfree(event_reply); ++out: ++ if (sas_device) ++ sas_device_put(sas_device); ++ return; ++ ++out_unlock: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ goto out; ++} ++ ++/** ++ * _scsih_io_done - scsi request callback ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Callback handler when using _scsih_qcmd_mpt2sas. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ++{ ++ Mpi2SCSIIORequest_t *mpi_request; ++ Mpi2SCSIIOReply_t *mpi_reply; ++ struct scsi_cmnd *scmd; ++ u16 ioc_status; ++ u32 xfer_cnt; ++ u8 scsi_state; ++ u8 scsi_status; ++ u32 log_info; ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ u32 response_code = 0; ++ unsigned long flags; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ scmd = _scsih_scsi_lookup_get_clear(ioc, smid); ++ if (scmd == NULL) ++ return 1; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ++ if (mpi_reply == NULL) { ++ scmd->result = DID_OK << 16; ++ goto out; ++ } ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target || ++ sas_device_priv_data->sas_target->deleted) { ++ scmd->result = DID_NO_CONNECT << 16; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus); ++ ++ /* ++ * WARPDRIVE: If direct_io is set then it is directIO, ++ * the failed direct I/O should be redirected to volume ++ */ ++ if (mpt2sas_scsi_direct_io_get(ioc, smid) && ++ ((ioc_status & MPI2_IOCSTATUS_MASK) ++ != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) { ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ ioc->scsi_lookup[smid - 1].scmd = scmd; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ mpt2sas_scsi_direct_io_set(ioc, smid, 0); ++ memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); ++ mpi_request->DevHandle = ++ cpu_to_le16(sas_device_priv_data->sas_target->handle); ++ mpt2sas_base_put_smid_scsi_io(ioc, smid, ++ sas_device_priv_data->sas_target->handle); ++ return 0; ++ } ++ /* turning off TLR */ ++ scsi_state = mpi_reply->SCSIState; ++ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) ++ response_code = ++ le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; ++ if (!sas_device_priv_data->tlr_snoop_check) { ++ sas_device_priv_data->tlr_snoop_check++; ++ if (!ioc->is_warpdrive && ++ !scsih_is_raid_mpt2sas(&scmd->device->sdev_gendev) && ++ sas_is_tlr_enabled(scmd->device) && ++ response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { ++ sas_disable_tlr(scmd->device); ++ sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); ++ } ++ } ++ ++ xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); ++ scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt); ++ if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) ++ log_info = le32_to_cpu(mpi_reply->IOCLogInfo); ++ else ++ log_info = 0; ++ ioc_status &= MPI2_IOCSTATUS_MASK; ++ scsi_status = mpi_reply->SCSIStatus; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && ++ (scsi_status == MPI2_SCSI_STATUS_BUSY || ++ scsi_status == MPI2_SCSI_STATUS_RESERVATION_CONFLICT || ++ scsi_status == MPI2_SCSI_STATUS_TASK_SET_FULL)) { ++ ioc_status = MPI2_IOCSTATUS_SUCCESS; ++ } ++ ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { ++ struct sense_info data; ++ const void *sense_data = mpt2sas_base_get_sense_buffer(ioc, ++ smid); ++ u32 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE, ++ le32_to_cpu(mpi_reply->SenseCount)); ++ memcpy(scmd->sense_buffer, sense_data, sz); ++ _scsih_normalize_sense(scmd->sense_buffer, &data); ++ /* failure prediction threshold exceeded */ ++ if (data.asc == 0x5D) ++ _scsih_smart_predicted_fault(ioc, ++ le16_to_cpu(mpi_reply->DevHandle)); ++ mpt2sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); ++ ++ if (!(ioc->logging_level & MPT_DEBUG_REPLY) && ++ ((scmd->sense_buffer[2] == UNIT_ATTENTION) || ++ (scmd->sense_buffer[2] == MEDIUM_ERROR) || ++ (scmd->sense_buffer[2] == HARDWARE_ERROR))) ++ _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid); ++ } ++ switch (ioc_status) { ++ case MPI2_IOCSTATUS_BUSY: ++ case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: ++ scmd->result = SAM_STAT_BUSY; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: ++ scmd->result = DID_NO_CONNECT << 16; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: ++ if (sas_device_priv_data->block) { ++ scmd->result = DID_TRANSPORT_DISRUPTED << 16; ++ goto out; ++ } ++ if (log_info == 0x31110630) { ++ if (scmd->retries > 2) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scsi_device_set_state(scmd->device, ++ SDEV_OFFLINE); ++ } else { ++ scmd->result = DID_SOFT_ERROR << 16; ++ scmd->device->expecting_cc_ua = 1; ++ } ++ break; ++ } else if (log_info == VIRTUAL_IO_FAILED_RETRY) { ++ scmd->result = DID_RESET << 16; ++ break; ++ } ++ scmd->result = DID_SOFT_ERROR << 16; ++ break; ++ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: ++ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: ++ scmd->result = DID_RESET << 16; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: ++ if ((xfer_cnt == 0) || (scmd->underflow > xfer_cnt)) ++ scmd->result = DID_SOFT_ERROR << 16; ++ else ++ scmd->result = (DID_OK << 16) | scsi_status; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: ++ scmd->result = (DID_OK << 16) | scsi_status; ++ ++ if ((scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)) ++ break; ++ ++ if (xfer_cnt < scmd->underflow) { ++ if (scsi_status == SAM_STAT_BUSY) ++ scmd->result = SAM_STAT_BUSY; ++ else ++ scmd->result = DID_SOFT_ERROR << 16; ++ } else if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | ++ MPI2_SCSI_STATE_NO_SCSI_STATUS)) ++ scmd->result = DID_SOFT_ERROR << 16; ++ else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) ++ scmd->result = DID_RESET << 16; ++ else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) { ++ mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID; ++ mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION; ++ scmd->result = (DRIVER_SENSE << 24) | ++ SAM_STAT_CHECK_CONDITION; ++ scmd->sense_buffer[0] = 0x70; ++ scmd->sense_buffer[2] = ILLEGAL_REQUEST; ++ scmd->sense_buffer[12] = 0x20; ++ scmd->sense_buffer[13] = 0; ++ } ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: ++ scsi_set_resid(scmd, 0); ++ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: ++ case MPI2_IOCSTATUS_SUCCESS: ++ scmd->result = (DID_OK << 16) | scsi_status; ++ if (response_code == ++ MPI2_SCSITASKMGMT_RSP_INVALID_FRAME || ++ (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | ++ MPI2_SCSI_STATE_NO_SCSI_STATUS))) ++ scmd->result = DID_SOFT_ERROR << 16; ++ else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) ++ scmd->result = DID_RESET << 16; ++ break; ++ ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ _scsih_eedp_error_handling(scmd, ioc_status); ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: ++ case MPI2_IOCSTATUS_INVALID_FUNCTION: ++ case MPI2_IOCSTATUS_INVALID_SGL: ++ case MPI2_IOCSTATUS_INTERNAL_ERROR: ++ case MPI2_IOCSTATUS_INVALID_FIELD: ++ case MPI2_IOCSTATUS_INVALID_STATE: ++ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: ++ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED: ++ case MPI2_IOCSTATUS_INSUFFICIENT_POWER: ++ default: ++ scmd->result = DID_SOFT_ERROR << 16; ++ break; ++ ++ } ++ ++ if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY)) ++ _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid); ++ ++ out: ++ ++ scsi_dma_unmap(scmd); ++ ++ scmd->scsi_done(scmd); ++ return 1; ++} ++ ++/** ++ * _scsih_sas_host_refresh - refreshing sas host object contents ++ * @ioc: per adapter object ++ * Context: user ++ * ++ * During port enable, fw will send topology events for every device. Its ++ * possible that the handles may change from the previous setting, so this ++ * code keeping handles updating if changed. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u16 sz; ++ u16 ioc_status; ++ int i; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ u16 attached_handle; ++ u8 link_rate; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "updating handles for sas_host(0x%016llx)\n", ++ ioc->name, (unsigned long long)ioc->sas_hba.sas_address)); ++ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys ++ * sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz)) != 0) ++ goto out; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ goto out; ++ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { ++ link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4; ++ if (i == 0) ++ ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> ++ PhyData[0].ControllerDevHandle); ++ ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; ++ attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. ++ AttachedDevHandle); ++ if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) ++ link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; ++ mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, ++ attached_handle, i, link_rate); ++ } ++ out: ++ kfree(sas_iounit_pg0); ++} ++ ++/** ++ * _scsih_sas_host_add - create sas host object ++ * @ioc: per adapter object ++ * ++ * Creating host side data object, stored in ioc->sas_hba ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int i; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2SasPhyPage0_t phy_pg0; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2SasEnclosurePage0_t enclosure_pg0; ++ u16 ioc_status; ++ u16 sz; ++ u8 device_missing_delay; ++ ++ mpt2sas_config_get_number_hba_phys(ioc, &ioc->sas_hba.num_phys); ++ if (!ioc->sas_hba.num_phys) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ /* sas_iounit page 0 */ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ /* sas_iounit page 1 */ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ ioc->io_missing_delay = ++ sas_iounit_pg1->IODeviceMissingDelay; ++ device_missing_delay = ++ sas_iounit_pg1->ReportDeviceMissingDelay; ++ if (device_missing_delay & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) ++ ioc->device_missing_delay = (device_missing_delay & ++ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; ++ else ++ ioc->device_missing_delay = device_missing_delay & ++ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; ++ ++ ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev; ++ ioc->sas_hba.phy = kcalloc(ioc->sas_hba.num_phys, ++ sizeof(struct _sas_phy), GFP_KERNEL); ++ if (!ioc->sas_hba.phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { ++ if ((mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, ++ i))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ if (i == 0) ++ ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> ++ PhyData[0].ControllerDevHandle); ++ ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; ++ ioc->sas_hba.phy[i].phy_id = i; ++ mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], ++ phy_pg0, ioc->sas_hba.parent_dev); ++ } ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc->sas_hba.enclosure_handle = ++ le16_to_cpu(sas_device_pg0.EnclosureHandle); ++ ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ pr_info(MPT3SAS_FMT ++ "host_add: handle(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ++ ioc->name, ioc->sas_hba.handle, ++ (unsigned long long) ioc->sas_hba.sas_address, ++ ioc->sas_hba.num_phys) ; ++ ++ if (ioc->sas_hba.enclosure_handle) { ++ if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, ++ &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ++ ioc->sas_hba.enclosure_handle))) ++ ioc->sas_hba.enclosure_logical_id = ++ le64_to_cpu(enclosure_pg0.EnclosureLogicalID); ++ } ++ ++ out: ++ kfree(sas_iounit_pg1); ++ kfree(sas_iounit_pg0); ++} ++ ++/** ++ * _scsih_expander_add - creating expander object ++ * @ioc: per adapter object ++ * @handle: expander handle ++ * ++ * Creating expander object, stored in ioc->sas_expander_list. ++ * ++ * Return 0 for success, else error. ++ */ ++static int ++_scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_node *sas_expander; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2ExpanderPage0_t expander_pg0; ++ Mpi2ExpanderPage1_t expander_pg1; ++ Mpi2SasEnclosurePage0_t enclosure_pg0; ++ u32 ioc_status; ++ u16 parent_handle; ++ u64 sas_address, sas_address_parent = 0; ++ int i; ++ unsigned long flags; ++ struct _sas_port *mpt2sas_port = NULL; ++ ++ int rc = 0; ++ ++ if (!handle) ++ return -1; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) ++ return -1; ++ ++ if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, ++ MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ /* handle out of order topology events */ ++ parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); ++ if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent) ++ != 0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ if (sas_address_parent != ioc->sas_hba.sas_address) { ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address_parent); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (!sas_expander) { ++ rc = _scsih_expander_add(ioc, parent_handle); ++ if (rc != 0) ++ return rc; ++ } ++ } ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_address = le64_to_cpu(expander_pg0.SASAddress); ++ sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (sas_expander) ++ return 0; ++ ++ sas_expander = kzalloc(sizeof(struct _sas_node), ++ GFP_KERNEL); ++ if (!sas_expander) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ sas_expander->handle = handle; ++ sas_expander->num_phys = expander_pg0.NumPhys; ++ sas_expander->sas_address_parent = sas_address_parent; ++ sas_expander->sas_address = sas_address; ++ ++ pr_info(MPT3SAS_FMT "expander_add: handle(0x%04x)," \ ++ " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, ++ handle, parent_handle, (unsigned long long) ++ sas_expander->sas_address, sas_expander->num_phys); ++ ++ if (!sas_expander->num_phys) ++ goto out_fail; ++ sas_expander->phy = kcalloc(sas_expander->num_phys, ++ sizeof(struct _sas_phy), GFP_KERNEL); ++ if (!sas_expander->phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ ++ INIT_LIST_HEAD(&sas_expander->sas_port_list); ++ mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, ++ sas_address_parent); ++ if (!mpt2sas_port) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ sas_expander->parent_dev = &mpt2sas_port->rphy->dev; ++ ++ for (i = 0 ; i < sas_expander->num_phys ; i++) { ++ if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply, ++ &expander_pg1, i, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ sas_expander->phy[i].handle = handle; ++ sas_expander->phy[i].phy_id = i; ++ ++ if ((mpt2sas_transport_add_expander_phy(ioc, ++ &sas_expander->phy[i], expander_pg1, ++ sas_expander->parent_dev))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ } ++ ++ if (sas_expander->enclosure_handle) { ++ if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, ++ &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ++ sas_expander->enclosure_handle))) ++ sas_expander->enclosure_logical_id = ++ le64_to_cpu(enclosure_pg0.EnclosureLogicalID); ++ } ++ ++ _scsih_expander_node_add(ioc, sas_expander); ++ return 0; ++ ++ out_fail: ++ ++ if (mpt2sas_port) ++ mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, ++ sas_address_parent); ++ kfree(sas_expander); ++ return rc; ++} ++ ++/** ++ * mpt2sas_expander_remove - removing expander object ++ * @ioc: per adapter object ++ * @sas_address: expander sas_address ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) ++{ ++ struct _sas_node *sas_expander; ++ unsigned long flags; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address); ++ if (sas_expander) ++ list_del(&sas_expander->list); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (sas_expander) ++ _scsih_expander_node_remove(ioc, sas_expander); ++} ++ ++/** ++ * _scsih_done - internal SCSI_IO callback handler. ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Callback handler when sending internal generated SCSI_IO. ++ * The callback index passed is `ioc->scsih_cb_idx` ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (ioc->scsih_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->scsih_cmds.smid != smid) ++ return 1; ++ ioc->scsih_cmds.status |= MPT3_CMD_COMPLETE; ++ if (mpi_reply) { ++ memcpy(ioc->scsih_cmds.reply, mpi_reply, ++ mpi_reply->MsgLength*4); ++ ioc->scsih_cmds.status |= MPT3_CMD_REPLY_VALID; ++ } ++ ioc->scsih_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->scsih_cmds.done); ++ return 1; ++} ++ ++ ++ ++ ++#define MPT3_MAX_LUNS (255) ++ ++ ++/** ++ * _scsih_check_access_status - check access flags ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * @handle: sas device handle ++ * @access_flags: errors returned during discovery of the device ++ * ++ * Return 0 for success, else failure ++ */ ++static u8 ++_scsih_check_access_status(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u16 handle, u8 access_status) ++{ ++ u8 rc = 1; ++ char *desc = NULL; ++ ++ switch (access_status) { ++ case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS: ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION: ++ rc = 0; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED: ++ desc = "sata capability failed"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT: ++ desc = "sata affiliation conflict"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE: ++ desc = "route not addressable"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE: ++ desc = "smp error not addressable"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED: ++ desc = "device blocked"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX: ++ desc = "sata initialization failed"; ++ break; ++ default: ++ desc = "unknown"; ++ break; ++ } ++ ++ if (!rc) ++ return 0; ++ ++ pr_err(MPT3SAS_FMT ++ "discovery errors(%s): sas_address(0x%016llx), handle(0x%04x)\n", ++ ioc->name, desc, (unsigned long long)sas_address, handle); ++ return rc; ++} ++ ++/** ++ * _scsih_check_device - checking device responsiveness ++ * @ioc: per adapter object ++ * @parent_sas_address: sas address of parent expander or sas host ++ * @handle: attached device handle ++ * @phy_numberv: phy number ++ * @link_rate: new link rate ++ * ++ * Returns nothing. ++ */ ++static void ++_scsih_check_device(struct MPT3SAS_ADAPTER *ioc, ++ u64 parent_sas_address, u16 handle, u8 phy_number, u8 link_rate) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ struct _sas_device *sas_device; ++ u32 ioc_status; ++ unsigned long flags; ++ u64 sas_address; ++ struct scsi_target *starget; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ u32 device_info; ++ ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) ++ return; ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ return; ++ ++ /* wide port handling ~ we need only handle device once for the phy that ++ * is matched in sas device page zero ++ */ ++ if (phy_number != sas_device_pg0.PhyNum) ++ return; ++ ++ /* check if this is end device */ ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ if (!(_scsih_is_end_device(device_info))) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ ++ if (!sas_device) ++ goto out_unlock; ++ ++ if (unlikely(sas_device->handle != handle)) { ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ starget_printk(KERN_INFO, starget, ++ "handle changed from(0x%04x) to (0x%04x)!!!\n", ++ sas_device->handle, handle); ++ sas_target_priv_data->handle = handle; ++ sas_device->handle = handle; ++ if (sas_device_pg0.Flags & ++ MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ le16_to_cpu(sas_device_pg0.EnclosureLevel); ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0.ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } ++ } ++ ++ /* check if device is present */ ++ if (!(le16_to_cpu(sas_device_pg0.Flags) & ++ MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { ++ pr_err(MPT3SAS_FMT ++ "device is not present handle(0x%04x), flags!!!\n", ++ ioc->name, handle); ++ goto out_unlock; ++ } ++ ++ /* check if there were any issues with discovery */ ++ if (_scsih_check_access_status(ioc, sas_address, handle, ++ sas_device_pg0.AccessStatus)) ++ goto out_unlock; ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ _scsih_ublock_io_device(ioc, sas_address); ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ return; ++ ++out_unlock: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (sas_device) ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_add_device - creating sas device object ++ * @ioc: per adapter object ++ * @handle: sas device handle ++ * @phy_num: phy number end device attached to ++ * @is_pd: is this hidden raid component ++ * ++ * Creating end device object, stored in ioc->sas_device_list. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, ++ u8 is_pd) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2SasEnclosurePage0_t enclosure_pg0; ++ struct _sas_device *sas_device; ++ u32 ioc_status; ++ u64 sas_address; ++ u32 device_info; ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ /* check if this is end device */ ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ if (!(_scsih_is_end_device(device_info))) ++ return -1; ++ sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ ++ /* check if device is present */ ++ if (!(le16_to_cpu(sas_device_pg0.Flags) & ++ MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { ++ pr_err(MPT3SAS_FMT "device is not present handle(0x04%x)!!!\n", ++ ioc->name, handle); ++ return -1; ++ } ++ ++ /* check if there were any issues with discovery */ ++ if (_scsih_check_access_status(ioc, sas_address, handle, ++ sas_device_pg0.AccessStatus)) ++ return -1; ++ ++ sas_device = mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ return -1; ++ } ++ ++ sas_device = kzalloc(sizeof(struct _sas_device), ++ GFP_KERNEL); ++ if (!sas_device) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 0; ++ } ++ ++ kref_init(&sas_device->refcount); ++ sas_device->handle = handle; ++ if (_scsih_get_sas_address(ioc, ++ le16_to_cpu(sas_device_pg0.ParentDevHandle), ++ &sas_device->sas_address_parent) != 0) ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_device->enclosure_handle = ++ le16_to_cpu(sas_device_pg0.EnclosureHandle); ++ if (sas_device->enclosure_handle != 0) ++ sas_device->slot = ++ le16_to_cpu(sas_device_pg0.Slot); ++ sas_device->device_info = device_info; ++ sas_device->sas_address = sas_address; ++ sas_device->phy = sas_device_pg0.PhyNum; ++ sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & ++ MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; ++ ++ if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ le16_to_cpu(sas_device_pg0.EnclosureLevel); ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0.ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } ++ /* get enclosure_logical_id */ ++ if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0( ++ ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ++ sas_device->enclosure_handle))) ++ sas_device->enclosure_logical_id = ++ le64_to_cpu(enclosure_pg0.EnclosureLogicalID); ++ ++ /* get device name */ ++ sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); ++ ++ if (ioc->wait_for_discovery_to_complete) ++ _scsih_sas_device_init_add(ioc, sas_device); ++ else ++ _scsih_sas_device_add(ioc, sas_device); ++ ++ sas_device_put(sas_device); ++ return 0; ++} ++ ++/** ++ * _scsih_remove_device - removing sas device object ++ * @ioc: per adapter object ++ * @sas_device_delete: the sas_device object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ ++ if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) && ++ (sas_device->pfa_led_on)) { ++ _scsih_turn_off_pfa_led(ioc, sas_device); ++ sas_device->pfa_led_on = 0; ++ } ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, __func__, ++ sas_device->handle, (unsigned long long) ++ sas_device->sas_address)); ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot)); ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter: enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, __func__, ++ sas_device->enclosure_level, ++ sas_device->connector_name)); ++ ++ if (sas_device->starget && sas_device->starget->hostdata) { ++ sas_target_priv_data = sas_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ _scsih_ublock_io_device(ioc, sas_device->sas_address); ++ sas_target_priv_data->handle = ++ MPT3SAS_INVALID_DEVICE_HANDLE; ++ } ++ ++ if (!ioc->hide_drives) ++ mpt2sas_transport_port_remove(ioc, ++ sas_device->sas_address, ++ sas_device->sas_address_parent); ++ ++ pr_info(MPT3SAS_FMT ++ "removing handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, sas_device->handle, ++ (unsigned long long) sas_device->sas_address); ++ if (sas_device->enclosure_handle != 0) ++ pr_info(MPT3SAS_FMT ++ "removing : enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ pr_info(MPT3SAS_FMT ++ "removing enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: exit: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, __func__, ++ sas_device->handle, (unsigned long long) ++ sas_device->sas_address)); ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: exit: enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot)); ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: exit: enclosure level(0x%04x), connector name(%s)\n", ++ ioc->name, __func__, sas_device->enclosure_level, ++ sas_device->connector_name)); ++} ++ ++/** ++ * _scsih_sas_topology_change_event_debug - debug for topology event ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ */ ++static void ++_scsih_sas_topology_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasTopologyChangeList_t *event_data) ++{ ++ int i; ++ u16 handle; ++ u16 reason_code; ++ u8 phy_number; ++ char *status_str = NULL; ++ u8 link_rate, prev_link_rate; ++ ++ switch (event_data->ExpStatus) { ++ case MPI2_EVENT_SAS_TOPO_ES_ADDED: ++ status_str = "add"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: ++ status_str = "remove"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: ++ case 0: ++ status_str = "responding"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: ++ status_str = "remove delay"; ++ break; ++ default: ++ status_str = "unknown status"; ++ break; ++ } ++ pr_info(MPT3SAS_FMT "sas topology change: (%s)\n", ++ ioc->name, status_str); ++ pr_info("\thandle(0x%04x), enclosure_handle(0x%04x) " \ ++ "start_phy(%02d), count(%d)\n", ++ le16_to_cpu(event_data->ExpanderDevHandle), ++ le16_to_cpu(event_data->EnclosureHandle), ++ event_data->StartPhyNum, event_data->NumEntries); ++ for (i = 0; i < event_data->NumEntries; i++) { ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ phy_number = event_data->StartPhyNum + i; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ switch (reason_code) { ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: ++ status_str = "target add"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: ++ status_str = "target remove"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: ++ status_str = "delay target remove"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: ++ status_str = "link rate change"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: ++ status_str = "target responding"; ++ break; ++ default: ++ status_str = "unknown"; ++ break; ++ } ++ link_rate = event_data->PHY[i].LinkRate >> 4; ++ prev_link_rate = event_data->PHY[i].LinkRate & 0xF; ++ pr_info("\tphy(%02d), attached_handle(0x%04x): %s:" \ ++ " link rate: new(0x%02x), old(0x%02x)\n", phy_number, ++ handle, status_str, link_rate, prev_link_rate); ++ ++ } ++} ++ ++/** ++ * _scsih_sas_topology_change_event - handle topology changes ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ */ ++static int ++_scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ int i; ++ u16 parent_handle, handle; ++ u16 reason_code; ++ u8 phy_number, max_phys; ++ struct _sas_node *sas_expander; ++ u64 sas_address; ++ unsigned long flags; ++ u8 link_rate, prev_link_rate; ++ Mpi2EventDataSasTopologyChangeList_t *event_data = ++ (Mpi2EventDataSasTopologyChangeList_t *) ++ fw_event->event_data; ++ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) ++ _scsih_sas_topology_change_event_debug(ioc, event_data); ++ ++ if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) ++ return 0; ++ ++ if (!ioc->sas_hba.num_phys) ++ _scsih_sas_host_add(ioc); ++ else ++ _scsih_sas_host_refresh(ioc); ++ ++ if (fw_event->ignore) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "ignoring expander event\n", ioc->name)); ++ return 0; ++ } ++ ++ parent_handle = le16_to_cpu(event_data->ExpanderDevHandle); ++ ++ /* handle expander add */ ++ if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) ++ if (_scsih_expander_add(ioc, parent_handle) != 0) ++ return 0; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, ++ parent_handle); ++ if (sas_expander) { ++ sas_address = sas_expander->sas_address; ++ max_phys = sas_expander->num_phys; ++ } else if (parent_handle < ioc->sas_hba.num_phys) { ++ sas_address = ioc->sas_hba.sas_address; ++ max_phys = ioc->sas_hba.num_phys; ++ } else { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* handle siblings events */ ++ for (i = 0; i < event_data->NumEntries; i++) { ++ if (fw_event->ignore) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "ignoring expander event\n", ioc->name)); ++ return 0; ++ } ++ if (ioc->remove_host || ioc->pci_error_recovery) ++ return 0; ++ phy_number = event_data->StartPhyNum + i; ++ if (phy_number >= max_phys) ++ continue; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ if ((event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code != ++ MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) ++ continue; ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ link_rate = event_data->PHY[i].LinkRate >> 4; ++ prev_link_rate = event_data->PHY[i].LinkRate & 0xF; ++ switch (reason_code) { ++ case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: ++ ++ if (ioc->shost_recovery) ++ break; ++ ++ if (link_rate == prev_link_rate) ++ break; ++ ++ mpt2sas_transport_update_links(ioc, sas_address, ++ handle, phy_number, link_rate); ++ ++ if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) ++ break; ++ ++ _scsih_check_device(ioc, sas_address, handle, ++ phy_number, link_rate); ++ ++ ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: ++ ++ if (ioc->shost_recovery) ++ break; ++ ++ mpt2sas_transport_update_links(ioc, sas_address, ++ handle, phy_number, link_rate); ++ ++ _scsih_add_device(ioc, handle, phy_number, 0); ++ ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: ++ ++ _scsih_device_remove_by_handle(ioc, handle); ++ break; ++ } ++ } ++ ++ /* handle expander removal */ ++ if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && ++ sas_expander) ++ mpt2sas_expander_remove(ioc, sas_address); ++ ++ return 0; ++} ++ ++/** ++ * _scsih_sas_device_status_change_event_debug - debug for device event ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasDeviceStatusChange_t *event_data) ++{ ++ char *reason_str = NULL; ++ ++ switch (event_data->ReasonCode) { ++ case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: ++ reason_str = "smart data"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: ++ reason_str = "unsupported device discovered"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: ++ reason_str = "internal device reset"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: ++ reason_str = "internal task abort"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: ++ reason_str = "internal task abort set"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: ++ reason_str = "internal clear task set"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: ++ reason_str = "internal query task"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE: ++ reason_str = "sata init failure"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: ++ reason_str = "internal device reset complete"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: ++ reason_str = "internal task abort complete"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: ++ reason_str = "internal async notification"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY: ++ reason_str = "expander reduced functionality"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY: ++ reason_str = "expander reduced functionality complete"; ++ break; ++ default: ++ reason_str = "unknown reason"; ++ break; ++ } ++ pr_info(MPT3SAS_FMT "device status change: (%s)\n" ++ "\thandle(0x%04x), sas address(0x%016llx), tag(%d)", ++ ioc->name, reason_str, le16_to_cpu(event_data->DevHandle), ++ (unsigned long long)le64_to_cpu(event_data->SASAddress), ++ le16_to_cpu(event_data->TaskTag)); ++ if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA) ++ pr_info(MPT3SAS_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name, ++ event_data->ASC, event_data->ASCQ); ++ pr_info("\n"); ++} ++ ++/** ++ * _scsih_sas_device_status_change_event - handle device status change ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ struct MPT3SAS_TARGET *target_priv_data; ++ struct _sas_device *sas_device; ++ u64 sas_address; ++ unsigned long flags; ++ Mpi2EventDataSasDeviceStatusChange_t *event_data = ++ (Mpi2EventDataSasDeviceStatusChange_t *) ++ fw_event->event_data; ++ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) ++ _scsih_sas_device_status_change_event_debug(ioc, ++ event_data); ++ ++ /* In MPI Revision K (0xC), the internal device reset complete was ++ * implemented, so avoid setting tm_busy flag for older firmware. ++ */ ++ if ((ioc->facts.HeaderVersion >> 8) < 0xC) ++ return; ++ ++ if (event_data->ReasonCode != ++ MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && ++ event_data->ReasonCode != ++ MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_address = le64_to_cpu(event_data->SASAddress); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ ++ if (!sas_device || !sas_device->starget) ++ goto out; ++ ++ target_priv_data = sas_device->starget->hostdata; ++ if (!target_priv_data) ++ goto out; ++ ++ if (event_data->ReasonCode == ++ MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) ++ target_priv_data->tm_busy = 1; ++ else ++ target_priv_data->tm_busy = 0; ++ ++out: ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++} ++ ++/** ++ * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure ++ * event ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_enclosure_dev_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasEnclDevStatusChange_t *event_data) ++{ ++ char *reason_str = NULL; ++ ++ switch (event_data->ReasonCode) { ++ case MPI2_EVENT_SAS_ENCL_RC_ADDED: ++ reason_str = "enclosure add"; ++ break; ++ case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: ++ reason_str = "enclosure remove"; ++ break; ++ default: ++ reason_str = "unknown reason"; ++ break; ++ } ++ ++ pr_info(MPT3SAS_FMT "enclosure status change: (%s)\n" ++ "\thandle(0x%04x), enclosure logical id(0x%016llx)" ++ " number slots(%d)\n", ioc->name, reason_str, ++ le16_to_cpu(event_data->EnclosureHandle), ++ (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID), ++ le16_to_cpu(event_data->StartSlot)); ++} ++ ++/** ++ * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) ++ _scsih_sas_enclosure_dev_status_change_event_debug(ioc, ++ (Mpi2EventDataSasEnclDevStatusChange_t *) ++ fw_event->event_data); ++} ++ ++/** ++ * _scsih_sas_broadcast_primitive_event - handle broadcast events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ struct scsi_cmnd *scmd; ++ struct scsi_device *sdev; ++ u16 smid, handle; ++ u32 lun; ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ u32 termination_count; ++ u32 query_count; ++ Mpi2SCSITaskManagementReply_t *mpi_reply; ++ Mpi2EventDataSasBroadcastPrimitive_t *event_data = ++ (Mpi2EventDataSasBroadcastPrimitive_t *) ++ fw_event->event_data; ++ u16 ioc_status; ++ unsigned long flags; ++ int r; ++ u8 max_retries = 0; ++ u8 task_abort_retries; ++ ++ mutex_lock(&ioc->tm_cmds.mutex); ++ pr_info(MPT3SAS_FMT ++ "%s: enter: phy number(%d), width(%d)\n", ++ ioc->name, __func__, event_data->PhyNum, ++ event_data->PortWidth); ++ ++ _scsih_block_io_all_device(ioc); ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ mpi_reply = ioc->tm_cmds.reply; ++ broadcast_aen_retry: ++ ++ /* sanity checks for retrying this loop */ ++ if (max_retries++ == 5) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT "%s: giving up\n", ++ ioc->name, __func__)); ++ goto out; ++ } else if (max_retries > 1) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT "%s: %d retry\n", ++ ioc->name, __func__, max_retries - 1)); ++ ++ termination_count = 0; ++ query_count = 0; ++ for (smid = 1; smid <= ioc->scsiio_depth; smid++) { ++ if (ioc->shost_recovery) ++ goto out; ++ scmd = _scsih_scsi_lookup_get(ioc, smid); ++ if (!scmd) ++ continue; ++ sdev = scmd->device; ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) ++ continue; ++ /* skip hidden raid components */ ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) ++ continue; ++ /* skip volumes */ ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_VOLUME) ++ continue; ++ ++ handle = sas_device_priv_data->sas_target->handle; ++ lun = sas_device_priv_data->lun; ++ query_count++; ++ ++ if (ioc->shost_recovery) ++ goto out; ++ ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ r = mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, ++ MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, ++ TM_MUTEX_OFF); ++ if (r == FAILED) { ++ sdev_printk(KERN_WARNING, sdev, ++ "mpt2sas_scsih_issue_tm: FAILED when sending " ++ "QUERY_TASK: scmd(%p)\n", scmd); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ goto broadcast_aen_retry; ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) ++ & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ sdev_printk(KERN_WARNING, sdev, ++ "query task: FAILED with IOCSTATUS(0x%04x), scmd(%p)\n", ++ ioc_status, scmd); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ goto broadcast_aen_retry; ++ } ++ ++ /* see if IO is still owned by IOC and target */ ++ if (mpi_reply->ResponseCode == ++ MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || ++ mpi_reply->ResponseCode == ++ MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC) { ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ continue; ++ } ++ task_abort_retries = 0; ++ tm_retry: ++ if (task_abort_retries++ == 60) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: ABORT_TASK: giving up\n", ioc->name, ++ __func__)); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ goto broadcast_aen_retry; ++ } ++ ++ if (ioc->shost_recovery) ++ goto out_no_lock; ++ ++ r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, ++ sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, ++ TM_MUTEX_OFF); ++ if (r == FAILED) { ++ sdev_printk(KERN_WARNING, sdev, ++ "mpt2sas_scsih_issue_tm: ABORT_TASK: FAILED : " ++ "scmd(%p)\n", scmd); ++ goto tm_retry; ++ } ++ ++ if (task_abort_retries > 1) ++ sdev_printk(KERN_WARNING, sdev, ++ "mpt2sas_scsih_issue_tm: ABORT_TASK: RETRIES (%d):" ++ " scmd(%p)\n", ++ task_abort_retries - 1, scmd); ++ ++ termination_count += le32_to_cpu(mpi_reply->TerminationCount); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ } ++ ++ if (ioc->broadcast_aen_pending) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: loop back due to pending AEN\n", ++ ioc->name, __func__)); ++ ioc->broadcast_aen_pending = 0; ++ goto broadcast_aen_retry; ++ } ++ ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ out_no_lock: ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - exit, query_count = %d termination_count = %d\n", ++ ioc->name, __func__, query_count, termination_count)); ++ ++ ioc->broadcast_aen_busy = 0; ++ if (!ioc->shost_recovery) ++ _scsih_ublock_io_all_device(ioc); ++ mutex_unlock(&ioc->tm_cmds.mutex); ++} ++ ++/** ++ * _scsih_sas_discovery_event - handle discovery events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ Mpi2EventDataSasDiscovery_t *event_data = ++ (Mpi2EventDataSasDiscovery_t *) fw_event->event_data; ++ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { ++ pr_info(MPT3SAS_FMT "discovery event: (%s)", ioc->name, ++ (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? ++ "start" : "stop"); ++ if (event_data->DiscoveryStatus) ++ pr_info("discovery_status(0x%08x)", ++ le32_to_cpu(event_data->DiscoveryStatus)); ++ pr_info("\n"); ++ } ++ ++ if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED && ++ !ioc->sas_hba.num_phys) { ++ if (disable_discovery > 0 && ioc->shost_recovery) { ++ /* Wait for the reset to complete */ ++ while (ioc->shost_recovery) ++ ssleep(1); ++ } ++ _scsih_sas_host_add(ioc); ++ } ++} ++ ++/** ++ * _scsih_ir_fastpath - turn on fastpath for IR physdisk ++ * @ioc: per adapter object ++ * @handle: device handle for physical disk ++ * @phys_disk_num: physical disk number ++ * ++ * Return 0 for success, else failure. ++ */ ++static int ++_scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num) ++{ ++ Mpi2RaidActionRequest_t *mpi_request; ++ Mpi2RaidActionReply_t *mpi_reply; ++ u16 smid; ++ u8 issue_reset = 0; ++ int rc = 0; ++ u16 ioc_status; ++ u32 log_info; ++ ++ if (ioc->hba_mpi_version_belonged == MPI2_VERSION) ++ return rc; ++ ++ mutex_lock(&ioc->scsih_cmds.mutex); ++ ++ if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: scsih_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->scsih_cmds.status = MPT3_CMD_PENDING; ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->scsih_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t)); ++ ++ mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; ++ mpi_request->Action = MPI2_RAID_ACTION_PHYSDISK_HIDDEN; ++ mpi_request->PhysDiskNum = phys_disk_num; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT "IR RAID_ACTION: turning fast "\ ++ "path on for handle(0x%04x), phys_disk_num (0x%02x)\n", ioc->name, ++ handle, phys_disk_num)); ++ ++ init_completion(&ioc->scsih_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); ++ ++ if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ if (!(ioc->scsih_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->scsih_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus); ++ if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) ++ log_info = le32_to_cpu(mpi_reply->IOCLogInfo); ++ else ++ log_info = 0; ++ ioc_status &= MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "IR RAID_ACTION: failed: ioc_status(0x%04x), " ++ "loginfo(0x%08x)!!!\n", ioc->name, ioc_status, ++ log_info)); ++ rc = -EFAULT; ++ } else ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "IR RAID_ACTION: completed successfully\n", ++ ioc->name)); ++ } ++ ++ out: ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->scsih_cmds.mutex); ++ ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ return rc; ++} ++ ++/** ++ * _scsih_reprobe_lun - reprobing lun ++ * @sdev: scsi device struct ++ * @no_uld_attach: sdev->no_uld_attach flag setting ++ * ++ **/ ++static void ++_scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach) ++{ ++ int rc; ++ sdev->no_uld_attach = no_uld_attach ? 1 : 0; ++ sdev_printk(KERN_INFO, sdev, "%s raid component\n", ++ sdev->no_uld_attach ? "hidding" : "exposing"); ++ rc = scsi_device_reprobe(sdev); ++} ++ ++/** ++ * _scsih_sas_volume_add - add new volume ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_volume_add(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ u64 wwid; ++ u16 handle = le16_to_cpu(element->VolDevHandle); ++ int rc; ++ ++ mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); ++ if (!wwid) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_wwid(ioc, wwid); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (raid_device) ++ return; ++ ++ raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL); ++ if (!raid_device) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ raid_device->id = ioc->sas_id++; ++ raid_device->channel = RAID_CHANNEL; ++ raid_device->handle = handle; ++ raid_device->wwid = wwid; ++ _scsih_raid_device_add(ioc, raid_device); ++ if (!ioc->wait_for_discovery_to_complete) { ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ } else { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ _scsih_determine_boot_device(ioc, raid_device, 1); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++} ++ ++/** ++ * _scsih_sas_volume_delete - delete volume ++ * @ioc: per adapter object ++ * @handle: volume device handle ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_volume_delete(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct scsi_target *starget = NULL; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device) { ++ if (raid_device->starget) { ++ starget = raid_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ } ++ pr_info(MPT3SAS_FMT "removing handle(0x%04x), wwid(0x%016llx)\n", ++ ioc->name, raid_device->handle, ++ (unsigned long long) raid_device->wwid); ++ list_del(&raid_device->list); ++ kfree(raid_device); ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ if (starget) ++ scsi_remove_target(&starget->dev); ++} ++ ++/** ++ * _scsih_sas_pd_expose - expose pd component to /dev/sdX ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _sas_device *sas_device; ++ struct scsi_target *starget = NULL; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ unsigned long flags; ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ sas_device->volume_handle = 0; ++ sas_device->volume_wwid = 0; ++ clear_bit(handle, ioc->pd_handles); ++ if (sas_device->starget && sas_device->starget->hostdata) { ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->flags &= ++ ~MPT_TARGET_FLAGS_RAID_COMPONENT; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (!sas_device) ++ return; ++ ++ /* exposing raid component */ ++ if (starget) ++ starget_for_each_device(starget, NULL, _scsih_reprobe_lun); ++ ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_sas_pd_hide - hide pd component from /dev/sdX ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _sas_device *sas_device; ++ struct scsi_target *starget = NULL; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ unsigned long flags; ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ u16 volume_handle = 0; ++ u64 volume_wwid = 0; ++ ++ mpt2sas_config_get_volume_handle(ioc, handle, &volume_handle); ++ if (volume_handle) ++ mpt2sas_config_get_volume_wwid(ioc, volume_handle, ++ &volume_wwid); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ set_bit(handle, ioc->pd_handles); ++ if (sas_device->starget && sas_device->starget->hostdata) { ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->flags |= ++ MPT_TARGET_FLAGS_RAID_COMPONENT; ++ sas_device->volume_handle = volume_handle; ++ sas_device->volume_wwid = volume_wwid; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (!sas_device) ++ return; ++ ++ /* hiding raid component */ ++ _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); ++ ++ if (starget) ++ starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); ++ ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_sas_pd_delete - delete pd component ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_delete(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ ++ _scsih_device_remove_by_handle(ioc, handle); ++} ++ ++/** ++ * _scsih_sas_pd_add - remove pd component ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _sas_device *sas_device; ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ u32 ioc_status; ++ u64 sas_address; ++ u16 parent_handle; ++ ++ set_bit(handle, ioc->pd_handles); ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); ++ sas_device_put(sas_device); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) ++ mpt2sas_transport_update_links(ioc, sas_address, handle, ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ ++ _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); ++ _scsih_add_device(ioc, handle, 0, 1); ++} ++ ++/** ++ * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_config_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrConfigChangeList_t *event_data) ++{ ++ Mpi2EventIrConfigElement_t *element; ++ u8 element_type; ++ int i; ++ char *reason_str = NULL, *element_str = NULL; ++ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ ++ pr_info(MPT3SAS_FMT "raid config change: (%s), elements(%d)\n", ++ ioc->name, (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? ++ "foreign" : "native", event_data->NumElements); ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ switch (element->ReasonCode) { ++ case MPI2_EVENT_IR_CHANGE_RC_ADDED: ++ reason_str = "add"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_REMOVED: ++ reason_str = "remove"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE: ++ reason_str = "no change"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_HIDE: ++ reason_str = "hide"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: ++ reason_str = "unhide"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: ++ reason_str = "volume_created"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: ++ reason_str = "volume_deleted"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: ++ reason_str = "pd_created"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: ++ reason_str = "pd_deleted"; ++ break; ++ default: ++ reason_str = "unknown reason"; ++ break; ++ } ++ element_type = le16_to_cpu(element->ElementFlags) & ++ MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK; ++ switch (element_type) { ++ case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT: ++ element_str = "volume"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT: ++ element_str = "phys disk"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT: ++ element_str = "hot spare"; ++ break; ++ default: ++ element_str = "unknown element"; ++ break; ++ } ++ pr_info("\t(%s:%s), vol handle(0x%04x), " \ ++ "pd handle(0x%04x), pd num(0x%02x)\n", element_str, ++ reason_str, le16_to_cpu(element->VolDevHandle), ++ le16_to_cpu(element->PhysDiskDevHandle), ++ element->PhysDiskNum); ++ } ++} ++ ++/** ++ * _scsih_sas_ir_config_change_event - handle ir configuration change events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ Mpi2EventIrConfigElement_t *element; ++ int i; ++ u8 foreign_config; ++ Mpi2EventDataIrConfigChangeList_t *event_data = ++ (Mpi2EventDataIrConfigChangeList_t *) ++ fw_event->event_data; ++ ++ if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && ++ (!ioc->hide_ir_msg)) ++ _scsih_sas_ir_config_change_event_debug(ioc, event_data); ++ ++ foreign_config = (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; ++ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ if (ioc->shost_recovery && ++ ioc->hba_mpi_version_belonged != MPI2_VERSION) { ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE) ++ _scsih_ir_fastpath(ioc, ++ le16_to_cpu(element->PhysDiskDevHandle), ++ element->PhysDiskNum); ++ } ++ return; ++ } ++ ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ ++ switch (element->ReasonCode) { ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: ++ case MPI2_EVENT_IR_CHANGE_RC_ADDED: ++ if (!foreign_config) ++ _scsih_sas_volume_add(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: ++ case MPI2_EVENT_IR_CHANGE_RC_REMOVED: ++ if (!foreign_config) ++ _scsih_sas_volume_delete(ioc, ++ le16_to_cpu(element->VolDevHandle)); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_hide(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_expose(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_HIDE: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_add(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_delete(ioc, element); ++ break; ++ } ++ } ++} ++ ++/** ++ * _scsih_sas_ir_volume_event - IR volume event ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ u64 wwid; ++ unsigned long flags; ++ struct _raid_device *raid_device; ++ u16 handle; ++ u32 state; ++ int rc; ++ Mpi2EventDataIrVolume_t *event_data = ++ (Mpi2EventDataIrVolume_t *) fw_event->event_data; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) ++ return; ++ ++ handle = le16_to_cpu(event_data->VolDevHandle); ++ state = le32_to_cpu(event_data->NewValue); ++ if (!ioc->hide_ir_msg) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", ++ ioc->name, __func__, handle, ++ le32_to_cpu(event_data->PreviousValue), state)); ++ switch (state) { ++ case MPI2_RAID_VOL_STATE_MISSING: ++ case MPI2_RAID_VOL_STATE_FAILED: ++ _scsih_sas_volume_delete(ioc, handle); ++ break; ++ ++ case MPI2_RAID_VOL_STATE_ONLINE: ++ case MPI2_RAID_VOL_STATE_DEGRADED: ++ case MPI2_RAID_VOL_STATE_OPTIMAL: ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (raid_device) ++ break; ++ ++ mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); ++ if (!wwid) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ break; ++ } ++ ++ raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL); ++ if (!raid_device) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ break; ++ } ++ ++ raid_device->id = ioc->sas_id++; ++ raid_device->channel = RAID_CHANNEL; ++ raid_device->handle = handle; ++ raid_device->wwid = wwid; ++ _scsih_raid_device_add(ioc, raid_device); ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ break; ++ ++ case MPI2_RAID_VOL_STATE_INITIALIZING: ++ default: ++ break; ++ } ++} ++ ++/** ++ * _scsih_sas_ir_physical_disk_event - PD event ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ u16 handle, parent_handle; ++ u32 state; ++ struct _sas_device *sas_device; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ u32 ioc_status; ++ Mpi2EventDataIrPhysicalDisk_t *event_data = ++ (Mpi2EventDataIrPhysicalDisk_t *) fw_event->event_data; ++ u64 sas_address; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) ++ return; ++ ++ handle = le16_to_cpu(event_data->PhysDiskDevHandle); ++ state = le32_to_cpu(event_data->NewValue); ++ ++ if (!ioc->hide_ir_msg) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", ++ ioc->name, __func__, handle, ++ le32_to_cpu(event_data->PreviousValue), state)); ++ ++ switch (state) { ++ case MPI2_RAID_PD_STATE_ONLINE: ++ case MPI2_RAID_PD_STATE_DEGRADED: ++ case MPI2_RAID_PD_STATE_REBUILDING: ++ case MPI2_RAID_PD_STATE_OPTIMAL: ++ case MPI2_RAID_PD_STATE_HOT_SPARE: ++ ++ if (!ioc->is_warpdrive) ++ set_bit(handle, ioc->pd_handles); ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ++ handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) ++ mpt2sas_transport_update_links(ioc, sas_address, handle, ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ ++ _scsih_add_device(ioc, handle, 0, 1); ++ ++ break; ++ ++ case MPI2_RAID_PD_STATE_OFFLINE: ++ case MPI2_RAID_PD_STATE_NOT_CONFIGURED: ++ case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: ++ default: ++ break; ++ } ++} ++ ++/** ++ * _scsih_sas_ir_operation_status_event_debug - debug for IR op event ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_operation_status_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrOperationStatus_t *event_data) ++{ ++ char *reason_str = NULL; ++ ++ switch (event_data->RAIDOperation) { ++ case MPI2_EVENT_IR_RAIDOP_RESYNC: ++ reason_str = "resync"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: ++ reason_str = "online capacity expansion"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: ++ reason_str = "consistency check"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT: ++ reason_str = "background init"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT: ++ reason_str = "make data consistent"; ++ break; ++ } ++ ++ if (!reason_str) ++ return; ++ ++ pr_info(MPT3SAS_FMT "raid operational status: (%s)" \ ++ "\thandle(0x%04x), percent complete(%d)\n", ++ ioc->name, reason_str, ++ le16_to_cpu(event_data->VolDevHandle), ++ event_data->PercentComplete); ++} ++ ++/** ++ * _scsih_sas_ir_operation_status_event - handle RAID operation events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ Mpi2EventDataIrOperationStatus_t *event_data = ++ (Mpi2EventDataIrOperationStatus_t *) ++ fw_event->event_data; ++ static struct _raid_device *raid_device; ++ unsigned long flags; ++ u16 handle; ++ ++ if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && ++ (!ioc->hide_ir_msg)) ++ _scsih_sas_ir_operation_status_event_debug(ioc, ++ event_data); ++ ++ /* code added for raid transport support */ ++ if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ handle = le16_to_cpu(event_data->VolDevHandle); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device) ++ raid_device->percent_complete = ++ event_data->PercentComplete; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++} ++ ++/** ++ * _scsih_prep_device_scan - initialize parameters prior to device scan ++ * @ioc: per adapter object ++ * ++ * Set the deleted flag prior to device scan. If the device is found during ++ * the scan, then we clear the deleted flag. ++ */ ++static void ++_scsih_prep_device_scan(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (sas_device_priv_data && sas_device_priv_data->sas_target) ++ sas_device_priv_data->sas_target->deleted = 1; ++ } ++} ++ ++/** ++ * _scsih_mark_responding_sas_device - mark a sas_devices as responding ++ * @ioc: per adapter object ++ * @sas_device_pg0: SAS Device page 0 ++ * ++ * After host reset, find out whether devices are still responding. ++ * Used in _scsih_remove_unresponsive_sas_devices. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc, ++Mpi2SasDevicePage0_t *sas_device_pg0) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data = NULL; ++ struct scsi_target *starget; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if ((sas_device->sas_address == sas_device_pg0->SASAddress) && ++ (sas_device->slot == sas_device_pg0->Slot)) { ++ sas_device->responding = 1; ++ starget = sas_device->starget; ++ if (starget && starget->hostdata) { ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->tm_busy = 0; ++ sas_target_priv_data->deleted = 0; ++ } else ++ sas_target_priv_data = NULL; ++ if (starget) { ++ starget_printk(KERN_INFO, starget, ++ "handle(0x%04x), sas_addr(0x%016llx)\n", ++ sas_device_pg0->DevHandle, ++ (unsigned long long) ++ sas_device->sas_address); ++ ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, ++ "enclosure logical id(0x%016llx)," ++ " slot(%d)\n", ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ } ++ if (sas_device_pg0->Flags & ++ MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ le16_to_cpu(sas_device_pg0->EnclosureLevel); ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0->ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } ++ ++ if (sas_device->handle == sas_device_pg0->DevHandle) ++ goto out; ++ pr_info("\thandle changed from(0x%04x)!!!\n", ++ sas_device->handle); ++ sas_device->handle = sas_device_pg0->DevHandle; ++ if (sas_target_priv_data) ++ sas_target_priv_data->handle = ++ sas_device_pg0->DevHandle; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_search_responding_sas_devices - ++ * @ioc: per adapter object ++ * ++ * After host reset, find out whether devices are still responding. ++ * If not remove. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 handle; ++ u32 device_info; ++ ++ pr_info(MPT3SAS_FMT "search for end-devices: start\n", ioc->name); ++ ++ if (list_empty(&ioc->sas_device_list)) ++ goto out; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, ++ handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ handle = sas_device_pg0.DevHandle = ++ le16_to_cpu(sas_device_pg0.DevHandle); ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ if (!(_scsih_is_end_device(device_info))) ++ continue; ++ sas_device_pg0.SASAddress = ++ le64_to_cpu(sas_device_pg0.SASAddress); ++ sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot); ++ _scsih_mark_responding_sas_device(ioc, &sas_device_pg0); ++ } ++ ++ out: ++ pr_info(MPT3SAS_FMT "search for end-devices: complete\n", ++ ioc->name); ++} ++ ++/** ++ * _scsih_mark_responding_raid_device - mark a raid_device as responding ++ * @ioc: per adapter object ++ * @wwid: world wide identifier for raid volume ++ * @handle: device handle ++ * ++ * After host reset, find out whether devices are still responding. ++ * Used in _scsih_remove_unresponsive_raid_devices. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, ++ u16 handle) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data = NULL; ++ struct scsi_target *starget; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->wwid == wwid && raid_device->starget) { ++ starget = raid_device->starget; ++ if (starget && starget->hostdata) { ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->deleted = 0; ++ } else ++ sas_target_priv_data = NULL; ++ raid_device->responding = 1; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ starget_printk(KERN_INFO, raid_device->starget, ++ "handle(0x%04x), wwid(0x%016llx)\n", handle, ++ (unsigned long long)raid_device->wwid); ++ ++ /* ++ * WARPDRIVE: The handles of the PDs might have changed ++ * across the host reset so re-initialize the ++ * required data for Direct IO ++ */ ++ mpt2sas_init_warpdrive_properties(ioc, raid_device); ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ if (raid_device->handle == handle) { ++ spin_unlock_irqrestore(&ioc->raid_device_lock, ++ flags); ++ return; ++ } ++ pr_info("\thandle changed from(0x%04x)!!!\n", ++ raid_device->handle); ++ raid_device->handle = handle; ++ if (sas_target_priv_data) ++ sas_target_priv_data->handle = handle; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ return; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * _scsih_search_responding_raid_devices - ++ * @ioc: per adapter object ++ * ++ * After host reset, find out whether devices are still responding. ++ * If not remove. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidVolPage1_t volume_pg1; ++ Mpi2RaidVolPage0_t volume_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 handle; ++ u8 phys_disk_num; ++ ++ if (!ioc->ir_firmware) ++ return; ++ ++ pr_info(MPT3SAS_FMT "search for raid volumes: start\n", ++ ioc->name); ++ ++ if (list_empty(&ioc->raid_device_list)) ++ goto out; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ handle = le16_to_cpu(volume_pg1.DevHandle); ++ ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, ++ &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) ++ continue; ++ ++ if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) ++ _scsih_mark_responding_raid_device(ioc, ++ le64_to_cpu(volume_pg1.WWID), handle); ++ } ++ ++ /* refresh the pd_handles */ ++ if (!ioc->is_warpdrive) { ++ phys_disk_num = 0xFF; ++ memset(ioc->pd_handles, 0, ioc->pd_handles_sz); ++ while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, ++ phys_disk_num))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ phys_disk_num = pd_pg0.PhysDiskNum; ++ handle = le16_to_cpu(pd_pg0.DevHandle); ++ set_bit(handle, ioc->pd_handles); ++ } ++ } ++ out: ++ pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n", ++ ioc->name); ++} ++ ++/** ++ * _scsih_mark_responding_expander - mark a expander as responding ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * @handle: ++ * ++ * After host reset, find out whether devices are still responding. ++ * Used in _scsih_remove_unresponsive_expanders. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_mark_responding_expander(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u16 handle) ++{ ++ struct _sas_node *sas_expander; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { ++ if (sas_expander->sas_address != sas_address) ++ continue; ++ sas_expander->responding = 1; ++ if (sas_expander->handle == handle) ++ goto out; ++ pr_info("\texpander(0x%016llx): handle changed" \ ++ " from(0x%04x) to (0x%04x)!!!\n", ++ (unsigned long long)sas_expander->sas_address, ++ sas_expander->handle, handle); ++ sas_expander->handle = handle; ++ for (i = 0 ; i < sas_expander->num_phys ; i++) ++ sas_expander->phy[i].handle = handle; ++ goto out; ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++} ++ ++/** ++ * _scsih_search_responding_expanders - ++ * @ioc: per adapter object ++ * ++ * After host reset, find out whether devices are still responding. ++ * If not remove. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2ExpanderPage0_t expander_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u64 sas_address; ++ u16 handle; ++ ++ pr_info(MPT3SAS_FMT "search for expanders: start\n", ioc->name); ++ ++ if (list_empty(&ioc->sas_expander_list)) ++ goto out; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, ++ MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) { ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ ++ handle = le16_to_cpu(expander_pg0.DevHandle); ++ sas_address = le64_to_cpu(expander_pg0.SASAddress); ++ pr_info("\texpander present: handle(0x%04x), sas_addr(0x%016llx)\n", ++ handle, ++ (unsigned long long)sas_address); ++ _scsih_mark_responding_expander(ioc, sas_address, handle); ++ } ++ ++ out: ++ pr_info(MPT3SAS_FMT "search for expanders: complete\n", ioc->name); ++} ++ ++/** ++ * _scsih_remove_unresponding_sas_devices - removing unresponding devices ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _sas_device *sas_device, *sas_device_next; ++ struct _sas_node *sas_expander, *sas_expander_next; ++ struct _raid_device *raid_device, *raid_device_next; ++ struct list_head tmp_list; ++ unsigned long flags; ++ LIST_HEAD(head); ++ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: start\n", ++ ioc->name); ++ ++ /* removing unresponding end devices */ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n", ++ ioc->name); ++ /* ++ * Iterate, pulling off devices marked as non-responding. We become the ++ * owner for the reference the list had on any object we prune. ++ */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ list_for_each_entry_safe(sas_device, sas_device_next, ++ &ioc->sas_device_list, list) { ++ if (!sas_device->responding) ++ list_move_tail(&sas_device->list, &head); ++ else ++ sas_device->responding = 0; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ /* ++ * Now, uninitialize and remove the unresponding devices we pruned. ++ */ ++ list_for_each_entry_safe(sas_device, sas_device_next, &head, list) { ++ _scsih_remove_device(ioc, sas_device); ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ ++ /* removing unresponding volumes */ ++ if (ioc->ir_firmware) { ++ pr_info(MPT3SAS_FMT "removing unresponding devices: volumes\n", ++ ioc->name); ++ list_for_each_entry_safe(raid_device, raid_device_next, ++ &ioc->raid_device_list, list) { ++ if (!raid_device->responding) ++ _scsih_sas_volume_delete(ioc, ++ raid_device->handle); ++ else ++ raid_device->responding = 0; ++ } ++ } ++ ++ /* removing unresponding expanders */ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: expanders\n", ++ ioc->name); ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ INIT_LIST_HEAD(&tmp_list); ++ list_for_each_entry_safe(sas_expander, sas_expander_next, ++ &ioc->sas_expander_list, list) { ++ if (!sas_expander->responding) ++ list_move_tail(&sas_expander->list, &tmp_list); ++ else ++ sas_expander->responding = 0; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list, ++ list) { ++ list_del(&sas_expander->list); ++ _scsih_expander_node_remove(ioc, sas_expander); ++ } ++ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: complete\n", ++ ioc->name); ++ ++ /* unblock devices */ ++ _scsih_ublock_io_all_device(ioc); ++} ++ ++static void ++_scsih_refresh_expander_links(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander, u16 handle) ++{ ++ Mpi2ExpanderPage1_t expander_pg1; ++ Mpi2ConfigReply_t mpi_reply; ++ int i; ++ ++ for (i = 0 ; i < sas_expander->num_phys ; i++) { ++ if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply, ++ &expander_pg1, i, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ mpt2sas_transport_update_links(ioc, sas_expander->sas_address, ++ le16_to_cpu(expander_pg1.AttachedDevHandle), i, ++ expander_pg1.NegotiatedLinkRate >> 4); ++ } ++} ++ ++/** ++ * _scsih_scan_for_devices_after_reset - scan for devices after host reset ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2ExpanderPage0_t expander_pg0; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2RaidVolPage1_t volume_pg1; ++ Mpi2RaidVolPage0_t volume_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2EventIrConfigElement_t element; ++ Mpi2ConfigReply_t mpi_reply; ++ u8 phys_disk_num; ++ u16 ioc_status; ++ u16 handle, parent_handle; ++ u64 sas_address; ++ struct _sas_device *sas_device; ++ struct _sas_node *expander_device; ++ static struct _raid_device *raid_device; ++ u8 retry_count; ++ unsigned long flags; ++ ++ pr_info(MPT3SAS_FMT "scan devices: start\n", ioc->name); ++ ++ _scsih_sas_host_refresh(ioc); ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: expanders start\n", ioc->name); ++ ++ /* expanders */ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, ++ MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from expander scan: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ handle = le16_to_cpu(expander_pg0.DevHandle); ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ expander_device = mpt2sas_scsih_expander_find_by_sas_address( ++ ioc, le64_to_cpu(expander_pg0.SASAddress)); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (expander_device) ++ _scsih_refresh_expander_links(ioc, expander_device, ++ handle); ++ else { ++ pr_info(MPT3SAS_FMT "\tBEFORE adding expander: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(expander_pg0.SASAddress)); ++ _scsih_expander_add(ioc, handle); ++ pr_info(MPT3SAS_FMT "\tAFTER adding expander: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(expander_pg0.SASAddress)); ++ } ++ } ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: expanders complete\n", ++ ioc->name); ++ ++ if (!ioc->ir_firmware) ++ goto skip_to_sas; ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: phys disk start\n", ioc->name); ++ ++ /* phys disk */ ++ phys_disk_num = 0xFF; ++ while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, ++ phys_disk_num))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from phys disk scan: "\ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ phys_disk_num = pd_pg0.PhysDiskNum; ++ handle = le16_to_cpu(pd_pg0.DevHandle); ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ continue; ++ } ++ if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ++ handle) != 0) ++ continue; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from phys disk scan " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, ++ &sas_address)) { ++ pr_info(MPT3SAS_FMT "\tBEFORE adding phys disk: " \ ++ " handle (0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ mpt2sas_transport_update_links(ioc, sas_address, ++ handle, sas_device_pg0.PhyNum, ++ MPI2_SAS_NEG_LINK_RATE_1_5); ++ set_bit(handle, ioc->pd_handles); ++ retry_count = 0; ++ /* This will retry adding the end device. ++ * _scsih_add_device() will decide on retries and ++ * return "1" when it should be retried ++ */ ++ while (_scsih_add_device(ioc, handle, retry_count++, ++ 1)) { ++ ssleep(1); ++ } ++ pr_info(MPT3SAS_FMT "\tAFTER adding phys disk: " \ ++ " handle (0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ } ++ } ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: phys disk complete\n", ++ ioc->name); ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: volumes start\n", ioc->name); ++ ++ /* volumes */ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ handle = le16_to_cpu(volume_pg1.DevHandle); ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_wwid(ioc, ++ le64_to_cpu(volume_pg1.WWID)); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ if (raid_device) ++ continue; ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, ++ &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) ++ continue; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) { ++ memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t)); ++ element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED; ++ element.VolDevHandle = volume_pg1.DevHandle; ++ pr_info(MPT3SAS_FMT ++ "\tBEFORE adding volume: handle (0x%04x)\n", ++ ioc->name, volume_pg1.DevHandle); ++ _scsih_sas_volume_add(ioc, &element); ++ pr_info(MPT3SAS_FMT ++ "\tAFTER adding volume: handle (0x%04x)\n", ++ ioc->name, volume_pg1.DevHandle); ++ } ++ } ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: volumes complete\n", ++ ioc->name); ++ ++ skip_to_sas: ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: end devices start\n", ++ ioc->name); ++ ++ /* sas devices */ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, ++ handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from end device scan:"\ ++ " ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ handle = le16_to_cpu(sas_device_pg0.DevHandle); ++ if (!(_scsih_is_end_device( ++ le32_to_cpu(sas_device_pg0.DeviceInfo)))) ++ continue; ++ sas_device = mpt2sas_get_sdev_by_addr(ioc, ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ continue; ++ } ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { ++ pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ mpt2sas_transport_update_links(ioc, sas_address, handle, ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ retry_count = 0; ++ /* This will retry adding the end device. ++ * _scsih_add_device() will decide on retries and ++ * return "1" when it should be retried ++ */ ++ while (_scsih_add_device(ioc, handle, retry_count++, ++ 0)) { ++ ssleep(1); ++ } ++ pr_info(MPT3SAS_FMT "\tAFTER adding end device: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ } ++ } ++ pr_info(MPT3SAS_FMT "\tscan devices: end devices complete\n", ++ ioc->name); ++ ++ pr_info(MPT3SAS_FMT "scan devices: complete\n", ioc->name); ++} ++/** ++ * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) ++ * @ioc: per adapter object ++ * @reset_phase: phase ++ * ++ * The handler for doing any required cleanup or initialization. ++ * ++ * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET, ++ * MPT3_IOC_DONE_RESET ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) ++{ ++ switch (reset_phase) { ++ case MPT3_IOC_PRE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__)); ++ break; ++ case MPT3_IOC_AFTER_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__)); ++ if (ioc->scsih_cmds.status & MPT3_CMD_PENDING) { ++ ioc->scsih_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->scsih_cmds.smid); ++ complete(&ioc->scsih_cmds.done); ++ } ++ if (ioc->tm_cmds.status & MPT3_CMD_PENDING) { ++ ioc->tm_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid); ++ complete(&ioc->tm_cmds.done); ++ } ++ ++ _scsih_fw_event_cleanup_queue(ioc); ++ _scsih_flush_running_cmds(ioc); ++ break; ++ case MPT3_IOC_DONE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__)); ++ if ((!ioc->is_driver_loading) && !(disable_discovery > 0 && ++ !ioc->sas_hba.num_phys)) { ++ _scsih_prep_device_scan(ioc); ++ _scsih_search_responding_sas_devices(ioc); ++ _scsih_search_responding_raid_devices(ioc); ++ _scsih_search_responding_expanders(ioc); ++ _scsih_error_recovery_delete_devices(ioc); ++ } ++ break; ++ } ++} ++ ++/** ++ * _mpt2sas_fw_work - delayed task for processing firmware events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_mpt2sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) ++{ ++ _scsih_fw_event_del_from_list(ioc, fw_event); ++ ++ /* the queue is being flushed so ignore this event */ ++ if (ioc->remove_host || ioc->pci_error_recovery) { ++ fw_event_work_put(fw_event); ++ return; ++ } ++ ++ switch (fw_event->event) { ++ case MPT3SAS_PROCESS_TRIGGER_DIAG: ++ mpt2sas_process_trigger_data(ioc, ++ (struct SL_WH_TRIGGERS_EVENT_DATA_T *) ++ fw_event->event_data); ++ break; ++ case MPT3SAS_REMOVE_UNRESPONDING_DEVICES: ++ while (scsi_host_in_recovery(ioc->shost) || ++ ioc->shost_recovery) { ++ /* ++ * If we're unloading, bail. Otherwise, this can become ++ * an infinite loop. ++ */ ++ if (ioc->remove_host) ++ goto out; ++ ssleep(1); ++ } ++ _scsih_remove_unresponding_sas_devices(ioc); ++ _scsih_scan_for_devices_after_reset(ioc); ++ break; ++ case MPT3SAS_PORT_ENABLE_COMPLETE: ++ ioc->start_scan = 0; ++ if (missing_delay[0] != -1 && missing_delay[1] != -1) ++ mpt2sas_base_update_missing_delay(ioc, missing_delay[0], ++ missing_delay[1]); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "port enable: complete from worker thread\n", ++ ioc->name)); ++ break; ++ case MPT3SAS_TURN_ON_PFA_LED: ++ _scsih_turn_on_pfa_led(ioc, fw_event->device_handle); ++ break; ++ case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: ++ _scsih_sas_topology_change_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: ++ _scsih_sas_device_status_change_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_DISCOVERY: ++ _scsih_sas_discovery_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: ++ _scsih_sas_broadcast_primitive_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: ++ _scsih_sas_enclosure_dev_status_change_event(ioc, ++ fw_event); ++ break; ++ case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: ++ _scsih_sas_ir_config_change_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_IR_VOLUME: ++ _scsih_sas_ir_volume_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_IR_PHYSICAL_DISK: ++ _scsih_sas_ir_physical_disk_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_IR_OPERATION_STATUS: ++ _scsih_sas_ir_operation_status_event(ioc, fw_event); ++ break; ++ } ++out: ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * _firmware_event_work ++ * @ioc: per adapter object ++ * @work: The fw_event_work object ++ * Context: user. ++ * ++ * wrappers for the work thread handling firmware events ++ * ++ * Return nothing. ++ */ ++ ++static void ++_firmware_event_work(struct work_struct *work) ++{ ++ struct fw_event_work *fw_event = container_of(work, ++ struct fw_event_work, work); ++ ++ _mpt2sas_fw_work(fw_event->ioc, fw_event); ++} ++ ++/** ++ * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time) ++ * @ioc: per adapter object ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt. ++ * ++ * This function merely adds a new work task into ioc->firmware_event_thread. ++ * The tasks are worked from _firmware_event_work in user context. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ++ u32 reply) ++{ ++ struct fw_event_work *fw_event; ++ Mpi2EventNotificationReply_t *mpi_reply; ++ u16 event; ++ u16 sz; ++ Mpi26EventDataActiveCableExcept_t *ActiveCableEventData; ++ ++ /* events turned off due to host reset or driver unloading */ ++ if (ioc->remove_host || ioc->pci_error_recovery) ++ return 1; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ ++ event = le16_to_cpu(mpi_reply->Event); ++ ++ if (event != MPI2_EVENT_LOG_ENTRY_ADDED) ++ mpt2sas_trigger_event(ioc, event, 0); ++ ++ switch (event) { ++ /* handle these */ ++ case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: ++ { ++ Mpi2EventDataSasBroadcastPrimitive_t *baen_data = ++ (Mpi2EventDataSasBroadcastPrimitive_t *) ++ mpi_reply->EventData; ++ ++ if (baen_data->Primitive != ++ MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT) ++ return 1; ++ ++ if (ioc->broadcast_aen_busy) { ++ ioc->broadcast_aen_pending++; ++ return 1; ++ } else ++ ioc->broadcast_aen_busy = 1; ++ break; ++ } ++ ++ case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: ++ _scsih_check_topo_delete_events(ioc, ++ (Mpi2EventDataSasTopologyChangeList_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: ++ _scsih_check_ir_config_unhide_events(ioc, ++ (Mpi2EventDataIrConfigChangeList_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_IR_VOLUME: ++ _scsih_check_volume_delete_events(ioc, ++ (Mpi2EventDataIrVolume_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_LOG_ENTRY_ADDED: ++ { ++ Mpi2EventDataLogEntryAdded_t *log_entry; ++ u32 *log_code; ++ ++ if (!ioc->is_warpdrive) ++ break; ++ ++ log_entry = (Mpi2EventDataLogEntryAdded_t *) ++ mpi_reply->EventData; ++ log_code = (u32 *)log_entry->LogData; ++ ++ if (le16_to_cpu(log_entry->LogEntryQualifier) ++ != MPT2_WARPDRIVE_LOGENTRY) ++ break; ++ ++ switch (le32_to_cpu(*log_code)) { ++ case MPT2_WARPDRIVE_LC_SSDT: ++ pr_warn(MPT3SAS_FMT "WarpDrive Warning: " ++ "IO Throttling has occurred in the WarpDrive " ++ "subsystem. Check WarpDrive documentation for " ++ "additional details.\n", ioc->name); ++ break; ++ case MPT2_WARPDRIVE_LC_SSDLW: ++ pr_warn(MPT3SAS_FMT "WarpDrive Warning: " ++ "Program/Erase Cycles for the WarpDrive subsystem " ++ "in degraded range. Check WarpDrive documentation " ++ "for additional details.\n", ioc->name); ++ break; ++ case MPT2_WARPDRIVE_LC_SSDLF: ++ pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " ++ "There are no Program/Erase Cycles for the " ++ "WarpDrive subsystem. The storage device will be " ++ "in read-only mode. Check WarpDrive documentation " ++ "for additional details.\n", ioc->name); ++ break; ++ case MPT2_WARPDRIVE_LC_BRMF: ++ pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " ++ "The Backup Rail Monitor has failed on the " ++ "WarpDrive subsystem. Check WarpDrive " ++ "documentation for additional details.\n", ++ ioc->name); ++ break; ++ } ++ ++ break; ++ } ++ case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: ++ case MPI2_EVENT_IR_OPERATION_STATUS: ++ case MPI2_EVENT_SAS_DISCOVERY: ++ case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: ++ case MPI2_EVENT_IR_PHYSICAL_DISK: ++ break; ++ ++ case MPI2_EVENT_TEMP_THRESHOLD: ++ _scsih_temp_threshold_events(ioc, ++ (Mpi2EventDataTemperature_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION: ++ ActiveCableEventData = ++ (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData; ++ if (ActiveCableEventData->ReasonCode == ++ MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) ++ pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d", ++ ioc->name, ActiveCableEventData->ReceptacleID); ++ pr_info("cannot be powered and devices connected to this active cable"); ++ pr_info("will not be seen. This active cable"); ++ pr_info("requires %d mW of power", ++ ActiveCableEventData->ActiveCablePowerRequirement); ++ break; ++ ++ default: /* ignore the rest */ ++ return 1; ++ } ++ ++ sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; ++ fw_event = alloc_fw_event_work(sz); ++ if (!fw_event) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ ++ memcpy(fw_event->event_data, mpi_reply->EventData, sz); ++ fw_event->ioc = ioc; ++ fw_event->VF_ID = mpi_reply->VF_ID; ++ fw_event->VP_ID = mpi_reply->VP_ID; ++ fw_event->event = event; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++ return 1; ++} ++ ++/** ++ * _scsih_expander_node_remove - removing expander device from list. ++ * @ioc: per adapter object ++ * @sas_expander: the sas_device object ++ * Context: Calling function should acquire ioc->sas_node_lock. ++ * ++ * Removing object and freeing associated memory from the ++ * ioc->sas_expander_list. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander) ++{ ++ struct _sas_port *mpt2sas_port, *next; ++ ++ /* remove sibling ports attached to this expander */ ++ list_for_each_entry_safe(mpt2sas_port, next, ++ &sas_expander->sas_port_list, port_list) { ++ if (ioc->shost_recovery) ++ return; ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_END_DEVICE) ++ mpt2sas_device_remove_by_sas_address(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ else if (mpt2sas_port->remote_identify.device_type == ++ SAS_EDGE_EXPANDER_DEVICE || ++ mpt2sas_port->remote_identify.device_type == ++ SAS_FANOUT_EXPANDER_DEVICE) ++ mpt2sas_expander_remove(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ } ++ ++ mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, ++ sas_expander->sas_address_parent); ++ ++ pr_info(MPT3SAS_FMT ++ "expander_remove: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, ++ sas_expander->handle, (unsigned long long) ++ sas_expander->sas_address); ++ ++ kfree(sas_expander->phy); ++ kfree(sas_expander); ++} ++ ++/** ++ * _scsih_ir_shutdown - IR shutdown notification ++ * @ioc: per adapter object ++ * ++ * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that ++ * the host system is shutting down. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidActionRequest_t *mpi_request; ++ Mpi2RaidActionReply_t *mpi_reply; ++ u16 smid; ++ ++ /* is IR firmware build loaded ? */ ++ if (!ioc->ir_firmware) ++ return; ++ ++ /* are there any volumes ? */ ++ if (list_empty(&ioc->raid_device_list)) ++ return; ++ ++ mutex_lock(&ioc->scsih_cmds.mutex); ++ ++ if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: scsih_cmd in use\n", ++ ioc->name, __func__); ++ goto out; ++ } ++ ioc->scsih_cmds.status = MPT3_CMD_PENDING; ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->scsih_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t)); ++ ++ mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; ++ mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; ++ ++ if (!ioc->hide_ir_msg) ++ pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); ++ init_completion(&ioc->scsih_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); ++ ++ if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ goto out; ++ } ++ ++ if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { ++ mpi_reply = ioc->scsih_cmds.reply; ++ if (!ioc->hide_ir_msg) ++ pr_info(MPT3SAS_FMT "IR shutdown " ++ "(complete): ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo)); ++ } ++ ++ out: ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->scsih_cmds.mutex); ++} ++ ++/** ++ * scsih_remove_mpt2sas - detach and remove add host ++ * @pdev: PCI device struct ++ * ++ * Routine called when unloading the driver. ++ * Return nothing. ++ */ ++void scsih_remove_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct _sas_port *mpt2sas_port, *next_port; ++ struct _raid_device *raid_device, *next; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct workqueue_struct *wq; ++ unsigned long flags; ++ ++ ioc->remove_host = 1; ++ _scsih_fw_event_cleanup_queue(ioc); ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ wq = ioc->firmware_event_thread; ++ ioc->firmware_event_thread = NULL; ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++ if (wq) ++ destroy_workqueue(wq); ++ ++ /* release all the volumes */ ++ _scsih_ir_shutdown(ioc); ++ list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, ++ list) { ++ if (raid_device->starget) { ++ sas_target_priv_data = ++ raid_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ scsi_remove_target(&raid_device->starget->dev); ++ } ++ pr_info(MPT3SAS_FMT "removing handle(0x%04x), wwid(0x%016llx)\n", ++ ioc->name, raid_device->handle, ++ (unsigned long long) raid_device->wwid); ++ _scsih_raid_device_remove(ioc, raid_device); ++ } ++ ++ /* free ports attached to the sas_host */ ++ list_for_each_entry_safe(mpt2sas_port, next_port, ++ &ioc->sas_hba.sas_port_list, port_list) { ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_END_DEVICE) ++ mpt2sas_device_remove_by_sas_address(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ else if (mpt2sas_port->remote_identify.device_type == ++ SAS_EDGE_EXPANDER_DEVICE || ++ mpt2sas_port->remote_identify.device_type == ++ SAS_FANOUT_EXPANDER_DEVICE) ++ mpt2sas_expander_remove(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ } ++ ++ /* free phys attached to the sas_host */ ++ if (ioc->sas_hba.num_phys) { ++ kfree(ioc->sas_hba.phy); ++ ioc->sas_hba.phy = NULL; ++ ioc->sas_hba.num_phys = 0; ++ } ++ ++ sas_remove_host(shost); ++ scsi_remove_host(shost); ++ mpt2sas_base_detach(ioc); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_del(&ioc->list); ++ spin_unlock(&gioc_lock_mpt2sas); ++ scsi_host_put(shost); ++} ++ ++/** ++ * scsih_shutdown_mpt2sas - routine call during system shutdown ++ * @pdev: PCI device struct ++ * ++ * Return nothing. ++ */ ++void ++scsih_shutdown_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct workqueue_struct *wq; ++ unsigned long flags; ++ ++ ioc->remove_host = 1; ++ _scsih_fw_event_cleanup_queue(ioc); ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ wq = ioc->firmware_event_thread; ++ ioc->firmware_event_thread = NULL; ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++ if (wq) ++ destroy_workqueue(wq); ++ ++ _scsih_ir_shutdown(ioc); ++ mpt2sas_base_detach(ioc); ++} ++ ++ ++/** ++ * _scsih_probe_boot_devices - reports 1st device ++ * @ioc: per adapter object ++ * ++ * If specified in bios page 2, this routine reports the 1st ++ * device scsi-ml or sas transport for persistent boot device ++ * purposes. Please refer to function _scsih_determine_boot_device() ++ */ ++static void ++_scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u8 is_raid; ++ void *device; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ u16 handle; ++ u64 sas_address_parent; ++ u64 sas_address; ++ unsigned long flags; ++ int rc; ++ ++ /* no Bios, return immediately */ ++ if (!ioc->bios_pg3.BiosVersion) ++ return; ++ ++ device = NULL; ++ is_raid = 0; ++ if (ioc->req_boot_device.device) { ++ device = ioc->req_boot_device.device; ++ is_raid = ioc->req_boot_device.is_raid; ++ } else if (ioc->req_alt_boot_device.device) { ++ device = ioc->req_alt_boot_device.device; ++ is_raid = ioc->req_alt_boot_device.is_raid; ++ } else if (ioc->current_boot_device.device) { ++ device = ioc->current_boot_device.device; ++ is_raid = ioc->current_boot_device.is_raid; ++ } ++ ++ if (!device) ++ return; ++ ++ if (is_raid) { ++ raid_device = device; ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ } else { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = device; ++ handle = sas_device->handle; ++ sas_address_parent = sas_device->sas_address_parent; ++ sas_address = sas_device->sas_address; ++ list_move_tail(&sas_device->list, &ioc->sas_device_list); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (ioc->hide_drives) ++ return; ++ if (!mpt2sas_transport_port_add(ioc, handle, ++ sas_address_parent)) { ++ _scsih_sas_device_remove(ioc, sas_device); ++ } else if (!sas_device->starget) { ++ if (!ioc->is_driver_loading) { ++ mpt2sas_transport_port_remove(ioc, ++ sas_address, ++ sas_address_parent); ++ _scsih_sas_device_remove(ioc, sas_device); ++ } ++ } ++ } ++} ++ ++/** ++ * _scsih_probe_raid - reporting raid volumes to scsi-ml ++ * @ioc: per adapter object ++ * ++ * Called during initial loading of the driver. ++ */ ++static void ++_scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _raid_device *raid_device, *raid_next; ++ int rc; ++ ++ list_for_each_entry_safe(raid_device, raid_next, ++ &ioc->raid_device_list, list) { ++ if (raid_device->starget) ++ continue; ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ } ++} ++ ++static struct _sas_device *get_next_sas_device(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _sas_device *sas_device = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ if (!list_empty(&ioc->sas_device_init_list)) { ++ sas_device = list_first_entry(&ioc->sas_device_init_list, ++ struct _sas_device, list); ++ sas_device_get(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return sas_device; ++} ++ ++static void sas_device_make_active(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ ++ /* ++ * Since we dropped the lock during the call to port_add(), we need to ++ * be careful here that somebody else didn't move or delete this item ++ * while we were busy with other things. ++ * ++ * If it was on the list, we need a put() for the reference the list ++ * had. Either way, we need a get() for the destination list. ++ */ ++ if (!list_empty(&sas_device->list)) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ ++ sas_device_get(sas_device); ++ list_add_tail(&sas_device->list, &ioc->sas_device_list); ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_probe_sas - reporting sas devices to sas transport ++ * @ioc: per adapter object ++ * ++ * Called during initial loading of the driver. ++ */ ++static void ++_scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _sas_device *sas_device; ++ ++ if (ioc->hide_drives) ++ return; ++ ++ while ((sas_device = get_next_sas_device(ioc))) { ++ if (!mpt2sas_transport_port_add(ioc, sas_device->handle, ++ sas_device->sas_address_parent)) { ++ _scsih_sas_device_remove(ioc, sas_device); ++ sas_device_put(sas_device); ++ continue; ++ } else if (!sas_device->starget) { ++ /* ++ * When asyn scanning is enabled, its not possible to ++ * remove devices while scanning is turned on due to an ++ * oops in scsi_sysfs_add_sdev()->add_device()-> ++ * sysfs_addrm_start() ++ */ ++ if (!ioc->is_driver_loading) { ++ mpt2sas_transport_port_remove(ioc, ++ sas_device->sas_address, ++ sas_device->sas_address_parent); ++ _scsih_sas_device_remove(ioc, sas_device); ++ sas_device_put(sas_device); ++ continue; ++ } ++ } ++ sas_device_make_active(ioc, sas_device); ++ sas_device_put(sas_device); ++ } ++} ++ ++/** ++ * _scsih_probe_devices - probing for devices ++ * @ioc: per adapter object ++ * ++ * Called during initial loading of the driver. ++ */ ++static void ++_scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u16 volume_mapping_flags; ++ ++ if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR)) ++ return; /* return when IOC doesn't support initiator mode */ ++ ++ _scsih_probe_boot_devices(ioc); ++ ++ if (ioc->ir_firmware) { ++ volume_mapping_flags = ++ le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) & ++ MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; ++ if (volume_mapping_flags == ++ MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) { ++ _scsih_probe_raid(ioc); ++ _scsih_probe_sas(ioc); ++ } else { ++ _scsih_probe_sas(ioc); ++ _scsih_probe_raid(ioc); ++ } ++ } else ++ _scsih_probe_sas(ioc); ++} ++ ++/** ++ * scsih_scan_start_mpt2sas - scsi lld callback for .scan_start ++ * @shost: SCSI host pointer ++ * ++ * The shost has the ability to discover targets on its own instead ++ * of scanning the entire bus. In our implemention, we will kick off ++ * firmware discovery. ++ */ ++void ++scsih_scan_start_mpt2sas(struct Scsi_Host *shost) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int rc; ++ if (diag_buffer_enable != -1 && diag_buffer_enable != 0) ++ mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); ++ ++ if (disable_discovery > 0) ++ return; ++ ++ ioc->start_scan = 1; ++ rc = mpt2sas_port_enable(ioc); ++ ++ if (rc != 0) ++ pr_info(MPT3SAS_FMT "port enable: FAILED\n", ioc->name); ++} ++ ++/** ++ * scsih_scan_finished_mpt2sas - scsi lld callback for .scan_finished ++ * @shost: SCSI host pointer ++ * @time: elapsed time of the scan in jiffies ++ * ++ * This function will be called periodicallyn until it returns 1 with the ++ * scsi_host and the elapsed time of the scan in jiffies. In our implemention, ++ * we wait for firmware discovery to complete, then return 1. ++ */ ++int ++scsih_scan_finished_mpt2sas(struct Scsi_Host *shost, unsigned long time) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ if (disable_discovery > 0) { ++ ioc->is_driver_loading = 0; ++ ioc->wait_for_discovery_to_complete = 0; ++ return 1; ++ } ++ ++ if (time >= (300 * HZ)) { ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ pr_info(MPT3SAS_FMT ++ "port enable: FAILED with timeout (timeout=300s)\n", ++ ioc->name); ++ ioc->is_driver_loading = 0; ++ return 1; ++ } ++ ++ if (ioc->start_scan) ++ return 0; ++ ++ if (ioc->start_scan_failed) { ++ pr_info(MPT3SAS_FMT ++ "port enable: FAILED with (ioc_status=0x%08x)\n", ++ ioc->name, ioc->start_scan_failed); ++ ioc->is_driver_loading = 0; ++ ioc->wait_for_discovery_to_complete = 0; ++ ioc->remove_host = 1; ++ return 1; ++ } ++ ++ pr_info(MPT3SAS_FMT "port enable: SUCCESS\n", ioc->name); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ ++ if (ioc->wait_for_discovery_to_complete) { ++ ioc->wait_for_discovery_to_complete = 0; ++ _scsih_probe_devices(ioc); ++ } ++ mpt2sas_base_start_watchdog(ioc); ++ ioc->is_driver_loading = 0; ++ return 1; ++} ++ ++/* shost template for SAS 2.0 HBA devices */ ++static struct scsi_host_template mpt2sas_driver_template_mpt2sas = { ++ .module = THIS_MODULE, ++ .name = "Fusion MPT SAS Host", ++ .proc_name = MPT2SAS_DRIVER_NAME, ++ .queuecommand = scsih_qcmd_mpt2sas, ++ .target_alloc = scsih_target_alloc_mpt2sas, ++ .slave_alloc = scsih_slave_alloc_mpt2sas, ++ .slave_configure = scsih_slave_configure_mpt2sas, ++ .target_destroy = scsih_target_destroy_mpt2sas, ++ .slave_destroy = scsih_slave_destroy_mpt2sas, ++ .scan_finished = scsih_scan_finished_mpt2sas, ++ .scan_start = scsih_scan_start_mpt2sas, ++ .change_queue_depth = scsih_change_queue_depth_mpt2sas, ++ .change_queue_type = _scsih_change_queue_type_mpt2sas, ++ .eh_abort_handler = scsih_abort_mpt2sas, ++ .eh_device_reset_handler = scsih_dev_reset_mpt2sas, ++ .eh_target_reset_handler = scsih_target_reset_mpt2sas, ++ .eh_host_reset_handler = scsih_host_reset_mpt2sas, ++ .bios_param = scsih_bios_param_mpt2sas, ++ .can_queue = 1, ++ .this_id = -1, ++ .sg_tablesize = MPT2SAS_SG_DEPTH, ++ .max_sectors = 32767, ++ .cmd_per_lun = 7, ++ .use_clustering = ENABLE_CLUSTERING, ++ .shost_attrs = mpt2sas_host_attrs, ++ .sdev_attrs = mpt2sas_dev_attrs, ++}; ++ ++#ifdef MPT2SAS_SCSI ++/* raid transport support for SAS 2.0 HBA devices */ ++static struct raid_function_template mpt2sas_raid_functions = { ++ .cookie = &mpt2sas_driver_template_mpt2sas, ++ .is_raid = scsih_is_raid_mpt2sas, ++ .get_resync = scsih_get_resync_mpt2sas, ++ .get_state = scsih_get_state_mpt2sas, ++}; ++#endif /* MPT2SAS_SCSI */ ++ ++/* shost template for SAS 3.0 HBA devices */ ++static struct scsi_host_template mpt3sas_driver_template_mpt2sas = { ++ .module = THIS_MODULE, ++ .name = "Fusion MPT SAS Host", ++ .proc_name = MPT3SAS_DRIVER_NAME, ++ .queuecommand = scsih_qcmd_mpt2sas, ++ .target_alloc = scsih_target_alloc_mpt2sas, ++ .slave_alloc = scsih_slave_alloc_mpt2sas, ++ .slave_configure = scsih_slave_configure_mpt2sas, ++ .target_destroy = scsih_target_destroy_mpt2sas, ++ .slave_destroy = scsih_slave_destroy_mpt2sas, ++ .scan_finished = scsih_scan_finished_mpt2sas, ++ .scan_start = scsih_scan_start_mpt2sas, ++ .change_queue_depth = scsih_change_queue_depth_mpt2sas, ++ .change_queue_type = _scsih_change_queue_type_mpt2sas, ++ .eh_abort_handler = scsih_abort_mpt2sas, ++ .eh_device_reset_handler = scsih_dev_reset_mpt2sas, ++ .eh_target_reset_handler = scsih_target_reset_mpt2sas, ++ .eh_host_reset_handler = scsih_host_reset_mpt2sas, ++ .bios_param = scsih_bios_param_mpt2sas, ++ .can_queue = 1, ++ .this_id = -1, ++ .sg_tablesize = MPT3SAS_SG_DEPTH, ++ .max_sectors = 32767, ++ .cmd_per_lun = 7, ++ .use_clustering = ENABLE_CLUSTERING, ++ .shost_attrs = mpt2sas_host_attrs, ++ .sdev_attrs = mpt2sas_dev_attrs, ++}; ++ ++#ifndef MPT2SAS_SCSI ++/* raid transport support for SAS 3.0 HBA devices */ ++static struct raid_function_template mpt3sas_raid_functions = { ++ .cookie = &mpt3sas_driver_template_mpt2sas, ++ .is_raid = scsih_is_raid_mpt2sas, ++ .get_resync = scsih_get_resync_mpt2sas, ++ .get_state = scsih_get_state_mpt2sas, ++}; ++#endif /* MPT2SAS_SCSI */ ++ ++/** ++ * _scsih_determine_hba_mpi_version_mpt2sas - determine in which MPI version class ++ * this device belongs to. ++ * @pdev: PCI device struct ++ * ++ * return MPI2_VERSION for SAS 2.0 HBA devices, ++ * MPI25_VERSION for SAS 3.0 HBA devices, and ++ * MPI26 VERSION for Cutlass & Invader SAS 3.0 HBA devices ++ */ ++u16 ++_scsih_determine_hba_mpi_version_mpt2sas(struct pci_dev *pdev) ++{ ++ ++ switch (pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SSS6200: ++ case MPI2_MFGPAGE_DEVID_SAS2004: ++ case MPI2_MFGPAGE_DEVID_SAS2008: ++ case MPI2_MFGPAGE_DEVID_SAS2108_1: ++ case MPI2_MFGPAGE_DEVID_SAS2108_2: ++ case MPI2_MFGPAGE_DEVID_SAS2108_3: ++ case MPI2_MFGPAGE_DEVID_SAS2116_1: ++ case MPI2_MFGPAGE_DEVID_SAS2116_2: ++ case MPI2_MFGPAGE_DEVID_SAS2208_1: ++ case MPI2_MFGPAGE_DEVID_SAS2208_2: ++ case MPI2_MFGPAGE_DEVID_SAS2208_3: ++ case MPI2_MFGPAGE_DEVID_SAS2208_4: ++ case MPI2_MFGPAGE_DEVID_SAS2208_5: ++ case MPI2_MFGPAGE_DEVID_SAS2208_6: ++ case MPI2_MFGPAGE_DEVID_SAS2308_1: ++ case MPI2_MFGPAGE_DEVID_SAS2308_2: ++ case MPI2_MFGPAGE_DEVID_SAS2308_3: ++ return MPI2_VERSION; ++ case MPI25_MFGPAGE_DEVID_SAS3004: ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ case MPI25_MFGPAGE_DEVID_SAS3108_1: ++ case MPI25_MFGPAGE_DEVID_SAS3108_2: ++ case MPI25_MFGPAGE_DEVID_SAS3108_5: ++ case MPI25_MFGPAGE_DEVID_SAS3108_6: ++ return MPI25_VERSION; ++ case MPI26_MFGPAGE_DEVID_SAS3216: ++ case MPI26_MFGPAGE_DEVID_SAS3224: ++ case MPI26_MFGPAGE_DEVID_SAS3316_1: ++ case MPI26_MFGPAGE_DEVID_SAS3316_2: ++ case MPI26_MFGPAGE_DEVID_SAS3316_3: ++ case MPI26_MFGPAGE_DEVID_SAS3316_4: ++ case MPI26_MFGPAGE_DEVID_SAS3324_1: ++ case MPI26_MFGPAGE_DEVID_SAS3324_2: ++ case MPI26_MFGPAGE_DEVID_SAS3324_3: ++ case MPI26_MFGPAGE_DEVID_SAS3324_4: ++ return MPI26_VERSION; ++ } ++ return 0; ++} ++ ++/** ++ * _scsih_probe_mpt2sas - attach and add scsi host ++ * @pdev: PCI device struct ++ * @id: pci device id ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++_scsih_probe_mpt2sas(struct pci_dev *pdev, const struct pci_device_id *id) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ struct Scsi_Host *shost = NULL; ++ int rv; ++ u16 hba_mpi_version; ++ ++ /* Determine in which MPI version class this pci device belongs */ ++ hba_mpi_version = _scsih_determine_hba_mpi_version_mpt2sas(pdev); ++ if (hba_mpi_version == 0) ++ return -ENODEV; ++ ++ switch (hba_mpi_version) { ++ case MPI2_VERSION: ++ /* Use mpt2sas driver host template for SAS 2.0 HBA's */ ++ shost = scsi_host_alloc(&mpt2sas_driver_template_mpt2sas, ++ sizeof(struct MPT3SAS_ADAPTER)); ++ if (!shost) ++ return -ENODEV; ++ ioc = shost_priv(shost); ++ memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); ++ ioc->hba_mpi_version_belonged = hba_mpi_version; ++ ioc->id = mpt2_ids++; ++ sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME); ++ if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) { ++ ioc->is_warpdrive = 1; ++ ioc->hide_ir_msg = 1; ++ } else ++ ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ /* Use mpt3sas driver host template for SAS 3.0 HBA's */ ++ shost = scsi_host_alloc(&mpt3sas_driver_template_mpt2sas, ++ sizeof(struct MPT3SAS_ADAPTER)); ++ if (!shost) ++ return -ENODEV; ++ ioc = shost_priv(shost); ++ memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); ++ ioc->hba_mpi_version_belonged = hba_mpi_version; ++ ioc->id = mpt3_ids++; ++ sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME); ++ if ((ioc->hba_mpi_version_belonged == MPI25_VERSION && ++ pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) || ++ (ioc->hba_mpi_version_belonged == MPI26_VERSION)) ++ ioc->msix96_vector = 1; ++ break; ++ default: ++ return -ENODEV; ++ } ++ ++ INIT_LIST_HEAD(&ioc->list); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_add_tail(&ioc->list, &mpt2sas_ioc_list); ++ spin_unlock(&gioc_lock_mpt2sas); ++ ioc->shost = shost; ++ ioc->pdev = pdev; ++ ioc->scsi_io_cb_idx = scsi_io_cb_idx; ++ ioc->tm_cb_idx = tm_cb_idx; ++ ioc->ctl_cb_idx = ctl_cb_idx; ++ ioc->base_cb_idx = base_cb_idx; ++ ioc->port_enable_cb_idx = port_enable_cb_idx; ++ ioc->transport_cb_idx = transport_cb_idx; ++ ioc->scsih_cb_idx = scsih_cb_idx; ++ ioc->config_cb_idx = config_cb_idx; ++ ioc->tm_tr_cb_idx = tm_tr_cb_idx; ++ ioc->tm_tr_volume_cb_idx = tm_tr_volume_cb_idx; ++ ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; ++ ioc->logging_level = logging_level; ++ ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; ++ /* misc semaphores and spin locks */ ++ mutex_init(&ioc->reset_in_progress_mutex); ++ /* initializing pci_access_mutex lock */ ++ mutex_init(&ioc->pci_access_mutex); ++ spin_lock_init(&ioc->ioc_reset_in_progress_lock); ++ spin_lock_init(&ioc->scsi_lookup_lock); ++ spin_lock_init(&ioc->sas_device_lock); ++ spin_lock_init(&ioc->sas_node_lock); ++ spin_lock_init(&ioc->fw_event_lock); ++ spin_lock_init(&ioc->raid_device_lock); ++ spin_lock_init(&ioc->diag_trigger_lock); ++ ++ INIT_LIST_HEAD(&ioc->sas_device_list); ++ INIT_LIST_HEAD(&ioc->sas_device_init_list); ++ INIT_LIST_HEAD(&ioc->sas_expander_list); ++ INIT_LIST_HEAD(&ioc->fw_event_list); ++ INIT_LIST_HEAD(&ioc->raid_device_list); ++ INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); ++ INIT_LIST_HEAD(&ioc->delayed_tr_list); ++ INIT_LIST_HEAD(&ioc->delayed_sc_list); ++ INIT_LIST_HEAD(&ioc->delayed_event_ack_list); ++ INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); ++ INIT_LIST_HEAD(&ioc->reply_queue_list); ++ ++ sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id); ++ ++ /* init shost parameters */ ++ shost->max_cmd_len = 32; ++ shost->max_lun = max_lun; ++ shost->transportt = mpt2sas_transport_template; ++ shost->unique_id = ioc->id; ++ ++ if (max_sectors != 0xFFFF) { ++ if (max_sectors < 64) { ++ shost->max_sectors = 64; ++ pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ ++ "for max_sectors, range is 64 to 32767. Assigning " ++ "value of 64.\n", ioc->name, max_sectors); ++ } else if (max_sectors > 32767) { ++ shost->max_sectors = 32767; ++ pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ ++ "for max_sectors, range is 64 to 32767. Assigning " ++ "default value of 32767.\n", ioc->name, ++ max_sectors); ++ } else { ++ shost->max_sectors = max_sectors & 0xFFFE; ++ pr_info(MPT3SAS_FMT ++ "The max_sectors value is set to %d\n", ++ ioc->name, shost->max_sectors); ++ } ++ } ++ ++ /* register EEDP capabilities with SCSI layer */ ++ if (prot_mask > 0) ++ scsi_host_set_prot(shost, prot_mask); ++ else ++ scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION ++ | SHOST_DIF_TYPE2_PROTECTION ++ | SHOST_DIF_TYPE3_PROTECTION); ++ ++ scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC); ++ ++ /* event thread */ ++ snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), ++ "fw_event_%s%d", ioc->driver_name, ioc->id); ++ ioc->firmware_event_thread = alloc_ordered_workqueue( ++ ioc->firmware_event_name, WQ_MEM_RECLAIM); ++ if (!ioc->firmware_event_thread) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rv = -ENODEV; ++ goto out_thread_fail; ++ } ++ ++ ioc->is_driver_loading = 1; ++ if ((mpt2sas_base_attach(ioc))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rv = -ENODEV; ++ goto out_attach_fail; ++ } ++ ++ if (ioc->is_warpdrive) { ++ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) ++ ioc->hide_drives = 0; ++ else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS) ++ ioc->hide_drives = 1; ++ else { ++ if (mpt2sas_get_num_volumes(ioc)) ++ ioc->hide_drives = 1; ++ else ++ ioc->hide_drives = 0; ++ } ++ } else ++ ioc->hide_drives = 0; ++ ++ rv = scsi_add_host(shost, &pdev->dev); ++ if (rv) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_add_shost_fail; ++ } ++ ++ scsi_scan_host(shost); ++ return 0; ++out_add_shost_fail: ++ mpt2sas_base_detach(ioc); ++ out_attach_fail: ++ destroy_workqueue(ioc->firmware_event_thread); ++ out_thread_fail: ++ spin_lock(&gioc_lock_mpt2sas); ++ list_del(&ioc->list); ++ spin_unlock(&gioc_lock_mpt2sas); ++ scsi_host_put(shost); ++ return rv; ++} ++ ++#ifdef CONFIG_PM ++/** ++ * scsih_suspend_mpt2sas - power management suspend main entry point ++ * @pdev: PCI device struct ++ * @state: PM state change to (usually PCI_D3) ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++scsih_suspend_mpt2sas(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ pci_power_t device_state; ++ ++ mpt2sas_base_stop_watchdog(ioc); ++ flush_scheduled_work(); ++ scsi_block_requests(shost); ++ device_state = pci_choose_state(pdev, state); ++ pr_info(MPT3SAS_FMT ++ "pdev=0x%p, slot=%s, entering operating state [D%d]\n", ++ ioc->name, pdev, pci_name(pdev), device_state); ++ ++ pci_save_state(pdev); ++ mpt2sas_base_free_resources(ioc); ++ pci_set_power_state(pdev, device_state); ++ return 0; ++} ++ ++/** ++ * scsih_resume_mpt2sas - power management resume main entry point ++ * @pdev: PCI device struct ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++scsih_resume_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ pci_power_t device_state = pdev->current_state; ++ int r; ++ ++ pr_info(MPT3SAS_FMT ++ "pdev=0x%p, slot=%s, previous operating state [D%d]\n", ++ ioc->name, pdev, pci_name(pdev), device_state); ++ ++ pci_set_power_state(pdev, PCI_D0); ++ pci_enable_wake(pdev, PCI_D0, 0); ++ pci_restore_state(pdev); ++ ioc->pdev = pdev; ++ r = mpt2sas_base_map_resources(ioc); ++ if (r) ++ return r; ++ ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); ++ scsi_unblock_requests(shost); ++ mpt2sas_base_start_watchdog(ioc); ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++/** ++ * scsih_pci_error_detected_mpt2sas - Called when a PCI error is detected. ++ * @pdev: PCI device struct ++ * @state: PCI channel state ++ * ++ * Description: Called when a PCI error is detected. ++ * ++ * Return value: ++ * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT ++ */ ++pci_ers_result_t ++scsih_pci_error_detected_mpt2sas(struct pci_dev *pdev, pci_channel_state_t state) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ pr_info(MPT3SAS_FMT "PCI error: detected callback, state(%d)!!\n", ++ ioc->name, state); ++ ++ switch (state) { ++ case pci_channel_io_normal: ++ return PCI_ERS_RESULT_CAN_RECOVER; ++ case pci_channel_io_frozen: ++ /* Fatal error, prepare for slot reset */ ++ ioc->pci_error_recovery = 1; ++ scsi_block_requests(ioc->shost); ++ mpt2sas_base_stop_watchdog(ioc); ++ mpt2sas_base_free_resources(ioc); ++ return PCI_ERS_RESULT_NEED_RESET; ++ case pci_channel_io_perm_failure: ++ /* Permanent error, prepare for device removal */ ++ ioc->pci_error_recovery = 1; ++ mpt2sas_base_stop_watchdog(ioc); ++ _scsih_flush_running_cmds(ioc); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ return PCI_ERS_RESULT_NEED_RESET; ++} ++ ++/** ++ * scsih_pci_slot_reset_mpt2sas - Called when PCI slot has been reset. ++ * @pdev: PCI device struct ++ * ++ * Description: This routine is called by the pci error recovery ++ * code after the PCI slot has been reset, just before we ++ * should resume normal operations. ++ */ ++pci_ers_result_t ++scsih_pci_slot_reset_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int rc; ++ ++ pr_info(MPT3SAS_FMT "PCI error: slot reset callback!!\n", ++ ioc->name); ++ ++ ioc->pci_error_recovery = 0; ++ ioc->pdev = pdev; ++ pci_restore_state(pdev); ++ rc = mpt2sas_base_map_resources(ioc); ++ if (rc) ++ return PCI_ERS_RESULT_DISCONNECT; ++ ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ pr_warn(MPT3SAS_FMT "hard reset: %s\n", ioc->name, ++ (rc == 0) ? "success" : "failed"); ++ ++ if (!rc) ++ return PCI_ERS_RESULT_RECOVERED; ++ else ++ return PCI_ERS_RESULT_DISCONNECT; ++} ++ ++/** ++ * scsih_pci_resume_mpt2sas() - resume normal ops after PCI reset ++ * @pdev: pointer to PCI device ++ * ++ * Called when the error recovery driver tells us that its ++ * OK to resume normal operation. Use completion to allow ++ * halted scsi ops to resume. ++ */ ++void ++scsih_pci_resume_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ pr_info(MPT3SAS_FMT "PCI error: resume callback!!\n", ioc->name); ++ ++ pci_cleanup_aer_uncorrect_error_status(pdev); ++ mpt2sas_base_start_watchdog(ioc); ++ scsi_unblock_requests(ioc->shost); ++} ++ ++/** ++ * scsih_pci_mmio_enabled_mpt2sas - Enable MMIO and dump debug registers ++ * @pdev: pointer to PCI device ++ */ ++pci_ers_result_t ++scsih_pci_mmio_enabled_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ pr_info(MPT3SAS_FMT "PCI error: mmio enabled callback!!\n", ++ ioc->name); ++ ++ /* TODO - dump whatever for debugging purposes */ ++ ++ /* This called only if scsih_pci_error_detected_mpt2sas returns ++ * PCI_ERS_RESULT_CAN_RECOVER. Read/write to the device still ++ * works, no need to reset slot. ++ */ ++ return PCI_ERS_RESULT_RECOVERED; ++} ++ ++/* ++ * The pci device ids are defined in mpi/mpi2_cnfg.h. ++ */ ++static const struct pci_device_id mpt2sas_pci_table[] = { ++#ifdef MPT2SAS_SCSI ++ /* Spitfire ~ 2004 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Falcon ~ 2008 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Liberator ~ 2108 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Meteor ~ 2116 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Thunderbolt ~ 2208 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Mustang ~ 2308 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* SSS6200 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, ++ PCI_ANY_ID, PCI_ANY_ID }, ++#else ++ /* Fury ~ 3004 and 3008 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Invader ~ 3108 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Cutlass ~ 3216 and 3224 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Intruder ~ 3316 and 3324 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_4, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_4, ++ PCI_ANY_ID, PCI_ANY_ID }, ++#endif /* MPT2SAS_SCSI */ ++ {0} /* Terminating entry */ ++}; ++MODULE_DEVICE_TABLE(pci, mpt2sas_pci_table); ++ ++static struct pci_error_handlers _mpt2sas_err_handler = { ++ .error_detected = scsih_pci_error_detected_mpt2sas, ++ .mmio_enabled = scsih_pci_mmio_enabled_mpt2sas, ++ .slot_reset = scsih_pci_slot_reset_mpt2sas, ++ .resume = scsih_pci_resume_mpt2sas, ++}; ++ ++static struct pci_driver mpt3sas_driver = { ++#ifdef MPT2SAS_SCSI ++ .name = MPT2SAS_DRIVER_NAME, ++#else ++ .name = MPT3SAS_DRIVER_NAME, ++#endif /* MPT2SAS_SCSI */ ++ .id_table = mpt2sas_pci_table, ++ .probe = _scsih_probe_mpt2sas, ++ .remove = scsih_remove_mpt2sas, ++ .shutdown = scsih_shutdown_mpt2sas, ++ .err_handler = &_mpt2sas_err_handler, ++#ifdef CONFIG_PM ++ .suspend = scsih_suspend_mpt2sas, ++ .resume = scsih_resume_mpt2sas, ++#endif ++}; ++ ++/** ++ * scsih_init_mpt2sas - main entry point for this driver. ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++scsih_init_mpt2sas(void) ++{ ++ mpt2_ids = 0; ++ mpt3_ids = 0; ++ ++ mpt2sas_base_initialize_callback_handler(); ++ ++ /* queuecommand callback hander */ ++ scsi_io_cb_idx = mpt2sas_base_register_callback_handler(_scsih_io_done); ++ ++ /* task managment callback handler */ ++ tm_cb_idx = mpt2sas_base_register_callback_handler(_scsih_tm_done); ++ ++ /* base internal commands callback handler */ ++ base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done); ++ port_enable_cb_idx = mpt2sas_base_register_callback_handler( ++ mpt2sas_port_enable_done); ++ ++ /* transport internal commands callback handler */ ++ transport_cb_idx = mpt2sas_base_register_callback_handler( ++ mpt2sas_transport_done); ++ ++ /* scsih internal commands callback handler */ ++ scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done); ++ ++ /* configuration page API internal commands callback handler */ ++ config_cb_idx = mpt2sas_base_register_callback_handler( ++ mpt2sas_config_done); ++ ++ /* ctl module callback handler */ ++ ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); ++ ++ tm_tr_cb_idx = mpt2sas_base_register_callback_handler( ++ _scsih_tm_tr_complete); ++ ++ tm_tr_volume_cb_idx = mpt2sas_base_register_callback_handler( ++ _scsih_tm_volume_tr_complete); ++ ++ tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler( ++ _scsih_sas_control_complete); ++ ++ return 0; ++} ++ ++/** ++ * scsih_exit_mpt2sas - exit point for this driver (when it is a module). ++ * ++ * Returns 0 success, anything else error. ++ */ ++void ++scsih_exit_mpt2sas(void) ++{ ++ ++ mpt2sas_base_release_callback_handler(scsi_io_cb_idx); ++ mpt2sas_base_release_callback_handler(tm_cb_idx); ++ mpt2sas_base_release_callback_handler(base_cb_idx); ++ mpt2sas_base_release_callback_handler(port_enable_cb_idx); ++ mpt2sas_base_release_callback_handler(transport_cb_idx); ++ mpt2sas_base_release_callback_handler(scsih_cb_idx); ++ mpt2sas_base_release_callback_handler(config_cb_idx); ++ mpt2sas_base_release_callback_handler(ctl_cb_idx); ++ ++ mpt2sas_base_release_callback_handler(tm_tr_cb_idx); ++ mpt2sas_base_release_callback_handler(tm_tr_volume_cb_idx); ++ mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); ++ ++/* raid transport support */ ++#ifdef MPT2SAS_SCSI ++ raid_class_release(mpt2sas_raid_template_mpt2sas); ++#else ++ raid_class_release(mpt3sas_raid_template_mpt2sas); ++#endif /* MPT2SAS_SCSI */ ++ sas_release_transport(mpt2sas_transport_template); ++} ++ ++/** ++ * _mpt2sas_init - main entry point for this driver. ++ * ++ * Returns 0 success, anything else error. ++ */ ++static int __init ++_mpt2sas_init(void) ++{ ++ int error; ++ ++#ifdef MPT2SAS_SCSI ++ pr_info("%s version %s loaded\n", MPT2SAS_DRIVER_NAME, ++ MPT2SAS_DRIVER_VERSION); ++#else ++ pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME, ++ MPT3SAS_DRIVER_VERSION); ++#endif /* MPT2SAS_SCSI */ ++ ++ mpt2sas_transport_template = ++ sas_attach_transport(&mpt2sas_transport_functions); ++ if (!mpt2sas_transport_template) ++ return -ENODEV; ++ ++#ifdef MPT2SAS_SCSI ++ mpt2sas_raid_template_mpt2sas = raid_class_attach(&mpt2sas_raid_functions); ++ if (!mpt2sas_raid_template_mpt2sas) { ++ sas_release_transport(mpt2sas_transport_template); ++ return -ENODEV; ++ } ++#else ++ mpt3sas_raid_template_mpt2sas = raid_class_attach(&mpt3sas_raid_functions); ++ if (!mpt3sas_raid_template_mpt2sas) { ++ sas_release_transport(mpt2sas_transport_template); ++ return -ENODEV; ++ } ++#endif /* MPT2SAS_SCSI */ ++ ++ error = scsih_init_mpt2sas(); ++ if (error) { ++ scsih_exit_mpt2sas(); ++ return error; ++ } ++ ++ ++#ifdef MPT2SAS_SCSI ++ mpt2sas_ctl_init(1); ++#else ++ mpt2sas_ctl_init(2); ++#endif /* MPT2SAS_SCSI */ ++ ++ error = pci_register_driver(&mpt3sas_driver); ++ if (error) ++ scsih_exit_mpt2sas(); ++ ++ return error; ++} ++ ++/** ++ * _mpt2sas_exit - exit point for this driver (when it is a module). ++ * ++ */ ++static void __exit ++_mpt2sas_exit(void) ++{ ++ pr_info("mpt3sas version %s unloading\n", ++ MPT3SAS_DRIVER_VERSION); ++ ++ pci_unregister_driver(&mpt3sas_driver); ++ ++#ifdef MPT2SAS_SCSI ++ mpt2sas_ctl_exit(1); ++#else ++ mpt2sas_ctl_exit(2); ++#endif /* MPT2SAS_SCSI */ ++ ++ scsih_exit_mpt2sas(); ++} ++ ++module_init(_mpt2sas_init); ++module_exit(_mpt2sas_exit); +diff --git a/drivers/scsi/mpt2sas/mpt3sas_transport.c b/drivers/scsi/mpt2sas/mpt3sas_transport.c +new file mode 100644 +index 0000000..690afa5 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_transport.c +@@ -0,0 +1,2138 @@ ++/* ++ * SAS Transport Layer for MPT (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/** ++ * _transport_sas_node_find_by_sas_address - sas node search ++ * @ioc: per adapter object ++ * @sas_address: sas address of expander or sas host ++ * Context: Calling function should acquire ioc->sas_node_lock. ++ * ++ * Search for either hba phys or expander device based on handle, then returns ++ * the sas_node object. ++ */ ++static struct _sas_node * ++_transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ if (ioc->sas_hba.sas_address == sas_address) ++ return &ioc->sas_hba; ++ else ++ return mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address); ++} ++ ++/** ++ * _transport_convert_phy_link_rate - ++ * @link_rate: link rate returned from mpt firmware ++ * ++ * Convert link_rate from mpi fusion into sas_transport form. ++ */ ++static enum sas_linkrate ++_transport_convert_phy_link_rate(u8 link_rate) ++{ ++ enum sas_linkrate rc; ++ ++ switch (link_rate) { ++ case MPI2_SAS_NEG_LINK_RATE_1_5: ++ rc = SAS_LINK_RATE_1_5_GBPS; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_3_0: ++ rc = SAS_LINK_RATE_3_0_GBPS; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_6_0: ++ rc = SAS_LINK_RATE_6_0_GBPS; ++ break; ++ case MPI25_SAS_NEG_LINK_RATE_12_0: ++ rc = SAS_LINK_RATE_12_0_GBPS; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED: ++ rc = SAS_PHY_DISABLED; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED: ++ rc = SAS_LINK_RATE_FAILED; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR: ++ rc = SAS_SATA_PORT_SELECTOR; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS: ++ rc = SAS_PHY_RESET_IN_PROGRESS; ++ break; ++ ++ default: ++ case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE: ++ case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE: ++ rc = SAS_LINK_RATE_UNKNOWN; ++ break; ++ } ++ return rc; ++} ++ ++/** ++ * _transport_set_identify - set identify for phys and end devices ++ * @ioc: per adapter object ++ * @handle: device handle ++ * @identify: sas identify info ++ * ++ * Populates sas identify info. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_set_identify(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ struct sas_identify *identify) ++{ ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 device_info; ++ u32 ioc_status; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT ++ "handle(0x%04x), ioc_status(0x%04x)\nfailure at %s:%d/%s()!\n", ++ ioc->name, handle, ioc_status, ++ __FILE__, __LINE__, __func__); ++ return -EIO; ++ } ++ ++ memset(identify, 0, sizeof(struct sas_identify)); ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ ++ /* sas_address */ ++ identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ ++ /* phy number of the parent device this device is linked to */ ++ identify->phy_identifier = sas_device_pg0.PhyNum; ++ ++ /* device_type */ ++ switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) { ++ case MPI2_SAS_DEVICE_INFO_NO_DEVICE: ++ identify->device_type = SAS_PHY_UNUSED; ++ break; ++ case MPI2_SAS_DEVICE_INFO_END_DEVICE: ++ identify->device_type = SAS_END_DEVICE; ++ break; ++ case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER: ++ identify->device_type = SAS_EDGE_EXPANDER_DEVICE; ++ break; ++ case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER: ++ identify->device_type = SAS_FANOUT_EXPANDER_DEVICE; ++ break; ++ } ++ ++ /* initiator_port_protocols */ ++ if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_STP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_SATA; ++ ++ /* target_port_protocols */ ++ if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) ++ identify->target_port_protocols |= SAS_PROTOCOL_SSP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) ++ identify->target_port_protocols |= SAS_PROTOCOL_STP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) ++ identify->target_port_protocols |= SAS_PROTOCOL_SMP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ identify->target_port_protocols |= SAS_PROTOCOL_SATA; ++ ++ return 0; ++} ++ ++/** ++ * mpt2sas_transport_done - internal transport layer callback handler. ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Callback handler when sending internal generated transport cmds. ++ * The callback index passed is `ioc->transport_cb_idx` ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (ioc->transport_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->transport_cmds.smid != smid) ++ return 1; ++ ioc->transport_cmds.status |= MPT3_CMD_COMPLETE; ++ if (mpi_reply) { ++ memcpy(ioc->transport_cmds.reply, mpi_reply, ++ mpi_reply->MsgLength*4); ++ ioc->transport_cmds.status |= MPT3_CMD_REPLY_VALID; ++ } ++ ioc->transport_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->transport_cmds.done); ++ return 1; ++} ++ ++/* report manufacture request structure */ ++struct rep_manu_request { ++ u8 smp_frame_type; ++ u8 function; ++ u8 reserved; ++ u8 request_length; ++}; ++ ++/* report manufacture reply structure */ ++struct rep_manu_reply { ++ u8 smp_frame_type; /* 0x41 */ ++ u8 function; /* 0x01 */ ++ u8 function_result; ++ u8 response_length; ++ u16 expander_change_count; ++ u8 reserved0[2]; ++ u8 sas_format; ++ u8 reserved2[3]; ++ u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; ++ u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; ++ u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN]; ++ u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN]; ++ u16 component_id; ++ u8 component_revision_id; ++ u8 reserved3; ++ u8 vendor_specific[8]; ++}; ++ ++/** ++ * transport_expander_report_manufacture - obtain SMP report_manufacture ++ * @ioc: per adapter object ++ * @sas_address: expander sas address ++ * @edev: the sas_expander_device object ++ * ++ * Fills in the sas_expander_device object when SMP port is created. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address, struct sas_expander_device *edev) ++{ ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ struct rep_manu_reply *manufacture_reply; ++ struct rep_manu_request *manufacture_request; ++ int rc; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma; ++ dma_addr_t data_in_dma; ++ size_t data_in_sz; ++ size_t data_out_sz; ++ u16 wait_state_count; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&ioc->transport_cmds.mutex); ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ data_out_sz = sizeof(struct rep_manu_request); ++ data_in_sz = sizeof(struct rep_manu_reply); ++ data_out = pci_alloc_consistent(ioc->pdev, data_out_sz + data_in_sz, ++ &data_out_dma); ++ ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ rc = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ ++ data_in_dma = data_out_dma + sizeof(struct rep_manu_request); ++ ++ manufacture_request = data_out; ++ manufacture_request->smp_frame_type = 0x40; ++ manufacture_request->function = 1; ++ manufacture_request->reserved = 0; ++ manufacture_request->request_length = 0; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->SASAddress = cpu_to_le64(sas_address); ++ mpi_request->RequestDataLength = cpu_to_le16(data_out_sz); ++ psge = &mpi_request->SGL; ++ ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - send to sas_addr(0x%016llx)\n", ++ ioc->name, (unsigned long long)sas_address)); ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - complete\n", ioc->name)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ u8 *tmp; ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - reply data transfer size(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ if (le16_to_cpu(mpi_reply->ResponseDataLength) != ++ sizeof(struct rep_manu_reply)) ++ goto out; ++ ++ manufacture_reply = data_out + sizeof(struct rep_manu_request); ++ strncpy(edev->vendor_id, manufacture_reply->vendor_id, ++ SAS_EXPANDER_VENDOR_ID_LEN); ++ strncpy(edev->product_id, manufacture_reply->product_id, ++ SAS_EXPANDER_PRODUCT_ID_LEN); ++ strncpy(edev->product_rev, manufacture_reply->product_rev, ++ SAS_EXPANDER_PRODUCT_REV_LEN); ++ edev->level = manufacture_reply->sas_format & 1; ++ if (edev->level) { ++ strncpy(edev->component_vendor_id, ++ manufacture_reply->component_vendor_id, ++ SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); ++ tmp = (u8 *)&manufacture_reply->component_id; ++ edev->component_id = tmp[0] << 8 | tmp[1]; ++ edev->component_revision_id = ++ manufacture_reply->component_revision_id; ++ } ++ } else ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - no reply\n", ioc->name)); ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ if (data_out) ++ pci_free_consistent(ioc->pdev, data_out_sz + data_in_sz, ++ data_out, data_out_dma); ++ ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++ ++/** ++ * _transport_delete_port - helper function to removing a port ++ * @ioc: per adapter object ++ * @mpt2sas_port: mpt3sas per port object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_delete_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_port *mpt2sas_port) ++{ ++ u64 sas_address = mpt2sas_port->remote_identify.sas_address; ++ enum sas_device_type device_type = ++ mpt2sas_port->remote_identify.device_type; ++ ++ dev_printk(KERN_INFO, &mpt2sas_port->port->dev, ++ "remove: sas_addr(0x%016llx)\n", ++ (unsigned long long) sas_address); ++ ++ ioc->logging_level |= MPT_DEBUG_TRANSPORT; ++ if (device_type == SAS_END_DEVICE) ++ mpt2sas_device_remove_by_sas_address(ioc, sas_address); ++ else if (device_type == SAS_EDGE_EXPANDER_DEVICE || ++ device_type == SAS_FANOUT_EXPANDER_DEVICE) ++ mpt2sas_expander_remove(ioc, sas_address); ++ ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; ++} ++ ++/** ++ * _transport_delete_phy - helper function to removing single phy from port ++ * @ioc: per adapter object ++ * @mpt2sas_port: mpt3sas per port object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_delete_phy(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy) ++{ ++ u64 sas_address = mpt2sas_port->remote_identify.sas_address; ++ ++ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, ++ "remove: sas_addr(0x%016llx), phy(%d)\n", ++ (unsigned long long) sas_address, mpt2sas_phy->phy_id); ++ ++ list_del(&mpt2sas_phy->port_siblings); ++ mpt2sas_port->num_phys--; ++ sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); ++ mpt2sas_phy->phy_belongs_to_port = 0; ++} ++ ++/** ++ * _transport_add_phy - helper function to adding single phy to port ++ * @ioc: per adapter object ++ * @mpt2sas_port: mpt3sas per port object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_add_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port, ++ struct _sas_phy *mpt2sas_phy) ++{ ++ u64 sas_address = mpt2sas_port->remote_identify.sas_address; ++ ++ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, ++ "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long) ++ sas_address, mpt2sas_phy->phy_id); ++ ++ list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list); ++ mpt2sas_port->num_phys++; ++ sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy); ++ mpt2sas_phy->phy_belongs_to_port = 1; ++} ++ ++/** ++ * _transport_add_phy_to_an_existing_port - adding new phy to existing port ++ * @ioc: per adapter object ++ * @sas_node: sas node object (either expander or sas host) ++ * @mpt2sas_phy: mpt3sas per phy object ++ * @sas_address: sas address of device/expander were phy needs to be added to ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, ++ u64 sas_address) ++{ ++ struct _sas_port *mpt2sas_port; ++ struct _sas_phy *phy_srch; ++ ++ if (mpt2sas_phy->phy_belongs_to_port == 1) ++ return; ++ ++ list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, ++ port_list) { ++ if (mpt2sas_port->remote_identify.sas_address != ++ sas_address) ++ continue; ++ list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, ++ port_siblings) { ++ if (phy_srch == mpt2sas_phy) ++ return; ++ } ++ _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy); ++ return; ++ } ++ ++} ++ ++/** ++ * _transport_del_phy_from_an_existing_port - delete phy from existing port ++ * @ioc: per adapter object ++ * @sas_node: sas node object (either expander or sas host) ++ * @mpt2sas_phy: mpt3sas per phy object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy) ++{ ++ struct _sas_port *mpt2sas_port, *next; ++ struct _sas_phy *phy_srch; ++ ++ if (mpt2sas_phy->phy_belongs_to_port == 0) ++ return; ++ ++ list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, ++ port_list) { ++ list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, ++ port_siblings) { ++ if (phy_srch != mpt2sas_phy) ++ continue; ++ ++ if (mpt2sas_port->num_phys == 1) ++ _transport_delete_port(ioc, mpt2sas_port); ++ else ++ _transport_delete_phy(ioc, mpt2sas_port, ++ mpt2sas_phy); ++ return; ++ } ++ } ++} ++ ++/** ++ * _transport_sanity_check - sanity check when adding a new port ++ * @ioc: per adapter object ++ * @sas_node: sas node object (either expander or sas host) ++ * @sas_address: sas address of device being added ++ * ++ * See the explanation above from _transport_delete_duplicate_port ++ */ ++static void ++_transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, ++ u64 sas_address) ++{ ++ int i; ++ ++ for (i = 0; i < sas_node->num_phys; i++) { ++ if (sas_node->phy[i].remote_identify.sas_address != sas_address) ++ continue; ++ if (sas_node->phy[i].phy_belongs_to_port == 1) ++ _transport_del_phy_from_an_existing_port(ioc, sas_node, ++ &sas_node->phy[i]); ++ } ++} ++ ++/** ++ * mpt2sas_transport_port_add - insert port to the list ++ * @ioc: per adapter object ++ * @handle: handle of attached device ++ * @sas_address: sas address of parent expander or sas host ++ * Context: This function will acquire ioc->sas_node_lock. ++ * ++ * Adding new port object to the sas_node->sas_port_list. ++ * ++ * Returns mpt2sas_port. ++ */ ++struct _sas_port * ++mpt2sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u64 sas_address) ++{ ++ struct _sas_phy *mpt2sas_phy, *next; ++ struct _sas_port *mpt2sas_port; ++ unsigned long flags; ++ struct _sas_node *sas_node; ++ struct sas_rphy *rphy; ++ struct _sas_device *sas_device = NULL; ++ int i; ++ struct sas_port *port; ++ ++ mpt2sas_port = kzalloc(sizeof(struct _sas_port), ++ GFP_KERNEL); ++ if (!mpt2sas_port) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return NULL; ++ } ++ ++ INIT_LIST_HEAD(&mpt2sas_port->port_list); ++ INIT_LIST_HEAD(&mpt2sas_port->phy_list); ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (!sas_node) { ++ pr_err(MPT3SAS_FMT ++ "%s: Could not find parent sas_address(0x%016llx)!\n", ++ ioc->name, __func__, (unsigned long long)sas_address); ++ goto out_fail; ++ } ++ ++ if ((_transport_set_identify(ioc, handle, ++ &mpt2sas_port->remote_identify))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ _transport_sanity_check(ioc, sas_node, ++ mpt2sas_port->remote_identify.sas_address); ++ ++ for (i = 0; i < sas_node->num_phys; i++) { ++ if (sas_node->phy[i].remote_identify.sas_address != ++ mpt2sas_port->remote_identify.sas_address) ++ continue; ++ list_add_tail(&sas_node->phy[i].port_siblings, ++ &mpt2sas_port->phy_list); ++ mpt2sas_port->num_phys++; ++ } ++ ++ if (!mpt2sas_port->num_phys) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ port = sas_port_alloc_num(sas_node->parent_dev); ++ if ((sas_port_add(port))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list, ++ port_siblings) { ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &port->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n", ++ handle, (unsigned long long) ++ mpt2sas_port->remote_identify.sas_address, ++ mpt2sas_phy->phy_id); ++ sas_port_add_phy(port, mpt2sas_phy->phy); ++ mpt2sas_phy->phy_belongs_to_port = 1; ++ } ++ ++ mpt2sas_port->port = port; ++ if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) ++ rphy = sas_end_device_alloc(port); ++ else ++ rphy = sas_expander_alloc(port, ++ mpt2sas_port->remote_identify.device_type); ++ ++ rphy->identify = mpt2sas_port->remote_identify; ++ ++ if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) { ++ sas_device = mpt2sas_get_sdev_by_addr(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ if (!sas_device) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__)); ++ goto out_fail; ++ } ++ sas_device->pend_sas_rphy_add = 1; ++ } ++ ++ if ((sas_rphy_add(rphy))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ } ++ ++ if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) { ++ sas_device->pend_sas_rphy_add = 0; ++ sas_device_put(sas_device); ++ } ++ ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &rphy->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx)\n", ++ handle, (unsigned long long) ++ mpt2sas_port->remote_identify.sas_address); ++ mpt2sas_port->rphy = rphy; ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* fill in report manufacture */ ++ if (mpt2sas_port->remote_identify.device_type == ++ MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || ++ mpt2sas_port->remote_identify.device_type == ++ MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) ++ _transport_expander_report_manufacture(ioc, ++ mpt2sas_port->remote_identify.sas_address, ++ rphy_to_expander_device(rphy)); ++ return mpt2sas_port; ++ ++ out_fail: ++ list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list, ++ port_siblings) ++ list_del(&mpt2sas_phy->port_siblings); ++ kfree(mpt2sas_port); ++ return NULL; ++} ++ ++/** ++ * mpt2sas_transport_port_remove - remove port from the list ++ * @ioc: per adapter object ++ * @sas_address: sas address of attached device ++ * @sas_address_parent: sas address of parent expander or sas host ++ * Context: This function will acquire ioc->sas_node_lock. ++ * ++ * Removing object and freeing associated memory from the ++ * ioc->sas_port_list. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u64 sas_address_parent) ++{ ++ int i; ++ unsigned long flags; ++ struct _sas_port *mpt2sas_port, *next; ++ struct _sas_node *sas_node; ++ u8 found = 0; ++ struct _sas_phy *mpt2sas_phy, *next_phy; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_node = _transport_sas_node_find_by_sas_address(ioc, ++ sas_address_parent); ++ if (!sas_node) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return; ++ } ++ list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, ++ port_list) { ++ if (mpt2sas_port->remote_identify.sas_address != sas_address) ++ continue; ++ found = 1; ++ list_del(&mpt2sas_port->port_list); ++ goto out; ++ } ++ out: ++ if (!found) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return; ++ } ++ ++ for (i = 0; i < sas_node->num_phys; i++) { ++ if (sas_node->phy[i].remote_identify.sas_address == sas_address) ++ memset(&sas_node->phy[i].remote_identify, 0 , ++ sizeof(struct sas_identify)); ++ } ++ ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ list_for_each_entry_safe(mpt2sas_phy, next_phy, ++ &mpt2sas_port->phy_list, port_siblings) { ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &mpt2sas_port->port->dev, ++ "remove: sas_addr(0x%016llx), phy(%d)\n", ++ (unsigned long long) ++ mpt2sas_port->remote_identify.sas_address, ++ mpt2sas_phy->phy_id); ++ mpt2sas_phy->phy_belongs_to_port = 0; ++ sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); ++ list_del(&mpt2sas_phy->port_siblings); ++ } ++ sas_port_delete(mpt2sas_port->port); ++ kfree(mpt2sas_port); ++} ++ ++/** ++ * mpt2sas_transport_add_host_phy - report sas_host phy to transport ++ * @ioc: per adapter object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * @phy_pg0: sas phy page 0 ++ * @parent_dev: parent device class object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy ++ *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev) ++{ ++ struct sas_phy *phy; ++ int phy_index = mpt2sas_phy->phy_id; ++ ++ ++ INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); ++ phy = sas_phy_alloc(parent_dev, phy_index); ++ if (!phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ if ((_transport_set_identify(ioc, mpt2sas_phy->handle, ++ &mpt2sas_phy->identify))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ phy->identify = mpt2sas_phy->identify; ++ mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle); ++ if (mpt2sas_phy->attached_handle) ++ _transport_set_identify(ioc, mpt2sas_phy->attached_handle, ++ &mpt2sas_phy->remote_identify); ++ phy->identify.phy_identifier = mpt2sas_phy->phy_id; ++ phy->negotiated_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); ++ phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( ++ phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( ++ phy_pg0.HwLinkRate >> 4); ++ phy->minimum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate >> 4); ++ ++ if ((sas_phy_add(phy))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &phy->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx)\n" ++ "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", ++ mpt2sas_phy->handle, (unsigned long long) ++ mpt2sas_phy->identify.sas_address, ++ mpt2sas_phy->attached_handle, ++ (unsigned long long) ++ mpt2sas_phy->remote_identify.sas_address); ++ mpt2sas_phy->phy = phy; ++ return 0; ++} ++ ++ ++/** ++ * mpt2sas_transport_add_expander_phy - report expander phy to transport ++ * @ioc: per adapter object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * @expander_pg1: expander page 1 ++ * @parent_dev: parent device class object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy ++ *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, ++ struct device *parent_dev) ++{ ++ struct sas_phy *phy; ++ int phy_index = mpt2sas_phy->phy_id; ++ ++ INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); ++ phy = sas_phy_alloc(parent_dev, phy_index); ++ if (!phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ if ((_transport_set_identify(ioc, mpt2sas_phy->handle, ++ &mpt2sas_phy->identify))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ phy->identify = mpt2sas_phy->identify; ++ mpt2sas_phy->attached_handle = ++ le16_to_cpu(expander_pg1.AttachedDevHandle); ++ if (mpt2sas_phy->attached_handle) ++ _transport_set_identify(ioc, mpt2sas_phy->attached_handle, ++ &mpt2sas_phy->remote_identify); ++ phy->identify.phy_identifier = mpt2sas_phy->phy_id; ++ phy->negotiated_linkrate = _transport_convert_phy_link_rate( ++ expander_pg1.NegotiatedLinkRate & ++ MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); ++ phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( ++ expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( ++ expander_pg1.HwLinkRate >> 4); ++ phy->minimum_linkrate = _transport_convert_phy_link_rate( ++ expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate = _transport_convert_phy_link_rate( ++ expander_pg1.ProgrammedLinkRate >> 4); ++ ++ if ((sas_phy_add(phy))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &phy->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx)\n" ++ "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", ++ mpt2sas_phy->handle, (unsigned long long) ++ mpt2sas_phy->identify.sas_address, ++ mpt2sas_phy->attached_handle, ++ (unsigned long long) ++ mpt2sas_phy->remote_identify.sas_address); ++ mpt2sas_phy->phy = phy; ++ return 0; ++} ++ ++/** ++ * mpt2sas_transport_update_links - refreshing phy link changes ++ * @ioc: per adapter object ++ * @sas_address: sas address of parent expander or sas host ++ * @handle: attached device handle ++ * @phy_numberv: phy number ++ * @link_rate: new link rate ++ * ++ * Returns nothing. ++ */ ++void ++mpt2sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) ++{ ++ unsigned long flags; ++ struct _sas_node *sas_node; ++ struct _sas_phy *mpt2sas_phy; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); ++ if (!sas_node) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return; ++ } ++ ++ mpt2sas_phy = &sas_node->phy[phy_number]; ++ mpt2sas_phy->attached_handle = handle; ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { ++ _transport_set_identify(ioc, handle, ++ &mpt2sas_phy->remote_identify); ++ _transport_add_phy_to_an_existing_port(ioc, sas_node, ++ mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address); ++ } else ++ memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct ++ sas_identify)); ++ ++ if (mpt2sas_phy->phy) ++ mpt2sas_phy->phy->negotiated_linkrate = ++ _transport_convert_phy_link_rate(link_rate); ++ ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, ++ "refresh: parent sas_addr(0x%016llx),\n" ++ "\tlink_rate(0x%02x), phy(%d)\n" ++ "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", ++ (unsigned long long)sas_address, ++ link_rate, phy_number, handle, (unsigned long long) ++ mpt2sas_phy->remote_identify.sas_address); ++} ++ ++static inline void * ++phy_to_ioc(struct sas_phy *phy) ++{ ++ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); ++ return shost_priv(shost); ++} ++ ++static inline void * ++rphy_to_ioc(struct sas_rphy *rphy) ++{ ++ struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); ++ return shost_priv(shost); ++} ++ ++/* report phy error log structure */ ++struct phy_error_log_request { ++ u8 smp_frame_type; /* 0x40 */ ++ u8 function; /* 0x11 */ ++ u8 allocated_response_length; ++ u8 request_length; /* 02 */ ++ u8 reserved_1[5]; ++ u8 phy_identifier; ++ u8 reserved_2[2]; ++}; ++ ++/* report phy error log reply structure */ ++struct phy_error_log_reply { ++ u8 smp_frame_type; /* 0x41 */ ++ u8 function; /* 0x11 */ ++ u8 function_result; ++ u8 response_length; ++ __be16 expander_change_count; ++ u8 reserved_1[3]; ++ u8 phy_identifier; ++ u8 reserved_2[2]; ++ __be32 invalid_dword; ++ __be32 running_disparity_error; ++ __be32 loss_of_dword_sync; ++ __be32 phy_reset_problem; ++}; ++ ++/** ++ * _transport_get_expander_phy_error_log - return expander counters ++ * @ioc: per adapter object ++ * @phy: The sas phy object ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc, ++ struct sas_phy *phy) ++{ ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ struct phy_error_log_request *phy_error_log_request; ++ struct phy_error_log_reply *phy_error_log_reply; ++ int rc; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma; ++ u32 sz; ++ u16 wait_state_count; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&ioc->transport_cmds.mutex); ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ sz = sizeof(struct phy_error_log_request) + ++ sizeof(struct phy_error_log_reply); ++ data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ rc = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ ++ rc = -EINVAL; ++ memset(data_out, 0, sz); ++ phy_error_log_request = data_out; ++ phy_error_log_request->smp_frame_type = 0x40; ++ phy_error_log_request->function = 0x11; ++ phy_error_log_request->request_length = 2; ++ phy_error_log_request->allocated_response_length = 0; ++ phy_error_log_request->phy_identifier = phy->number; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); ++ mpi_request->RequestDataLength = ++ cpu_to_le16(sizeof(struct phy_error_log_request)); ++ psge = &mpi_request->SGL; ++ ++ ioc->build_sg(ioc, psge, data_out_dma, ++ sizeof(struct phy_error_log_request), ++ data_out_dma + sizeof(struct phy_error_log_request), ++ sizeof(struct phy_error_log_reply)); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n", ++ ioc->name, (unsigned long long)phy->identify.sas_address, ++ phy->number)); ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - complete\n", ioc->name)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - reply data transfer size(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ if (le16_to_cpu(mpi_reply->ResponseDataLength) != ++ sizeof(struct phy_error_log_reply)) ++ goto out; ++ ++ phy_error_log_reply = data_out + ++ sizeof(struct phy_error_log_request); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - function_result(%d)\n", ++ ioc->name, phy_error_log_reply->function_result)); ++ ++ phy->invalid_dword_count = ++ be32_to_cpu(phy_error_log_reply->invalid_dword); ++ phy->running_disparity_error_count = ++ be32_to_cpu(phy_error_log_reply->running_disparity_error); ++ phy->loss_of_dword_sync_count = ++ be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); ++ phy->phy_reset_problem_count = ++ be32_to_cpu(phy_error_log_reply->phy_reset_problem); ++ rc = 0; ++ } else ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - no reply\n", ioc->name)); ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ if (data_out) ++ pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); ++ ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _transport_get_linkerrors - return phy counters for both hba and expanders ++ * @phy: The sas phy object ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_transport_get_linkerrors(struct sas_phy *phy) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ unsigned long flags; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasPhyPage1_t phy_pg1; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) ++ return _transport_get_expander_phy_error_log(ioc, phy); ++ ++ /* get hba phy error logs */ ++ if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1, ++ phy->number))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n", ++ ioc->name, phy->number, ++ le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ ++ phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount); ++ phy->running_disparity_error_count = ++ le32_to_cpu(phy_pg1.RunningDisparityErrorCount); ++ phy->loss_of_dword_sync_count = ++ le32_to_cpu(phy_pg1.LossDwordSynchCount); ++ phy->phy_reset_problem_count = ++ le32_to_cpu(phy_pg1.PhyResetProblemCount); ++ return 0; ++} ++ ++/** ++ * _transport_get_enclosure_identifier - ++ * @phy: The sas phy object ++ * ++ * Obtain the enclosure logical id for an expander. ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) ++{ ++ struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy); ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ int rc; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ rphy->identify.sas_address); ++ if (sas_device) { ++ *identifier = sas_device->enclosure_logical_id; ++ rc = 0; ++ sas_device_put(sas_device); ++ } else { ++ *identifier = 0; ++ rc = -ENXIO; ++ } ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ return rc; ++} ++ ++/** ++ * _transport_get_bay_identifier - ++ * @phy: The sas phy object ++ * ++ * Returns the slot id for a device that resides inside an enclosure. ++ */ ++static int ++_transport_get_bay_identifier(struct sas_rphy *rphy) ++{ ++ struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy); ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ int rc; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ rphy->identify.sas_address); ++ if (sas_device) { ++ rc = sas_device->slot; ++ sas_device_put(sas_device); ++ } else { ++ rc = -ENXIO; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ return rc; ++} ++ ++/* phy control request structure */ ++struct phy_control_request { ++ u8 smp_frame_type; /* 0x40 */ ++ u8 function; /* 0x91 */ ++ u8 allocated_response_length; ++ u8 request_length; /* 0x09 */ ++ u16 expander_change_count; ++ u8 reserved_1[3]; ++ u8 phy_identifier; ++ u8 phy_operation; ++ u8 reserved_2[13]; ++ u64 attached_device_name; ++ u8 programmed_min_physical_link_rate; ++ u8 programmed_max_physical_link_rate; ++ u8 reserved_3[6]; ++}; ++ ++/* phy control reply structure */ ++struct phy_control_reply { ++ u8 smp_frame_type; /* 0x41 */ ++ u8 function; /* 0x11 */ ++ u8 function_result; ++ u8 response_length; ++}; ++ ++#define SMP_PHY_CONTROL_LINK_RESET (0x01) ++#define SMP_PHY_CONTROL_HARD_RESET (0x02) ++#define SMP_PHY_CONTROL_DISABLE (0x03) ++ ++/** ++ * _transport_expander_phy_control - expander phy control ++ * @ioc: per adapter object ++ * @phy: The sas phy object ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc, ++ struct sas_phy *phy, u8 phy_operation) ++{ ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ struct phy_control_request *phy_control_request; ++ struct phy_control_reply *phy_control_reply; ++ int rc; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma; ++ u32 sz; ++ u16 wait_state_count; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&ioc->transport_cmds.mutex); ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ sz = sizeof(struct phy_control_request) + ++ sizeof(struct phy_control_reply); ++ data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ rc = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ ++ rc = -EINVAL; ++ memset(data_out, 0, sz); ++ phy_control_request = data_out; ++ phy_control_request->smp_frame_type = 0x40; ++ phy_control_request->function = 0x91; ++ phy_control_request->request_length = 9; ++ phy_control_request->allocated_response_length = 0; ++ phy_control_request->phy_identifier = phy->number; ++ phy_control_request->phy_operation = phy_operation; ++ phy_control_request->programmed_min_physical_link_rate = ++ phy->minimum_linkrate << 4; ++ phy_control_request->programmed_max_physical_link_rate = ++ phy->maximum_linkrate << 4; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); ++ mpi_request->RequestDataLength = ++ cpu_to_le16(sizeof(struct phy_error_log_request)); ++ psge = &mpi_request->SGL; ++ ++ ioc->build_sg(ioc, psge, data_out_dma, ++ sizeof(struct phy_control_request), ++ data_out_dma + sizeof(struct phy_control_request), ++ sizeof(struct phy_control_reply)); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ++ ioc->name, (unsigned long long)phy->identify.sas_address, ++ phy->number, phy_operation)); ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - complete\n", ioc->name)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - reply data transfer size(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ if (le16_to_cpu(mpi_reply->ResponseDataLength) != ++ sizeof(struct phy_control_reply)) ++ goto out; ++ ++ phy_control_reply = data_out + ++ sizeof(struct phy_control_request); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - function_result(%d)\n", ++ ioc->name, phy_control_reply->function_result)); ++ ++ rc = 0; ++ } else ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - no reply\n", ioc->name)); ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ if (data_out) ++ pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); ++ ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _transport_phy_reset - ++ * @phy: The sas phy object ++ * @hard_reset: ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_phy_reset(struct sas_phy *phy, int hard_reset) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ Mpi2SasIoUnitControlReply_t mpi_reply; ++ Mpi2SasIoUnitControlRequest_t mpi_request; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* handle expander phys */ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) ++ return _transport_expander_phy_control(ioc, phy, ++ (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET : ++ SMP_PHY_CONTROL_LINK_RESET); ++ ++ /* handle hba phys */ ++ memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; ++ mpi_request.Operation = hard_reset ? ++ MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET; ++ mpi_request.PhyNum = phy->number; ++ ++ if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, phy->number, le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ ++ return 0; ++} ++ ++/** ++ * _transport_phy_enable - enable/disable phys ++ * @phy: The sas phy object ++ * @enable: enable phy when true ++ * ++ * Only support sas_host direct attached phys. ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_phy_enable(struct sas_phy *phy, int enable) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 sz; ++ int rc = 0; ++ unsigned long flags; ++ int i, discovery_active; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* handle expander phys */ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) ++ return _transport_expander_phy_control(ioc, phy, ++ (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET : ++ SMP_PHY_CONTROL_DISABLE); ++ ++ /* handle hba phys */ ++ ++ /* read sas_iounit page 0 */ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -EIO; ++ goto out; ++ } ++ ++ /* unable to enable/disable phys when when discovery is active */ ++ for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) { ++ if (sas_iounit_pg0->PhyData[i].PortFlags & ++ MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) { ++ pr_err(MPT3SAS_FMT "discovery is active on " \ ++ "port = %d, phy = %d: unable to enable/disable " ++ "phys, try again later!\n", ioc->name, ++ sas_iounit_pg0->PhyData[i].Port, i); ++ discovery_active = 1; ++ } ++ } ++ ++ if (discovery_active) { ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ /* read sas_iounit page 1 */ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -EIO; ++ goto out; ++ } ++ ++ /* copy Port/PortFlags/PhyFlags from page 0 */ ++ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { ++ sas_iounit_pg1->PhyData[i].Port = ++ sas_iounit_pg0->PhyData[i].Port; ++ sas_iounit_pg1->PhyData[i].PortFlags = ++ (sas_iounit_pg0->PhyData[i].PortFlags & ++ MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG); ++ sas_iounit_pg1->PhyData[i].PhyFlags = ++ (sas_iounit_pg0->PhyData[i].PhyFlags & ++ (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED + ++ MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED)); ++ } ++ ++ if (enable) ++ sas_iounit_pg1->PhyData[phy->number].PhyFlags ++ &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; ++ else ++ sas_iounit_pg1->PhyData[phy->number].PhyFlags ++ |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; ++ ++ mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz); ++ ++ /* link reset */ ++ if (enable) ++ _transport_phy_reset(phy, 0); ++ ++ out: ++ kfree(sas_iounit_pg1); ++ kfree(sas_iounit_pg0); ++ return rc; ++} ++ ++/** ++ * _transport_phy_speed - set phy min/max link rates ++ * @phy: The sas phy object ++ * @rates: rates defined in sas_phy_linkrates ++ * ++ * Only support sas_host direct attached phys. ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2SasPhyPage0_t phy_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 sz; ++ int i; ++ int rc = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (!rates->minimum_linkrate) ++ rates->minimum_linkrate = phy->minimum_linkrate; ++ else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) ++ rates->minimum_linkrate = phy->minimum_linkrate_hw; ++ ++ if (!rates->maximum_linkrate) ++ rates->maximum_linkrate = phy->maximum_linkrate; ++ else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) ++ rates->maximum_linkrate = phy->maximum_linkrate_hw; ++ ++ /* handle expander phys */ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) { ++ phy->minimum_linkrate = rates->minimum_linkrate; ++ phy->maximum_linkrate = rates->maximum_linkrate; ++ return _transport_expander_phy_control(ioc, phy, ++ SMP_PHY_CONTROL_LINK_RESET); ++ } ++ ++ /* handle hba phys */ ++ ++ /* sas_iounit page 1 */ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -EIO; ++ goto out; ++ } ++ ++ for (i = 0; i < ioc->sas_hba.num_phys; i++) { ++ if (phy->number != i) { ++ sas_iounit_pg1->PhyData[i].MaxMinLinkRate = ++ (ioc->sas_hba.phy[i].phy->minimum_linkrate + ++ (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); ++ } else { ++ sas_iounit_pg1->PhyData[i].MaxMinLinkRate = ++ (rates->minimum_linkrate + ++ (rates->maximum_linkrate << 4)); ++ } ++ } ++ ++ if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, ++ sz)) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ++ /* link reset */ ++ _transport_phy_reset(phy, 0); ++ ++ /* read phy page 0, then update the rates in the sas transport phy */ ++ if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, ++ phy->number)) { ++ phy->minimum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate >> 4); ++ phy->negotiated_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.NegotiatedLinkRate & ++ MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); ++ } ++ ++ out: ++ kfree(sas_iounit_pg1); ++ return rc; ++} ++ ++/** ++ * _transport_smp_handler - transport portal for smp passthru ++ * @shost: shost object ++ * @rphy: sas transport rphy object ++ * @req: ++ * ++ * This used primarily for smp_utils. ++ * Example: ++ * smp_rep_general /sys/class/bsg/expander-5:0 ++ */ ++static int ++_transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ++ struct request *req) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ int rc, i; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ dma_addr_t dma_addr_in = 0; ++ dma_addr_t dma_addr_out = 0; ++ dma_addr_t pci_dma_in = 0; ++ dma_addr_t pci_dma_out = 0; ++ void *pci_addr_in = NULL; ++ void *pci_addr_out = NULL; ++ u16 wait_state_count; ++ struct request *rsp = req->next_rq; ++ struct bio_vec *bvec = NULL; ++ ++ if (!rsp) { ++ pr_err(MPT3SAS_FMT "%s: the smp response space is missing\n", ++ ioc->name, __func__); ++ return -EINVAL; ++ } ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex); ++ if (rc) ++ return rc; ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ioc->name, ++ __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ /* Check if the request is split across multiple segments */ ++ if (req->bio->bi_vcnt > 1) { ++ u32 offset = 0; ++ ++ /* Allocate memory and copy the request */ ++ pci_addr_out = pci_alloc_consistent(ioc->pdev, ++ blk_rq_bytes(req), &pci_dma_out); ++ if (!pci_addr_out) { ++ pr_info(MPT3SAS_FMT "%s(): PCI Addr out = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ ++ bio_for_each_segment(bvec, req->bio, i) { ++ memcpy(pci_addr_out + offset, ++ page_address(bvec->bv_page) + bvec->bv_offset, ++ bvec->bv_len); ++ offset += bvec->bv_len; ++ } ++ } else { ++ dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), ++ blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(ioc->pdev, dma_addr_out)) { ++ pr_info(MPT3SAS_FMT "%s(): DMA Addr out = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto free_pci; ++ } ++ } ++ ++ /* Check if the response needs to be populated across ++ * multiple segments */ ++ if (rsp->bio->bi_vcnt > 1) { ++ pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp), ++ &pci_dma_in); ++ if (!pci_addr_in) { ++ pr_info(MPT3SAS_FMT "%s(): PCI Addr in = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto unmap; ++ } ++ } else { ++ dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), ++ blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(ioc->pdev, dma_addr_in)) { ++ pr_info(MPT3SAS_FMT "%s(): DMA Addr in = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto unmap; ++ } ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto unmap; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto unmap; ++ } ++ ++ rc = 0; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->SASAddress = (rphy) ? ++ cpu_to_le64(rphy->identify.sas_address) : ++ cpu_to_le64(ioc->sas_hba.sas_address); ++ mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); ++ psge = &mpi_request->SGL; ++ ++ if (req->bio->bi_vcnt > 1) ++ ioc->build_sg(ioc, psge, pci_dma_out, (blk_rq_bytes(req) - 4), ++ pci_dma_in, (blk_rq_bytes(rsp) + 4)); ++ else ++ ioc->build_sg(ioc, psge, dma_addr_out, (blk_rq_bytes(req) - 4), ++ dma_addr_in, (blk_rq_bytes(rsp) + 4)); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - sending smp request\n", ioc->name, __func__)); ++ ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s : timeout\n", ++ __func__, ioc->name); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - complete\n", ioc->name, __func__)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - reply data transfer size(%d)\n", ++ ioc->name, __func__, ++ le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); ++ req->sense_len = sizeof(*mpi_reply); ++ req->resid_len = 0; ++ rsp->resid_len -= ++ le16_to_cpu(mpi_reply->ResponseDataLength); ++ ++ /* check if the resp needs to be copied from the allocated ++ * pci mem */ ++ if (rsp->bio->bi_vcnt > 1) { ++ u32 offset = 0; ++ u32 bytes_to_copy = ++ le16_to_cpu(mpi_reply->ResponseDataLength); ++ bio_for_each_segment(bvec, rsp->bio, i) { ++ if (bytes_to_copy <= bvec->bv_len) { ++ memcpy(page_address(bvec->bv_page) + ++ bvec->bv_offset, pci_addr_in + ++ offset, bytes_to_copy); ++ break; ++ } else { ++ memcpy(page_address(bvec->bv_page) + ++ bvec->bv_offset, pci_addr_in + ++ offset, bvec->bv_len); ++ bytes_to_copy -= bvec->bv_len; ++ } ++ offset += bvec->bv_len; ++ } ++ } ++ } else { ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - no reply\n", ioc->name, __func__)); ++ rc = -ENXIO; ++ } ++ ++ issue_host_reset: ++ if (issue_reset) { ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = -ETIMEDOUT; ++ } ++ ++ unmap: ++ if (dma_addr_out) ++ pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req), ++ PCI_DMA_BIDIRECTIONAL); ++ if (dma_addr_in) ++ pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp), ++ PCI_DMA_BIDIRECTIONAL); ++ ++ free_pci: ++ if (pci_addr_out) ++ pci_free_consistent(ioc->pdev, blk_rq_bytes(req), pci_addr_out, ++ pci_dma_out); ++ ++ if (pci_addr_in) ++ pci_free_consistent(ioc->pdev, blk_rq_bytes(rsp), pci_addr_in, ++ pci_dma_in); ++ ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++struct sas_function_template mpt2sas_transport_functions = { ++ .get_linkerrors = _transport_get_linkerrors, ++ .get_enclosure_identifier = _transport_get_enclosure_identifier, ++ .get_bay_identifier = _transport_get_bay_identifier, ++ .phy_reset = _transport_phy_reset, ++ .phy_enable = _transport_phy_enable, ++ .set_phy_speed = _transport_phy_speed, ++ .smp_handler = _transport_smp_handler, ++}; ++ ++struct scsi_transport_template *mpt2sas_transport_template; +diff --git a/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c +new file mode 100644 +index 0000000..d5038ec +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c +@@ -0,0 +1,434 @@ ++/* ++ * This module provides common API to set Diagnostic trigger for MPT ++ * (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/** ++ * _mpt2sas_raise_sigio - notifiy app ++ * @ioc: per adapter object ++ * @event_data: ++ */ ++static void ++_mpt2sas_raise_sigio(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) ++{ ++ Mpi2EventNotificationReply_t *mpi_reply; ++ u16 sz, event_data_sz; ++ unsigned long flags; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ++ ioc->name, __func__)); ++ ++ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + ++ sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4; ++ mpi_reply = kzalloc(sz, GFP_KERNEL); ++ if (!mpi_reply) ++ goto out; ++ mpi_reply->Event = cpu_to_le16(MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED); ++ event_data_sz = (sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4) / 4; ++ mpi_reply->EventDataLength = cpu_to_le16(event_data_sz); ++ memcpy(&mpi_reply->EventData, event_data, ++ sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: add to driver event log\n", ++ ioc->name, __func__)); ++ mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); ++ kfree(mpi_reply); ++ out: ++ ++ /* clearing the diag_trigger_active flag */ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: clearing diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ ioc->diag_trigger_active = 0; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_process_trigger_data - process the event data for the trigger ++ * @ioc: per adapter object ++ * @event_data: ++ */ ++void ++mpt2sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) ++{ ++ u8 issue_reset = 0; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ++ ioc->name, __func__)); ++ ++ /* release the diag buffer trace */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: release trace diag buffer\n", ioc->name, __func__)); ++ mpt2sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, ++ &issue_reset); ++ } ++ ++ _mpt2sas_raise_sigio(ioc, event_data); ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_master - Master trigger handler ++ * @ioc: per adapter object ++ * @trigger_bitmask: ++ * ++ */ ++void ++mpt2sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, u32 trigger_bitmask) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ unsigned long flags; ++ u8 found_match = 0; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT || ++ trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET) ++ goto by_pass_checks; ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ by_pass_checks: ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - trigger_bitmask = 0x%08x\n", ++ ioc->name, __func__, trigger_bitmask)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ if (ioc->diag_trigger_master.MasterData & trigger_bitmask) { ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_MASTER; ++ event_data.u.master.MasterData = trigger_bitmask; ++ ++ if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT || ++ trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET) ++ _mpt2sas_raise_sigio(ioc, &event_data); ++ else ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_event - Event trigger handler ++ * @ioc: per adapter object ++ * @event: ++ * @log_entry_qualifier: ++ * ++ */ ++void ++mpt2sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event, ++ u16 log_entry_qualifier) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ struct SL_WH_EVENT_TRIGGER_T *event_trigger; ++ int i; ++ unsigned long flags; ++ u8 found_match; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - event = 0x%04x, log_entry_qualifier = 0x%04x\n", ++ ioc->name, __func__, event, log_entry_qualifier)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ event_trigger = ioc->diag_trigger_event.EventTriggerEntry; ++ for (i = 0 , found_match = 0; i < ioc->diag_trigger_event.ValidEntries ++ && !found_match; i++, event_trigger++) { ++ if (event_trigger->EventValue != event) ++ continue; ++ if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { ++ if (event_trigger->LogEntryQualifier == ++ log_entry_qualifier) ++ found_match = 1; ++ continue; ++ } ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_EVENT; ++ event_data.u.event.EventValue = event; ++ event_data.u.event.LogEntryQualifier = log_entry_qualifier; ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_scsi - SCSI trigger handler ++ * @ioc: per adapter object ++ * @sense_key: ++ * @asc: ++ * @ascq: ++ * ++ */ ++void ++mpt2sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, u8 asc, ++ u8 ascq) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ struct SL_WH_SCSI_TRIGGER_T *scsi_trigger; ++ int i; ++ unsigned long flags; ++ u8 found_match; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - sense_key = 0x%02x, asc = 0x%02x, ascq = 0x%02x\n", ++ ioc->name, __func__, sense_key, asc, ascq)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ scsi_trigger = ioc->diag_trigger_scsi.SCSITriggerEntry; ++ for (i = 0 , found_match = 0; i < ioc->diag_trigger_scsi.ValidEntries ++ && !found_match; i++, scsi_trigger++) { ++ if (scsi_trigger->SenseKey != sense_key) ++ continue; ++ if (!(scsi_trigger->ASC == 0xFF || scsi_trigger->ASC == asc)) ++ continue; ++ if (!(scsi_trigger->ASCQ == 0xFF || scsi_trigger->ASCQ == ascq)) ++ continue; ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_SCSI; ++ event_data.u.scsi.SenseKey = sense_key; ++ event_data.u.scsi.ASC = asc; ++ event_data.u.scsi.ASCQ = ascq; ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_mpi - MPI trigger handler ++ * @ioc: per adapter object ++ * @ioc_status: ++ * @loginfo: ++ * ++ */ ++void ++mpt2sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status, u32 loginfo) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ struct SL_WH_MPI_TRIGGER_T *mpi_trigger; ++ int i; ++ unsigned long flags; ++ u8 found_match; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - ioc_status = 0x%04x, loginfo = 0x%08x\n", ++ ioc->name, __func__, ioc_status, loginfo)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ mpi_trigger = ioc->diag_trigger_mpi.MPITriggerEntry; ++ for (i = 0 , found_match = 0; i < ioc->diag_trigger_mpi.ValidEntries ++ && !found_match; i++, mpi_trigger++) { ++ if (mpi_trigger->IOCStatus != ioc_status) ++ continue; ++ if (!(mpi_trigger->IocLogInfo == 0xFFFFFFFF || ++ mpi_trigger->IocLogInfo == loginfo)) ++ continue; ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_MPI; ++ event_data.u.mpi.IOCStatus = ioc_status; ++ event_data.u.mpi.IocLogInfo = loginfo; ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h +new file mode 100644 +index 0000000..6586a46 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h +@@ -0,0 +1,194 @@ ++/* ++ * This is the Fusion MPT base driver providing common API layer interface ++ * to set Diagnostic triggers for MPT (Message Passing Technology) based ++ * controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ /* Diagnostic Trigger Configuration Data Structures */ ++ ++#ifndef MPT3SAS_TRIGGER_DIAG_H_INCLUDED ++#define MPT3SAS_TRIGGER_DIAG_H_INCLUDED ++ ++/* limitation on number of entries */ ++#define NUM_VALID_ENTRIES (20) ++ ++/* trigger types */ ++#define MPT3SAS_TRIGGER_MASTER (1) ++#define MPT3SAS_TRIGGER_EVENT (2) ++#define MPT3SAS_TRIGGER_SCSI (3) ++#define MPT3SAS_TRIGGER_MPI (4) ++ ++/* trigger names */ ++#define MASTER_TRIGGER_FILE_NAME "diag_trigger_master" ++#define EVENT_TRIGGERS_FILE_NAME "diag_trigger_event" ++#define SCSI_TRIGGERS_FILE_NAME "diag_trigger_scsi" ++#define MPI_TRIGGER_FILE_NAME "diag_trigger_mpi" ++ ++/* master trigger bitmask */ ++#define MASTER_TRIGGER_FW_FAULT (0x00000001) ++#define MASTER_TRIGGER_ADAPTER_RESET (0x00000002) ++#define MASTER_TRIGGER_TASK_MANAGMENT (0x00000004) ++#define MASTER_TRIGGER_DEVICE_REMOVAL (0x00000008) ++ ++/* fake firmware event for tigger */ ++#define MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED (0x6E) ++ ++/** ++ * MasterTrigger is a single U32 passed to/from sysfs. ++ * ++ * Bit Flags (enables) include: ++ * 1. FW Faults ++ * 2. Adapter Reset issued by driver ++ * 3. TMs ++ * 4. Device Remove Event sent by FW ++ */ ++ ++struct SL_WH_MASTER_TRIGGER_T { ++ uint32_t MasterData; ++}; ++ ++/** ++ * struct SL_WH_EVENT_TRIGGER_T - Definition of an event trigger element ++ * @EventValue: Event Code to trigger on ++ * @LogEntryQualifier: Type of FW event that logged (Log Entry Added Event only) ++ * ++ * Defines an event that should induce a DIAG_TRIGGER driver event if observed. ++ */ ++struct SL_WH_EVENT_TRIGGER_T { ++ uint16_t EventValue; ++ uint16_t LogEntryQualifier; ++}; ++ ++/** ++ * struct SL_WH_EVENT_TRIGGERS_T - Structure passed to/from sysfs containing a ++ * list of Event Triggers to be monitored for. ++ * @ValidEntries: Number of _SL_WH_EVENT_TRIGGER_T structures contained in this ++ * structure. ++ * @EventTriggerEntry: List of Event trigger elements. ++ * ++ * This binary structure is transferred via sysfs to get/set Event Triggers ++ * in the Linux Driver. ++ */ ++ ++struct SL_WH_EVENT_TRIGGERS_T { ++ uint32_t ValidEntries; ++ struct SL_WH_EVENT_TRIGGER_T EventTriggerEntry[NUM_VALID_ENTRIES]; ++}; ++ ++/** ++ * struct SL_WH_SCSI_TRIGGER_T - Definition of a SCSI trigger element ++ * @ASCQ: Additional Sense Code Qualifier. Can be specific or 0xFF for ++ * wildcard. ++ * @ASC: Additional Sense Code. Can be specific or 0xFF for wildcard ++ * @SenseKey: SCSI Sense Key ++ * ++ * Defines a sense key (single or many variants) that should induce a ++ * DIAG_TRIGGER driver event if observed. ++ */ ++struct SL_WH_SCSI_TRIGGER_T { ++ U8 ASCQ; ++ U8 ASC; ++ U8 SenseKey; ++ U8 Reserved; ++}; ++ ++/** ++ * struct SL_WH_SCSI_TRIGGERS_T - Structure passed to/from sysfs containing a ++ * list of SCSI sense codes that should trigger a DIAG_SERVICE event when ++ * observed. ++ * @ValidEntries: Number of _SL_WH_SCSI_TRIGGER_T structures contained in this ++ * structure. ++ * @SCSITriggerEntry: List of SCSI Sense Code trigger elements. ++ * ++ * This binary structure is transferred via sysfs to get/set SCSI Sense Code ++ * Triggers in the Linux Driver. ++ */ ++struct SL_WH_SCSI_TRIGGERS_T { ++ uint32_t ValidEntries; ++ struct SL_WH_SCSI_TRIGGER_T SCSITriggerEntry[NUM_VALID_ENTRIES]; ++}; ++ ++/** ++ * struct SL_WH_MPI_TRIGGER_T - Definition of an MPI trigger element ++ * @IOCStatus: MPI IOCStatus ++ * @IocLogInfo: MPI IocLogInfo. Can be specific or 0xFFFFFFFF for wildcard ++ * ++ * Defines a MPI IOCStatus/IocLogInfo pair that should induce a DIAG_TRIGGER ++ * driver event if observed. ++ */ ++struct SL_WH_MPI_TRIGGER_T { ++ uint16_t IOCStatus; ++ uint16_t Reserved; ++ uint32_t IocLogInfo; ++}; ++ ++/** ++ * struct SL_WH_MPI_TRIGGERS_T - Structure passed to/from sysfs containing a ++ * list of MPI IOCStatus/IocLogInfo pairs that should trigger a DIAG_SERVICE ++ * event when observed. ++ * @ValidEntries: Number of _SL_WH_MPI_TRIGGER_T structures contained in this ++ * structure. ++ * @MPITriggerEntry: List of MPI IOCStatus/IocLogInfo trigger elements. ++ * ++ * This binary structure is transferred via sysfs to get/set MPI Error Triggers ++ * in the Linux Driver. ++ */ ++struct SL_WH_MPI_TRIGGERS_T { ++ uint32_t ValidEntries; ++ struct SL_WH_MPI_TRIGGER_T MPITriggerEntry[NUM_VALID_ENTRIES]; ++}; ++ ++/** ++ * struct SL_WH_TRIGGERS_EVENT_DATA_T - event data for trigger ++ * @trigger_type: trigger type (see MPT3SAS_TRIGGER_XXXX) ++ * @u: trigger condition that caused trigger to be sent ++ */ ++struct SL_WH_TRIGGERS_EVENT_DATA_T { ++ uint32_t trigger_type; ++ union { ++ struct SL_WH_MASTER_TRIGGER_T master; ++ struct SL_WH_EVENT_TRIGGER_T event; ++ struct SL_WH_SCSI_TRIGGER_T scsi; ++ struct SL_WH_MPI_TRIGGER_T mpi; ++ } u; ++}; ++#endif /* MPT3SAS_TRIGGER_DIAG_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_warpdrive.c b/drivers/scsi/mpt2sas/mpt3sas_warpdrive.c +new file mode 100644 +index 0000000..2542263 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_warpdrive.c +@@ -0,0 +1,344 @@ ++/* ++ * Scsi Host Layer for MPT (Message Passing Technology) based controllers ++ * ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2015 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/** ++ * _warpdrive_disable_ddio - Disable direct I/O for all the volumes ++ * @ioc: per adapter object ++ */ ++static void ++_warpdrive_disable_ddio(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidVolPage1_t vol_pg1; ++ Mpi2ConfigReply_t mpi_reply; ++ struct _raid_device *raid_device; ++ u16 handle; ++ u16 ioc_status; ++ unsigned long flags; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ break; ++ handle = le16_to_cpu(vol_pg1.DevHandle); ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device) ++ raid_device->direct_io_enabled = 0; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++ return; ++} ++ ++ ++/** ++ * mpt2sas_get_num_volumes - Get number of volumes in the ioc ++ * @ioc: per adapter object ++ */ ++u8 ++mpt2sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidVolPage1_t vol_pg1; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 handle; ++ u8 vol_cnt = 0; ++ u16 ioc_status; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ break; ++ vol_cnt++; ++ handle = le16_to_cpu(vol_pg1.DevHandle); ++ } ++ return vol_cnt; ++} ++ ++ ++/** ++ * mpt2sas_init_warpdrive_properties - Set properties for warpdrive direct I/O. ++ * @ioc: per adapter object ++ * @raid_device: the raid_device object ++ */ ++void ++mpt2sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ Mpi2RaidVolPage0_t *vol_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 sz; ++ u8 num_pds, count; ++ unsigned long stripe_sz, block_sz; ++ u8 stripe_exp, block_exp; ++ u64 dev_max_lba; ++ ++ if (!ioc->is_warpdrive) ++ return; ++ ++ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "globally as drives are exposed\n", ioc->name); ++ return; ++ } ++ if (mpt2sas_get_num_volumes(ioc) > 1) { ++ _warpdrive_disable_ddio(ioc); ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "globally as number of drives > 1\n", ioc->name); ++ return; ++ } ++ if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, ++ &num_pds)) || !num_pds) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "Failure in computing number of drives\n", ioc->name); ++ return; ++ } ++ ++ sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * ++ sizeof(Mpi2RaidVol0PhysDisk_t)); ++ vol_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!vol_pg0) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "Memory allocation failure for RVPG0\n", ioc->name); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "Failure in retrieving RVPG0\n", ioc->name); ++ kfree(vol_pg0); ++ return; ++ } ++ ++ /* ++ * WARPDRIVE:If number of physical disks in a volume exceeds the max pds ++ * assumed for WARPDRIVE, disable direct I/O ++ */ ++ if (num_pds > MPT_MAX_WARPDRIVE_PDS) { ++ pr_warn(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x): num_mem=%d, " ++ "max_mem_allowed=%d\n", ioc->name, raid_device->handle, ++ num_pds, MPT_MAX_WARPDRIVE_PDS); ++ kfree(vol_pg0); ++ return; ++ } ++ for (count = 0; count < num_pds; count++) { ++ if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, ++ vol_pg0->PhysDisk[count].PhysDiskNum) || ++ pd_pg0.DevHandle == MPT3SAS_INVALID_DEVICE_HANDLE) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is " ++ "disabled for the drive with handle(0x%04x) member" ++ "handle retrieval failed for member number=%d\n", ++ ioc->name, raid_device->handle, ++ vol_pg0->PhysDisk[count].PhysDiskNum); ++ goto out_error; ++ } ++ /* Disable direct I/O if member drive lba exceeds 4 bytes */ ++ dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA); ++ if (dev_max_lba >> 32) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is " ++ "disabled for the drive with handle(0x%04x) member" ++ " handle (0x%04x) unsupported max lba 0x%016llx\n", ++ ioc->name, raid_device->handle, ++ le16_to_cpu(pd_pg0.DevHandle), ++ (unsigned long long)dev_max_lba); ++ goto out_error; ++ } ++ ++ raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle); ++ } ++ ++ /* ++ * Assumption for WD: Direct I/O is not supported if the volume is ++ * not RAID0 ++ */ ++ if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x): type=%d, " ++ "s_sz=%uK, blk_size=%u\n", ioc->name, ++ raid_device->handle, raid_device->volume_type, ++ (le32_to_cpu(vol_pg0->StripeSize) * ++ le16_to_cpu(vol_pg0->BlockSize)) / 1024, ++ le16_to_cpu(vol_pg0->BlockSize)); ++ goto out_error; ++ } ++ ++ stripe_sz = le32_to_cpu(vol_pg0->StripeSize); ++ stripe_exp = find_first_bit(&stripe_sz, 32); ++ if (stripe_exp == 32) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x) invalid stripe sz %uK\n", ++ ioc->name, raid_device->handle, ++ (le32_to_cpu(vol_pg0->StripeSize) * ++ le16_to_cpu(vol_pg0->BlockSize)) / 1024); ++ goto out_error; ++ } ++ raid_device->stripe_exponent = stripe_exp; ++ block_sz = le16_to_cpu(vol_pg0->BlockSize); ++ block_exp = find_first_bit(&block_sz, 16); ++ if (block_exp == 16) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x) invalid block sz %u\n", ++ ioc->name, raid_device->handle, ++ le16_to_cpu(vol_pg0->BlockSize)); ++ goto out_error; ++ } ++ raid_device->block_exponent = block_exp; ++ raid_device->direct_io_enabled = 1; ++ ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is Enabled for the drive" ++ " with handle(0x%04x)\n", ioc->name, raid_device->handle); ++ /* ++ * WARPDRIVE: Though the following fields are not used for direct IO, ++ * stored for future purpose: ++ */ ++ raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA); ++ raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize); ++ raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize); ++ ++ ++ kfree(vol_pg0); ++ return; ++ ++out_error: ++ raid_device->direct_io_enabled = 0; ++ for (count = 0; count < num_pds; count++) ++ raid_device->pd_handle[count] = 0; ++ kfree(vol_pg0); ++ return; ++} ++ ++/** ++ * mpt2sas_scsi_direct_io_get - returns direct io flag ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns the smid stored scmd pointer. ++ */ ++inline u8 ++mpt2sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return ioc->scsi_lookup[smid - 1].direct_io; ++} ++ ++/** ++ * mpt2sas_scsi_direct_io_set - sets direct io flag ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @direct_io: Zero or non-zero value to set in the direct_io flag ++ * ++ * Returns Nothing. ++ */ ++inline void ++mpt2sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io) ++{ ++ ioc->scsi_lookup[smid - 1].direct_io = direct_io; ++} ++ ++/** ++ * mpt2sas_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O ++ * @ioc: per adapter object ++ * @scmd: pointer to scsi command object ++ * @raid_device: pointer to raid device data structure ++ * @mpi_request: pointer to the SCSI_IO reqest message frame ++ * @smid: system request message index ++ * ++ * Returns nothing ++ */ ++void ++mpt2sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, ++ u16 smid) ++{ ++ sector_t v_lba, p_lba, stripe_off, column, io_size; ++ u32 stripe_sz, stripe_exp; ++ u8 num_pds, cmd = scmd->cmnd[0]; ++ ++ if (cmd != READ_10 && cmd != WRITE_10 && ++ cmd != READ_16 && cmd != WRITE_16) ++ return; ++ ++ if (cmd == READ_10 || cmd == WRITE_10) ++ v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]); ++ else ++ v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]); ++ ++ io_size = scsi_bufflen(scmd) >> raid_device->block_exponent; ++ ++ if (v_lba + io_size - 1 > raid_device->max_lba) ++ return; ++ ++ stripe_sz = raid_device->stripe_sz; ++ stripe_exp = raid_device->stripe_exponent; ++ stripe_off = v_lba & (stripe_sz - 1); ++ ++ /* Return unless IO falls within a stripe */ ++ if (stripe_off + io_size > stripe_sz) ++ return; ++ ++ num_pds = raid_device->num_pds; ++ p_lba = v_lba >> stripe_exp; ++ column = sector_div(p_lba, num_pds); ++ p_lba = (p_lba << stripe_exp) + stripe_off; ++ mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]); ++ ++ if (cmd == READ_10 || cmd == WRITE_10) ++ put_unaligned_be32(lower_32_bits(p_lba), ++ &mpi_request->CDB.CDB32[2]); ++ else ++ put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]); ++ ++ mpt2sas_scsi_direct_io_set(ioc, smid, 1); ++} +diff --git a/drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c b/drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c +new file mode 100644 +index 0000000..7852050 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c +@@ -0,0 +1,4 @@ ++#define MPT2SAS_SCSI ++/* This directive is used to create the mpt2sas driver from the mpt3sas sources */ ++ ++#include "mpt3sas_scsih.c" +diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig +index 5743420..9aa67e2 100644 +--- a/drivers/scsi/mpt3sas/Kconfig ++++ b/drivers/scsi/mpt3sas/Kconfig +@@ -40,14 +40,6 @@ + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + # USA. + +-config SCSI_MPT2SAS +- tristate "LSI MPT Fusion SAS 2.0 Device Driver" +- depends on PCI && SCSI +- select SCSI_SAS_ATTRS +- select RAID_ATTRS +- ---help--- +- This driver supports PCI-Express SAS 6Gb/s Host Adapters. +- + config SCSI_MPT3SAS + tristate "LSI MPT Fusion SAS 3.0 Device Driver" + depends on PCI && SCSI +@@ -56,18 +48,6 @@ config SCSI_MPT3SAS + ---help--- + This driver supports PCI-Express SAS 12Gb/s Host Adapters. + +-config SCSI_MPT2SAS_MAX_SGE +- int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)" +- depends on PCI && SCSI && SCSI_MPT3SAS +- default "128" +- range 16 256 +- ---help--- +- This option allows you to specify the maximum number of scatter- +- gather entries per I/O. The driver default is 128, which matches +- MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this +- can be 256. However, it may decreased down to 16. Decreasing this +- parameter will reduce memory requirements on a per controller instance. +- + config SCSI_MPT3SAS_MAX_SGE + int "LSI MPT Fusion SAS 3.0 Max number of SG Entries (16 - 256)" + depends on PCI && SCSI && SCSI_MPT3SAS +diff --git a/drivers/scsi/mpt3sas/Makefile b/drivers/scsi/mpt3sas/Makefile +index 0b90877..450b84b 100644 +--- a/drivers/scsi/mpt3sas/Makefile ++++ b/drivers/scsi/mpt3sas/Makefile +@@ -1,6 +1,5 @@ + # mpt2-3sas makefile + +-obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o + obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o + + obj-m += mpt3sas.o +@@ -12,11 +11,3 @@ mpt3sas-y += mpt3sas_base.o \ + mpt3sas_trigger_diag.o \ + mpt3sas_warpdrive.o + +-obj-m += mpt2sas.o +-mpt2sas-y += mpt3sas_base.o \ +- mpt3sas_config.o \ +- wrapper_mpt3sas_scsih.o \ +- mpt3sas_transport.o \ +- mpt3sas_ctl.o \ +- mpt3sas_trigger_diag.o \ +- mpt3sas_warpdrive.o +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch b/kernel-rt/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch new file mode 100644 index 000000000..ce29a6a9f --- /dev/null +++ b/kernel-rt/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch @@ -0,0 +1,114 @@ +From 5f99bc2a1bed716a9b602e6fdd6e240a6c61260e Mon Sep 17 00:00:00 2001 +Message-Id: <5f99bc2a1bed716a9b602e6fdd6e240a6c61260e.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Wed, 19 Jul 2017 02:25:15 -0500 +Subject: [PATCH 18/26] Fix cacheinfo compilation issues for 3.10 + +Had to revert commit 7cc277b489b4fe91f42eb596b282879c2d13152e: +"Install the callbacks via the state machine and let the core invoke +the callbacks on the already online CPUs. No functional change." +There is no hotplug state machine in 3.10 kernel. +Also implemented cpumap_print_to_pagebuf() function in place. + +Signed-off-by: Jim Somerville +--- + drivers/base/cacheinfo.c | 65 ++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 49 insertions(+), 16 deletions(-) + +diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c +index eb3af27..c924f7e 100644 +--- a/drivers/base/cacheinfo.c ++++ b/drivers/base/cacheinfo.c +@@ -383,7 +383,12 @@ static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + const struct cpumask *mask = &this_leaf->shared_cpu_map; + +- return cpumap_print_to_pagebuf(list, buf, mask); ++ int len = list? ++ cpulist_scnprintf(buf, PAGE_SIZE-2, mask) : ++ cpumask_scnprintf(buf, PAGE_SIZE-2, mask); ++ buf[len++] = '\n'; ++ buf[len] = '\0'; ++ return len; + } + + static ssize_t shared_cpu_map_show(struct device *dev, +@@ -633,30 +638,58 @@ err: + return rc; + } + +-static int cacheinfo_cpu_online(unsigned int cpu) ++static void cache_remove_dev(unsigned int cpu) + { +- int rc = detect_cache_attributes(cpu); ++ if (!cpumask_test_cpu(cpu, &cache_dev_map)) ++ return; ++ cpumask_clear_cpu(cpu, &cache_dev_map); + +- if (rc) +- return rc; +- rc = cache_add_dev(cpu); +- if (rc) +- free_cache_attributes(cpu); +- return rc; ++ cpu_cache_sysfs_exit(cpu); + } + +-static int cacheinfo_cpu_pre_down(unsigned int cpu) ++static int cacheinfo_cpu_callback(struct notifier_block *nfb, ++ unsigned long action, void *hcpu) + { +- if (cpumask_test_and_clear_cpu(cpu, &cache_dev_map)) +- cpu_cache_sysfs_exit(cpu); ++ unsigned int cpu = (unsigned long)hcpu; ++ int rc = 0; + +- free_cache_attributes(cpu); +- return 0; ++ switch (action & ~CPU_TASKS_FROZEN) { ++ case CPU_ONLINE: ++ rc = detect_cache_attributes(cpu); ++ if (!rc) ++ rc = cache_add_dev(cpu); ++ break; ++ case CPU_DEAD: ++ cache_remove_dev(cpu); ++ if (per_cpu_cacheinfo(cpu)) ++ free_cache_attributes(cpu); ++ break; ++ } ++ return notifier_from_errno(rc); + } + + static int __init cacheinfo_sysfs_init(void) + { +- return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/cacheinfo:online", +- cacheinfo_cpu_online, cacheinfo_cpu_pre_down); ++ int cpu, rc = 0; ++ ++ cpu_notifier_register_begin(); ++ ++ for_each_online_cpu(cpu) { ++ rc = detect_cache_attributes(cpu); ++ if (rc) ++ goto out; ++ rc = cache_add_dev(cpu); ++ if (rc) { ++ free_cache_attributes(cpu); ++ pr_err("error populating cacheinfo..cpu%d\n", cpu); ++ goto out; ++ } ++ } ++ __hotcpu_notifier(cacheinfo_cpu_callback, 0); ++ ++out: ++ cpu_notifier_register_done(); ++ return rc; + } ++ + device_initcall(cacheinfo_sysfs_init); +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch b/kernel-rt/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch new file mode 100644 index 000000000..df6007a2e --- /dev/null +++ b/kernel-rt/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch @@ -0,0 +1,91 @@ +From f944a307041bf3d43dbc9ca3484982dfec4340f5 Mon Sep 17 00:00:00 2001 +From: Wanpeng Li +Date: Thu, 11 May 2017 18:12:05 -0700 +Subject: [PATCH 1/1] KVM: x86: Fix potential preemption when get the current + kvmclock timestamp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + BUG: using __this_cpu_read() in preemptible [00000000] code: qemu-system-x86/2809 + caller is __this_cpu_preempt_check+0x13/0x20 + CPU: 2 PID: 2809 Comm: qemu-system-x86 Not tainted 4.11.0+ #13 + Call Trace: + dump_stack+0x99/0xce + check_preemption_disabled+0xf5/0x100 + __this_cpu_preempt_check+0x13/0x20 + get_kvmclock_ns+0x6f/0x110 [kvm] + get_time_ref_counter+0x5d/0x80 [kvm] + kvm_hv_process_stimers+0x2a1/0x8a0 [kvm] + ? kvm_hv_process_stimers+0x2a1/0x8a0 [kvm] + ? kvm_arch_vcpu_ioctl_run+0xac9/0x1ce0 [kvm] + kvm_arch_vcpu_ioctl_run+0x5bf/0x1ce0 [kvm] + kvm_vcpu_ioctl+0x384/0x7b0 [kvm] + ? kvm_vcpu_ioctl+0x384/0x7b0 [kvm] + ? __fget+0xf3/0x210 + do_vfs_ioctl+0xa4/0x700 + ? __fget+0x114/0x210 + SyS_ioctl+0x79/0x90 + entry_SYSCALL_64_fastpath+0x23/0xc2 + RIP: 0033:0x7f9d164ed357 + ? __this_cpu_preempt_check+0x13/0x20 + +This can be reproduced by run kvm-unit-tests/hyperv_stimer.flat w/ +CONFIG_PREEMPT and CONFIG_DEBUG_PREEMPT enabled. + +Safe access to per-CPU data requires a couple of constraints, though: the +thread working with the data cannot be preempted and it cannot be migrated +while it manipulates per-CPU variables. If the thread is preempted, the +thread that replaces it could try to work with the same variables; migration +to another CPU could also cause confusion. However there is no preemption +disable when reads host per-CPU tsc rate to calculate the current kvmclock +timestamp. + +This patch fixes it by utilizing get_cpu/put_cpu pair to guarantee both +__this_cpu_read() and rdtsc() are not preempted. + +Cc: Paolo Bonzini +Cc: Radim Krčmář +Signed-off-by: Wanpeng Li +Reviewed-by: Paolo Bonzini +Cc: stable@vger.kernel.org +Signed-off-by: Radim Krčmář +Signed-off-by: Alex Kozyrev +--- + arch/x86/kvm/x86.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 8babcb5..84925dc 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1743,6 +1743,7 @@ u64 get_kvmclock_ns(struct kvm *kvm) + { + struct kvm_arch *ka = &kvm->arch; + struct pvclock_vcpu_time_info hv_clock; ++ u64 ret; + + spin_lock(&ka->pvclock_gtod_sync_lock); + if (!ka->use_master_clock) { +@@ -1753,10 +1754,17 @@ u64 get_kvmclock_ns(struct kvm *kvm) + hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset; + spin_unlock(&ka->pvclock_gtod_sync_lock); + ++ /* both __this_cpu_read() and rdtsc() should be on the same cpu */ ++ get_cpu(); ++ + kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL, + &hv_clock.tsc_shift, + &hv_clock.tsc_to_system_mul); +- return __pvclock_read_cycles(&hv_clock, rdtsc()); ++ ret = __pvclock_read_cycles(&hv_clock, rdtsc()); ++ ++ put_cpu(); ++ ++ return ret; + } + + static int kvm_guest_time_update(struct kvm_vcpu *v) +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Make-kernel-start-eth-devices-at-offset.patch b/kernel-rt/centos/patches/Make-kernel-start-eth-devices-at-offset.patch new file mode 100644 index 000000000..e26956ef7 --- /dev/null +++ b/kernel-rt/centos/patches/Make-kernel-start-eth-devices-at-offset.patch @@ -0,0 +1,37 @@ +From 0f49e3a41bc1edcea227deed767bf24af144b691 Mon Sep 17 00:00:00 2001 +Message-Id: <0f49e3a41bc1edcea227deed767bf24af144b691.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Thu, 12 May 2016 18:00:00 -0400 +Subject: [PATCH 06/26] Make kernel start eth devices at offset + +In order to avoid naming collisions, we want to make the kernel +start naming its "ethX" devices at eth1000 instead of eth0. This +will let us rename to a range starting at eth0. + +Signed-off-by: Jim Somerville +--- + net/core/dev.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 6e016cf..ca3ef1a 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1057,6 +1057,12 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + set_bit(i, inuse); + } + ++ /* WRS extension, want kernel to start at eth1000 */ ++ if (strcmp(name, "eth%d") == 0) { ++ for (i=0; i < 1000; i++) ++ set_bit(i, inuse); ++ } ++ + i = find_first_zero_bit(inuse, max_netdevices); + free_page((unsigned long) inuse); + } +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Notification-of-death-of-arbitrary-processes.patch b/kernel-rt/centos/patches/Notification-of-death-of-arbitrary-processes.patch new file mode 100644 index 000000000..88b5a22b9 --- /dev/null +++ b/kernel-rt/centos/patches/Notification-of-death-of-arbitrary-processes.patch @@ -0,0 +1,539 @@ +From e7474cc4bfff10e58d239a773423074d0f71ff38 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Thu, 7 Apr 2016 11:16:19 -0600 +Subject: [PATCH 08/26] Notification of death of arbitrary processes + +Note: this commit was copied from Titanium Cloud Rel2 + +This exposes a new feature which may be called to request +notification when an arbitrary process changes state. The +caller specifies a pid, signal number, and event mask, and +when that pid dies, or is stopped, or anything else that +would normally cause a SIGCHLD, the kernel will send the +specified signal to the caller if the event is in the event +mask originally passed down. The siginfo_t struct will +contain the same information as would be included with SIGCHLD. + +This is exposed to userspace via the prctl() call with the +PR_DO_NOTIFY_TASK_STATE option. + +Signed-off-by: Jim Somerville +--- + include/linux/init_task.h | 9 ++ + include/linux/sched.h | 6 ++ + include/uapi/linux/prctl.h | 18 ++++ + init/Kconfig | 15 +++ + kernel/Makefile | 1 + + kernel/death_notify.c | 227 +++++++++++++++++++++++++++++++++++++++++++++ + kernel/death_notify.h | 45 +++++++++ + kernel/exit.c | 6 ++ + kernel/fork.c | 4 + + kernel/signal.c | 11 +++ + kernel/sys.c | 9 ++ + 11 files changed, 351 insertions(+) + create mode 100644 kernel/death_notify.c + create mode 100644 kernel/death_notify.h + +diff --git a/include/linux/init_task.h b/include/linux/init_task.h +index d8c82e0..ba0c12e 100644 +--- a/include/linux/init_task.h ++++ b/include/linux/init_task.h +@@ -77,6 +77,14 @@ extern struct nsproxy init_nsproxy; + .signalfd_wqh = __WAIT_QUEUE_HEAD_INITIALIZER(sighand.signalfd_wqh), \ + } + ++#ifdef CONFIG_SIGEXIT ++#define INIT_SIGEXIT(tsk) \ ++ .notify = LIST_HEAD_INIT(tsk.notify), \ ++ .monitor = LIST_HEAD_INIT(tsk.monitor), ++#else ++#define INIT_SIGEXIT(tsk) ++#endif ++ + extern struct group_info init_groups; + + #define INIT_STRUCT_PID { \ +@@ -231,6 +239,7 @@ extern struct task_group root_task_group; + .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ + .journal_info = NULL, \ + .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ ++ INIT_SIGEXIT(tsk) \ + .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ + .timer_slack_ns = 50000, /* 50 usec default slack */ \ + INIT_TIMER_LIST \ +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 4e8bf6a..175461f 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1660,6 +1660,12 @@ struct task_struct { + short il_next; + short pref_node_fork; + #endif ++#ifdef CONFIG_SIGEXIT ++ /* list of processes to notify on death */ ++ struct list_head notify; ++ /* list of outstanding monitor requests */ ++ struct list_head monitor; ++#endif + #ifdef CONFIG_NUMA_BALANCING + int numa_scan_seq; + unsigned int numa_scan_period; +diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h +index f818d08..3e0d502 100644 +--- a/include/uapi/linux/prctl.h ++++ b/include/uapi/linux/prctl.h +@@ -55,6 +55,24 @@ + #define PR_SET_NAME 15 /* Set process name */ + #define PR_GET_NAME 16 /* Get process name */ + ++#ifdef CONFIG_SIGEXIT ++#define PR_DO_NOTIFY_TASK_STATE 17 /* Set/get notification for task ++ state changes */ ++ ++/* This is the data structure for requestion process death ++ * (and other state change) information. Sig of -1 means ++ * query, sig of 0 means deregistration, positive sig means ++ * that you want to set it. sig and events are value-result ++ * and will be updated with the previous values on every ++ * successful call. ++ */ ++struct task_state_notify_info { ++ pid_t pid; ++ int sig; ++ unsigned int events; ++}; ++#endif ++ + /* Get/set process endian */ + #define PR_GET_ENDIAN 19 + #define PR_SET_ENDIAN 20 +diff --git a/init/Kconfig b/init/Kconfig +index 055cc3a..3c97be2 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1538,6 +1538,21 @@ config VM_EVENT_COUNTERS + on EXPERT systems. /proc/vmstat will only show page counts + if VM event counters are disabled. + ++config SIGEXIT ++ bool "Notification of death of arbitrary processes" ++ default n ++ help ++ When enabled this exposes a new feature which may be called to request ++ notification when an arbitrary process changes state. The caller specifies ++ a pid, signal number, and event mask, and when that pid dies, or is ++ stopped, or anything else that would normally cause a SIGCHLD, the ++ kernel will send the specified signal to the caller if the event is in ++ the event mask originally passed down. The siginfo_t struct will ++ contain the same information as would be included with SIGCHLD. ++ ++ This is exposed to userspace via the prctl() ++ call with the PR_DO_NOTIFY_TASK_STATE option ++ + config SLUB_DEBUG + default y + bool "Enable SLUB debugging support" if EXPERT +diff --git a/kernel/Makefile b/kernel/Makefile +index 57b6d6e..26e10e1 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -116,6 +116,7 @@ obj-$(CONFIG_RING_BUFFER) += trace/ + obj-$(CONFIG_TRACEPOINTS) += trace/ + obj-$(CONFIG_IRQ_WORK) += irq_work.o + obj-$(CONFIG_CPU_PM) += cpu_pm.o ++obj-$(CONFIG_SIGEXIT) += death_notify.o + + obj-$(CONFIG_PERF_EVENTS) += events/ + +diff --git a/kernel/death_notify.c b/kernel/death_notify.c +new file mode 100644 +index 0000000..5eb8bfc +--- /dev/null ++++ b/kernel/death_notify.c +@@ -0,0 +1,227 @@ ++/* ++ * kernel/death_notify.c, Process death notification support ++ * ++ * Copyright (c) 2006-2014 Wind River Systems, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See the GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "death_notify.h" ++ ++static void unlink_status_notifier(struct signotifier *n) ++{ ++ list_del(&n->monitor_list); ++ list_del(&n->notify_list); ++ kfree(n); ++} ++ ++static void handle_already_monitoring(struct signotifier *node, ++ struct task_state_notify_info *args, ++ struct task_state_notify_info *oldargs) ++{ ++ /* Store the old values */ ++ oldargs->sig = node->sig; ++ oldargs->events = node->events; ++ ++ /* We know that args->sig is 0 or a valid signal. */ ++ if (args->sig > 0) { ++ /* Update the new values */ ++ node->sig = args->sig; ++ node->events = args->events; ++ } else if (!args->sig) { ++ /* args->sig of 0 means to deregister */ ++ unlink_status_notifier(node); ++ } ++} ++ ++static void setup_new_node(struct task_struct *p, ++ struct signotifier *node, ++ struct task_state_notify_info *args) ++{ ++ node->notify_tsk = current; ++ node->sig = args->sig; ++ node->events = args->events; ++ ++ /* Add this node to the list of notification requests ++ * for the specified process. ++ */ ++ list_add_tail(&node->notify_list, &p->notify); ++ ++ /* Also add this node to the list of monitor requests ++ * for the current process. ++ */ ++ list_add_tail(&node->monitor_list, ¤t->monitor); ++} ++ ++ ++/* Returns 0 if arguments are valid, 1 if they are not. */ ++static int invalid_args(struct task_state_notify_info *args) ++{ ++ int ret = 1; ++ ++ if (args->pid <= 0) ++ goto out; ++ ++ /* Sig of -1 implies query, sig of 0 implies deregistration. ++ * Otherwise sig must be positive and within range. ++ */ ++ if ((args->sig < -1) || (args->sig > _NSIG)) ++ goto out; ++ ++ /* If positive sig, must have valid events. */ ++ if (args->sig > 0) { ++ if (!args->events || (args->events >= (1 << (NSIGCHLD+1)))) ++ goto out; ++ } ++ ++ ret = 0; ++out: ++ return ret; ++} ++ ++/* Notify those registered for process state updates via do_notify_task_state(). ++ * If "del" is nonzero, the process is dying and we want to free ++ * the nodes in the list as we go. ++ * ++ * Note: we only notify processes for events in which they have registered ++ * interest. ++ * ++ * Must be called holding a lock on tasklist_lock. ++ */ ++void do_notify_others(struct task_struct *tsk, struct siginfo *info) ++{ ++ struct signotifier *node; ++ unsigned int events; ++ ++ /* This method of generating the event bit must be ++ * matched in the userspace library. ++ */ ++ events = 1 << (info->si_code & 0xFF); ++ ++ list_for_each_entry(node, &tsk->notify, notify_list) { ++ if (events & node->events) { ++ info->si_signo = node->sig; ++ group_send_sig_info(node->sig, info, node->notify_tsk); ++ } ++ } ++} ++ ++void release_notify_others(struct task_struct *p) ++{ ++ struct signotifier *n, *t; ++ ++ /* Need to clean up any outstanding requests where we ++ * wanted to be notified when others died. ++ */ ++ list_for_each_entry_safe(n, t, &p->monitor, monitor_list) { ++ unlink_status_notifier(n); ++ } ++ ++ /* Also need to clean up any outstanding requests where others ++ * wanted to be notified when we died. ++ */ ++ list_for_each_entry_safe(n, t, &p->notify, notify_list) { ++ unlink_status_notifier(n); ++ } ++} ++ ++/* If the config is defined, then processes can call this routine ++ * to request notification when the specified task's state changes. ++ * On the death (or other state change) of the specified process, ++ * we will send them the specified signal if the event is listed ++ * in their event bitfield. ++ * ++ * A sig of 0 means that we want to deregister. ++ * ++ * The sig/events fields are value/result. On success we update them ++ * to reflect what they were before the call. ++ * ++ * Returns error code on error, on success we return 0. ++ */ ++int do_notify_task_state(unsigned long arg) ++{ ++ int err; ++ struct task_struct *p; ++ struct signotifier *node, *tmp; ++ struct task_state_notify_info args, oldargs; ++ ++ if (copy_from_user(&args, (struct task_state_notify_info __user *)arg, ++ sizeof(args))) ++ return -EFAULT; ++ oldargs.pid = args.pid; ++ ++ /* Validate the arguments passed in. */ ++ err = -EINVAL; ++ if (invalid_args(&args)) ++ goto out; ++ ++ /* We must hold a write lock on tasklist_lock to add the notification ++ * later on, and we need some lock on tasklist_lock for ++ * find_task_by_pid(), so may as well take the write lock now. ++ * Must use write_lock_irq(). ++ */ ++ write_lock_irq(&tasklist_lock); ++ ++ err = -ESRCH; ++ p = find_task_by_vpid(args.pid); ++ if (!p) ++ goto unlock_out; ++ ++ /* Now we know pid exists, unlikely to fail. */ ++ err = 0; ++ ++ /* Check if we're already monitoring the specified pid. If so, update ++ * the monitoring parameters and return the old ones. ++ */ ++ list_for_each_entry(tmp, &p->notify, notify_list) { ++ if (tmp->notify_tsk == current) { ++ handle_already_monitoring(tmp, &args, &oldargs); ++ goto unlock_out; ++ } ++ } ++ ++ /* If we get here, we're not currently monitoring the process. */ ++ oldargs.sig = 0; ++ oldargs.events = 0; ++ ++ /* If we wanted to set up a new monitor, do it now. If we didn't ++ * manage to allocate memory for the new node, then we return ++ * an appropriate error. ++ */ ++ if (args.sig > 0) { ++ node = kmalloc(sizeof(*node), GFP_ATOMIC); ++ if (node) ++ setup_new_node(p, node, &args); ++ else ++ err = -ENOMEM; ++ } ++ ++unlock_out: ++ write_unlock_irq(&tasklist_lock); ++ ++ /* Copy the old values back to caller. */ ++ if (copy_to_user((struct task_state_notify_info __user *)arg, ++ &oldargs, sizeof(oldargs))) ++ err = -EFAULT; ++ ++out: ++ return err; ++} +diff --git a/kernel/death_notify.h b/kernel/death_notify.h +new file mode 100644 +index 0000000..b2b8e8c +--- /dev/null ++++ b/kernel/death_notify.h +@@ -0,0 +1,45 @@ ++/* ++ * kernel/death_notify.h, Process death notification support ++ * ++ * Copyright (c) 2006-2014 Wind River Systems, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See the GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++#ifndef _KERNEL_DEATH_NOTIFY_H ++#define _KERNEL_DEATH_NOTIFY_H ++ ++#ifdef CONFIG_SIGEXIT ++ ++struct signotifier { ++ struct task_struct *notify_tsk; ++ struct list_head notify_list; ++ struct list_head monitor_list; ++ int sig; ++ unsigned int events; ++}; ++ ++extern int do_notify_task_state(unsigned long arg); ++extern void do_notify_others(struct task_struct *tsk, ++ struct siginfo *info); ++extern void release_notify_others(struct task_struct *p); ++ ++#else /* !CONFIG_SIGEXIT */ ++ ++static inline void do_notify_others(struct task_struct *tsk, ++ struct siginfo *info) {} ++static inline void release_notify_others(struct task_struct *p) {} ++ ++#endif /* CONFIG_SIGEXIT */ ++#endif +diff --git a/kernel/exit.c b/kernel/exit.c +index 8a908ea..448a3c3 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -59,6 +59,9 @@ + #include + #include + #include ++#ifdef CONFIG_SIGEXIT ++#include "death_notify.h" ++#endif + + static void exit_mm(struct task_struct * tsk); + +@@ -184,6 +187,9 @@ repeat: + proc_flush_task(p); + + tasklist_write_lock_irq(); ++#ifdef CONFIG_SIGEXIT ++ release_notify_others(p); ++#endif + ptrace_release_task(p); + __exit_signal(p); + +diff --git a/kernel/fork.c b/kernel/fork.c +index 81a8d77..0644030 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1469,6 +1469,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, + p->sequential_io = 0; + p->sequential_io_avg = 0; + #endif ++#ifdef CONFIG_SIGEXIT ++ INIT_LIST_HEAD(&p->notify); ++ INIT_LIST_HEAD(&p->monitor); ++#endif + + /* Perform scheduler related setup. Assign this task to a CPU. */ + retval = sched_fork(clone_flags, p); +diff --git a/kernel/signal.c b/kernel/signal.c +index 27994f8..b226f57 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -45,6 +45,9 @@ + #include + #include + #include "audit.h" /* audit_signal_info() */ ++#ifdef CONFIG_SIGEXIT ++#include "death_notify.h" ++#endif + + /* + * SLAB caches for signal bits. +@@ -1830,6 +1833,10 @@ bool do_notify_parent(struct task_struct *tsk, int sig) + __wake_up_parent(tsk, tsk->parent); + spin_unlock_irqrestore(&psig->siglock, flags); + ++#ifdef CONFIG_SIGEXIT ++ do_notify_others(tsk, &info); ++#endif ++ + return autoreap; + } + +@@ -1901,6 +1908,10 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, + */ + __wake_up_parent(tsk, parent); + spin_unlock_irqrestore(&sighand->siglock, flags); ++ ++#ifdef CONFIG_SIGEXIT ++ do_notify_others(tsk, &info); ++#endif + } + + static inline int may_ptrace_stop(void) +diff --git a/kernel/sys.c b/kernel/sys.c +index 29a73db..1bb3011 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -62,6 +62,10 @@ + #include + #include + ++#ifdef CONFIG_SIGEXIT ++#include "death_notify.h" ++#endif ++ + #ifndef SET_UNALIGN_CTL + # define SET_UNALIGN_CTL(a,b) (-EINVAL) + #endif +@@ -2462,6 +2466,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + else + error = PR_MCE_KILL_DEFAULT; + break; ++#ifdef CONFIG_SIGEXIT ++ case PR_DO_NOTIFY_TASK_STATE: ++ error = do_notify_task_state(arg2); ++ break; ++#endif + case PR_SET_MM: + error = prctl_set_mm(arg2, arg3, arg4, arg5); + break; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch b/kernel-rt/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch new file mode 100644 index 000000000..425b174a2 --- /dev/null +++ b/kernel-rt/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch @@ -0,0 +1,34 @@ +From 06088df87c55e7fac3783e539b0acf45fd9a5bad Mon Sep 17 00:00:00 2001 +Message-Id: <06088df87c55e7fac3783e539b0acf45fd9a5bad.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Dahir Osman +Date: Wed, 13 Jan 2016 10:01:11 -0500 +Subject: [PATCH 09/26] PCI: Add ACS quirk for Intel Fortville NICs + +Use quirks to determine isolation for now until a later kernel can +properly read the Fortville ACS capabilities. + +Signed-off-by: Jim Somerville +--- + drivers/pci/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index f6f2658..b5349eb 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4108,6 +4108,10 @@ static const struct pci_dev_acs_enabled { + /* I219 */ + { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs }, ++ /* I40 */ ++ { PCI_VENDOR_ID_INTEL, 0x1572, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_INTEL, 0x1586, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_INTEL, 0x1583, pci_quirk_mf_endpoint_acs }, + /* Intel PCH root ports */ + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch b/kernel-rt/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch new file mode 100644 index 000000000..88715faf2 --- /dev/null +++ b/kernel-rt/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch @@ -0,0 +1,2122 @@ +From f00521f1f3af8dc5784e16e92d51f6f386da824d Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Wed, 19 Jul 2017 02:21:59 -0500 +Subject: [PATCH 17/26] Porting Cacheinfo from Kernel 4.10.17 + +Original source code from tag v4.10.17 in Linux stable tree for: +intel_cacheinfo.c, cacheinfo.c and cacheinfo.h. +Main commit that we are interested for is 246246cbde5e840012f853e27630ebb59f409486: +This patch adds initial support for providing processor cache information +to userspace through sysfs interface. This is based on already existing +implementations(x86, ia64, s390 and powerpc) and hence the interface is +intended to be fully compatible. + +The main purpose of this generic support is to avoid further code +duplication to support new architectures and also to unify all the existing +different implementations. + +This implementation maintains the hierarchy of cache objects which reflects +the system's cache topology. Cache devices are instantiated as needed as +CPUs come online. The cache information is replicated per-cpu even if they are +shared. A per-cpu array of cache information maintained is used mainly for +sysfs-related book keeping. + +It also implements the shared_cpu_map attribute, which is essential for +enabling both kernel and user-space to discover the system's overall cache +topology. + +This patch also add the missing ABI documentation for the cacheinfo sysfs +interface already, which is well defined and widely used. + +sysfs-devices-system-cpu was nodified by taking commit 1d78dc59f5ab6f467e49882518453adc7e4caa44: +Add an ABI document entry for /sys/devices/system/cpu/cpu*/cache/index*/id. + +cpu.h and cpu.c was enhanced with commit 3d52943b3a51497a777e6d7d840a38596a92cee9: +This patch adds a new function to create per-cpu devices. +This helps in: +1. reusing the device infrastructure to create any cpu related + attributes and corresponding sysfs instead of creating and + dealing with raw kobjects directly +2. retaining the legacy path(/sys/devices/system/cpu/..) to support + existing sysfs ABI +3. avoiding to create links in the bus directory pointing to the + device as there would be per-cpu instance of these devices with + the same name since dev->bus is not populated to cpu_sysbus on + purpose + +Signed-off-by: Jim Somerville +--- + Documentation/ABI/testing/sysfs-devices-system-cpu | 65 ++ + arch/x86/kernel/cpu/intel_cacheinfo.c | 832 +++++++-------------- + drivers/base/Makefile | 2 +- + drivers/base/cacheinfo.c | 662 ++++++++++++++++ + drivers/base/cpu.c | 54 ++ + include/linux/cacheinfo.h | 104 +++ + include/linux/cpu.h | 3 + + 7 files changed, 1148 insertions(+), 574 deletions(-) + create mode 100644 drivers/base/cacheinfo.c + create mode 100644 include/linux/cacheinfo.h + +diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu +index 4a639ed..9e877e1 100644 +--- a/Documentation/ABI/testing/sysfs-devices-system-cpu ++++ b/Documentation/ABI/testing/sysfs-devices-system-cpu +@@ -201,6 +201,71 @@ Description: address and size of the percpu note. + + crash_notes_size: size of the note of cpu#. + ++ ++What: /sys/devices/system/cpu/cpu*/cache/index*/ ++Date: July 2014(documented, existed before August 2008) ++Contact: Sudeep Holla ++ Linux kernel mailing list ++Description: Parameters for the CPU cache attributes ++ ++ allocation_policy: ++ - WriteAllocate: allocate a memory location to a cache line ++ on a cache miss because of a write ++ - ReadAllocate: allocate a memory location to a cache line ++ on a cache miss because of a read ++ - ReadWriteAllocate: both writeallocate and readallocate ++ ++ attributes: LEGACY used only on IA64 and is same as write_policy ++ ++ coherency_line_size: the minimum amount of data in bytes that gets ++ transferred from memory to cache ++ ++ level: the cache hierarchy in the multi-level cache configuration ++ ++ number_of_sets: total number of sets in the cache, a set is a ++ collection of cache lines with the same cache index ++ ++ physical_line_partition: number of physical cache line per cache tag ++ ++ shared_cpu_list: the list of logical cpus sharing the cache ++ ++ shared_cpu_map: logical cpu mask containing the list of cpus sharing ++ the cache ++ ++ size: the total cache size in kB ++ ++ type: ++ - Instruction: cache that only holds instructions ++ - Data: cache that only caches data ++ - Unified: cache that holds both data and instructions ++ ++ ways_of_associativity: degree of freedom in placing a particular block ++ of memory in the cache ++ ++ write_policy: ++ - WriteThrough: data is written to both the cache line ++ and to the block in the lower-level memory ++ - WriteBack: data is written only to the cache line and ++ the modified cache line is written to main ++ memory only when it is replaced ++ ++ ++What: /sys/devices/system/cpu/cpu*/cache/index*/id ++Date: September 2016 ++Contact: Linux kernel mailing list ++Description: Cache id ++ ++ The id provides a unique number for a specific instance of ++ a cache of a particular type. E.g. there may be a level ++ 3 unified cache on each socket in a server and we may ++ assign them ids 0, 1, 2, ... ++ ++ Note that id value can be non-contiguous. E.g. level 1 ++ caches typically exist per core, but there may not be a ++ power of two cores on a socket, so these caches may be ++ numbered 0, 1, 2, 3, 4, 5, 8, 9, 10, ... ++ ++ + What: /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/turbo_stat + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/sub_turbo_stat +diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c +index 3182124..d8bb5bd 100644 +--- a/arch/x86/kernel/cpu/intel_cacheinfo.c ++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c +@@ -1,5 +1,5 @@ + /* +- * Routines to indentify caches on Intel CPU. ++ * Routines to identify caches on Intel CPU. + * + * Changes: + * Venkatesh Pallipadi : Adding cache identification through cpuid(4) +@@ -7,16 +7,14 @@ + * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD. + */ + +-#include + #include +-#include +-#include ++#include + #include + #include ++#include + #include + +-#include +-#include ++#include + #include + #include + +@@ -116,10 +114,10 @@ static const struct _cache_table cache_table[] = + + + enum _cache_type { +- CACHE_TYPE_NULL = 0, +- CACHE_TYPE_DATA = 1, +- CACHE_TYPE_INST = 2, +- CACHE_TYPE_UNIFIED = 3 ++ CTYPE_NULL = 0, ++ CTYPE_DATA = 1, ++ CTYPE_INST = 2, ++ CTYPE_UNIFIED = 3 + }; + + union _cpuid4_leaf_eax { +@@ -160,12 +158,7 @@ struct _cpuid4_info_regs { + struct amd_northbridge *nb; + }; + +-struct _cpuid4_info { +- struct _cpuid4_info_regs base; +- DECLARE_BITMAP(shared_cpu_map, NR_CPUS); +-}; +- +-unsigned short num_cache_leaves; ++static unsigned short num_cache_leaves; + + /* AMD doesn't have CPUID4. Emulate it here to report the same + information to the user. This makes some assumptions about the machine: +@@ -221,6 +214,13 @@ static const unsigned short assocs[] = { + static const unsigned char levels[] = { 1, 1, 2, 3 }; + static const unsigned char types[] = { 1, 2, 3, 3 }; + ++static const enum cache_type cache_type_map[] = { ++ [CTYPE_NULL] = CACHE_TYPE_NOCACHE, ++ [CTYPE_DATA] = CACHE_TYPE_DATA, ++ [CTYPE_INST] = CACHE_TYPE_INST, ++ [CTYPE_UNIFIED] = CACHE_TYPE_UNIFIED, ++}; ++ + static void + amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, + union _cpuid4_leaf_ebx *ebx, +@@ -292,14 +292,8 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, + (ebx->split.ways_of_associativity + 1) - 1; + } + +-struct _cache_attr { +- struct attribute attr; +- ssize_t (*show)(struct _cpuid4_info *, char *, unsigned int); +- ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count, +- unsigned int); +-}; +- + #if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS) ++ + /* + * L3 cache descriptors + */ +@@ -326,20 +320,6 @@ static void amd_calc_l3_indices(struct amd_northbridge *nb) + l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; + } + +-static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) +-{ +- int node; +- +- /* only for L3, and not in virtualized environments */ +- if (index < 3) +- return; +- +- node = amd_get_nb_id(smp_processor_id()); +- this_leaf->nb = node_to_amd_nb(node); +- if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) +- amd_calc_l3_indices(this_leaf->nb); +-} +- + /* + * check whether a slot used for disabling an L3 index is occupied. + * @l3: L3 cache descriptor +@@ -347,7 +327,7 @@ static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) + * + * @returns: the disabled index if used or negative value if slot free. + */ +-int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) ++static int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) + { + unsigned int reg = 0; + +@@ -360,15 +340,13 @@ int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) + return -1; + } + +-static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, ++static ssize_t show_cache_disable(struct cacheinfo *this_leaf, char *buf, + unsigned int slot) + { + int index; ++ struct amd_northbridge *nb = this_leaf->priv; + +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) +- return -EINVAL; +- +- index = amd_get_l3_disable_slot(this_leaf->base.nb, slot); ++ index = amd_get_l3_disable_slot(nb, slot); + if (index >= 0) + return sprintf(buf, "%d\n", index); + +@@ -377,9 +355,10 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, + + #define SHOW_CACHE_DISABLE(slot) \ + static ssize_t \ +-show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf, \ +- unsigned int cpu) \ ++cache_disable_##slot##_show(struct device *dev, \ ++ struct device_attribute *attr, char *buf) \ + { \ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ + return show_cache_disable(this_leaf, buf, slot); \ + } + SHOW_CACHE_DISABLE(0) +@@ -425,8 +404,8 @@ static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu, + * + * @return: 0 on success, error status on failure + */ +-int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, +- unsigned long index) ++static int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, ++ unsigned slot, unsigned long index) + { + int ret = 0; + +@@ -447,28 +426,26 @@ int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, + return 0; + } + +-static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, +- const char *buf, size_t count, +- unsigned int slot) ++static ssize_t store_cache_disable(struct cacheinfo *this_leaf, ++ const char *buf, size_t count, ++ unsigned int slot) + { + unsigned long val = 0; + int cpu, err = 0; ++ struct amd_northbridge *nb = this_leaf->priv; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) +- return -EINVAL; +- +- cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); ++ cpu = cpumask_first(&this_leaf->shared_cpu_map); + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + +- err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); ++ err = amd_set_l3_disable_slot(nb, cpu, slot, val); + if (err) { + if (err == -EEXIST) +- pr_warning("L3 slot %d in use/index already disabled!\n", ++ pr_warn("L3 slot %d in use/index already disabled!\n", + slot); + return err; + } +@@ -477,41 +454,36 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, + + #define STORE_CACHE_DISABLE(slot) \ + static ssize_t \ +-store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \ +- const char *buf, size_t count, \ +- unsigned int cpu) \ ++cache_disable_##slot##_store(struct device *dev, \ ++ struct device_attribute *attr, \ ++ const char *buf, size_t count) \ + { \ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ + return store_cache_disable(this_leaf, buf, count, slot); \ + } + STORE_CACHE_DISABLE(0) + STORE_CACHE_DISABLE(1) + +-static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644, +- show_cache_disable_0, store_cache_disable_0); +-static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, +- show_cache_disable_1, store_cache_disable_1); +- +-static ssize_t +-show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu) ++static ssize_t subcaches_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- return -EINVAL; ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ int cpu = cpumask_first(&this_leaf->shared_cpu_map); + + return sprintf(buf, "%x\n", amd_get_subcaches(cpu)); + } + +-static ssize_t +-store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, +- unsigned int cpu) ++static ssize_t subcaches_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) + { ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ int cpu = cpumask_first(&this_leaf->shared_cpu_map); + unsigned long val; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- return -EINVAL; +- + if (kstrtoul(buf, 16, &val) < 0) + return -EINVAL; + +@@ -521,9 +493,92 @@ store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, + return count; + } + +-static struct _cache_attr subcaches = +- __ATTR(subcaches, 0644, show_subcaches, store_subcaches); ++static DEVICE_ATTR_RW(cache_disable_0); ++static DEVICE_ATTR_RW(cache_disable_1); ++static DEVICE_ATTR_RW(subcaches); ++ ++static umode_t ++cache_private_attrs_is_visible(struct kobject *kobj, ++ struct attribute *attr, int unused) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ umode_t mode = attr->mode; ++ ++ if (!this_leaf->priv) ++ return 0; ++ ++ if ((attr == &dev_attr_subcaches.attr) && ++ amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ return mode; ++ ++ if ((attr == &dev_attr_cache_disable_0.attr || ++ attr == &dev_attr_cache_disable_1.attr) && ++ amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) ++ return mode; ++ ++ return 0; ++} ++ ++static struct attribute_group cache_private_group = { ++ .is_visible = cache_private_attrs_is_visible, ++}; ++ ++static void init_amd_l3_attrs(void) ++{ ++ int n = 1; ++ static struct attribute **amd_l3_attrs; ++ ++ if (amd_l3_attrs) /* already initialized */ ++ return; ++ ++ if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) ++ n += 2; ++ if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ n += 1; ++ ++ amd_l3_attrs = kcalloc(n, sizeof(*amd_l3_attrs), GFP_KERNEL); ++ if (!amd_l3_attrs) ++ return; ++ ++ n = 0; ++ if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) { ++ amd_l3_attrs[n++] = &dev_attr_cache_disable_0.attr; ++ amd_l3_attrs[n++] = &dev_attr_cache_disable_1.attr; ++ } ++ if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ amd_l3_attrs[n++] = &dev_attr_subcaches.attr; ++ ++ cache_private_group.attrs = amd_l3_attrs; ++} ++ ++const struct attribute_group * ++cache_get_priv_group(struct cacheinfo *this_leaf) ++{ ++ struct amd_northbridge *nb = this_leaf->priv; ++ ++ if (this_leaf->level < 3 || !nb) ++ return NULL; ++ ++ if (nb && nb->l3_cache.indices) ++ init_amd_l3_attrs(); ++ ++ return &cache_private_group; ++} ++ ++static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) ++{ ++ int node; ++ ++ /* only for L3, and not in virtualized environments */ ++ if (index < 3) ++ return; + ++ node = amd_get_nb_id(smp_processor_id()); ++ this_leaf->nb = node_to_amd_nb(node); ++ if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) ++ amd_calc_l3_indices(this_leaf->nb); ++} + #else + #define amd_init_l3_cache(x, y) + #endif /* CONFIG_AMD_NB && CONFIG_SYSFS */ +@@ -537,7 +592,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) + unsigned edx; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- if (cpu_has_topoext) ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) + cpuid_count(0x8000001d, index, &eax.full, + &ebx.full, &ecx.full, &edx); + else +@@ -547,7 +602,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) + cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); + } + +- if (eax.split.type == CACHE_TYPE_NULL) ++ if (eax.split.type == CTYPE_NULL) + return -EIO; /* better error ? */ + + this_leaf->eax = eax; +@@ -576,14 +631,14 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) + /* Do cpuid(op) loop to find out num_cache_leaves */ + cpuid_count(op, i, &eax, &ebx, &ecx, &edx); + cache_eax.full = eax; +- } while (cache_eax.split.type != CACHE_TYPE_NULL); ++ } while (cache_eax.split.type != CTYPE_NULL); + return i; + } + + void init_amd_cacheinfo(struct cpuinfo_x86 *c) + { + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + num_cache_leaves = find_num_cache_leaves(c); + } else if (c->extended_cpuid_level >= 0x80000006) { + if (cpuid_edx(0x80000006) & 0xf000) +@@ -600,7 +655,7 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) + unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ + unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ + unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; +-#ifdef CONFIG_X86_HT ++#ifdef CONFIG_SMP + unsigned int cpu = c->cpu_index; + #endif + +@@ -618,36 +673,34 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) + * parameters cpuid leaf to find the cache details + */ + for (i = 0; i < num_cache_leaves; i++) { +- struct _cpuid4_info_regs this_leaf; ++ struct _cpuid4_info_regs this_leaf = {}; + int retval; + + retval = cpuid4_cache_lookup_regs(i, &this_leaf); +- if (retval >= 0) { +- switch (this_leaf.eax.split.level) { +- case 1: +- if (this_leaf.eax.split.type == +- CACHE_TYPE_DATA) +- new_l1d = this_leaf.size/1024; +- else if (this_leaf.eax.split.type == +- CACHE_TYPE_INST) +- new_l1i = this_leaf.size/1024; +- break; +- case 2: +- new_l2 = this_leaf.size/1024; +- num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; +- index_msb = get_count_order(num_threads_sharing); +- l2_id = c->apicid & ~((1 << index_msb) - 1); +- break; +- case 3: +- new_l3 = this_leaf.size/1024; +- num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; +- index_msb = get_count_order( +- num_threads_sharing); +- l3_id = c->apicid & ~((1 << index_msb) - 1); +- break; +- default: +- break; +- } ++ if (retval < 0) ++ continue; ++ ++ switch (this_leaf.eax.split.level) { ++ case 1: ++ if (this_leaf.eax.split.type == CTYPE_DATA) ++ new_l1d = this_leaf.size/1024; ++ else if (this_leaf.eax.split.type == CTYPE_INST) ++ new_l1i = this_leaf.size/1024; ++ break; ++ case 2: ++ new_l2 = this_leaf.size/1024; ++ num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; ++ index_msb = get_count_order(num_threads_sharing); ++ l2_id = c->apicid & ~((1 << index_msb) - 1); ++ break; ++ case 3: ++ new_l3 = this_leaf.size/1024; ++ num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; ++ index_msb = get_count_order(num_threads_sharing); ++ l3_id = c->apicid & ~((1 << index_msb) - 1); ++ break; ++ default: ++ break; + } + } + } +@@ -721,72 +774,81 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) + + if (new_l2) { + l2 = new_l2; +-#ifdef CONFIG_X86_HT ++#ifdef CONFIG_SMP + per_cpu(cpu_llc_id, cpu) = l2_id; + #endif + } + + if (new_l3) { + l3 = new_l3; +-#ifdef CONFIG_X86_HT ++#ifdef CONFIG_SMP + per_cpu(cpu_llc_id, cpu) = l3_id; + #endif + } + ++#ifdef CONFIG_SMP ++ /* ++ * If cpu_llc_id is not yet set, this means cpuid_level < 4 which in ++ * turns means that the only possibility is SMT (as indicated in ++ * cpuid1). Since cpuid2 doesn't specify shared caches, and we know ++ * that SMT shares all caches, we can unconditionally set cpu_llc_id to ++ * c->phys_proc_id. ++ */ ++ if (per_cpu(cpu_llc_id, cpu) == BAD_APICID) ++ per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; ++#endif ++ + c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); + + return l2; + } + +-#ifdef CONFIG_SYSFS +- +-/* pointer to _cpuid4_info array (for each cache leaf) */ +-static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); +-#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) +- +-#ifdef CONFIG_SMP +- +-static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) ++static int __cache_amd_cpumap_setup(unsigned int cpu, int index, ++ struct _cpuid4_info_regs *base) + { +- struct _cpuid4_info *this_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf; + int i, sibling; + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + unsigned int apicid, nshared, first, last; + +- if (!per_cpu(ici_cpuid4_info, cpu)) +- return 0; +- +- this_leaf = CPUID4_INFO_IDX(cpu, index); +- nshared = this_leaf->base.eax.split.num_threads_sharing + 1; ++ this_leaf = this_cpu_ci->info_list + index; ++ nshared = base->eax.split.num_threads_sharing + 1; + apicid = cpu_data(cpu).apicid; + first = apicid - (apicid % nshared); + last = first + nshared - 1; + + for_each_online_cpu(i) { ++ this_cpu_ci = get_cpu_cacheinfo(i); ++ if (!this_cpu_ci->info_list) ++ continue; ++ + apicid = cpu_data(i).apicid; + if ((apicid < first) || (apicid > last)) + continue; +- if (!per_cpu(ici_cpuid4_info, i)) +- continue; +- this_leaf = CPUID4_INFO_IDX(i, index); ++ ++ this_leaf = this_cpu_ci->info_list + index; + + for_each_online_cpu(sibling) { + apicid = cpu_data(sibling).apicid; + if ((apicid < first) || (apicid > last)) + continue; +- set_bit(sibling, this_leaf->shared_cpu_map); ++ cpumask_set_cpu(sibling, ++ &this_leaf->shared_cpu_map); + } + } + } else if (index == 3) { + for_each_cpu(i, cpu_llc_shared_mask(cpu)) { +- if (!per_cpu(ici_cpuid4_info, i)) ++ this_cpu_ci = get_cpu_cacheinfo(i); ++ if (!this_cpu_ci->info_list) + continue; +- this_leaf = CPUID4_INFO_IDX(i, index); ++ this_leaf = this_cpu_ci->info_list + index; + for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { + if (!cpu_online(sibling)) + continue; +- set_bit(sibling, this_leaf->shared_cpu_map); ++ cpumask_set_cpu(sibling, ++ &this_leaf->shared_cpu_map); + } + } + } else +@@ -795,72 +857,70 @@ static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) + return 1; + } + +-static void cache_shared_cpu_map_setup(unsigned int cpu, int index) ++static void __cache_cpumap_setup(unsigned int cpu, int index, ++ struct _cpuid4_info_regs *base) + { +- struct _cpuid4_info *this_leaf, *sibling_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf, *sibling_leaf; + unsigned long num_threads_sharing; + int index_msb, i; + struct cpuinfo_x86 *c = &cpu_data(cpu); + + if (c->x86_vendor == X86_VENDOR_AMD) { +- if (cache_shared_amd_cpu_map_setup(cpu, index)) ++ if (__cache_amd_cpumap_setup(cpu, index, base)) + return; + } + +- this_leaf = CPUID4_INFO_IDX(cpu, index); +- num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; ++ this_leaf = this_cpu_ci->info_list + index; ++ num_threads_sharing = 1 + base->eax.split.num_threads_sharing; + ++ cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); + if (num_threads_sharing == 1) +- cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); +- else { +- index_msb = get_count_order(num_threads_sharing); ++ return; + +- for_each_online_cpu(i) { +- if (cpu_data(i).apicid >> index_msb == +- c->apicid >> index_msb) { +- cpumask_set_cpu(i, +- to_cpumask(this_leaf->shared_cpu_map)); +- if (i != cpu && per_cpu(ici_cpuid4_info, i)) { +- sibling_leaf = +- CPUID4_INFO_IDX(i, index); +- cpumask_set_cpu(cpu, to_cpumask( +- sibling_leaf->shared_cpu_map)); +- } +- } ++ index_msb = get_count_order(num_threads_sharing); ++ ++ for_each_online_cpu(i) ++ if (cpu_data(i).apicid >> index_msb == c->apicid >> index_msb) { ++ struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); ++ ++ if (i == cpu || !sib_cpu_ci->info_list) ++ continue;/* skip if itself or no cacheinfo */ ++ sibling_leaf = sib_cpu_ci->info_list + index; ++ cpumask_set_cpu(i, &this_leaf->shared_cpu_map); ++ cpumask_set_cpu(cpu, &sibling_leaf->shared_cpu_map); + } +- } +-} +-static void cache_remove_shared_cpu_map(unsigned int cpu, int index) +-{ +- struct _cpuid4_info *this_leaf, *sibling_leaf; +- int sibling; +- +- this_leaf = CPUID4_INFO_IDX(cpu, index); +- for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) { +- sibling_leaf = CPUID4_INFO_IDX(sibling, index); +- cpumask_clear_cpu(cpu, +- to_cpumask(sibling_leaf->shared_cpu_map)); +- } +-} +-#else +-static void cache_shared_cpu_map_setup(unsigned int cpu, int index) +-{ + } + +-static void cache_remove_shared_cpu_map(unsigned int cpu, int index) ++static void ci_leaf_init(struct cacheinfo *this_leaf, ++ struct _cpuid4_info_regs *base) + { ++ this_leaf->id = base->id; ++ this_leaf->attributes = CACHE_ID; ++ this_leaf->level = base->eax.split.level; ++ this_leaf->type = cache_type_map[base->eax.split.type]; ++ this_leaf->coherency_line_size = ++ base->ebx.split.coherency_line_size + 1; ++ this_leaf->ways_of_associativity = ++ base->ebx.split.ways_of_associativity + 1; ++ this_leaf->size = base->size; ++ this_leaf->number_of_sets = base->ecx.split.number_of_sets + 1; ++ this_leaf->physical_line_partition = ++ base->ebx.split.physical_line_partition + 1; ++ this_leaf->priv = base->nb; + } +-#endif + +-static void free_cache_attributes(unsigned int cpu) ++static int __init_cache_level(unsigned int cpu) + { +- int i; +- +- for (i = 0; i < num_cache_leaves; i++) +- cache_remove_shared_cpu_map(cpu, i); ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + +- kfree(per_cpu(ici_cpuid4_info, cpu)); +- per_cpu(ici_cpuid4_info, cpu) = NULL; ++ if (!num_cache_leaves) ++ return -ENOENT; ++ if (!this_cpu_ci) ++ return -EINVAL; ++ this_cpu_ci->num_levels = 3; ++ this_cpu_ci->num_leaves = num_cache_leaves; ++ return 0; + } + + /* +@@ -882,411 +942,37 @@ static void get_cache_id(int cpu, struct _cpuid4_info_regs *id4_regs) + int get_cpu_cache_id(int cpu, int level) + { + int i; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + +- for (i = 0; i < num_cache_leaves; i++) { +- struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, i); ++ for (i = 0; i < this_cpu_ci->num_leaves; i++) { ++ struct cacheinfo *this_leaf = this_cpu_ci->info_list + i; + +- if (this_leaf->base.eax.split.level == level) +- return this_leaf->base.id; ++ if (this_leaf->level == level) ++ return this_leaf->id; + } + + return -1; + } + +-static void get_cpu_leaves(void *_retval) +-{ +- int j, *retval = _retval, cpu = smp_processor_id(); +- +- /* Do cpuid and store the results */ +- for (j = 0; j < num_cache_leaves; j++) { +- struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, j); +- +- *retval = cpuid4_cache_lookup_regs(j, &this_leaf->base); +- if (unlikely(*retval < 0)) { +- int i; +- +- for (i = 0; i < j; i++) +- cache_remove_shared_cpu_map(cpu, i); +- break; +- } +- cache_shared_cpu_map_setup(cpu, j); +- get_cache_id(cpu, &this_leaf->base); +- } +-} +- +-static int detect_cache_attributes(unsigned int cpu) +-{ +- int retval; +- +- if (num_cache_leaves == 0) +- return -ENOENT; +- +- per_cpu(ici_cpuid4_info, cpu) = kzalloc( +- sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); +- if (per_cpu(ici_cpuid4_info, cpu) == NULL) +- return -ENOMEM; +- +- smp_call_function_single(cpu, get_cpu_leaves, &retval, true); +- if (retval) { +- kfree(per_cpu(ici_cpuid4_info, cpu)); +- per_cpu(ici_cpuid4_info, cpu) = NULL; +- } +- +- return retval; +-} +- +-#include +-#include +-#include +- +-/* pointer to kobject for cpuX/cache */ +-static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject); +- +-struct _index_kobject { +- struct kobject kobj; +- unsigned int cpu; +- unsigned short index; +-}; +- +-/* pointer to array of kobjects for cpuX/cache/indexY */ +-static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject); +-#define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y])) +- +-#define show_one_plus(file_name, object, val) \ +-static ssize_t show_##file_name(struct _cpuid4_info *this_leaf, char *buf, \ +- unsigned int cpu) \ +-{ \ +- return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ +-} +- +-show_one_plus(level, base.eax.split.level, 0); +-show_one_plus(coherency_line_size, base.ebx.split.coherency_line_size, 1); +-show_one_plus(physical_line_partition, base.ebx.split.physical_line_partition, 1); +-show_one_plus(ways_of_associativity, base.ebx.split.ways_of_associativity, 1); +-show_one_plus(number_of_sets, base.ecx.split.number_of_sets, 1); +- +-static ssize_t show_id(struct _cpuid4_info *this_leaf, char *buf, +- unsigned int cpu) +-{ +- return sprintf(buf, "%u\n", this_leaf->base.id); +-} +- +-static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf, +- unsigned int cpu) +-{ +- return sprintf(buf, "%luK\n", this_leaf->base.size / 1024); +-} +- +-static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, +- int type, char *buf) +-{ +- ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; +- int n = 0; +- +- if (len > 1) { +- const struct cpumask *mask; +- +- mask = to_cpumask(this_leaf->shared_cpu_map); +- n = type ? +- cpulist_scnprintf(buf, len-2, mask) : +- cpumask_scnprintf(buf, len-2, mask); +- buf[n++] = '\n'; +- buf[n] = '\0'; +- } +- return n; +-} +- +-static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf, +- unsigned int cpu) +-{ +- return show_shared_cpu_map_func(leaf, 0, buf); +-} +- +-static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf, +- unsigned int cpu) +-{ +- return show_shared_cpu_map_func(leaf, 1, buf); +-} +- +-static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf, +- unsigned int cpu) +-{ +- switch (this_leaf->base.eax.split.type) { +- case CACHE_TYPE_DATA: +- return sprintf(buf, "Data\n"); +- case CACHE_TYPE_INST: +- return sprintf(buf, "Instruction\n"); +- case CACHE_TYPE_UNIFIED: +- return sprintf(buf, "Unified\n"); +- default: +- return sprintf(buf, "Unknown\n"); +- } +-} +- +-#define to_object(k) container_of(k, struct _index_kobject, kobj) +-#define to_attr(a) container_of(a, struct _cache_attr, attr) +- +-#define define_one_ro(_name) \ +-static struct _cache_attr _name = \ +- __ATTR(_name, 0444, show_##_name, NULL) +- +-define_one_ro(id); +-define_one_ro(level); +-define_one_ro(type); +-define_one_ro(coherency_line_size); +-define_one_ro(physical_line_partition); +-define_one_ro(ways_of_associativity); +-define_one_ro(number_of_sets); +-define_one_ro(size); +-define_one_ro(shared_cpu_map); +-define_one_ro(shared_cpu_list); +- +-static struct attribute *default_attrs[] = { +- &id.attr, +- &type.attr, +- &level.attr, +- &coherency_line_size.attr, +- &physical_line_partition.attr, +- &ways_of_associativity.attr, +- &number_of_sets.attr, +- &size.attr, +- &shared_cpu_map.attr, +- &shared_cpu_list.attr, +- NULL +-}; +- +-#ifdef CONFIG_AMD_NB +-static struct attribute **amd_l3_attrs(void) +-{ +- static struct attribute **attrs; +- int n; +- +- if (attrs) +- return attrs; +- +- n = ARRAY_SIZE(default_attrs); +- +- if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) +- n += 2; +- +- if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- n += 1; +- +- attrs = kzalloc(n * sizeof (struct attribute *), GFP_KERNEL); +- if (attrs == NULL) +- return attrs = default_attrs; +- +- for (n = 0; default_attrs[n]; n++) +- attrs[n] = default_attrs[n]; +- +- if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) { +- attrs[n++] = &cache_disable_0.attr; +- attrs[n++] = &cache_disable_1.attr; +- } +- +- if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- attrs[n++] = &subcaches.attr; +- +- return attrs; +-} +-#endif +- +-static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) +-{ +- struct _cache_attr *fattr = to_attr(attr); +- struct _index_kobject *this_leaf = to_object(kobj); +- ssize_t ret; +- +- ret = fattr->show ? +- fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), +- buf, this_leaf->cpu) : +- 0; +- return ret; +-} +- +-static ssize_t store(struct kobject *kobj, struct attribute *attr, +- const char *buf, size_t count) +-{ +- struct _cache_attr *fattr = to_attr(attr); +- struct _index_kobject *this_leaf = to_object(kobj); +- ssize_t ret; +- +- ret = fattr->store ? +- fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), +- buf, count, this_leaf->cpu) : +- 0; +- return ret; +-} +- +-static const struct sysfs_ops sysfs_ops = { +- .show = show, +- .store = store, +-}; +- +-static struct kobj_type ktype_cache = { +- .sysfs_ops = &sysfs_ops, +- .default_attrs = default_attrs, +-}; +- +-static struct kobj_type ktype_percpu_entry = { +- .sysfs_ops = &sysfs_ops, +-}; +- +-static void cpuid4_cache_sysfs_exit(unsigned int cpu) +-{ +- kfree(per_cpu(ici_cache_kobject, cpu)); +- kfree(per_cpu(ici_index_kobject, cpu)); +- per_cpu(ici_cache_kobject, cpu) = NULL; +- per_cpu(ici_index_kobject, cpu) = NULL; +- free_cache_attributes(cpu); +-} +- +-static int cpuid4_cache_sysfs_init(unsigned int cpu) +-{ +- int err; +- +- if (num_cache_leaves == 0) +- return -ENOENT; +- +- err = detect_cache_attributes(cpu); +- if (err) +- return err; +- +- /* Allocate all required memory */ +- per_cpu(ici_cache_kobject, cpu) = +- kzalloc(sizeof(struct kobject), GFP_KERNEL); +- if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL)) +- goto err_out; +- +- per_cpu(ici_index_kobject, cpu) = kzalloc( +- sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL); +- if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL)) +- goto err_out; +- +- return 0; +- +-err_out: +- cpuid4_cache_sysfs_exit(cpu); +- return -ENOMEM; +-} +- +-static DECLARE_BITMAP(cache_dev_map, NR_CPUS); +- +-/* Add/Remove cache interface for CPU device */ +-static int cache_add_dev(struct device *dev) ++static int __populate_cache_leaves(unsigned int cpu) + { +- unsigned int cpu = dev->id; +- unsigned long i, j; +- struct _index_kobject *this_object; +- struct _cpuid4_info *this_leaf; +- int retval; +- +- retval = cpuid4_cache_sysfs_init(cpu); +- if (unlikely(retval < 0)) +- return retval; +- +- retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu), +- &ktype_percpu_entry, +- &dev->kobj, "%s", "cache"); +- if (retval < 0) { +- cpuid4_cache_sysfs_exit(cpu); +- return retval; +- } +- +- for (i = 0; i < num_cache_leaves; i++) { +- this_object = INDEX_KOBJECT_PTR(cpu, i); +- this_object->cpu = cpu; +- this_object->index = i; ++ unsigned int idx, ret; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf = this_cpu_ci->info_list; ++ struct _cpuid4_info_regs id4_regs = {}; + +- this_leaf = CPUID4_INFO_IDX(cpu, i); +- +- ktype_cache.default_attrs = default_attrs; +-#ifdef CONFIG_AMD_NB +- if (this_leaf->base.nb) +- ktype_cache.default_attrs = amd_l3_attrs(); +-#endif +- retval = kobject_init_and_add(&(this_object->kobj), +- &ktype_cache, +- per_cpu(ici_cache_kobject, cpu), +- "index%1lu", i); +- if (unlikely(retval)) { +- for (j = 0; j < i; j++) +- kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj)); +- kobject_put(per_cpu(ici_cache_kobject, cpu)); +- cpuid4_cache_sysfs_exit(cpu); +- return retval; +- } +- kobject_uevent(&(this_object->kobj), KOBJ_ADD); ++ for (idx = 0; idx < this_cpu_ci->num_leaves; idx++) { ++ ret = cpuid4_cache_lookup_regs(idx, &id4_regs); ++ if (ret) ++ return ret; ++ get_cache_id(cpu, &id4_regs); ++ ci_leaf_init(this_leaf++, &id4_regs); ++ __cache_cpumap_setup(cpu, idx, &id4_regs); + } +- cpumask_set_cpu(cpu, to_cpumask(cache_dev_map)); ++ this_cpu_ci->cpu_map_populated = true; + +- kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD); + return 0; + } + +-static void cache_remove_dev(struct device *dev) +-{ +- unsigned int cpu = dev->id; +- unsigned long i; +- +- if (per_cpu(ici_cpuid4_info, cpu) == NULL) +- return; +- if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map))) +- return; +- cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); +- +- for (i = 0; i < num_cache_leaves; i++) +- kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj)); +- kobject_put(per_cpu(ici_cache_kobject, cpu)); +- cpuid4_cache_sysfs_exit(cpu); +-} +- +-static int cacheinfo_cpu_callback(struct notifier_block *nfb, +- unsigned long action, void *hcpu) +-{ +- unsigned int cpu = (unsigned long)hcpu; +- struct device *dev; +- +- dev = get_cpu_device(cpu); +- switch (action) { +- case CPU_ONLINE: +- case CPU_ONLINE_FROZEN: +- cache_add_dev(dev); +- break; +- case CPU_DEAD: +- case CPU_DEAD_FROZEN: +- cache_remove_dev(dev); +- break; +- } +- return NOTIFY_OK; +-} +- +-static struct notifier_block cacheinfo_cpu_notifier = { +- .notifier_call = cacheinfo_cpu_callback, +-}; +- +-static int __init cache_sysfs_init(void) +-{ +- int i, err = 0; +- +- if (num_cache_leaves == 0) +- return 0; +- +- cpu_notifier_register_begin(); +- for_each_online_cpu(i) { +- struct device *dev = get_cpu_device(i); +- +- err = cache_add_dev(dev); +- if (err) +- goto out; +- } +- __register_hotcpu_notifier(&cacheinfo_cpu_notifier); +- +-out: +- cpu_notifier_register_done(); +- return err; +-} +- +-device_initcall(cache_sysfs_init); +- +-#endif ++DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) ++DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) +diff --git a/drivers/base/Makefile b/drivers/base/Makefile +index 53c3fe1..527d291 100644 +--- a/drivers/base/Makefile ++++ b/drivers/base/Makefile +@@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ + driver.o class.o platform.o \ + cpu.o firmware.o init.o map.o devres.o \ + attribute_container.o transport_class.o \ +- topology.o container.o property.o ++ topology.o container.o property.o cacheinfo.o + obj-$(CONFIG_DEVTMPFS) += devtmpfs.o + obj-$(CONFIG_DMA_CMA) += dma-contiguous.o + obj-y += power/ +diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c +new file mode 100644 +index 0000000..eb3af27 +--- /dev/null ++++ b/drivers/base/cacheinfo.c +@@ -0,0 +1,662 @@ ++/* ++ * cacheinfo support - processor cache information via sysfs ++ * ++ * Based on arch/x86/kernel/cpu/intel_cacheinfo.c ++ * Author: Sudeep Holla ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* pointer to per cpu cacheinfo */ ++static DEFINE_PER_CPU(struct cpu_cacheinfo, ci_cpu_cacheinfo); ++#define ci_cacheinfo(cpu) (&per_cpu(ci_cpu_cacheinfo, cpu)) ++#define cache_leaves(cpu) (ci_cacheinfo(cpu)->num_leaves) ++#define per_cpu_cacheinfo(cpu) (ci_cacheinfo(cpu)->info_list) ++ ++struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu) ++{ ++ return ci_cacheinfo(cpu); ++} ++ ++#ifdef CONFIG_OF ++static int cache_setup_of_node(unsigned int cpu) ++{ ++ struct device_node *np; ++ struct cacheinfo *this_leaf; ++ struct device *cpu_dev = get_cpu_device(cpu); ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ unsigned int index = 0; ++ ++ /* skip if of_node is already populated */ ++ if (this_cpu_ci->info_list->of_node) ++ return 0; ++ ++ if (!cpu_dev) { ++ pr_err("No cpu device for CPU %d\n", cpu); ++ return -ENODEV; ++ } ++ np = cpu_dev->of_node; ++ if (!np) { ++ pr_err("Failed to find cpu%d device node\n", cpu); ++ return -ENOENT; ++ } ++ ++ while (index < cache_leaves(cpu)) { ++ this_leaf = this_cpu_ci->info_list + index; ++ if (this_leaf->level != 1) ++ np = of_find_next_cache_node(np); ++ else ++ np = of_node_get(np);/* cpu node itself */ ++ if (!np) ++ break; ++ this_leaf->of_node = np; ++ index++; ++ } ++ ++ if (index != cache_leaves(cpu)) /* not all OF nodes populated */ ++ return -ENOENT; ++ ++ return 0; ++} ++ ++static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, ++ struct cacheinfo *sib_leaf) ++{ ++ return sib_leaf->of_node == this_leaf->of_node; ++} ++ ++/* OF properties to query for a given cache type */ ++struct cache_type_info { ++ const char *size_prop; ++ const char *line_size_props[2]; ++ const char *nr_sets_prop; ++}; ++ ++static const struct cache_type_info cache_type_info[] = { ++ { ++ .size_prop = "cache-size", ++ .line_size_props = { "cache-line-size", ++ "cache-block-size", }, ++ .nr_sets_prop = "cache-sets", ++ }, { ++ .size_prop = "i-cache-size", ++ .line_size_props = { "i-cache-line-size", ++ "i-cache-block-size", }, ++ .nr_sets_prop = "i-cache-sets", ++ }, { ++ .size_prop = "d-cache-size", ++ .line_size_props = { "d-cache-line-size", ++ "d-cache-block-size", }, ++ .nr_sets_prop = "d-cache-sets", ++ }, ++}; ++ ++static inline int get_cacheinfo_idx(enum cache_type type) ++{ ++ if (type == CACHE_TYPE_UNIFIED) ++ return 0; ++ return type; ++} ++ ++static void cache_size(struct cacheinfo *this_leaf) ++{ ++ const char *propname; ++ const __be32 *cache_size; ++ int ct_idx; ++ ++ ct_idx = get_cacheinfo_idx(this_leaf->type); ++ propname = cache_type_info[ct_idx].size_prop; ++ ++ cache_size = of_get_property(this_leaf->of_node, propname, NULL); ++ if (cache_size) ++ this_leaf->size = of_read_number(cache_size, 1); ++} ++ ++/* not cache_line_size() because that's a macro in include/linux/cache.h */ ++static void cache_get_line_size(struct cacheinfo *this_leaf) ++{ ++ const __be32 *line_size; ++ int i, lim, ct_idx; ++ ++ ct_idx = get_cacheinfo_idx(this_leaf->type); ++ lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props); ++ ++ for (i = 0; i < lim; i++) { ++ const char *propname; ++ ++ propname = cache_type_info[ct_idx].line_size_props[i]; ++ line_size = of_get_property(this_leaf->of_node, propname, NULL); ++ if (line_size) ++ break; ++ } ++ ++ if (line_size) ++ this_leaf->coherency_line_size = of_read_number(line_size, 1); ++} ++ ++static void cache_nr_sets(struct cacheinfo *this_leaf) ++{ ++ const char *propname; ++ const __be32 *nr_sets; ++ int ct_idx; ++ ++ ct_idx = get_cacheinfo_idx(this_leaf->type); ++ propname = cache_type_info[ct_idx].nr_sets_prop; ++ ++ nr_sets = of_get_property(this_leaf->of_node, propname, NULL); ++ if (nr_sets) ++ this_leaf->number_of_sets = of_read_number(nr_sets, 1); ++} ++ ++static void cache_associativity(struct cacheinfo *this_leaf) ++{ ++ unsigned int line_size = this_leaf->coherency_line_size; ++ unsigned int nr_sets = this_leaf->number_of_sets; ++ unsigned int size = this_leaf->size; ++ ++ /* ++ * If the cache is fully associative, there is no need to ++ * check the other properties. ++ */ ++ if (!(nr_sets == 1) && (nr_sets > 0 && size > 0 && line_size > 0)) ++ this_leaf->ways_of_associativity = (size / nr_sets) / line_size; ++} ++ ++static void cache_of_override_properties(unsigned int cpu) ++{ ++ int index; ++ struct cacheinfo *this_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ ++ for (index = 0; index < cache_leaves(cpu); index++) { ++ this_leaf = this_cpu_ci->info_list + index; ++ cache_size(this_leaf); ++ cache_get_line_size(this_leaf); ++ cache_nr_sets(this_leaf); ++ cache_associativity(this_leaf); ++ } ++} ++#else ++static void cache_of_override_properties(unsigned int cpu) { } ++static inline int cache_setup_of_node(unsigned int cpu) { return 0; } ++static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, ++ struct cacheinfo *sib_leaf) ++{ ++ /* ++ * For non-DT systems, assume unique level 1 cache, system-wide ++ * shared caches for all other levels. This will be used only if ++ * arch specific code has not populated shared_cpu_map ++ */ ++ return !(this_leaf->level == 1); ++} ++#endif ++ ++static int cache_shared_cpu_map_setup(unsigned int cpu) ++{ ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf, *sib_leaf; ++ unsigned int index; ++ int ret = 0; ++ ++ if (this_cpu_ci->cpu_map_populated) ++ return 0; ++ ++ if (of_have_populated_dt()) ++ ret = cache_setup_of_node(cpu); ++ else if (!acpi_disabled) ++ /* No cache property/hierarchy support yet in ACPI */ ++ ret = -ENOTSUPP; ++ if (ret) ++ return ret; ++ ++ for (index = 0; index < cache_leaves(cpu); index++) { ++ unsigned int i; ++ ++ this_leaf = this_cpu_ci->info_list + index; ++ /* skip if shared_cpu_map is already populated */ ++ if (!cpumask_empty(&this_leaf->shared_cpu_map)) ++ continue; ++ ++ cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); ++ for_each_online_cpu(i) { ++ struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); ++ ++ if (i == cpu || !sib_cpu_ci->info_list) ++ continue;/* skip if itself or no cacheinfo */ ++ sib_leaf = sib_cpu_ci->info_list + index; ++ if (cache_leaves_are_shared(this_leaf, sib_leaf)) { ++ cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map); ++ cpumask_set_cpu(i, &this_leaf->shared_cpu_map); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static void cache_shared_cpu_map_remove(unsigned int cpu) ++{ ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf, *sib_leaf; ++ unsigned int sibling, index; ++ ++ for (index = 0; index < cache_leaves(cpu); index++) { ++ this_leaf = this_cpu_ci->info_list + index; ++ for_each_cpu(sibling, &this_leaf->shared_cpu_map) { ++ struct cpu_cacheinfo *sib_cpu_ci; ++ ++ if (sibling == cpu) /* skip itself */ ++ continue; ++ ++ sib_cpu_ci = get_cpu_cacheinfo(sibling); ++ if (!sib_cpu_ci->info_list) ++ continue; ++ ++ sib_leaf = sib_cpu_ci->info_list + index; ++ cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map); ++ cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map); ++ } ++ of_node_put(this_leaf->of_node); ++ } ++} ++ ++static void cache_override_properties(unsigned int cpu) ++{ ++ if (of_have_populated_dt()) ++ return cache_of_override_properties(cpu); ++} ++ ++static void free_cache_attributes(unsigned int cpu) ++{ ++ if (!per_cpu_cacheinfo(cpu)) ++ return; ++ ++ cache_shared_cpu_map_remove(cpu); ++ ++ kfree(per_cpu_cacheinfo(cpu)); ++ per_cpu_cacheinfo(cpu) = NULL; ++} ++ ++int __weak init_cache_level(unsigned int cpu) ++{ ++ return -ENOENT; ++} ++ ++int __weak populate_cache_leaves(unsigned int cpu) ++{ ++ return -ENOENT; ++} ++ ++static int detect_cache_attributes(unsigned int cpu) ++{ ++ int ret; ++ ++ if (init_cache_level(cpu) || !cache_leaves(cpu)) ++ return -ENOENT; ++ ++ per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), ++ sizeof(struct cacheinfo), GFP_KERNEL); ++ if (per_cpu_cacheinfo(cpu) == NULL) ++ return -ENOMEM; ++ ++ ret = populate_cache_leaves(cpu); ++ if (ret) ++ goto free_ci; ++ /* ++ * For systems using DT for cache hierarchy, of_node and shared_cpu_map ++ * will be set up here only if they are not populated already ++ */ ++ ret = cache_shared_cpu_map_setup(cpu); ++ if (ret) { ++ pr_warn("Unable to detect cache hierarchy for CPU %d\n", cpu); ++ goto free_ci; ++ } ++ ++ cache_override_properties(cpu); ++ return 0; ++ ++free_ci: ++ free_cache_attributes(cpu); ++ return ret; ++} ++ ++/* pointer to cpuX/cache device */ ++static DEFINE_PER_CPU(struct device *, ci_cache_dev); ++#define per_cpu_cache_dev(cpu) (per_cpu(ci_cache_dev, cpu)) ++ ++static cpumask_t cache_dev_map; ++ ++/* pointer to array of devices for cpuX/cache/indexY */ ++static DEFINE_PER_CPU(struct device **, ci_index_dev); ++#define per_cpu_index_dev(cpu) (per_cpu(ci_index_dev, cpu)) ++#define per_cache_index_dev(cpu, idx) ((per_cpu_index_dev(cpu))[idx]) ++ ++#define show_one(file_name, object) \ ++static ssize_t file_name##_show(struct device *dev, \ ++ struct device_attribute *attr, char *buf) \ ++{ \ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ ++ return sprintf(buf, "%u\n", this_leaf->object); \ ++} ++ ++show_one(id, id); ++show_one(level, level); ++show_one(coherency_line_size, coherency_line_size); ++show_one(number_of_sets, number_of_sets); ++show_one(physical_line_partition, physical_line_partition); ++show_one(ways_of_associativity, ways_of_associativity); ++ ++static ssize_t size_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%uK\n", this_leaf->size >> 10); ++} ++ ++static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ const struct cpumask *mask = &this_leaf->shared_cpu_map; ++ ++ return cpumap_print_to_pagebuf(list, buf, mask); ++} ++ ++static ssize_t shared_cpu_map_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return shared_cpumap_show_func(dev, false, buf); ++} ++ ++static ssize_t shared_cpu_list_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return shared_cpumap_show_func(dev, true, buf); ++} ++ ++static ssize_t type_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ ++ switch (this_leaf->type) { ++ case CACHE_TYPE_DATA: ++ return sprintf(buf, "Data\n"); ++ case CACHE_TYPE_INST: ++ return sprintf(buf, "Instruction\n"); ++ case CACHE_TYPE_UNIFIED: ++ return sprintf(buf, "Unified\n"); ++ default: ++ return -EINVAL; ++ } ++} ++ ++static ssize_t allocation_policy_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ unsigned int ci_attr = this_leaf->attributes; ++ int n = 0; ++ ++ if ((ci_attr & CACHE_READ_ALLOCATE) && (ci_attr & CACHE_WRITE_ALLOCATE)) ++ n = sprintf(buf, "ReadWriteAllocate\n"); ++ else if (ci_attr & CACHE_READ_ALLOCATE) ++ n = sprintf(buf, "ReadAllocate\n"); ++ else if (ci_attr & CACHE_WRITE_ALLOCATE) ++ n = sprintf(buf, "WriteAllocate\n"); ++ return n; ++} ++ ++static ssize_t write_policy_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ unsigned int ci_attr = this_leaf->attributes; ++ int n = 0; ++ ++ if (ci_attr & CACHE_WRITE_THROUGH) ++ n = sprintf(buf, "WriteThrough\n"); ++ else if (ci_attr & CACHE_WRITE_BACK) ++ n = sprintf(buf, "WriteBack\n"); ++ return n; ++} ++ ++static DEVICE_ATTR_RO(id); ++static DEVICE_ATTR_RO(level); ++static DEVICE_ATTR_RO(type); ++static DEVICE_ATTR_RO(coherency_line_size); ++static DEVICE_ATTR_RO(ways_of_associativity); ++static DEVICE_ATTR_RO(number_of_sets); ++static DEVICE_ATTR_RO(size); ++static DEVICE_ATTR_RO(allocation_policy); ++static DEVICE_ATTR_RO(write_policy); ++static DEVICE_ATTR_RO(shared_cpu_map); ++static DEVICE_ATTR_RO(shared_cpu_list); ++static DEVICE_ATTR_RO(physical_line_partition); ++ ++static struct attribute *cache_default_attrs[] = { ++ &dev_attr_id.attr, ++ &dev_attr_type.attr, ++ &dev_attr_level.attr, ++ &dev_attr_shared_cpu_map.attr, ++ &dev_attr_shared_cpu_list.attr, ++ &dev_attr_coherency_line_size.attr, ++ &dev_attr_ways_of_associativity.attr, ++ &dev_attr_number_of_sets.attr, ++ &dev_attr_size.attr, ++ &dev_attr_allocation_policy.attr, ++ &dev_attr_write_policy.attr, ++ &dev_attr_physical_line_partition.attr, ++ NULL ++}; ++ ++static umode_t ++cache_default_attrs_is_visible(struct kobject *kobj, ++ struct attribute *attr, int unused) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ const struct cpumask *mask = &this_leaf->shared_cpu_map; ++ umode_t mode = attr->mode; ++ ++ if ((attr == &dev_attr_id.attr) && (this_leaf->attributes & CACHE_ID)) ++ return mode; ++ if ((attr == &dev_attr_type.attr) && this_leaf->type) ++ return mode; ++ if ((attr == &dev_attr_level.attr) && this_leaf->level) ++ return mode; ++ if ((attr == &dev_attr_shared_cpu_map.attr) && !cpumask_empty(mask)) ++ return mode; ++ if ((attr == &dev_attr_shared_cpu_list.attr) && !cpumask_empty(mask)) ++ return mode; ++ if ((attr == &dev_attr_coherency_line_size.attr) && ++ this_leaf->coherency_line_size) ++ return mode; ++ if ((attr == &dev_attr_ways_of_associativity.attr) && ++ this_leaf->size) /* allow 0 = full associativity */ ++ return mode; ++ if ((attr == &dev_attr_number_of_sets.attr) && ++ this_leaf->number_of_sets) ++ return mode; ++ if ((attr == &dev_attr_size.attr) && this_leaf->size) ++ return mode; ++ if ((attr == &dev_attr_write_policy.attr) && ++ (this_leaf->attributes & CACHE_WRITE_POLICY_MASK)) ++ return mode; ++ if ((attr == &dev_attr_allocation_policy.attr) && ++ (this_leaf->attributes & CACHE_ALLOCATE_POLICY_MASK)) ++ return mode; ++ if ((attr == &dev_attr_physical_line_partition.attr) && ++ this_leaf->physical_line_partition) ++ return mode; ++ ++ return 0; ++} ++ ++static const struct attribute_group cache_default_group = { ++ .attrs = cache_default_attrs, ++ .is_visible = cache_default_attrs_is_visible, ++}; ++ ++static const struct attribute_group *cache_default_groups[] = { ++ &cache_default_group, ++ NULL, ++}; ++ ++static const struct attribute_group *cache_private_groups[] = { ++ &cache_default_group, ++ NULL, /* Place holder for private group */ ++ NULL, ++}; ++ ++const struct attribute_group * ++__weak cache_get_priv_group(struct cacheinfo *this_leaf) ++{ ++ return NULL; ++} ++ ++static const struct attribute_group ** ++cache_get_attribute_groups(struct cacheinfo *this_leaf) ++{ ++ const struct attribute_group *priv_group = ++ cache_get_priv_group(this_leaf); ++ ++ if (!priv_group) ++ return cache_default_groups; ++ ++ if (!cache_private_groups[1]) ++ cache_private_groups[1] = priv_group; ++ ++ return cache_private_groups; ++} ++ ++/* Add/Remove cache interface for CPU device */ ++static void cpu_cache_sysfs_exit(unsigned int cpu) ++{ ++ int i; ++ struct device *ci_dev; ++ ++ if (per_cpu_index_dev(cpu)) { ++ for (i = 0; i < cache_leaves(cpu); i++) { ++ ci_dev = per_cache_index_dev(cpu, i); ++ if (!ci_dev) ++ continue; ++ device_unregister(ci_dev); ++ } ++ kfree(per_cpu_index_dev(cpu)); ++ per_cpu_index_dev(cpu) = NULL; ++ } ++ device_unregister(per_cpu_cache_dev(cpu)); ++ per_cpu_cache_dev(cpu) = NULL; ++} ++ ++static int cpu_cache_sysfs_init(unsigned int cpu) ++{ ++ struct device *dev = get_cpu_device(cpu); ++ ++ if (per_cpu_cacheinfo(cpu) == NULL) ++ return -ENOENT; ++ ++ per_cpu_cache_dev(cpu) = cpu_device_create(dev, NULL, NULL, "cache"); ++ if (IS_ERR(per_cpu_cache_dev(cpu))) ++ return PTR_ERR(per_cpu_cache_dev(cpu)); ++ ++ /* Allocate all required memory */ ++ per_cpu_index_dev(cpu) = kcalloc(cache_leaves(cpu), ++ sizeof(struct device *), GFP_KERNEL); ++ if (unlikely(per_cpu_index_dev(cpu) == NULL)) ++ goto err_out; ++ ++ return 0; ++ ++err_out: ++ cpu_cache_sysfs_exit(cpu); ++ return -ENOMEM; ++} ++ ++static int cache_add_dev(unsigned int cpu) ++{ ++ unsigned int i; ++ int rc; ++ struct device *ci_dev, *parent; ++ struct cacheinfo *this_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ const struct attribute_group **cache_groups; ++ ++ rc = cpu_cache_sysfs_init(cpu); ++ if (unlikely(rc < 0)) ++ return rc; ++ ++ parent = per_cpu_cache_dev(cpu); ++ for (i = 0; i < cache_leaves(cpu); i++) { ++ this_leaf = this_cpu_ci->info_list + i; ++ if (this_leaf->disable_sysfs) ++ continue; ++ cache_groups = cache_get_attribute_groups(this_leaf); ++ ci_dev = cpu_device_create(parent, this_leaf, cache_groups, ++ "index%1u", i); ++ if (IS_ERR(ci_dev)) { ++ rc = PTR_ERR(ci_dev); ++ goto err; ++ } ++ per_cache_index_dev(cpu, i) = ci_dev; ++ } ++ cpumask_set_cpu(cpu, &cache_dev_map); ++ ++ return 0; ++err: ++ cpu_cache_sysfs_exit(cpu); ++ return rc; ++} ++ ++static int cacheinfo_cpu_online(unsigned int cpu) ++{ ++ int rc = detect_cache_attributes(cpu); ++ ++ if (rc) ++ return rc; ++ rc = cache_add_dev(cpu); ++ if (rc) ++ free_cache_attributes(cpu); ++ return rc; ++} ++ ++static int cacheinfo_cpu_pre_down(unsigned int cpu) ++{ ++ if (cpumask_test_and_clear_cpu(cpu, &cache_dev_map)) ++ cpu_cache_sysfs_exit(cpu); ++ ++ free_cache_attributes(cpu); ++ return 0; ++} ++ ++static int __init cacheinfo_sysfs_init(void) ++{ ++ return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/cacheinfo:online", ++ cacheinfo_cpu_online, cacheinfo_cpu_pre_down); ++} ++device_initcall(cacheinfo_sysfs_init); +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index dfc7870..0ff0eff 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -338,6 +338,60 @@ struct device *get_cpu_device(unsigned cpu) + } + EXPORT_SYMBOL_GPL(get_cpu_device); + ++static void device_create_release(struct device *dev) ++{ ++ kfree(dev); ++} ++ ++static struct device * ++__cpu_device_create(struct device *parent, void *drvdata, ++ const struct attribute_group **groups, ++ const char *fmt, va_list args) ++{ ++ struct device *dev = NULL; ++ int retval = -ENODEV; ++ ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ if (!dev) { ++ retval = -ENOMEM; ++ goto error; ++ } ++ ++ device_initialize(dev); ++ dev->parent = parent; ++ dev->groups = groups; ++ dev->release = device_create_release; ++ dev_set_drvdata(dev, drvdata); ++ ++ retval = kobject_set_name_vargs(&dev->kobj, fmt, args); ++ if (retval) ++ goto error; ++ ++ retval = device_add(dev); ++ if (retval) ++ goto error; ++ ++ return dev; ++ ++error: ++ put_device(dev); ++ return ERR_PTR(retval); ++} ++ ++struct device *cpu_device_create(struct device *parent, void *drvdata, ++ const struct attribute_group **groups, ++ const char *fmt, ...) ++{ ++ va_list vargs; ++ struct device *dev; ++ ++ va_start(vargs, fmt); ++ dev = __cpu_device_create(parent, drvdata, groups, fmt, vargs); ++ va_end(vargs); ++ return dev; ++} ++EXPORT_SYMBOL_GPL(cpu_device_create); ++ + #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); + #endif +diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h +new file mode 100644 +index 0000000..6a524bf +--- /dev/null ++++ b/include/linux/cacheinfo.h +@@ -0,0 +1,104 @@ ++#ifndef _LINUX_CACHEINFO_H ++#define _LINUX_CACHEINFO_H ++ ++#include ++#include ++#include ++ ++struct device_node; ++struct attribute; ++ ++enum cache_type { ++ CACHE_TYPE_NOCACHE = 0, ++ CACHE_TYPE_INST = BIT(0), ++ CACHE_TYPE_DATA = BIT(1), ++ CACHE_TYPE_SEPARATE = CACHE_TYPE_INST | CACHE_TYPE_DATA, ++ CACHE_TYPE_UNIFIED = BIT(2), ++}; ++ ++/** ++ * struct cacheinfo - represent a cache leaf node ++ * @id: This cache's id. It is unique among caches with the same (type, level). ++ * @type: type of the cache - data, inst or unified ++ * @level: represents the hierarchy in the multi-level cache ++ * @coherency_line_size: size of each cache line usually representing ++ * the minimum amount of data that gets transferred from memory ++ * @number_of_sets: total number of sets, a set is a collection of cache ++ * lines sharing the same index ++ * @ways_of_associativity: number of ways in which a particular memory ++ * block can be placed in the cache ++ * @physical_line_partition: number of physical cache lines sharing the ++ * same cachetag ++ * @size: Total size of the cache ++ * @shared_cpu_map: logical cpumask representing all the cpus sharing ++ * this cache node ++ * @attributes: bitfield representing various cache attributes ++ * @of_node: if devicetree is used, this represents either the cpu node in ++ * case there's no explicit cache node or the cache node itself in the ++ * device tree ++ * @disable_sysfs: indicates whether this node is visible to the user via ++ * sysfs or not ++ * @priv: pointer to any private data structure specific to particular ++ * cache design ++ * ++ * While @of_node, @disable_sysfs and @priv are used for internal book ++ * keeping, the remaining members form the core properties of the cache ++ */ ++struct cacheinfo { ++ unsigned int id; ++ enum cache_type type; ++ unsigned int level; ++ unsigned int coherency_line_size; ++ unsigned int number_of_sets; ++ unsigned int ways_of_associativity; ++ unsigned int physical_line_partition; ++ unsigned int size; ++ cpumask_t shared_cpu_map; ++ unsigned int attributes; ++#define CACHE_WRITE_THROUGH BIT(0) ++#define CACHE_WRITE_BACK BIT(1) ++#define CACHE_WRITE_POLICY_MASK \ ++ (CACHE_WRITE_THROUGH | CACHE_WRITE_BACK) ++#define CACHE_READ_ALLOCATE BIT(2) ++#define CACHE_WRITE_ALLOCATE BIT(3) ++#define CACHE_ALLOCATE_POLICY_MASK \ ++ (CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE) ++#define CACHE_ID BIT(4) ++ ++ struct device_node *of_node; ++ bool disable_sysfs; ++ void *priv; ++}; ++ ++struct cpu_cacheinfo { ++ struct cacheinfo *info_list; ++ unsigned int num_levels; ++ unsigned int num_leaves; ++ bool cpu_map_populated; ++}; ++ ++/* ++ * Helpers to make sure "func" is executed on the cpu whose cache ++ * attributes are being detected ++ */ ++#define DEFINE_SMP_CALL_CACHE_FUNCTION(func) \ ++static inline void _##func(void *ret) \ ++{ \ ++ int cpu = smp_processor_id(); \ ++ *(int *)ret = __##func(cpu); \ ++} \ ++ \ ++int func(unsigned int cpu) \ ++{ \ ++ int ret; \ ++ smp_call_function_single(cpu, _##func, &ret, true); \ ++ return ret; \ ++} ++ ++struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu); ++int init_cache_level(unsigned int cpu); ++int populate_cache_leaves(unsigned int cpu); ++ ++const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf); ++ ++#endif /* _LINUX_CACHEINFO_H */ +diff --git a/include/linux/cpu.h b/include/linux/cpu.h +index 6b8e456..f473ccc 100644 +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -36,6 +36,9 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); + extern int cpu_add_dev_attr_group(struct attribute_group *attrs); + extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); + ++extern struct device *cpu_device_create(struct device *parent, void *drvdata, ++ const struct attribute_group **groups, ++ const char *fmt, ...); + #ifdef CONFIG_HOTPLUG_CPU + extern void unregister_cpu(struct cpu *cpu); + extern ssize_t arch_cpu_probe(const char *, size_t); +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch b/kernel-rt/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch new file mode 100644 index 000000000..5370458b3 --- /dev/null +++ b/kernel-rt/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch @@ -0,0 +1,373 @@ +From 6ccffebc5216dffb264c996db07dacc2a6764818 Mon Sep 17 00:00:00 2001 +Message-Id: <6ccffebc5216dffb264c996db07dacc2a6764818.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Wed, 23 Aug 2017 17:58:12 -0400 +Subject: [PATCH 23/26] US101216: IMA support in Titanium kernel + +facilitate building the IMA subsytem out-of-the-kernel tree as a Kernel +module (for which CONFIG_IMA and CONFIG_INTEGRITY will be undefined) by: +- exporting certain function symbols which will be linked to the kernel + module. This includes redefining the export symbols for kernel +functions such that when the kernel module loads, it dynamically points +to those new function definations and reverts to Kernel default +definitions on module deinit +- enabling inode readcount +- modification to ima_file_check to pass in file OPEN status + +Signed-off-by: Jim Somerville +--- + fs/namei.c | 2 +- + fs/nfsd/vfs.c | 2 +- + fs/xattr.c | 1 + + include/linux/fs.h | 15 +------ + include/linux/ima.h | 77 +++++++------------------------- + include/linux/integrity.h | 22 ++++----- + security/security.c | 111 +++++++++++++++++++++++++++++++++++++++++++++- + 7 files changed, 140 insertions(+), 90 deletions(-) + +diff --git a/fs/namei.c b/fs/namei.c +index 0a37e5a..db7455e 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -3198,7 +3198,7 @@ opened: + error = open_check_o_direct(file); + if (error) + goto exit_fput; +- error = ima_file_check(file, op->acc_mode); ++ error = ima_file_check(file, op->acc_mode, *opened); + if (error) + goto exit_fput; + +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index c439a9b..2f169fe 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -883,7 +883,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + goto out_nfserr; + } + +- host_err = ima_file_check(file, may_flags); ++ host_err = ima_file_check(file, may_flags, 0); + if (host_err) { + fput(file); + goto out_nfserr; +diff --git a/fs/xattr.c b/fs/xattr.c +index 3377dff..59ee1c7 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, + *xattr_value = value; + return error; + } ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); + + /* Compare an extended attribute value with the given value */ + int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name, +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 5853208..0e8d7d5 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -666,9 +666,8 @@ struct inode { + struct hlist_head i_fsnotify_marks; + #endif + +-#ifdef CONFIG_IMA + atomic_t i_readcount; /* struct files open RO */ +-#endif ++ + void *i_private; /* fs or device private pointer */ + }; + +@@ -2765,7 +2764,6 @@ static inline bool inode_is_open_for_write(const struct inode *inode) + return atomic_read(&inode->i_writecount) > 0; + } + +-#ifdef CONFIG_IMA + static inline void i_readcount_dec(struct inode *inode) + { + BUG_ON(!atomic_read(&inode->i_readcount)); +@@ -2775,16 +2773,7 @@ static inline void i_readcount_inc(struct inode *inode) + { + atomic_inc(&inode->i_readcount); + } +-#else +-static inline void i_readcount_dec(struct inode *inode) +-{ +- return; +-} +-static inline void i_readcount_inc(struct inode *inode) +-{ +- return; +-} +-#endif ++ + extern int do_pipe_flags(int *, int); + + extern int kernel_read(struct file *, loff_t, char *, unsigned long); +diff --git a/include/linux/ima.h b/include/linux/ima.h +index 1b7f268..9fee45c 100644 +--- a/include/linux/ima.h ++++ b/include/linux/ima.h +@@ -13,64 +13,21 @@ + #include + struct linux_binprm; + +-#ifdef CONFIG_IMA +-extern int ima_bprm_check(struct linux_binprm *bprm); +-extern int ima_file_check(struct file *file, int mask); +-extern void ima_file_free(struct file *file); +-extern int ima_file_mmap(struct file *file, unsigned long prot); +-extern int ima_module_check(struct file *file); +- +-#else +-static inline int ima_bprm_check(struct linux_binprm *bprm) +-{ +- return 0; +-} +- +-static inline int ima_file_check(struct file *file, int mask) +-{ +- return 0; +-} +- +-static inline void ima_file_free(struct file *file) +-{ +- return; +-} +- +-static inline int ima_file_mmap(struct file *file, unsigned long prot) +-{ +- return 0; +-} +- +-static inline int ima_module_check(struct file *file) +-{ +- return 0; +-} +- +-#endif /* CONFIG_IMA */ +- +-#ifdef CONFIG_IMA_APPRAISE +-extern void ima_inode_post_setattr(struct dentry *dentry); +-extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, ++/* ++ * The IMA Kernel module has to redefine these symbols so that ++ * the kernel module can link a dynamic function, as a hook into ++ * the Kernel FS calls (which use these) ++ */ ++/* ifdef CONFIG_IMA */ ++extern int (*ima_bprm_check)(struct linux_binprm *bprm); ++extern int (*ima_file_check)(struct file *file, int mask, int opened); ++extern void (*ima_file_free)(struct file *file); ++extern int (*ima_file_mmap)(struct file *file, unsigned long prot); ++extern int (*ima_module_check)(struct file *file); ++ ++/* ifdef CONFIG_IMA_APPRAISE */ ++extern void (*ima_inode_post_setattr)(struct dentry *dentry); ++extern int (*ima_inode_setxattr)(struct dentry *dentry, const char *xattr_name, + const void *xattr_value, size_t xattr_value_len); +-extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name); +-#else +-static inline void ima_inode_post_setattr(struct dentry *dentry) +-{ +- return; +-} +- +-static inline int ima_inode_setxattr(struct dentry *dentry, +- const char *xattr_name, +- const void *xattr_value, +- size_t xattr_value_len) +-{ +- return 0; +-} +- +-static inline int ima_inode_removexattr(struct dentry *dentry, +- const char *xattr_name) +-{ +- return 0; +-} +-#endif /* CONFIG_IMA_APPRAISE */ +-#endif /* _LINUX_IMA_H */ ++extern int (*ima_inode_removexattr)(struct dentry *dentry, const char *xattr_name); ++#endif +diff --git a/include/linux/integrity.h b/include/linux/integrity.h +index 83222ce..a5040b6 100644 +--- a/include/linux/integrity.h ++++ b/include/linux/integrity.h +@@ -21,20 +21,14 @@ enum integrity_status { + }; + + /* List of EVM protected security xattrs */ +-#ifdef CONFIG_INTEGRITY +-extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode); +-extern void integrity_inode_free(struct inode *inode); ++/* ++ * The Integrity Kernel module has to redefine these symbols so that ++ * the kernel module can link a dynamic function, as a hook into ++ * the Kernel Security subsystem (which use these) ++ */ + +-#else +-static inline struct integrity_iint_cache * +- integrity_inode_get(struct inode *inode) +-{ +- return NULL; +-} ++/* #ifdef CONFIG_INTEGRITY */ ++extern struct integrity_iint_cache *(*integrity_inode_get)(struct inode *inode); ++extern void (*integrity_inode_free)(struct inode *inode); + +-static inline void integrity_inode_free(struct inode *inode) +-{ +- return; +-} +-#endif /* CONFIG_INTEGRITY */ + #endif /* _LINUX_INTEGRITY_H */ +diff --git a/security/security.c b/security/security.c +index 576b882..e7d33c9 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -135,6 +135,110 @@ int __init register_security(struct security_operations *ops) + + /* Security operations */ + ++/* ++ * Export these symbols since the IMA and Integrity ++ * modules will redefine it. We do this EXPORT in ++ * the security endpoint as this is the last Kernel ++ * hook into the Integrity / IMA modules ++ */ ++#ifndef CONFIG_INTEGRITY ++static struct integrity_iint_cache* integrity_inode_get_kmod(struct inode *inode) ++{ ++ return NULL; ++} ++ ++static void integrity_inode_free_kmod(struct inode *inode) ++{ ++ return; ++} ++ ++struct integrity_iint_cache * ++ (*integrity_inode_get)(struct inode *) = &integrity_inode_get_kmod; ++void ++ (*integrity_inode_free)(struct inode*) = &integrity_inode_free_kmod; ++ ++EXPORT_SYMBOL_GPL(integrity_inode_get); ++EXPORT_SYMBOL_GPL(integrity_inode_free); ++#endif ++ ++#ifndef CONFIG_IMA ++static int ima_bprm_check_kmod(struct linux_binprm *bprm) ++{ ++ return 0; ++} ++ ++static int ima_file_check_kmod(struct file *file, int mask, int opened) ++{ ++ return 0; ++} ++ ++static void ima_file_free_kmod(struct file *file) ++{ ++ return; ++} ++ ++static int ima_file_mmap_kmod(struct file *file, unsigned long prot) ++{ ++ return 0; ++} ++ ++static int ima_module_check_kmod(struct file *file) ++{ ++ return 0; ++} ++ ++int ++ (*ima_bprm_check)(struct linux_binprm *) = &ima_bprm_check_kmod; ++int ++ (*ima_file_check)(struct file *, int, int) = &ima_file_check_kmod; ++void ++ (*ima_file_free)(struct file *) = &ima_file_free_kmod; ++int ++ (*ima_file_mmap)(struct file*, unsigned long) = &ima_file_mmap_kmod; ++int ++ (*ima_module_check)(struct file *) = &ima_module_check_kmod; ++ ++EXPORT_SYMBOL_GPL(ima_bprm_check); ++EXPORT_SYMBOL_GPL(ima_file_check); ++EXPORT_SYMBOL_GPL(ima_file_free); ++EXPORT_SYMBOL_GPL(ima_file_mmap); ++EXPORT_SYMBOL_GPL(ima_module_check); ++#endif ++ ++#ifndef CONFIG_IMA_APPRAISE ++static void ima_inode_post_setattr_kmod(struct dentry *dentry) ++{ ++ return; ++} ++ ++static int ima_inode_setxattr_kmod(struct dentry *dentry, ++ const char *xattr_name, ++ const void *xattr_value, ++ size_t xattr_value_len) ++{ ++ return 0; ++} ++ ++static int ima_inode_removexattr_kmod(struct dentry *dentry, ++ const char *xattr_name) ++{ ++ return 0; ++} ++ ++void ++ (*ima_inode_post_setattr)(struct dentry *) = &ima_inode_post_setattr_kmod; ++int ++ (*ima_inode_setxattr)(struct dentry *, const char *, ++ const void *, size_t) = &ima_inode_setxattr_kmod; ++int ++ (*ima_inode_removexattr)(struct dentry *, ++ const char *) = &ima_inode_removexattr_kmod; ++ ++EXPORT_SYMBOL_GPL(ima_inode_post_setattr); ++EXPORT_SYMBOL_GPL(ima_inode_setxattr); ++EXPORT_SYMBOL_GPL(ima_inode_removexattr); ++#endif ++ + int security_ptrace_access_check(struct task_struct *child, unsigned int mode) + { + #ifdef CONFIG_SECURITY_YAMA_STACKED +@@ -694,8 +798,11 @@ EXPORT_SYMBOL(security_inode_listsecurity); + + void security_inode_getsecid(struct inode *inode, u32 *secid) + { +- security_ops->inode_getsecid(inode, secid); ++ if (unlikely(IS_PRIVATE(inode))) ++ return; ++ security_ops->inode_getsecid(inode, secid); + } ++EXPORT_SYMBOL_GPL(security_inode_getsecid); + + int security_inode_copy_up(struct dentry *src, struct cred **new) + { +@@ -1478,6 +1585,7 @@ int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) + { + return security_ops->audit_rule_init(field, op, rulestr, lsmrule); + } ++EXPORT_SYMBOL_GPL(security_audit_rule_init); + + int security_audit_rule_known(struct audit_krule *krule) + { +@@ -1494,5 +1602,6 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, + { + return security_ops->audit_rule_match(secid, field, op, lsmrule, actx); + } ++EXPORT_SYMBOL_GPL(security_audit_rule_match); + + #endif /* CONFIG_AUDIT */ +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/US103091-IMA-System-Configuration.patch b/kernel-rt/centos/patches/US103091-IMA-System-Configuration.patch new file mode 100644 index 000000000..f267fcaca --- /dev/null +++ b/kernel-rt/centos/patches/US103091-IMA-System-Configuration.patch @@ -0,0 +1,234 @@ +From 57cc2aae684bbea546044e973a013bec8bedf409 Mon Sep 17 00:00:00 2001 +Message-Id: <57cc2aae684bbea546044e973a013bec8bedf409.1508185780.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Wed, 4 Oct 2017 14:02:10 -0400 +Subject: [PATCH 1/1] US103091: IMA: System Configuration + +Normally (if trusted integrity keyring is disabled), the _ima keyring +needs to be created by user space (specifically systemd), but that has +the added disadvantage of requiring the IMA public key to reside on the +file system as opposed to being compiled in. Somebody could render some +serious Grade A damage by corrupting this public key on the FS. +Crippling the system if IMA 'enforce' action is enabled. + +We will therefore create the IMA keyring inside the kernel and load the +IMA public key as a compiled data blob, similar to how the Kernel loads +trusted X509 keys into the system truststore (.system_keyring) + +Signed-off-by: Jim Somerville +--- + include/keys/system_keyring.h | 2 ++ + kernel/Makefile | 42 ++++++++++++++++++++-- + kernel/ima_certificate.S | 20 +++++++++++ + kernel/system_keyring.c | 82 +++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 144 insertions(+), 2 deletions(-) + create mode 100644 kernel/ima_certificate.S + +diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h +index 0e49b3c..6b2da90 100644 +--- a/include/keys/system_keyring.h ++++ b/include/keys/system_keyring.h +@@ -34,4 +34,6 @@ static inline struct key *get_system_trusted_keyring(void) + + #endif /* CONFIG_SYSTEM_TRUSTED_KEYRING */ + ++extern struct key *ima_keyring; ++ + #endif /* _KEYS_SYSTEM_KEYRING_H */ +diff --git a/kernel/Makefile b/kernel/Makefile +index 26e10e1..52d4d6a 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -61,7 +61,7 @@ obj-$(CONFIG_QUEUED_SPINLOCKS) += qspinlock.o + obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o + obj-$(CONFIG_LOCK_SPIN_ON_OWNER) += osq_lock.o + obj-$(CONFIG_UID16) += uid16.o +-obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o ++obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o ima_certificate.o + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_MODULE_SIG) += module_signing.o + obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o +@@ -201,7 +201,45 @@ targets += $(obj)/.x509.list + $(obj)/.x509.list: + @echo $(X509_CERTIFICATES) >$@ + +-clean-files := x509_certificate_list .x509.list ++ ++############################################################################### ++# ++# We will roll in the IMA X.509 certificate and pull it in the the kernel ++# so that it gets loaded into the _ima keyring during boot. ++# ++# Ideally, this should have been treated similar to other .x509 certificates ++# (X509_CERTIFICATES), but those all get loaded into the system trusted keyring ++# and since the canonical pathnames are not available in the x509_certificate_list ++# compiled data blob, there is no way to isolate the IMA certificate from the ++# rest. Therefore we treat the IMA certificate as a seperate blob all together. ++# ++# We look in the source root for the IMA certificate, of name "ima_signing_key.pub" ++# ++############################################################################### ++IMA_X509_CERTIFICATE := $(srctree)/ima_signing_key.pub ++ ++ifneq ($(wildcard $(obj)/.x509.ima),) ++ifneq ($(shell cat $(obj)/.x509.ima),$(IMA_X509_CERTIFICATE)) ++$(info IMA: X.509 certificate changed) ++$(shell rm $(obj)/.x509.ima) ++endif ++endif ++ ++kernel/ima_certificate.o: $(obj)/ima_x509_certificate ++ ++quiet_cmd_imacert = CERTS $@ ++ cmd_imacert = cat $(IMA_X509_CERTIFICATE) >$@ $(foreach IMA_X509,$(IMA_X509_CERTIFICATE),; echo " - Including cert $(IMA_X509)") ++ ++targets += $(obj)/ima_x509_certificate ++$(obj)/ima_x509_certificate: $(IMA_X509_CERTIFICATE) $(obj)/.x509.ima ++ $(call if_changed,imacert) ++ ++targets += $(obj)/.x509.ima ++$(obj)/.x509.ima: ++ @echo $(IMA_X509_CERTIFICATE) >$@ ++ ++ ++clean-files := x509_certificate_list .x509.list ima_x509_certificate .x509.ima + endif + + ifeq ($(CONFIG_MODULE_SIG),y) +diff --git a/kernel/ima_certificate.S b/kernel/ima_certificate.S +new file mode 100644 +index 0000000..0c665dd +--- /dev/null ++++ b/kernel/ima_certificate.S +@@ -0,0 +1,20 @@ ++#include ++#include ++ ++ __INITRODATA ++ ++ .align 8 ++ .globl VMLINUX_SYMBOL(ima_system_certificate) ++VMLINUX_SYMBOL(ima_system_certificate): ++__cert_list_start: ++ .incbin "kernel/ima_x509_certificate" ++__cert_list_end: ++ ++ .align 8 ++ .globl VMLINUX_SYMBOL(ima_system_certificate_size) ++VMLINUX_SYMBOL(ima_system_certificate_size): ++#ifdef CONFIG_64BIT ++ .quad __cert_list_end - __cert_list_start ++#else ++ .long __cert_list_end - __cert_list_start ++#endif +diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c +index c15e93f..92beb15 100644 +--- a/kernel/system_keyring.c ++++ b/kernel/system_keyring.c +@@ -23,10 +23,15 @@ EXPORT_SYMBOL_GPL(system_trusted_keyring); + #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING + struct key *system_blacklist_keyring; + #endif ++struct key *ima_keyring; ++EXPORT_SYMBOL_GPL(ima_keyring); + + extern __initconst const u8 system_certificate_list[]; + extern __initconst const unsigned long system_certificate_list_size; + ++extern __initconst const u8 ima_system_certificate[]; ++extern __initconst const unsigned long ima_system_certificate_size; ++ + /* + * Load the compiled-in keys + */ +@@ -57,6 +62,27 @@ static __init int system_trusted_keyring_init(void) + + set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags); + #endif ++ /* Normally (if trusted integrity keyring is disabled), the _ima ++ * keyring needs to be created by user space but that has the ++ * added disadvantage of requiring the IMA public key to reside on ++ * the file system as opposed to being compiled in. ++ * We will therefore form a _ima keyring here and load build ++ * the IMA X.509 certificate ++ * ++ * N.B: The IMA keyring only allows root userspace view & read ops ++ */ ++ pr_notice("Initializing system IMA keyring\n"); ++ ++ ima_keyring = keyring_alloc("_ima", ++ KUIDT_INIT(0), KGIDT_INIT(0), ++ current_cred(), ++ ((KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), ++ KEY_ALLOC_NOT_IN_QUOTA, NULL); ++ if (IS_ERR(ima_keyring)) ++ panic("Can't allocate system IMA keyring\n"); ++ ++ set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_keyring->flags); + + return 0; + } +@@ -121,3 +147,59 @@ dodgy_cert: + return 0; + } + late_initcall(load_system_certificate_list); ++ ++/* ++ * Load the compiled-in IMA certificate. ++ */ ++static __init int load_ima_system_certificate(void) ++{ ++ key_ref_t key; ++ const u8 *p, *end; ++ size_t plen; ++ ++ pr_notice("Loading compiled-in X.509 IMA certificate\n"); ++ ++ p = ima_system_certificate; ++ end = p + ima_system_certificate_size; ++ while (p < end) { ++ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more ++ * than 256 bytes in size. ++ */ ++ if (end - p < 4) ++ goto dodgy_cert; ++ if (p[0] != 0x30 && ++ p[1] != 0x82) ++ goto dodgy_cert; ++ plen = (p[2] << 8) | p[3]; ++ plen += 4; ++ if (plen > end - p) ++ goto dodgy_cert; ++ ++ key = key_create_or_update(make_key_ref(ima_keyring, 1), ++ "asymmetric", ++ NULL, ++ p, ++ plen, ++ ((KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ), ++ KEY_ALLOC_NOT_IN_QUOTA | ++ KEY_ALLOC_TRUSTED); ++ if (IS_ERR(key)) { ++ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", ++ PTR_ERR(key)); ++ } else { ++ set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags); ++ pr_notice("Loaded X.509 cert '%s'\n", ++ key_ref_to_ptr(key)->description); ++ key_ref_put(key); ++ } ++ p += plen; ++ } ++ ++ return 0; ++ ++dodgy_cert: ++ pr_err("Problem parsing in-kernel X.509 IMA certificate\n"); ++ return 0; ++} ++late_initcall(load_ima_system_certificate); +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/affine-compute-kernel-threads.patch b/kernel-rt/centos/patches/affine-compute-kernel-threads.patch new file mode 100644 index 000000000..1f26d537e --- /dev/null +++ b/kernel-rt/centos/patches/affine-compute-kernel-threads.patch @@ -0,0 +1,166 @@ +From 0bd66eb88c950d172a7dcefc61cb2e89b89cacce Mon Sep 17 00:00:00 2001 +Message-Id: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Tue, 24 Nov 2015 16:27:28 -0500 +Subject: [PATCH 01/26] affine compute kernel threads + +This is a kernel enhancement to configure the cpu affinity of kernel +threads via kernel boot option kthread_cpus=. The compute +kickstart file and compute-huge.sh scripts will update grub with the +new option. + +With kthread_cpus specified, the cpumask is immediately applied upon +thread launch. This does not affect kernel threads that specify cpu +and node. + +Note: this is based off of Christoph Lameter's patch at +https://lwn.net/Articles/565932/ with the only difference being +the kernel parameter changed from kthread to kthread_cpus. + +Signed-off-by: Christoph Lameter +Signed-off-by: Chris Friesen +[VT: The existing "isolcpus" + kernel bootarg, cgroup/cpuset, and taskset might provide the some + way to have cpu isolation. However none of them satisfies the requirements. + Replacing spaces with tabs. Combine two calls of set_cpus_allowed_ptr() + in kernel_init_freeable() in init/main.c into one. Performed tests] +Signed-off-by: Vu Tran + +Signed-off-by: Jim Somerville +--- + Documentation/kernel-parameters.txt | 10 ++++++++++ + include/linux/cpumask.h | 2 ++ + init/main.c | 6 ++---- + kernel/cpu.c | 13 +++++++++++++ + kernel/kmod.c | 3 +++ + kernel/kthread.c | 4 ++-- + 6 files changed, 32 insertions(+), 6 deletions(-) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 92b5ff7..e6109df 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -1482,6 +1482,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + kstack=N [X86] Print N words from the kernel stack + in oops dumps. + ++ kthread_cpus= [KNL, SMP] Only run kernel threads on the specified ++ list of processors. The kernel will start threads ++ on the indicated processors only (unless there ++ are specific reasons to run a thread with ++ different affinities). This can be used to make ++ init start on certain processors and also to ++ control where kmod and other user space threads ++ are being spawned. Allows to keep kernel threads ++ away from certain cores unless absoluteluy necessary. ++ + kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. + Default is 0 (don't ignore, but inject #GP) + +diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h +index 123f0a3..bc4fea4 100644 +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -52,6 +52,7 @@ extern int nr_cpu_ids; + * cpu_present_mask - has bit 'cpu' set iff cpu is populated + * cpu_online_mask - has bit 'cpu' set iff cpu available to scheduler + * cpu_active_mask - has bit 'cpu' set iff cpu available to migration ++ * cpu_kthread_mask - has bit 'cpu' set iff general kernel threads allowed + * + * If !CONFIG_HOTPLUG_CPU, present == possible, and active == online. + * +@@ -88,6 +89,7 @@ extern const struct cpumask *const cpu_possible_mask; + extern const struct cpumask *const cpu_online_mask; + extern const struct cpumask *const cpu_present_mask; + extern const struct cpumask *const cpu_active_mask; ++extern const struct cpumask *const cpu_kthread_mask; + + #if NR_CPUS > 1 + #define num_online_cpus() cpumask_weight(cpu_online_mask) +diff --git a/init/main.c b/init/main.c +index c39460d..49ec0cd 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -945,10 +945,6 @@ static noinline void __init kernel_init_freeable(void) + * init can allocate pages on any node + */ + set_mems_allowed(node_states[N_MEMORY]); +- /* +- * init can run on any cpu. +- */ +- set_cpus_allowed_ptr(current, cpu_all_mask); + + cad_pid = task_pid(current); + +@@ -964,6 +960,8 @@ static noinline void __init kernel_init_freeable(void) + + do_basic_setup(); + ++ set_cpus_allowed_ptr(current, cpu_kthread_mask); ++ + /* Open the /dev/console on the rootfs, this should never fail */ + if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) + pr_err("Warning: unable to open an initial console.\n"); +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 05556d0..e23d7ea 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1030,6 +1030,19 @@ static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly; + const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits); + EXPORT_SYMBOL(cpu_active_mask); + ++static DECLARE_BITMAP(cpu_kthread_bits, CONFIG_NR_CPUS) __read_mostly ++ = CPU_BITS_ALL; ++const struct cpumask *const cpu_kthread_mask = to_cpumask(cpu_kthread_bits); ++EXPORT_SYMBOL(cpu_kthread_mask); ++ ++static int __init kthread_setup(char *str) ++{ ++ cpulist_parse(str, (struct cpumask *)&cpu_kthread_bits); ++ return 1; ++} ++__setup("kthread_cpus=", kthread_setup); ++ ++ + void set_cpu_possible(unsigned int cpu, bool possible) + { + if (possible) +diff --git a/kernel/kmod.c b/kernel/kmod.c +index 86ab754..4bf584b 100644 +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -204,6 +204,9 @@ static int ____call_usermodehelper(void *data) + flush_signal_handlers(current, 1); + spin_unlock_irq(¤t->sighand->siglock); + ++ /* We can run only where init is allowed to run. */ ++ set_cpus_allowed_ptr(current, cpu_kthread_mask); ++ + /* + * Our parent is keventd, which runs with elevated scheduling priority. + * Avoid propagating that into the userspace child. +diff --git a/kernel/kthread.c b/kernel/kthread.c +index 703d910..7ea32eb 100644 +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -284,7 +284,7 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), + * The kernel thread should not inherit these properties. + */ + sched_setscheduler_nocheck(create.result, SCHED_NORMAL, ¶m); +- set_cpus_allowed_ptr(create.result, cpu_all_mask); ++ set_cpus_allowed_ptr(create.result, cpu_kthread_mask); + } + return create.result; + } +@@ -454,7 +454,7 @@ int kthreadd(void *unused) + /* Setup a clean context for our children to inherit. */ + set_task_comm(tsk, "kthreadd"); + ignore_signals(tsk); +- set_cpus_allowed_ptr(tsk, cpu_all_mask); ++ set_cpus_allowed_ptr(tsk, cpu_kthread_mask); + set_mems_allowed(node_states[N_MEMORY]); + + current->flags |= PF_NOFREEZE; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch b/kernel-rt/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch new file mode 100644 index 000000000..1ef77dce7 --- /dev/null +++ b/kernel-rt/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch @@ -0,0 +1,52 @@ +From 36dd5acd196574d41de3e81d8264df475bbb7123 Mon Sep 17 00:00:00 2001 +Message-Id: <36dd5acd196574d41de3e81d8264df475bbb7123.1510260544.git.Jim.Somerville@windriver.com> +From: Hannes Reinecke +Date: Mon, 6 Jul 2015 13:07:58 +0200 +Subject: [PATCH 1/1] aic94xx: Skip reading user settings if flash is not found + +If no user settings are found it's pointless trying to +read them from flash. So skip that step. +This also fixes a compilation warning about uninitialized variables in +aic94xx. + +Signed-off-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Signed-off-by: James Bottomley +Signed-off-by: Jim Somerville +--- + drivers/scsi/aic94xx/aic94xx_sds.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c +index edb43fd..c831e30 100644 +--- a/drivers/scsi/aic94xx/aic94xx_sds.c ++++ b/drivers/scsi/aic94xx/aic94xx_sds.c +@@ -983,7 +983,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, + { + int err, i; + u32 offs, size; +- struct asd_ll_el *el; ++ struct asd_ll_el *el = NULL; + struct asd_ctrla_phy_settings *ps; + struct asd_ctrla_phy_settings dflt_ps; + +@@ -1004,6 +1004,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, + + size = sizeof(struct asd_ctrla_phy_settings); + ps = &dflt_ps; ++ goto out_process; + } + + if (size == 0) +@@ -1028,7 +1029,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, + ASD_DPRINTK("couldn't find ctrla phy settings struct\n"); + goto out2; + } +- ++out_process: + err = asd_process_ctrla_phy_settings(asd_ha, ps); + if (err) { + ASD_DPRINTK("couldn't process ctrla phy settings\n"); +-- +1.9.1 + diff --git a/kernel-rt/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch b/kernel-rt/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch new file mode 100644 index 000000000..50423c60b --- /dev/null +++ b/kernel-rt/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch @@ -0,0 +1,58 @@ +From 3c27b4b6c4a4ba1f703fdf270a6c886963117b23 Mon Sep 17 00:00:00 2001 +Message-Id: <3c27b4b6c4a4ba1f703fdf270a6c886963117b23.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Wed, 4 Jun 2014 16:06:56 -0700 +Subject: [PATCH 15/26] arch/x86/kernel/pci-dma.c: fix + dma_generic_alloc_coherent() when CONFIG_DMA_CMA is enabled + +dma_generic_alloc_coherent() firstly attempts to allocate by +dma_alloc_from_contiguous() if CONFIG_DMA_CMA is enabled. But the +memory region allocated by it may not fit within the device's DMA mask. +This change makes it fall back to usual alloc_pages_node() allocation +for such cases. + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +(cherry picked from commit 38f7ea5a082bbde9e64b7ece389f20e71a9806f4) + +Conflicts: + arch/x86/kernel/pci-dma.c + +Signed-off-by: Jim Somerville +--- + arch/x86/kernel/pci-dma.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c +index 9d92ea8..dbc2c74 100644 +--- a/arch/x86/kernel/pci-dma.c ++++ b/arch/x86/kernel/pci-dma.c +@@ -100,8 +100,13 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, + flag &= ~__GFP_ZERO; + again: + page = NULL; +- if (!(flag & GFP_ATOMIC)) ++ if (!(flag & GFP_ATOMIC)) { + page = dma_alloc_from_contiguous(dev, count, get_order(size)); ++ if (page && page_to_phys(page) + size > dma_mask) { ++ dma_release_from_contiguous(dev, page, count); ++ page = NULL; ++ } ++ } + if (!page) + page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); + if (!page) +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch b/kernel-rt/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch new file mode 100644 index 000000000..71a89e2ef --- /dev/null +++ b/kernel-rt/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch @@ -0,0 +1,224 @@ +From 4e9b5379a010ad11e88365fbca2828fc08ab5243 Mon Sep 17 00:00:00 2001 +Message-Id: <4e9b5379a010ad11e88365fbca2828fc08ab5243.1507911922.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Tue, 31 May 2016 16:09:04 -0400 +Subject: [PATCH 04/26] cma: add placement specifier for "cma=" kernel + parameter + +Commit 5ea3b1b2f8ad9162684431ce6188102ca4c64b7a upstream +Backported-by: Nam Ninh + +Currently, "cma=" kernel parameter is used to specify the size of CMA, +but we can't specify where it is located. We want to locate CMA below +4GB for devices only supporting 32-bit addressing on 64-bit systems +without iommu. + +This enables to specify the placement of CMA by extending "cma=" kernel +parameter. + +Examples: + 1. locate 64MB CMA below 4GB by "cma=64M@0-4G" + 2. locate 64MB CMA exact at 512MB by "cma=64M@512M" + +Note that the DMA contiguous memory allocator on x86 assumes that +page_address() works for the pages to allocate. So this change requires +to limit end address of contiguous memory area upto max_pfn_mapped to +prevent from locating it on highmem area by the argument of +dma_contiguous_reserve(). + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + Documentation/kernel-parameters.txt | 7 +++++-- + arch/x86/kernel/setup.c | 2 +- + drivers/base/dma-contiguous.c | 42 ++++++++++++++++++++++++++++--------- + include/linux/dma-contiguous.h | 9 +++++--- + 4 files changed, 44 insertions(+), 16 deletions(-) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index e6109df..d723499 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -560,8 +560,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + Also note the kernel might malfunction if you disable + some critical bits. + +- cma=nn[MG] [ARM,KNL] +- Sets the size of kernel global memory area for contiguous ++ cma=nn[MG]@[start[MG][-end[MG]]] ++ [ARM,X86,KNL] ++ Sets the size of kernel global memory area for ++ contiguous memory allocations and optionally the ++ placement constraint by the physical address range of + memory allocations. For more information, see + include/linux/dma-contiguous.h + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index dcb7e8a..ab7c0c3 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1252,7 +1252,7 @@ void __init setup_arch(char **cmdline_p) + setup_real_mode(); + + memblock_set_current_limit(get_max_mapped()); +- dma_contiguous_reserve(0); ++ dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT); + + /* + * NOTE: On x86-32, only from this point on, fixmaps are ready for use. +diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c +index 99802d6..8f50513 100644 +--- a/drivers/base/dma-contiguous.c ++++ b/drivers/base/dma-contiguous.c +@@ -59,11 +59,22 @@ struct cma *dma_contiguous_default_area; + */ + static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M; + static phys_addr_t size_cmdline = -1; ++static phys_addr_t base_cmdline; ++static phys_addr_t limit_cmdline; + + static int __init early_cma(char *p) + { + pr_debug("%s(%s)\n", __func__, p); + size_cmdline = memparse(p, &p); ++ if (*p != '@') ++ return 0; ++ base_cmdline = memparse(p + 1, &p); ++ if (*p != '-') { ++ limit_cmdline = base_cmdline + size_cmdline; ++ return 0; ++ } ++ limit_cmdline = memparse(p + 1, &p); ++ + return 0; + } + early_param("cma", early_cma); +@@ -107,11 +118,18 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void) + void __init dma_contiguous_reserve(phys_addr_t limit) + { + phys_addr_t selected_size = 0; ++ phys_addr_t selected_base = 0; ++ phys_addr_t selected_limit = limit; ++ bool fixed = false; + + pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); + + if (size_cmdline != -1) { + selected_size = size_cmdline; ++ selected_base = base_cmdline; ++ selected_limit = min_not_zero(limit_cmdline, limit); ++ if (base_cmdline + size_cmdline == limit_cmdline) ++ fixed = true; + } else { + #ifdef CONFIG_CMA_SIZE_SEL_MBYTES + selected_size = size_bytes; +@@ -128,10 +146,12 @@ void __init dma_contiguous_reserve(phys_addr_t limit) + pr_debug("%s: reserving %ld MiB for global area\n", __func__, + (unsigned long)selected_size / SZ_1M); + +- dma_contiguous_reserve_area(selected_size, 0, limit, +- &dma_contiguous_default_area); ++ dma_contiguous_reserve_area(selected_size, selected_base, ++ selected_limit, ++ &dma_contiguous_default_area, ++ fixed); + } +-}; ++} + + static DEFINE_MUTEX(cma_mutex); + +@@ -187,15 +207,20 @@ core_initcall(cma_init_reserved_areas); + * @base: Base address of the reserved area optional, use 0 for any + * @limit: End address of the reserved memory (optional, 0 for any). + * @res_cma: Pointer to store the created cma region. ++ * @fixed: hint about where to place the reserved area + * + * This function reserves memory from early allocator. It should be + * called by arch specific code once the early allocator (memblock or bootmem) + * has been activated and all other subsystems have already allocated/reserved + * memory. This function allows to create custom reserved areas for specific + * devices. ++ * ++ * If @fixed is true, reserve contiguous area at exactly @base. If false, ++ * reserve in range from @base to @limit. + */ + int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, +- phys_addr_t limit, struct cma **res_cma) ++ phys_addr_t limit, struct cma **res_cma, ++ bool fixed) + { + struct cma *cma = &cma_areas[cma_area_count]; + phys_addr_t alignment; +@@ -221,18 +246,15 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + limit &= ~(alignment - 1); + + /* Reserve memory */ +- if (base) { ++ if (base && fixed) { + if (memblock_is_region_reserved(base, size) || + memblock_reserve(base, size) < 0) { + ret = -EBUSY; + goto err; + } + } else { +- /* +- * Use __memblock_alloc_base() since +- * memblock_alloc_base() panic()s. +- */ +- phys_addr_t addr = __memblock_alloc_base(size, alignment, limit); ++ phys_addr_t addr = memblock_alloc_range(size, alignment, base, ++ limit); + if (!addr) { + ret = -ENOMEM; + goto err; +diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h +index 3b28f93..772eab5 100644 +--- a/include/linux/dma-contiguous.h ++++ b/include/linux/dma-contiguous.h +@@ -88,7 +88,8 @@ static inline void dma_contiguous_set_default(struct cma *cma) + void dma_contiguous_reserve(phys_addr_t addr_limit); + + int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, +- phys_addr_t limit, struct cma **res_cma); ++ phys_addr_t limit, struct cma **res_cma, ++ bool fixed); + + /** + * dma_declare_contiguous() - reserve area for contiguous memory handling +@@ -108,7 +109,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, + { + struct cma *cma; + int ret; +- ret = dma_contiguous_reserve_area(size, base, limit, &cma); ++ ret = dma_contiguous_reserve_area(size, base, limit, &cma, true); + if (ret == 0) + dev_set_cma_area(dev, cma); + +@@ -136,7 +137,9 @@ static inline void dma_contiguous_set_default(struct cma *cma) { } + static inline void dma_contiguous_reserve(phys_addr_t limit) { } + + static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, +- phys_addr_t limit, struct cma **res_cma) { ++ phys_addr_t limit, struct cma **res_cma, ++ bool fixed) ++{ + return -ENOSYS; + } + +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch b/kernel-rt/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch new file mode 100644 index 000000000..833837cbe --- /dev/null +++ b/kernel-rt/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch @@ -0,0 +1,92 @@ +From 83c9c822f24ee171998e209dd571b32a7416eca4 Mon Sep 17 00:00:00 2001 +Message-Id: <83c9c822f24ee171998e209dd571b32a7416eca4.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: "Rafael J. Wysocki" +Date: Fri, 24 Feb 2017 13:25:14 +0100 +Subject: [PATCH 22/26] cpuidle: menu: Avoid taking spinlock for accessing QoS + values + +[commit 6dbf5cea05a7098a69f294c96b6d76f08562cae5 from linux-stable ] + +After commit 9908859acaa9 (cpuidle/menu: add per CPU PM QoS resume +latency consideration) the cpuidle menu governor calls +dev_pm_qos_read_value() on CPU devices to read the current resume latency QoS +constraint values for them. That function takes a spinlock to prevent the +device's power.qos pointer from becoming NULL during the access which is a +problem for the RT patchset where spinlocks are converted into mutexes and +the idle loop stops working. + +However, it is not even necessary for the menu governor to take +that spinlock, because the power.qos pointer accessed under it +cannot be modified during the access anyway. + +For this reason, introduce a "raw" routine for accessing device +QoS resume latency constraints without locking and use it in the +menu governor. + +Fixes: 9908859acaa9 (cpuidle/menu: add per CPU PM QoS resume latency consideration) +Acked-by: Alex Shi +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + drivers/base/power/qos.c | 3 +-- + drivers/cpuidle/governors/menu.c | 2 +- + include/linux/pm_qos.h | 6 ++++++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c +index 2f8ac59..08a4cec 100644 +--- a/drivers/base/power/qos.c ++++ b/drivers/base/power/qos.c +@@ -104,8 +104,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags); + */ + s32 __dev_pm_qos_read_value(struct device *dev) + { +- return IS_ERR_OR_NULL(dev->power.qos) ? +- 0 : pm_qos_read_value(&dev->power.qos->latency); ++ return dev_pm_qos_raw_read_value(dev); + } + + /** +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index fe2dcb8..f9861fd 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -265,7 +265,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + int i; + int multiplier; + struct timespec t; +- int resume_latency = dev_pm_qos_read_value(device); ++ int resume_latency = dev_pm_qos_raw_read_value(device); + + if (data->needs_update) { + menu_update(drv, dev); +diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h +index 5281e7f..1d8b629 100644 +--- a/include/linux/pm_qos.h ++++ b/include/linux/pm_qos.h +@@ -217,6 +217,11 @@ static inline s32 dev_pm_qos_requested_flags(struct device *dev) + { + return dev->power.qos->flags_req->data.flr.flags; + } ++static inline s32 dev_pm_qos_raw_read_value(struct device *dev) ++{ ++ return IS_ERR_OR_NULL(dev->power.qos) ? ++ 0 : pm_qos_read_value(&dev->power.qos->latency); ++} + #else + static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) + { return 0; } +@@ -236,6 +241,7 @@ static inline void dev_pm_qos_hide_latency_tolerance(struct device *dev) {} + + static inline s32 dev_pm_qos_requested_latency(struct device *dev) { return 0; } + static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; } ++static inline s32 dev_pm_qos_raw_read_value(struct device *dev) { return 0; } + #endif + + #endif +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch b/kernel-rt/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch new file mode 100644 index 000000000..c15856e6b --- /dev/null +++ b/kernel-rt/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch @@ -0,0 +1,71 @@ +From d087440dbd07fea5c5c52015b93fc46ce8a96d5f Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Alex Shi +Date: Thu, 12 Jan 2017 21:27:04 +0800 +Subject: [PATCH 20/26] cpuidle/menu: add per CPU PM QoS resume latency + consideration + +[ commit 9908859acaa95640d4a07991a93f7cd5bfc18e02 from linux-stable ] + +There may be special requirements on CPU response time, like if +a interrupt is pinned to a CPU, that CPU should not go into excessively deep +idle states. For this reason, add a mechanism for adding PM QoS resume +latency constraints for individual CPUs and modify the menu governor to take +them into account. + +To that end, extend the device PM QoS pm_qos_resume_latency attribute +to CPUs, which is possible, because the exit latency for CPUs is +effectively equivalent to the resume latency for devices. + +Signed-off-by: Alex Shi +Acked-by: Rik van Riel +[ rjw : Subject & changelog ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev + +Signed-off-by: Jim Somerville +--- + drivers/cpuidle/governors/menu.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index eb9fb0e..fe2dcb8 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + #define BUCKETS 12 +@@ -259,10 +260,12 @@ again: + static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + { + struct menu_device *data = &__get_cpu_var(menu_devices); ++ struct device *device = get_cpu_device(dev->cpu); + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); + int i; + int multiplier; + struct timespec t; ++ int resume_latency = dev_pm_qos_read_value(device); + + if (data->needs_update) { + menu_update(drv, dev); +@@ -271,6 +274,10 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + + data->exit_us = 0; + ++ /* resume_latency is 0 means no restriction */ ++ if (resume_latency && resume_latency < latency_req) ++ latency_req = resume_latency; ++ + /* Special case when user has set very strict latency requirement */ + if (unlikely(latency_req == 0)) + return 0; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch b/kernel-rt/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch new file mode 100644 index 000000000..819cf4bce --- /dev/null +++ b/kernel-rt/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch @@ -0,0 +1,52 @@ +From dfc5d8197b1e2550462352c15afe4150aa53392a Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Alex Shi +Date: Thu, 12 Jan 2017 21:27:02 +0800 +Subject: [PATCH 19/26] cpuidle/menu: stop seeking deeper idle if current state + is deep enough + +[ commit 8e37e1a2a3295f5d99e6dbe99eca24eca7a034ef from linux-stable ] + +Obsolete commit 71abbbf856a0 (cpuidle: extend cpuidle and menu +governor to handle dynamic states) wanted to introduce dynamic C-states, but +that idea was dropped long ago. The nonsense deeper C-state checking +remained, though. + +Since both target_residency and exit_latency are longer for deeper +idle state, there's no need to waste CPU time on useless checks. + +Signed-off-by: Alex Shi +Acked-by: Rik van Riel +[ rjw: Subject & changelog ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev + +Signed-off-by: Jim Somerville +--- + drivers/cpuidle/governors/menu.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index c99fee9..eb9fb0e 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -323,11 +323,11 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + if (s->disabled || su->disable) + continue; + if (s->target_residency > data->predicted_us) +- continue; ++ break; + if (s->exit_latency > latency_req) +- continue; ++ break; + if (s->exit_latency * multiplier > data->predicted_us) +- continue; ++ break; + + data->last_state_idx = i; + data->exit_us = s->exit_latency; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/cpupower.config b/kernel-rt/centos/patches/cpupower.config new file mode 100644 index 000000000..8629a4a3e --- /dev/null +++ b/kernel-rt/centos/patches/cpupower.config @@ -0,0 +1,3 @@ +# See 'cpupower help' and cpupower(1) for more info +CPUPOWER_START_OPTS="frequency-set -g performance" +CPUPOWER_STOP_OPTS="frequency-set -g ondemand" diff --git a/kernel-rt/centos/patches/cpupower.service b/kernel-rt/centos/patches/cpupower.service new file mode 100644 index 000000000..5f10ab7ee --- /dev/null +++ b/kernel-rt/centos/patches/cpupower.service @@ -0,0 +1,13 @@ +[Unit] +Description=Configure CPU power related settings +After=syslog.target + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=/etc/sysconfig/cpupower +ExecStart=/usr/bin/cpupower $CPUPOWER_START_OPTS +ExecStop=/usr/bin/cpupower $CPUPOWER_STOP_OPTS + +[Install] +WantedBy=multi-user.target diff --git a/kernel-rt/centos/patches/debrand-rh-i686-cpu.patch b/kernel-rt/centos/patches/debrand-rh-i686-cpu.patch new file mode 100644 index 000000000..739855c26 --- /dev/null +++ b/kernel-rt/centos/patches/debrand-rh-i686-cpu.patch @@ -0,0 +1,11 @@ +--- a/arch/x86/boot/main.c 2014-06-04 10:05:04.000000000 -0700 ++++ b/arch/x86/boot/main.c 2014-07-09 12:54:40.000000000 -0700 +@@ -146,7 +146,7 @@ void main(void) + + /* Make sure we have all the proper CPU support */ + if (validate_cpu()) { +- puts("This processor is unsupported in RHEL7.\n"); ++ puts("This processor is unsupported in CentOS 7.\n"); + die(); + } + diff --git a/kernel-rt/centos/patches/debrand-rh_taint.patch b/kernel-rt/centos/patches/debrand-rh_taint.patch new file mode 100644 index 000000000..8ef4557ac --- /dev/null +++ b/kernel-rt/centos/patches/debrand-rh_taint.patch @@ -0,0 +1,25 @@ +From 69c0d42cfa26515196896dea086857c2caccb6eb Mon Sep 17 00:00:00 2001 +From: Jim Perrin +Date: Thu, 19 Jun 2014 10:05:12 -0500 +Subject: [PATCH] branding patch for rh_taint + +--- + kernel/rh_taint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/rh_taint.c b/kernel/rh_taint.c +index 59a74b0..0708e15 100644 +--- a/kernel/rh_taint.c ++++ b/kernel/rh_taint.c +@@ -8,7 +8,7 @@ + void mark_hardware_unsupported(const char *msg) + { + /* Print one single message */ +- pr_crit("Warning: %s - this hardware has not undergone testing by Red Hat and might not be certified. Please consult https://hardware.redhat.com for certified hardware.\n", msg); ++ pr_crit("Warning: %s - this hardware has not undergone upstream testing. Please consult http://wiki.centos.org/FAQ for more information\n", msg); + } + EXPORT_SYMBOL(mark_hardware_unsupported); + +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/debrand-single-cpu.patch b/kernel-rt/centos/patches/debrand-single-cpu.patch new file mode 100644 index 000000000..9d2e08b04 --- /dev/null +++ b/kernel-rt/centos/patches/debrand-single-cpu.patch @@ -0,0 +1,25 @@ +From 66185f5c6f881847776702e3a7956c504400f4f2 Mon Sep 17 00:00:00 2001 +From: Jim Perrin +Date: Thu, 19 Jun 2014 09:53:13 -0500 +Subject: [PATCH] branding patch for single-cpu systems + +--- + arch/x86/kernel/setup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index b289118..9d25982 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -846,7 +846,7 @@ static void rh_check_supported(void) + if (((boot_cpu_data.x86_max_cores * smp_num_siblings) == 1) && + !x86_hyper && !cpu_has_hypervisor && !is_kdump_kernel()) { + pr_crit("Detected single cpu native boot.\n"); +- pr_crit("Important: In Red Hat Enterprise Linux 7, single threaded, single CPU 64-bit physical systems are unsupported by Red Hat. Please contact your Red Hat support representative for a list of certified and supported systems."); ++ pr_crit("Important: In CentOS 7, single threaded, single CPU 64-bit physical systems are unsupported. Please see http://wiki.centos.org/FAQ for more information"); + } + + /* The RHEL7 kernel does not support this hardware. The kernel will +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/dpt_i2o-fix-build-warning.patch b/kernel-rt/centos/patches/dpt_i2o-fix-build-warning.patch new file mode 100644 index 000000000..b865b44e9 --- /dev/null +++ b/kernel-rt/centos/patches/dpt_i2o-fix-build-warning.patch @@ -0,0 +1,42 @@ +From f50abb9b63b1d8773e1ce32115701c06416e6f91 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sudip Mukherjee +Date: Thu, 18 Feb 2016 13:59:13 +0530 +Subject: [PATCH 1/1] dpt_i2o: fix build warning + +We were getting build warning about: +drivers/scsi/dpt_i2o.c:183:29: warning: 'dptids' defined but not used + +dptids[] is only used in the MODULE_DEVICE_TABLE so when MODULE is not +defined then dptids[] becomes unused. + +Signed-off-by: Sudip Mukherjee +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Jim Somerville +--- + drivers/scsi/dpt_i2o.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c +index d4cda5e..21c8d21 100644 +--- a/drivers/scsi/dpt_i2o.c ++++ b/drivers/scsi/dpt_i2o.c +@@ -180,11 +180,14 @@ static u8 adpt_read_blink_led(adpt_hba* host) + *============================================================================ + */ + ++#ifdef MODULE + static struct pci_device_id dptids[] = { + { PCI_DPT_VENDOR_ID, PCI_DPT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + { PCI_DPT_VENDOR_ID, PCI_DPT_RAPTOR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + { 0, } + }; ++#endif ++ + MODULE_DEVICE_TABLE(pci,dptids); + + static int adpt_detect(struct scsi_host_template* sht) +-- +1.9.1 + diff --git a/kernel-rt/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch b/kernel-rt/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch new file mode 100644 index 000000000..071a4bbec --- /dev/null +++ b/kernel-rt/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch @@ -0,0 +1,120 @@ +From d72c68c72ecef169b3a01c2623ef7b4542449aa6 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Matt Peters +Date: Mon, 30 May 2016 10:51:02 -0400 +Subject: [PATCH 05/26] intel-iommu: allow ignoring Ethernet device RMRR with + IOMMU passthrough + +Some BIOS's are reporting DMAR RMRR entries for Ethernet devices +which is causing problems when PCI passthrough is enabled. These +devices should be able to use the static identity map since the +host should not be enforcing specific address ranges when IOMMU +passthrough is enabled. + +Originally-by: Matt Peters +[PG: Added bootarg wrapper and documentation entries.] +Signed-off-by: Paul Gortmaker +Signed-off-by: Nam Ninh + +Signed-off-by: Nam Ninh +Signed-off-by: Jim Somerville +--- + Documentation/Intel-IOMMU.txt | 18 ++++++++++++++++++ + Documentation/kernel-parameters.txt | 5 +++++ + drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++ + 3 files changed, 42 insertions(+) + +diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt +index cf9431d..1dcc349 100644 +--- a/Documentation/Intel-IOMMU.txt ++++ b/Documentation/Intel-IOMMU.txt +@@ -32,6 +32,24 @@ regions will fail. Hence BIOS uses RMRR to specify these regions along with + devices that need to access these regions. OS is expected to setup + unity mappings for these regions for these devices to access these regions. + ++RMRR for other devices? ++----------------------- ++ ++There are reports of BIOS out there that indicate RMRR regions for things ++like ethernet devices. As per mainline commit c875d2c1b8083 ("iommu/vt-d: ++ Exclude devices using RMRRs from IOMMU API domains") such a device is ++"fundamentally incompatible" with the IOMMU API and "we must prevent such ++devices from being used by the IOMMU API." However, in the event that ++the RMRR indicated by the BIOS is assumed to be just a reporting error, ++there is an additional iommu boot arg that can be used to ignore RMRR ++settings for ethernet, i.e. "intel_iommu=on,eth_no_rmrr iommu=pt". ++Note that iommu=pt is required in order to eth_no_rmrr to have effect. ++ ++If you use this setting, you should consult with your hardware vendor to ++confirm that it is just a reporting error, and that it truly is not ++actively using any DMA to/from RMRR, as otherwise system instability ++may result. ++ + How is IOVA generated? + --------------------- + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index d723499..907487a 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -1267,6 +1267,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + than 32-bit addressing. The default is to look + for translation below 32-bit and if not available + then look in the higher range. ++ eth_no_rmrr [Default Off] ++ With this option provided, the kernel will ignore ++ any specified RMRR regions specified by the BIOS ++ for PCI ethernet devices. Confirm with your hardware ++ vendor the RMRR regions are indeed invalid first. + strict [Default Off] + With this option on every unmap_single operation will + result in a hardware IOTLB flush operation as opposed +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index 171a8b2..e763e78 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -496,6 +496,7 @@ static int dmar_forcedac; + static int intel_iommu_strict; + static int intel_iommu_superpage = 1; + static int intel_iommu_ecs = 1; ++static int intel_iommu_ethrmrr = 1; + + /* We only actually use ECS when PASID support (on the new bit 40) + * is also advertised. Some early implementations — the ones with +@@ -555,6 +556,15 @@ static int __init intel_iommu_setup(char *str) + } else if (!strncmp(str, "forcedac", 8)) { + pr_info("Forcing DAC for PCI devices\n"); + dmar_forcedac = 1; ++ } else if (!strncmp(str, "eth_no_rmrr", 11)) { ++ if (!iommu_pass_through) { ++ printk(KERN_WARNING ++ "Intel-IOMMU: error - eth_no_rmrr requires iommu=pt\n"); ++ } else { ++ printk(KERN_INFO ++ "Intel-IOMMU: ignoring ethernet RMRR values\n"); ++ intel_iommu_ethrmrr = 0; ++ } + } else if (!strncmp(str, "strict", 6)) { + pr_info("Disable batched IOTLB flush\n"); + intel_iommu_strict = 1; +@@ -2674,6 +2684,15 @@ static bool device_is_rmrr_locked(struct device *dev) + + if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev)) + return false; ++ /* As a temporary workaround for issues seen on ProLiant DL380p, ++ * allow the operator to ignore the RMRR settings for ethernet ++ * devices. Ideally the end user should contact their vendor ++ * regarding why there are RMRR, as per mainline c875d2c1b8083 ++ * ("iommu/vt-d: Exclude devices using RMRRs from IOMMU API domains") ++ * it seems that these make no sense at all. ++ */ ++ if ((pdev->class >> 8) == PCI_CLASS_NETWORK_ETHERNET && !intel_iommu_ethrmrr) ++ return false; + } + + return true; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-debug.config.tis_extra b/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-debug.config.tis_extra new file mode 100644 index 000000000..d6ec97cac --- /dev/null +++ b/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-debug.config.tis_extra @@ -0,0 +1,6 @@ +CONFIG_SIGEXIT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_SIZE_SEL_MBYTES=y +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=7 diff --git a/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-trace.config.tis_extra b/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-trace.config.tis_extra new file mode 100644 index 000000000..d6ec97cac --- /dev/null +++ b/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt-trace.config.tis_extra @@ -0,0 +1,6 @@ +CONFIG_SIGEXIT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_SIZE_SEL_MBYTES=y +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=7 diff --git a/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt.config.tis_extra b/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt.config.tis_extra new file mode 100644 index 000000000..08cd477c4 --- /dev/null +++ b/kernel-rt/centos/patches/kernel-3.10.0-x86_64-rt.config.tis_extra @@ -0,0 +1,967 @@ +# Add builtin +CONFIG_MAXSMP=n +CONFIG_NR_CPUS=256 +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_SAS_ATTRS=y +CONFIG_ISCSI_TCP=y +# SCSI Related Drivers +# Let's enable lots of them, pretty much anything RAID capable +CONFIG_ATA=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_BLK_DEV_3W_XXXX_RAID=y +CONFIG_SCSI_3W_9XXX=y +CONFIG_SCSI_3W_SAS=y +CONFIG_SCSI_AACRAID=y +CONFIG_SCSI_DPT_I2O=y +CONFIG_SCSI_ARCMSR=y +CONFIG_SCSI_HPTIOP=y +CONFIG_SCSI_GDTH=y +CONFIG_SCSI_IPS=y +CONFIG_SCSI_STEX=y +CONFIG_SCSI_PMCRAID=y +CONFIG_SCSI_HPSA=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_SMARTPQI=y +CONFIG_SCSI_MPT2SAS=y +CONFIG_SCSI_MPT3SAS=y +CONFIG_SCSI_VIRTIO=y +CONFIG_FUSION_SAS=y +CONFIG_SCSI_AIC94XX=y +CONFIG_SCSI_MVSAS=y +# +CONFIG_SOFT_WATCHDOG=y +CONFIG_VIRTIO=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_MMIO=y +CONFIG_ISO9660_FS=y +CONFIG_VFAT_FS=y +CONFIG_NLS_ISO8859_1=y +#CONFIG_MCORE2=y +CONFIG_SIGEXIT=y +CONFIG_SCHEDSTATS=y + +# Enable runtime Huge TLB support +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_SIZE_SEL_MBYTES=y +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=7 + +# Turn on Intel IOMMU, EXT2_FS and EXT3_FS +CONFIG_INTEL_IOMMU_DEFAULT_ON=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=n +CONFIG_EXT3_FS=y +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y + +# Turn off network drivers that we want +# to build out-of-tree +CONFIG_I40E=n +CONFIG_I40EVF=n +CONFIG_IXGB=n +CONFIG_IXGBE=n +CONFIG_IXGBEVF=n +CONFIG_MLX4_EN=n +CONFIG_MLX4_CORE=n +CONFIG_MLX5_EN=n +CONFIG_MLX5_CORE=n + +# Turn off TPM drivers that we want +# to build out-of-tree. This will +# disable the TPM HW-RandomNUmberGenerator(RNG) +# and TrustedKeys modules as well, since +# they require the in-kernel TPM driver. +# Both these modules will also need to be +# built out-of-tree when needed. +CONFIG_TCG_TPM=n +CONFIG_TCG_TIS=n +CONFIG_HW_RANDOM_TPM=n +CONFIG_TRUSTED_KEYS=n +CONFIG_TCG_TIS_I2C_ATMEL=n +CONFIG_TCG_TIS_I2C_INFINEON=n +CONFIG_TCG_TIS_I2C_NUVOTON=n +CONFIG_TCG_NSC=n +CONFIG_TCG_ATMEL=n +CONFIG_TCG_INFINEON=n +CONFIG_TCG_CRB=n +CONFIG_TCG_TIS_ST33ZP24=n +CONFIG_TCG_TIS_ST33ZP24_I2C=n + +# Also disable TPM Integrity Measurement Architecture +# (IMA), as this will be built out of tree but ensure +# that all their dependencies (that comes from the base kernel) +# that are marked as "select" within the Integrity / IMA +# Kconfigs are still enabled +CONFIG_INTEGRITY=n +CONFIG_IMA=n +CONFIG_EVM=n +CONFIG_SIGNATURE=y +CONFIG_KEYS=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_SECURITYFS=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y + +# Remove unneeded stuff (including stuff exposed +# by saying y to new options above. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=n +CONFIG_PANIC_ON_OOPS=n +CONFIG_SOUND=n +CONFIG_FIREWIRE=n +CONFIG_KPROBES=n +CONFIG_XEN=n +CONFIG_IP_SET=n +CONFIG_IP_VS=n +CONFIG_BT=n +CONFIG_INTEL_MEI=n +CONFIG_USB_USBNET=n +CONFIG_RTL8187=n +CONFIG_MWL8K=n +CONFIG_CFG80211=n +CONFIG_WAN=n +CONFIG_ISDN=n +CONFIG_INPUT_TOUCHSCREEN=n +CONFIG_SSB=n +CONFIG_BCMA=n +CONFIG_MEDIA_SUPPORT=n +CONFIG_ACPI_PROCESSOR_AGGREGATOR=n +CONFIG_ACPI_EXTLOG=n +CONFIG_NET_FOU=n +CONFIG_NET_FOU_IP_TUNNELS=n +CONFIG_GENEVE=n +CONFIG_IPV6_VTI=n +CONFIG_NETFILTER_XT_TARGET_TPROXY=n +CONFIG_NETFILTER_XT_MATCH_CGROUP=n +CONFIG_NETFILTER_XT_MATCH_SOCKET=n +CONFIG_NET_SCH_FQ=n +CONFIG_NET_CLS_BPF=n +CONFIG_BLK_DEV_NULL_BLK=n +CONFIG_GENWQE=n +CONFIG_CXL_BASE=n +CONFIG_DM_ERA=n +CONFIG_DM_RAID=n +CONFIG_DM_SWITCH=n +CONFIG_NLMON=n +CONFIG_FM10K=n +CONFIG_CRASH=n +CONFIG_IPMI_SSIF=n +CONFIG_POWERCAP=n +CONFIG_DRM_BOCHS=n +CONFIG_HID_RMI=n +CONFIG_NET_DMA_RH_KABI=n +CONFIG_HP_WIRELESS=n +CONFIG_OVERLAY_FS=n +CONFIG_NFSD_V4_SECURITY_LABEL=n +CONFIG_DEBUG_SHIRQ=n +CONFIG_PERSISTENT_KEYRINGS=n +CONFIG_BIG_KEYS=n +CONFIG_SECURITY_SECURELEVEL=n +CONFIG_CRYPTO_MCRYPTD=n +CONFIG_CRYPTO_SHA1_MB=n +CONFIG_CRYPTO_DRBG_MENU=n +CONFIG_CRYPTO_DEV_QAT=n +CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=n +CONFIG_CRYPTO_DEV_QAT_DH895xCC=n +CONFIG_CRYPTO_DEV_QAT_C3XXX=n +CONFIG_CRYPTO_DEV_QAT_C62X=n +CONFIG_CRYPTO_DEV_QAT_C3XXXVF=n +CONFIG_CRYPTO_DEV_QAT_C62XVF=n +CONFIG_BPF_JIT=n +CONFIG_PARPORT=n +CONFIG_CDROM_PKTCDVD=n +CONFIG_SENSORS_LIS3LV02D=n +CONFIG_SGI_IOC4=n +CONFIG_TIFM_CORE=n +CONFIG_ENCLOSURE_SERVICES=n +CONFIG_APDS9802ALS=n +CONFIG_ISL29003=n +CONFIG_ISL29020=n +CONFIG_SENSORS_TSL2550=n +CONFIG_SENSORS_BH1770=n +CONFIG_SENSORS_APDS990X=n +CONFIG_PCH_PHUB=n +CONFIG_EEPROM_AT24=n +CONFIG_EEPROM_MAX6875=n +CONFIG_EEPROM_93CX6=n +CONFIG_CB710_CORE=n +CONFIG_SENSORS_LIS3_I2C=n +CONFIG_ALTERA_STAPL=n +CONFIG_VMWARE_VMCI=n +CONFIG_CHR_DEV_ST=n +CONFIG_CHR_DEV_OSST=n +CONFIG_CHR_DEV_SG=n +CONFIG_CHR_DEV_SCH=n +CONFIG_SCSI_CONSTANTS=n +CONFIG_SCSI_LOGGING=n +CONFIG_SCSI_CXGB3_ISCSI=n +CONFIG_SCSI_CXGB4_ISCSI=n +CONFIG_SCSI_AIC79XX=n +CONFIG_SCSI_MVUMI=n +CONFIG_SCSI_MPT2SAS_LOGGING=n +CONFIG_SCSI_MPT3SAS_LOGGING=n +CONFIG_SCSI_UFSHCD=n +CONFIG_VMWARE_PVSCSI=n +CONFIG_FCOE=n +CONFIG_FCOE_FNIC=n +CONFIG_SCSI_INITIO=n +CONFIG_SCSI_PM8001=n +CONFIG_SCSI_SRP=n +CONFIG_SCSI_DH=n +CONFIG_SATA_ACARD_AHCI=n +CONFIG_SATA_SIL24=n +CONFIG_PDC_ADMA=n +CONFIG_SATA_QSTOR=n +CONFIG_SATA_SX4=n +CONFIG_SATA_MV=n +CONFIG_SATA_NV=n +CONFIG_SATA_PROMISE=n +CONFIG_SATA_SIL=n +CONFIG_SATA_SIS=n +CONFIG_SATA_SVW=n +CONFIG_SATA_ULI=n +CONFIG_SATA_VIA=n +CONFIG_SATA_VITESSE=n +CONFIG_PATA_ALI=n +CONFIG_PATA_AMD=n +CONFIG_PATA_ARASAN_CF=n +CONFIG_PATA_ARTOP=n +CONFIG_PATA_ATIIXP=n +CONFIG_PATA_ATP867X=n +CONFIG_PATA_CMD64X=n +CONFIG_PATA_CS5536=n +CONFIG_PATA_HPT366=n +CONFIG_PATA_HPT37X=n +CONFIG_PATA_HPT3X2N=n +CONFIG_PATA_HPT3X3=n +CONFIG_PATA_IT8213=n +CONFIG_PATA_IT821X=n +CONFIG_PATA_JMICRON=n +CONFIG_PATA_MARVELL=n +CONFIG_PATA_NETCELL=n +CONFIG_PATA_NINJA32=n +CONFIG_PATA_OLDPIIX=n +CONFIG_PATA_PDC2027X=n +CONFIG_PATA_PDC_OLD=n +CONFIG_PATA_RDC=n +CONFIG_PATA_SCH=n +CONFIG_PATA_SERVERWORKS=n +CONFIG_PATA_SIL680=n +CONFIG_PATA_SIS=n +CONFIG_PATA_TOSHIBA=n +CONFIG_PATA_VIA=n +CONFIG_DM_DEBUG=n +CONFIG_MACINTOSH_DRIVERS=n +CONFIG_NET_FC=n +CONFIG_NET_TEAM=n +CONFIG_ATL2=n +CONFIG_ATL1=n +CONFIG_ATL1E=n +CONFIG_ATL1C=n +CONFIG_ALX=n +CONFIG_ARM_AT91_ETHER=n +CONFIG_MACB=n +CONFIG_B44=n +CONFIG_BNA=n +CONFIG_NET_CALXEDA_XGMAC=n +CONFIG_CHELSIO_T3=n +CONFIG_CHELSIO_T4=n +CONFIG_CHELSIO_T4VF=n +CONFIG_NET_TULIP=n +CONFIG_IP1000=n +CONFIG_JME=n +CONFIG_MVMDIO=n +CONFIG_SKGE=n +CONFIG_SKY2=n +CONFIG_MYRI10GE=n +CONFIG_PCH_GBE=n +CONFIG_ETHOC=n +CONFIG_QLCNIC=n +CONFIG_QLGE=n +CONFIG_NETXEN_NIC=n +CONFIG_SFC=n +CONFIG_EPIC100=n +CONFIG_SMSC9420=n +CONFIG_AT803X_PHY=n +CONFIG_DAVICOM_PHY=n +CONFIG_QSEMI_PHY=n +CONFIG_LXT_PHY=n +CONFIG_CICADA_PHY=n +CONFIG_VITESSE_PHY=n +CONFIG_SMSC_PHY=n +CONFIG_BCM87XX_PHY=n +CONFIG_ICPLUS_PHY=n +CONFIG_REALTEK_PHY=n +CONFIG_NATIONAL_PHY=n +CONFIG_STE10XP=n +CONFIG_LSI_ET1011C_PHY=n +CONFIG_MICREL_PHY=n +CONFIG_MDIO_BITBANG=n +CONFIG_RT_GROUP_SCHED=n +CONFIG_OPROFILE=n +CONFIG_JUMP_LABEL=n +CONFIG_SYSTEM_BLACKLIST_KEYRING=n +CONFIG_OSF_PARTITION=n +CONFIG_AMIGA_PARTITION=n +CONFIG_MAC_PARTITION=n +CONFIG_BSD_DISKLABEL=n +CONFIG_MINIX_SUBPARTITION=n +CONFIG_SOLARIS_X86_PARTITION=n +CONFIG_UNIXWARE_DISKLABEL=n +CONFIG_SGI_PARTITION=n +CONFIG_SUN_PARTITION=n +CONFIG_KARMA_PARTITION=n +CONFIG_X86_UV=n +CONFIG_I8K=n +CONFIG_MICROCODE_AMD=n +CONFIG_MICROCODE_AMD_EARLY=n +CONFIG_MOVABLE_NODE=n +CONFIG_MEMORY_HOTPLUG=n +CONFIG_BOOTPARAM_HOTPLUG_CPU0=n +CONFIG_X86_POWERNOW_K8=n +CONFIG_X86_AMD_FREQ_SENSITIVITY=n +CONFIG_X86_P4_CLOCKMOD=n +CONFIG_PCIE_ECRC=n +CONFIG_PCIEAER_INJECT=n +CONFIG_PCCARD=n +CONFIG_HOTPLUG_PCI_ACPI_IBM=n +CONFIG_HOTPLUG_PCI_SHPC=n +CONFIG_XFRM_STATISTICS=n +CONFIG_IP_FIB_TRIE_STATS=n +CONFIG_PPP_MPPE=n +CONFIG_USB_CATC=n +CONFIG_USB_KAWETH=n +CONFIG_USB_PEGASUS=n +CONFIG_USB_RTL8150=n +CONFIG_USB_RTL8152=n +CONFIG_USB_HSO=n +CONFIG_USB_IPHETH=n +CONFIG_INPUT_FF_MEMLESS=n +CONFIG_INPUT_POLLDEV=n +CONFIG_INPUT_SPARSEKMAP=n +CONFIG_MOUSE_PS2_ELANTECH=n +CONFIG_MOUSE_PS2_SENTELIC=n +CONFIG_MOUSE_APPLETOUCH=n +CONFIG_MOUSE_BCM5974=n +CONFIG_MOUSE_CYAPA=n +CONFIG_MOUSE_VSXXXAA=n +CONFIG_MOUSE_SYNAPTICS_I2C=n +CONFIG_MOUSE_SYNAPTICS_USB=n +CONFIG_INPUT_TABLET=n +CONFIG_INPUT_PCSPKR=n +CONFIG_INPUT_APANEL=n +CONFIG_INPUT_ATLAS_BTNS=n +CONFIG_INPUT_ATI_REMOTE2=n +CONFIG_INPUT_KEYSPAN_REMOTE=n +CONFIG_INPUT_POWERMATE=n +CONFIG_INPUT_YEALINK=n +CONFIG_INPUT_CM109=n +CONFIG_INPUT_UINPUT=n +CONFIG_SERIO_ALTERA_PS2=n +CONFIG_SERIO_ARC_PS2=n +CONFIG_NOZOMI=n +CONFIG_N_GSM=n +CONFIG_SERIAL_JSM=n +CONFIG_SERIAL_ARC=n +CONFIG_HANGCHECK_TIMER=n +CONFIG_TELCLOCK=n +CONFIG_I2C_AMD756=n +CONFIG_I2C_AMD8111=n +CONFIG_I2C_PIIX4=n +CONFIG_I2C_NFORCE2=n +CONFIG_I2C_SIS96X=n +CONFIG_I2C_VIA=n +CONFIG_I2C_VIAPRO=n +CONFIG_I2C_PCA_PLATFORM=n +CONFIG_I2C_SIMTEC=n +CONFIG_I2C_DIOLAN_U2C=n +CONFIG_I2C_PARPORT_LIGHT=n +CONFIG_PPS_CLIENT_LDISC=n +CONFIG_PPS_CLIENT_GPIO=n +CONFIG_PTP_1588_CLOCK_PCH=n +CONFIG_CHARGER_SMB347=n +CONFIG_SENSORS_ABITUGURU=n +CONFIG_SENSORS_ABITUGURU3=n +CONFIG_SENSORS_AD7414=n +CONFIG_SENSORS_AD7418=n +CONFIG_SENSORS_ADM1021=n +CONFIG_SENSORS_ADM1025=n +CONFIG_SENSORS_ADM1026=n +CONFIG_SENSORS_ADM1029=n +CONFIG_SENSORS_ADM1031=n +CONFIG_SENSORS_ADM9240=n +CONFIG_SENSORS_ADT7410=n +CONFIG_SENSORS_ADT7411=n +CONFIG_SENSORS_ADT7462=n +CONFIG_SENSORS_ADT7470=n +CONFIG_SENSORS_ADT7475=n +CONFIG_SENSORS_ASC7621=n +CONFIG_SENSORS_K8TEMP=n +CONFIG_SENSORS_K10TEMP=n +CONFIG_SENSORS_FAM15H_POWER=n +CONFIG_SENSORS_ASB100=n +CONFIG_SENSORS_ATXP1=n +CONFIG_SENSORS_DS620=n +CONFIG_SENSORS_DS1621=n +CONFIG_SENSORS_I5K_AMB=n +CONFIG_SENSORS_F71805F=n +CONFIG_SENSORS_F71882FG=n +CONFIG_SENSORS_F75375S=n +CONFIG_SENSORS_FSCHMD=n +CONFIG_SENSORS_G760A=n +CONFIG_SENSORS_GL518SM=n +CONFIG_SENSORS_GL520SM=n +CONFIG_SENSORS_IBMAEM=n +CONFIG_SENSORS_IBMPEX=n +CONFIG_SENSORS_IT87=n +CONFIG_SENSORS_LINEAGE=n +CONFIG_SENSORS_LM63=n +CONFIG_SENSORS_LM73=n +CONFIG_SENSORS_LM75=n +CONFIG_SENSORS_LM77=n +CONFIG_SENSORS_LM78=n +CONFIG_SENSORS_LM80=n +CONFIG_SENSORS_LM83=n +CONFIG_SENSORS_LM85=n +CONFIG_SENSORS_LM87=n +CONFIG_SENSORS_LM90=n +CONFIG_SENSORS_LM92=n +CONFIG_SENSORS_LM93=n +CONFIG_SENSORS_LTC4151=n +CONFIG_SENSORS_LTC4215=n +CONFIG_SENSORS_LTC4245=n +CONFIG_SENSORS_LTC4261=n +CONFIG_SENSORS_LM95234=n +CONFIG_SENSORS_LM95241=n +CONFIG_SENSORS_LM95245=n +CONFIG_SENSORS_MAX16065=n +CONFIG_SENSORS_MAX1619=n +CONFIG_SENSORS_MAX1668=n +CONFIG_SENSORS_MAX197=n +CONFIG_SENSORS_MAX6639=n +CONFIG_SENSORS_MAX6642=n +CONFIG_SENSORS_MAX6650=n +CONFIG_SENSORS_MAX6697=n +CONFIG_SENSORS_MCP3021=n +CONFIG_SENSORS_NCT6775=n +CONFIG_SENSORS_NTC_THERMISTOR=n +CONFIG_SENSORS_PC87360=n +CONFIG_SENSORS_PC87427=n +CONFIG_SENSORS_PCF8591=n +CONFIG_SENSORS_PMBUS=n +CONFIG_SENSORS_ADM1275=n +CONFIG_SENSORS_LM25066=n +CONFIG_SENSORS_LTC2978=n +CONFIG_SENSORS_MAX16064=n +CONFIG_SENSORS_MAX34440=n +CONFIG_SENSORS_MAX8688=n +CONFIG_SENSORS_UCD9000=n +CONFIG_SENSORS_UCD9200=n +CONFIG_SENSORS_ZL6100=n +CONFIG_SENSORS_SHT21=n +CONFIG_SENSORS_SIS5595=n +CONFIG_SENSORS_DME1737=n +CONFIG_SENSORS_EMC1403=n +CONFIG_SENSORS_EMC6W201=n +CONFIG_SENSORS_SMSC47M1=n +CONFIG_SENSORS_SMSC47M192=n +CONFIG_SENSORS_SMSC47B397=n +CONFIG_SENSORS_SCH56XX_COMMON=n +CONFIG_SENSORS_SCH5627=n +CONFIG_SENSORS_SCH5636=n +CONFIG_SENSORS_ADS1015=n +CONFIG_SENSORS_ADS7828=n +CONFIG_SENSORS_AMC6821=n +CONFIG_SENSORS_INA209=n +CONFIG_SENSORS_INA2XX=n +CONFIG_SENSORS_THMC50=n +CONFIG_SENSORS_TMP102=n +CONFIG_SENSORS_TMP401=n +CONFIG_SENSORS_TMP421=n +CONFIG_SENSORS_VIA_CPUTEMP=n +CONFIG_SENSORS_VIA686A=n +CONFIG_SENSORS_VT1211=n +CONFIG_SENSORS_VT8231=n +CONFIG_SENSORS_W83781D=n +CONFIG_SENSORS_W83791D=n +CONFIG_SENSORS_W83792D=n +CONFIG_SENSORS_W83793=n +CONFIG_SENSORS_W83795=n +CONFIG_SENSORS_W83L785TS=n +CONFIG_SENSORS_W83L786NG=n +CONFIG_SENSORS_W83627HF=n +CONFIG_SENSORS_W83627EHF=n +CONFIG_SENSORS_APPLESMC=n +CONFIG_SENSORS_ATK0110=n +CONFIG_ALIM1535_WDT=n +CONFIG_ALIM7101_WDT=n +CONFIG_F71808E_WDT=n +CONFIG_SP5100_TCO=n +CONFIG_SBC_FITPC2_WATCHDOG=n +CONFIG_IB700_WDT=n +CONFIG_IBMASR=n +CONFIG_IT8712F_WDT=n +CONFIG_IT87_WDT=n +CONFIG_NV_TCO=n +CONFIG_SMSC_SCH311X_WDT=n +CONFIG_VIA_WDT=n +CONFIG_W83627HF_WDT=n +CONFIG_W83697HF_WDT=n +CONFIG_W83697UG_WDT=n +CONFIG_W83877F_WDT=n +CONFIG_W83977F_WDT=n +CONFIG_MACHZ_WDT=n +CONFIG_PCIPCWATCHDOG=n +CONFIG_WDTPCI=n +CONFIG_USBPCWATCHDOG=n +CONFIG_MFD_VIPERBOARD=n +CONFIG_MFD_SM501=n +CONFIG_MFD_VX855=n +CONFIG_AGP_AMD64=n +CONFIG_AGP_SIS=n +CONFIG_AGP_VIA=n +CONFIG_VGA_SWITCHEROO=n +CONFIG_DRM_LOAD_EDID_FIRMWARE=n +CONFIG_DRM_I2C_CH7006=n +CONFIG_DRM_I2C_SIL164=n +CONFIG_DRM_I2C_NXP_TDA998X=n +CONFIG_DRM_RADEON=n +CONFIG_DRM_NOUVEAU=n +CONFIG_DRM_VMWGFX=n +CONFIG_DRM_GMA500=n +CONFIG_DRM_GMA600=n +CONFIG_DRM_GMA3600=n +CONFIG_DRM_UDL=n +CONFIG_DRM_AST=n +CONFIG_DRM_MGAG200=n +CONFIG_DRM_CIRRUS_QEMU=n +CONFIG_DRM_QXL=n +CONFIG_FB_SYS_FILLRECT=n +CONFIG_FB_SYS_COPYAREA=n +CONFIG_FB_SYS_IMAGEBLIT=n +CONFIG_FB_SYS_FOPS=n +CONFIG_FB_BACKLIGHT=n +CONFIG_LCD_PLATFORM=n +CONFIG_BACKLIGHT_APPLE=n +CONFIG_BACKLIGHT_LP855X=n +CONFIG_VGACON_SOFT_SCROLLBACK=n +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=n +CONFIG_LOGO=n +CONFIG_HID_BATTERY_STRENGTH=n +CONFIG_HIDRAW=n +CONFIG_UHID=n +CONFIG_HID_ACRUX=n +CONFIG_HID_APPLEIR=n +CONFIG_HID_AUREAL=n +CONFIG_HID_DRAGONRISE=n +CONFIG_HID_ELECOM=n +CONFIG_HID_HOLTEK=n +CONFIG_HID_KEYTOUCH=n +CONFIG_HID_KYE=n +CONFIG_HID_UCLOGIC=n +CONFIG_HID_WALTOP=n +CONFIG_HID_GYRATION=n +CONFIG_HID_ICADE=n +CONFIG_HID_TWINHAN=n +CONFIG_HID_LCPOWER=n +CONFIG_HID_LENOVO_TPKBD=n +CONFIG_HID_MAGICMOUSE=n +CONFIG_HID_NTRIG=n +CONFIG_HID_ORTEK=n +CONFIG_HID_PANTHERLORD=n +CONFIG_HID_PETALYNX=n +CONFIG_HID_PICOLCD=n +CONFIG_HID_PRIMAX=n +CONFIG_HID_PS3REMOTE=n +CONFIG_HID_ROCCAT=n +CONFIG_HID_SAITEK=n +CONFIG_HID_SAMSUNG=n +CONFIG_HID_SONY=n +CONFIG_HID_SPEEDLINK=n +CONFIG_HID_STEELSERIES=n +CONFIG_HID_SUNPLUS=n +CONFIG_HID_GREENASIA=n +CONFIG_HID_SMARTJOYPLUS=n +CONFIG_HID_TIVO=n +CONFIG_HID_TOPSEED=n +CONFIG_HID_THINGM=n +CONFIG_HID_THRUSTMASTER=n +CONFIG_HID_WACOM=n +CONFIG_HID_WIIMOTE=n +CONFIG_HID_ZEROPLUS=n +CONFIG_HID_ZYDACRON=n +CONFIG_HID_PID=n +CONFIG_USB_HIDDEV=n +CONFIG_USB_ANNOUNCE_NEW_DEVICES=n +CONFIG_USB_MON=n +CONFIG_USB_WUSB_CBAF=n +CONFIG_USB_OHCI_HCD=n +CONFIG_USB_ACM=n +CONFIG_USB_PRINTER=n +CONFIG_USB_WDM=n +CONFIG_USB_TMC=n +CONFIG_USB_STORAGE_REALTEK=n +CONFIG_USB_STORAGE_DATAFAB=n +CONFIG_USB_STORAGE_FREECOM=n +CONFIG_USB_STORAGE_ISD200=n +CONFIG_USB_STORAGE_USBAT=n +CONFIG_USB_STORAGE_SDDR09=n +CONFIG_USB_STORAGE_SDDR55=n +CONFIG_USB_STORAGE_JUMPSHOT=n +CONFIG_USB_STORAGE_ALAUDA=n +CONFIG_USB_STORAGE_ONETOUCH=n +CONFIG_USB_STORAGE_KARMA=n +CONFIG_USB_STORAGE_CYPRESS_ATACB=n +CONFIG_USB_STORAGE_ENE_UB6250=n +CONFIG_USB_MDC800=n +CONFIG_USB_MICROTEK=n +CONFIG_USB_SERIAL_AIRCABLE=n +CONFIG_USB_SERIAL_ARK3116=n +CONFIG_USB_SERIAL_BELKIN=n +CONFIG_USB_SERIAL_WHITEHEAT=n +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=n +CONFIG_USB_SERIAL_CYPRESS_M8=n +CONFIG_USB_SERIAL_EMPEG=n +CONFIG_USB_SERIAL_VISOR=n +CONFIG_USB_SERIAL_IPAQ=n +CONFIG_USB_SERIAL_IR=n +CONFIG_USB_SERIAL_EDGEPORT=n +CONFIG_USB_SERIAL_EDGEPORT_TI=n +CONFIG_USB_SERIAL_GARMIN=n +CONFIG_USB_SERIAL_IPW=n +CONFIG_USB_SERIAL_IUU=n +CONFIG_USB_SERIAL_KEYSPAN_PDA=n +CONFIG_USB_SERIAL_KEYSPAN=n +CONFIG_USB_SERIAL_KLSI=n +CONFIG_USB_SERIAL_KOBIL_SCT=n +CONFIG_USB_SERIAL_MCT_U232=n +CONFIG_USB_SERIAL_MOS7720=n +CONFIG_USB_SERIAL_MOS7840=n +CONFIG_USB_SERIAL_NAVMAN=n +CONFIG_USB_SERIAL_OTI6858=n +CONFIG_USB_SERIAL_QCAUX=n +CONFIG_USB_SERIAL_QUALCOMM=n +CONFIG_USB_SERIAL_SPCP8X5=n +CONFIG_USB_SERIAL_SAFE=n +CONFIG_USB_SERIAL_SIERRAWIRELESS=n +CONFIG_USB_SERIAL_SYMBOL=n +CONFIG_USB_SERIAL_TI=n +CONFIG_USB_SERIAL_CYBERJACK=n +CONFIG_USB_SERIAL_XIRCOM=n +CONFIG_USB_SERIAL_OPTION=n +CONFIG_USB_SERIAL_OMNINET=n +CONFIG_USB_SERIAL_OPTICON=n +CONFIG_USB_SERIAL_XSENS_MT=n +CONFIG_USB_SERIAL_SSU100=n +CONFIG_USB_SERIAL_QT2=n +CONFIG_USB_SERIAL_DEBUG=n +CONFIG_USB_EMI62=n +CONFIG_USB_EMI26=n +CONFIG_USB_ADUTUX=n +CONFIG_USB_SEVSEG=n +CONFIG_USB_LEGOTOWER=n +CONFIG_USB_LCD=n +CONFIG_USB_LED=n +CONFIG_USB_IDMOUSE=n +CONFIG_USB_FTDI_ELAN=n +CONFIG_USB_APPLEDISPLAY=n +CONFIG_USB_SISUSBVGA=n +CONFIG_USB_LD=n +CONFIG_USB_IOWARRIOR=n +CONFIG_USB_ISIGHTFW=n +CONFIG_USB_EZUSB_FX2=n +CONFIG_USB_HSIC_USB3503=n +CONFIG_USB_ATM=n +CONFIG_UWB=n +CONFIG_MMC_RICOH_MMC=n +CONFIG_MMC_TIFM_SD=n +CONFIG_MMC_CB710=n +CONFIG_MMC_VIA_SDMMC=n +CONFIG_MMC_VUB300=n +CONFIG_MMC_USHC=n +CONFIG_MEMSTICK=n +CONFIG_LEDS_LM3530=n +CONFIG_LEDS_LP3944=n +CONFIG_LEDS_LP5521=n +CONFIG_LEDS_LP5523=n +CONFIG_LEDS_LP5562=n +CONFIG_LEDS_CLEVO_MAIL=n +CONFIG_LEDS_INTEL_SS4200=n +CONFIG_LEDS_BLINKM=n +CONFIG_LEDS_TRIGGER_TIMER=n +CONFIG_LEDS_TRIGGER_ONESHOT=n +CONFIG_LEDS_TRIGGER_HEARTBEAT=n +CONFIG_LEDS_TRIGGER_BACKLIGHT=n +CONFIG_LEDS_TRIGGER_TRANSIENT=n +CONFIG_LEDS_TRIGGER_CAMERA=n +CONFIG_INFINIBAND=n +CONFIG_EDAC=n +CONFIG_UIO_CIF=n +CONFIG_UIO_AEC=n +CONFIG_UIO_SERCOS3=n +CONFIG_STAGING=n +CONFIG_ACERHDF=n +CONFIG_ASUS_LAPTOP=n +CONFIG_CHROMEOS_LAPTOP=n +CONFIG_FUJITSU_LAPTOP=n +CONFIG_FUJITSU_TABLET=n +CONFIG_AMILO_RFKILL=n +CONFIG_HP_ACCEL=n +CONFIG_MSI_LAPTOP=n +CONFIG_PANASONIC_LAPTOP=n +CONFIG_COMPAL_LAPTOP=n +CONFIG_SONY_LAPTOP=n +CONFIG_IDEAPAD_LAPTOP=n +CONFIG_THINKPAD_ACPI=n +CONFIG_SENSORS_HDAPS=n +CONFIG_EEEPC_LAPTOP=n +CONFIG_ACPI_WMI=n +CONFIG_TOPSTAR_LAPTOP=n +CONFIG_TOSHIBA_BT_RFKILL=n +CONFIG_ACPI_CMPC=n +CONFIG_SAMSUNG_LAPTOP=n +CONFIG_INTEL_OAKTRAIL=n +CONFIG_SAMSUNG_Q10=n +CONFIG_APPLE_GMUX=n +CONFIG_PVPANIC=n +CONFIG_EDD=n +CONFIG_DELL_RBU=n +CONFIG_DCDBAS=n +CONFIG_JBD_DEBUG=n +CONFIG_FANOTIFY=n +CONFIG_JOLIET=n +CONFIG_UDF_FS=n +CONFIG_CRAMFS=n +CONFIG_SQUASHFS=n +CONFIG_EFIVAR_FS=n +CONFIG_SUNRPC_DEBUG=n +CONFIG_NLS_MAC_ROMAN=n +CONFIG_NLS_MAC_CELTIC=n +CONFIG_NLS_MAC_CENTEURO=n +CONFIG_NLS_MAC_CROATIAN=n +CONFIG_NLS_MAC_CYRILLIC=n +CONFIG_NLS_MAC_GAELIC=n +CONFIG_NLS_MAC_GREEK=n +CONFIG_NLS_MAC_ICELAND=n +CONFIG_NLS_MAC_INUIT=n +CONFIG_NLS_MAC_ROMANIAN=n +CONFIG_NLS_MAC_TURKISH=n +CONFIG_SCHED_TRACER=n +CONFIG_TRACER_SNAPSHOT=n +CONFIG_UPROBE_EVENT=n +CONFIG_PROBE_EVENTS=n +CONFIG_FUNCTION_PROFILER=n +CONFIG_RING_BUFFER_BENCHMARK=n +CONFIG_ATOMIC64_SELFTEST=n +CONFIG_ASYNC_RAID6_TEST=n +CONFIG_KGDB=n +CONFIG_TEST_KSTRTOX=n +CONFIG_STRICT_DEVMEM=n +CONFIG_DEBUG_SET_MODULE_RONX=n +CONFIG_DEBUG_NX_TEST=n +CONFIG_CRYPTO_BLOWFISH_X86_64=n +CONFIG_CRYPTO_CAMELLIA_X86_64=n +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=n +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=n +CONFIG_CRYPTO_CAST5_AVX_X86_64=n +CONFIG_CRYPTO_CAST6_AVX_X86_64=n +CONFIG_CRYPTO_SALSA20=n +CONFIG_CRYPTO_SALSA20_X86_64=n +CONFIG_CRYPTO_SERPENT_SSE2_X86_64=n +CONFIG_CRYPTO_SERPENT_AVX_X86_64=n +CONFIG_CRYPTO_SERPENT_AVX2_X86_64=n +CONFIG_CRYPTO_TWOFISH_X86_64=n +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=n +CONFIG_CRYPTO_TWOFISH_AVX_X86_64=n +CONFIG_CRYPTO_USER_API_HASH=n +CONFIG_CRYPTO_USER_API_SKCIPHER=n +CONFIG_CRYPTO_DEV_PADLOCK=n + +#Disable unused options from rt kernel +CONFIG_WIRELESS_EXT=n +CONFIG_DLCI=n +CONFIG_IPPP_FILTER=n +CONFIG_HISAX_EURO=n +CONFIG_DE_AOC=n +CONFIG_HISAX_NO_SENDCOMPLETE=n +CONFIG_HISAX_NO_LLC=n +CONFIG_HISAX_NO_KEYPAD=n +CONFIG_HISAX_1TR6=n +CONFIG_HISAX_NI1=n +CONFIG_HISAX_16_3=n +CONFIG_HISAX_TELESPCI=n +CONFIG_HISAX_S0BOX=n +CONFIG_HISAX_FRITZPCI=n +CONFIG_HISAX_AVM_A1_PCMCIA=n +CONFIG_HISAX_ELSA=n +CONFIG_HISAX_DIEHLDIVA=n +CONFIG_HISAX_SEDLBAUER=n +CONFIG_HISAX_NETJET=n +CONFIG_HISAX_NETJET_U=n +CONFIG_HISAX_NICCY=n +CONFIG_HISAX_BKM_A4T=n +CONFIG_HISAX_SCT_QUADRO=n +CONFIG_HISAX_GAZEL=n +CONFIG_HISAX_HFC_PCI=n +CONFIG_HISAX_W6692=n +CONFIG_HISAX_HFC_SX=n +CONFIG_HISAX_ENTERNOW_PCI=n +CONFIG_HISAX_ST5481=n +CONFIG_HISAX_HFC4S8S=n +CONFIG_HISAX_FRITZ_PCIPNP=n +CONFIG_CAPI_AVM=n +CONFIG_GIGASET_CAPI=n +CONFIG_GIGASET_BASE=n +CONFIG_GIGASET_M105=n +CONFIG_GIGASET_M101=n +CONFIG_HYSDN=n +CONFIG_HYSDN_CAPI=n +CONFIG_MISDN=n +CONFIG_MISDN_DSP=n +CONFIG_MISDN_L1OIP=n +CONFIG_MISDN_HFCPCI=n +CONFIG_MISDN_HFCMULTI=n +CONFIG_MISDN_HFCUSB=n +CONFIG_MISDN_AVMFRITZ=n +CONFIG_MISDN_SPEEDFAX=n +CONFIG_MISDN_INFINEON=n +CONFIG_MISDN_W6692=n +CONFIG_MISDN_NETJET=n +CONFIG_MISDN_IPAC=n +CONFIG_MISDN_ISAR=n +CONFIG_MEDIA_CAMERA_SUPPORT=n +CONFIG_MEDIA_ANALOG_TV_SUPPORT=n +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=n +CONFIG_MEDIA_RADIO_SUPPORT=n +CONFIG_MEDIA_RC_SUPPORT=n +CONFIG_VIDEO_DEV=n +CONFIG_VIDEO_V4L2=n +CONFIG_VIDEO_TUNER=n +CONFIG_VIDEOBUF_GEN=n +CONFIG_VIDEOBUF_DMA_SG=n +CONFIG_VIDEOBUF_VMALLOC=n +CONFIG_VIDEOBUF_DVB=n +CONFIG_VIDEOBUF2_CORE=n +CONFIG_VIDEOBUF2_MEMOPS=n +CONFIG_VIDEOBUF2_VMALLOC=n +CONFIG_DVB=n +CONFIG_DVB_CORE=n +CONFIG_DVB_NET=n +CONFIG_TTPCI_EEPROM=n +CONFIG_DVB_DYNAMIC_MINORS=n +CONFIG_RC_CORE=n +CONFIG_RC_MAP=n +CONFIG_RC_DECODERS=n +CONFIG_LIRC=n +CONFIG_IR_LIRC_CODEC=n +CONFIG_IR_NEC_DECODER=n +CONFIG_IR_RC5_DECODER=n +CONFIG_IR_RC6_DECODER=n +CONFIG_IR_JVC_DECODER=n +CONFIG_IR_SONY_DECODER=n +CONFIG_IR_RC5_SZ_DECODER=n +CONFIG_IR_SANYO_DECODER=n +CONFIG_IR_MCE_KBD_DECODER=n +CONFIG_RC_DEVICES=n +CONFIG_RC_ATI_REMOTE=n +CONFIG_IR_ENE=n +CONFIG_IR_IMON=n +CONFIG_IR_MCEUSB=n +CONFIG_IR_ITE_CIR=n +CONFIG_IR_FINTEK=n +CONFIG_IR_NUVOTON=n +CONFIG_IR_REDRAT3=n +CONFIG_IR_STREAMZAP=n +CONFIG_IR_WINBOND_CIR=n +CONFIG_IR_IGUANA=n +CONFIG_IR_TTUSBIR=n +CONFIG_VIDEO_EM28XX=n +CONFIG_VIDEO_EM28XX_ALSA=n +CONFIG_VIDEO_EM28XX_DVB=n +CONFIG_VIDEO_EM28XX_RC=n +CONFIG_MEDIA_PCI_SUPPORT=n +CONFIG_VIDEO_IVTV=n +CONFIG_VIDEO_FB_IVTV=n +CONFIG_VIDEO_CX18=n +CONFIG_VIDEO_CX18_ALSA=n +CONFIG_VIDEO_CX23885=n +CONFIG_MEDIA_ALTERA_CI=n +CONFIG_VIDEO_CX88=n +CONFIG_VIDEO_CX88_ALSA=n +CONFIG_VIDEO_CX88_BLACKBIRD=n +CONFIG_VIDEO_CX88_DVB=n +CONFIG_VIDEO_CX88_VP3054=n +CONFIG_VIDEO_CX88_MPEG=n +CONFIG_VIDEO_BT848=n +CONFIG_VIDEO_SAA7134=n +CONFIG_VIDEO_SAA7134_ALSA=n +CONFIG_VIDEO_SAA7134_RC=n +CONFIG_VIDEO_SAA7134_DVB=n +CONFIG_VIDEO_SAA7164=n +CONFIG_MANTIS_CORE=n +CONFIG_SMS_SDIO_DRV=n +CONFIG_MEDIA_COMMON_OPTIONS=n +CONFIG_VIDEO_CX2341X=n +CONFIG_VIDEO_BTCX=n +CONFIG_VIDEO_TVEEPROM=n +CONFIG_CYPRESS_FIRMWARE=n +CONFIG_VIDEO_SAA7146=n +CONFIG_VIDEO_SAA7146_VV=n +CONFIG_SMS_SIANO_MDTV=n +CONFIG_SMS_SIANO_RC=n +CONFIG_MEDIA_SUBDRV_AUTOSELECT=n +CONFIG_MEDIA_ATTACH=n +CONFIG_VIDEO_IR_I2C=n +CONFIG_VIDEO_TVAUDIO=n +CONFIG_VIDEO_TDA7432=n +CONFIG_VIDEO_MSP3400=n +CONFIG_VIDEO_CS5345=n +CONFIG_VIDEO_CS53L32A=n +CONFIG_VIDEO_WM8775=n +CONFIG_VIDEO_WM8739=n +CONFIG_VIDEO_VP27SMPX=n +CONFIG_VIDEO_SAA6588=n +CONFIG_VIDEO_SAA711X=n +CONFIG_VIDEO_TVP5150=n +CONFIG_VIDEO_SAA717X=n +CONFIG_VIDEO_CX25840=n +CONFIG_VIDEO_SAA7127=n +CONFIG_VIDEO_MT9V011=n +CONFIG_VIDEO_UPD64031A=n +CONFIG_VIDEO_UPD64083=n +CONFIG_VIDEO_M52790=n +CONFIG_MEDIA_TUNER=n +CONFIG_SND=n +CONFIG_IR_GPIO_CIR=n +CONFIG_BLK_DEV_NBD=m +CONFIG_AIC94XX_DEBUG=n + +# Disable transparent huge pages +CONFIG_TRANSPARENT_HUGEPAGE=n +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=n + +# Disable unused cgroups +CONFIG_CGROUP_HUGETLB=n +CONFIG_CGROUP_PERF=n +CONFIG_BLK_CGROUP=n + +# Make performance default govenror +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=n +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y + +CONFIG_GPIO_BT8XX=n + +CONFIG_KERNFS=y +CONFIG_INTEL_RDT_A=y diff --git a/kernel-rt/centos/patches/memblock-introduce-memblock_alloc_range.patch b/kernel-rt/centos/patches/memblock-introduce-memblock_alloc_range.patch new file mode 100644 index 000000000..de5f0c953 --- /dev/null +++ b/kernel-rt/centos/patches/memblock-introduce-memblock_alloc_range.patch @@ -0,0 +1,96 @@ +From d0f00e7d2fe5e3b77edb1e390ef33c665e644e02 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Tue, 31 May 2016 16:07:55 -0400 +Subject: [PATCH 07/26] memblock: introduce memblock_alloc_range() + +Commit 2bfc2862c4fe38379a2fb2cfba33fad32ccb4ff4 upstream +Backported-by: Nam Ninh + +This introduces memblock_alloc_range() which allocates memblock from the +specified range of physical address. I would like to use this function +to specify the location of CMA. + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + include/linux/memblock.h | 2 ++ + mm/memblock.c | 22 ++++++++++++++++++---- + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index 5a439c9..d6bcbef 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -304,6 +304,8 @@ static inline bool memblock_bottom_up(void) { return false; } + #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) + #define MEMBLOCK_ALLOC_ACCESSIBLE 0 + ++phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align, ++ phys_addr_t start, phys_addr_t end); + phys_addr_t memblock_alloc_base(phys_addr_t size, phys_addr_t align, + phys_addr_t max_addr); + phys_addr_t __memblock_alloc_base(phys_addr_t size, phys_addr_t align, +diff --git a/mm/memblock.c b/mm/memblock.c +index fbc8071..ff910a4 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -1120,9 +1120,9 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size, + } + #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ + +-static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, +- phys_addr_t align, phys_addr_t max_addr, +- int nid, ulong flags) ++static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, ++ phys_addr_t align, phys_addr_t start, ++ phys_addr_t end, int nid, ulong flags) + { + phys_addr_t found; + +@@ -1132,7 +1132,7 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, + /* align @size to avoid excessive fragmentation on reserved array */ + size = round_up(size, align); + +- found = memblock_find_in_range_node(size, align, 0, max_addr, nid, ++ found = memblock_find_in_range_node(size, align, start, end, nid, + flags); + if (found && !memblock_reserve(found, size)) + return found; +@@ -1140,6 +1140,20 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, + return 0; + } + ++phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align, ++ phys_addr_t start, phys_addr_t end) ++{ ++ ulong flags = choose_memblock_flags(); ++ return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE, flags); ++} ++ ++static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, ++ phys_addr_t align, phys_addr_t max_addr, ++ int nid, ulong flags) ++{ ++ return memblock_alloc_range_nid(size, align, 0, max_addr, nid, flags); ++} ++ + phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid) + { + ulong flags = choose_memblock_flags(); +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch b/kernel-rt/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch new file mode 100644 index 000000000..c35d3c95d --- /dev/null +++ b/kernel-rt/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch @@ -0,0 +1,51 @@ +From c6b013ca69eea1b231191d12ff6392ad5313e6c7 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Cong Wang +Date: Sun, 9 Jul 2017 13:19:55 -0700 +Subject: [PATCH 1/1] mqueue: fix a use-after-free in sys_mq_notify() + +The retry logic for netlink_attachskb() inside sys_mq_notify() +is nasty and vulnerable: + +1) The sock refcnt is already released when retry is needed +2) The fd is controllable by user-space because we already + release the file refcnt + +so we when retry but the fd has been just closed by user-space +during this small window, we end up calling netlink_detachskb() +on the error path which releases the sock again, later when +the user-space closes this socket a use-after-free could be +triggered. + +Setting 'sock' to NULL here should be sufficient to fix it. + +Reported-by: GeneBlue +Signed-off-by: Cong Wang +Cc: Andrew Morton +Cc: Manfred Spraul +Cc: stable@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + ipc/mqueue.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/ipc/mqueue.c b/ipc/mqueue.c +index ae9cf6a..8a244f4 100644 +--- a/ipc/mqueue.c ++++ b/ipc/mqueue.c +@@ -1254,8 +1254,10 @@ retry: + + timeo = MAX_SCHEDULE_TIMEOUT; + ret = netlink_attachskb(sock, nc, &timeo, NULL); +- if (ret == 1) ++ if (ret == 1) { ++ sock = NULL; + goto retry; ++ } + if (ret) { + sock = NULL; + nc = NULL; +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch b/kernel-rt/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch new file mode 100644 index 000000000..4020137a8 --- /dev/null +++ b/kernel-rt/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch @@ -0,0 +1,47 @@ +From d25e7c407b3556ea8ecccaf6dadaa728d6bcd234 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: "Paul E. McKenney" +Date: Thu, 15 Dec 2016 15:37:47 -0800 +Subject: [PATCH 16/26] rcu: Don't wake rcuc/X kthreads on NOCB CPUs + +[ upstream 630c7ed9ca0608912fa7c8591d05dfc8742dc9e6 in tip repo ] + +Chris Friesen notice that rcuc/X kthreads were consuming CPU even on +NOCB CPUs. This makes no sense because the only purpose or these +kthreads is to invoke normal (non-offloaded) callbacks, of which there +will never be any on NOCB CPUs. This problem was due to a bug in +cpu_has_callbacks_ready_to_invoke(), which should have been checking +->nxttail[RCU_NEXT_TAIL] for NULL, but which was instead (incorrectly) +checking ->nxttail[RCU_DONE_TAIL]. Because ->nxttail[RCU_DONE_TAIL] is +never NULL, the only effect is to cause the rcuc/X kthread to execute +when it should not do so. + +This commit therefore checks ->nxttail[RCU_NEXT_TAIL], which is NULL +for NOCB CPUs. + +Reported-by: Chris Friesen +Signed-off-by: Paul E. McKenney +Reviewed-by: Josh Triplett +Signed-off-by: Jim Somerville +--- + kernel/rcutree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/rcutree.c b/kernel/rcutree.c +index 6cd6521..a6c84c2 100644 +--- a/kernel/rcutree.c ++++ b/kernel/rcutree.c +@@ -319,7 +319,7 @@ static int + cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp) + { + return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] && +- rdp->nxttail[RCU_DONE_TAIL] != NULL; ++ rdp->nxttail[RCU_NEXT_TAIL] != NULL; + } + + /* +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/timer-Minimize-nohz-off-overhead.patch b/kernel-rt/centos/patches/timer-Minimize-nohz-off-overhead.patch new file mode 100644 index 000000000..cccb58fad --- /dev/null +++ b/kernel-rt/centos/patches/timer-Minimize-nohz-off-overhead.patch @@ -0,0 +1,168 @@ +From 2e4df25b1cd4cd67877e1d5ad8cb48776b678b2d Mon Sep 17 00:00:00 2001 +Message-Id: <2e4df25b1cd4cd67877e1d5ad8cb48776b678b2d.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Thomas Gleixner +Date: Tue, 26 May 2015 22:50:35 +0000 +Subject: [PATCH 26/26] timer: Minimize nohz off overhead + +If nohz is disabled on the kernel command line the [hr]timer code +still calls wake_up_nohz_cpu() and tick_nohz_full_cpu(), a pretty +pointless exercise. Cache nohz_active in [hr]timer per cpu bases and +avoid the overhead. + +Before: + 48.10% hog [.] main + 15.25% [kernel] [k] _raw_spin_lock_irqsave + 9.76% [kernel] [k] _raw_spin_unlock_irqrestore + 6.50% [kernel] [k] mod_timer + 6.44% [kernel] [k] lock_timer_base.isra.38 + 3.87% [kernel] [k] detach_if_pending + 3.80% [kernel] [k] del_timer + 2.67% [kernel] [k] internal_add_timer + 1.33% [kernel] [k] __internal_add_timer + 0.73% [kernel] [k] timerfn + 0.54% [kernel] [k] wake_up_nohz_cpu + +After: + 48.73% hog [.] main + 15.36% [kernel] [k] _raw_spin_lock_irqsave + 9.77% [kernel] [k] _raw_spin_unlock_irqrestore + 6.61% [kernel] [k] lock_timer_base.isra.38 + 6.42% [kernel] [k] mod_timer + 3.90% [kernel] [k] detach_if_pending + 3.76% [kernel] [k] del_timer + 2.41% [kernel] [k] internal_add_timer + 1.39% [kernel] [k] __internal_add_timer + 0.76% [kernel] [k] timerfn + +We probably should have a cached value for nohz full in the per cpu +bases as well to avoid the cpumask check. The base cache line is hot +already, the cpumask not necessarily. + +Signed-off-by: Thomas Gleixner +Cc: Peter Zijlstra +Cc: Paul McKenney +Cc: Frederic Weisbecker +Cc: Eric Dumazet +Cc: Viresh Kumar +Cc: John Stultz +Cc: Joonwoo Park +Cc: Wenbo Wang +Link: http://lkml.kernel.org/r/20150526224512.207378134@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + include/linux/hrtimer.h | 2 ++ + kernel/time/tick-internal.h | 4 ++-- + kernel/time/tick-sched.c | 2 +- + kernel/timer.c | 14 +++++++++++--- + 4 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h +index 37b5233..f93bcf7 100644 +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -176,6 +176,7 @@ enum hrtimer_base_type { + * Note that in RHEL7 clock_was_set is upstream's + * clock_was_set_seq (KABI). + * @migration_enabled: The migration of hrtimers to other cpus is enabled ++ * @nohz_active: The nohz functionality is enabled + * @expires_next: absolute time of the next event which was scheduled + * via clock_set_next_event() + * @hres_active: State of high resolution mode +@@ -191,6 +192,7 @@ struct hrtimer_cpu_base { + unsigned int active_bases; + unsigned int clock_was_set; /* clock_was_set_seq */ + bool migration_enabled; ++ bool nohz_active; + #ifdef CONFIG_HIGH_RES_TIMERS + ktime_t expires_next; + int hres_active; +diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h +index 3ebdda4..13468bd 100644 +--- a/kernel/time/tick-internal.h ++++ b/kernel/time/tick-internal.h +@@ -173,9 +173,9 @@ extern unsigned long tick_nohz_active; + #endif + + #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) +-extern void timers_update_migration(void); ++extern void timers_update_migration(bool update_nohz); + #else +-static inline void timers_update_migration(void) { } ++static inline void timers_update_migration(bool update_nohz) { } + #endif + + DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index 6c92920..3ccc18c 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -980,7 +980,7 @@ static inline void tick_nohz_activate(struct tick_sched *ts, int mode) + ts->nohz_mode = mode; + /* One update is enough */ + if (!test_and_set_bit(0, &tick_nohz_active)) +- timers_update_migration(); ++ timers_update_migration(true); + } + + /** +diff --git a/kernel/timer.c b/kernel/timer.c +index 1c40b95..d14e37b 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -88,6 +88,7 @@ struct tvec_base { + unsigned long active_timers; + int cpu; + bool migration_enabled; ++ bool nohz_active; + struct tvec_root tv1; + struct tvec tv2; + struct tvec tv3; +@@ -103,7 +104,7 @@ static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases; + #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) + unsigned int sysctl_timer_migration = 1; + +-void timers_update_migration(void) ++void timers_update_migration(bool update_nohz) + { + bool on = sysctl_timer_migration && tick_nohz_active; + unsigned int cpu; +@@ -119,6 +120,10 @@ void timers_update_migration(void) + tvec_base->migration_enabled = on; + hrtimer_base = &per_cpu(hrtimer_bases, cpu); + hrtimer_base->migration_enabled = on; ++ if (!update_nohz) ++ continue; ++ tvec_base->nohz_active = true; ++ hrtimer_base->nohz_active = true; + } + } + +@@ -132,7 +137,7 @@ int timer_migration_handler(struct ctl_table *table, int write, + mutex_lock(&mutex); + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (!ret && write) +- timers_update_migration(); ++ timers_update_migration(false); + mutex_unlock(&mutex); + return ret; + } +@@ -482,8 +487,11 @@ static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) + * require special care against races with idle_cpu(), lets deal + * with that later. + */ +- if (!tbase_get_deferrable(base) || tick_nohz_full_cpu(base->cpu)) ++ if (base->nohz_active) { ++ if (!tbase_get_deferrable(base) || ++ tick_nohz_full_cpu(base->cpu)) + wake_up_nohz_cpu(base->cpu); ++ } + } + + #ifdef CONFIG_TIMER_STATS +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/timer-Reduce-timer-migration-overhead-if-disabled.patch b/kernel-rt/centos/patches/timer-Reduce-timer-migration-overhead-if-disabled.patch new file mode 100644 index 000000000..211168783 --- /dev/null +++ b/kernel-rt/centos/patches/timer-Reduce-timer-migration-overhead-if-disabled.patch @@ -0,0 +1,533 @@ +From dc913075a43c45343b3f1d028ff7c3ab32a80c40 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Thomas Gleixner +Date: Tue, 26 May 2015 22:50:33 +0000 +Subject: [PATCH 25/26] timer: Reduce timer migration overhead if disabled + +Eric reported that the timer_migration sysctl is not really nice +performance wise as it needs to check at every timer insertion whether +the feature is enabled or not. Further the check does not live in the +timer code, so we have an extra function call which checks an extra +cache line to figure out that it is disabled. + +We can do better and store that information in the per cpu (hr)timer +bases. I pondered to use a static key, but that's a nightmare to +update from the nohz code and the timer base cache line is hot anyway +when we select a timer base. + +The old logic enabled the timer migration unconditionally if +CONFIG_NO_HZ was set even if nohz was disabled on the kernel command +line. + +With this modification, we start off with migration disabled. The user +visible sysctl is still set to enabled. If the kernel switches to NOHZ +migration is enabled, if the user did not disable it via the sysctl +prior to the switch. If nohz=off is on the kernel command line, +migration stays disabled no matter what. + +Before: + 47.76% hog [.] main + 14.84% [kernel] [k] _raw_spin_lock_irqsave + 9.55% [kernel] [k] _raw_spin_unlock_irqrestore + 6.71% [kernel] [k] mod_timer + 6.24% [kernel] [k] lock_timer_base.isra.38 + 3.76% [kernel] [k] detach_if_pending + 3.71% [kernel] [k] del_timer + 2.50% [kernel] [k] internal_add_timer + 1.51% [kernel] [k] get_nohz_timer_target + 1.28% [kernel] [k] __internal_add_timer + 0.78% [kernel] [k] timerfn + 0.48% [kernel] [k] wake_up_nohz_cpu + +After: + 48.10% hog [.] main + 15.25% [kernel] [k] _raw_spin_lock_irqsave + 9.76% [kernel] [k] _raw_spin_unlock_irqrestore + 6.50% [kernel] [k] mod_timer + 6.44% [kernel] [k] lock_timer_base.isra.38 + 3.87% [kernel] [k] detach_if_pending + 3.80% [kernel] [k] del_timer + 2.67% [kernel] [k] internal_add_timer + 1.33% [kernel] [k] __internal_add_timer + 0.73% [kernel] [k] timerfn + 0.54% [kernel] [k] wake_up_nohz_cpu + +Reported-by: Eric Dumazet +Signed-off-by: Thomas Gleixner +Cc: Peter Zijlstra +Cc: Paul McKenney +Cc: Frederic Weisbecker +Cc: Viresh Kumar +Cc: John Stultz +Cc: Joonwoo Park +Cc: Wenbo Wang +Link: http://lkml.kernel.org/r/20150526224512.127050787@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + include/linux/hrtimer.h | 2 ++ + include/linux/sched/sysctl.h | 12 -------- + include/linux/timer.h | 8 +++++ + kernel/hrtimer.c | 48 +++++++++++++++++------------- + kernel/rcutree_plugin.h | 2 -- + kernel/sched/core.c | 2 -- + kernel/sysctl.c | 18 ++++++------ + kernel/time/tick-internal.h | 14 +++++++++ + kernel/time/tick-sched.c | 25 +++++++++------- + kernel/time/timer_list.c | 3 +- + kernel/timer.c | 70 ++++++++++++++++++++++++++++++++++++-------- + 11 files changed, 133 insertions(+), 71 deletions(-) + +diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h +index 5435498..37b5233 100644 +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -175,6 +175,7 @@ enum hrtimer_base_type { + * @clock_was_set: Sequence counter of clock was set events + * Note that in RHEL7 clock_was_set is upstream's + * clock_was_set_seq (KABI). ++ * @migration_enabled: The migration of hrtimers to other cpus is enabled + * @expires_next: absolute time of the next event which was scheduled + * via clock_set_next_event() + * @hres_active: State of high resolution mode +@@ -189,6 +190,7 @@ struct hrtimer_cpu_base { + raw_spinlock_t lock; + unsigned int active_bases; + unsigned int clock_was_set; /* clock_was_set_seq */ ++ bool migration_enabled; + #ifdef CONFIG_HIGH_RES_TIMERS + ktime_t expires_next; + int hres_active; +diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h +index 4895484..02ab10e 100644 +--- a/include/linux/sched/sysctl.h ++++ b/include/linux/sched/sysctl.h +@@ -54,24 +54,12 @@ extern unsigned int sysctl_numa_balancing_settle_count; + extern unsigned int sysctl_sched_migration_cost; + extern unsigned int sysctl_sched_nr_migrate; + extern unsigned int sysctl_sched_time_avg; +-extern unsigned int sysctl_timer_migration; + extern unsigned int sysctl_sched_shares_window; + + int sched_proc_update_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *length, + loff_t *ppos); + #endif +-#ifdef CONFIG_SCHED_DEBUG +-static inline unsigned int get_sysctl_timer_migration(void) +-{ +- return sysctl_timer_migration; +-} +-#else +-static inline unsigned int get_sysctl_timer_migration(void) +-{ +- return 1; +-} +-#endif + + /* + * control realtime throttling: +diff --git a/include/linux/timer.h b/include/linux/timer.h +index 05ed589..694e389 100644 +--- a/include/linux/timer.h ++++ b/include/linux/timer.h +@@ -247,6 +247,14 @@ extern void run_local_timers(void); + struct hrtimer; + extern enum hrtimer_restart it_real_fn(struct hrtimer *); + ++#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) ++#include ++extern unsigned int sysctl_timer_migration; ++int timer_migration_handler(struct ctl_table *table, int write, ++ void __user *buffer, size_t *lenp, ++ loff_t *ppos); ++#endif ++ + unsigned long __round_jiffies(unsigned long j, int cpu); + unsigned long __round_jiffies_relative(unsigned long j, int cpu); + unsigned long round_jiffies(unsigned long j); +diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c +index 9ce838e..d5a76d8 100644 +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -168,19 +168,6 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, + } + } + +- +-/* +- * Get the preferred target CPU for NOHZ +- */ +-static int hrtimer_get_target(int this_cpu, int pinned) +-{ +-#ifdef CONFIG_NO_HZ_COMMON +- if (!pinned && get_sysctl_timer_migration()) +- return get_nohz_timer_target(); +-#endif +- return this_cpu; +-} +- + /* + * With HIGHRES=y we do not migrate the timer when it is expiring + * before the next event on the target cpu because we cannot reprogram +@@ -204,6 +191,24 @@ hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base) + #endif + } + ++#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) ++static inline ++struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, ++ int pinned) ++{ ++ if (pinned || !base->migration_enabled) ++ return this_cpu_ptr(&hrtimer_bases); ++ return &per_cpu(hrtimer_bases, get_nohz_timer_target()); ++} ++#else ++static inline ++struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base, ++ int pinned) ++{ ++ return this_cpu_ptr(&hrtimer_bases); ++} ++#endif ++ + /* + * Switch the timer base to the current CPU when possible. + */ +@@ -211,14 +216,13 @@ static inline struct hrtimer_clock_base * + switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, + int pinned) + { ++ struct hrtimer_cpu_base *new_cpu_base, *this_base; + struct hrtimer_clock_base *new_base; +- struct hrtimer_cpu_base *new_cpu_base; +- int this_cpu = smp_processor_id(); +- int cpu = hrtimer_get_target(this_cpu, pinned); + int basenum = base->index; + ++ this_base = this_cpu_ptr(&hrtimer_bases); ++ new_cpu_base = get_target_base(this_base, pinned); + again: +- new_cpu_base = &per_cpu(hrtimer_bases, cpu); + new_base = &new_cpu_base->clock_base[basenum]; + + if (base != new_base) { +@@ -239,17 +243,19 @@ again: + raw_spin_unlock(&base->cpu_base->lock); + raw_spin_lock(&new_base->cpu_base->lock); + +- if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) { +- cpu = this_cpu; ++ if (new_cpu_base != this_base && ++ hrtimer_check_target(timer, new_base)) { + raw_spin_unlock(&new_base->cpu_base->lock); + raw_spin_lock(&base->cpu_base->lock); ++ new_cpu_base = this_base; + timer->base = base; + goto again; + } + timer->base = new_base; + } else { +- if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) { +- cpu = this_cpu; ++ if (new_cpu_base != this_base && ++ hrtimer_check_target(timer, new_base)) { ++ new_cpu_base = this_base; + goto again; + } + } +diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h +index 6213316..0a70c49 100644 +--- a/kernel/rcutree_plugin.h ++++ b/kernel/rcutree_plugin.h +@@ -1503,8 +1503,6 @@ module_param(rcu_idle_gp_delay, int, 0644); + static int rcu_idle_lazy_gp_delay = RCU_IDLE_LAZY_GP_DELAY; + module_param(rcu_idle_lazy_gp_delay, int, 0644); + +-extern int tick_nohz_active; +- + /* + * Try to advance callbacks for all flavors of RCU on the current CPU. + * Afterwards, if there are any callbacks ready for immediate invocation, +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 54ab4d8..3fff45b 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -8560,8 +8560,6 @@ void __init sched_init_smp(void) + } + #endif /* CONFIG_SMP */ + +-const_debug unsigned int sysctl_timer_migration = 1; +- + int in_sched_functions(unsigned long addr) + { + return in_lock_functions(addr) || +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 61f4051..86aba20 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -347,15 +347,6 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec, + }, +- { +- .procname = "timer_migration", +- .data = &sysctl_timer_migration, +- .maxlen = sizeof(unsigned int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = &zero, +- .extra2 = &one, +- }, + #ifdef CONFIG_SCHEDSTATS + { + .procname = "sched_schedstats", +@@ -1169,6 +1160,15 @@ static struct ctl_table kern_table[] = { + .extra1 = &zero, + .extra2 = &one, + }, ++#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) ++ { ++ .procname = "timer_migration", ++ .data = &sysctl_timer_migration, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = timer_migration_handler, ++ }, ++#endif + { } + }; + +diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h +index ecd2ff4..3ebdda4 100644 +--- a/kernel/time/tick-internal.h ++++ b/kernel/time/tick-internal.h +@@ -165,3 +165,17 @@ extern void do_timer(unsigned long ticks); + extern void update_wall_time(void); + + extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem); ++ ++#ifdef CONFIG_NO_HZ_COMMON ++extern unsigned long tick_nohz_active; ++#else ++#define tick_nohz_active (0) ++#endif ++ ++#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) ++extern void timers_update_migration(void); ++#else ++static inline void timers_update_migration(void) { } ++#endif ++ ++DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index 625c116..6c92920 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -412,7 +412,7 @@ void __init tick_nohz_init(void) + /* + * NO HZ enabled ? + */ +-int tick_nohz_active __read_mostly; ++unsigned long tick_nohz_active __read_mostly; + /* + * Enable / Disable tickless mode + */ +@@ -973,6 +973,16 @@ static void tick_nohz_handler(struct clock_event_device *dev) + tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1); + } + ++static inline void tick_nohz_activate(struct tick_sched *ts, int mode) ++{ ++ if (!tick_nohz_enabled) ++ return; ++ ts->nohz_mode = mode; ++ /* One update is enough */ ++ if (!test_and_set_bit(0, &tick_nohz_active)) ++ timers_update_migration(); ++} ++ + /** + * tick_nohz_switch_to_nohz - switch to nohz mode + */ +@@ -987,9 +997,6 @@ static void tick_nohz_switch_to_nohz(void) + if (tick_switch_to_oneshot(tick_nohz_handler)) + return; + +- tick_nohz_active = 1; +- ts->nohz_mode = NOHZ_MODE_LOWRES; +- + /* + * Recycle the hrtimer in ts, so we can share the + * hrtimer_forward with the highres code. +@@ -1001,6 +1008,7 @@ static void tick_nohz_switch_to_nohz(void) + hrtimer_forward_now(&ts->sched_timer, tick_period); + hrtimer_set_expires(&ts->sched_timer, next); + tick_program_event(next, 1); ++ tick_nohz_activate(ts, NOHZ_MODE_LOWRES); + } + + /* +@@ -1052,6 +1060,7 @@ static inline void tick_check_nohz_this_cpu(void) + + static inline void tick_nohz_switch_to_nohz(void) { } + static inline void tick_check_nohz_this_cpu(void) { } ++static inline void tick_nohz_activate(struct tick_sched *ts, int mode) { } + + #endif /* CONFIG_NO_HZ_COMMON */ + +@@ -1137,13 +1146,7 @@ void tick_setup_sched_timer(void) + + hrtimer_forward(&ts->sched_timer, now, tick_period); + hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED); +- +-#ifdef CONFIG_NO_HZ_COMMON +- if (tick_nohz_enabled) { +- ts->nohz_mode = NOHZ_MODE_HIGHRES; +- tick_nohz_active = 1; +- } +-#endif ++ tick_nohz_activate(ts, NOHZ_MODE_HIGHRES); + } + #endif /* HIGH_RES_TIMERS */ + +diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c +index 9174c0a..d7dd92a 100644 +--- a/kernel/time/timer_list.c ++++ b/kernel/time/timer_list.c +@@ -20,6 +20,7 @@ + + #include + ++#include "tick-internal.h" + + struct timer_list_iter { + int cpu; +@@ -29,8 +30,6 @@ struct timer_list_iter { + + typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes); + +-DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); +- + /* + * This allows printing both to /proc/timer_list and + * to the console (on SysRq-Q): +diff --git a/kernel/timer.c b/kernel/timer.c +index 63f2f43..1c40b95 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -49,6 +49,8 @@ + #include + #include + ++#include "time/tick-internal.h" ++ + #define CREATE_TRACE_POINTS + #include + +@@ -85,6 +87,7 @@ struct tvec_base { + unsigned long next_timer; + unsigned long active_timers; + int cpu; ++ bool migration_enabled; + struct tvec_root tv1; + struct tvec tv2; + struct tvec tv3; +@@ -97,6 +100,58 @@ struct tvec_base boot_tvec_bases; + EXPORT_SYMBOL(boot_tvec_bases); + static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases; + ++#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) ++unsigned int sysctl_timer_migration = 1; ++ ++void timers_update_migration(void) ++{ ++ bool on = sysctl_timer_migration && tick_nohz_active; ++ unsigned int cpu; ++ struct tvec_base *tvec_base = this_cpu_read(tvec_bases); ++ struct hrtimer_cpu_base *hrtimer_base = this_cpu_ptr(&hrtimer_bases); ++ ++ /* Avoid the loop, if nothing to update */ ++ if (tvec_base->migration_enabled == on) ++ return; ++ ++ for_each_possible_cpu(cpu) { ++ tvec_base = per_cpu(tvec_bases, cpu); ++ tvec_base->migration_enabled = on; ++ hrtimer_base = &per_cpu(hrtimer_bases, cpu); ++ hrtimer_base->migration_enabled = on; ++ } ++} ++ ++int timer_migration_handler(struct ctl_table *table, int write, ++ void __user *buffer, size_t *lenp, ++ loff_t *ppos) ++{ ++ static DEFINE_MUTEX(mutex); ++ int ret; ++ ++ mutex_lock(&mutex); ++ ret = proc_dointvec(table, write, buffer, lenp, ppos); ++ if (!ret && write) ++ timers_update_migration(); ++ mutex_unlock(&mutex); ++ return ret; ++} ++ ++static inline struct tvec_base *get_target_base(struct tvec_base *base, ++ int pinned) ++{ ++ if (pinned || !base->migration_enabled) ++ return this_cpu_read(tvec_bases); ++ return per_cpu(tvec_bases, get_nohz_timer_target()); ++} ++#else ++static inline struct tvec_base *get_target_base(struct tvec_base *base, ++ int pinned) ++{ ++ return this_cpu_read(tvec_bases); ++} ++#endif ++ + /* Functions below help us manage 'deferrable' flag */ + static inline unsigned int tbase_get_deferrable(struct tvec_base *base) + { +@@ -793,11 +848,11 @@ static inline struct tvec_base *switch_timer_base(struct timer_list *timer, + + static inline int + __mod_timer(struct timer_list *timer, unsigned long expires, +- bool pending_only, int pinned) ++ bool pending_only, int pinned) + { + struct tvec_base *base, *new_base; + unsigned long flags; +- int ret = 0 , cpu; ++ int ret = 0; + + timer_stats_timer_set_start_info(timer); + BUG_ON(!timer->function); +@@ -810,16 +865,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, + + debug_activate(timer, expires); + +- preempt_disable_rt(); +- cpu = smp_processor_id(); +- +-#if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP) +- if (!pinned && get_sysctl_timer_migration()) +- cpu = get_nohz_timer_target(); +-#endif +- preempt_enable_rt(); +- +- new_base = per_cpu(tvec_bases, cpu); ++ new_base = get_target_base(base, pinned); + + if (base != new_base) { + /* +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/turn-off-write-same-in-smartqpi-driver.patch b/kernel-rt/centos/patches/turn-off-write-same-in-smartqpi-driver.patch new file mode 100644 index 000000000..095f4358f --- /dev/null +++ b/kernel-rt/centos/patches/turn-off-write-same-in-smartqpi-driver.patch @@ -0,0 +1,26 @@ +From 88dc5da8815c32f80f1791c00fa4a435897b45f1 Mon Sep 17 00:00:00 2001 +Message-Id: <88dc5da8815c32f80f1791c00fa4a435897b45f1.1520358900.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 6 Mar 2018 12:54:40 -0500 +Subject: [PATCH 1/1] turn off write same in smartqpi driver + +Signed-off-by: Jim Somerville +--- + drivers/scsi/smartpqi/smartpqi_init.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 638af91..a891516 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -5155,6 +5155,7 @@ static struct scsi_host_template pqi_driver_template = { + .slave_configure = pqi_slave_configure, + .sdev_attrs = pqi_sdev_attrs, + .shost_attrs = pqi_shost_attrs, ++ .no_write_same = 1, + }; + + static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch b/kernel-rt/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch new file mode 100644 index 000000000..a51a9f821 --- /dev/null +++ b/kernel-rt/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch @@ -0,0 +1,182 @@ +From 2948323707c9abfca9431da3b7dd81c0c505a27e Mon Sep 17 00:00:00 2001 +Message-Id: <2948323707c9abfca9431da3b7dd81c0c505a27e.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Wed, 4 Jun 2014 16:06:50 -0700 +Subject: [PATCH 10/26] x86: enable DMA CMA with swiotlb + +commit 9c5a3621427da68afe6a078cadf807d2c8cc1d12 upstream. +Ported-by: Nam Ninh + +The DMA Contiguous Memory Allocator support on x86 is disabled when +swiotlb config option is enabled. So DMA CMA is always disabled on +x86_64 because swiotlb is always enabled. This attempts to support for +DMA CMA with enabling swiotlb config option. + +The contiguous memory allocator on x86 is integrated in the function +dma_generic_alloc_coherent() which is .alloc callback in nommu_dma_ops +for dma_alloc_coherent(). + +x86_swiotlb_alloc_coherent() which is .alloc callback in swiotlb_dma_ops +tries to allocate with dma_generic_alloc_coherent() firstly and then +swiotlb_alloc_coherent() is called as a fallback. + +The main part of supporting DMA CMA with swiotlb is that changing +x86_swiotlb_free_coherent() which is .free callback in swiotlb_dma_ops +for dma_free_coherent() so that it can distinguish memory allocated by +dma_generic_alloc_coherent() from one allocated by +swiotlb_alloc_coherent() and release it with dma_generic_free_coherent() +which can handle contiguous memory. This change requires making +is_swiotlb_buffer() global function. + +This also needs to change .free callback in the dma_map_ops for amd_gart +and sta2x11, because these dma_ops are also using +dma_generic_alloc_coherent(). + +Signed-off-by: Akinobu Mita +Acked-by: Marek Szyprowski +Acked-by: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + arch/x86/Kconfig | 2 +- + arch/x86/include/asm/swiotlb.h | 7 +++++++ + arch/x86/kernel/amd_gart_64.c | 2 +- + arch/x86/kernel/pci-swiotlb.c | 9 ++++++--- + arch/x86/pci/sta2x11-fixup.c | 6 ++---- + include/linux/swiotlb.h | 2 ++ + lib/swiotlb.c | 2 +- + 7 files changed, 20 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index d9ab220..31d8683 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -43,7 +43,7 @@ config X86 + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARCH_WANT_FRAME_POINTERS + select HAVE_DMA_ATTRS +- select HAVE_DMA_CONTIGUOUS if !SWIOTLB ++ select HAVE_DMA_CONTIGUOUS + select HAVE_KRETPROBES + select HAVE_OPTPROBES + select HAVE_KPROBES_ON_FTRACE +diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h +index 977f176..ab05d73 100644 +--- a/arch/x86/include/asm/swiotlb.h ++++ b/arch/x86/include/asm/swiotlb.h +@@ -29,4 +29,11 @@ static inline void pci_swiotlb_late_init(void) + + static inline void dma_mark_clean(void *addr, size_t size) {} + ++extern void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, ++ dma_addr_t *dma_handle, gfp_t flags, ++ struct dma_attrs *attrs); ++extern void x86_swiotlb_free_coherent(struct device *dev, size_t size, ++ void *vaddr, dma_addr_t dma_addr, ++ struct dma_attrs *attrs); ++ + #endif /* _ASM_X86_SWIOTLB_H */ +diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c +index b574b29..8e3842f 100644 +--- a/arch/x86/kernel/amd_gart_64.c ++++ b/arch/x86/kernel/amd_gart_64.c +@@ -512,7 +512,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_addr, struct dma_attrs *attrs) + { + gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); +- free_pages((unsigned long)vaddr, get_order(size)); ++ dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs); + } + + static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr) +diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c +index 48f9755..23a71b6 100644 +--- a/arch/x86/kernel/pci-swiotlb.c ++++ b/arch/x86/kernel/pci-swiotlb.c +@@ -14,7 +14,7 @@ + #include + int swiotlb __read_mostly; + +-static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, ++void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) + { +@@ -28,11 +28,14 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, + return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); + } + +-static void x86_swiotlb_free_coherent(struct device *dev, size_t size, ++void x86_swiotlb_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_addr, + struct dma_attrs *attrs) + { +- swiotlb_free_coherent(dev, size, vaddr, dma_addr); ++ if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr))) ++ swiotlb_free_coherent(dev, size, vaddr, dma_addr); ++ else ++ dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs); + } + + static struct dma_map_ops swiotlb_dma_ops = { +diff --git a/arch/x86/pci/sta2x11-fixup.c b/arch/x86/pci/sta2x11-fixup.c +index 9d8a509..5ceda85 100644 +--- a/arch/x86/pci/sta2x11-fixup.c ++++ b/arch/x86/pci/sta2x11-fixup.c +@@ -173,9 +173,7 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev, + { + void *vaddr; + +- vaddr = dma_generic_alloc_coherent(dev, size, dma_handle, flags, attrs); +- if (!vaddr) +- vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, flags); ++ vaddr = x86_swiotlb_alloc_coherent(dev, size, dma_handle, flags, attrs); + *dma_handle = p2a(*dma_handle, to_pci_dev(dev)); + return vaddr; + } +@@ -183,7 +181,7 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev, + /* We have our own dma_ops: the same as swiotlb but from alloc (above) */ + static struct dma_map_ops sta2x11_dma_ops = { + .alloc = sta2x11_swiotlb_alloc_coherent, +- .free = swiotlb_free_coherent, ++ .free = x86_swiotlb_free_coherent, + .map_page = swiotlb_map_page, + .unmap_page = swiotlb_unmap_page, + .map_sg = swiotlb_map_sg_attrs, +diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h +index a5ffd32..e7a018e 100644 +--- a/include/linux/swiotlb.h ++++ b/include/linux/swiotlb.h +@@ -116,4 +116,6 @@ static inline void swiotlb_free(void) { } + #endif + + extern void swiotlb_print_info(void); ++extern int is_swiotlb_buffer(phys_addr_t paddr); ++ + #endif /* __LINUX_SWIOTLB_H */ +diff --git a/lib/swiotlb.c b/lib/swiotlb.c +index d23762e..eba74ec 100644 +--- a/lib/swiotlb.c ++++ b/lib/swiotlb.c +@@ -366,7 +366,7 @@ void __init swiotlb_free(void) + io_tlb_nslabs = 0; + } + +-static int is_swiotlb_buffer(phys_addr_t paddr) ++int is_swiotlb_buffer(phys_addr_t paddr) + { + return paddr >= io_tlb_start && paddr < io_tlb_end; + } +-- +1.8.3.1 + diff --git a/kernel-rt/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch b/kernel-rt/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch new file mode 100644 index 000000000..56e6cf8e1 --- /dev/null +++ b/kernel-rt/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch @@ -0,0 +1,87 @@ +From 026d80830e4450cff921a28a554b51509b779ace Mon Sep 17 00:00:00 2001 +Message-Id: <026d80830e4450cff921a28a554b51509b779ace.1507911923.git.Jim.Somerville@windriver.com> +In-Reply-To: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +References: <0bd66eb88c950d172a7dcefc61cb2e89b89cacce.1507911922.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Wed, 4 Jun 2014 16:06:48 -0700 +Subject: [PATCH 14/26] x86: make dma_alloc_coherent() return zeroed memory if + CMA is enabled + +This patchset enhances the DMA Contiguous Memory Allocator on x86. + +Currently the DMA CMA is only supported with pci-nommu dma_map_ops and +furthermore it can't be enabled on x86_64. But I would like to allocate +big contiguous memory with dma_alloc_coherent() and tell it to the device +that requires it, regardless of which dma mapping implementation is +actually used in the system. + +So this makes it work with swiotlb and intel-iommu dma_map_ops, too. And +this also extends "cma=" kernel parameter to specify placement constraint +by the physical address range of memory allocations. For example, CMA +allocates memory below 4GB by "cma=64M@0-4G", it is required for the +devices only supporting 32-bit addressing on 64-bit systems without iommu. + +This patch (of 5): + +Calling dma_alloc_coherent() with __GFP_ZERO must return zeroed memory. + +But when the contiguous memory allocator (CMA) is enabled on x86 and the +memory region is allocated by dma_alloc_from_contiguous(), it doesn't +return zeroed memory. Because dma_generic_alloc_coherent() forgot to fill +the memory region with zero if it was allocated by +dma_alloc_from_contiguous() + +Most implementations of dma_alloc_coherent() return zeroed memory +regardless of whether __GFP_ZERO is specified. So this fixes it by +unconditionally zeroing the allocated memory region. + +Alternatively, we could fix dma_alloc_from_contiguous() to return zeroed +out memory and remove memset() from all caller of it. But we can't simply +remove the memset on arm because __dma_clear_buffer() is used there for +ensuring cache flushing and it is used in many places. Of course we can +do redundant memset in dma_alloc_from_contiguous(), but I think this patch +is less impact for fixing this problem. + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +(cherry picked from commit d92ef66c4f8fdf7a24736b1ab6c48d32de9bfc07) +Signed-off-by: Jim Somerville +--- + arch/x86/kernel/pci-dma.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c +index 872079a..9d92ea8 100644 +--- a/arch/x86/kernel/pci-dma.c ++++ b/arch/x86/kernel/pci-dma.c +@@ -97,7 +97,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, + + dma_mask = dma_alloc_coherent_mask(dev, flag); + +- flag |= __GFP_ZERO; ++ flag &= ~__GFP_ZERO; + again: + page = NULL; + if (!(flag & GFP_ATOMIC)) +@@ -118,7 +118,7 @@ again: + + return NULL; + } +- ++ memset(page_address(page), 0, size); + *dma_addr = addr; + return page_address(page); + } +-- +1.8.3.1 + diff --git a/kernel-rt/centos/srpm_path b/kernel-rt/centos/srpm_path new file mode 100644 index 000000000..47f89c554 --- /dev/null +++ b/kernel-rt/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/kernel-rt-3.10.0-693.2.2.rt56.623.el7.src.rpm diff --git a/kernel-rt/files/centos.cer b/kernel-rt/files/centos.cer new file mode 100644 index 0000000000000000000000000000000000000000..00a55801930e1c918da263aac17ec14511a06e91 GIT binary patch literal 1500 zcma)6Yfw~W7~b!kv&&_dn`c1@kR8F~GQfA1%Z|vX%d*NXAqY@vtkbgY9$a>pvnNp` z!Ub3OQHVAIL9#%Mh2b!0F;s&KkwBvng|a_g=r}y*w{8 z^T(kXvsqCDAc#9MUh?#M%CO6P$5T0;Qo8YMPNG=~aX`T+6A2xO-7iQFtC}Qn99Rm7#zLg~6N&#Wy^UP-aUM zhCH<-lhWuZy+)#tOM)^J<g~x<6~7CuelT zU3VF1Mk`T}v_VJdN&7zzxI+f1Q&Sr4idJT*^CXGnQYXXhY7`f(R6{e^uyQnj&qK|? zjmPSp5i%{h(u^#!}uVOvC$x}1aQ!PYxU*+7-%EB`f zr%mKSVw1R}v^;67p4n+hZM$5NLs=G%<`35Fi_h$AD^_LvQrJB6_aosW$~0SEm)v|P zwyxeyzQ(`yaEm<%K;X!(6QA$kh+5g{itwz=umokQ zJV&0P3|rorr5*Bf17H!uP{g5Zi6nj-F%fjON24e_%q8{57)V2zHQE|!A+!u*jE#s; z(YnZ0q=`^wa|BuD2S<%C4H3?|{Wmb`e+I^LpG&YUa5Iz%oZhe`0?Sh!iog&UWQT|V zFJBIkiG}oU8b>J7GhwOS699~cMi^+9A+W4luEn4-8COAqiO;?8bg*=R_pDmtQ;+-GPbs2%Ym26-S70U*|qZ{u$NQpf1?(a_meD()Bng=Pv!WV+u z{le|<-z{$JvJU#ZB31p=ZW}dt%NN>qM29{2B<1bS243SwGv|}k9$haz`}k7R{Y@uL zH~-izeq7x=+PBwXYP_}yb3FyFIj=j5Jv+O-zWmO`6Si{Wi^&Q7VWa2py@z(c_Vrb* zF-VTwsw#;Oj2S2v1kMlSTKeQEzcu(y{wVC;JcK?as;p_P?FIQE_d-N1lMCKt&pS2S zcK-D}Xe^rcpHSshTnTzo6!_=tSfghu`c0cIV}7Kw?{RO*VC9-ir?2?G@Un4gwRyCC=VfH%W@RvFY&7IH;ACSC zWnmL$a&|NnFyI4mIC$9o^GXtnGV=}jfm(nf>^yA#B_)aFiH6b!k{|&t9-;8eycC6? z%(B!Xh2YBKlGNN{LvaI9kR&$`Ur1(2VqRuxu7Yz;erbxKq=7g{f|*AEF5&6xsF0mn zX&@)gYiMp@X=q_+Zfa^^93{?c0^%A%xr4%uO^iy&LC46-z}&>h&tTBR$i>ve$jGp4 z`@?;Kq7JR5UTs_~1$R$a_9SOaESx<#Rw(YtzV&;J7hUu!tW=r)S;|&oWmlt^mdAyx zlLZAoW*FCSZGQMm&?QT6TFD#Zy8FF7??0Ky>)dMH%+ z&1Zo~mHqDnMimZ+i*814UcK?wSN|Nls0@}%$4e&IDcflUZ&{>!ZlCj=#4Ki_JGp*nUQtcV4^I`NXqX%g$Iz7reQq5SaO0W|r{0 z1iPHQ%o7`%>a{~A%_}{1PSV|XQwQ^-ggu3E{d|QwlP7#@-=>we(eq@e$MK>P>5aN^ zYSo|-$@M3?b#x1)GOYYY-1SRkMm?$Mu`m(;4*Z;xtmp`70gztGaFKf5GO7Wu5 z|Lbd?#M-1N{kq$hzGZupZ}IcM<1haQaes}9%r7jO!M3k +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:23 -0400 +Subject: [PATCH 04/25] Allow ignoring Ethernet device RMRR with IOMMU passt + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 13dc572..c7c4df4 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -4,7 +4,7 @@ + Summary: The Linux kernel + + # This is the WRS patch release +-%define patch_rel 3 ++%define patch_rel 4 + %define buildid .%{patch_rel}.tis + + # For a kernel released for public testing, released_kernel should be 1. +@@ -429,6 +429,7 @@ Patch40007: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + Patch40008: affine-compute-kernel-threads.patch + Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch + Patch40010: Make-kernel-start-eth-devices-at-offset.patch ++Patch40011: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -755,6 +756,7 @@ ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + ApplyOptionalPatch affine-compute-kernel-threads.patch + ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch + ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch ++ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch b/kernel-std/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch new file mode 100644 index 000000000..84958037a --- /dev/null +++ b/kernel-std/centos/meta_patches/CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch @@ -0,0 +1,35 @@ +From c75bec8f18ac99965a5134e541b4334d82a0f2a3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jim Somerville +Date: Tue, 19 Dec 2017 17:53:28 -0500 +Subject: [PATCH 1/1] CVE mqueue fix a use after free in sys_mq_notify + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 8532f98..db2e319 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -450,6 +450,8 @@ Patch40026: aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + Patch40027: dpt_i2o-fix-build-warning.patch + Patch40028: KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch + Patch40029: KVM-x86-Fix-potential-preemption-when-get-the-curren.patch ++# CVE-2017-11176: kernel: Use-after-free in sys_mq_notify() ++Patch40030: mqueue-fix-a-use-after-free-in-sys_mq_notify.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -802,6 +804,7 @@ ApplyOptionalPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + ApplyOptionalPatch dpt_i2o-fix-build-warning.patch + ApplyOptionalPatch KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch + ApplyOptionalPatch KVM-x86-Fix-potential-preemption-when-get-the-curren.patch ++ApplyOptionalPatch mqueue-fix-a-use-after-free-in-sys_mq_notify.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Centos-fix-calltrace-in-megaraid-sas-driver.patch b/kernel-std/centos/meta_patches/Centos-fix-calltrace-in-megaraid-sas-driver.patch new file mode 100644 index 000000000..ccc199186 --- /dev/null +++ b/kernel-std/centos/meta_patches/Centos-fix-calltrace-in-megaraid-sas-driver.patch @@ -0,0 +1,49 @@ +From 1cedf3c592d1c6400e8f0c6899c116e97bd2cecf Mon Sep 17 00:00:00 2001 +Message-Id: <1cedf3c592d1c6400e8f0c6899c116e97bd2cecf.1507220784.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:23 -0400 +Subject: [PATCH 05/25] Centos fix calltrace in megaraid sas driver + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index c7c4df4..004ebcb 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -4,7 +4,7 @@ + Summary: The Linux kernel + + # This is the WRS patch release +-%define patch_rel 4 ++%define patch_rel 5 + %define buildid .%{patch_rel}.tis + + # For a kernel released for public testing, released_kernel should be 1. +@@ -430,6 +430,9 @@ Patch40008: affine-compute-kernel-threads.patch + Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch + Patch40010: Make-kernel-start-eth-devices-at-offset.patch + Patch40011: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++Patch40012: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch ++Patch40013: memblock-introduce-memblock_alloc_range.patch ++Patch40014: cma-add-placement-specifier-for-cma-kernel-parameter.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -757,6 +760,9 @@ ApplyOptionalPatch affine-compute-kernel-threads.patch + ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch + ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch + ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++ApplyOptionalPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch ++ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch ++ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Check-for-oversized-nfs-arguments.patch b/kernel-std/centos/meta_patches/Check-for-oversized-nfs-arguments.patch new file mode 100644 index 000000000..5445c7c42 --- /dev/null +++ b/kernel-std/centos/meta_patches/Check-for-oversized-nfs-arguments.patch @@ -0,0 +1,36 @@ +From eb1aeb0fce42608f4c76c50daba8705c680b960b Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 22 Aug 2017 17:26:15 -0400 +Subject: [PATCH 22/25] Check for oversized nfs arguments + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 466bcdc..ed85a41 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -443,6 +443,7 @@ Patch40026: stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch + Patch40027: add-per-cpu-pm-qos-resume-latency-consideration.patch + Patch40028: expose-pm_qos_resume_latency-for-cpus.patch + Patch40029: avoid-taking-spinlock-for-accessing-qos-values.patch ++Patch40030: nfsd-check-for-oversized-NFSv2-v3-arguments.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -790,6 +791,7 @@ ApplyOptionalPatch stop-seeking-deeper-idle-if-current-state-is-deep-enough.patc + ApplyOptionalPatch add-per-cpu-pm-qos-resume-latency-consideration.patch + ApplyOptionalPatch expose-pm_qos_resume_latency-for-cpus.patch + ApplyOptionalPatch avoid-taking-spinlock-for-accessing-qos-values.patch ++ApplyOptionalPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch b/kernel-std/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch new file mode 100644 index 000000000..8f5127ee1 --- /dev/null +++ b/kernel-std/centos/meta_patches/Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch @@ -0,0 +1,74 @@ +From 7bdeda20d3df0a642c1242253cb5b8fc58a31702 Mon Sep 17 00:00:00 2001 +Message-Id: <7bdeda20d3df0a642c1242253cb5b8fc58a31702.1507326521.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Thu, 5 Oct 2017 17:27:15 -0400 +Subject: [PATCH 1/1] Cleanup TIC patch list for CentOS 7.4 port + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 40 ++++++++++++++++------------------------ + 1 file changed, 16 insertions(+), 24 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 62103ae..84a95eb 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -436,19 +436,15 @@ Patch40013: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + Patch40014: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + Patch40015: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + Patch40016: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch +-Patch40022: cacheinfo-porting-original-4.10.17-version.patch +-Patch40023: cacheinfo-fixing-compilation-issues-on-3.10.patch +-Patch40024: intel-rdt-porting-original-4.10.17-version.patch +-Patch40025: intel-rdt-fixing-compilation-issues-on-3.10.patch +-Patch40026: stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch +-Patch40027: add-per-cpu-pm-qos-resume-latency-consideration.patch +-Patch40028: expose-pm_qos_resume_latency-for-cpus.patch +-Patch40029: avoid-taking-spinlock-for-accessing-qos-values.patch +-Patch40030: nfsd-check-for-oversized-NFSv2-v3-arguments.patch +-Patch40031: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch +-Patch40032: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch +-Patch40033: US101216-IMA-support-in-Titanium-kernel.patch +-Patch40036: US103091-IMA-System-Configuration.patch ++Patch40017: Porting-Cacheinfo-from-Kernel-4.10.17.patch ++Patch40018: Fix-cacheinfo-compilation-issues-for-3.10.patch ++Patch40019: cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch ++Patch40020: cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch ++Patch40021: CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch ++Patch40022: cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch ++Patch40023: US101216-IMA-support-in-Titanium-kernel.patch ++Patch40024: US103091-IMA-System-Configuration.patch ++Patch40025: Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -788,19 +784,15 @@ ApplyOptionalPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + ApplyOptionalPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + ApplyOptionalPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + ApplyOptionalPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch +-ApplyOptionalPatch cacheinfo-porting-original-4.10.17-version.patch +-ApplyOptionalPatch cacheinfo-fixing-compilation-issues-on-3.10.patch +-ApplyOptionalPatch intel-rdt-porting-original-4.10.17-version.patch +-ApplyOptionalPatch intel-rdt-fixing-compilation-issues-on-3.10.patch +-ApplyOptionalPatch stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch +-ApplyOptionalPatch add-per-cpu-pm-qos-resume-latency-consideration.patch +-ApplyOptionalPatch expose-pm_qos_resume_latency-for-cpus.patch +-ApplyOptionalPatch avoid-taking-spinlock-for-accessing-qos-values.patch +-ApplyOptionalPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch +-ApplyOptionalPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch +-ApplyOptionalPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch ++ApplyOptionalPatch Porting-Cacheinfo-from-Kernel-4.10.17.patch ++ApplyOptionalPatch Fix-cacheinfo-compilation-issues-for-3.10.patch ++ApplyOptionalPatch cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch ++ApplyOptionalPatch cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch ++ApplyOptionalPatch CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch ++ApplyOptionalPatch cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch + ApplyOptionalPatch US101216-IMA-support-in-Titanium-kernel.patch + ApplyOptionalPatch US103091-IMA-System-Configuration.patch ++ApplyOptionalPatch Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Enable-DMA-CMA-with-swiotlb.patch b/kernel-std/centos/meta_patches/Enable-DMA-CMA-with-swiotlb.patch new file mode 100644 index 000000000..171a9a7e8 --- /dev/null +++ b/kernel-std/centos/meta_patches/Enable-DMA-CMA-with-swiotlb.patch @@ -0,0 +1,45 @@ +From 05211712f0b2ca66fde4997d2d2d325b17b4f21c Mon Sep 17 00:00:00 2001 +Message-Id: <05211712f0b2ca66fde4997d2d2d325b17b4f21c.1507220785.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:23 -0400 +Subject: [PATCH 06/25] Enable DMA CMA with swiotlb + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 004ebcb..54fc219 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -4,7 +4,7 @@ + Summary: The Linux kernel + + # This is the WRS patch release +-%define patch_rel 5 ++%define patch_rel 6 + %define buildid .%{patch_rel}.tis + + # For a kernel released for public testing, released_kernel should be 1. +@@ -433,6 +433,7 @@ Patch40011: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + Patch40012: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch + Patch40013: memblock-introduce-memblock_alloc_range.patch + Patch40014: cma-add-placement-specifier-for-cma-kernel-parameter.patch ++Patch40015: x86-enable-DMA-CMA-with-swiotlb.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -763,6 +764,7 @@ ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + ApplyOptionalPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch + ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch + ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch ++ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch b/kernel-std/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch new file mode 100644 index 000000000..fc01c1c80 --- /dev/null +++ b/kernel-std/centos/meta_patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch @@ -0,0 +1,36 @@ +From 86ee436ccb3760bb0802d4372e992192c2dedb29 Mon Sep 17 00:00:00 2001 +Message-Id: <86ee436ccb3760bb0802d4372e992192c2dedb29.1507220786.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:26 -0400 +Subject: [PATCH 15/25] Enable building kernel with CONFIG_BLK_DEV_NBD + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 73a7f99..c0559d5 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -431,6 +431,7 @@ Patch40009: memblock-introduce-memblock_alloc_range.patch + Patch40010: cma-add-placement-specifier-for-cma-kernel-parameter.patch + Patch40011: x86-enable-DMA-CMA-with-swiotlb.patch + Patch40012: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch ++Patch40013: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -766,6 +767,7 @@ ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch + ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch + ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch + ApplyOptionalPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch ++ApplyOptionalPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Enable-the-rebased-source-patches.patch b/kernel-std/centos/meta_patches/Enable-the-rebased-source-patches.patch new file mode 100644 index 000000000..dd016b7e9 --- /dev/null +++ b/kernel-std/centos/meta_patches/Enable-the-rebased-source-patches.patch @@ -0,0 +1,84 @@ +From 0db14f243797d5c24524c453fedce25d9662fa41 Mon Sep 17 00:00:00 2001 +Message-Id: <0db14f243797d5c24524c453fedce25d9662fa41.1507220786.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:25 -0400 +Subject: [PATCH 12/25] Enable the rebased source patches + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 50 ++++++++++++++++++++------------------------------ + 1 file changed, 20 insertions(+), 30 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index bc52f1d..de04976 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -420,21 +420,16 @@ Source30000: kernel-3.10.0-x86_64.config.tis_extra + + # Titanium Cloud patches here. + Patch40001: Fix-compile-issue-when-transparent-hugepages-are-off.patch +-#Patch40001: Notification-of-death-of-arbitrary-processes.patch +-#Patch40002: CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch +-#Patch40003: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch +-#Patch40004: ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch +-#Patch40005: ixgbe-disable-LRO-by-default.patch +-#Patch40006: ixgbe-RXC-nextp-bounds-check.patch +-#Patch40007: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch +-#Patch40008: affine-compute-kernel-threads.patch +-#Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch +-#Patch40010: Make-kernel-start-eth-devices-at-offset.patch +-#Patch40011: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch +-#Patch40012: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch +-#Patch40013: memblock-introduce-memblock_alloc_range.patch +-#Patch40014: cma-add-placement-specifier-for-cma-kernel-parameter.patch +-#Patch40015: x86-enable-DMA-CMA-with-swiotlb.patch ++Patch40002: Notification-of-death-of-arbitrary-processes.patch ++Patch40003: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++Patch40004: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++Patch40005: affine-compute-kernel-threads.patch ++Patch40006: Affine-irqs-and-workqueues-with-kthread_cpus.patch ++Patch40007: Make-kernel-start-eth-devices-at-offset.patch ++Patch40008: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++Patch40009: memblock-introduce-memblock_alloc_range.patch ++Patch40010: cma-add-placement-specifier-for-cma-kernel-parameter.patch ++Patch40011: x86-enable-DMA-CMA-with-swiotlb.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -752,21 +747,16 @@ ApplyOptionalPatch debrand-rh-i686-cpu.patch + + # Titanium Cloud patches here. + ApplyOptionalPatch Fix-compile-issue-when-transparent-hugepages-are-off.patch +-#ApplyOptionalPatch Notification-of-death-of-arbitrary-processes.patch +-#ApplyOptionalPatch CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch +-#ApplyOptionalPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch +-#ApplyOptionalPatch ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch +-#ApplyOptionalPatch ixgbe-disable-LRO-by-default.patch +-#ApplyOptionalPatch ixgbe-RXC-nextp-bounds-check.patch +-#ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch +-#ApplyOptionalPatch affine-compute-kernel-threads.patch +-#ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch +-#ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch +-#ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch +-#ApplyOptionalPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch +-#ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch +-#ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch +-#ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch ++ApplyOptionalPatch Notification-of-death-of-arbitrary-processes.patch ++ApplyOptionalPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++ApplyOptionalPatch affine-compute-kernel-threads.patch ++ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch ++ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch ++ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch ++ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch ++ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Fix-compile-issue-with-transparent-hugepages.patch b/kernel-std/centos/meta_patches/Fix-compile-issue-with-transparent-hugepages.patch new file mode 100644 index 000000000..d367bfd26 --- /dev/null +++ b/kernel-std/centos/meta_patches/Fix-compile-issue-with-transparent-hugepages.patch @@ -0,0 +1,36 @@ +From 228d8848a4af532af1d4c92c20389851db1497f0 Mon Sep 17 00:00:00 2001 +Message-Id: <228d8848a4af532af1d4c92c20389851db1497f0.1507220785.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:25 -0400 +Subject: [PATCH 11/25] Fix compile issue with transparent hugepages + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 9fa6c7b..bc52f1d 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -419,6 +419,7 @@ Patch1002: debrand-rh-i686-cpu.patch + Source30000: kernel-3.10.0-x86_64.config.tis_extra + + # Titanium Cloud patches here. ++Patch40001: Fix-compile-issue-when-transparent-hugepages-are-off.patch + #Patch40001: Notification-of-death-of-arbitrary-processes.patch + #Patch40002: CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch + #Patch40003: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch +@@ -750,6 +751,7 @@ ApplyOptionalPatch debrand-rh_taint.patch + ApplyOptionalPatch debrand-rh-i686-cpu.patch + + # Titanium Cloud patches here. ++ApplyOptionalPatch Fix-compile-issue-when-transparent-hugepages-are-off.patch + #ApplyOptionalPatch Notification-of-death-of-arbitrary-processes.patch + #ApplyOptionalPatch CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch + #ApplyOptionalPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch b/kernel-std/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch new file mode 100644 index 000000000..91f6f67ae --- /dev/null +++ b/kernel-std/centos/meta_patches/Fix-compile-warnings-in-scsi-drivers.patch @@ -0,0 +1,39 @@ +From a56528b5e47a925d169ce3b7e8b5e4bde43c2a1b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jim Somerville +Date: Thu, 9 Nov 2017 15:53:41 -0500 +Subject: [PATCH 1/1] Fix compile warnings in scsi drivers + +They get turned into errors and thus break the build. + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 263bc01..8e1a50d 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -445,6 +445,9 @@ Patch40022: cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch + Patch40023: US101216-IMA-support-in-Titanium-kernel.patch + Patch40024: US103091-IMA-System-Configuration.patch + Patch40025: Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch ++# Fix compile warnings that break the build ++Patch40026: aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch ++Patch40027: dpt_i2o-fix-build-warning.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -793,6 +796,8 @@ ApplyOptionalPatch cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch + ApplyOptionalPatch US101216-IMA-support-in-Titanium-kernel.patch + ApplyOptionalPatch US103091-IMA-System-Configuration.patch + ApplyOptionalPatch Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch ++ApplyOptionalPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch ++ApplyOptionalPatch dpt_i2o-fix-build-warning.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Further-parallelize-kernel-build.patch b/kernel-std/centos/meta_patches/Further-parallelize-kernel-build.patch new file mode 100644 index 000000000..cb1a217e2 --- /dev/null +++ b/kernel-std/centos/meta_patches/Further-parallelize-kernel-build.patch @@ -0,0 +1,77 @@ +From 6b34cc7b511afc2fa8f01985a6d74490bcc12e77 Mon Sep 17 00:00:00 2001 +Message-Id: <6b34cc7b511afc2fa8f01985a6d74490bcc12e77.1507220787.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:27 -0400 +Subject: [PATCH 18/25] Further parallelize kernel build + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 3289bba..6f82e53 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -896,7 +896,7 @@ BuildKernel() { + + # and now to start the build process + +- make %{?cross_opts} -s mrproper ++ make -j"%(nproc)" %{?cross_opts} -s mrproper + + cp %{SOURCE11} . # x509.genkey + cp %{SOURCE12} . # extra_certificates +@@ -916,8 +916,8 @@ BuildKernel() { + fi + %endif + +- make -s %{?cross_opts} ARCH=$Arch oldnoconfig >/dev/null +- make -s %{?cross_opts} ARCH=$Arch V=1 %{?_smp_mflags} KCFLAGS="%{?kcflags}" WITH_GCOV="%{?with_gcov}" $MakeTarget %{?sparse_mflags} ++ make -s -j"%(nproc)" %{?cross_opts} ARCH=$Arch oldnoconfig >/dev/null ++ make -s -j"%(nproc)" %{?cross_opts} ARCH=$Arch V=1 %{?_smp_mflags} KCFLAGS="%{?kcflags}" WITH_GCOV="%{?with_gcov}" $MakeTarget %{?sparse_mflags} + + if [ "$Flavour" != "kdump" ]; then + make -s %{?cross_opts} ARCH=$Arch V=1 %{?_smp_mflags} KCFLAGS="%{?kcflags}" WITH_GCOV="%{?with_gcov}" modules %{?sparse_mflags} || exit 1 +@@ -959,7 +959,7 @@ BuildKernel() { + if [ "$Flavour" != "kdump" ]; then + # Override $(mod-fw) because we don't want it to install any firmware + # we'll get it from the linux-firmware package and we don't want conflicts +- make -s %{?cross_opts} ARCH=$Arch INSTALL_MOD_PATH=$RPM_BUILD_ROOT modules_install KERNELRELEASE=$KernelVer mod-fw= ++ make -s -j"%(nproc)" %{?cross_opts} ARCH=$Arch INSTALL_MOD_PATH=$RPM_BUILD_ROOT modules_install KERNELRELEASE=$KernelVer mod-fw= + %if %{with_gcov} + # install gcov-needed files to $BUILDROOT/$BUILD/...: + # gcov_info->filename is absolute path +@@ -969,7 +969,7 @@ BuildKernel() { + %endif + fi + %ifarch %{vdso_arches} +- make -s %{?cross_opts} ARCH=$Arch INSTALL_MOD_PATH=$RPM_BUILD_ROOT vdso_install KERNELRELEASE=$KernelVer ++ make -s -j"%(nproc)" %{?cross_opts} ARCH=$Arch INSTALL_MOD_PATH=$RPM_BUILD_ROOT vdso_install KERNELRELEASE=$KernelVer + if [ ! -s ldconfig-kernel.conf ]; then + echo > ldconfig-kernel.conf "\ + # Placeholder file, no vDSO hwcap entries used in this kernel." +@@ -1184,15 +1184,15 @@ make %{?cross_opts} %{?_smp_mflags} -C tools/power/cpupower CPUFREQ_BENCH=false + %endif + %ifarch x86_64 + pushd tools/power/x86/x86_energy_perf_policy/ +- make ++ make -j"%(nproc)" + popd + pushd tools/power/x86/turbostat +- make ++ make -j"%(nproc)" + popd + %endif #turbostat/x86_energy_perf_policy + %endif + pushd tools +-make tmon ++make -j"%(nproc)" tmon + popd + %endif + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Initial-kernel-build-for-TiS.patch b/kernel-std/centos/meta_patches/Initial-kernel-build-for-TiS.patch new file mode 100644 index 000000000..b9d51adec --- /dev/null +++ b/kernel-std/centos/meta_patches/Initial-kernel-build-for-TiS.patch @@ -0,0 +1,110 @@ +From 08db0b379c2009e0d5bc0c20427267fa07d75e5a Mon Sep 17 00:00:00 2001 +Message-Id: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:22 -0400 +Subject: [PATCH 01/25] Initial kernel build for TiS + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 45 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 42 insertions(+), 3 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index f3cd16f..a6884c2 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -3,7 +3,7 @@ + + Summary: The Linux kernel + +-# % define buildid .local ++%define buildid .tis + + # For a kernel released for public testing, released_kernel should be 1. + # For internal testing builds during development, it should be 0. +@@ -61,7 +61,7 @@ Summary: The Linux kernel + %define with_dbgonly %{?_with_dbgonly: 1} %{?!_with_dbgonly: 0} + + # Control whether we perform a compat. check against published ABI. +-%define with_kabichk %{?_without_kabichk: 0} %{?!_without_kabichk: 1} ++%define with_kabichk 0 + + # Control whether we perform a compat. check against DUP ABI. + %define with_kabidupchk 1 +@@ -78,7 +78,7 @@ Summary: The Linux kernel + # Set debugbuildsenabled to 1 for production (build separate debug kernels) + # and 0 for rawhide (all kernels are debug kernels). + # See also 'make debug' and 'make release'. RHEL only ever does 1. +-%define debugbuildsenabled 1 ++%define debugbuildsenabled 0 + + %define with_gcov %{?_with_gcov: 1} %{?!_with_gcov: 0} + +@@ -410,6 +410,22 @@ Patch1000: debrand-single-cpu.patch + Patch1001: debrand-rh_taint.patch + Patch1002: debrand-rh-i686-cpu.patch + ++# Titanium Cloud sources here. ++# Not sure if we need to worry about numerical collisions between ++# SourceX and PatchX, so let's not risk it ++Source30000: kernel-3.10.0-x86_64.config.tis_extra ++ ++# Titanium Cloud patches here. ++Patch40001: Notification-of-death-of-arbitrary-processes.patch ++Patch40002: CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch ++Patch40003: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++Patch40004: ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch ++Patch40005: ixgbe-disable-LRO-by-default.patch ++Patch40006: ixgbe-RXC-nextp-bounds-check.patch ++Patch40007: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++Patch40008: affine-compute-kernel-threads.patch ++Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch ++ + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + + %description +@@ -716,11 +732,25 @@ cd linux-%{KVRA} + # Drop some necessary files from the source dir into the buildroot + cp $RPM_SOURCE_DIR/kernel-%{version}-*.config . + ++# Copy any TiS-specific config changes ++cp $RPM_SOURCE_DIR/kernel-%{version}-*.config.tis_extra . ++ + ApplyOptionalPatch linux-kernel-test.patch + ApplyOptionalPatch debrand-single-cpu.patch + ApplyOptionalPatch debrand-rh_taint.patch + ApplyOptionalPatch debrand-rh-i686-cpu.patch + ++# Titanium Cloud patches here. ++ApplyOptionalPatch Notification-of-death-of-arbitrary-processes.patch ++ApplyOptionalPatch CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch ++ApplyOptionalPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++ApplyOptionalPatch ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch ++ApplyOptionalPatch ixgbe-disable-LRO-by-default.patch ++ApplyOptionalPatch ixgbe-RXC-nextp-bounds-check.patch ++ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++ApplyOptionalPatch affine-compute-kernel-threads.patch ++ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch ++ + # Any further pre-build tree manipulations happen here. + + chmod +x scripts/checkpatch.pl +@@ -760,6 +790,15 @@ for i in *.config + do + mv $i .config + Arch=`head -1 .config | cut -b 3-` ++ ++ # Handle Titanium Cloud customizations. Use -n to match oldnoconfig below. We want this before ++ # the make line below so that the one below removes any dependencies of ones that we ++ # turn off here. We also want it before "make listnewconfig" so that we can set the ++ # config option for new configs introduced in the Titanium Cloud patches. ++ if [ -f ${i}.tis_extra ]; then ++ scripts/kconfig/merge_config.sh -m -n .config ${i}.tis_extra ++ fi ++ + make %{?cross_opts} ARCH=$Arch listnewconfig | grep -E '^CONFIG_' >.newoptions || true + %if %{listnewconfig_fail} + if [ -s .newoptions ]; then +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Make-kernel-start-eth-devices-at-offset.patch b/kernel-std/centos/meta_patches/Make-kernel-start-eth-devices-at-offset.patch new file mode 100644 index 000000000..8c01830e8 --- /dev/null +++ b/kernel-std/centos/meta_patches/Make-kernel-start-eth-devices-at-offset.patch @@ -0,0 +1,45 @@ +From 4f0d9b095c0ec101e7dfb2c7af84084f955d308e Mon Sep 17 00:00:00 2001 +Message-Id: <4f0d9b095c0ec101e7dfb2c7af84084f955d308e.1507220784.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:23 -0400 +Subject: [PATCH 03/25] Make kernel start eth devices at offset + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 0fc23c5..13dc572 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -4,7 +4,7 @@ + Summary: The Linux kernel + + # This is the WRS patch release +-%define patch_rel 2 ++%define patch_rel 3 + %define buildid .%{patch_rel}.tis + + # For a kernel released for public testing, released_kernel should be 1. +@@ -428,6 +428,7 @@ Patch40006: ixgbe-RXC-nextp-bounds-check.patch + Patch40007: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + Patch40008: affine-compute-kernel-threads.patch + Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch ++Patch40010: Make-kernel-start-eth-devices-at-offset.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -753,6 +754,7 @@ ApplyOptionalPatch ixgbe-RXC-nextp-bounds-check.patch + ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch + ApplyOptionalPatch affine-compute-kernel-threads.patch + ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch ++ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/PATCH_ORDER b/kernel-std/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..964a1e7f0 --- /dev/null +++ b/kernel-std/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,31 @@ +Initial-kernel-build-for-TiS.patch +Tweak-install-script-for-patching-add-patch-release.patch +Make-kernel-start-eth-devices-at-offset.patch +Allow-ignoring-Ethernet-device-RMRR-with-IOMMU-passt.patch +Centos-fix-calltrace-in-megaraid-sas-driver.patch +Enable-DMA-CMA-with-swiotlb.patch +kernel-build_requires.patch +ixgbe-remove-kernel-builtin-drivers.patch +Update-package-versioning-for-TIS-format.patch +Temporarily-neuter-off-any-TiS-specific-patches.patch +Fix-compile-issue-with-transparent-hugepages.patch +Enable-the-rebased-source-patches.patch +Package-unsigned-kernel.patch +enable-building-mpt2sas-mpt3sas-as-builtin.patch +Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch +x86_dma_alloc_coherent-fix.patch +rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch +Further-parallelize-kernel-build.patch +Porting-Cacheinfo-from-Kernel-4.10.17.patch +Porting-Resource-Director-Technology-from-Kernel-4.1.patch +PM-introduce-per-cpu-power-management.patch +Check-for-oversized-nfs-arguments.patch +Stricter-decoding-of-NFS-ops.patch +meta-patch-for-Kernel-IMA-changes.patch +meta-patch-for-Kernel-IMA-keyring-changes.patch +Cleanup-TIC-patch-list-for-CentOS-7.4-port.patch +Fix-compile-warnings-in-scsi-drivers.patch +Resolve-hard-lockup-in-get_kvmclock_ns.patch +export-module-signing-key-in-kernel-devel.patch +CVE-mqueue-fix-a-use-after-free-in-sys_mq_notify.patch +fix-drbd-by-turning-off-write-same-in-smartpqi.patch diff --git a/kernel-std/centos/meta_patches/PM-introduce-per-cpu-power-management.patch b/kernel-std/centos/meta_patches/PM-introduce-per-cpu-power-management.patch new file mode 100644 index 000000000..a5b3bf8e6 --- /dev/null +++ b/kernel-std/centos/meta_patches/PM-introduce-per-cpu-power-management.patch @@ -0,0 +1,47 @@ +From e6db3094a1f71bec80302884257be833f37c75e3 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Thu, 17 Aug 2017 12:37:41 -0400 +Subject: [PATCH 21/25] PM: introduce per-cpu power management + +Cherry-picking 4 commits from the 4.11 branch of the linux-stable tree. +All of the patches require small amount of work to apply to TiC kernel. +Fixes are temporary until we switch to CentOS kernel that includes them. + +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 2886708..466bcdc 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -439,6 +439,10 @@ Patch40022: cacheinfo-porting-original-4.10.17-version.patch + Patch40023: cacheinfo-fixing-compilation-issues-on-3.10.patch + Patch40024: intel-rdt-porting-original-4.10.17-version.patch + Patch40025: intel-rdt-fixing-compilation-issues-on-3.10.patch ++Patch40026: stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch ++Patch40027: add-per-cpu-pm-qos-resume-latency-consideration.patch ++Patch40028: expose-pm_qos_resume_latency-for-cpus.patch ++Patch40029: avoid-taking-spinlock-for-accessing-qos-values.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -782,6 +786,10 @@ ApplyOptionalPatch cacheinfo-porting-original-4.10.17-version.patch + ApplyOptionalPatch cacheinfo-fixing-compilation-issues-on-3.10.patch + ApplyOptionalPatch intel-rdt-porting-original-4.10.17-version.patch + ApplyOptionalPatch intel-rdt-fixing-compilation-issues-on-3.10.patch ++ApplyOptionalPatch stop-seeking-deeper-idle-if-current-state-is-deep-enough.patch ++ApplyOptionalPatch add-per-cpu-pm-qos-resume-latency-consideration.patch ++ApplyOptionalPatch expose-pm_qos_resume_latency-for-cpus.patch ++ApplyOptionalPatch avoid-taking-spinlock-for-accessing-qos-values.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Package-unsigned-kernel.patch b/kernel-std/centos/meta_patches/Package-unsigned-kernel.patch new file mode 100644 index 000000000..99c838d4a --- /dev/null +++ b/kernel-std/centos/meta_patches/Package-unsigned-kernel.patch @@ -0,0 +1,55 @@ +From 381a06a934075707e637ef7a9f818dc4e731e09c Mon Sep 17 00:00:00 2001 +Message-Id: <381a06a934075707e637ef7a9f818dc4e731e09c.1507220786.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:25 -0400 +Subject: [PATCH 13/25] Package unsigned kernel + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index de04976..aa4f957 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -582,6 +582,13 @@ This package provides debug information for package kernel-tools. + + %endif # with_tools + ++%ifarch x86_64 ++%package unsigned ++Summary: Unsigned build of the Linux kernel ++%description unsigned ++Contains an unsigned version of the Linux kernel ++%endif # x86_64 ++ + %if %{with_gcov} + %package gcov + Summary: gcov graph and source files for coverage data collection. +@@ -924,6 +931,8 @@ BuildKernel() { + fi + # EFI SecureBoot signing, x86_64-only + %ifarch x86_64 ++ cp $KernelImage vmlinuz.unsigned ++ $CopyKernel vmlinuz.unsigned $RPM_BUILD_ROOT/%{image_install_path}/vmlinuz.unsigned + %pesign -s -i $KernelImage -o $KernelImage.signed -a %{SOURCE13} -c %{SOURCE13} + mv $KernelImage.signed $KernelImage + %endif +@@ -1637,6 +1646,11 @@ fi + %kernel_variant_files %{with_debug} debug + %kernel_variant_files %{with_kdump} kdump + ++%ifarch x86_64 ++%files unsigned ++/boot/vmlinuz.unsigned ++%endif ++ + %changelog + * Tue Sep 12 2017 CentOS Sources - 3.10.0-693.2.2.el7 + - Apply debranding changes +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch b/kernel-std/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch new file mode 100644 index 000000000..9fea21041 --- /dev/null +++ b/kernel-std/centos/meta_patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch @@ -0,0 +1,38 @@ +From b0e305322f0d22cbd2505c9cdc133ff9f526ed5e Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Fri, 21 Jul 2017 09:47:48 -0500 +Subject: [PATCH 19/25] Porting Cacheinfo from Kernel 4.10.17 + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 6f82e53..103fd01 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -435,6 +435,8 @@ Patch40013: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + Patch40014: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + Patch40015: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + Patch40016: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch ++Patch40022: cacheinfo-porting-original-4.10.17-version.patch ++Patch40023: cacheinfo-fixing-compilation-issues-on-3.10.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -774,6 +776,8 @@ ApplyOptionalPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + ApplyOptionalPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + ApplyOptionalPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + ApplyOptionalPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch ++ApplyOptionalPatch cacheinfo-porting-original-4.10.17-version.patch ++ApplyOptionalPatch cacheinfo-fixing-compilation-issues-on-3.10.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch b/kernel-std/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch new file mode 100644 index 000000000..3ff6f7d14 --- /dev/null +++ b/kernel-std/centos/meta_patches/Porting-Resource-Director-Technology-from-Kernel-4.1.patch @@ -0,0 +1,39 @@ +From e976aca15e3136d7e42e98ac65deed8fa5eea336 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Mon, 24 Jul 2017 11:46:36 -0500 +Subject: [PATCH 20/25] Porting Resource Director Technology from Kernel + 4.10.17 + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 103fd01..2886708 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -437,6 +437,8 @@ Patch40015: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + Patch40016: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + Patch40022: cacheinfo-porting-original-4.10.17-version.patch + Patch40023: cacheinfo-fixing-compilation-issues-on-3.10.patch ++Patch40024: intel-rdt-porting-original-4.10.17-version.patch ++Patch40025: intel-rdt-fixing-compilation-issues-on-3.10.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -778,6 +780,8 @@ ApplyOptionalPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + ApplyOptionalPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + ApplyOptionalPatch cacheinfo-porting-original-4.10.17-version.patch + ApplyOptionalPatch cacheinfo-fixing-compilation-issues-on-3.10.patch ++ApplyOptionalPatch intel-rdt-porting-original-4.10.17-version.patch ++ApplyOptionalPatch intel-rdt-fixing-compilation-issues-on-3.10.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch b/kernel-std/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch new file mode 100644 index 000000000..6f547f967 --- /dev/null +++ b/kernel-std/centos/meta_patches/Resolve-hard-lockup-in-get_kvmclock_ns.patch @@ -0,0 +1,34 @@ +From c89b0d1916fffc8e8594a7308b35a391bbee6061 Mon Sep 17 00:00:00 2001 +From: Alex Kozyrev +Date: Thu, 16 Nov 2017 11:32:45 -0500 +Subject: [PATCH 1/1] Resolve hard lockup in get_kvmclock_ns + +--- + SPECS/kernel.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 8e1a50d..ac9eb8c 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -448,6 +448,8 @@ Patch40025: Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch + # Fix compile warnings that break the build + Patch40026: aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + Patch40027: dpt_i2o-fix-build-warning.patch ++Patch40028: KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch ++Patch40029: KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -798,6 +800,8 @@ ApplyOptionalPatch US103091-IMA-System-Configuration.patch + ApplyOptionalPatch Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch + ApplyOptionalPatch aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch + ApplyOptionalPatch dpt_i2o-fix-build-warning.patch ++ApplyOptionalPatch KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch ++ApplyOptionalPatch KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch b/kernel-std/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch new file mode 100644 index 000000000..e9aada600 --- /dev/null +++ b/kernel-std/centos/meta_patches/Stricter-decoding-of-NFS-ops.patch @@ -0,0 +1,38 @@ +From 475beba36f3ec495a70c8823c44b376c249257c0 Mon Sep 17 00:00:00 2001 +Message-Id: <475beba36f3ec495a70c8823c44b376c249257c0.1507220787.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 22 Aug 2017 17:30:01 -0400 +Subject: [PATCH 23/25] Stricter decoding of NFS ops + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index ed85a41..32e5a52 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -444,6 +444,8 @@ Patch40027: add-per-cpu-pm-qos-resume-latency-consideration.patch + Patch40028: expose-pm_qos_resume_latency-for-cpus.patch + Patch40029: avoid-taking-spinlock-for-accessing-qos-values.patch + Patch40030: nfsd-check-for-oversized-NFSv2-v3-arguments.patch ++Patch40031: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch ++Patch40032: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -792,6 +794,8 @@ ApplyOptionalPatch add-per-cpu-pm-qos-resume-latency-consideration.patch + ApplyOptionalPatch expose-pm_qos_resume_latency-for-cpus.patch + ApplyOptionalPatch avoid-taking-spinlock-for-accessing-qos-values.patch + ApplyOptionalPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch ++ApplyOptionalPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch ++ApplyOptionalPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Temporarily-neuter-off-any-TiS-specific-patches.patch b/kernel-std/centos/meta_patches/Temporarily-neuter-off-any-TiS-specific-patches.patch new file mode 100644 index 000000000..8d5c3bf7e --- /dev/null +++ b/kernel-std/centos/meta_patches/Temporarily-neuter-off-any-TiS-specific-patches.patch @@ -0,0 +1,94 @@ +From 5425a28666187bdad67d5cdb673b4d33df5b6a9d Mon Sep 17 00:00:00 2001 +Message-Id: <5425a28666187bdad67d5cdb673b4d33df5b6a9d.1507220785.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:25 -0400 +Subject: [PATCH 10/25] Temporarily neuter off any TiS specific patches + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 60 +++++++++++++++++++++++++++---------------------------- + 1 file changed, 30 insertions(+), 30 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 3a2d10d..9fa6c7b 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -419,21 +419,21 @@ Patch1002: debrand-rh-i686-cpu.patch + Source30000: kernel-3.10.0-x86_64.config.tis_extra + + # Titanium Cloud patches here. +-Patch40001: Notification-of-death-of-arbitrary-processes.patch +-Patch40002: CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch +-Patch40003: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch +-Patch40004: ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch +-Patch40005: ixgbe-disable-LRO-by-default.patch +-Patch40006: ixgbe-RXC-nextp-bounds-check.patch +-Patch40007: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch +-Patch40008: affine-compute-kernel-threads.patch +-Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch +-Patch40010: Make-kernel-start-eth-devices-at-offset.patch +-Patch40011: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch +-Patch40012: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch +-Patch40013: memblock-introduce-memblock_alloc_range.patch +-Patch40014: cma-add-placement-specifier-for-cma-kernel-parameter.patch +-Patch40015: x86-enable-DMA-CMA-with-swiotlb.patch ++#Patch40001: Notification-of-death-of-arbitrary-processes.patch ++#Patch40002: CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch ++#Patch40003: CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++#Patch40004: ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch ++#Patch40005: ixgbe-disable-LRO-by-default.patch ++#Patch40006: ixgbe-RXC-nextp-bounds-check.patch ++#Patch40007: PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++#Patch40008: affine-compute-kernel-threads.patch ++#Patch40009: Affine-irqs-and-workqueues-with-kthread_cpus.patch ++#Patch40010: Make-kernel-start-eth-devices-at-offset.patch ++#Patch40011: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++#Patch40012: mm-memblock-reorder-parameters-of-memblock_find_in_r.patch ++#Patch40013: memblock-introduce-memblock_alloc_range.patch ++#Patch40014: cma-add-placement-specifier-for-cma-kernel-parameter.patch ++#Patch40015: x86-enable-DMA-CMA-with-swiotlb.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -750,21 +750,21 @@ ApplyOptionalPatch debrand-rh_taint.patch + ApplyOptionalPatch debrand-rh-i686-cpu.patch + + # Titanium Cloud patches here. +-ApplyOptionalPatch Notification-of-death-of-arbitrary-processes.patch +-ApplyOptionalPatch CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch +-ApplyOptionalPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch +-ApplyOptionalPatch ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch +-ApplyOptionalPatch ixgbe-disable-LRO-by-default.patch +-ApplyOptionalPatch ixgbe-RXC-nextp-bounds-check.patch +-ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch +-ApplyOptionalPatch affine-compute-kernel-threads.patch +-ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch +-ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch +-ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch +-ApplyOptionalPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch +-ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch +-ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch +-ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch ++#ApplyOptionalPatch Notification-of-death-of-arbitrary-processes.patch ++#ApplyOptionalPatch CGTS-3456-emit-CPU-logging-on-hard-soft-lockup.patch ++#ApplyOptionalPatch CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch ++#ApplyOptionalPatch ixgbe-fully-disable-hardware-RSC-logic-when-disablin.patch ++#ApplyOptionalPatch ixgbe-disable-LRO-by-default.patch ++#ApplyOptionalPatch ixgbe-RXC-nextp-bounds-check.patch ++#ApplyOptionalPatch PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch ++#ApplyOptionalPatch affine-compute-kernel-threads.patch ++#ApplyOptionalPatch Affine-irqs-and-workqueues-with-kthread_cpus.patch ++#ApplyOptionalPatch Make-kernel-start-eth-devices-at-offset.patch ++#ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch ++#ApplyOptionalPatch mm-memblock-reorder-parameters-of-memblock_find_in_r.patch ++#ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch ++#ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch ++#ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Tweak-install-script-for-patching-add-patch-release.patch b/kernel-std/centos/meta_patches/Tweak-install-script-for-patching-add-patch-release.patch new file mode 100644 index 000000000..db454b6ee --- /dev/null +++ b/kernel-std/centos/meta_patches/Tweak-install-script-for-patching-add-patch-release.patch @@ -0,0 +1,52 @@ +From ab67f811ca20a8ac98307472382876f6c247b00c Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:22 -0400 +Subject: [PATCH 02/25] Tweak install script for patching add patch release + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index a6884c2..0fc23c5 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -3,7 +3,9 @@ + + Summary: The Linux kernel + +-%define buildid .tis ++# This is the WRS patch release ++%define patch_rel 2 ++%define buildid .%{patch_rel}.tis + + # For a kernel released for public testing, released_kernel should be 1. + # For internal testing builds during development, it should be 0. +@@ -12,7 +14,8 @@ Summary: The Linux kernel + %global distro_build 693 + + %define rpmversion 3.10.0 +-%define pkgrelease 693.2.2.el7 ++%define _pkgrelease 693.2.2 ++%define pkgrelease %{_pkgrelease}.el7 + + %define pkg_release %{pkgrelease}%{?buildid} + +@@ -1425,6 +1428,10 @@ fi}\ + %{expand:\ + %{_sbindir}/new-kernel-pkg --package kernel%{?-v:-%{-v*}} --install %{KVRA}%{?-v:.%{-v*}} || exit $?\ + }\ ++# If this is a pkg upgrade (ie installed as a patch), set the reboot flag\ ++if [ $1 -gt 1 ] ; then\ ++ touch /var/run/node_is_patched_rr\ ++fi\ + %{nil} + + # +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/Update-package-versioning-for-TIS-format.patch b/kernel-std/centos/meta_patches/Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..a1cf21b3a --- /dev/null +++ b/kernel-std/centos/meta_patches/Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,39 @@ +From 02791ff1f3bd5267ffdf2aafb04b9a57cd4eb176 Mon Sep 17 00:00:00 2001 +Message-Id: <02791ff1f3bd5267ffdf2aafb04b9a57cd4eb176.1507220785.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:24 -0400 +Subject: [PATCH 09/25] Update package versioning for TIS format + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index bff543a..3a2d10d 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -4,8 +4,7 @@ + Summary: The Linux kernel + + # This is the WRS patch release +-%define patch_rel 7 +-%define buildid .%{patch_rel}.tis ++%define buildid .%{tis_patch_ver}.tis + + # For a kernel released for public testing, released_kernel should be 1. + # For internal testing builds during development, it should be 0. +@@ -17,7 +16,7 @@ Summary: The Linux kernel + %define _pkgrelease 693.2.2 + %define pkgrelease %{_pkgrelease}.el7 + +-%define pkg_release %{pkgrelease}%{?buildid} ++%define pkg_release %{pkgrelease}%{buildid} + + # The kernel tarball/base version + %define rheltarball %{rpmversion}-%{pkgrelease} +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch b/kernel-std/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch new file mode 100644 index 000000000..3ad1a8176 --- /dev/null +++ b/kernel-std/centos/meta_patches/enable-building-mpt2sas-mpt3sas-as-builtin.patch @@ -0,0 +1,36 @@ +From 82398d8f076c50099cf9ab99342d70930e390e39 Mon Sep 17 00:00:00 2001 +Message-Id: <82398d8f076c50099cf9ab99342d70930e390e39.1507220786.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:26 -0400 +Subject: [PATCH 14/25] enable building mpt2sas mpt3sas as builtin + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index aa4f957..73a7f99 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -430,6 +430,7 @@ Patch40008: intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + Patch40009: memblock-introduce-memblock_alloc_range.patch + Patch40010: cma-add-placement-specifier-for-cma-kernel-parameter.patch + Patch40011: x86-enable-DMA-CMA-with-swiotlb.patch ++Patch40012: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -764,6 +765,7 @@ ApplyOptionalPatch intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch + ApplyOptionalPatch memblock-introduce-memblock_alloc_range.patch + ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch + ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch ++ApplyOptionalPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch b/kernel-std/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch new file mode 100644 index 000000000..45a768151 --- /dev/null +++ b/kernel-std/centos/meta_patches/export-module-signing-key-in-kernel-devel.patch @@ -0,0 +1,29 @@ +From ebc3ffc011206683e0351078fbc5bf1fd2c57047 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Wed, 10 Jan 2018 17:34:42 -0500 +Subject: [PATCH] export module signing key in kernel devel + +--- + SPECS/kernel.spec | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index decef93..708b04c 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -1155,6 +1155,12 @@ BuildKernel() { + cp signing_key.priv signing_key.priv.sign${Flavour:+.${Flavour}} + cp signing_key.x509 signing_key.x509.sign${Flavour:+.${Flavour}} + ++ # WRS: Copy these keys as part of the devel package ++ # The Module signing keys are to ensure that only Out-of-tree ++ # built against the Titanium Kernel get signed and loaded sans warnings ++ cp signing_key.priv ${RPM_BUILD_ROOT}/lib/modules/${KernelVer}/build/ ++ cp signing_key.x509 ${RPM_BUILD_ROOT}/lib/modules/${KernelVer}/build/ ++ + # remove files that will be auto generated by depmod at rpm -i time + for i in alias alias.bin builtin.bin ccwmap dep dep.bin ieee1394map inputmap isapnpmap ofmap pcimap seriomap symbols symbols.bin usbmap softdep devname + do +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch b/kernel-std/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch new file mode 100644 index 000000000..a9a1ad215 --- /dev/null +++ b/kernel-std/centos/meta_patches/fix-drbd-by-turning-off-write-same-in-smartpqi.patch @@ -0,0 +1,35 @@ +From ea71426ebe355c44a44d3c3039a9577aa75fa411 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jim Somerville +Date: Tue, 6 Mar 2018 12:58:10 -0500 +Subject: [PATCH 1/1] fix drbd by turning off write same in smartpqi + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index db2e319..5054518 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -452,6 +452,8 @@ Patch40028: KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch + Patch40029: KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + # CVE-2017-11176: kernel: Use-after-free in sys_mq_notify() + Patch40030: mqueue-fix-a-use-after-free-in-sys_mq_notify.patch ++# DRBD was choking on write same ++Patch40031: turn-off-write-same-in-smartqpi-driver.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -805,6 +807,7 @@ ApplyOptionalPatch dpt_i2o-fix-build-warning.patch + ApplyOptionalPatch KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch + ApplyOptionalPatch KVM-x86-Fix-potential-preemption-when-get-the-curren.patch + ApplyOptionalPatch mqueue-fix-a-use-after-free-in-sys_mq_notify.patch ++ApplyOptionalPatch turn-off-write-same-in-smartqpi-driver.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/ixgbe-remove-kernel-builtin-drivers.patch b/kernel-std/centos/meta_patches/ixgbe-remove-kernel-builtin-drivers.patch new file mode 100644 index 000000000..61668656b --- /dev/null +++ b/kernel-std/centos/meta_patches/ixgbe-remove-kernel-builtin-drivers.patch @@ -0,0 +1,29 @@ +From cea119181a969a24a45783bd0ae372ed8b42a3d0 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:24 -0400 +Subject: [PATCH 08/25] ixgbe remove kernel builtin drivers + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index df2f9e4..bff543a 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -4,7 +4,7 @@ + Summary: The Linux kernel + + # This is the WRS patch release +-%define patch_rel 6 ++%define patch_rel 7 + %define buildid .%{patch_rel}.tis + + # For a kernel released for public testing, released_kernel should be 1. +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/kernel-build_requires.patch b/kernel-std/centos/meta_patches/kernel-build_requires.patch new file mode 100644 index 000000000..e34cf4b11 --- /dev/null +++ b/kernel-std/centos/meta_patches/kernel-build_requires.patch @@ -0,0 +1,28 @@ +From 7e257fd0c2bb38653e4c2a7e5a01af28c90bba76 Mon Sep 17 00:00:00 2001 +Message-Id: <7e257fd0c2bb38653e4c2a7e5a01af28c90bba76.1507220785.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:24 -0400 +Subject: [PATCH 07/25] kernel build_requires + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 54fc219..df2f9e4 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -352,6 +352,7 @@ BuildRequires: rpm-build >= 4.9.0-1, elfutils >= 0.153-1 + # required for zfcpdump + BuildRequires: glibc-static + %endif ++BuildRequires: util-linux + + Source0: linux-%{rpmversion}-%{pkgrelease}.tar.xz + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch b/kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch new file mode 100644 index 000000000..a4c779132 --- /dev/null +++ b/kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-changes.patch @@ -0,0 +1,36 @@ +From 3e12b4680cf198b652a4f0d0a7edeeb948b00091 Mon Sep 17 00:00:00 2001 +Message-Id: <3e12b4680cf198b652a4f0d0a7edeeb948b00091.1507220788.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Fri, 1 Sep 2017 13:45:40 -0400 +Subject: [PATCH 24/25] meta patch for Kernel IMA changes + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 32e5a52..bb5a106 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -446,6 +446,7 @@ Patch40029: avoid-taking-spinlock-for-accessing-qos-values.patch + Patch40030: nfsd-check-for-oversized-NFSv2-v3-arguments.patch + Patch40031: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + Patch40032: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch ++Patch40033: US101216-IMA-support-in-Titanium-kernel.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -796,6 +797,7 @@ ApplyOptionalPatch avoid-taking-spinlock-for-accessing-qos-values.patch + ApplyOptionalPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch + ApplyOptionalPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + ApplyOptionalPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch ++ApplyOptionalPatch US101216-IMA-support-in-Titanium-kernel.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch b/kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch new file mode 100644 index 000000000..e3f43edb5 --- /dev/null +++ b/kernel-std/centos/meta_patches/meta-patch-for-Kernel-IMA-keyring-changes.patch @@ -0,0 +1,52 @@ +From 49857784e8efe0aeedc17206240064273ce458a6 Mon Sep 17 00:00:00 2001 +Message-Id: <49857784e8efe0aeedc17206240064273ce458a6.1507220788.git.Jim.Somerville@windriver.com> +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Mon, 25 Sep 2017 17:20:15 -0400 +Subject: [PATCH 25/25] meta patch for Kernel IMA keyring changes + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index bb5a106..62103ae 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -417,6 +417,7 @@ Patch1002: debrand-rh-i686-cpu.patch + # Not sure if we need to worry about numerical collisions between + # SourceX and PatchX, so let's not risk it + Source30000: kernel-3.10.0-x86_64.config.tis_extra ++Source30001: ima_signing_key.pub + + # Titanium Cloud patches here. + Patch40001: Fix-compile-issue-when-transparent-hugepages-are-off.patch +@@ -447,6 +448,7 @@ Patch40030: nfsd-check-for-oversized-NFSv2-v3-arguments.patch + Patch40031: nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + Patch40032: nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + Patch40033: US101216-IMA-support-in-Titanium-kernel.patch ++Patch40036: US103091-IMA-System-Configuration.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -798,6 +800,7 @@ ApplyOptionalPatch nfsd-check-for-oversized-NFSv2-v3-arguments.patch + ApplyOptionalPatch nfsd4-minor-NFSv2-v3-write-decoding-cleanup.patch + ApplyOptionalPatch nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch + ApplyOptionalPatch US101216-IMA-support-in-Titanium-kernel.patch ++ApplyOptionalPatch US103091-IMA-System-Configuration.patch + + # Any further pre-build tree manipulations happen here. + +@@ -926,6 +929,7 @@ BuildKernel() { + cp %{SOURCE12} . # extra_certificates + cp %{SOURCE15} . # rheldup3.x509 + cp %{SOURCE16} . # rhelkpatch1.x509 ++ cp %{SOURCE30001} . # ima_signing_key.pub + + cp configs/$Config .config + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch b/kernel-std/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch new file mode 100644 index 000000000..01930e211 --- /dev/null +++ b/kernel-std/centos/meta_patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch @@ -0,0 +1,36 @@ +From c36c0ea4b420cd5ef1429b39a56da47e333ce588 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:27 -0400 +Subject: [PATCH 17/25] rcu Don't wake rcuc-X-kthreads on NOCB CPUs + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index 6112a8f..3289bba 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -434,6 +434,7 @@ Patch40012: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + Patch40013: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + Patch40014: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + Patch40015: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch ++Patch40016: rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -772,6 +773,7 @@ ApplyOptionalPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + ApplyOptionalPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch + ApplyOptionalPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch + ApplyOptionalPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch ++ApplyOptionalPatch rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/meta_patches/x86_dma_alloc_coherent-fix.patch b/kernel-std/centos/meta_patches/x86_dma_alloc_coherent-fix.patch new file mode 100644 index 000000000..86aba05a6 --- /dev/null +++ b/kernel-std/centos/meta_patches/x86_dma_alloc_coherent-fix.patch @@ -0,0 +1,38 @@ +From a3afbb969ce7b3542cbc74c0677d981e314a0763 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +References: <08db0b379c2009e0d5bc0c20427267fa07d75e5a.1507220784.git.Jim.Somerville@windriver.com> +From: Scott Little +Date: Tue, 9 May 2017 13:10:26 -0400 +Subject: [PATCH 16/25] x86_dma_alloc_coherent fix + +Signed-off-by: Jim Somerville +--- + SPECS/kernel.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec +index c0559d5..6112a8f 100644 +--- a/SPECS/kernel.spec ++++ b/SPECS/kernel.spec +@@ -432,6 +432,8 @@ Patch40010: cma-add-placement-specifier-for-cma-kernel-parameter.patch + Patch40011: x86-enable-DMA-CMA-with-swiotlb.patch + Patch40012: Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + Patch40013: Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch ++Patch40014: x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch ++Patch40015: arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + + BuildRoot: %{_tmppath}/kernel-%{KVRA}-root + +@@ -768,6 +770,8 @@ ApplyOptionalPatch cma-add-placement-specifier-for-cma-kernel-parameter.patch + ApplyOptionalPatch x86-enable-DMA-CMA-with-swiotlb.patch + ApplyOptionalPatch Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch + ApplyOptionalPatch Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch ++ApplyOptionalPatch x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch ++ApplyOptionalPatch arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch + + # Any further pre-build tree manipulations happen here. + +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch b/kernel-std/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch new file mode 100644 index 000000000..ba24f1d59 --- /dev/null +++ b/kernel-std/centos/patches/Affine-irqs-and-workqueues-with-kthread_cpus.patch @@ -0,0 +1,73 @@ +From 26472a7be73409ba33dc9ca001e7a5cc056b24fc Mon Sep 17 00:00:00 2001 +Message-Id: <26472a7be73409ba33dc9ca001e7a5cc056b24fc.1507237258.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Tue, 24 Nov 2015 16:27:29 -0500 +Subject: [PATCH 06/24] Affine irqs and workqueues with kthread_cpus + +If the kthread_cpus boot arg is set it means we want to affine +kernel threads to the specified CPU mask as much as possible +in order to avoid doing work on other CPUs. + +In this commit we extend the meaning of that boot arg to also +apply to the CPU affinity of unbound and ordered workqueues. + +We also use the kthread_cpus value to determine the default irq +affinity. Specifically, as long as the previously-calculated +irq affinity intersects with the kthread_cpus affinity then we'll +use the intersection of the two as the default irq affinity. + +Signed-off-by: Chris Friesen +[VT: replacing spaces with tabs. Performed tests] +Signed-off-by: Vu Tran + +Signed-off-by: Jim Somerville +--- + kernel/irq/manage.c | 7 +++++++ + kernel/workqueue.c | 4 ++++ + 2 files changed, 11 insertions(+) + +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 90f4309..54d58bc 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -348,6 +348,13 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) + if (cpumask_intersects(mask, nodemask)) + cpumask_and(mask, mask, nodemask); + } ++ ++ /* This will narrow down the affinity further if we've specified ++ * a reduced cpu_kthread_mask in the boot args. ++ */ ++ if (cpumask_intersects(mask, cpu_kthread_mask)) ++ cpumask_and(mask, mask, cpu_kthread_mask); ++ + irq_do_set_affinity(&desc->irq_data, mask, false); + return 0; + } +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index d54b4e3..99fe902 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5417,6 +5417,8 @@ static int __init init_workqueues(void) + + BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL))); + attrs->nice = std_nice[i]; ++ /* If we've specified a kthread mask apply it here too. */ ++ cpumask_copy(attrs->cpumask, cpu_kthread_mask); + unbound_std_wq_attrs[i] = attrs; + + /* +@@ -5427,6 +5429,8 @@ static int __init init_workqueues(void) + BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL))); + attrs->nice = std_nice[i]; + attrs->no_numa = true; ++ /* If we've specified a kthread mask apply it here too. */ ++ cpumask_copy(attrs->cpumask, cpu_kthread_mask); + ordered_wq_attrs[i] = attrs; + } + +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch b/kernel-std/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch new file mode 100644 index 000000000..7cc866b01 --- /dev/null +++ b/kernel-std/centos/patches/CGTS-3744-route-do-not-cache-fib-route-info-on-local.patch @@ -0,0 +1,58 @@ +From 181e7d3d7f1a3ea9cd532f8a18441ae4f569255b Mon Sep 17 00:00:00 2001 +Message-Id: <181e7d3d7f1a3ea9cd532f8a18441ae4f569255b.1507237258.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Allain Legacy +Date: Fri, 29 Jan 2016 12:13:40 -0500 +Subject: [PATCH 03/24] CGTS-3744: route: do not cache fib route info on local + routes with oif + +For local routes that require a particular output interface we do not want to +cache the result. Caching the result causes incorrect behaviour when there are +multiple source addresses on the interface. The end result being that if the +intended recipient is waiting on that interface for the packet he won't receive +it because it will be delivered on the loopback interface and the IP_PKTINFO +ipi_ifindex will be set to the loopback interface as well. + +This can be tested by running a program such as "dhcp_release" which attempts +to inject a packet on a particular interface so that it is received by another +program on the same board. The receiving process should see an IP_PKTINFO +ipi_ifndex value of the source interface (e.g., eth1) instead of the loopback +interface (e.g., lo). The packet will still appear on the loopback interface +in tcpdump but the important aspect is that the CMSG info is correct. + +Sample dhcp_release command line: + + dhcp_release eth1 192.168.204.222 02:11:33:22:44:66 + +Signed-off-by: Allain Legacy +Signed-off-by: Jim Somerville +--- + net/ipv4/route.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index e9a2b06..66a2a89 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2044,6 +2044,17 @@ static struct rtable *__mkroute_output(const struct fib_result *res, + */ + if (fi && res->prefixlen < 4) + fi = NULL; ++ } else if ((type == RTN_LOCAL) && (orig_oif != 0)) { ++ /* ++ * For local routes that require a particular output interface we do ++ * not want to cache the result. Caching the result causes incorrect ++ * behaviour when there are multiple source addresses on the interface. ++ * The end result being that if the intended recipient is waiting on ++ * that interface for the packet he won't receive it because it will be ++ * delivered on the loopback interface and the IP_PKTINFO ipi_ifindex ++ * will be set to the loopback interface as well. ++ */ ++ fi = NULL; + } + + fnhe = NULL; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch b/kernel-std/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch new file mode 100644 index 000000000..7715b3925 --- /dev/null +++ b/kernel-std/centos/patches/CPU-PM-expose-pm_qos_resume_latency-for-CPUs.patch @@ -0,0 +1,63 @@ +From b95a4456ba09301a5b42a6da77ee1f2c85342b60 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Alex Shi +Date: Thu, 12 Jan 2017 21:27:03 +0800 +Subject: [PATCH 21/24] CPU / PM: expose pm_qos_resume_latency for CPUs + +[ commit 37efa4b41ffb31dcdfc3beb97d47992bb2a083e5 from linux-stable ] + +The cpu-dma PM QoS constraint impacts all the cpus in the system. There is no way +to let the user to choose a PM QoS constraint per cpu. + +The following patch exposes to the userspace a per cpu based sysfs file +in order to let the userspace to change the value of the PM QoS latency +constraint. + +This change is inoperative in its form and the cpuidle governors have to +take into account the per cpu latency constraint in addition to the +global cpu-dma latency constraint in order to operate properly. + +BTW +The pm_qos_resume_latency usage defined in +Documentation/ABI/testing/sysfs-devices-power +The /sys/devices/.../power/pm_qos_resume_latency_us attribute +contains the PM QoS resume latency limit for the given device, +which is the maximum allowed time it can take to resume the +device, after it has been suspended at run time, from a resume +request to the moment the device will be ready to process I/O, +in microseconds. If it is equal to 0, however, this means that +the PM QoS resume latency may be arbitrary. + +Signed-off-by: Alex Shi +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + drivers/base/cpu.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index 0ff0eff..e5a5de3 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "base.h" + +@@ -318,6 +319,7 @@ int register_cpu(struct cpu *cpu, int num) + per_cpu(cpu_sys_devices, num) = &cpu->dev; + if (!error) + register_cpu_under_node(num, cpu_to_node(num)); ++ dev_pm_qos_expose_latency_limit(&cpu->dev, 0); + + #ifdef CONFIG_KEXEC + if (!error) +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch b/kernel-std/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch new file mode 100644 index 000000000..71e532b95 --- /dev/null +++ b/kernel-std/centos/patches/Enable-building-kernel-with-CONFIG_BLK_DEV_NBD.patch @@ -0,0 +1,36 @@ +From 12944d162e13c7f853c29730c45dce27b5256e8a Mon Sep 17 00:00:00 2001 +Message-Id: <12944d162e13c7f853c29730c45dce27b5256e8a.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Wed, 11 Jan 2017 13:38:37 -0500 +Subject: [PATCH 13/24] Enable building kernel with CONFIG_BLK_DEV_NBD + +By default, the CentOS 7.3 kernel will fail to build if +CONFIG_BLK_DEV_NBD is enabled, either as module or builtin. + +The issue seems to be due to the use of REQ_TYPE_SPECIAL in the +NBD code. Switching it to use REQ_TYPE_DRV_PRIV instead makes the +problem go away. + +Signed-off-by: Jim Somerville +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index a40a4f0..e0c6b62 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -616,7 +616,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + fsync_bdev(bdev); + mutex_lock(&nbd->tx_lock); + blk_rq_init(NULL, &sreq); +- sreq.cmd_type = REQ_TYPE_SPECIAL; ++ sreq.cmd_type = REQ_TYPE_DRV_PRIV; + nbd_cmd(&sreq) = NBD_CMD_DISC; + + /* Check again after getting mutex back. */ +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch b/kernel-std/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch new file mode 100644 index 000000000..117527bb9 --- /dev/null +++ b/kernel-std/centos/patches/Enable-building-mpt2sas-and-mpt3sas-as-builtin-for-C.patch @@ -0,0 +1,34236 @@ +From a62adecc1c6ac05d65d2a93db961b0f28a40d373 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Mon, 9 Jan 2017 15:03:00 -0500 +Subject: [PATCH 12/24] Enable building mpt2sas and mpt3sas as builtin for + CentOS 7.3 + +In CentOS 7.3 the upstream mpt2sas/mpt3sas drivers are built from +essentially the same codebase with a flag defined to give the mpt2sas +behaviour. This is purely a problem in 7.3 due to how they have mangled +the drivers. More recently in the Linux kernel these have been merged +into a single driver, while previously in 7.2 they were two totally +separate drivers. + +The 7.3 code works fine when building as modules, but when building as +builtin it gives problems because KBUILD_MODNAME is not defined for files +that are included in multiple drivers. + +The workaround is to move the mpt2sas driver into its own directory, +copying the whole mpt3sas codebase into it. This required a number of +changes after duplicating the codebase: + +1) Add knowledge of the new "mpt2sas" directory to from drivers/scsi/Kconfig +and drivers/scsi/Makefile. + +2) Remove mention of mpt2sas from drivers/scsi/mpt3sas/Kconfig and +drivers/scsi/mpt3sas/Makefile. + +3) Remove mention of mpt3sas from drivers/scsi/mpt2sas/Kconfig and +drivers/scsi/mpt2sas/Makefile. + +4) In the mpt2sas directory, all functions/variables with "mpt3sas" in +the name which did not already have an mpt2sas equivalent were renamed +to instead use "mpt2sas". Thus "_mpt3sas_init" became "_mpt2sas_init". + +5) All other symbols that collided between the two modules were renamed +in the mpt2sas driver by appending "_mpt2sas". This included ones with +"mpt2sas" already in the name, so "mpt2sas_raid_template" became +"mpt2sas_raid_template_mpt2sas". (While the version in the mpt3sas +driver remained "mpt2sas_raid_template".) + +Signed-off-by: Jim Somerville +--- + drivers/scsi/Kconfig | 1 + + drivers/scsi/Makefile | 1 + + drivers/scsi/mpt2sas/Kconfig | 61 + + drivers/scsi/mpt2sas/Makefile | 12 + + drivers/scsi/mpt2sas/mpi/mpi2.h | 1243 ++++ + drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h | 3493 ++++++++++ + drivers/scsi/mpt2sas/mpi/mpi2_init.h | 581 ++ + drivers/scsi/mpt2sas/mpi/mpi2_ioc.h | 1860 +++++ + drivers/scsi/mpt2sas/mpi/mpi2_raid.h | 355 + + drivers/scsi/mpt2sas/mpi/mpi2_sas.h | 303 + + drivers/scsi/mpt2sas/mpi/mpi2_tool.h | 483 ++ + drivers/scsi/mpt2sas/mpi/mpi2_type.h | 57 + + drivers/scsi/mpt2sas/mpt3sas_base.c | 5713 ++++++++++++++++ + drivers/scsi/mpt2sas/mpt3sas_base.h | 1462 ++++ + drivers/scsi/mpt2sas/mpt3sas_config.c | 1716 +++++ + drivers/scsi/mpt2sas/mpt3sas_ctl.c | 3483 ++++++++++ + drivers/scsi/mpt2sas/mpt3sas_ctl.h | 423 ++ + drivers/scsi/mpt2sas/mpt3sas_debug.h | 206 + + drivers/scsi/mpt2sas/mpt3sas_scsih.c | 9356 ++++++++++++++++++++++++++ + drivers/scsi/mpt2sas/mpt3sas_transport.c | 2138 ++++++ + drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c | 434 ++ + drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h | 194 + + drivers/scsi/mpt2sas/mpt3sas_warpdrive.c | 344 + + drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c | 4 + + drivers/scsi/mpt3sas/Kconfig | 20 - + drivers/scsi/mpt3sas/Makefile | 9 - + 26 files changed, 33923 insertions(+), 29 deletions(-) + create mode 100644 drivers/scsi/mpt2sas/Kconfig + create mode 100644 drivers/scsi/mpt2sas/Makefile + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_init.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_ioc.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_raid.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_sas.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_tool.h + create mode 100644 drivers/scsi/mpt2sas/mpi/mpi2_type.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_base.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_base.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_config.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_ctl.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_ctl.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_debug.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_scsih.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_transport.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h + create mode 100644 drivers/scsi/mpt2sas/mpt3sas_warpdrive.c + create mode 100644 drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c + +diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig +index d1293c0..1c9fc44 100644 +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -599,6 +599,7 @@ config SCSI_ARCMSR + module will be called arcmsr (modprobe arcmsr). + + source "drivers/scsi/megaraid/Kconfig.megaraid" ++source "drivers/scsi/mpt2sas/Kconfig" + source "drivers/scsi/mpt3sas/Kconfig" + source "drivers/scsi/smartpqi/Kconfig" + source "drivers/scsi/ufs/Kconfig" +diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile +index 95aed68..1a08fca 100644 +--- a/drivers/scsi/Makefile ++++ b/drivers/scsi/Makefile +@@ -109,6 +109,7 @@ obj-$(CONFIG_CXLFLASH) += cxlflash/ + obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o + obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ + obj-$(CONFIG_MEGARAID_SAS) += megaraid/ ++obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/ + obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/ + obj-$(CONFIG_SCSI_UFSHCD) += ufs/ + obj-$(CONFIG_SCSI_ACARD) += atp870u.o +diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig +new file mode 100644 +index 0000000..a53ee73 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/Kconfig +@@ -0,0 +1,61 @@ ++# ++# Kernel configuration file for the MPT2SAS ++# ++# This code is based on drivers/scsi/mpt3sas/Kconfig ++# Copyright (C) 2012-2014 LSI Corporation ++# (mailto:DL-MPTFusionLinux@lsi.com) ++ ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version 2 ++# of the License, or (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# NO WARRANTY ++# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++# solely responsible for determining the appropriateness of using and ++# distributing the Program and assumes all risks associated with its ++# exercise of rights under this Agreement, including but not limited to ++# the risks and costs of program errors, damage to or loss of data, ++# programs or equipment, and unavailability or interruption of operations. ++ ++# DISCLAIMER OF LIABILITY ++# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++# USA. ++ ++config SCSI_MPT2SAS ++ tristate "LSI MPT Fusion SAS 2.0 Device Driver" ++ depends on PCI && SCSI ++ select SCSI_SAS_ATTRS ++ select RAID_ATTRS ++ ---help--- ++ This driver supports PCI-Express SAS 6Gb/s Host Adapters. ++ ++config SCSI_MPT2SAS_MAX_SGE ++ int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)" ++ depends on PCI && SCSI && SCSI_MPT2SAS ++ default "128" ++ range 16 256 ++ ---help--- ++ This option allows you to specify the maximum number of scatter- ++ gather entries per I/O. The driver default is 128, which matches ++ MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this ++ can be 256. However, it may decreased down to 16. Decreasing this ++ parameter will reduce memory requirements on a per controller instance. +diff --git a/drivers/scsi/mpt2sas/Makefile b/drivers/scsi/mpt2sas/Makefile +new file mode 100644 +index 0000000..5706ea4 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/Makefile +@@ -0,0 +1,12 @@ ++# mpt2-3sas makefile ++ ++obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o ++ ++obj-m += mpt2sas.o ++mpt2sas-y += mpt3sas_base.o \ ++ mpt3sas_config.o \ ++ wrapper_mpt3sas_scsih.o \ ++ mpt3sas_transport.o \ ++ mpt3sas_ctl.o \ ++ mpt3sas_trigger_diag.o \ ++ mpt3sas_warpdrive.o +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h +new file mode 100644 +index 0000000..a9a659f +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2.h +@@ -0,0 +1,1243 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2.h ++ * Title: MPI Message independent structures and definitions ++ * including System Interface Register Set and ++ * scatter/gather formats. ++ * Creation Date: June 21, 2006 ++ * ++ * mpi2.h Version: 02.00.42 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-04-07 02.00.01 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 06-26-07 02.00.02 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-31-07 02.00.03 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Moved ReplyPostHostIndex register to offset 0x6C of the ++ * MPI2_SYSTEM_INTERFACE_REGS and modified the define for ++ * MPI2_REPLY_POST_HOST_INDEX_OFFSET. ++ * Added union of request descriptors. ++ * Added union of reply descriptors. ++ * 10-31-07 02.00.04 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added define for MPI2_VERSION_02_00. ++ * Fixed the size of the FunctionDependent5 field in the ++ * MPI2_DEFAULT_REPLY structure. ++ * 12-18-07 02.00.05 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Removed the MPI-defined Fault Codes and extended the ++ * product specific codes up to 0xEFFF. ++ * Added a sixth key value for the WriteSequence register ++ * and changed the flush value to 0x0. ++ * Added message function codes for Diagnostic Buffer Post ++ * and Diagnsotic Release. ++ * New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED ++ * Moved MPI2_VERSION_UNION from mpi2_ioc.h. ++ * 02-29-08 02.00.06 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 03-03-08 02.00.07 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-21-08 02.00.08 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added #defines for marking a reply descriptor as unused. ++ * 06-27-08 02.00.09 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Moved LUN field defines from mpi2_init.h. ++ * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT. ++ * In all request and reply descriptors, replaced VF_ID ++ * field with MSIxIndex field. ++ * Removed DevHandle field from ++ * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those ++ * bytes reserved. ++ * Added RAID Accelerator functionality. ++ * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MSI-x index mask and shift for Reply Post Host ++ * Index register. ++ * Added function code for Host Based Discovery Action. ++ * 02-10-10 02.00.15 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL. ++ * Added defines for product-specific range of message ++ * function codes, 0xF0 to 0xFF. ++ * 05-12-10 02.00.16 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added alternative defines for the SGE Direction bit. ++ * 08-11-10 02.00.17 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-10-10 02.00.18 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define. ++ * 02-23-11 02.00.19 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MPI2_FUNCTION_SEND_HOST_MESSAGE. ++ * 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-25-11 02.00.21 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-24-11 02.00.22 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-18-11 02.00.23 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Incorporating additions for MPI v2.5. ++ * 02-06-12 02.00.24 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added Hard Reset delay timings. ++ * 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-27-12 02.00.28 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 12-20-12 02.00.29 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. ++ * 04-09-13 02.00.30 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 12-05-13 02.00.33 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 01-08-14 02.00.34 Bumped MPI2_HEADER_VERSION_UNIT ++ * 06-13-14 02.00.35 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 11-18-14 02.00.36 Updated copyright information. ++ * Bumped MPI2_HEADER_VERSION_UNIT. ++ * 03-16-15 02.00.37 Bumped MPI2_HEADER_VERSION_UNIT. ++ * Added Scratchpad registers to ++ * MPI2_SYSTEM_INTERFACE_REGS. ++ * Added MPI2_DIAG_SBR_RELOAD. ++ * 03-19-15 02.00.38 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 05-25-15 02.00.39 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 08-25-15 02.00.40 Bumped MPI2_HEADER_VERSION_UNIT. ++ * 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT ++ * 01-01-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_H ++#define MPI2_H ++ ++/***************************************************************************** ++* ++* MPI Version Definitions ++* ++*****************************************************************************/ ++ ++#define MPI2_VERSION_MAJOR_MASK (0xFF00) ++#define MPI2_VERSION_MAJOR_SHIFT (8) ++#define MPI2_VERSION_MINOR_MASK (0x00FF) ++#define MPI2_VERSION_MINOR_SHIFT (0) ++ ++/*major version for all MPI v2.x */ ++#define MPI2_VERSION_MAJOR (0x02) ++ ++/*minor version for MPI v2.0 compatible products */ ++#define MPI2_VERSION_MINOR (0x00) ++#define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ ++ MPI2_VERSION_MINOR) ++#define MPI2_VERSION_02_00 (0x0200) ++ ++/*minor version for MPI v2.5 compatible products */ ++#define MPI25_VERSION_MINOR (0x05) ++#define MPI25_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ ++ MPI25_VERSION_MINOR) ++#define MPI2_VERSION_02_05 (0x0205) ++ ++/*minor version for MPI v2.6 compatible products */ ++#define MPI26_VERSION_MINOR (0x06) ++#define MPI26_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ ++ MPI26_VERSION_MINOR) ++#define MPI2_VERSION_02_06 (0x0206) ++ ++/*Unit and Dev versioning for this MPI header set */ ++#define MPI2_HEADER_VERSION_UNIT (0x2A) ++#define MPI2_HEADER_VERSION_DEV (0x00) ++#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) ++#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) ++#define MPI2_HEADER_VERSION_DEV_MASK (0x00FF) ++#define MPI2_HEADER_VERSION_DEV_SHIFT (0) ++#define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | \ ++ MPI2_HEADER_VERSION_DEV) ++ ++/***************************************************************************** ++* ++* IOC State Definitions ++* ++*****************************************************************************/ ++ ++#define MPI2_IOC_STATE_RESET (0x00000000) ++#define MPI2_IOC_STATE_READY (0x10000000) ++#define MPI2_IOC_STATE_OPERATIONAL (0x20000000) ++#define MPI2_IOC_STATE_FAULT (0x40000000) ++ ++#define MPI2_IOC_STATE_MASK (0xF0000000) ++#define MPI2_IOC_STATE_SHIFT (28) ++ ++/*Fault state range for prodcut specific codes */ ++#define MPI2_FAULT_PRODUCT_SPECIFIC_MIN (0x0000) ++#define MPI2_FAULT_PRODUCT_SPECIFIC_MAX (0xEFFF) ++ ++/***************************************************************************** ++* ++* System Interface Register Definitions ++* ++*****************************************************************************/ ++ ++typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS { ++ U32 Doorbell; /*0x00 */ ++ U32 WriteSequence; /*0x04 */ ++ U32 HostDiagnostic; /*0x08 */ ++ U32 Reserved1; /*0x0C */ ++ U32 DiagRWData; /*0x10 */ ++ U32 DiagRWAddressLow; /*0x14 */ ++ U32 DiagRWAddressHigh; /*0x18 */ ++ U32 Reserved2[5]; /*0x1C */ ++ U32 HostInterruptStatus; /*0x30 */ ++ U32 HostInterruptMask; /*0x34 */ ++ U32 DCRData; /*0x38 */ ++ U32 DCRAddress; /*0x3C */ ++ U32 Reserved3[2]; /*0x40 */ ++ U32 ReplyFreeHostIndex; /*0x48 */ ++ U32 Reserved4[8]; /*0x4C */ ++ U32 ReplyPostHostIndex; /*0x6C */ ++ U32 Reserved5; /*0x70 */ ++ U32 HCBSize; /*0x74 */ ++ U32 HCBAddressLow; /*0x78 */ ++ U32 HCBAddressHigh; /*0x7C */ ++ U32 Reserved6[12]; /*0x80 */ ++ U32 Scratchpad[4]; /*0xB0 */ ++ U32 RequestDescriptorPostLow; /*0xC0 */ ++ U32 RequestDescriptorPostHigh; /*0xC4 */ ++ U32 AtomicRequestDescriptorPost;/*0xC8 */ ++ U32 Reserved7[13]; /*0xCC */ ++} MPI2_SYSTEM_INTERFACE_REGS, ++ *PTR_MPI2_SYSTEM_INTERFACE_REGS, ++ Mpi2SystemInterfaceRegs_t, ++ *pMpi2SystemInterfaceRegs_t; ++ ++/* ++ *Defines for working with the Doorbell register. ++ */ ++#define MPI2_DOORBELL_OFFSET (0x00000000) ++ ++/*IOC --> System values */ ++#define MPI2_DOORBELL_USED (0x08000000) ++#define MPI2_DOORBELL_WHO_INIT_MASK (0x07000000) ++#define MPI2_DOORBELL_WHO_INIT_SHIFT (24) ++#define MPI2_DOORBELL_FAULT_CODE_MASK (0x0000FFFF) ++#define MPI2_DOORBELL_DATA_MASK (0x0000FFFF) ++ ++/*System --> IOC values */ ++#define MPI2_DOORBELL_FUNCTION_MASK (0xFF000000) ++#define MPI2_DOORBELL_FUNCTION_SHIFT (24) ++#define MPI2_DOORBELL_ADD_DWORDS_MASK (0x00FF0000) ++#define MPI2_DOORBELL_ADD_DWORDS_SHIFT (16) ++ ++/* ++ *Defines for the WriteSequence register ++ */ ++#define MPI2_WRITE_SEQUENCE_OFFSET (0x00000004) ++#define MPI2_WRSEQ_KEY_VALUE_MASK (0x0000000F) ++#define MPI2_WRSEQ_FLUSH_KEY_VALUE (0x0) ++#define MPI2_WRSEQ_1ST_KEY_VALUE (0xF) ++#define MPI2_WRSEQ_2ND_KEY_VALUE (0x4) ++#define MPI2_WRSEQ_3RD_KEY_VALUE (0xB) ++#define MPI2_WRSEQ_4TH_KEY_VALUE (0x2) ++#define MPI2_WRSEQ_5TH_KEY_VALUE (0x7) ++#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD) ++ ++/* ++ *Defines for the HostDiagnostic register ++ */ ++#define MPI2_HOST_DIAGNOSTIC_OFFSET (0x00000008) ++ ++#define MPI2_DIAG_SBR_RELOAD (0x00002000) ++ ++#define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK (0x00001800) ++#define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT (0x00000000) ++#define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW (0x00000800) ++ ++#define MPI2_DIAG_CLEAR_FLASH_BAD_SIG (0x00000400) ++#define MPI2_DIAG_FORCE_HCB_ON_RESET (0x00000200) ++#define MPI2_DIAG_HCB_MODE (0x00000100) ++#define MPI2_DIAG_DIAG_WRITE_ENABLE (0x00000080) ++#define MPI2_DIAG_FLASH_BAD_SIG (0x00000040) ++#define MPI2_DIAG_RESET_HISTORY (0x00000020) ++#define MPI2_DIAG_DIAG_RW_ENABLE (0x00000010) ++#define MPI2_DIAG_RESET_ADAPTER (0x00000004) ++#define MPI2_DIAG_HOLD_IOC_RESET (0x00000002) ++ ++/* ++ *Offsets for DiagRWData and address ++ */ ++#define MPI2_DIAG_RW_DATA_OFFSET (0x00000010) ++#define MPI2_DIAG_RW_ADDRESS_LOW_OFFSET (0x00000014) ++#define MPI2_DIAG_RW_ADDRESS_HIGH_OFFSET (0x00000018) ++ ++/* ++ *Defines for the HostInterruptStatus register ++ */ ++#define MPI2_HOST_INTERRUPT_STATUS_OFFSET (0x00000030) ++#define MPI2_HIS_SYS2IOC_DB_STATUS (0x80000000) ++#define MPI2_HIS_IOP_DOORBELL_STATUS MPI2_HIS_SYS2IOC_DB_STATUS ++#define MPI2_HIS_RESET_IRQ_STATUS (0x40000000) ++#define MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT (0x00000008) ++#define MPI2_HIS_IOC2SYS_DB_STATUS (0x00000001) ++#define MPI2_HIS_DOORBELL_INTERRUPT MPI2_HIS_IOC2SYS_DB_STATUS ++ ++/* ++ *Defines for the HostInterruptMask register ++ */ ++#define MPI2_HOST_INTERRUPT_MASK_OFFSET (0x00000034) ++#define MPI2_HIM_RESET_IRQ_MASK (0x40000000) ++#define MPI2_HIM_REPLY_INT_MASK (0x00000008) ++#define MPI2_HIM_RIM MPI2_HIM_REPLY_INT_MASK ++#define MPI2_HIM_IOC2SYS_DB_MASK (0x00000001) ++#define MPI2_HIM_DIM MPI2_HIM_IOC2SYS_DB_MASK ++ ++/* ++ *Offsets for DCRData and address ++ */ ++#define MPI2_DCR_DATA_OFFSET (0x00000038) ++#define MPI2_DCR_ADDRESS_OFFSET (0x0000003C) ++ ++/* ++ *Offset for the Reply Free Queue ++ */ ++#define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048) ++ ++/* ++ *Defines for the Reply Descriptor Post Queue ++ */ ++#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) ++#define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF) ++#define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000) ++#define MPI2_RPHI_MSIX_INDEX_SHIFT (24) ++#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) /*MPI v2.5 only*/ ++ ++ ++/* ++ *Defines for the HCBSize and address ++ */ ++#define MPI2_HCB_SIZE_OFFSET (0x00000074) ++#define MPI2_HCB_SIZE_SIZE_MASK (0xFFFFF000) ++#define MPI2_HCB_SIZE_HCB_ENABLE (0x00000001) ++ ++#define MPI2_HCB_ADDRESS_LOW_OFFSET (0x00000078) ++#define MPI2_HCB_ADDRESS_HIGH_OFFSET (0x0000007C) ++ ++/* ++ *Offsets for the Scratchpad registers ++ */ ++#define MPI26_SCRATCHPAD0_OFFSET (0x000000B0) ++#define MPI26_SCRATCHPAD1_OFFSET (0x000000B4) ++#define MPI26_SCRATCHPAD2_OFFSET (0x000000B8) ++#define MPI26_SCRATCHPAD3_OFFSET (0x000000BC) ++ ++/* ++ *Offsets for the Request Descriptor Post Queue ++ */ ++#define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET (0x000000C0) ++#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4) ++#define MPI26_ATOMIC_REQUEST_DESCRIPTOR_POST_OFFSET (0x000000C8) ++ ++/*Hard Reset delay timings */ ++#define MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC (50000) ++#define MPI2_HARD_RESET_PCIE_RESET_READ_WINDOW_MICRO_SEC (255000) ++#define MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC (256000) ++ ++/***************************************************************************** ++* ++* Message Descriptors ++* ++*****************************************************************************/ ++ ++/*Request Descriptors */ ++ ++/*Default Request Descriptor */ ++typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 DescriptorTypeDependent; /*0x06 */ ++} MPI2_DEFAULT_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_DEFAULT_REQUEST_DESCRIPTOR, ++ Mpi2DefaultRequestDescriptor_t, ++ *pMpi2DefaultRequestDescriptor_t; ++ ++/*defines for the RequestFlags field */ ++#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x1E) ++#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_RSHIFT (1) ++#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00) ++#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02) ++#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06) ++#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08) ++#define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR (0x0A) ++#define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO (0x0C) ++ ++#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01) ++ ++/*High Priority Request Descriptor */ ++typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++} MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR, ++ Mpi2HighPriorityRequestDescriptor_t, ++ *pMpi2HighPriorityRequestDescriptor_t; ++ ++/*SCSI IO Request Descriptor */ ++typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 DevHandle; /*0x06 */ ++} MPI2_SCSI_IO_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_SCSI_IO_REQUEST_DESCRIPTOR, ++ Mpi2SCSIIORequestDescriptor_t, ++ *pMpi2SCSIIORequestDescriptor_t; ++ ++/*SCSI Target Request Descriptor */ ++typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 IoIndex; /*0x06 */ ++} MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR, ++ Mpi2SCSITargetRequestDescriptor_t, ++ *pMpi2SCSITargetRequestDescriptor_t; ++ ++/*RAID Accelerator Request Descriptor */ ++typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 LMID; /*0x04 */ ++ U16 Reserved; /*0x06 */ ++} MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, ++ *PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, ++ Mpi2RAIDAcceleratorRequestDescriptor_t, ++ *pMpi2RAIDAcceleratorRequestDescriptor_t; ++ ++/*Fast Path SCSI IO Request Descriptor */ ++typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR ++ MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR, ++ *PTR_MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR, ++ Mpi25FastPathSCSIIORequestDescriptor_t, ++ *pMpi25FastPathSCSIIORequestDescriptor_t; ++ ++/*union of Request Descriptors */ ++typedef union _MPI2_REQUEST_DESCRIPTOR_UNION { ++ MPI2_DEFAULT_REQUEST_DESCRIPTOR Default; ++ MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority; ++ MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO; ++ MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget; ++ MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator; ++ MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO; ++ U64 Words; ++} MPI2_REQUEST_DESCRIPTOR_UNION, ++ *PTR_MPI2_REQUEST_DESCRIPTOR_UNION, ++ Mpi2RequestDescriptorUnion_t, ++ *pMpi2RequestDescriptorUnion_t; ++ ++/*Atomic Request Descriptors */ ++ ++/* ++ * All Atomic Request Descriptors have the same format, so the following ++ * structure is used for all Atomic Request Descriptors: ++ * Atomic Default Request Descriptor ++ * Atomic High Priority Request Descriptor ++ * Atomic SCSI IO Request Descriptor ++ * Atomic SCSI Target Request Descriptor ++ * Atomic RAID Accelerator Request Descriptor ++ * Atomic Fast Path SCSI IO Request Descriptor ++ */ ++ ++/*Atomic Request Descriptor */ ++typedef struct _MPI26_ATOMIC_REQUEST_DESCRIPTOR { ++ U8 RequestFlags; /* 0x00 */ ++ U8 MSIxIndex; /* 0x01 */ ++ U16 SMID; /* 0x02 */ ++} MPI26_ATOMIC_REQUEST_DESCRIPTOR, ++ *PTR_MPI26_ATOMIC_REQUEST_DESCRIPTOR, ++ Mpi26AtomicRequestDescriptor_t, ++ *pMpi26AtomicRequestDescriptor_t; ++ ++/*for the RequestFlags field, use the same ++ *defines as MPI2_DEFAULT_REQUEST_DESCRIPTOR ++ */ ++ ++/*Reply Descriptors */ ++ ++/*Default Reply Descriptor */ ++typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 DescriptorTypeDependent1; /*0x02 */ ++ U32 DescriptorTypeDependent2; /*0x04 */ ++} MPI2_DEFAULT_REPLY_DESCRIPTOR, ++ *PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR, ++ Mpi2DefaultReplyDescriptor_t, ++ *pMpi2DefaultReplyDescriptor_t; ++ ++/*defines for the ReplyFlags field */ ++#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F) ++#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00) ++#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01) ++#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02) ++#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03) ++#define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS (0x05) ++#define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS (0x06) ++#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F) ++ ++/*values for marking a reply descriptor as unused */ ++#define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF) ++#define MPI2_RPY_DESCRIPT_UNUSED_WORD1_MARK (0xFFFFFFFF) ++ ++/*Address Reply Descriptor */ ++typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U32 ReplyFrameAddress; /*0x04 */ ++} MPI2_ADDRESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR, ++ Mpi2AddressReplyDescriptor_t, ++ *pMpi2AddressReplyDescriptor_t; ++ ++#define MPI2_ADDRESS_REPLY_SMID_INVALID (0x00) ++ ++/*SCSI IO Success Reply Descriptor */ ++typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U16 TaskTag; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi2SCSIIOSuccessReplyDescriptor_t, ++ *pMpi2SCSIIOSuccessReplyDescriptor_t; ++ ++/*TargetAssist Success Reply Descriptor */ ++typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U8 SequenceNumber; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 IoIndex; /*0x06 */ ++} MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi2TargetAssistSuccessReplyDescriptor_t, ++ *pMpi2TargetAssistSuccessReplyDescriptor_t; ++ ++/*Target Command Buffer Reply Descriptor */ ++typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U8 VP_ID; /*0x02 */ ++ U8 Flags; /*0x03 */ ++ U16 InitiatorDevHandle; /*0x04 */ ++ U16 IoIndex; /*0x06 */ ++} MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR, ++ *PTR_MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR, ++ Mpi2TargetCommandBufferReplyDescriptor_t, ++ *pMpi2TargetCommandBufferReplyDescriptor_t; ++ ++/*defines for Flags field */ ++#define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F) ++ ++/*RAID Accelerator Success Reply Descriptor */ ++typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR { ++ U8 ReplyFlags; /*0x00 */ ++ U8 MSIxIndex; /*0x01 */ ++ U16 SMID; /*0x02 */ ++ U32 Reserved; /*0x04 */ ++} MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi2RAIDAcceleratorSuccessReplyDescriptor_t, ++ *pMpi2RAIDAcceleratorSuccessReplyDescriptor_t; ++ ++/*Fast Path SCSI IO Success Reply Descriptor */ ++typedef MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR ++ MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ *PTR_MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, ++ Mpi25FastPathSCSIIOSuccessReplyDescriptor_t, ++ *pMpi25FastPathSCSIIOSuccessReplyDescriptor_t; ++ ++/*union of Reply Descriptors */ ++typedef union _MPI2_REPLY_DESCRIPTORS_UNION { ++ MPI2_DEFAULT_REPLY_DESCRIPTOR Default; ++ MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply; ++ MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess; ++ MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess; ++ MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer; ++ MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess; ++ MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR FastPathSCSIIOSuccess; ++ U64 Words; ++} MPI2_REPLY_DESCRIPTORS_UNION, ++ *PTR_MPI2_REPLY_DESCRIPTORS_UNION, ++ Mpi2ReplyDescriptorsUnion_t, ++ *pMpi2ReplyDescriptorsUnion_t; ++ ++/***************************************************************************** ++* ++* Message Functions ++* ++*****************************************************************************/ ++ ++#define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) ++#define MPI2_FUNCTION_SCSI_TASK_MGMT (0x01) ++#define MPI2_FUNCTION_IOC_INIT (0x02) ++#define MPI2_FUNCTION_IOC_FACTS (0x03) ++#define MPI2_FUNCTION_CONFIG (0x04) ++#define MPI2_FUNCTION_PORT_FACTS (0x05) ++#define MPI2_FUNCTION_PORT_ENABLE (0x06) ++#define MPI2_FUNCTION_EVENT_NOTIFICATION (0x07) ++#define MPI2_FUNCTION_EVENT_ACK (0x08) ++#define MPI2_FUNCTION_FW_DOWNLOAD (0x09) ++#define MPI2_FUNCTION_TARGET_ASSIST (0x0B) ++#define MPI2_FUNCTION_TARGET_STATUS_SEND (0x0C) ++#define MPI2_FUNCTION_TARGET_MODE_ABORT (0x0D) ++#define MPI2_FUNCTION_FW_UPLOAD (0x12) ++#define MPI2_FUNCTION_RAID_ACTION (0x15) ++#define MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH (0x16) ++#define MPI2_FUNCTION_TOOLBOX (0x17) ++#define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR (0x18) ++#define MPI2_FUNCTION_SMP_PASSTHROUGH (0x1A) ++#define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) ++#define MPI2_FUNCTION_IO_UNIT_CONTROL (0x1B) ++#define MPI2_FUNCTION_SATA_PASSTHROUGH (0x1C) ++#define MPI2_FUNCTION_DIAG_BUFFER_POST (0x1D) ++#define MPI2_FUNCTION_DIAG_RELEASE (0x1E) ++#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) ++#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) ++#define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) ++#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F) ++#define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30) ++#define MPI2_FUNCTION_SEND_HOST_MESSAGE (0x31) ++#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0) ++#define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++/*Doorbell functions */ ++#define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) ++#define MPI2_FUNCTION_HANDSHAKE (0x42) ++ ++/***************************************************************************** ++* ++* IOC Status Values ++* ++*****************************************************************************/ ++ ++/*mask for IOCStatus status value */ ++#define MPI2_IOCSTATUS_MASK (0x7FFF) ++ ++/**************************************************************************** ++* Common IOCStatus values for all replies ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_SUCCESS (0x0000) ++#define MPI2_IOCSTATUS_INVALID_FUNCTION (0x0001) ++#define MPI2_IOCSTATUS_BUSY (0x0002) ++#define MPI2_IOCSTATUS_INVALID_SGL (0x0003) ++#define MPI2_IOCSTATUS_INTERNAL_ERROR (0x0004) ++#define MPI2_IOCSTATUS_INVALID_VPID (0x0005) ++#define MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006) ++#define MPI2_IOCSTATUS_INVALID_FIELD (0x0007) ++#define MPI2_IOCSTATUS_INVALID_STATE (0x0008) ++#define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009) ++#define MPI2_IOCSTATUS_INSUFFICIENT_POWER (0x000A) ++ ++/**************************************************************************** ++* Config IOCStatus values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020) ++#define MPI2_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021) ++#define MPI2_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022) ++#define MPI2_IOCSTATUS_CONFIG_INVALID_DATA (0x0023) ++#define MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024) ++#define MPI2_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025) ++ ++/**************************************************************************** ++* SCSI IO Reply ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR (0x0040) ++#define MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE (0x0042) ++#define MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE (0x0043) ++#define MPI2_IOCSTATUS_SCSI_DATA_OVERRUN (0x0044) ++#define MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN (0x0045) ++#define MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR (0x0046) ++#define MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR (0x0047) ++#define MPI2_IOCSTATUS_SCSI_TASK_TERMINATED (0x0048) ++#define MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH (0x0049) ++#define MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED (0x004A) ++#define MPI2_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B) ++#define MPI2_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) ++ ++/**************************************************************************** ++* For use by SCSI Initiator and SCSI Target end-to-end data protection ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_EEDP_GUARD_ERROR (0x004D) ++#define MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E) ++#define MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F) ++ ++/**************************************************************************** ++* SCSI Target values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) ++#define MPI2_IOCSTATUS_TARGET_ABORTED (0x0063) ++#define MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) ++#define MPI2_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) ++#define MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A) ++#define MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D) ++#define MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E) ++#define MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F) ++#define MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT (0x0070) ++#define MPI2_IOCSTATUS_TARGET_NAK_RECEIVED (0x0071) ++ ++/**************************************************************************** ++* Serial Attached SCSI values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) ++#define MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN (0x0091) ++ ++/**************************************************************************** ++* Diagnostic Buffer Post / Diagnostic Release values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0) ++ ++/**************************************************************************** ++* RAID Accelerator values ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_RAID_ACCEL_ERROR (0x00B0) ++ ++/**************************************************************************** ++* IOCStatus flag to indicate that log info is available ++****************************************************************************/ ++ ++#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000) ++ ++/**************************************************************************** ++* IOCLogInfo Types ++****************************************************************************/ ++ ++#define MPI2_IOCLOGINFO_TYPE_MASK (0xF0000000) ++#define MPI2_IOCLOGINFO_TYPE_SHIFT (28) ++#define MPI2_IOCLOGINFO_TYPE_NONE (0x0) ++#define MPI2_IOCLOGINFO_TYPE_SCSI (0x1) ++#define MPI2_IOCLOGINFO_TYPE_FC (0x2) ++#define MPI2_IOCLOGINFO_TYPE_SAS (0x3) ++#define MPI2_IOCLOGINFO_TYPE_ISCSI (0x4) ++#define MPI2_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF) ++ ++/***************************************************************************** ++* ++* Standard Message Structures ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++*Request Message Header for all request messages ++****************************************************************************/ ++ ++typedef struct _MPI2_REQUEST_HEADER { ++ U16 FunctionDependent1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 FunctionDependent2; /*0x04 */ ++ U8 FunctionDependent3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++} MPI2_REQUEST_HEADER, *PTR_MPI2_REQUEST_HEADER, ++ MPI2RequestHeader_t, *pMPI2RequestHeader_t; ++ ++/**************************************************************************** ++* Default Reply ++****************************************************************************/ ++ ++typedef struct _MPI2_DEFAULT_REPLY { ++ U16 FunctionDependent1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 FunctionDependent2; /*0x04 */ ++ U8 FunctionDependent3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U16 FunctionDependent5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_DEFAULT_REPLY, *PTR_MPI2_DEFAULT_REPLY, ++ MPI2DefaultReply_t, *pMPI2DefaultReply_t; ++ ++/*common version structure/union used in messages and configuration pages */ ++ ++typedef struct _MPI2_VERSION_STRUCT { ++ U8 Dev; /*0x00 */ ++ U8 Unit; /*0x01 */ ++ U8 Minor; /*0x02 */ ++ U8 Major; /*0x03 */ ++} MPI2_VERSION_STRUCT; ++ ++typedef union _MPI2_VERSION_UNION { ++ MPI2_VERSION_STRUCT Struct; ++ U32 Word; ++} MPI2_VERSION_UNION; ++ ++/*LUN field defines, common to many structures */ ++#define MPI2_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF) ++#define MPI2_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000) ++#define MPI2_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF) ++#define MPI2_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000) ++#define MPI2_LUN_LEVEL_1_WORD (0xFF00) ++#define MPI2_LUN_LEVEL_1_DWORD (0x0000FF00) ++ ++/***************************************************************************** ++* ++* Fusion-MPT MPI Scatter Gather Elements ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* MPI Simple Element structures ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_SIMPLE32 { ++ U32 FlagsLength; ++ U32 Address; ++} MPI2_SGE_SIMPLE32, *PTR_MPI2_SGE_SIMPLE32, ++ Mpi2SGESimple32_t, *pMpi2SGESimple32_t; ++ ++typedef struct _MPI2_SGE_SIMPLE64 { ++ U32 FlagsLength; ++ U64 Address; ++} MPI2_SGE_SIMPLE64, *PTR_MPI2_SGE_SIMPLE64, ++ Mpi2SGESimple64_t, *pMpi2SGESimple64_t; ++ ++typedef struct _MPI2_SGE_SIMPLE_UNION { ++ U32 FlagsLength; ++ union { ++ U32 Address32; ++ U64 Address64; ++ } u; ++} MPI2_SGE_SIMPLE_UNION, ++ *PTR_MPI2_SGE_SIMPLE_UNION, ++ Mpi2SGESimpleUnion_t, ++ *pMpi2SGESimpleUnion_t; ++ ++/**************************************************************************** ++* MPI Chain Element structures - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_CHAIN32 { ++ U16 Length; ++ U8 NextChainOffset; ++ U8 Flags; ++ U32 Address; ++} MPI2_SGE_CHAIN32, *PTR_MPI2_SGE_CHAIN32, ++ Mpi2SGEChain32_t, *pMpi2SGEChain32_t; ++ ++typedef struct _MPI2_SGE_CHAIN64 { ++ U16 Length; ++ U8 NextChainOffset; ++ U8 Flags; ++ U64 Address; ++} MPI2_SGE_CHAIN64, *PTR_MPI2_SGE_CHAIN64, ++ Mpi2SGEChain64_t, *pMpi2SGEChain64_t; ++ ++typedef struct _MPI2_SGE_CHAIN_UNION { ++ U16 Length; ++ U8 NextChainOffset; ++ U8 Flags; ++ union { ++ U32 Address32; ++ U64 Address64; ++ } u; ++} MPI2_SGE_CHAIN_UNION, ++ *PTR_MPI2_SGE_CHAIN_UNION, ++ Mpi2SGEChainUnion_t, ++ *pMpi2SGEChainUnion_t; ++ ++/**************************************************************************** ++* MPI Transaction Context Element structures - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_TRANSACTION32 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[1]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION32, ++ *PTR_MPI2_SGE_TRANSACTION32, ++ Mpi2SGETransaction32_t, ++ *pMpi2SGETransaction32_t; ++ ++typedef struct _MPI2_SGE_TRANSACTION64 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[2]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION64, ++ *PTR_MPI2_SGE_TRANSACTION64, ++ Mpi2SGETransaction64_t, ++ *pMpi2SGETransaction64_t; ++ ++typedef struct _MPI2_SGE_TRANSACTION96 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[3]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION96, *PTR_MPI2_SGE_TRANSACTION96, ++ Mpi2SGETransaction96_t, *pMpi2SGETransaction96_t; ++ ++typedef struct _MPI2_SGE_TRANSACTION128 { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ U32 TransactionContext[4]; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION128, *PTR_MPI2_SGE_TRANSACTION128, ++ Mpi2SGETransaction_t128, *pMpi2SGETransaction_t128; ++ ++typedef struct _MPI2_SGE_TRANSACTION_UNION { ++ U8 Reserved; ++ U8 ContextSize; ++ U8 DetailsLength; ++ U8 Flags; ++ union { ++ U32 TransactionContext32[1]; ++ U32 TransactionContext64[2]; ++ U32 TransactionContext96[3]; ++ U32 TransactionContext128[4]; ++ } u; ++ U32 TransactionDetails[1]; ++} MPI2_SGE_TRANSACTION_UNION, ++ *PTR_MPI2_SGE_TRANSACTION_UNION, ++ Mpi2SGETransactionUnion_t, ++ *pMpi2SGETransactionUnion_t; ++ ++/**************************************************************************** ++* MPI SGE union for IO SGL's - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_MPI_SGE_IO_UNION { ++ union { ++ MPI2_SGE_SIMPLE_UNION Simple; ++ MPI2_SGE_CHAIN_UNION Chain; ++ } u; ++} MPI2_MPI_SGE_IO_UNION, *PTR_MPI2_MPI_SGE_IO_UNION, ++ Mpi2MpiSGEIOUnion_t, *pMpi2MpiSGEIOUnion_t; ++ ++/**************************************************************************** ++* MPI SGE union for SGL's with Simple and Transaction elements - for MPI v2.0 products only ++****************************************************************************/ ++ ++typedef struct _MPI2_SGE_TRANS_SIMPLE_UNION { ++ union { ++ MPI2_SGE_SIMPLE_UNION Simple; ++ MPI2_SGE_TRANSACTION_UNION Transaction; ++ } u; ++} MPI2_SGE_TRANS_SIMPLE_UNION, ++ *PTR_MPI2_SGE_TRANS_SIMPLE_UNION, ++ Mpi2SGETransSimpleUnion_t, ++ *pMpi2SGETransSimpleUnion_t; ++ ++/**************************************************************************** ++* All MPI SGE types union ++****************************************************************************/ ++ ++typedef struct _MPI2_MPI_SGE_UNION { ++ union { ++ MPI2_SGE_SIMPLE_UNION Simple; ++ MPI2_SGE_CHAIN_UNION Chain; ++ MPI2_SGE_TRANSACTION_UNION Transaction; ++ } u; ++} MPI2_MPI_SGE_UNION, *PTR_MPI2_MPI_SGE_UNION, ++ Mpi2MpiSgeUnion_t, *pMpi2MpiSgeUnion_t; ++ ++/**************************************************************************** ++* MPI SGE field definition and masks ++****************************************************************************/ ++ ++/*Flags field bit definitions */ ++ ++#define MPI2_SGE_FLAGS_LAST_ELEMENT (0x80) ++#define MPI2_SGE_FLAGS_END_OF_BUFFER (0x40) ++#define MPI2_SGE_FLAGS_ELEMENT_TYPE_MASK (0x30) ++#define MPI2_SGE_FLAGS_LOCAL_ADDRESS (0x08) ++#define MPI2_SGE_FLAGS_DIRECTION (0x04) ++#define MPI2_SGE_FLAGS_ADDRESS_SIZE (0x02) ++#define MPI2_SGE_FLAGS_END_OF_LIST (0x01) ++ ++#define MPI2_SGE_FLAGS_SHIFT (24) ++ ++#define MPI2_SGE_LENGTH_MASK (0x00FFFFFF) ++#define MPI2_SGE_CHAIN_LENGTH_MASK (0x0000FFFF) ++ ++/*Element Type */ ++ ++#define MPI2_SGE_FLAGS_TRANSACTION_ELEMENT (0x00) ++#define MPI2_SGE_FLAGS_SIMPLE_ELEMENT (0x10) ++#define MPI2_SGE_FLAGS_CHAIN_ELEMENT (0x30) ++#define MPI2_SGE_FLAGS_ELEMENT_MASK (0x30) ++ ++/*Address location */ ++ ++#define MPI2_SGE_FLAGS_SYSTEM_ADDRESS (0x00) ++ ++/*Direction */ ++ ++#define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00) ++#define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04) ++ ++#define MPI2_SGE_FLAGS_DEST (MPI2_SGE_FLAGS_IOC_TO_HOST) ++#define MPI2_SGE_FLAGS_SOURCE (MPI2_SGE_FLAGS_HOST_TO_IOC) ++ ++/*Address Size */ ++ ++#define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00) ++#define MPI2_SGE_FLAGS_64_BIT_ADDRESSING (0x02) ++ ++/*Context Size */ ++ ++#define MPI2_SGE_FLAGS_32_BIT_CONTEXT (0x00) ++#define MPI2_SGE_FLAGS_64_BIT_CONTEXT (0x02) ++#define MPI2_SGE_FLAGS_96_BIT_CONTEXT (0x04) ++#define MPI2_SGE_FLAGS_128_BIT_CONTEXT (0x06) ++ ++#define MPI2_SGE_CHAIN_OFFSET_MASK (0x00FF0000) ++#define MPI2_SGE_CHAIN_OFFSET_SHIFT (16) ++ ++/**************************************************************************** ++* MPI SGE operation Macros ++****************************************************************************/ ++ ++/*SIMPLE FlagsLength manipulations... */ ++#define MPI2_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_SGE_FLAGS_SHIFT) ++#define MPI2_SGE_GET_FLAGS(f) (((f) & ~MPI2_SGE_LENGTH_MASK) >> \ ++ MPI2_SGE_FLAGS_SHIFT) ++#define MPI2_SGE_LENGTH(f) ((f) & MPI2_SGE_LENGTH_MASK) ++#define MPI2_SGE_CHAIN_LENGTH(f) ((f) & MPI2_SGE_CHAIN_LENGTH_MASK) ++ ++#define MPI2_SGE_SET_FLAGS_LENGTH(f, l) (MPI2_SGE_SET_FLAGS(f) | \ ++ MPI2_SGE_LENGTH(l)) ++ ++#define MPI2_pSGE_GET_FLAGS(psg) MPI2_SGE_GET_FLAGS((psg)->FlagsLength) ++#define MPI2_pSGE_GET_LENGTH(psg) MPI2_SGE_LENGTH((psg)->FlagsLength) ++#define MPI2_pSGE_SET_FLAGS_LENGTH(psg, f, l) ((psg)->FlagsLength = \ ++ MPI2_SGE_SET_FLAGS_LENGTH(f, l)) ++ ++/*CAUTION - The following are READ-MODIFY-WRITE! */ ++#define MPI2_pSGE_SET_FLAGS(psg, f) ((psg)->FlagsLength |= \ ++ MPI2_SGE_SET_FLAGS(f)) ++#define MPI2_pSGE_SET_LENGTH(psg, l) ((psg)->FlagsLength |= \ ++ MPI2_SGE_LENGTH(l)) ++ ++#define MPI2_GET_CHAIN_OFFSET(x) ((x & MPI2_SGE_CHAIN_OFFSET_MASK) >> \ ++ MPI2_SGE_CHAIN_OFFSET_SHIFT) ++ ++/***************************************************************************** ++* ++* Fusion-MPT IEEE Scatter Gather Elements ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* IEEE Simple Element structures ++****************************************************************************/ ++ ++/*MPI2_IEEE_SGE_SIMPLE32 is for MPI v2.0 products only */ ++typedef struct _MPI2_IEEE_SGE_SIMPLE32 { ++ U32 Address; ++ U32 FlagsLength; ++} MPI2_IEEE_SGE_SIMPLE32, *PTR_MPI2_IEEE_SGE_SIMPLE32, ++ Mpi2IeeeSgeSimple32_t, *pMpi2IeeeSgeSimple32_t; ++ ++typedef struct _MPI2_IEEE_SGE_SIMPLE64 { ++ U64 Address; ++ U32 Length; ++ U16 Reserved1; ++ U8 Reserved2; ++ U8 Flags; ++} MPI2_IEEE_SGE_SIMPLE64, *PTR_MPI2_IEEE_SGE_SIMPLE64, ++ Mpi2IeeeSgeSimple64_t, *pMpi2IeeeSgeSimple64_t; ++ ++typedef union _MPI2_IEEE_SGE_SIMPLE_UNION { ++ MPI2_IEEE_SGE_SIMPLE32 Simple32; ++ MPI2_IEEE_SGE_SIMPLE64 Simple64; ++} MPI2_IEEE_SGE_SIMPLE_UNION, ++ *PTR_MPI2_IEEE_SGE_SIMPLE_UNION, ++ Mpi2IeeeSgeSimpleUnion_t, ++ *pMpi2IeeeSgeSimpleUnion_t; ++ ++/**************************************************************************** ++* IEEE Chain Element structures ++****************************************************************************/ ++ ++/*MPI2_IEEE_SGE_CHAIN32 is for MPI v2.0 products only */ ++typedef MPI2_IEEE_SGE_SIMPLE32 MPI2_IEEE_SGE_CHAIN32; ++ ++/*MPI2_IEEE_SGE_CHAIN64 is for MPI v2.0 products only */ ++typedef MPI2_IEEE_SGE_SIMPLE64 MPI2_IEEE_SGE_CHAIN64; ++ ++typedef union _MPI2_IEEE_SGE_CHAIN_UNION { ++ MPI2_IEEE_SGE_CHAIN32 Chain32; ++ MPI2_IEEE_SGE_CHAIN64 Chain64; ++} MPI2_IEEE_SGE_CHAIN_UNION, ++ *PTR_MPI2_IEEE_SGE_CHAIN_UNION, ++ Mpi2IeeeSgeChainUnion_t, ++ *pMpi2IeeeSgeChainUnion_t; ++ ++/*MPI25_IEEE_SGE_CHAIN64 is for MPI v2.5 and later */ ++typedef struct _MPI25_IEEE_SGE_CHAIN64 { ++ U64 Address; ++ U32 Length; ++ U16 Reserved1; ++ U8 NextChainOffset; ++ U8 Flags; ++} MPI25_IEEE_SGE_CHAIN64, ++ *PTR_MPI25_IEEE_SGE_CHAIN64, ++ Mpi25IeeeSgeChain64_t, ++ *pMpi25IeeeSgeChain64_t; ++ ++/**************************************************************************** ++* All IEEE SGE types union ++****************************************************************************/ ++ ++/*MPI2_IEEE_SGE_UNION is for MPI v2.0 products only */ ++typedef struct _MPI2_IEEE_SGE_UNION { ++ union { ++ MPI2_IEEE_SGE_SIMPLE_UNION Simple; ++ MPI2_IEEE_SGE_CHAIN_UNION Chain; ++ } u; ++} MPI2_IEEE_SGE_UNION, *PTR_MPI2_IEEE_SGE_UNION, ++ Mpi2IeeeSgeUnion_t, *pMpi2IeeeSgeUnion_t; ++ ++/**************************************************************************** ++* IEEE SGE union for IO SGL's ++****************************************************************************/ ++ ++typedef union _MPI25_SGE_IO_UNION { ++ MPI2_IEEE_SGE_SIMPLE64 IeeeSimple; ++ MPI25_IEEE_SGE_CHAIN64 IeeeChain; ++} MPI25_SGE_IO_UNION, *PTR_MPI25_SGE_IO_UNION, ++ Mpi25SGEIOUnion_t, *pMpi25SGEIOUnion_t; ++ ++/**************************************************************************** ++* IEEE SGE field definitions and masks ++****************************************************************************/ ++ ++/*Flags field bit definitions */ ++ ++#define MPI2_IEEE_SGE_FLAGS_ELEMENT_TYPE_MASK (0x80) ++#define MPI25_IEEE_SGE_FLAGS_END_OF_LIST (0x40) ++ ++#define MPI2_IEEE32_SGE_FLAGS_SHIFT (24) ++ ++#define MPI2_IEEE32_SGE_LENGTH_MASK (0x00FFFFFF) ++ ++/*Element Type */ ++ ++#define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT (0x00) ++#define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80) ++ ++/*Next Segment Format */ ++ ++#define MPI26_IEEE_SGE_FLAGS_NSF_MASK (0x1C) ++#define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE (0x00) ++ ++/*Data Location Address Space */ ++ ++#define MPI2_IEEE_SGE_FLAGS_ADDR_MASK (0x03) ++#define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00) ++#define MPI2_IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01) ++#define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02) ++#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03) ++#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR (0x03) ++#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR \ ++ (MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR) ++#define MPI26_IEEE_SGE_FLAGS_IOCCTL_ADDR (0x02) ++ ++/**************************************************************************** ++* IEEE SGE operation Macros ++****************************************************************************/ ++ ++/*SIMPLE FlagsLength manipulations... */ ++#define MPI2_IEEE32_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_IEEE32_SGE_FLAGS_SHIFT) ++#define MPI2_IEEE32_SGE_GET_FLAGS(f) (((f) & ~MPI2_IEEE32_SGE_LENGTH_MASK) \ ++ >> MPI2_IEEE32_SGE_FLAGS_SHIFT) ++#define MPI2_IEEE32_SGE_LENGTH(f) ((f) & MPI2_IEEE32_SGE_LENGTH_MASK) ++ ++#define MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l) (MPI2_IEEE32_SGE_SET_FLAGS(f) |\ ++ MPI2_IEEE32_SGE_LENGTH(l)) ++ ++#define MPI2_IEEE32_pSGE_GET_FLAGS(psg) \ ++ MPI2_IEEE32_SGE_GET_FLAGS((psg)->FlagsLength) ++#define MPI2_IEEE32_pSGE_GET_LENGTH(psg) \ ++ MPI2_IEEE32_SGE_LENGTH((psg)->FlagsLength) ++#define MPI2_IEEE32_pSGE_SET_FLAGS_LENGTH(psg, f, l) ((psg)->FlagsLength = \ ++ MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l)) ++ ++/*CAUTION - The following are READ-MODIFY-WRITE! */ ++#define MPI2_IEEE32_pSGE_SET_FLAGS(psg, f) ((psg)->FlagsLength |= \ ++ MPI2_IEEE32_SGE_SET_FLAGS(f)) ++#define MPI2_IEEE32_pSGE_SET_LENGTH(psg, l) ((psg)->FlagsLength |= \ ++ MPI2_IEEE32_SGE_LENGTH(l)) ++ ++/***************************************************************************** ++* ++* Fusion-MPT MPI/IEEE Scatter Gather Unions ++* ++*****************************************************************************/ ++ ++typedef union _MPI2_SIMPLE_SGE_UNION { ++ MPI2_SGE_SIMPLE_UNION MpiSimple; ++ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; ++} MPI2_SIMPLE_SGE_UNION, *PTR_MPI2_SIMPLE_SGE_UNION, ++ Mpi2SimpleSgeUntion_t, *pMpi2SimpleSgeUntion_t; ++ ++typedef union _MPI2_SGE_IO_UNION { ++ MPI2_SGE_SIMPLE_UNION MpiSimple; ++ MPI2_SGE_CHAIN_UNION MpiChain; ++ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; ++ MPI2_IEEE_SGE_CHAIN_UNION IeeeChain; ++} MPI2_SGE_IO_UNION, *PTR_MPI2_SGE_IO_UNION, ++ Mpi2SGEIOUnion_t, *pMpi2SGEIOUnion_t; ++ ++/**************************************************************************** ++* ++* Values for SGLFlags field, used in many request messages with an SGL ++* ++****************************************************************************/ ++ ++/*values for MPI SGL Data Location Address Space subfield */ ++#define MPI2_SGLFLAGS_ADDRESS_SPACE_MASK (0x0C) ++#define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE (0x00) ++#define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE (0x04) ++#define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) ++#define MPI26_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) ++#define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE (0x0C) ++/*values for SGL Type subfield */ ++#define MPI2_SGLFLAGS_SGL_TYPE_MASK (0x03) ++#define MPI2_SGLFLAGS_SGL_TYPE_MPI (0x00) ++#define MPI2_SGLFLAGS_SGL_TYPE_IEEE32 (0x01) ++#define MPI2_SGLFLAGS_SGL_TYPE_IEEE64 (0x02) ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +new file mode 100644 +index 0000000..95356a8 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h +@@ -0,0 +1,3493 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_cnfg.h ++ * Title: MPI Configuration messages and pages ++ * Creation Date: November 10, 2006 ++ * ++ * mpi2_cnfg.h Version: 02.00.35 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-04-07 02.00.01 Added defines for SAS IO Unit Page 2 PhyFlags. ++ * Added Manufacturing Page 11. ++ * Added MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE ++ * define. ++ * 06-26-07 02.00.02 Adding generic structure for product-specific ++ * Manufacturing pages: MPI2_CONFIG_PAGE_MANUFACTURING_PS. ++ * Rework of BIOS Page 2 configuration page. ++ * Fixed MPI2_BIOSPAGE2_BOOT_DEVICE to be a union of the ++ * forms. ++ * Added configuration pages IOC Page 8 and Driver ++ * Persistent Mapping Page 0. ++ * 08-31-07 02.00.03 Modified configuration pages dealing with Integrated ++ * RAID (Manufacturing Page 4, RAID Volume Pages 0 and 1, ++ * RAID Physical Disk Pages 0 and 1, RAID Configuration ++ * Page 0). ++ * Added new value for AccessStatus field of SAS Device ++ * Page 0 (_SATA_NEEDS_INITIALIZATION). ++ * 10-31-07 02.00.04 Added missing SEPDevHandle field to ++ * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. ++ * 12-18-07 02.00.05 Modified IO Unit Page 0 to use 32-bit version fields for ++ * NVDATA. ++ * Modified IOC Page 7 to use masks and added field for ++ * SASBroadcastPrimitiveMasks. ++ * Added MPI2_CONFIG_PAGE_BIOS_4. ++ * Added MPI2_CONFIG_PAGE_LOG_0. ++ * 02-29-08 02.00.06 Modified various names to make them 32-character unique. ++ * Added SAS Device IDs. ++ * Updated Integrated RAID configuration pages including ++ * Manufacturing Page 4, IOC Page 6, and RAID Configuration ++ * Page 0. ++ * 05-21-08 02.00.07 Added define MPI2_MANPAGE4_MIX_SSD_SAS_SATA. ++ * Added define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION. ++ * Fixed define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING. ++ * Added missing MaxNumRoutedSasAddresses field to ++ * MPI2_CONFIG_PAGE_EXPANDER_0. ++ * Added SAS Port Page 0. ++ * Modified structure layout for ++ * MPI2_CONFIG_PAGE_DRIVER_MAPPING_0. ++ * 06-27-08 02.00.08 Changed MPI2_CONFIG_PAGE_RD_PDISK_1 to use ++ * MPI2_RAID_PHYS_DISK1_PATH_MAX to size the array. ++ * 10-02-08 02.00.09 Changed MPI2_RAID_PGAD_CONFIGNUM_MASK from 0x0000FFFF ++ * to 0x000000FF. ++ * Added two new values for the Physical Disk Coercion Size ++ * bits in the Flags field of Manufacturing Page 4. ++ * Added product-specific Manufacturing pages 16 to 31. ++ * Modified Flags bits for controlling write cache on SATA ++ * drives in IO Unit Page 1. ++ * Added new bit to AdditionalControlFlags of SAS IO Unit ++ * Page 1 to control Invalid Topology Correction. ++ * Added additional defines for RAID Volume Page 0 ++ * VolumeStatusFlags field. ++ * Modified meaning of RAID Volume Page 0 VolumeSettings ++ * define for auto-configure of hot-swap drives. ++ * Added SupportedPhysDisks field to RAID Volume Page 1 and ++ * added related defines. ++ * Added PhysDiskAttributes field (and related defines) to ++ * RAID Physical Disk Page 0. ++ * Added MPI2_SAS_PHYINFO_PHY_VACANT define. ++ * Added three new DiscoveryStatus bits for SAS IO Unit ++ * Page 0 and SAS Expander Page 0. ++ * Removed multiplexing information from SAS IO Unit pages. ++ * Added BootDeviceWaitTime field to SAS IO Unit Page 4. ++ * Removed Zone Address Resolved bit from PhyInfo and from ++ * Expander Page 0 Flags field. ++ * Added two new AccessStatus values to SAS Device Page 0 ++ * for indicating routing problems. Added 3 reserved words ++ * to this page. ++ * 01-19-09 02.00.10 Fixed defines for GPIOVal field of IO Unit Page 3. ++ * Inserted missing reserved field into structure for IOC ++ * Page 6. ++ * Added more pending task bits to RAID Volume Page 0 ++ * VolumeStatusFlags defines. ++ * Added MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED define. ++ * Added a new DiscoveryStatus bit for SAS IO Unit Page 0 ++ * and SAS Expander Page 0 to flag a downstream initiator ++ * when in simplified routing mode. ++ * Removed SATA Init Failure defines for DiscoveryStatus ++ * fields of SAS IO Unit Page 0 and SAS Expander Page 0. ++ * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define. ++ * Added PortGroups, DmaGroup, and ControlGroup fields to ++ * SAS Device Page 0. ++ * 05-06-09 02.00.11 Added structures and defines for IO Unit Page 5 and IO ++ * Unit Page 6. ++ * Added expander reduced functionality data to SAS ++ * Expander Page 0. ++ * Added SAS PHY Page 2 and SAS PHY Page 3. ++ * 07-30-09 02.00.12 Added IO Unit Page 7. ++ * Added new device ids. ++ * Added SAS IO Unit Page 5. ++ * Added partial and slumber power management capable flags ++ * to SAS Device Page 0 Flags field. ++ * Added PhyInfo defines for power condition. ++ * Added Ethernet configuration pages. ++ * 10-28-09 02.00.13 Added MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY. ++ * Added SAS PHY Page 4 structure and defines. ++ * 02-10-10 02.00.14 Modified the comments for the configuration page ++ * structures that contain an array of data. The host ++ * should use the "count" field in the page data (e.g. the ++ * NumPhys field) to determine the number of valid elements ++ * in the array. ++ * Added/modified some MPI2_MFGPAGE_DEVID_SAS defines. ++ * Added PowerManagementCapabilities to IO Unit Page 7. ++ * Added PortWidthModGroup field to ++ * MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS. ++ * Added MPI2_CONFIG_PAGE_SASIOUNIT_6 and related defines. ++ * Added MPI2_CONFIG_PAGE_SASIOUNIT_7 and related defines. ++ * Added MPI2_CONFIG_PAGE_SASIOUNIT_8 and related defines. ++ * 05-12-10 02.00.15 Added MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT ++ * define. ++ * Added MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE define. ++ * Added MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY define. ++ * 08-11-10 02.00.16 Removed IO Unit Page 1 device path (multi-pathing) ++ * defines. ++ * 11-10-10 02.00.17 Added ReceptacleID field (replacing Reserved1) to ++ * MPI2_MANPAGE7_CONNECTOR_INFO and reworked defines for ++ * the Pinout field. ++ * Added BoardTemperature and BoardTemperatureUnits fields ++ * to MPI2_CONFIG_PAGE_IO_UNIT_7. ++ * Added MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING define ++ * and MPI2_CONFIG_PAGE_EXT_MAN_PS structure. ++ * 02-23-11 02.00.18 Added ProxyVF_ID field to MPI2_CONFIG_REQUEST. ++ * Added IO Unit Page 8, IO Unit Page 9, ++ * and IO Unit Page 10. ++ * Added SASNotifyPrimitiveMasks field to ++ * MPI2_CONFIG_PAGE_IOC_7. ++ * 03-09-11 02.00.19 Fixed IO Unit Page 10 (to match the spec). ++ * 05-25-11 02.00.20 Cleaned up a few comments. ++ * 08-24-11 02.00.21 Marked the IO Unit Page 7 PowerManagementCapabilities ++ * for PCIe link as obsolete. ++ * Added SpinupFlags field containing a Disable Spin-up bit ++ * to the MPI2_SAS_IOUNIT4_SPINUP_GROUP fields of SAS IO ++ * Unit Page 4. ++ * 11-18-11 02.00.22 Added define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT. ++ * Added UEFIVersion field to BIOS Page 1 and defined new ++ * BiosOptions bits. ++ * Incorporating additions for MPI v2.5. ++ * 11-27-12 02.00.23 Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER. ++ * Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID. ++ * 12-20-12 02.00.24 Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as ++ * obsolete for MPI v2.5 and later. ++ * Added some defines for 12G SAS speeds. ++ * 04-09-13 02.00.25 Added MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK. ++ * Fixed MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS to ++ * match the specification. ++ * 08-19-13 02.00.26 Added reserved words to MPI2_CONFIG_PAGE_IO_UNIT_7 for ++ * future use. ++ * 12-05-13 02.00.27 Added MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL for ++ * MPI2_CONFIG_PAGE_MAN_7. ++ * Added EnclosureLevel and ConnectorName fields to ++ * MPI2_CONFIG_PAGE_SAS_DEV_0. ++ * Added MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID for ++ * MPI2_CONFIG_PAGE_SAS_DEV_0. ++ * Added EnclosureLevel field to ++ * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. ++ * Added MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID for ++ * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. ++ * 01-08-14 02.00.28 Added more defines for the BiosOptions field of ++ * MPI2_CONFIG_PAGE_BIOS_1. ++ * 06-13-14 02.00.29 Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and ++ * more defines for the BiosOptions field. ++ * 11-18-14 02.00.30 Updated copyright information. ++ * Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG. ++ * Added AdapterOrderAux fields to BIOS Page 3. ++ * 03-16-15 02.00.31 Updated for MPI v2.6. ++ * Added Flags field to IO Unit Page 7. ++ * Added new SAS Phy Event codes ++ * 05-25-15 02.00.33 Added more defines for the BiosOptions field of ++ * MPI2_CONFIG_PAGE_BIOS_1. ++ * 08-25-15 02.00.34 Bumped Header Version. ++ * 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_CNFG_H ++#define MPI2_CNFG_H ++ ++/***************************************************************************** ++* Configuration Page Header and defines ++*****************************************************************************/ ++ ++/*Config Page Header */ ++typedef struct _MPI2_CONFIG_PAGE_HEADER { ++ U8 PageVersion; /*0x00 */ ++ U8 PageLength; /*0x01 */ ++ U8 PageNumber; /*0x02 */ ++ U8 PageType; /*0x03 */ ++} MPI2_CONFIG_PAGE_HEADER, *PTR_MPI2_CONFIG_PAGE_HEADER, ++ Mpi2ConfigPageHeader_t, *pMpi2ConfigPageHeader_t; ++ ++typedef union _MPI2_CONFIG_PAGE_HEADER_UNION { ++ MPI2_CONFIG_PAGE_HEADER Struct; ++ U8 Bytes[4]; ++ U16 Word16[2]; ++ U32 Word32; ++} MPI2_CONFIG_PAGE_HEADER_UNION, *PTR_MPI2_CONFIG_PAGE_HEADER_UNION, ++ Mpi2ConfigPageHeaderUnion, *pMpi2ConfigPageHeaderUnion; ++ ++/*Extended Config Page Header */ ++typedef struct _MPI2_CONFIG_EXTENDED_PAGE_HEADER { ++ U8 PageVersion; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 PageNumber; /*0x02 */ ++ U8 PageType; /*0x03 */ ++ U16 ExtPageLength; /*0x04 */ ++ U8 ExtPageType; /*0x06 */ ++ U8 Reserved2; /*0x07 */ ++} MPI2_CONFIG_EXTENDED_PAGE_HEADER, ++ *PTR_MPI2_CONFIG_EXTENDED_PAGE_HEADER, ++ Mpi2ConfigExtendedPageHeader_t, ++ *pMpi2ConfigExtendedPageHeader_t; ++ ++typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION { ++ MPI2_CONFIG_PAGE_HEADER Struct; ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Ext; ++ U8 Bytes[8]; ++ U16 Word16[4]; ++ U32 Word32[2]; ++} MPI2_CONFIG_EXT_PAGE_HEADER_UNION, ++ *PTR_MPI2_CONFIG_EXT_PAGE_HEADER_UNION, ++ Mpi2ConfigPageExtendedHeaderUnion, ++ *pMpi2ConfigPageExtendedHeaderUnion; ++ ++ ++/*PageType field values */ ++#define MPI2_CONFIG_PAGEATTR_READ_ONLY (0x00) ++#define MPI2_CONFIG_PAGEATTR_CHANGEABLE (0x10) ++#define MPI2_CONFIG_PAGEATTR_PERSISTENT (0x20) ++#define MPI2_CONFIG_PAGEATTR_MASK (0xF0) ++ ++#define MPI2_CONFIG_PAGETYPE_IO_UNIT (0x00) ++#define MPI2_CONFIG_PAGETYPE_IOC (0x01) ++#define MPI2_CONFIG_PAGETYPE_BIOS (0x02) ++#define MPI2_CONFIG_PAGETYPE_RAID_VOLUME (0x08) ++#define MPI2_CONFIG_PAGETYPE_MANUFACTURING (0x09) ++#define MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A) ++#define MPI2_CONFIG_PAGETYPE_EXTENDED (0x0F) ++#define MPI2_CONFIG_PAGETYPE_MASK (0x0F) ++ ++#define MPI2_CONFIG_TYPENUM_MASK (0x0FFF) ++ ++ ++/*ExtPageType field values */ ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT (0x10) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER (0x11) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE (0x12) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_PHY (0x13) ++#define MPI2_CONFIG_EXTPAGETYPE_LOG (0x14) ++#define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE (0x15) ++#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16) ++#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17) ++#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18) ++#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET (0x19) ++#define MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING (0x1A) ++ ++ ++/***************************************************************************** ++* PageAddress defines ++*****************************************************************************/ ++ ++/*RAID Volume PageAddress format */ ++#define MPI2_RAID_VOLUME_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) ++#define MPI2_RAID_VOLUME_PGAD_FORM_HANDLE (0x10000000) ++ ++#define MPI2_RAID_VOLUME_PGAD_HANDLE_MASK (0x0000FFFF) ++ ++ ++/*RAID Physical Disk PageAddress format */ ++#define MPI2_PHYSDISK_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM (0x00000000) ++#define MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM (0x10000000) ++#define MPI2_PHYSDISK_PGAD_FORM_DEVHANDLE (0x20000000) ++ ++#define MPI2_PHYSDISK_PGAD_PHYSDISKNUM_MASK (0x000000FF) ++#define MPI2_PHYSDISK_PGAD_DEVHANDLE_MASK (0x0000FFFF) ++ ++ ++/*SAS Expander PageAddress format */ ++#define MPI2_SAS_EXPAND_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL (0x00000000) ++#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM (0x10000000) ++#define MPI2_SAS_EXPAND_PGAD_FORM_HNDL (0x20000000) ++ ++#define MPI2_SAS_EXPAND_PGAD_HANDLE_MASK (0x0000FFFF) ++#define MPI2_SAS_EXPAND_PGAD_PHYNUM_MASK (0x00FF0000) ++#define MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT (16) ++ ++ ++/*SAS Device PageAddress format */ ++#define MPI2_SAS_DEVICE_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) ++#define MPI2_SAS_DEVICE_PGAD_FORM_HANDLE (0x20000000) ++ ++#define MPI2_SAS_DEVICE_PGAD_HANDLE_MASK (0x0000FFFF) ++ ++ ++/*SAS PHY PageAddress format */ ++#define MPI2_SAS_PHY_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER (0x00000000) ++#define MPI2_SAS_PHY_PGAD_FORM_PHY_TBL_INDEX (0x10000000) ++ ++#define MPI2_SAS_PHY_PGAD_PHY_NUMBER_MASK (0x000000FF) ++#define MPI2_SAS_PHY_PGAD_PHY_TBL_INDEX_MASK (0x0000FFFF) ++ ++ ++/*SAS Port PageAddress format */ ++#define MPI2_SASPORT_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SASPORT_PGAD_FORM_GET_NEXT_PORT (0x00000000) ++#define MPI2_SASPORT_PGAD_FORM_PORT_NUM (0x10000000) ++ ++#define MPI2_SASPORT_PGAD_PORTNUMBER_MASK (0x00000FFF) ++ ++ ++/*SAS Enclosure PageAddress format */ ++#define MPI2_SAS_ENCLOS_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE (0x00000000) ++#define MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE (0x10000000) ++ ++#define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK (0x0000FFFF) ++ ++ ++/*RAID Configuration PageAddress format */ ++#define MPI2_RAID_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM (0x00000000) ++#define MPI2_RAID_PGAD_FORM_CONFIGNUM (0x10000000) ++#define MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG (0x20000000) ++ ++#define MPI2_RAID_PGAD_CONFIGNUM_MASK (0x000000FF) ++ ++ ++/*Driver Persistent Mapping PageAddress format */ ++#define MPI2_DPM_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_DPM_PGAD_FORM_ENTRY_RANGE (0x00000000) ++ ++#define MPI2_DPM_PGAD_ENTRY_COUNT_MASK (0x0FFF0000) ++#define MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT (16) ++#define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF) ++ ++ ++/*Ethernet PageAddress format */ ++#define MPI2_ETHERNET_PGAD_FORM_MASK (0xF0000000) ++#define MPI2_ETHERNET_PGAD_FORM_IF_NUM (0x00000000) ++ ++#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF) ++ ++ ++/**************************************************************************** ++* Configuration messages ++****************************************************************************/ ++ ++/*Configuration Request Message */ ++typedef struct _MPI2_CONFIG_REQUEST { ++ U8 Action; /*0x00 */ ++ U8 SGLFlags; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 ExtPageLength; /*0x04 */ ++ U8 ExtPageType; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U8 Reserved2; /*0x0C */ ++ U8 ProxyVF_ID; /*0x0D */ ++ U16 Reserved4; /*0x0E */ ++ U32 Reserved3; /*0x10 */ ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x14 */ ++ U32 PageAddress; /*0x18 */ ++ MPI2_SGE_IO_UNION PageBufferSGE; /*0x1C */ ++} MPI2_CONFIG_REQUEST, *PTR_MPI2_CONFIG_REQUEST, ++ Mpi2ConfigRequest_t, *pMpi2ConfigRequest_t; ++ ++/*values for the Action field */ ++#define MPI2_CONFIG_ACTION_PAGE_HEADER (0x00) ++#define MPI2_CONFIG_ACTION_PAGE_READ_CURRENT (0x01) ++#define MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT (0x02) ++#define MPI2_CONFIG_ACTION_PAGE_DEFAULT (0x03) ++#define MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM (0x04) ++#define MPI2_CONFIG_ACTION_PAGE_READ_DEFAULT (0x05) ++#define MPI2_CONFIG_ACTION_PAGE_READ_NVRAM (0x06) ++#define MPI2_CONFIG_ACTION_PAGE_GET_CHANGEABLE (0x07) ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++ ++/*Config Reply Message */ ++typedef struct _MPI2_CONFIG_REPLY { ++ U8 Action; /*0x00 */ ++ U8 SGLFlags; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 ExtPageLength; /*0x04 */ ++ U8 ExtPageType; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U16 Reserved2; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x14 */ ++} MPI2_CONFIG_REPLY, *PTR_MPI2_CONFIG_REPLY, ++ Mpi2ConfigReply_t, *pMpi2ConfigReply_t; ++ ++ ++ ++/***************************************************************************** ++* ++* C o n f i g u r a t i o n P a g e s ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* Manufacturing Config pages ++****************************************************************************/ ++ ++#define MPI2_MFGPAGE_VENDORID_LSI (0x1000) ++ ++/*MPI v2.0 SAS products */ ++#define MPI2_MFGPAGE_DEVID_SAS2004 (0x0070) ++#define MPI2_MFGPAGE_DEVID_SAS2008 (0x0072) ++#define MPI2_MFGPAGE_DEVID_SAS2108_1 (0x0074) ++#define MPI2_MFGPAGE_DEVID_SAS2108_2 (0x0076) ++#define MPI2_MFGPAGE_DEVID_SAS2108_3 (0x0077) ++#define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) ++#define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) ++ ++#define MPI2_MFGPAGE_DEVID_SSS6200 (0x007E) ++ ++#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) ++#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) ++#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) ++#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083) ++#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084) ++#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085) ++#define MPI2_MFGPAGE_DEVID_SAS2308_1 (0x0086) ++#define MPI2_MFGPAGE_DEVID_SAS2308_2 (0x0087) ++#define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E) ++ ++/*MPI v2.5 SAS products */ ++#define MPI25_MFGPAGE_DEVID_SAS3004 (0x0096) ++#define MPI25_MFGPAGE_DEVID_SAS3008 (0x0097) ++#define MPI25_MFGPAGE_DEVID_SAS3108_1 (0x0090) ++#define MPI25_MFGPAGE_DEVID_SAS3108_2 (0x0091) ++#define MPI25_MFGPAGE_DEVID_SAS3108_5 (0x0094) ++#define MPI25_MFGPAGE_DEVID_SAS3108_6 (0x0095) ++ ++/* MPI v2.6 SAS Products */ ++#define MPI26_MFGPAGE_DEVID_SAS3216 (0x00C9) ++#define MPI26_MFGPAGE_DEVID_SAS3224 (0x00C4) ++#define MPI26_MFGPAGE_DEVID_SAS3316_1 (0x00C5) ++#define MPI26_MFGPAGE_DEVID_SAS3316_2 (0x00C6) ++#define MPI26_MFGPAGE_DEVID_SAS3316_3 (0x00C7) ++#define MPI26_MFGPAGE_DEVID_SAS3316_4 (0x00C8) ++#define MPI26_MFGPAGE_DEVID_SAS3324_1 (0x00C0) ++#define MPI26_MFGPAGE_DEVID_SAS3324_2 (0x00C1) ++#define MPI26_MFGPAGE_DEVID_SAS3324_3 (0x00C2) ++#define MPI26_MFGPAGE_DEVID_SAS3324_4 (0x00C3) ++ ++/*Manufacturing Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 ChipName[16]; /*0x04 */ ++ U8 ChipRevision[8]; /*0x14 */ ++ U8 BoardName[16]; /*0x1C */ ++ U8 BoardAssembly[16]; /*0x2C */ ++ U8 BoardTracerNumber[16]; /*0x3C */ ++} MPI2_CONFIG_PAGE_MAN_0, ++ *PTR_MPI2_CONFIG_PAGE_MAN_0, ++ Mpi2ManufacturingPage0_t, ++ *pMpi2ManufacturingPage0_t; ++ ++#define MPI2_MANUFACTURING0_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 VPD[256]; /*0x04 */ ++} MPI2_CONFIG_PAGE_MAN_1, ++ *PTR_MPI2_CONFIG_PAGE_MAN_1, ++ Mpi2ManufacturingPage1_t, ++ *pMpi2ManufacturingPage1_t; ++ ++#define MPI2_MANUFACTURING1_PAGEVERSION (0x00) ++ ++ ++typedef struct _MPI2_CHIP_REVISION_ID { ++ U16 DeviceID; /*0x00 */ ++ U8 PCIRevisionID; /*0x02 */ ++ U8 Reserved; /*0x03 */ ++} MPI2_CHIP_REVISION_ID, *PTR_MPI2_CHIP_REVISION_ID, ++ Mpi2ChipRevisionId_t, *pMpi2ChipRevisionId_t; ++ ++ ++/*Manufacturing Page 2 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check Header.PageLength at runtime. ++ */ ++#ifndef MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS ++#define MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_2 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ MPI2_CHIP_REVISION_ID ChipId; /*0x04 */ ++ U32 ++ HwSettings[MPI2_MAN_PAGE_2_HW_SETTINGS_WORDS];/*0x08 */ ++} MPI2_CONFIG_PAGE_MAN_2, ++ *PTR_MPI2_CONFIG_PAGE_MAN_2, ++ Mpi2ManufacturingPage2_t, ++ *pMpi2ManufacturingPage2_t; ++ ++#define MPI2_MANUFACTURING2_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 3 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check Header.PageLength at runtime. ++ */ ++#ifndef MPI2_MAN_PAGE_3_INFO_WORDS ++#define MPI2_MAN_PAGE_3_INFO_WORDS (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_3 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ MPI2_CHIP_REVISION_ID ChipId; /*0x04 */ ++ U32 ++ Info[MPI2_MAN_PAGE_3_INFO_WORDS];/*0x08 */ ++} MPI2_CONFIG_PAGE_MAN_3, ++ *PTR_MPI2_CONFIG_PAGE_MAN_3, ++ Mpi2ManufacturingPage3_t, ++ *pMpi2ManufacturingPage3_t; ++ ++#define MPI2_MANUFACTURING3_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 4 */ ++ ++typedef struct _MPI2_MANPAGE4_PWR_SAVE_SETTINGS { ++ U8 PowerSaveFlags; /*0x00 */ ++ U8 InternalOperationsSleepTime; /*0x01 */ ++ U8 InternalOperationsRunTime; /*0x02 */ ++ U8 HostIdleTime; /*0x03 */ ++} MPI2_MANPAGE4_PWR_SAVE_SETTINGS, ++ *PTR_MPI2_MANPAGE4_PWR_SAVE_SETTINGS, ++ Mpi2ManPage4PwrSaveSettings_t, ++ *pMpi2ManPage4PwrSaveSettings_t; ++ ++/*defines for the PowerSaveFlags field */ ++#define MPI2_MANPAGE4_MASK_POWERSAVE_MODE (0x03) ++#define MPI2_MANPAGE4_POWERSAVE_MODE_DISABLED (0x00) ++#define MPI2_MANPAGE4_CUSTOM_POWERSAVE_MODE (0x01) ++#define MPI2_MANPAGE4_FULL_POWERSAVE_MODE (0x02) ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_4 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Flags; /*0x08 */ ++ U8 InquirySize; /*0x0C */ ++ U8 Reserved2; /*0x0D */ ++ U16 Reserved3; /*0x0E */ ++ U8 InquiryData[56]; /*0x10 */ ++ U32 RAID0VolumeSettings; /*0x48 */ ++ U32 RAID1EVolumeSettings; /*0x4C */ ++ U32 RAID1VolumeSettings; /*0x50 */ ++ U32 RAID10VolumeSettings; /*0x54 */ ++ U32 Reserved4; /*0x58 */ ++ U32 Reserved5; /*0x5C */ ++ MPI2_MANPAGE4_PWR_SAVE_SETTINGS PowerSaveSettings; /*0x60 */ ++ U8 MaxOCEDisks; /*0x64 */ ++ U8 ResyncRate; /*0x65 */ ++ U16 DataScrubDuration; /*0x66 */ ++ U8 MaxHotSpares; /*0x68 */ ++ U8 MaxPhysDisksPerVol; /*0x69 */ ++ U8 MaxPhysDisks; /*0x6A */ ++ U8 MaxVolumes; /*0x6B */ ++} MPI2_CONFIG_PAGE_MAN_4, ++ *PTR_MPI2_CONFIG_PAGE_MAN_4, ++ Mpi2ManufacturingPage4_t, ++ *pMpi2ManufacturingPage4_t; ++ ++#define MPI2_MANUFACTURING4_PAGEVERSION (0x0A) ++ ++/*Manufacturing Page 4 Flags field */ ++#define MPI2_MANPAGE4_METADATA_SIZE_MASK (0x00030000) ++#define MPI2_MANPAGE4_METADATA_512MB (0x00000000) ++ ++#define MPI2_MANPAGE4_MIX_SSD_SAS_SATA (0x00008000) ++#define MPI2_MANPAGE4_MIX_SSD_AND_NON_SSD (0x00004000) ++#define MPI2_MANPAGE4_HIDE_PHYSDISK_NON_IR (0x00002000) ++ ++#define MPI2_MANPAGE4_MASK_PHYSDISK_COERCION (0x00001C00) ++#define MPI2_MANPAGE4_PHYSDISK_COERCION_1GB (0x00000000) ++#define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION (0x00000400) ++#define MPI2_MANPAGE4_PHYSDISK_ADAPTIVE_COERCION (0x00000800) ++#define MPI2_MANPAGE4_PHYSDISK_ZERO_COERCION (0x00000C00) ++ ++#define MPI2_MANPAGE4_MASK_BAD_BLOCK_MARKING (0x00000300) ++#define MPI2_MANPAGE4_DEFAULT_BAD_BLOCK_MARKING (0x00000000) ++#define MPI2_MANPAGE4_TABLE_BAD_BLOCK_MARKING (0x00000100) ++#define MPI2_MANPAGE4_WRITE_LONG_BAD_BLOCK_MARKING (0x00000200) ++ ++#define MPI2_MANPAGE4_FORCE_OFFLINE_FAILOVER (0x00000080) ++#define MPI2_MANPAGE4_RAID10_DISABLE (0x00000040) ++#define MPI2_MANPAGE4_RAID1E_DISABLE (0x00000020) ++#define MPI2_MANPAGE4_RAID1_DISABLE (0x00000010) ++#define MPI2_MANPAGE4_RAID0_DISABLE (0x00000008) ++#define MPI2_MANPAGE4_IR_MODEPAGE8_DISABLE (0x00000004) ++#define MPI2_MANPAGE4_IM_RESYNC_CACHE_ENABLE (0x00000002) ++#define MPI2_MANPAGE4_IR_NO_MIX_SAS_SATA (0x00000001) ++ ++ ++/*Manufacturing Page 5 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_MAN_PAGE_5_PHY_ENTRIES ++#define MPI2_MAN_PAGE_5_PHY_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_MANUFACTURING5_ENTRY { ++ U64 WWID; /*0x00 */ ++ U64 DeviceName; /*0x08 */ ++} MPI2_MANUFACTURING5_ENTRY, ++ *PTR_MPI2_MANUFACTURING5_ENTRY, ++ Mpi2Manufacturing5Entry_t, ++ *pMpi2Manufacturing5Entry_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_5 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhys; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++ MPI2_MANUFACTURING5_ENTRY ++ Phy[MPI2_MAN_PAGE_5_PHY_ENTRIES];/*0x08 */ ++} MPI2_CONFIG_PAGE_MAN_5, ++ *PTR_MPI2_CONFIG_PAGE_MAN_5, ++ Mpi2ManufacturingPage5_t, ++ *pMpi2ManufacturingPage5_t; ++ ++#define MPI2_MANUFACTURING5_PAGEVERSION (0x03) ++ ++ ++/*Manufacturing Page 6 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_6 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 ProductSpecificInfo;/*0x04 */ ++} MPI2_CONFIG_PAGE_MAN_6, ++ *PTR_MPI2_CONFIG_PAGE_MAN_6, ++ Mpi2ManufacturingPage6_t, ++ *pMpi2ManufacturingPage6_t; ++ ++#define MPI2_MANUFACTURING6_PAGEVERSION (0x00) ++ ++ ++/*Manufacturing Page 7 */ ++ ++typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO { ++ U32 Pinout; /*0x00 */ ++ U8 Connector[16]; /*0x04 */ ++ U8 Location; /*0x14 */ ++ U8 ReceptacleID; /*0x15 */ ++ U16 Slot; /*0x16 */ ++ U32 Reserved2; /*0x18 */ ++} MPI2_MANPAGE7_CONNECTOR_INFO, ++ *PTR_MPI2_MANPAGE7_CONNECTOR_INFO, ++ Mpi2ManPage7ConnectorInfo_t, ++ *pMpi2ManPage7ConnectorInfo_t; ++ ++/*defines for the Pinout field */ ++#define MPI2_MANPAGE7_PINOUT_LANE_MASK (0x0000FF00) ++#define MPI2_MANPAGE7_PINOUT_LANE_SHIFT (8) ++ ++#define MPI2_MANPAGE7_PINOUT_TYPE_MASK (0x000000FF) ++#define MPI2_MANPAGE7_PINOUT_TYPE_UNKNOWN (0x00) ++#define MPI2_MANPAGE7_PINOUT_SATA_SINGLE (0x01) ++#define MPI2_MANPAGE7_PINOUT_SFF_8482 (0x02) ++#define MPI2_MANPAGE7_PINOUT_SFF_8486 (0x03) ++#define MPI2_MANPAGE7_PINOUT_SFF_8484 (0x04) ++#define MPI2_MANPAGE7_PINOUT_SFF_8087 (0x05) ++#define MPI2_MANPAGE7_PINOUT_SFF_8643_4I (0x06) ++#define MPI2_MANPAGE7_PINOUT_SFF_8643_8I (0x07) ++#define MPI2_MANPAGE7_PINOUT_SFF_8470 (0x08) ++#define MPI2_MANPAGE7_PINOUT_SFF_8088 (0x09) ++#define MPI2_MANPAGE7_PINOUT_SFF_8644_4X (0x0A) ++#define MPI2_MANPAGE7_PINOUT_SFF_8644_8X (0x0B) ++#define MPI2_MANPAGE7_PINOUT_SFF_8644_16X (0x0C) ++#define MPI2_MANPAGE7_PINOUT_SFF_8436 (0x0D) ++ ++/*defines for the Location field */ ++#define MPI2_MANPAGE7_LOCATION_UNKNOWN (0x01) ++#define MPI2_MANPAGE7_LOCATION_INTERNAL (0x02) ++#define MPI2_MANPAGE7_LOCATION_EXTERNAL (0x04) ++#define MPI2_MANPAGE7_LOCATION_SWITCHABLE (0x08) ++#define MPI2_MANPAGE7_LOCATION_AUTO (0x10) ++#define MPI2_MANPAGE7_LOCATION_NOT_PRESENT (0x20) ++#define MPI2_MANPAGE7_LOCATION_NOT_CONNECTED (0x80) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_MANPAGE7_CONNECTOR_INFO_MAX ++#define MPI2_MANPAGE7_CONNECTOR_INFO_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_7 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U32 Flags; /*0x0C */ ++ U8 EnclosureName[16]; /*0x10 */ ++ U8 NumPhys; /*0x20 */ ++ U8 Reserved3; /*0x21 */ ++ U16 Reserved4; /*0x22 */ ++ MPI2_MANPAGE7_CONNECTOR_INFO ++ ConnectorInfo[MPI2_MANPAGE7_CONNECTOR_INFO_MAX]; /*0x24 */ ++} MPI2_CONFIG_PAGE_MAN_7, ++ *PTR_MPI2_CONFIG_PAGE_MAN_7, ++ Mpi2ManufacturingPage7_t, ++ *pMpi2ManufacturingPage7_t; ++ ++#define MPI2_MANUFACTURING7_PAGEVERSION (0x01) ++ ++/*defines for the Flags field */ ++#define MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL (0x00000008) ++#define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002) ++#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) ++ ++ ++/* ++ *Generic structure to use for product-specific manufacturing pages ++ *(currently Manufacturing Page 8 through Manufacturing Page 31). ++ */ ++ ++typedef struct _MPI2_CONFIG_PAGE_MAN_PS { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 ProductSpecificInfo;/*0x04 */ ++} MPI2_CONFIG_PAGE_MAN_PS, ++ *PTR_MPI2_CONFIG_PAGE_MAN_PS, ++ Mpi2ManufacturingPagePS_t, ++ *pMpi2ManufacturingPagePS_t; ++ ++#define MPI2_MANUFACTURING8_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING9_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING10_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING11_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING12_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING13_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING14_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING15_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING16_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING17_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING18_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING19_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING20_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING21_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING22_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING23_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING24_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING25_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING26_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING27_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING28_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING29_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING30_PAGEVERSION (0x00) ++#define MPI2_MANUFACTURING31_PAGEVERSION (0x00) ++ ++ ++/**************************************************************************** ++* IO Unit Config Pages ++****************************************************************************/ ++ ++/*IO Unit Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U64 UniqueValue; /*0x04 */ ++ MPI2_VERSION_UNION NvdataVersionDefault; /*0x08 */ ++ MPI2_VERSION_UNION NvdataVersionPersistent; /*0x0A */ ++} MPI2_CONFIG_PAGE_IO_UNIT_0, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_0, ++ Mpi2IOUnitPage0_t, *pMpi2IOUnitPage0_t; ++ ++#define MPI2_IOUNITPAGE0_PAGEVERSION (0x02) ++ ++ ++/*IO Unit Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Flags; /*0x04 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_1, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_1, ++ Mpi2IOUnitPage1_t, *pMpi2IOUnitPage1_t; ++ ++#define MPI2_IOUNITPAGE1_PAGEVERSION (0x04) ++ ++/*IO Unit Page 1 Flags defines */ ++#define MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK (0x00004000) ++#define MPI25_IOUNITPAGE1_NEW_DEVICE_FAST_PATH_DISABLE (0x00002000) ++#define MPI25_IOUNITPAGE1_DISABLE_FAST_PATH (0x00001000) ++#define MPI2_IOUNITPAGE1_ENABLE_HOST_BASED_DISCOVERY (0x00000800) ++#define MPI2_IOUNITPAGE1_MASK_SATA_WRITE_CACHE (0x00000600) ++#define MPI2_IOUNITPAGE1_SATA_WRITE_CACHE_SHIFT (9) ++#define MPI2_IOUNITPAGE1_ENABLE_SATA_WRITE_CACHE (0x00000000) ++#define MPI2_IOUNITPAGE1_DISABLE_SATA_WRITE_CACHE (0x00000200) ++#define MPI2_IOUNITPAGE1_UNCHANGED_SATA_WRITE_CACHE (0x00000400) ++#define MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100) ++#define MPI2_IOUNITPAGE1_DISABLE_IR (0x00000040) ++#define MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING (0x00000020) ++#define MPI2_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID (0x00000004) ++ ++ ++/*IO Unit Page 3 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for GPIOCount at runtime. ++ */ ++#ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX ++#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 GPIOCount; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U16 ++ GPIOVal[MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX];/*0x08 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_3, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_3, ++ Mpi2IOUnitPage3_t, *pMpi2IOUnitPage3_t; ++ ++#define MPI2_IOUNITPAGE3_PAGEVERSION (0x01) ++ ++/*defines for IO Unit Page 3 GPIOVal field */ ++#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_MASK (0xFFFC) ++#define MPI2_IOUNITPAGE3_GPIO_FUNCTION_SHIFT (2) ++#define MPI2_IOUNITPAGE3_GPIO_SETTING_OFF (0x0000) ++#define MPI2_IOUNITPAGE3_GPIO_SETTING_ON (0x0001) ++ ++ ++/*IO Unit Page 5 */ ++ ++/* ++ *Upper layer code (drivers, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumDmaEngines at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES ++#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_5 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U64 ++ RaidAcceleratorBufferBaseAddress; /*0x04 */ ++ U64 ++ RaidAcceleratorBufferSize; /*0x0C */ ++ U64 ++ RaidAcceleratorControlBaseAddress; /*0x14 */ ++ U8 RAControlSize; /*0x1C */ ++ U8 NumDmaEngines; /*0x1D */ ++ U8 RAMinControlSize; /*0x1E */ ++ U8 RAMaxControlSize; /*0x1F */ ++ U32 Reserved1; /*0x20 */ ++ U32 Reserved2; /*0x24 */ ++ U32 Reserved3; /*0x28 */ ++ U32 ++ DmaEngineCapabilities[MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES]; /*0x2C */ ++} MPI2_CONFIG_PAGE_IO_UNIT_5, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_5, ++ Mpi2IOUnitPage5_t, *pMpi2IOUnitPage5_t; ++ ++#define MPI2_IOUNITPAGE5_PAGEVERSION (0x00) ++ ++/*defines for IO Unit Page 5 DmaEngineCapabilities field */ ++#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS (0xFFFF0000) ++#define MPI2_IOUNITPAGE5_DMA_CAP_SHIFT_MAX_REQUESTS (16) ++ ++#define MPI2_IOUNITPAGE5_DMA_CAP_EEDP (0x0008) ++#define MPI2_IOUNITPAGE5_DMA_CAP_PARITY_GENERATION (0x0004) ++#define MPI2_IOUNITPAGE5_DMA_CAP_HASHING (0x0002) ++#define MPI2_IOUNITPAGE5_DMA_CAP_ENCRYPTION (0x0001) ++ ++ ++/*IO Unit Page 6 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 Flags; /*0x04 */ ++ U8 RAHostControlSize; /*0x06 */ ++ U8 Reserved0; /*0x07 */ ++ U64 ++ RaidAcceleratorHostControlBaseAddress; /*0x08 */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++ U32 Reserved3; /*0x18 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_6, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_6, ++ Mpi2IOUnitPage6_t, *pMpi2IOUnitPage6_t; ++ ++#define MPI2_IOUNITPAGE6_PAGEVERSION (0x00) ++ ++/*defines for IO Unit Page 6 Flags field */ ++#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001) ++ ++ ++/*IO Unit Page 7 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 CurrentPowerMode; /*0x04 */ ++ U8 PreviousPowerMode; /*0x05 */ ++ U8 PCIeWidth; /*0x06 */ ++ U8 PCIeSpeed; /*0x07 */ ++ U32 ProcessorState; /*0x08 */ ++ U32 ++ PowerManagementCapabilities; /*0x0C */ ++ U16 IOCTemperature; /*0x10 */ ++ U8 ++ IOCTemperatureUnits; /*0x12 */ ++ U8 IOCSpeed; /*0x13 */ ++ U16 BoardTemperature; /*0x14 */ ++ U8 ++ BoardTemperatureUnits; /*0x16 */ ++ U8 Reserved3; /*0x17 */ ++ U32 BoardPowerRequirement; /*0x18 */ ++ U32 PCISlotPowerAllocation; /*0x1C */ ++/* reserved prior to MPI v2.6 */ ++ U8 Flags; /* 0x20 */ ++ U8 Reserved6; /* 0x21 */ ++ U16 Reserved7; /* 0x22 */ ++ U32 Reserved8; /* 0x24 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_7, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_7, ++ Mpi2IOUnitPage7_t, *pMpi2IOUnitPage7_t; ++ ++#define MPI2_IOUNITPAGE7_PAGEVERSION (0x05) ++ ++/*defines for IO Unit Page 7 CurrentPowerMode and PreviousPowerMode fields */ ++#define MPI25_IOUNITPAGE7_PM_INIT_MASK (0xC0) ++#define MPI25_IOUNITPAGE7_PM_INIT_UNAVAILABLE (0x00) ++#define MPI25_IOUNITPAGE7_PM_INIT_HOST (0x40) ++#define MPI25_IOUNITPAGE7_PM_INIT_IO_UNIT (0x80) ++#define MPI25_IOUNITPAGE7_PM_INIT_PCIE_DPA (0xC0) ++ ++#define MPI25_IOUNITPAGE7_PM_MODE_MASK (0x07) ++#define MPI25_IOUNITPAGE7_PM_MODE_UNAVAILABLE (0x00) ++#define MPI25_IOUNITPAGE7_PM_MODE_UNKNOWN (0x01) ++#define MPI25_IOUNITPAGE7_PM_MODE_FULL_POWER (0x04) ++#define MPI25_IOUNITPAGE7_PM_MODE_REDUCED_POWER (0x05) ++#define MPI25_IOUNITPAGE7_PM_MODE_STANDBY (0x06) ++ ++ ++/*defines for IO Unit Page 7 PCIeWidth field */ ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01) ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2 (0x02) ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4 (0x04) ++#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8 (0x08) ++ ++/*defines for IO Unit Page 7 PCIeSpeed field */ ++#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS (0x00) ++#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01) ++#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02) ++ ++/*defines for IO Unit Page 7 ProcessorState field */ ++#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F) ++#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND (0) ++ ++#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT (0x00) ++#define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01) ++#define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02) ++ ++/*defines for IO Unit Page 7 PowerManagementCapabilities field */ ++#define MPI25_IOUNITPAGE7_PMCAP_DPA_FULL_PWR_MODE (0x00400000) ++#define MPI25_IOUNITPAGE7_PMCAP_DPA_REDUCED_PWR_MODE (0x00200000) ++#define MPI25_IOUNITPAGE7_PMCAP_DPA_STANDBY_MODE (0x00100000) ++#define MPI25_IOUNITPAGE7_PMCAP_HOST_FULL_PWR_MODE (0x00040000) ++#define MPI25_IOUNITPAGE7_PMCAP_HOST_REDUCED_PWR_MODE (0x00020000) ++#define MPI25_IOUNITPAGE7_PMCAP_HOST_STANDBY_MODE (0x00010000) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_FULL_PWR_MODE (0x00004000) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_REDUCED_PWR_MODE (0x00002000) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_STANDBY_MODE (0x00001000) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_12_5_PCT_IOCSPEED (0x00000400) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_25_0_PCT_IOCSPEED (0x00000200) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_50_0_PCT_IOCSPEED (0x00000100) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_12_5_PCT_IOCSPEED (0x00000040) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_25_0_PCT_IOCSPEED (0x00000020) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_50_0_PCT_IOCSPEED (0x00000010) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_WIDTH_CHANGE_PCIE (0x00000008) ++#define MPI2_IOUNITPAGE7_PMCAP_HOST_SPEED_CHANGE_PCIE (0x00000004) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_WIDTH_CHANGE_PCIE (0x00000002) ++#define MPI25_IOUNITPAGE7_PMCAP_IO_SPEED_CHANGE_PCIE (0x00000001) ++ ++/*obsolete names for the PowerManagementCapabilities bits (above) */ ++#define MPI2_IOUNITPAGE7_PMCAP_12_5_PCT_IOCSPEED (0x00000400) ++#define MPI2_IOUNITPAGE7_PMCAP_25_0_PCT_IOCSPEED (0x00000200) ++#define MPI2_IOUNITPAGE7_PMCAP_50_0_PCT_IOCSPEED (0x00000100) ++#define MPI2_IOUNITPAGE7_PMCAP_PCIE_WIDTH_CHANGE (0x00000008) /*obsolete */ ++#define MPI2_IOUNITPAGE7_PMCAP_PCIE_SPEED_CHANGE (0x00000004) /*obsolete */ ++ ++ ++/*defines for IO Unit Page 7 IOCTemperatureUnits field */ ++#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00) ++#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01) ++#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS (0x02) ++ ++/*defines for IO Unit Page 7 IOCSpeed field */ ++#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL (0x01) ++#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF (0x02) ++#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER (0x04) ++#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH (0x08) ++ ++/*defines for IO Unit Page 7 BoardTemperatureUnits field */ ++#define MPI2_IOUNITPAGE7_BOARD_TEMP_NOT_PRESENT (0x00) ++#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT (0x01) ++#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02) ++ ++/* defines for IO Unit Page 7 Flags field */ ++#define MPI2_IOUNITPAGE7_FLAG_CABLE_POWER_EXC (0x01) ++ ++/*IO Unit Page 8 */ ++ ++#define MPI2_IOUNIT8_NUM_THRESHOLDS (4) ++ ++typedef struct _MPI2_IOUNIT8_SENSOR { ++ U16 Flags; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U16 ++ Threshold[MPI2_IOUNIT8_NUM_THRESHOLDS]; /*0x04 */ ++ U32 Reserved2; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U32 Reserved4; /*0x14 */ ++} MPI2_IOUNIT8_SENSOR, *PTR_MPI2_IOUNIT8_SENSOR, ++ Mpi2IOUnit8Sensor_t, *pMpi2IOUnit8Sensor_t; ++ ++/*defines for IO Unit Page 8 Sensor Flags field */ ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T3_ENABLE (0x0008) ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T2_ENABLE (0x0004) ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T1_ENABLE (0x0002) ++#define MPI2_IOUNIT8_SENSOR_FLAGS_T0_ENABLE (0x0001) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumSensors at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE8_SENSOR_ENTRIES ++#define MPI2_IOUNITPAGE8_SENSOR_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_8 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U8 NumSensors; /*0x0C */ ++ U8 PollingInterval; /*0x0D */ ++ U16 Reserved3; /*0x0E */ ++ MPI2_IOUNIT8_SENSOR ++ Sensor[MPI2_IOUNITPAGE8_SENSOR_ENTRIES];/*0x10 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_8, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_8, ++ Mpi2IOUnitPage8_t, *pMpi2IOUnitPage8_t; ++ ++#define MPI2_IOUNITPAGE8_PAGEVERSION (0x00) ++ ++ ++/*IO Unit Page 9 */ ++ ++typedef struct _MPI2_IOUNIT9_SENSOR { ++ U16 CurrentTemperature; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U8 Flags; /*0x04 */ ++ U8 Reserved2; /*0x05 */ ++ U16 Reserved3; /*0x06 */ ++ U32 Reserved4; /*0x08 */ ++ U32 Reserved5; /*0x0C */ ++} MPI2_IOUNIT9_SENSOR, *PTR_MPI2_IOUNIT9_SENSOR, ++ Mpi2IOUnit9Sensor_t, *pMpi2IOUnit9Sensor_t; ++ ++/*defines for IO Unit Page 9 Sensor Flags field */ ++#define MPI2_IOUNIT9_SENSOR_FLAGS_TEMP_VALID (0x01) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumSensors at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE9_SENSOR_ENTRIES ++#define MPI2_IOUNITPAGE9_SENSOR_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_9 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U8 NumSensors; /*0x0C */ ++ U8 Reserved4; /*0x0D */ ++ U16 Reserved3; /*0x0E */ ++ MPI2_IOUNIT9_SENSOR ++ Sensor[MPI2_IOUNITPAGE9_SENSOR_ENTRIES];/*0x10 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_9, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_9, ++ Mpi2IOUnitPage9_t, *pMpi2IOUnitPage9_t; ++ ++#define MPI2_IOUNITPAGE9_PAGEVERSION (0x00) ++ ++ ++/*IO Unit Page 10 */ ++ ++typedef struct _MPI2_IOUNIT10_FUNCTION { ++ U8 CreditPercent; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++} MPI2_IOUNIT10_FUNCTION, ++ *PTR_MPI2_IOUNIT10_FUNCTION, ++ Mpi2IOUnit10Function_t, ++ *pMpi2IOUnit10Function_t; ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumFunctions at runtime. ++ */ ++#ifndef MPI2_IOUNITPAGE10_FUNCTION_ENTRIES ++#define MPI2_IOUNITPAGE10_FUNCTION_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_10 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumFunctions; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++ MPI2_IOUNIT10_FUNCTION ++ Function[MPI2_IOUNITPAGE10_FUNCTION_ENTRIES];/*0x10 */ ++} MPI2_CONFIG_PAGE_IO_UNIT_10, ++ *PTR_MPI2_CONFIG_PAGE_IO_UNIT_10, ++ Mpi2IOUnitPage10_t, *pMpi2IOUnitPage10_t; ++ ++#define MPI2_IOUNITPAGE10_PAGEVERSION (0x01) ++ ++ ++/* IO Unit Page 11 (for MPI v2.6 and later) */ ++ ++typedef struct _MPI26_IOUNIT11_SPINUP_GROUP { ++ U8 MaxTargetSpinup; /* 0x00 */ ++ U8 SpinupDelay; /* 0x01 */ ++ U8 SpinupFlags; /* 0x02 */ ++ U8 Reserved1; /* 0x03 */ ++} MPI26_IOUNIT11_SPINUP_GROUP, ++ *PTR_MPI26_IOUNIT11_SPINUP_GROUP, ++ Mpi26IOUnit11SpinupGroup_t, ++ *pMpi26IOUnit11SpinupGroup_t; ++ ++/* defines for IO Unit Page 11 SpinupFlags */ ++#define MPI26_IOUNITPAGE11_SPINUP_DISABLE_FLAG (0x01) ++ ++ ++/* ++ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ * four and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI26_IOUNITPAGE11_PHY_MAX ++#define MPI26_IOUNITPAGE11_PHY_MAX (4) ++#endif ++ ++typedef struct _MPI26_CONFIG_PAGE_IO_UNIT_11 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ MPI26_IOUNIT11_SPINUP_GROUP SpinupGroupParameters[4]; /*0x08 */ ++ U32 Reserved2; /*0x18 */ ++ U32 Reserved3; /*0x1C */ ++ U32 Reserved4; /*0x20 */ ++ U8 BootDeviceWaitTime; /*0x24 */ ++ U8 Reserved5; /*0x25 */ ++ U16 Reserved6; /*0x26 */ ++ U8 NumPhys; /*0x28 */ ++ U8 PEInitialSpinupDelay; /*0x29 */ ++ U8 PEReplyDelay; /*0x2A */ ++ U8 Flags; /*0x2B */ ++ U8 PHY[MPI26_IOUNITPAGE11_PHY_MAX];/*0x2C */ ++} MPI26_CONFIG_PAGE_IO_UNIT_11, ++ *PTR_MPI26_CONFIG_PAGE_IO_UNIT_11, ++ Mpi26IOUnitPage11_t, ++ *pMpi26IOUnitPage11_t; ++ ++#define MPI26_IOUNITPAGE11_PAGEVERSION (0x00) ++ ++/* defines for Flags field */ ++#define MPI26_IOUNITPAGE11_FLAGS_AUTO_PORTENABLE (0x01) ++ ++/* defines for PHY field */ ++#define MPI26_IOUNITPAGE11_PHY_SPINUP_GROUP_MASK (0x03) ++ ++ ++ ++ ++ ++ ++/**************************************************************************** ++* IOC Config Pages ++****************************************************************************/ ++ ++/*IOC Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U16 VendorID; /*0x0C */ ++ U16 DeviceID; /*0x0E */ ++ U8 RevisionID; /*0x10 */ ++ U8 Reserved3; /*0x11 */ ++ U16 Reserved4; /*0x12 */ ++ U32 ClassCode; /*0x14 */ ++ U16 SubsystemVendorID; /*0x18 */ ++ U16 SubsystemID; /*0x1A */ ++} MPI2_CONFIG_PAGE_IOC_0, ++ *PTR_MPI2_CONFIG_PAGE_IOC_0, ++ Mpi2IOCPage0_t, *pMpi2IOCPage0_t; ++ ++#define MPI2_IOCPAGE0_PAGEVERSION (0x02) ++ ++ ++/*IOC Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Flags; /*0x04 */ ++ U32 CoalescingTimeout; /*0x08 */ ++ U8 CoalescingDepth; /*0x0C */ ++ U8 PCISlotNum; /*0x0D */ ++ U8 PCIBusNum; /*0x0E */ ++ U8 PCIDomainSegment; /*0x0F */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++} MPI2_CONFIG_PAGE_IOC_1, ++ *PTR_MPI2_CONFIG_PAGE_IOC_1, ++ Mpi2IOCPage1_t, *pMpi2IOCPage1_t; ++ ++#define MPI2_IOCPAGE1_PAGEVERSION (0x05) ++ ++/*defines for IOC Page 1 Flags field */ ++#define MPI2_IOCPAGE1_REPLY_COALESCING (0x00000001) ++ ++#define MPI2_IOCPAGE1_PCISLOTNUM_UNKNOWN (0xFF) ++#define MPI2_IOCPAGE1_PCIBUSNUM_UNKNOWN (0xFF) ++#define MPI2_IOCPAGE1_PCIDOMAIN_UNKNOWN (0xFF) ++ ++/*IOC Page 6 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_6 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 ++ CapabilitiesFlags; /*0x04 */ ++ U8 MaxDrivesRAID0; /*0x08 */ ++ U8 MaxDrivesRAID1; /*0x09 */ ++ U8 ++ MaxDrivesRAID1E; /*0x0A */ ++ U8 ++ MaxDrivesRAID10; /*0x0B */ ++ U8 MinDrivesRAID0; /*0x0C */ ++ U8 MinDrivesRAID1; /*0x0D */ ++ U8 ++ MinDrivesRAID1E; /*0x0E */ ++ U8 ++ MinDrivesRAID10; /*0x0F */ ++ U32 Reserved1; /*0x10 */ ++ U8 ++ MaxGlobalHotSpares; /*0x14 */ ++ U8 MaxPhysDisks; /*0x15 */ ++ U8 MaxVolumes; /*0x16 */ ++ U8 MaxConfigs; /*0x17 */ ++ U8 MaxOCEDisks; /*0x18 */ ++ U8 Reserved2; /*0x19 */ ++ U16 Reserved3; /*0x1A */ ++ U32 ++ SupportedStripeSizeMapRAID0; /*0x1C */ ++ U32 ++ SupportedStripeSizeMapRAID1E; /*0x20 */ ++ U32 ++ SupportedStripeSizeMapRAID10; /*0x24 */ ++ U32 Reserved4; /*0x28 */ ++ U32 Reserved5; /*0x2C */ ++ U16 ++ DefaultMetadataSize; /*0x30 */ ++ U16 Reserved6; /*0x32 */ ++ U16 ++ MaxBadBlockTableEntries; /*0x34 */ ++ U16 Reserved7; /*0x36 */ ++ U32 ++ IRNvsramVersion; /*0x38 */ ++} MPI2_CONFIG_PAGE_IOC_6, ++ *PTR_MPI2_CONFIG_PAGE_IOC_6, ++ Mpi2IOCPage6_t, *pMpi2IOCPage6_t; ++ ++#define MPI2_IOCPAGE6_PAGEVERSION (0x05) ++ ++/*defines for IOC Page 6 CapabilitiesFlags */ ++#define MPI2_IOCPAGE6_CAP_FLAGS_4K_SECTORS_SUPPORT (0x00000020) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID10_SUPPORT (0x00000010) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1_SUPPORT (0x00000008) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID1E_SUPPORT (0x00000004) ++#define MPI2_IOCPAGE6_CAP_FLAGS_RAID0_SUPPORT (0x00000002) ++#define MPI2_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) ++ ++ ++/*IOC Page 7 */ ++ ++#define MPI2_IOCPAGE7_EVENTMASK_WORDS (4) ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_7 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 ++ EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/*0x08 */ ++ U16 SASBroadcastPrimitiveMasks; /*0x18 */ ++ U16 SASNotifyPrimitiveMasks; /*0x1A */ ++ U32 Reserved3; /*0x1C */ ++} MPI2_CONFIG_PAGE_IOC_7, ++ *PTR_MPI2_CONFIG_PAGE_IOC_7, ++ Mpi2IOCPage7_t, *pMpi2IOCPage7_t; ++ ++#define MPI2_IOCPAGE7_PAGEVERSION (0x02) ++ ++ ++/*IOC Page 8 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_IOC_8 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumDevsPerEnclosure; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U16 MaxPersistentEntries; /*0x08 */ ++ U16 MaxNumPhysicalMappedIDs; /*0x0A */ ++ U16 Flags; /*0x0C */ ++ U16 Reserved3; /*0x0E */ ++ U16 IRVolumeMappingFlags; /*0x10 */ ++ U16 Reserved4; /*0x12 */ ++ U32 Reserved5; /*0x14 */ ++} MPI2_CONFIG_PAGE_IOC_8, ++ *PTR_MPI2_CONFIG_PAGE_IOC_8, ++ Mpi2IOCPage8_t, *pMpi2IOCPage8_t; ++ ++#define MPI2_IOCPAGE8_PAGEVERSION (0x00) ++ ++/*defines for IOC Page 8 Flags field */ ++#define MPI2_IOCPAGE8_FLAGS_DA_START_SLOT_1 (0x00000020) ++#define MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0 (0x00000010) ++ ++#define MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE (0x0000000E) ++#define MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING (0x00000000) ++#define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING (0x00000002) ++ ++#define MPI2_IOCPAGE8_FLAGS_DISABLE_PERSISTENT_MAPPING (0x00000001) ++#define MPI2_IOCPAGE8_FLAGS_ENABLE_PERSISTENT_MAPPING (0x00000000) ++ ++/*defines for IOC Page 8 IRVolumeMappingFlags */ ++#define MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE (0x00000003) ++#define MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING (0x00000000) ++#define MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING (0x00000001) ++ ++ ++/**************************************************************************** ++* BIOS Config Pages ++****************************************************************************/ ++ ++/*BIOS Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 BiosOptions; /*0x04 */ ++ U32 IOCSettings; /*0x08 */ ++ U8 SSUTimeout; /*0x0C */ ++ U8 Reserved1; /*0x0D */ ++ U16 Reserved2; /*0x0E */ ++ U32 DeviceSettings; /*0x10 */ ++ U16 NumberOfDevices; /*0x14 */ ++ U16 UEFIVersion; /*0x16 */ ++ U16 IOTimeoutBlockDevicesNonRM; /*0x18 */ ++ U16 IOTimeoutSequential; /*0x1A */ ++ U16 IOTimeoutOther; /*0x1C */ ++ U16 IOTimeoutBlockDevicesRM; /*0x1E */ ++} MPI2_CONFIG_PAGE_BIOS_1, ++ *PTR_MPI2_CONFIG_PAGE_BIOS_1, ++ Mpi2BiosPage1_t, *pMpi2BiosPage1_t; ++ ++#define MPI2_BIOSPAGE1_PAGEVERSION (0x07) ++ ++/*values for BIOS Page 1 BiosOptions field */ ++#define MPI2_BIOSPAGE1_OPTIONS_BOOT_LIST_ADD_ALT_BOOT_DEVICE (0x00008000) ++#define MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG (0x00004000) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK (0x00003800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK (0x00003800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_PBDHL (0x00000000) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_ENCSLOSURE (0x00000800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_LWWID (0x00001000) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_PSENS (0x00001800) ++#define MPI2_BIOSPAGE1_OPTIONS_PNS_ESPHY (0x00002000) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_X86_DISABLE_BIOS (0x00000400) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_MASK_REGISTRATION_UEFI_BSD (0x00000300) ++#define MPI2_BIOSPAGE1_OPTIONS_USE_BIT0_REGISTRATION_UEFI_BSD (0x00000000) ++#define MPI2_BIOSPAGE1_OPTIONS_FULL_REGISTRATION_UEFI_BSD (0x00000100) ++#define MPI2_BIOSPAGE1_OPTIONS_ADAPTER_REGISTRATION_UEFI_BSD (0x00000200) ++#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_REGISTRATION_UEFI_BSD (0x00000300) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0) ++#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006) ++#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000) ++#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002) ++#define MPI2_BIOSPAGE1_OPTIONS_VERSION_CHECK_UEFI_HII (0x00000004) ++ ++#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) ++ ++/*values for BIOS Page 1 IOCSettings field */ ++#define MPI2_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) ++#define MPI2_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000) ++#define MPI2_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000) ++ ++#define MPI2_BIOSPAGE1_IOCSET_MASK_RM_SETTING (0x000000C0) ++#define MPI2_BIOSPAGE1_IOCSET_NONE_RM_SETTING (0x00000000) ++#define MPI2_BIOSPAGE1_IOCSET_BOOT_RM_SETTING (0x00000040) ++#define MPI2_BIOSPAGE1_IOCSET_MEDIA_RM_SETTING (0x00000080) ++ ++#define MPI2_BIOSPAGE1_IOCSET_MASK_ADAPTER_SUPPORT (0x00000030) ++#define MPI2_BIOSPAGE1_IOCSET_NO_SUPPORT (0x00000000) ++#define MPI2_BIOSPAGE1_IOCSET_BIOS_SUPPORT (0x00000010) ++#define MPI2_BIOSPAGE1_IOCSET_OS_SUPPORT (0x00000020) ++#define MPI2_BIOSPAGE1_IOCSET_ALL_SUPPORT (0x00000030) ++ ++#define MPI2_BIOSPAGE1_IOCSET_ALTERNATE_CHS (0x00000008) ++ ++/*values for BIOS Page 1 DeviceSettings field */ ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SMART_POLLING (0x00000010) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN (0x00000008) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_RM_LUN (0x00000004) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002) ++#define MPI2_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001) ++ ++/*defines for BIOS Page 1 UEFIVersion field */ ++#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_MASK (0xFF00) ++#define MPI2_BIOSPAGE1_UEFI_VER_MAJOR_SHIFT (8) ++#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_MASK (0x00FF) ++#define MPI2_BIOSPAGE1_UEFI_VER_MINOR_SHIFT (0) ++ ++ ++ ++/*BIOS Page 2 */ ++ ++typedef struct _MPI2_BOOT_DEVICE_ADAPTER_ORDER { ++ U32 Reserved1; /*0x00 */ ++ U32 Reserved2; /*0x04 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++ U32 Reserved5; /*0x10 */ ++ U32 Reserved6; /*0x14 */ ++} MPI2_BOOT_DEVICE_ADAPTER_ORDER, ++ *PTR_MPI2_BOOT_DEVICE_ADAPTER_ORDER, ++ Mpi2BootDeviceAdapterOrder_t, ++ *pMpi2BootDeviceAdapterOrder_t; ++ ++typedef struct _MPI2_BOOT_DEVICE_SAS_WWID { ++ U64 SASAddress; /*0x00 */ ++ U8 LUN[8]; /*0x08 */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++} MPI2_BOOT_DEVICE_SAS_WWID, ++ *PTR_MPI2_BOOT_DEVICE_SAS_WWID, ++ Mpi2BootDeviceSasWwid_t, ++ *pMpi2BootDeviceSasWwid_t; ++ ++typedef struct _MPI2_BOOT_DEVICE_ENCLOSURE_SLOT { ++ U64 EnclosureLogicalID; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ U16 SlotNumber; /*0x10 */ ++ U16 Reserved3; /*0x12 */ ++ U32 Reserved4; /*0x14 */ ++} MPI2_BOOT_DEVICE_ENCLOSURE_SLOT, ++ *PTR_MPI2_BOOT_DEVICE_ENCLOSURE_SLOT, ++ Mpi2BootDeviceEnclosureSlot_t, ++ *pMpi2BootDeviceEnclosureSlot_t; ++ ++typedef struct _MPI2_BOOT_DEVICE_DEVICE_NAME { ++ U64 DeviceName; /*0x00 */ ++ U8 LUN[8]; /*0x08 */ ++ U32 Reserved1; /*0x10 */ ++ U32 Reserved2; /*0x14 */ ++} MPI2_BOOT_DEVICE_DEVICE_NAME, ++ *PTR_MPI2_BOOT_DEVICE_DEVICE_NAME, ++ Mpi2BootDeviceDeviceName_t, ++ *pMpi2BootDeviceDeviceName_t; ++ ++typedef union _MPI2_MPI2_BIOSPAGE2_BOOT_DEVICE { ++ MPI2_BOOT_DEVICE_ADAPTER_ORDER AdapterOrder; ++ MPI2_BOOT_DEVICE_SAS_WWID SasWwid; ++ MPI2_BOOT_DEVICE_ENCLOSURE_SLOT EnclosureSlot; ++ MPI2_BOOT_DEVICE_DEVICE_NAME DeviceName; ++} MPI2_BIOSPAGE2_BOOT_DEVICE, ++ *PTR_MPI2_BIOSPAGE2_BOOT_DEVICE, ++ Mpi2BiosPage2BootDevice_t, ++ *pMpi2BiosPage2BootDevice_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_2 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++ U32 Reserved4; /*0x10 */ ++ U32 Reserved5; /*0x14 */ ++ U32 Reserved6; /*0x18 */ ++ U8 ReqBootDeviceForm; /*0x1C */ ++ U8 Reserved7; /*0x1D */ ++ U16 Reserved8; /*0x1E */ ++ MPI2_BIOSPAGE2_BOOT_DEVICE RequestedBootDevice; /*0x20 */ ++ U8 ReqAltBootDeviceForm; /*0x38 */ ++ U8 Reserved9; /*0x39 */ ++ U16 Reserved10; /*0x3A */ ++ MPI2_BIOSPAGE2_BOOT_DEVICE RequestedAltBootDevice; /*0x3C */ ++ U8 CurrentBootDeviceForm; /*0x58 */ ++ U8 Reserved11; /*0x59 */ ++ U16 Reserved12; /*0x5A */ ++ MPI2_BIOSPAGE2_BOOT_DEVICE CurrentBootDevice; /*0x58 */ ++} MPI2_CONFIG_PAGE_BIOS_2, *PTR_MPI2_CONFIG_PAGE_BIOS_2, ++ Mpi2BiosPage2_t, *pMpi2BiosPage2_t; ++ ++#define MPI2_BIOSPAGE2_PAGEVERSION (0x04) ++ ++/*values for BIOS Page 2 BootDeviceForm fields */ ++#define MPI2_BIOSPAGE2_FORM_MASK (0x0F) ++#define MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED (0x00) ++#define MPI2_BIOSPAGE2_FORM_SAS_WWID (0x05) ++#define MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06) ++#define MPI2_BIOSPAGE2_FORM_DEVICE_NAME (0x07) ++ ++ ++/*BIOS Page 3 */ ++ ++#define MPI2_BIOSPAGE3_NUM_ADAPTER (4) ++ ++typedef struct _MPI2_ADAPTER_INFO { ++ U8 PciBusNumber; /*0x00 */ ++ U8 PciDeviceAndFunctionNumber; /*0x01 */ ++ U16 AdapterFlags; /*0x02 */ ++} MPI2_ADAPTER_INFO, *PTR_MPI2_ADAPTER_INFO, ++ Mpi2AdapterInfo_t, *pMpi2AdapterInfo_t; ++ ++#define MPI2_ADAPTER_INFO_FLAGS_EMBEDDED (0x0001) ++#define MPI2_ADAPTER_INFO_FLAGS_INIT_STATUS (0x0002) ++ ++typedef struct _MPI2_ADAPTER_ORDER_AUX { ++ U64 WWID; /* 0x00 */ ++ U32 Reserved1; /* 0x08 */ ++ U32 Reserved2; /* 0x0C */ ++} MPI2_ADAPTER_ORDER_AUX, *PTR_MPI2_ADAPTER_ORDER_AUX, ++ Mpi2AdapterOrderAux_t, *pMpi2AdapterOrderAux_t; ++ ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_3 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U32 GlobalFlags; /*0x04 */ ++ U32 BiosVersion; /*0x08 */ ++ MPI2_ADAPTER_INFO AdapterOrder[MPI2_BIOSPAGE3_NUM_ADAPTER]; ++ U32 Reserved1; /*0x1C */ ++ MPI2_ADAPTER_ORDER_AUX AdapterOrderAux[MPI2_BIOSPAGE3_NUM_ADAPTER]; ++} MPI2_CONFIG_PAGE_BIOS_3, ++ *PTR_MPI2_CONFIG_PAGE_BIOS_3, ++ Mpi2BiosPage3_t, *pMpi2BiosPage3_t; ++ ++#define MPI2_BIOSPAGE3_PAGEVERSION (0x01) ++ ++/*values for BIOS Page 3 GlobalFlags */ ++#define MPI2_BIOSPAGE3_FLAGS_PAUSE_ON_ERROR (0x00000002) ++#define MPI2_BIOSPAGE3_FLAGS_VERBOSE_ENABLE (0x00000004) ++#define MPI2_BIOSPAGE3_FLAGS_HOOK_INT_40_DISABLE (0x00000010) ++ ++#define MPI2_BIOSPAGE3_FLAGS_DEV_LIST_DISPLAY_MASK (0x000000E0) ++#define MPI2_BIOSPAGE3_FLAGS_INSTALLED_DEV_DISPLAY (0x00000000) ++#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DISPLAY (0x00000020) ++#define MPI2_BIOSPAGE3_FLAGS_ADAPTER_DEV_DISPLAY (0x00000040) ++ ++ ++/*BIOS Page 4 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_BIOS_PAGE_4_PHY_ENTRIES ++#define MPI2_BIOS_PAGE_4_PHY_ENTRIES (1) ++#endif ++ ++typedef struct _MPI2_BIOS4_ENTRY { ++ U64 ReassignmentWWID; /*0x00 */ ++ U64 ReassignmentDeviceName; /*0x08 */ ++} MPI2_BIOS4_ENTRY, *PTR_MPI2_BIOS4_ENTRY, ++ Mpi2MBios4Entry_t, *pMpi2Bios4Entry_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_BIOS_4 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhys; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ MPI2_BIOS4_ENTRY ++ Phy[MPI2_BIOS_PAGE_4_PHY_ENTRIES]; /*0x08 */ ++} MPI2_CONFIG_PAGE_BIOS_4, *PTR_MPI2_CONFIG_PAGE_BIOS_4, ++ Mpi2BiosPage4_t, *pMpi2BiosPage4_t; ++ ++#define MPI2_BIOSPAGE4_PAGEVERSION (0x01) ++ ++ ++/**************************************************************************** ++* RAID Volume Config Pages ++****************************************************************************/ ++ ++/*RAID Volume Page 0 */ ++ ++typedef struct _MPI2_RAIDVOL0_PHYS_DISK { ++ U8 RAIDSetNum; /*0x00 */ ++ U8 PhysDiskMap; /*0x01 */ ++ U8 PhysDiskNum; /*0x02 */ ++ U8 Reserved; /*0x03 */ ++} MPI2_RAIDVOL0_PHYS_DISK, *PTR_MPI2_RAIDVOL0_PHYS_DISK, ++ Mpi2RaidVol0PhysDisk_t, *pMpi2RaidVol0PhysDisk_t; ++ ++/*defines for the PhysDiskMap field */ ++#define MPI2_RAIDVOL0_PHYSDISK_PRIMARY (0x01) ++#define MPI2_RAIDVOL0_PHYSDISK_SECONDARY (0x02) ++ ++typedef struct _MPI2_RAIDVOL0_SETTINGS { ++ U16 Settings; /*0x00 */ ++ U8 HotSparePool; /*0x01 */ ++ U8 Reserved; /*0x02 */ ++} MPI2_RAIDVOL0_SETTINGS, *PTR_MPI2_RAIDVOL0_SETTINGS, ++ Mpi2RaidVol0Settings_t, ++ *pMpi2RaidVol0Settings_t; ++ ++/*RAID Volume Page 0 HotSparePool defines, also used in RAID Physical Disk */ ++#define MPI2_RAID_HOT_SPARE_POOL_0 (0x01) ++#define MPI2_RAID_HOT_SPARE_POOL_1 (0x02) ++#define MPI2_RAID_HOT_SPARE_POOL_2 (0x04) ++#define MPI2_RAID_HOT_SPARE_POOL_3 (0x08) ++#define MPI2_RAID_HOT_SPARE_POOL_4 (0x10) ++#define MPI2_RAID_HOT_SPARE_POOL_5 (0x20) ++#define MPI2_RAID_HOT_SPARE_POOL_6 (0x40) ++#define MPI2_RAID_HOT_SPARE_POOL_7 (0x80) ++ ++/*RAID Volume Page 0 VolumeSettings defines */ ++#define MPI2_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0008) ++#define MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE (0x0004) ++ ++#define MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING (0x0003) ++#define MPI2_RAIDVOL0_SETTING_UNCHANGED (0x0000) ++#define MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING (0x0001) ++#define MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING (0x0002) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhysDisks at runtime. ++ */ ++#ifndef MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX ++#define MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 DevHandle; /*0x04 */ ++ U8 VolumeState; /*0x06 */ ++ U8 VolumeType; /*0x07 */ ++ U32 VolumeStatusFlags; /*0x08 */ ++ MPI2_RAIDVOL0_SETTINGS VolumeSettings; /*0x0C */ ++ U64 MaxLBA; /*0x10 */ ++ U32 StripeSize; /*0x18 */ ++ U16 BlockSize; /*0x1C */ ++ U16 Reserved1; /*0x1E */ ++ U8 SupportedPhysDisks;/*0x20 */ ++ U8 ResyncRate; /*0x21 */ ++ U16 DataScrubDuration; /*0x22 */ ++ U8 NumPhysDisks; /*0x24 */ ++ U8 Reserved2; /*0x25 */ ++ U8 Reserved3; /*0x26 */ ++ U8 InactiveStatus; /*0x27 */ ++ MPI2_RAIDVOL0_PHYS_DISK ++ PhysDisk[MPI2_RAID_VOL_PAGE_0_PHYSDISK_MAX]; /*0x28 */ ++} MPI2_CONFIG_PAGE_RAID_VOL_0, ++ *PTR_MPI2_CONFIG_PAGE_RAID_VOL_0, ++ Mpi2RaidVolPage0_t, *pMpi2RaidVolPage0_t; ++ ++#define MPI2_RAIDVOLPAGE0_PAGEVERSION (0x0A) ++ ++/*values for RAID VolumeState */ ++#define MPI2_RAID_VOL_STATE_MISSING (0x00) ++#define MPI2_RAID_VOL_STATE_FAILED (0x01) ++#define MPI2_RAID_VOL_STATE_INITIALIZING (0x02) ++#define MPI2_RAID_VOL_STATE_ONLINE (0x03) ++#define MPI2_RAID_VOL_STATE_DEGRADED (0x04) ++#define MPI2_RAID_VOL_STATE_OPTIMAL (0x05) ++ ++/*values for RAID VolumeType */ ++#define MPI2_RAID_VOL_TYPE_RAID0 (0x00) ++#define MPI2_RAID_VOL_TYPE_RAID1E (0x01) ++#define MPI2_RAID_VOL_TYPE_RAID1 (0x02) ++#define MPI2_RAID_VOL_TYPE_RAID10 (0x05) ++#define MPI2_RAID_VOL_TYPE_UNKNOWN (0xFF) ++ ++/*values for RAID Volume Page 0 VolumeStatusFlags field */ ++#define MPI2_RAIDVOL0_STATUS_FLAG_PENDING_RESYNC (0x02000000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BACKG_INIT_PENDING (0x01000000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_MDC_PENDING (0x00800000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_USER_CONSIST_PENDING (0x00400000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_MAKE_DATA_CONSISTENT (0x00200000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB (0x00100000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK (0x00080000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION (0x00040000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT (0x00020000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x00010000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_VOL_NOT_CONSISTENT (0x00000080) ++#define MPI2_RAIDVOL0_STATUS_FLAG_OCE_ALLOWED (0x00000040) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BGI_COMPLETE (0x00000020) ++#define MPI2_RAIDVOL0_STATUS_FLAG_1E_OFFSET_MIRROR (0x00000000) ++#define MPI2_RAIDVOL0_STATUS_FLAG_1E_ADJACENT_MIRROR (0x00000010) ++#define MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x00000008) ++#define MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x00000004) ++#define MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED (0x00000002) ++#define MPI2_RAIDVOL0_STATUS_FLAG_ENABLED (0x00000001) ++ ++/*values for RAID Volume Page 0 SupportedPhysDisks field */ ++#define MPI2_RAIDVOL0_SUPPORT_SOLID_STATE_DISKS (0x08) ++#define MPI2_RAIDVOL0_SUPPORT_HARD_DISKS (0x04) ++#define MPI2_RAIDVOL0_SUPPORT_SAS_PROTOCOL (0x02) ++#define MPI2_RAIDVOL0_SUPPORT_SATA_PROTOCOL (0x01) ++ ++/*values for RAID Volume Page 0 InactiveStatus field */ ++#define MPI2_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) ++#define MPI2_RAIDVOLPAGE0_STALE_METADATA_INACTIVE (0x01) ++#define MPI2_RAIDVOLPAGE0_FOREIGN_VOLUME_INACTIVE (0x02) ++#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_RESOURCE_INACTIVE (0x03) ++#define MPI2_RAIDVOLPAGE0_CLONE_VOLUME_INACTIVE (0x04) ++#define MPI2_RAIDVOLPAGE0_INSUFFICIENT_METADATA_INACTIVE (0x05) ++#define MPI2_RAIDVOLPAGE0_PREVIOUSLY_DELETED (0x06) ++ ++ ++/*RAID Volume Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_RAID_VOL_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 DevHandle; /*0x04 */ ++ U16 Reserved0; /*0x06 */ ++ U8 GUID[24]; /*0x08 */ ++ U8 Name[16]; /*0x20 */ ++ U64 WWID; /*0x30 */ ++ U32 Reserved1; /*0x38 */ ++ U32 Reserved2; /*0x3C */ ++} MPI2_CONFIG_PAGE_RAID_VOL_1, ++ *PTR_MPI2_CONFIG_PAGE_RAID_VOL_1, ++ Mpi2RaidVolPage1_t, *pMpi2RaidVolPage1_t; ++ ++#define MPI2_RAIDVOLPAGE1_PAGEVERSION (0x03) ++ ++ ++/**************************************************************************** ++* RAID Physical Disk Config Pages ++****************************************************************************/ ++ ++/*RAID Physical Disk Page 0 */ ++ ++typedef struct _MPI2_RAIDPHYSDISK0_SETTINGS { ++ U16 Reserved1; /*0x00 */ ++ U8 HotSparePool; /*0x02 */ ++ U8 Reserved2; /*0x03 */ ++} MPI2_RAIDPHYSDISK0_SETTINGS, ++ *PTR_MPI2_RAIDPHYSDISK0_SETTINGS, ++ Mpi2RaidPhysDisk0Settings_t, ++ *pMpi2RaidPhysDisk0Settings_t; ++ ++/*use MPI2_RAID_HOT_SPARE_POOL_ defines for the HotSparePool field */ ++ ++typedef struct _MPI2_RAIDPHYSDISK0_INQUIRY_DATA { ++ U8 VendorID[8]; /*0x00 */ ++ U8 ProductID[16]; /*0x08 */ ++ U8 ProductRevLevel[4]; /*0x18 */ ++ U8 SerialNum[32]; /*0x1C */ ++} MPI2_RAIDPHYSDISK0_INQUIRY_DATA, ++ *PTR_MPI2_RAIDPHYSDISK0_INQUIRY_DATA, ++ Mpi2RaidPhysDisk0InquiryData_t, ++ *pMpi2RaidPhysDisk0InquiryData_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_0 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U16 DevHandle; /*0x04 */ ++ U8 Reserved1; /*0x06 */ ++ U8 PhysDiskNum; /*0x07 */ ++ MPI2_RAIDPHYSDISK0_SETTINGS PhysDiskSettings; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ MPI2_RAIDPHYSDISK0_INQUIRY_DATA InquiryData; /*0x10 */ ++ U32 Reserved3; /*0x4C */ ++ U8 PhysDiskState; /*0x50 */ ++ U8 OfflineReason; /*0x51 */ ++ U8 IncompatibleReason; /*0x52 */ ++ U8 PhysDiskAttributes; /*0x53 */ ++ U32 PhysDiskStatusFlags;/*0x54 */ ++ U64 DeviceMaxLBA; /*0x58 */ ++ U64 HostMaxLBA; /*0x60 */ ++ U64 CoercedMaxLBA; /*0x68 */ ++ U16 BlockSize; /*0x70 */ ++ U16 Reserved5; /*0x72 */ ++ U32 Reserved6; /*0x74 */ ++} MPI2_CONFIG_PAGE_RD_PDISK_0, ++ *PTR_MPI2_CONFIG_PAGE_RD_PDISK_0, ++ Mpi2RaidPhysDiskPage0_t, ++ *pMpi2RaidPhysDiskPage0_t; ++ ++#define MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION (0x05) ++ ++/*PhysDiskState defines */ ++#define MPI2_RAID_PD_STATE_NOT_CONFIGURED (0x00) ++#define MPI2_RAID_PD_STATE_NOT_COMPATIBLE (0x01) ++#define MPI2_RAID_PD_STATE_OFFLINE (0x02) ++#define MPI2_RAID_PD_STATE_ONLINE (0x03) ++#define MPI2_RAID_PD_STATE_HOT_SPARE (0x04) ++#define MPI2_RAID_PD_STATE_DEGRADED (0x05) ++#define MPI2_RAID_PD_STATE_REBUILDING (0x06) ++#define MPI2_RAID_PD_STATE_OPTIMAL (0x07) ++ ++/*OfflineReason defines */ ++#define MPI2_PHYSDISK0_ONLINE (0x00) ++#define MPI2_PHYSDISK0_OFFLINE_MISSING (0x01) ++#define MPI2_PHYSDISK0_OFFLINE_FAILED (0x03) ++#define MPI2_PHYSDISK0_OFFLINE_INITIALIZING (0x04) ++#define MPI2_PHYSDISK0_OFFLINE_REQUESTED (0x05) ++#define MPI2_PHYSDISK0_OFFLINE_FAILED_REQUESTED (0x06) ++#define MPI2_PHYSDISK0_OFFLINE_OTHER (0xFF) ++ ++/*IncompatibleReason defines */ ++#define MPI2_PHYSDISK0_COMPATIBLE (0x00) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_PROTOCOL (0x01) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_BLOCKSIZE (0x02) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_MAX_LBA (0x03) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_SATA_EXTENDED_CMD (0x04) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_REMOVEABLE_MEDIA (0x05) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_MEDIA_TYPE (0x06) ++#define MPI2_PHYSDISK0_INCOMPATIBLE_UNKNOWN (0xFF) ++ ++/*PhysDiskAttributes defines */ ++#define MPI2_PHYSDISK0_ATTRIB_MEDIA_MASK (0x0C) ++#define MPI2_PHYSDISK0_ATTRIB_SOLID_STATE_DRIVE (0x08) ++#define MPI2_PHYSDISK0_ATTRIB_HARD_DISK_DRIVE (0x04) ++ ++#define MPI2_PHYSDISK0_ATTRIB_PROTOCOL_MASK (0x03) ++#define MPI2_PHYSDISK0_ATTRIB_SAS_PROTOCOL (0x02) ++#define MPI2_PHYSDISK0_ATTRIB_SATA_PROTOCOL (0x01) ++ ++/*PhysDiskStatusFlags defines */ ++#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED (0x00000040) ++#define MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET (0x00000020) ++#define MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED (0x00000010) ++#define MPI2_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00000000) ++#define MPI2_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x00000008) ++#define MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x00000004) ++#define MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED (0x00000002) ++#define MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x00000001) ++ ++ ++/*RAID Physical Disk Page 1 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhysDiskPaths at runtime. ++ */ ++#ifndef MPI2_RAID_PHYS_DISK1_PATH_MAX ++#define MPI2_RAID_PHYS_DISK1_PATH_MAX (1) ++#endif ++ ++typedef struct _MPI2_RAIDPHYSDISK1_PATH { ++ U16 DevHandle; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U64 WWID; /*0x04 */ ++ U64 OwnerWWID; /*0x0C */ ++ U8 OwnerIdentifier; /*0x14 */ ++ U8 Reserved2; /*0x15 */ ++ U16 Flags; /*0x16 */ ++} MPI2_RAIDPHYSDISK1_PATH, *PTR_MPI2_RAIDPHYSDISK1_PATH, ++ Mpi2RaidPhysDisk1Path_t, ++ *pMpi2RaidPhysDisk1Path_t; ++ ++/*RAID Physical Disk Page 1 Physical Disk Path Flags field defines */ ++#define MPI2_RAID_PHYSDISK1_FLAG_PRIMARY (0x0004) ++#define MPI2_RAID_PHYSDISK1_FLAG_BROKEN (0x0002) ++#define MPI2_RAID_PHYSDISK1_FLAG_INVALID (0x0001) ++ ++typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 { ++ MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhysDiskPaths; /*0x04 */ ++ U8 PhysDiskNum; /*0x05 */ ++ U16 Reserved1; /*0x06 */ ++ U32 Reserved2; /*0x08 */ ++ MPI2_RAIDPHYSDISK1_PATH ++ PhysicalDiskPath[MPI2_RAID_PHYS_DISK1_PATH_MAX];/*0x0C */ ++} MPI2_CONFIG_PAGE_RD_PDISK_1, ++ *PTR_MPI2_CONFIG_PAGE_RD_PDISK_1, ++ Mpi2RaidPhysDiskPage1_t, ++ *pMpi2RaidPhysDiskPage1_t; ++ ++#define MPI2_RAIDPHYSDISKPAGE1_PAGEVERSION (0x02) ++ ++ ++/**************************************************************************** ++* values for fields used by several types of SAS Config Pages ++****************************************************************************/ ++ ++/*values for NegotiatedLinkRates fields */ ++#define MPI2_SAS_NEG_LINK_RATE_MASK_LOGICAL (0xF0) ++#define MPI2_SAS_NEG_LINK_RATE_SHIFT_LOGICAL (4) ++#define MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL (0x0F) ++/*link rates used for Negotiated Physical and Logical Link Rate */ ++#define MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE (0x00) ++#define MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED (0x01) ++#define MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED (0x02) ++#define MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE (0x03) ++#define MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR (0x04) ++#define MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS (0x05) ++#define MPI2_SAS_NEG_LINK_RATE_UNSUPPORTED_PHY (0x06) ++#define MPI2_SAS_NEG_LINK_RATE_1_5 (0x08) ++#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09) ++#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A) ++#define MPI25_SAS_NEG_LINK_RATE_12_0 (0x0B) ++ ++ ++/*values for AttachedPhyInfo fields */ ++#define MPI2_SAS_APHYINFO_INSIDE_ZPSDS_PERSISTENT (0x00000040) ++#define MPI2_SAS_APHYINFO_REQUESTED_INSIDE_ZPSDS (0x00000020) ++#define MPI2_SAS_APHYINFO_BREAK_REPLY_CAPABLE (0x00000010) ++ ++#define MPI2_SAS_APHYINFO_REASON_MASK (0x0000000F) ++#define MPI2_SAS_APHYINFO_REASON_UNKNOWN (0x00000000) ++#define MPI2_SAS_APHYINFO_REASON_POWER_ON (0x00000001) ++#define MPI2_SAS_APHYINFO_REASON_HARD_RESET (0x00000002) ++#define MPI2_SAS_APHYINFO_REASON_SMP_PHY_CONTROL (0x00000003) ++#define MPI2_SAS_APHYINFO_REASON_LOSS_OF_SYNC (0x00000004) ++#define MPI2_SAS_APHYINFO_REASON_MULTIPLEXING_SEQ (0x00000005) ++#define MPI2_SAS_APHYINFO_REASON_IT_NEXUS_LOSS_TIMER (0x00000006) ++#define MPI2_SAS_APHYINFO_REASON_BREAK_TIMEOUT (0x00000007) ++#define MPI2_SAS_APHYINFO_REASON_PHY_TEST_STOPPED (0x00000008) ++ ++ ++/*values for PhyInfo fields */ ++#define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) ++ ++#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000) ++#define MPI2_SAS_PHYINFO_SHIFT_PHY_POWER_CONDITION (27) ++#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) ++#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) ++#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) ++ ++#define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000) ++#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000) ++#define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000) ++#define MPI2_SAS_PHYINFO_ZONE_GROUP_PERSISTENT (0x00400000) ++#define MPI2_SAS_PHYINFO_INSIDE_ZPSDS (0x00200000) ++#define MPI2_SAS_PHYINFO_ZONING_ENABLED (0x00100000) ++ ++#define MPI2_SAS_PHYINFO_REASON_MASK (0x000F0000) ++#define MPI2_SAS_PHYINFO_REASON_UNKNOWN (0x00000000) ++#define MPI2_SAS_PHYINFO_REASON_POWER_ON (0x00010000) ++#define MPI2_SAS_PHYINFO_REASON_HARD_RESET (0x00020000) ++#define MPI2_SAS_PHYINFO_REASON_SMP_PHY_CONTROL (0x00030000) ++#define MPI2_SAS_PHYINFO_REASON_LOSS_OF_SYNC (0x00040000) ++#define MPI2_SAS_PHYINFO_REASON_MULTIPLEXING_SEQ (0x00050000) ++#define MPI2_SAS_PHYINFO_REASON_IT_NEXUS_LOSS_TIMER (0x00060000) ++#define MPI2_SAS_PHYINFO_REASON_BREAK_TIMEOUT (0x00070000) ++#define MPI2_SAS_PHYINFO_REASON_PHY_TEST_STOPPED (0x00080000) ++ ++#define MPI2_SAS_PHYINFO_MULTIPLEXING_SUPPORTED (0x00008000) ++#define MPI2_SAS_PHYINFO_SATA_PORT_ACTIVE (0x00004000) ++#define MPI2_SAS_PHYINFO_SATA_PORT_SELECTOR_PRESENT (0x00002000) ++#define MPI2_SAS_PHYINFO_VIRTUAL_PHY (0x00001000) ++ ++#define MPI2_SAS_PHYINFO_MASK_PARTIAL_PATHWAY_TIME (0x00000F00) ++#define MPI2_SAS_PHYINFO_SHIFT_PARTIAL_PATHWAY_TIME (8) ++ ++#define MPI2_SAS_PHYINFO_MASK_ROUTING_ATTRIBUTE (0x000000F0) ++#define MPI2_SAS_PHYINFO_DIRECT_ROUTING (0x00000000) ++#define MPI2_SAS_PHYINFO_SUBTRACTIVE_ROUTING (0x00000010) ++#define MPI2_SAS_PHYINFO_TABLE_ROUTING (0x00000020) ++ ++ ++/*values for SAS ProgrammedLinkRate fields */ ++#define MPI2_SAS_PRATE_MAX_RATE_MASK (0xF0) ++#define MPI2_SAS_PRATE_MAX_RATE_NOT_PROGRAMMABLE (0x00) ++#define MPI2_SAS_PRATE_MAX_RATE_1_5 (0x80) ++#define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90) ++#define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0) ++#define MPI25_SAS_PRATE_MAX_RATE_12_0 (0xB0) ++#define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F) ++#define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00) ++#define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08) ++#define MPI2_SAS_PRATE_MIN_RATE_3_0 (0x09) ++#define MPI2_SAS_PRATE_MIN_RATE_6_0 (0x0A) ++#define MPI25_SAS_PRATE_MIN_RATE_12_0 (0x0B) ++ ++ ++/*values for SAS HwLinkRate fields */ ++#define MPI2_SAS_HWRATE_MAX_RATE_MASK (0xF0) ++#define MPI2_SAS_HWRATE_MAX_RATE_1_5 (0x80) ++#define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90) ++#define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0) ++#define MPI25_SAS_HWRATE_MAX_RATE_12_0 (0xB0) ++#define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F) ++#define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08) ++#define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09) ++#define MPI2_SAS_HWRATE_MIN_RATE_6_0 (0x0A) ++#define MPI25_SAS_HWRATE_MIN_RATE_12_0 (0x0B) ++ ++ ++ ++/**************************************************************************** ++* SAS IO Unit Config Pages ++****************************************************************************/ ++ ++/*SAS IO Unit Page 0 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT0_PHY_DATA { ++ U8 Port; /*0x00 */ ++ U8 PortFlags; /*0x01 */ ++ U8 PhyFlags; /*0x02 */ ++ U8 NegotiatedLinkRate; /*0x03 */ ++ U32 ControllerPhyDeviceInfo;/*0x04 */ ++ U16 AttachedDevHandle; /*0x08 */ ++ U16 ControllerDevHandle; /*0x0A */ ++ U32 DiscoveryStatus; /*0x0C */ ++ U32 Reserved; /*0x10 */ ++} MPI2_SAS_IO_UNIT0_PHY_DATA, ++ *PTR_MPI2_SAS_IO_UNIT0_PHY_DATA, ++ Mpi2SasIOUnit0PhyData_t, ++ *pMpi2SasIOUnit0PhyData_t; ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT0_PHY_MAX ++#define MPI2_SAS_IOUNIT0_PHY_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1;/*0x08 */ ++ U8 NumPhys; /*0x0C */ ++ U8 Reserved2;/*0x0D */ ++ U16 Reserved3;/*0x0E */ ++ MPI2_SAS_IO_UNIT0_PHY_DATA ++ PhyData[MPI2_SAS_IOUNIT0_PHY_MAX]; /*0x10 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_0, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_0, ++ Mpi2SasIOUnitPage0_t, *pMpi2SasIOUnitPage0_t; ++ ++#define MPI2_SASIOUNITPAGE0_PAGEVERSION (0x05) ++ ++/*values for SAS IO Unit Page 0 PortFlags */ ++#define MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS (0x08) ++#define MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG (0x01) ++ ++/*values for SAS IO Unit Page 0 PhyFlags */ ++#define MPI2_SASIOUNIT0_PHYFLAGS_INIT_PERSIST_CONNECT (0x40) ++#define MPI2_SASIOUNIT0_PHYFLAGS_TARG_PERSIST_CONNECT (0x20) ++#define MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED (0x10) ++#define MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED (0x08) ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ ++ ++/*see mpi2_sas.h for values for ++ *SAS IO Unit Page 0 ControllerPhyDeviceInfo values */ ++ ++/*values for SAS IO Unit Page 0 DiscoveryStatus */ ++#define MPI2_SASIOUNIT0_DS_MAX_ENCLOSURES_EXCEED (0x80000000) ++#define MPI2_SASIOUNIT0_DS_MAX_EXPANDERS_EXCEED (0x40000000) ++#define MPI2_SASIOUNIT0_DS_MAX_DEVICES_EXCEED (0x20000000) ++#define MPI2_SASIOUNIT0_DS_MAX_TOPO_PHYS_EXCEED (0x10000000) ++#define MPI2_SASIOUNIT0_DS_DOWNSTREAM_INITIATOR (0x08000000) ++#define MPI2_SASIOUNIT0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000) ++#define MPI2_SASIOUNIT0_DS_EXP_MULTI_SUBTRACTIVE (0x00004000) ++#define MPI2_SASIOUNIT0_DS_MULTI_PORT_DOMAIN (0x00002000) ++#define MPI2_SASIOUNIT0_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000) ++#define MPI2_SASIOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800) ++#define MPI2_SASIOUNIT0_DS_TABLE_LINK (0x00000400) ++#define MPI2_SASIOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200) ++#define MPI2_SASIOUNIT0_DS_SMP_CRC_ERROR (0x00000100) ++#define MPI2_SASIOUNIT0_DS_SMP_FUNCTION_FAILED (0x00000080) ++#define MPI2_SASIOUNIT0_DS_INDEX_NOT_EXIST (0x00000040) ++#define MPI2_SASIOUNIT0_DS_OUT_ROUTE_ENTRIES (0x00000020) ++#define MPI2_SASIOUNIT0_DS_SMP_TIMEOUT (0x00000010) ++#define MPI2_SASIOUNIT0_DS_MULTIPLE_PORTS (0x00000004) ++#define MPI2_SASIOUNIT0_DS_UNADDRESSABLE_DEVICE (0x00000002) ++#define MPI2_SASIOUNIT0_DS_LOOP_DETECTED (0x00000001) ++ ++ ++/*SAS IO Unit Page 1 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT1_PHY_DATA { ++ U8 Port; /*0x00 */ ++ U8 PortFlags; /*0x01 */ ++ U8 PhyFlags; /*0x02 */ ++ U8 MaxMinLinkRate; /*0x03 */ ++ U32 ControllerPhyDeviceInfo; /*0x04 */ ++ U16 MaxTargetPortConnectTime; /*0x08 */ ++ U16 Reserved1; /*0x0A */ ++} MPI2_SAS_IO_UNIT1_PHY_DATA, ++ *PTR_MPI2_SAS_IO_UNIT1_PHY_DATA, ++ Mpi2SasIOUnit1PhyData_t, ++ *pMpi2SasIOUnit1PhyData_t; ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT1_PHY_MAX ++#define MPI2_SAS_IOUNIT1_PHY_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U16 ++ ControlFlags; /*0x08 */ ++ U16 ++ SASNarrowMaxQueueDepth; /*0x0A */ ++ U16 ++ AdditionalControlFlags; /*0x0C */ ++ U16 ++ SASWideMaxQueueDepth; /*0x0E */ ++ U8 ++ NumPhys; /*0x10 */ ++ U8 ++ SATAMaxQDepth; /*0x11 */ ++ U8 ++ ReportDeviceMissingDelay; /*0x12 */ ++ U8 ++ IODeviceMissingDelay; /*0x13 */ ++ MPI2_SAS_IO_UNIT1_PHY_DATA ++ PhyData[MPI2_SAS_IOUNIT1_PHY_MAX]; /*0x14 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_1, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_1, ++ Mpi2SasIOUnitPage1_t, *pMpi2SasIOUnitPage1_t; ++ ++#define MPI2_SASIOUNITPAGE1_PAGEVERSION (0x09) ++ ++/*values for SAS IO Unit Page 1 ControlFlags */ ++#define MPI2_SASIOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_3_0_MAX (0x4000) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_1_5_MAX (0x2000) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000) ++ ++#define MPI2_SASIOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600) ++#define MPI2_SASIOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9) ++#define MPI2_SASIOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x0) ++#define MPI2_SASIOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x1) ++#define MPI2_SASIOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x2) ++ ++#define MPI2_SASIOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020) ++#define MPI2_SASIOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010) ++#define MPI2_SASIOUNIT1_CONTROL_TABLE_SUBTRACTIVE_ILLEGAL (0x0008) ++#define MPI2_SASIOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004) ++#define MPI2_SASIOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) ++#define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) ++ ++/*values for SAS IO Unit Page 1 AdditionalControlFlags */ ++#define MPI2_SASIOUNIT1_ACONTROL_DA_PERSIST_CONNECT (0x0100) ++#define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL (0x0080) ++#define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040) ++#define MPI2_SASIOUNIT1_ACONTROL_INVALID_TOPOLOGY_CORRECTION (0x0020) ++#define MPI2_SASIOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET (0x0010) ++#define MPI2_SASIOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET (0x0008) ++#define MPI2_SASIOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET (0x0004) ++#define MPI2_SASIOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET (0x0002) ++#define MPI2_SASIOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) ++ ++/*defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ ++#define MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) ++#define MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16 (0x80) ++ ++/*values for SAS IO Unit Page 1 PortFlags */ ++#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) ++ ++/*values for SAS IO Unit Page 1 PhyFlags */ ++#define MPI2_SASIOUNIT1_PHYFLAGS_INIT_PERSIST_CONNECT (0x40) ++#define MPI2_SASIOUNIT1_PHYFLAGS_TARG_PERSIST_CONNECT (0x20) ++#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10) ++#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08) ++ ++/*values for SAS IO Unit Page 1 MaxMinLinkRate */ ++#define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0) ++#define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80) ++#define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90) ++#define MPI2_SASIOUNIT1_MAX_RATE_6_0 (0xA0) ++#define MPI25_SASIOUNIT1_MAX_RATE_12_0 (0xB0) ++#define MPI2_SASIOUNIT1_MIN_RATE_MASK (0x0F) ++#define MPI2_SASIOUNIT1_MIN_RATE_1_5 (0x08) ++#define MPI2_SASIOUNIT1_MIN_RATE_3_0 (0x09) ++#define MPI2_SASIOUNIT1_MIN_RATE_6_0 (0x0A) ++#define MPI25_SASIOUNIT1_MIN_RATE_12_0 (0x0B) ++ ++/*see mpi2_sas.h for values for ++ *SAS IO Unit Page 1 ControllerPhyDeviceInfo values */ ++ ++ ++/*SAS IO Unit Page 4 (for MPI v2.5 and earlier) */ ++ ++typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP { ++ U8 MaxTargetSpinup; /*0x00 */ ++ U8 SpinupDelay; /*0x01 */ ++ U8 SpinupFlags; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++} MPI2_SAS_IOUNIT4_SPINUP_GROUP, ++ *PTR_MPI2_SAS_IOUNIT4_SPINUP_GROUP, ++ Mpi2SasIOUnit4SpinupGroup_t, ++ *pMpi2SasIOUnit4SpinupGroup_t; ++/*defines for SAS IO Unit Page 4 SpinupFlags */ ++#define MPI2_SASIOUNIT4_SPINUP_DISABLE_FLAG (0x01) ++ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT4_PHY_MAX ++#define MPI2_SAS_IOUNIT4_PHY_MAX (4) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header;/*0x00 */ ++ MPI2_SAS_IOUNIT4_SPINUP_GROUP ++ SpinupGroupParameters[4]; /*0x08 */ ++ U32 ++ Reserved1; /*0x18 */ ++ U32 ++ Reserved2; /*0x1C */ ++ U32 ++ Reserved3; /*0x20 */ ++ U8 ++ BootDeviceWaitTime; /*0x24 */ ++ U8 ++ SATADeviceWaitTime; /*0x25 */ ++ U16 ++ Reserved5; /*0x26 */ ++ U8 ++ NumPhys; /*0x28 */ ++ U8 ++ PEInitialSpinupDelay; /*0x29 */ ++ U8 ++ PEReplyDelay; /*0x2A */ ++ U8 ++ Flags; /*0x2B */ ++ U8 ++ PHY[MPI2_SAS_IOUNIT4_PHY_MAX]; /*0x2C */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_4, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_4, ++ Mpi2SasIOUnitPage4_t, *pMpi2SasIOUnitPage4_t; ++ ++#define MPI2_SASIOUNITPAGE4_PAGEVERSION (0x02) ++ ++/*defines for Flags field */ ++#define MPI2_SASIOUNIT4_FLAGS_AUTO_PORTENABLE (0x01) ++ ++/*defines for PHY field */ ++#define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03) ++ ++ ++/*SAS IO Unit Page 5 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS { ++ U8 ControlFlags; /*0x00 */ ++ U8 PortWidthModGroup; /*0x01 */ ++ U16 InactivityTimerExponent; /*0x02 */ ++ U8 SATAPartialTimeout; /*0x04 */ ++ U8 Reserved2; /*0x05 */ ++ U8 SATASlumberTimeout; /*0x06 */ ++ U8 Reserved3; /*0x07 */ ++ U8 SASPartialTimeout; /*0x08 */ ++ U8 Reserved4; /*0x09 */ ++ U8 SASSlumberTimeout; /*0x0A */ ++ U8 Reserved5; /*0x0B */ ++} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, ++ *PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, ++ Mpi2SasIOUnit5PhyPmSettings_t, ++ *pMpi2SasIOUnit5PhyPmSettings_t; ++ ++/*defines for ControlFlags field */ ++#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE (0x08) ++#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE (0x04) ++#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02) ++#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01) ++ ++/*defines for PortWidthModeGroup field */ ++#define MPI2_SASIOUNIT5_PWMG_DISABLE (0xFF) ++ ++/*defines for InactivityTimerExponent field */ ++#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12) ++#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL (0x0700) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL (8) ++#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER (0x0070) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER (4) ++#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL (0x0007) ++#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL (0) ++ ++#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS (7) ++#define MPI2_SASIOUNIT5_ITE_ONE_SECOND (6) ++#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS (5) ++#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS (4) ++#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND (3) ++#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS (2) ++#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS (1) ++#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND (0) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhys at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT5_PHY_MAX ++#define MPI2_SAS_IOUNIT5_PHY_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 NumPhys; /*0x08 */ ++ U8 Reserved1;/*0x09 */ ++ U16 Reserved2;/*0x0A */ ++ U32 Reserved3;/*0x0C */ ++ MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS ++ SASPhyPowerManagementSettings[MPI2_SAS_IOUNIT5_PHY_MAX];/*0x10 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_5, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5, ++ Mpi2SasIOUnitPage5_t, *pMpi2SasIOUnitPage5_t; ++ ++#define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x01) ++ ++ ++/*SAS IO Unit Page 6 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS { ++ U8 CurrentStatus; /*0x00 */ ++ U8 CurrentModulation; /*0x01 */ ++ U8 CurrentUtilization; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U32 Reserved2; /*0x04 */ ++} MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS, ++ *PTR_MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS, ++ Mpi2SasIOUnit6PortWidthModGroupStatus_t, ++ *pMpi2SasIOUnit6PortWidthModGroupStatus_t; ++ ++/*defines for CurrentStatus field */ ++#define MPI2_SASIOUNIT6_STATUS_UNAVAILABLE (0x00) ++#define MPI2_SASIOUNIT6_STATUS_UNCONFIGURED (0x01) ++#define MPI2_SASIOUNIT6_STATUS_INVALID_CONFIG (0x02) ++#define MPI2_SASIOUNIT6_STATUS_LINK_DOWN (0x03) ++#define MPI2_SASIOUNIT6_STATUS_OBSERVATION_ONLY (0x04) ++#define MPI2_SASIOUNIT6_STATUS_INACTIVE (0x05) ++#define MPI2_SASIOUNIT6_STATUS_ACTIVE_IOUNIT (0x06) ++#define MPI2_SASIOUNIT6_STATUS_ACTIVE_HOST (0x07) ++ ++/*defines for CurrentModulation field */ ++#define MPI2_SASIOUNIT6_MODULATION_25_PERCENT (0x00) ++#define MPI2_SASIOUNIT6_MODULATION_50_PERCENT (0x01) ++#define MPI2_SASIOUNIT6_MODULATION_75_PERCENT (0x02) ++#define MPI2_SASIOUNIT6_MODULATION_100_PERCENT (0x03) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumGroups at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT6_GROUP_MAX ++#define MPI2_SAS_IOUNIT6_GROUP_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_6 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ U8 NumGroups; /*0x10 */ ++ U8 Reserved3; /*0x11 */ ++ U16 Reserved4; /*0x12 */ ++ MPI2_SAS_IO_UNIT6_PORT_WIDTH_MOD_GROUP_STATUS ++ PortWidthModulationGroupStatus[MPI2_SAS_IOUNIT6_GROUP_MAX]; /*0x14 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_6, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_6, ++ Mpi2SasIOUnitPage6_t, *pMpi2SasIOUnitPage6_t; ++ ++#define MPI2_SASIOUNITPAGE6_PAGEVERSION (0x00) ++ ++ ++/*SAS IO Unit Page 7 */ ++ ++typedef struct _MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS { ++ U8 Flags; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U8 Threshold75Pct; /*0x04 */ ++ U8 Threshold50Pct; /*0x05 */ ++ U8 Threshold25Pct; /*0x06 */ ++ U8 Reserved3; /*0x07 */ ++} MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS, ++ *PTR_MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS, ++ Mpi2SasIOUnit7PortWidthModGroupSettings_t, ++ *pMpi2SasIOUnit7PortWidthModGroupSettings_t; ++ ++/*defines for Flags field */ ++#define MPI2_SASIOUNIT7_FLAGS_ENABLE_PORT_WIDTH_MODULATION (0x01) ++ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumGroups at runtime. ++ */ ++#ifndef MPI2_SAS_IOUNIT7_GROUP_MAX ++#define MPI2_SAS_IOUNIT7_GROUP_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_7 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 SamplingInterval; /*0x08 */ ++ U8 WindowLength; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Reserved2; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U8 NumGroups; /*0x14 */ ++ U8 Reserved4; /*0x15 */ ++ U16 Reserved5; /*0x16 */ ++ MPI2_SAS_IO_UNIT7_PORT_WIDTH_MOD_GROUP_SETTINGS ++ PortWidthModulationGroupSettings[MPI2_SAS_IOUNIT7_GROUP_MAX];/*0x18 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_7, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_7, ++ Mpi2SasIOUnitPage7_t, *pMpi2SasIOUnitPage7_t; ++ ++#define MPI2_SASIOUNITPAGE7_PAGEVERSION (0x00) ++ ++ ++/*SAS IO Unit Page 8 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U32 ++ PowerManagementCapabilities; /*0x0C */ ++ U8 ++ TxRxSleepStatus; /*0x10 */ ++ U8 ++ Reserved2; /*0x11 */ ++ U16 ++ Reserved3; /*0x12 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT_8, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT_8, ++ Mpi2SasIOUnitPage8_t, *pMpi2SasIOUnitPage8_t; ++ ++#define MPI2_SASIOUNITPAGE8_PAGEVERSION (0x00) ++ ++/*defines for PowerManagementCapabilities field */ ++#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD (0x00001000) ++#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE (0x00000800) ++#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE (0x00000400) ++#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE (0x00000200) ++#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE (0x00000100) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD (0x00000010) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE (0x00000008) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE (0x00000004) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE (0x00000002) ++#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE (0x00000001) ++ ++/*defines for TxRxSleepStatus field */ ++#define MPI25_SASIOUNIT8_TXRXSLEEP_UNSUPPORTED (0x00) ++#define MPI25_SASIOUNIT8_TXRXSLEEP_DISENGAGED (0x01) ++#define MPI25_SASIOUNIT8_TXRXSLEEP_ACTIVE (0x02) ++#define MPI25_SASIOUNIT8_TXRXSLEEP_SHUTDOWN (0x03) ++ ++ ++ ++/*SAS IO Unit Page 16 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT16 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U64 ++ TimeStamp; /*0x08 */ ++ U32 ++ Reserved1; /*0x10 */ ++ U32 ++ Reserved2; /*0x14 */ ++ U32 ++ FastPathPendedRequests; /*0x18 */ ++ U32 ++ FastPathUnPendedRequests; /*0x1C */ ++ U32 ++ FastPathHostRequestStarts; /*0x20 */ ++ U32 ++ FastPathFirmwareRequestStarts; /*0x24 */ ++ U32 ++ FastPathHostCompletions; /*0x28 */ ++ U32 ++ FastPathFirmwareCompletions; /*0x2C */ ++ U32 ++ NonFastPathRequestStarts; /*0x30 */ ++ U32 ++ NonFastPathHostCompletions; /*0x30 */ ++} MPI2_CONFIG_PAGE_SASIOUNIT16, ++ *PTR_MPI2_CONFIG_PAGE_SASIOUNIT16, ++ Mpi2SasIOUnitPage16_t, *pMpi2SasIOUnitPage16_t; ++ ++#define MPI2_SASIOUNITPAGE16_PAGEVERSION (0x00) ++ ++ ++/**************************************************************************** ++* SAS Expander Config Pages ++****************************************************************************/ ++ ++/*SAS Expander Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_EXPANDER_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U8 ++ PhysicalPort; /*0x08 */ ++ U8 ++ ReportGenLength; /*0x09 */ ++ U16 ++ EnclosureHandle; /*0x0A */ ++ U64 ++ SASAddress; /*0x0C */ ++ U32 ++ DiscoveryStatus; /*0x14 */ ++ U16 ++ DevHandle; /*0x18 */ ++ U16 ++ ParentDevHandle; /*0x1A */ ++ U16 ++ ExpanderChangeCount; /*0x1C */ ++ U16 ++ ExpanderRouteIndexes; /*0x1E */ ++ U8 ++ NumPhys; /*0x20 */ ++ U8 ++ SASLevel; /*0x21 */ ++ U16 ++ Flags; /*0x22 */ ++ U16 ++ STPBusInactivityTimeLimit; /*0x24 */ ++ U16 ++ STPMaxConnectTimeLimit; /*0x26 */ ++ U16 ++ STP_SMP_NexusLossTime; /*0x28 */ ++ U16 ++ MaxNumRoutedSasAddresses; /*0x2A */ ++ U64 ++ ActiveZoneManagerSASAddress;/*0x2C */ ++ U16 ++ ZoneLockInactivityLimit; /*0x34 */ ++ U16 ++ Reserved1; /*0x36 */ ++ U8 ++ TimeToReducedFunc; /*0x38 */ ++ U8 ++ InitialTimeToReducedFunc; /*0x39 */ ++ U8 ++ MaxReducedFuncTime; /*0x3A */ ++ U8 ++ Reserved2; /*0x3B */ ++} MPI2_CONFIG_PAGE_EXPANDER_0, ++ *PTR_MPI2_CONFIG_PAGE_EXPANDER_0, ++ Mpi2ExpanderPage0_t, *pMpi2ExpanderPage0_t; ++ ++#define MPI2_SASEXPANDER0_PAGEVERSION (0x06) ++ ++/*values for SAS Expander Page 0 DiscoveryStatus field */ ++#define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED (0x80000000) ++#define MPI2_SAS_EXPANDER0_DS_MAX_EXPANDERS_EXCEED (0x40000000) ++#define MPI2_SAS_EXPANDER0_DS_MAX_DEVICES_EXCEED (0x20000000) ++#define MPI2_SAS_EXPANDER0_DS_MAX_TOPO_PHYS_EXCEED (0x10000000) ++#define MPI2_SAS_EXPANDER0_DS_DOWNSTREAM_INITIATOR (0x08000000) ++#define MPI2_SAS_EXPANDER0_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000) ++#define MPI2_SAS_EXPANDER0_DS_EXP_MULTI_SUBTRACTIVE (0x00004000) ++#define MPI2_SAS_EXPANDER0_DS_MULTI_PORT_DOMAIN (0x00002000) ++#define MPI2_SAS_EXPANDER0_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000) ++#define MPI2_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE (0x00000800) ++#define MPI2_SAS_EXPANDER0_DS_TABLE_LINK (0x00000400) ++#define MPI2_SAS_EXPANDER0_DS_SUBTRACTIVE_LINK (0x00000200) ++#define MPI2_SAS_EXPANDER0_DS_SMP_CRC_ERROR (0x00000100) ++#define MPI2_SAS_EXPANDER0_DS_SMP_FUNCTION_FAILED (0x00000080) ++#define MPI2_SAS_EXPANDER0_DS_INDEX_NOT_EXIST (0x00000040) ++#define MPI2_SAS_EXPANDER0_DS_OUT_ROUTE_ENTRIES (0x00000020) ++#define MPI2_SAS_EXPANDER0_DS_SMP_TIMEOUT (0x00000010) ++#define MPI2_SAS_EXPANDER0_DS_MULTIPLE_PORTS (0x00000004) ++#define MPI2_SAS_EXPANDER0_DS_UNADDRESSABLE_DEVICE (0x00000002) ++#define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001) ++ ++/*values for SAS Expander Page 0 Flags field */ ++#define MPI2_SAS_EXPANDER0_FLAGS_REDUCED_FUNCTIONALITY (0x2000) ++#define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED (0x1000) ++#define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES (0x0800) ++#define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES (0x0400) ++#define MPI2_SAS_EXPANDER0_FLAGS_ZONING_SUPPORT (0x0200) ++#define MPI2_SAS_EXPANDER0_FLAGS_ENABLED_ZONING (0x0100) ++#define MPI2_SAS_EXPANDER0_FLAGS_TABLE_TO_TABLE_SUPPORT (0x0080) ++#define MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE (0x0010) ++#define MPI2_SAS_EXPANDER0_FLAGS_OTHERS_CONFIG (0x0004) ++#define MPI2_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS (0x0002) ++#define MPI2_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG (0x0001) ++ ++ ++/*SAS Expander Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_EXPANDER_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U8 ++ PhysicalPort; /*0x08 */ ++ U8 ++ Reserved1; /*0x09 */ ++ U16 ++ Reserved2; /*0x0A */ ++ U8 ++ NumPhys; /*0x0C */ ++ U8 ++ Phy; /*0x0D */ ++ U16 ++ NumTableEntriesProgrammed; /*0x0E */ ++ U8 ++ ProgrammedLinkRate; /*0x10 */ ++ U8 ++ HwLinkRate; /*0x11 */ ++ U16 ++ AttachedDevHandle; /*0x12 */ ++ U32 ++ PhyInfo; /*0x14 */ ++ U32 ++ AttachedDeviceInfo; /*0x18 */ ++ U16 ++ ExpanderDevHandle; /*0x1C */ ++ U8 ++ ChangeCount; /*0x1E */ ++ U8 ++ NegotiatedLinkRate; /*0x1F */ ++ U8 ++ PhyIdentifier; /*0x20 */ ++ U8 ++ AttachedPhyIdentifier; /*0x21 */ ++ U8 ++ Reserved3; /*0x22 */ ++ U8 ++ DiscoveryInfo; /*0x23 */ ++ U32 ++ AttachedPhyInfo; /*0x24 */ ++ U8 ++ ZoneGroup; /*0x28 */ ++ U8 ++ SelfConfigStatus; /*0x29 */ ++ U16 ++ Reserved4; /*0x2A */ ++} MPI2_CONFIG_PAGE_EXPANDER_1, ++ *PTR_MPI2_CONFIG_PAGE_EXPANDER_1, ++ Mpi2ExpanderPage1_t, *pMpi2ExpanderPage1_t; ++ ++#define MPI2_SASEXPANDER1_PAGEVERSION (0x02) ++ ++/*use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */ ++ ++/*use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */ ++ ++/*use MPI2_SAS_PHYINFO_ for the PhyInfo field */ ++ ++/*see mpi2_sas.h for the MPI2_SAS_DEVICE_INFO_ defines ++ *used for the AttachedDeviceInfo field */ ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ ++ ++/*values for SAS Expander Page 1 DiscoveryInfo field */ ++#define MPI2_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED (0x04) ++#define MPI2_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE (0x02) ++#define MPI2_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES (0x01) ++ ++/*use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */ ++ ++ ++/**************************************************************************** ++* SAS Device Config Pages ++****************************************************************************/ ++ ++/*SAS Device Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U16 ++ Slot; /*0x08 */ ++ U16 ++ EnclosureHandle; /*0x0A */ ++ U64 ++ SASAddress; /*0x0C */ ++ U16 ++ ParentDevHandle; /*0x14 */ ++ U8 ++ PhyNum; /*0x16 */ ++ U8 ++ AccessStatus; /*0x17 */ ++ U16 ++ DevHandle; /*0x18 */ ++ U8 ++ AttachedPhyIdentifier; /*0x1A */ ++ U8 ++ ZoneGroup; /*0x1B */ ++ U32 ++ DeviceInfo; /*0x1C */ ++ U16 ++ Flags; /*0x20 */ ++ U8 ++ PhysicalPort; /*0x22 */ ++ U8 ++ MaxPortConnections; /*0x23 */ ++ U64 ++ DeviceName; /*0x24 */ ++ U8 ++ PortGroups; /*0x2C */ ++ U8 ++ DmaGroup; /*0x2D */ ++ U8 ++ ControlGroup; /*0x2E */ ++ U8 ++ EnclosureLevel; /*0x2F */ ++ U32 ++ ConnectorName[4]; /*0x30 */ ++ U32 ++ Reserved3; /*0x34 */ ++} MPI2_CONFIG_PAGE_SAS_DEV_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_DEV_0, ++ Mpi2SasDevicePage0_t, ++ *pMpi2SasDevicePage0_t; ++ ++#define MPI2_SASDEVICE0_PAGEVERSION (0x09) ++ ++/*values for SAS Device Page 0 AccessStatus field */ ++#define MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03) ++#define MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION (0x04) ++#define MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE (0x05) ++#define MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE (0x06) ++#define MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED (0x07) ++/*specific values for SATA Init failures */ ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG (0x12) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION (0x13) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER (0x14) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN (0x15) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN (0x16) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN (0x17) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION (0x18) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE (0x19) ++#define MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX (0x1F) ++ ++/*see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ ++ ++/*values for SAS Device Page 0 Flags field */ ++#define MPI2_SAS_DEVICE0_FLAGS_UNAUTHORIZED_DEVICE (0x8000) ++#define MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH (0x4000) ++#define MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE (0x2000) ++#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000) ++#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) ++#define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) ++#define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) ++#define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) ++#define MPI2_SAS_DEVICE0_FLAGS_PERSIST_CAPABLE (0x0004) ++#define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID (0x0002) ++#define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) ++ ++ ++/*SAS Device Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U64 ++ SASAddress; /*0x0C */ ++ U32 ++ Reserved2; /*0x14 */ ++ U16 ++ DevHandle; /*0x18 */ ++ U16 ++ Reserved3; /*0x1A */ ++ U8 ++ InitialRegDeviceFIS[20];/*0x1C */ ++} MPI2_CONFIG_PAGE_SAS_DEV_1, ++ *PTR_MPI2_CONFIG_PAGE_SAS_DEV_1, ++ Mpi2SasDevicePage1_t, ++ *pMpi2SasDevicePage1_t; ++ ++#define MPI2_SASDEVICE1_PAGEVERSION (0x01) ++ ++ ++/**************************************************************************** ++* SAS PHY Config Pages ++****************************************************************************/ ++ ++/*SAS PHY Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U16 ++ OwnerDevHandle; /*0x08 */ ++ U16 ++ Reserved1; /*0x0A */ ++ U16 ++ AttachedDevHandle; /*0x0C */ ++ U8 ++ AttachedPhyIdentifier; /*0x0E */ ++ U8 ++ Reserved2; /*0x0F */ ++ U32 ++ AttachedPhyInfo; /*0x10 */ ++ U8 ++ ProgrammedLinkRate; /*0x14 */ ++ U8 ++ HwLinkRate; /*0x15 */ ++ U8 ++ ChangeCount; /*0x16 */ ++ U8 ++ Flags; /*0x17 */ ++ U32 ++ PhyInfo; /*0x18 */ ++ U8 ++ NegotiatedLinkRate; /*0x1C */ ++ U8 ++ Reserved3; /*0x1D */ ++ U16 ++ Reserved4; /*0x1E */ ++} MPI2_CONFIG_PAGE_SAS_PHY_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_0, ++ Mpi2SasPhyPage0_t, *pMpi2SasPhyPage0_t; ++ ++#define MPI2_SASPHY0_PAGEVERSION (0x03) ++ ++/*use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */ ++ ++/*use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */ ++ ++/*use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */ ++ ++/*values for SAS PHY Page 0 Flags field */ ++#define MPI2_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01) ++ ++/*use MPI2_SAS_PHYINFO_ for the PhyInfo field */ ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ ++ ++ ++/*SAS PHY Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U32 ++ InvalidDwordCount; /*0x0C */ ++ U32 ++ RunningDisparityErrorCount; /*0x10 */ ++ U32 ++ LossDwordSynchCount; /*0x14 */ ++ U32 ++ PhyResetProblemCount; /*0x18 */ ++} MPI2_CONFIG_PAGE_SAS_PHY_1, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_1, ++ Mpi2SasPhyPage1_t, *pMpi2SasPhyPage1_t; ++ ++#define MPI2_SASPHY1_PAGEVERSION (0x01) ++ ++ ++/*SAS PHY Page 2 */ ++ ++typedef struct _MPI2_SASPHY2_PHY_EVENT { ++ U8 PhyEventCode; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 PhyEventInfo; /*0x04 */ ++} MPI2_SASPHY2_PHY_EVENT, *PTR_MPI2_SASPHY2_PHY_EVENT, ++ Mpi2SasPhy2PhyEvent_t, *pMpi2SasPhy2PhyEvent_t; ++ ++/*use MPI2_SASPHY3_EVENT_CODE_ for the PhyEventCode field */ ++ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhyEvents at runtime. ++ */ ++#ifndef MPI2_SASPHY2_PHY_EVENT_MAX ++#define MPI2_SASPHY2_PHY_EVENT_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_2 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U8 ++ NumPhyEvents; /*0x0C */ ++ U8 ++ Reserved2; /*0x0D */ ++ U16 ++ Reserved3; /*0x0E */ ++ MPI2_SASPHY2_PHY_EVENT ++ PhyEvent[MPI2_SASPHY2_PHY_EVENT_MAX]; /*0x10 */ ++} MPI2_CONFIG_PAGE_SAS_PHY_2, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_2, ++ Mpi2SasPhyPage2_t, ++ *pMpi2SasPhyPage2_t; ++ ++#define MPI2_SASPHY2_PAGEVERSION (0x00) ++ ++ ++/*SAS PHY Page 3 */ ++ ++typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG { ++ U8 PhyEventCode; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U8 CounterType; /*0x04 */ ++ U8 ThresholdWindow; /*0x05 */ ++ U8 TimeUnits; /*0x06 */ ++ U8 Reserved3; /*0x07 */ ++ U32 EventThreshold; /*0x08 */ ++ U16 ThresholdFlags; /*0x0C */ ++ U16 Reserved4; /*0x0E */ ++} MPI2_SASPHY3_PHY_EVENT_CONFIG, ++ *PTR_MPI2_SASPHY3_PHY_EVENT_CONFIG, ++ Mpi2SasPhy3PhyEventConfig_t, ++ *pMpi2SasPhy3PhyEventConfig_t; ++ ++/*values for PhyEventCode field */ ++#define MPI2_SASPHY3_EVENT_CODE_NO_EVENT (0x00) ++#define MPI2_SASPHY3_EVENT_CODE_INVALID_DWORD (0x01) ++#define MPI2_SASPHY3_EVENT_CODE_RUNNING_DISPARITY_ERROR (0x02) ++#define MPI2_SASPHY3_EVENT_CODE_LOSS_DWORD_SYNC (0x03) ++#define MPI2_SASPHY3_EVENT_CODE_PHY_RESET_PROBLEM (0x04) ++#define MPI2_SASPHY3_EVENT_CODE_ELASTICITY_BUF_OVERFLOW (0x05) ++#define MPI2_SASPHY3_EVENT_CODE_RX_ERROR (0x06) ++#define MPI2_SASPHY3_EVENT_CODE_RX_ADDR_FRAME_ERROR (0x20) ++#define MPI2_SASPHY3_EVENT_CODE_TX_AC_OPEN_REJECT (0x21) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AC_OPEN_REJECT (0x22) ++#define MPI2_SASPHY3_EVENT_CODE_TX_RC_OPEN_REJECT (0x23) ++#define MPI2_SASPHY3_EVENT_CODE_RX_RC_OPEN_REJECT (0x24) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_PARTIAL_WAITING_ON (0x25) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_CONNECT_WAITING_ON (0x26) ++#define MPI2_SASPHY3_EVENT_CODE_TX_BREAK (0x27) ++#define MPI2_SASPHY3_EVENT_CODE_RX_BREAK (0x28) ++#define MPI2_SASPHY3_EVENT_CODE_BREAK_TIMEOUT (0x29) ++#define MPI2_SASPHY3_EVENT_CODE_CONNECTION (0x2A) ++#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_PATHWAY_BLOCKED (0x2B) ++#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_ARB_WAIT_TIME (0x2C) ++#define MPI2_SASPHY3_EVENT_CODE_PEAK_ARB_WAIT_TIME (0x2D) ++#define MPI2_SASPHY3_EVENT_CODE_PEAK_CONNECT_TIME (0x2E) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_FRAMES (0x40) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_FRAMES (0x41) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_ERROR_FRAMES (0x42) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_ERROR_FRAMES (0x43) ++#define MPI2_SASPHY3_EVENT_CODE_TX_CREDIT_BLOCKED (0x44) ++#define MPI2_SASPHY3_EVENT_CODE_RX_CREDIT_BLOCKED (0x45) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SATA_FRAMES (0x50) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SATA_FRAMES (0x51) ++#define MPI2_SASPHY3_EVENT_CODE_SATA_OVERFLOW (0x52) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_FRAMES (0x60) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_FRAMES (0x61) ++#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_ERROR_FRAMES (0x63) ++#define MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT (0xD0) ++#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE (0xD1) ++#define MPI2_SASPHY3_EVENT_CODE_RX_AIP (0xD2) ++ ++/*Following codes are product specific and in MPI v2.6 and later */ ++#define MPI2_SASPHY3_EVENT_CODE_LCARB_WAIT_TIME (0xD3) ++#define MPI2_SASPHY3_EVENT_CODE_RCVD_CONN_RESP_WAIT_TIME (0xD4) ++#define MPI2_SASPHY3_EVENT_CODE_LCCONN_TIME (0xD5) ++#define MPI2_SASPHY3_EVENT_CODE_SSP_TX_START_TRANSMIT (0xD6) ++#define MPI2_SASPHY3_EVENT_CODE_SATA_TX_START (0xD7) ++#define MPI2_SASPHY3_EVENT_CODE_SMP_TX_START_TRANSMT (0xD8) ++#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_BREAK_CONN (0xD9) ++#define MPI2_SASPHY3_EVENT_CODE_SSP_RX_START_RECEIVE (0xDA) ++#define MPI2_SASPHY3_EVENT_CODE_SATA_RX_START_RECEIVE (0xDB) ++#define MPI2_SASPHY3_EVENT_CODE_SMP_RX_START_RECEIVE (0xDC) ++ ++ ++/*values for the CounterType field */ ++#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING (0x00) ++#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING (0x01) ++#define MPI2_SASPHY3_COUNTER_TYPE_PEAK_VALUE (0x02) ++ ++/*values for the TimeUnits field */ ++#define MPI2_SASPHY3_TIME_UNITS_10_MICROSECONDS (0x00) ++#define MPI2_SASPHY3_TIME_UNITS_100_MICROSECONDS (0x01) ++#define MPI2_SASPHY3_TIME_UNITS_1_MILLISECOND (0x02) ++#define MPI2_SASPHY3_TIME_UNITS_10_MILLISECONDS (0x03) ++ ++/*values for the ThresholdFlags field */ ++#define MPI2_SASPHY3_TFLAGS_PHY_RESET (0x0002) ++#define MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY (0x0001) ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumPhyEvents at runtime. ++ */ ++#ifndef MPI2_SASPHY3_PHY_EVENT_MAX ++#define MPI2_SASPHY3_PHY_EVENT_MAX (1) ++#endif ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U8 ++ NumPhyEvents; /*0x0C */ ++ U8 ++ Reserved2; /*0x0D */ ++ U16 ++ Reserved3; /*0x0E */ ++ MPI2_SASPHY3_PHY_EVENT_CONFIG ++ PhyEventConfig[MPI2_SASPHY3_PHY_EVENT_MAX]; /*0x10 */ ++} MPI2_CONFIG_PAGE_SAS_PHY_3, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_3, ++ Mpi2SasPhyPage3_t, *pMpi2SasPhyPage3_t; ++ ++#define MPI2_SASPHY3_PAGEVERSION (0x00) ++ ++ ++/*SAS PHY Page 4 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_4 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U16 ++ Reserved1; /*0x08 */ ++ U8 ++ Reserved2; /*0x0A */ ++ U8 ++ Flags; /*0x0B */ ++ U8 ++ InitialFrame[28]; /*0x0C */ ++} MPI2_CONFIG_PAGE_SAS_PHY_4, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PHY_4, ++ Mpi2SasPhyPage4_t, *pMpi2SasPhyPage4_t; ++ ++#define MPI2_SASPHY4_PAGEVERSION (0x00) ++ ++/*values for the Flags field */ ++#define MPI2_SASPHY4_FLAGS_FRAME_VALID (0x02) ++#define MPI2_SASPHY4_FLAGS_SATA_FRAME (0x01) ++ ++ ++ ++ ++/**************************************************************************** ++* SAS Port Config Pages ++****************************************************************************/ ++ ++/*SAS Port Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_PORT_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U8 ++ PortNumber; /*0x08 */ ++ U8 ++ PhysicalPort; /*0x09 */ ++ U8 ++ PortWidth; /*0x0A */ ++ U8 ++ PhysicalPortWidth; /*0x0B */ ++ U8 ++ ZoneGroup; /*0x0C */ ++ U8 ++ Reserved1; /*0x0D */ ++ U16 ++ Reserved2; /*0x0E */ ++ U64 ++ SASAddress; /*0x10 */ ++ U32 ++ DeviceInfo; /*0x18 */ ++ U32 ++ Reserved3; /*0x1C */ ++ U32 ++ Reserved4; /*0x20 */ ++} MPI2_CONFIG_PAGE_SAS_PORT_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_PORT_0, ++ Mpi2SasPortPage0_t, *pMpi2SasPortPage0_t; ++ ++#define MPI2_SASPORT0_PAGEVERSION (0x00) ++ ++/*see mpi2_sas.h for values for SAS Port Page 0 DeviceInfo values */ ++ ++ ++/**************************************************************************** ++* SAS Enclosure Config Pages ++****************************************************************************/ ++ ++/*SAS Enclosure Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved1; /*0x08 */ ++ U64 ++ EnclosureLogicalID; /*0x0C */ ++ U16 ++ Flags; /*0x14 */ ++ U16 ++ EnclosureHandle; /*0x16 */ ++ U16 ++ NumSlots; /*0x18 */ ++ U16 ++ StartSlot; /*0x1A */ ++ U8 ++ Reserved2; /*0x1C */ ++ U8 ++ EnclosureLevel; /*0x1D */ ++ U16 ++ SEPDevHandle; /*0x1E */ ++ U32 ++ Reserved3; /*0x20 */ ++ U32 ++ Reserved4; /*0x24 */ ++} MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0, ++ *PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0, ++ Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t; ++ ++#define MPI2_SASENCLOSURE0_PAGEVERSION (0x04) ++ ++/*values for SAS Enclosure Page 0 Flags field */ ++#define MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID (0x0010) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK (0x000F) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN (0x0000) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES (0x0001) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004) ++#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005) ++ ++ ++/**************************************************************************** ++* Log Config Page ++****************************************************************************/ ++ ++/*Log Page 0 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumLogEntries at runtime. ++ */ ++#ifndef MPI2_LOG_0_NUM_LOG_ENTRIES ++#define MPI2_LOG_0_NUM_LOG_ENTRIES (1) ++#endif ++ ++#define MPI2_LOG_0_LOG_DATA_LENGTH (0x1C) ++ ++typedef struct _MPI2_LOG_0_ENTRY { ++ U64 TimeStamp; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U16 LogSequence; /*0x0C */ ++ U16 LogEntryQualifier; /*0x0E */ ++ U8 VP_ID; /*0x10 */ ++ U8 VF_ID; /*0x11 */ ++ U16 Reserved2; /*0x12 */ ++ U8 ++ LogData[MPI2_LOG_0_LOG_DATA_LENGTH];/*0x14 */ ++} MPI2_LOG_0_ENTRY, *PTR_MPI2_LOG_0_ENTRY, ++ Mpi2Log0Entry_t, *pMpi2Log0Entry_t; ++ ++/*values for Log Page 0 LogEntry LogEntryQualifier field */ ++#define MPI2_LOG_0_ENTRY_QUAL_ENTRY_UNUSED (0x0000) ++#define MPI2_LOG_0_ENTRY_QUAL_POWER_ON_RESET (0x0001) ++#define MPI2_LOG_0_ENTRY_QUAL_TIMESTAMP_UPDATE (0x0002) ++#define MPI2_LOG_0_ENTRY_QUAL_MIN_IMPLEMENT_SPEC (0x8000) ++#define MPI2_LOG_0_ENTRY_QUAL_MAX_IMPLEMENT_SPEC (0xFFFF) ++ ++typedef struct _MPI2_CONFIG_PAGE_LOG_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++ U16 NumLogEntries;/*0x10 */ ++ U16 Reserved3; /*0x12 */ ++ MPI2_LOG_0_ENTRY ++ LogEntry[MPI2_LOG_0_NUM_LOG_ENTRIES]; /*0x14 */ ++} MPI2_CONFIG_PAGE_LOG_0, *PTR_MPI2_CONFIG_PAGE_LOG_0, ++ Mpi2LogPage0_t, *pMpi2LogPage0_t; ++ ++#define MPI2_LOG_0_PAGEVERSION (0x02) ++ ++ ++/**************************************************************************** ++* RAID Config Page ++****************************************************************************/ ++ ++/*RAID Page 0 */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check the value returned for NumElements at runtime. ++ */ ++#ifndef MPI2_RAIDCONFIG0_MAX_ELEMENTS ++#define MPI2_RAIDCONFIG0_MAX_ELEMENTS (1) ++#endif ++ ++typedef struct _MPI2_RAIDCONFIG0_CONFIG_ELEMENT { ++ U16 ElementFlags; /*0x00 */ ++ U16 VolDevHandle; /*0x02 */ ++ U8 HotSparePool; /*0x04 */ ++ U8 PhysDiskNum; /*0x05 */ ++ U16 PhysDiskDevHandle; /*0x06 */ ++} MPI2_RAIDCONFIG0_CONFIG_ELEMENT, ++ *PTR_MPI2_RAIDCONFIG0_CONFIG_ELEMENT, ++ Mpi2RaidConfig0ConfigElement_t, ++ *pMpi2RaidConfig0ConfigElement_t; ++ ++/*values for the ElementFlags field */ ++#define MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE (0x000F) ++#define MPI2_RAIDCONFIG0_EFLAGS_VOLUME_ELEMENT (0x0000) ++#define MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT (0x0001) ++#define MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT (0x0002) ++#define MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT (0x0003) ++ ++ ++typedef struct _MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 NumHotSpares; /*0x08 */ ++ U8 NumPhysDisks; /*0x09 */ ++ U8 NumVolumes; /*0x0A */ ++ U8 ConfigNum; /*0x0B */ ++ U32 Flags; /*0x0C */ ++ U8 ConfigGUID[24]; /*0x10 */ ++ U32 Reserved1; /*0x28 */ ++ U8 NumElements; /*0x2C */ ++ U8 Reserved2; /*0x2D */ ++ U16 Reserved3; /*0x2E */ ++ MPI2_RAIDCONFIG0_CONFIG_ELEMENT ++ ConfigElement[MPI2_RAIDCONFIG0_MAX_ELEMENTS]; /*0x30 */ ++} MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0, ++ *PTR_MPI2_CONFIG_PAGE_RAID_CONFIGURATION_0, ++ Mpi2RaidConfigurationPage0_t, ++ *pMpi2RaidConfigurationPage0_t; ++ ++#define MPI2_RAIDCONFIG0_PAGEVERSION (0x00) ++ ++/*values for RAID Configuration Page 0 Flags field */ ++#define MPI2_RAIDCONFIG0_FLAG_FOREIGN_CONFIG (0x00000001) ++ ++ ++/**************************************************************************** ++* Driver Persistent Mapping Config Pages ++****************************************************************************/ ++ ++/*Driver Persistent Mapping Page 0 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY { ++ U64 PhysicalIdentifier; /*0x00 */ ++ U16 MappingInformation; /*0x08 */ ++ U16 DeviceIndex; /*0x0A */ ++ U32 PhysicalBitsMapping; /*0x0C */ ++ U32 Reserved1; /*0x10 */ ++} MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY, ++ *PTR_MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY, ++ Mpi2DriverMap0Entry_t, *pMpi2DriverMap0Entry_t; ++ ++typedef struct _MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ MPI2_CONFIG_PAGE_DRIVER_MAP0_ENTRY Entry; /*0x08 */ ++} MPI2_CONFIG_PAGE_DRIVER_MAPPING_0, ++ *PTR_MPI2_CONFIG_PAGE_DRIVER_MAPPING_0, ++ Mpi2DriverMappingPage0_t, *pMpi2DriverMappingPage0_t; ++ ++#define MPI2_DRIVERMAPPING0_PAGEVERSION (0x00) ++ ++/*values for Driver Persistent Mapping Page 0 MappingInformation field */ ++#define MPI2_DRVMAP0_MAPINFO_SLOT_MASK (0x07F0) ++#define MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT (4) ++#define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F) ++ ++ ++/**************************************************************************** ++* Ethernet Config Pages ++****************************************************************************/ ++ ++/*Ethernet Page 0 */ ++ ++/*IP address (union of IPv4 and IPv6) */ ++typedef union _MPI2_ETHERNET_IP_ADDR { ++ U32 IPv4Addr; ++ U32 IPv6Addr[4]; ++} MPI2_ETHERNET_IP_ADDR, *PTR_MPI2_ETHERNET_IP_ADDR, ++ Mpi2EthernetIpAddr_t, *pMpi2EthernetIpAddr_t; ++ ++#define MPI2_ETHERNET_HOST_NAME_LENGTH (32) ++ ++typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /*0x00 */ ++ U8 NumInterfaces; /*0x08 */ ++ U8 Reserved0; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Status; /*0x0C */ ++ U8 MediaState; /*0x10 */ ++ U8 Reserved2; /*0x11 */ ++ U16 Reserved3; /*0x12 */ ++ U8 MacAddress[6]; /*0x14 */ ++ U8 Reserved4; /*0x1A */ ++ U8 Reserved5; /*0x1B */ ++ MPI2_ETHERNET_IP_ADDR IpAddress; /*0x1C */ ++ MPI2_ETHERNET_IP_ADDR SubnetMask; /*0x2C */ ++ MPI2_ETHERNET_IP_ADDR GatewayIpAddress;/*0x3C */ ++ MPI2_ETHERNET_IP_ADDR DNS1IpAddress; /*0x4C */ ++ MPI2_ETHERNET_IP_ADDR DNS2IpAddress; /*0x5C */ ++ MPI2_ETHERNET_IP_ADDR DhcpIpAddress; /*0x6C */ ++ U8 ++ HostName[MPI2_ETHERNET_HOST_NAME_LENGTH];/*0x7C */ ++} MPI2_CONFIG_PAGE_ETHERNET_0, ++ *PTR_MPI2_CONFIG_PAGE_ETHERNET_0, ++ Mpi2EthernetPage0_t, *pMpi2EthernetPage0_t; ++ ++#define MPI2_ETHERNETPAGE0_PAGEVERSION (0x00) ++ ++/*values for Ethernet Page 0 Status field */ ++#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE (0x80000000) ++#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE (0x40000000) ++#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED (0x20000000) ++#define MPI2_ETHPG0_STATUS_DEFAULT_IF (0x00000100) ++#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED (0x00000080) ++#define MPI2_ETHPG0_STATUS_TELNET_ENABLED (0x00000040) ++#define MPI2_ETHPG0_STATUS_SSH2_ENABLED (0x00000020) ++#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED (0x00000010) ++#define MPI2_ETHPG0_STATUS_IPV6_ENABLED (0x00000008) ++#define MPI2_ETHPG0_STATUS_IPV4_ENABLED (0x00000004) ++#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES (0x00000002) ++#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED (0x00000001) ++ ++/*values for Ethernet Page 0 MediaState field */ ++#define MPI2_ETHPG0_MS_DUPLEX_MASK (0x80) ++#define MPI2_ETHPG0_MS_HALF_DUPLEX (0x00) ++#define MPI2_ETHPG0_MS_FULL_DUPLEX (0x80) ++ ++#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK (0x07) ++#define MPI2_ETHPG0_MS_NOT_CONNECTED (0x00) ++#define MPI2_ETHPG0_MS_10MBIT (0x01) ++#define MPI2_ETHPG0_MS_100MBIT (0x02) ++#define MPI2_ETHPG0_MS_1GBIT (0x03) ++ ++ ++/*Ethernet Page 1 */ ++ ++typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ Reserved0; /*0x08 */ ++ U32 ++ Flags; /*0x0C */ ++ U8 ++ MediaState; /*0x10 */ ++ U8 ++ Reserved1; /*0x11 */ ++ U16 ++ Reserved2; /*0x12 */ ++ U8 ++ MacAddress[6]; /*0x14 */ ++ U8 ++ Reserved3; /*0x1A */ ++ U8 ++ Reserved4; /*0x1B */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticIpAddress; /*0x1C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticSubnetMask; /*0x2C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticGatewayIpAddress; /*0x3C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticDNS1IpAddress; /*0x4C */ ++ MPI2_ETHERNET_IP_ADDR ++ StaticDNS2IpAddress; /*0x5C */ ++ U32 ++ Reserved5; /*0x6C */ ++ U32 ++ Reserved6; /*0x70 */ ++ U32 ++ Reserved7; /*0x74 */ ++ U32 ++ Reserved8; /*0x78 */ ++ U8 ++ HostName[MPI2_ETHERNET_HOST_NAME_LENGTH];/*0x7C */ ++} MPI2_CONFIG_PAGE_ETHERNET_1, ++ *PTR_MPI2_CONFIG_PAGE_ETHERNET_1, ++ Mpi2EthernetPage1_t, *pMpi2EthernetPage1_t; ++ ++#define MPI2_ETHERNETPAGE1_PAGEVERSION (0x00) ++ ++/*values for Ethernet Page 1 Flags field */ ++#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF (0x00000100) ++#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD (0x00000080) ++#define MPI2_ETHPG1_FLAG_ENABLE_TELNET (0x00000040) ++#define MPI2_ETHPG1_FLAG_ENABLE_SSH2 (0x00000020) ++#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT (0x00000010) ++#define MPI2_ETHPG1_FLAG_ENABLE_IPV6 (0x00000008) ++#define MPI2_ETHPG1_FLAG_ENABLE_IPV4 (0x00000004) ++#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES (0x00000002) ++#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF (0x00000001) ++ ++/*values for Ethernet Page 1 MediaState field */ ++#define MPI2_ETHPG1_MS_DUPLEX_MASK (0x80) ++#define MPI2_ETHPG1_MS_HALF_DUPLEX (0x00) ++#define MPI2_ETHPG1_MS_FULL_DUPLEX (0x80) ++ ++#define MPI2_ETHPG1_MS_DATA_RATE_MASK (0x07) ++#define MPI2_ETHPG1_MS_DATA_RATE_AUTO (0x00) ++#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT (0x01) ++#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT (0x02) ++#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT (0x03) ++ ++ ++/**************************************************************************** ++* Extended Manufacturing Config Pages ++****************************************************************************/ ++ ++/* ++ *Generic structure to use for product-specific extended manufacturing pages ++ *(currently Extended Manufacturing Page 40 through Extended Manufacturing ++ *Page 60). ++ */ ++ ++typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS { ++ MPI2_CONFIG_EXTENDED_PAGE_HEADER ++ Header; /*0x00 */ ++ U32 ++ ProductSpecificInfo; /*0x08 */ ++} MPI2_CONFIG_PAGE_EXT_MAN_PS, ++ *PTR_MPI2_CONFIG_PAGE_EXT_MAN_PS, ++ Mpi2ExtManufacturingPagePS_t, ++ *pMpi2ExtManufacturingPagePS_t; ++ ++/*PageVersion should be provided by product-specific code */ ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h +new file mode 100644 +index 0000000..bba56b6 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h +@@ -0,0 +1,581 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_init.h ++ * Title: MPI SCSI initiator mode messages and structures ++ * Creation Date: June 23, 2006 ++ * ++ * mpi2_init.h Version: 02.00.20 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t. ++ * 12-18-07 02.00.02 Modified Task Management Target Reset Method defines. ++ * 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention. ++ * 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY. ++ * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. ++ * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO ++ * Control field Task Attribute flags. ++ * Moved LUN field defines to mpi2.h becasue they are ++ * common to many structures. ++ * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to ++ * Query Asynchronous Event. ++ * Defined two new bits in the SlotStatus field of the SCSI ++ * Enclosure Processor Request and Reply. ++ * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for ++ * both SCSI IO Error Reply and SCSI Task Management Reply. ++ * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. ++ * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define. ++ * 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it. ++ * 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request. ++ * 11-10-10 02.00.11 Added MPI2_SCSIIO_NUM_SGLOFFSETS define. ++ * 11-18-11 02.00.12 Incorporating additions for MPI v2.5. ++ * 02-06-12 02.00.13 Added alternate defines for Task Priority / Command ++ * Priority to match SAM-4. ++ * Added EEDPErrorOffset to MPI2_SCSI_IO_REPLY. ++ * 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION. ++ * 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY, ++ * replacing the Reserved4 field. ++ * 11-18-14 02.00.16 Updated copyright information. ++ * 03-16-15 02.00.17 Updated for MPI v2.6. ++ * Added MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH. ++ * Added MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF and ++ * MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF. ++ * 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset. ++ * 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message. ++ * 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_INIT_H ++#define MPI2_INIT_H ++ ++/***************************************************************************** ++* ++* SCSI Initiator Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* SCSI IO messages and associated structures ++****************************************************************************/ ++ ++typedef struct _MPI2_SCSI_IO_CDB_EEDP32 { ++ U8 CDB[20]; /*0x00 */ ++ U32 PrimaryReferenceTag; /*0x14 */ ++ U16 PrimaryApplicationTag; /*0x18 */ ++ U16 PrimaryApplicationTagMask; /*0x1A */ ++ U32 TransferLength; /*0x1C */ ++} MPI2_SCSI_IO_CDB_EEDP32, *PTR_MPI2_SCSI_IO_CDB_EEDP32, ++ Mpi2ScsiIoCdbEedp32_t, *pMpi2ScsiIoCdbEedp32_t; ++ ++/*MPI v2.0 CDB field */ ++typedef union _MPI2_SCSI_IO_CDB_UNION { ++ U8 CDB32[32]; ++ MPI2_SCSI_IO_CDB_EEDP32 EEDP32; ++ MPI2_SGE_SIMPLE_UNION SGE; ++} MPI2_SCSI_IO_CDB_UNION, *PTR_MPI2_SCSI_IO_CDB_UNION, ++ Mpi2ScsiIoCdb_t, *pMpi2ScsiIoCdb_t; ++ ++/*MPI v2.0 SCSI IO Request Message */ ++typedef struct _MPI2_SCSI_IO_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U32 SenseBufferLowAddress; /*0x0C */ ++ U16 SGLFlags; /*0x10 */ ++ U8 SenseBufferLength; /*0x12 */ ++ U8 Reserved4; /*0x13 */ ++ U8 SGLOffset0; /*0x14 */ ++ U8 SGLOffset1; /*0x15 */ ++ U8 SGLOffset2; /*0x16 */ ++ U8 SGLOffset3; /*0x17 */ ++ U32 SkipCount; /*0x18 */ ++ U32 DataLength; /*0x1C */ ++ U32 BidirectionalDataLength; /*0x20 */ ++ U16 IoFlags; /*0x24 */ ++ U16 EEDPFlags; /*0x26 */ ++ U32 EEDPBlockSize; /*0x28 */ ++ U32 SecondaryReferenceTag; /*0x2C */ ++ U16 SecondaryApplicationTag; /*0x30 */ ++ U16 ApplicationTagTranslationMask; /*0x32 */ ++ U8 LUN[8]; /*0x34 */ ++ U32 Control; /*0x3C */ ++ MPI2_SCSI_IO_CDB_UNION CDB; /*0x40 */ ++ ++#ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /*typically this is left undefined */ ++ MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion; ++#endif ++ ++ MPI2_SGE_IO_UNION SGL; /*0x60 */ ++ ++} MPI2_SCSI_IO_REQUEST, *PTR_MPI2_SCSI_IO_REQUEST, ++ Mpi2SCSIIORequest_t, *pMpi2SCSIIORequest_t; ++ ++/*SCSI IO MsgFlags bits */ ++ ++/*MsgFlags for SenseBufferAddressSpace */ ++#define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR (0x0C) ++#define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR (0x00) ++#define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR (0x04) ++#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08) ++#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C) ++#define MPI26_SCSIIO_MSGFLAGS_IOCCTL_SENSE_ADDR (0x08) ++ ++/*SCSI IO SGLFlags bits */ ++ ++/*base values for Data Location Address Space */ ++#define MPI2_SCSIIO_SGLFLAGS_ADDR_MASK (0x0C) ++#define MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR (0x00) ++#define MPI2_SCSIIO_SGLFLAGS_IOCDDR_ADDR (0x04) ++#define MPI2_SCSIIO_SGLFLAGS_IOCPLB_ADDR (0x08) ++#define MPI2_SCSIIO_SGLFLAGS_IOCPLBNTA_ADDR (0x0C) ++ ++/*base values for Type */ ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_MASK (0x03) ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_MPI (0x00) ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE32 (0x01) ++#define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE64 (0x02) ++ ++/*shift values for each sub-field */ ++#define MPI2_SCSIIO_SGLFLAGS_SGL3_SHIFT (12) ++#define MPI2_SCSIIO_SGLFLAGS_SGL2_SHIFT (8) ++#define MPI2_SCSIIO_SGLFLAGS_SGL1_SHIFT (4) ++#define MPI2_SCSIIO_SGLFLAGS_SGL0_SHIFT (0) ++ ++/*number of SGLOffset fields */ ++#define MPI2_SCSIIO_NUM_SGLOFFSETS (4) ++ ++/*SCSI IO IoFlags bits */ ++ ++/*Large CDB Address Space */ ++#define MPI2_SCSIIO_CDB_ADDR_MASK (0x6000) ++#define MPI2_SCSIIO_CDB_ADDR_SYSTEM (0x0000) ++#define MPI2_SCSIIO_CDB_ADDR_IOCDDR (0x2000) ++#define MPI2_SCSIIO_CDB_ADDR_IOCPLB (0x4000) ++#define MPI2_SCSIIO_CDB_ADDR_IOCPLBNTA (0x6000) ++ ++#define MPI2_SCSIIO_IOFLAGS_LARGE_CDB (0x1000) ++#define MPI2_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800) ++#define MPI2_SCSIIO_IOFLAGS_MULTICAST (0x0400) ++#define MPI2_SCSIIO_IOFLAGS_CMD_DETERMINES_DATA_DIR (0x0200) ++#define MPI2_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF) ++ ++/*SCSI IO EEDPFlags bits */ ++ ++#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000) ++#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_REFTAG (0x4000) ++#define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_APPTAG (0x2000) ++#define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_APPTAG (0x1000) ++ ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100) ++ ++#define MPI2_SCSIIO_EEDPFLAGS_PASSTHRU_REFTAG (0x0008) ++ ++#define MPI2_SCSIIO_EEDPFLAGS_MASK_OP (0x0007) ++#define MPI2_SCSIIO_EEDPFLAGS_NOOP_OP (0x0000) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_OP (0x0001) ++#define MPI2_SCSIIO_EEDPFLAGS_STRIP_OP (0x0002) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003) ++#define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004) ++#define MPI2_SCSIIO_EEDPFLAGS_REPLACE_OP (0x0006) ++#define MPI2_SCSIIO_EEDPFLAGS_CHECK_REGEN_OP (0x0007) ++ ++/*SCSI IO LUN fields: use MPI2_LUN_ from mpi2.h */ ++ ++/*SCSI IO Control bits */ ++#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_MASK (0xFC000000) ++#define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT (26) ++ ++#define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK (0x03000000) ++#define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24) ++#define MPI2_SCSIIO_CONTROL_NODATATRANSFER (0x00000000) ++#define MPI2_SCSIIO_CONTROL_WRITE (0x01000000) ++#define MPI2_SCSIIO_CONTROL_READ (0x02000000) ++#define MPI2_SCSIIO_CONTROL_BIDIRECTIONAL (0x03000000) ++ ++#define MPI2_SCSIIO_CONTROL_TASKPRI_MASK (0x00007800) ++#define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT (11) ++/*alternate name for the previous field; called Command Priority in SAM-4 */ ++#define MPI2_SCSIIO_CONTROL_CMDPRI_MASK (0x00007800) ++#define MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT (11) ++ ++#define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK (0x00000700) ++#define MPI2_SCSIIO_CONTROL_SIMPLEQ (0x00000000) ++#define MPI2_SCSIIO_CONTROL_HEADOFQ (0x00000100) ++#define MPI2_SCSIIO_CONTROL_ORDEREDQ (0x00000200) ++#define MPI2_SCSIIO_CONTROL_ACAQ (0x00000400) ++ ++#define MPI2_SCSIIO_CONTROL_TLR_MASK (0x000000C0) ++#define MPI2_SCSIIO_CONTROL_NO_TLR (0x00000000) ++#define MPI2_SCSIIO_CONTROL_TLR_ON (0x00000040) ++#define MPI2_SCSIIO_CONTROL_TLR_OFF (0x00000080) ++ ++/*MPI v2.5 CDB field */ ++typedef union _MPI25_SCSI_IO_CDB_UNION { ++ U8 CDB32[32]; ++ MPI2_SCSI_IO_CDB_EEDP32 EEDP32; ++ MPI2_IEEE_SGE_SIMPLE64 SGE; ++} MPI25_SCSI_IO_CDB_UNION, *PTR_MPI25_SCSI_IO_CDB_UNION, ++ Mpi25ScsiIoCdb_t, *pMpi25ScsiIoCdb_t; ++ ++/*MPI v2.5/2.6 SCSI IO Request Message */ ++typedef struct _MPI25_SCSI_IO_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U32 SenseBufferLowAddress; /*0x0C */ ++ U8 DMAFlags; /*0x10 */ ++ U8 Reserved5; /*0x11 */ ++ U8 SenseBufferLength; /*0x12 */ ++ U8 Reserved4; /*0x13 */ ++ U8 SGLOffset0; /*0x14 */ ++ U8 SGLOffset1; /*0x15 */ ++ U8 SGLOffset2; /*0x16 */ ++ U8 SGLOffset3; /*0x17 */ ++ U32 SkipCount; /*0x18 */ ++ U32 DataLength; /*0x1C */ ++ U32 BidirectionalDataLength; /*0x20 */ ++ U16 IoFlags; /*0x24 */ ++ U16 EEDPFlags; /*0x26 */ ++ U16 EEDPBlockSize; /*0x28 */ ++ U16 Reserved6; /*0x2A */ ++ U32 SecondaryReferenceTag; /*0x2C */ ++ U16 SecondaryApplicationTag; /*0x30 */ ++ U16 ApplicationTagTranslationMask; /*0x32 */ ++ U8 LUN[8]; /*0x34 */ ++ U32 Control; /*0x3C */ ++ MPI25_SCSI_IO_CDB_UNION CDB; /*0x40 */ ++ ++#ifdef MPI25_SCSI_IO_VENDOR_UNIQUE_REGION /*typically this is left undefined */ ++ MPI25_SCSI_IO_VENDOR_UNIQUE VendorRegion; ++#endif ++ ++ MPI25_SGE_IO_UNION SGL; /*0x60 */ ++ ++} MPI25_SCSI_IO_REQUEST, *PTR_MPI25_SCSI_IO_REQUEST, ++ Mpi25SCSIIORequest_t, *pMpi25SCSIIORequest_t; ++ ++/*use MPI2_SCSIIO_MSGFLAGS_ defines for the MsgFlags field */ ++ ++/*Defines for the DMAFlags field ++ * Each setting affects 4 SGLS, from SGL0 to SGL3. ++ * D = Data ++ * C = Cache DIF ++ * I = Interleaved ++ * H = Host DIF ++ */ ++#define MPI25_SCSIIO_DMAFLAGS_OP_MASK (0x0F) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_D_D (0x00) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_D_C (0x01) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_D_I (0x02) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_C_C (0x03) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_C_I (0x04) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_D_I_I (0x05) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_C_C_C (0x06) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_C_C_I (0x07) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_C_I_I (0x08) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_I_I_I (0x09) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_D_D (0x0A) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_D_C (0x0B) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_D_I (0x0C) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_C_C (0x0D) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_C_I (0x0E) ++#define MPI25_SCSIIO_DMAFLAGS_OP_D_H_I_I (0x0F) ++ ++/*number of SGLOffset fields */ ++#define MPI25_SCSIIO_NUM_SGLOFFSETS (4) ++ ++/*defines for the IoFlags field */ ++#define MPI25_SCSIIO_IOFLAGS_IO_PATH_MASK (0xC000) ++#define MPI25_SCSIIO_IOFLAGS_NORMAL_PATH (0x0000) ++#define MPI25_SCSIIO_IOFLAGS_FAST_PATH (0x4000) ++ ++#define MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH (0x2000) ++#define MPI25_SCSIIO_IOFLAGS_LARGE_CDB (0x1000) ++#define MPI25_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800) ++#define MPI26_SCSIIO_IOFLAGS_PORT_REQUEST (0x0400) ++#define MPI25_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF) ++ ++/*MPI v2.5 defines for the EEDPFlags bits */ ++/*use MPI2_SCSIIO_EEDPFLAGS_ defines for the other EEDPFlags bits */ ++#define MPI25_SCSIIO_EEDPFLAGS_ESCAPE_MODE_MASK (0x00C0) ++#define MPI25_SCSIIO_EEDPFLAGS_COMPATIBLE_MODE (0x0000) ++#define MPI25_SCSIIO_EEDPFLAGS_DO_NOT_DISABLE_MODE (0x0040) ++#define MPI25_SCSIIO_EEDPFLAGS_APPTAG_DISABLE_MODE (0x0080) ++#define MPI25_SCSIIO_EEDPFLAGS_APPTAG_REFTAG_DISABLE_MODE (0x00C0) ++ ++#define MPI25_SCSIIO_EEDPFLAGS_HOST_GUARD_METHOD_MASK (0x0030) ++#define MPI25_SCSIIO_EEDPFLAGS_T10_CRC_HOST_GUARD (0x0000) ++#define MPI25_SCSIIO_EEDPFLAGS_IP_CHKSUM_HOST_GUARD (0x0010) ++ ++/*use MPI2_LUN_ defines from mpi2.h for the LUN field */ ++ ++/*use MPI2_SCSIIO_CONTROL_ defines for the Control field */ ++ ++/*NOTE: The SCSI IO Reply is nearly the same for MPI 2.0 and MPI 2.5, so ++ * MPI2_SCSI_IO_REPLY is used for both. ++ */ ++ ++/*SCSI IO Error Reply Message */ ++typedef struct _MPI2_SCSI_IO_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U8 SCSIStatus; /*0x0C */ ++ U8 SCSIState; /*0x0D */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 TransferCount; /*0x14 */ ++ U32 SenseCount; /*0x18 */ ++ U32 ResponseInfo; /*0x1C */ ++ U16 TaskTag; /*0x20 */ ++ U16 SCSIStatusQualifier; /* 0x22 */ ++ U32 BidirectionalTransferCount; /*0x24 */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U32 EEDPErrorOffset; /* 0x28 */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U16 EEDPObservedAppTag; /* 0x2C */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U16 EEDPObservedGuard; /* 0x2E */ ++ /* MPI 2.5+ only; Reserved in MPI 2.0 */ ++ U32 EEDPObservedRefTag; /* 0x30 */ ++} MPI2_SCSI_IO_REPLY, *PTR_MPI2_SCSI_IO_REPLY, ++ Mpi2SCSIIOReply_t, *pMpi2SCSIIOReply_t; ++ ++/*SCSI IO Reply SCSIStatus values (SAM-4 status codes) */ ++ ++#define MPI2_SCSI_STATUS_GOOD (0x00) ++#define MPI2_SCSI_STATUS_CHECK_CONDITION (0x02) ++#define MPI2_SCSI_STATUS_CONDITION_MET (0x04) ++#define MPI2_SCSI_STATUS_BUSY (0x08) ++#define MPI2_SCSI_STATUS_INTERMEDIATE (0x10) ++#define MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET (0x14) ++#define MPI2_SCSI_STATUS_RESERVATION_CONFLICT (0x18) ++#define MPI2_SCSI_STATUS_COMMAND_TERMINATED (0x22) /*obsolete */ ++#define MPI2_SCSI_STATUS_TASK_SET_FULL (0x28) ++#define MPI2_SCSI_STATUS_ACA_ACTIVE (0x30) ++#define MPI2_SCSI_STATUS_TASK_ABORTED (0x40) ++ ++/*SCSI IO Reply SCSIState flags */ ++ ++#define MPI2_SCSI_STATE_RESPONSE_INFO_VALID (0x10) ++#define MPI2_SCSI_STATE_TERMINATED (0x08) ++#define MPI2_SCSI_STATE_NO_SCSI_STATUS (0x04) ++#define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02) ++#define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01) ++ ++/*masks and shifts for the ResponseInfo field */ ++ ++#define MPI2_SCSI_RI_MASK_REASONCODE (0x000000FF) ++#define MPI2_SCSI_RI_SHIFT_REASONCODE (0) ++ ++#define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF) ++ ++/**************************************************************************** ++* SCSI Task Management messages ++****************************************************************************/ ++ ++/*SCSI Task Management Request Message */ ++typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Reserved1; /*0x04 */ ++ U8 TaskType; /*0x05 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U8 LUN[8]; /*0x0C */ ++ U32 Reserved4[7]; /*0x14 */ ++ U16 TaskMID; /*0x30 */ ++ U16 Reserved5; /*0x32 */ ++} MPI2_SCSI_TASK_MANAGE_REQUEST, ++ *PTR_MPI2_SCSI_TASK_MANAGE_REQUEST, ++ Mpi2SCSITaskManagementRequest_t, ++ *pMpi2SCSITaskManagementRequest_t; ++ ++/*TaskType values */ ++ ++#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01) ++#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02) ++#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) ++#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) ++#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) ++#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) ++#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08) ++#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09) ++#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A) ++ ++/*obsolete TaskType name */ ++#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION \ ++ (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT) ++ ++/*MsgFlags bits */ ++ ++#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18) ++#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00) ++#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08) ++#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10) ++ ++#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01) ++ ++/*SCSI Task Management Reply Message */ ++typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 ResponseCode; /*0x04 */ ++ U8 TaskType; /*0x05 */ ++ U8 Reserved1; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 TerminationCount; /*0x14 */ ++ U32 ResponseInfo; /*0x18 */ ++} MPI2_SCSI_TASK_MANAGE_REPLY, ++ *PTR_MPI2_SCSI_TASK_MANAGE_REPLY, ++ Mpi2SCSITaskManagementReply_t, *pMpi2SCSIManagementReply_t; ++ ++/*ResponseCode values */ ++ ++#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE (0x00) ++#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME (0x02) ++#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04) ++#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05) ++#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08) ++#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09) ++#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A) ++#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80) ++ ++/*masks and shifts for the ResponseInfo field */ ++ ++#define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE (0x000000FF) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE (0) ++#define MPI2_SCSITASKMGMT_RI_MASK_ARI2 (0x0000FF00) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2 (8) ++#define MPI2_SCSITASKMGMT_RI_MASK_ARI1 (0x00FF0000) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1 (16) ++#define MPI2_SCSITASKMGMT_RI_MASK_ARI0 (0xFF000000) ++#define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0 (24) ++ ++/**************************************************************************** ++* SCSI Enclosure Processor messages ++****************************************************************************/ ++ ++/*SCSI Enclosure Processor Request Message */ ++typedef struct _MPI2_SEP_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Action; /*0x04 */ ++ U8 Flags; /*0x05 */ ++ U8 Reserved1; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U32 SlotStatus; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U32 Reserved4; /*0x14 */ ++ U32 Reserved5; /*0x18 */ ++ U16 Slot; /*0x1C */ ++ U16 EnclosureHandle; /*0x1E */ ++} MPI2_SEP_REQUEST, *PTR_MPI2_SEP_REQUEST, ++ Mpi2SepRequest_t, *pMpi2SepRequest_t; ++ ++/*Action defines */ ++#define MPI2_SEP_REQ_ACTION_WRITE_STATUS (0x00) ++#define MPI2_SEP_REQ_ACTION_READ_STATUS (0x01) ++ ++/*Flags defines */ ++#define MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS (0x00) ++#define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01) ++ ++/*SlotStatus defines */ ++#define MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF (0x00080000) ++#define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000) ++#define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) ++#define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200) ++#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) ++#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) ++#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040) ++#define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) ++#define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) ++#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004) ++#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002) ++#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001) ++ ++/*SCSI Enclosure Processor Reply Message */ ++typedef struct _MPI2_SEP_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Action; /*0x04 */ ++ U8 Flags; /*0x05 */ ++ U8 Reserved1; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 SlotStatus; /*0x14 */ ++ U32 Reserved4; /*0x18 */ ++ U16 Slot; /*0x1C */ ++ U16 EnclosureHandle; /*0x1E */ ++} MPI2_SEP_REPLY, *PTR_MPI2_SEP_REPLY, ++ Mpi2SepReply_t, *pMpi2SepReply_t; ++ ++/*SlotStatus defines */ ++#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF (0x00080000) ++#define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000) ++#define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) ++#define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200) ++#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) ++#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) ++#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040) ++#define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) ++#define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) ++#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004) ++#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002) ++#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001) ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +new file mode 100644 +index 0000000..8bae305 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h +@@ -0,0 +1,1860 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_ioc.h ++ * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages ++ * Creation Date: October 11, 2006 ++ * ++ * mpi2_ioc.h Version: 02.00.27 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-04-07 02.00.01 In IOCFacts Reply structure, renamed MaxDevices to ++ * MaxTargets. ++ * Added TotalImageSize field to FWDownload Request. ++ * Added reserved words to FWUpload Request. ++ * 06-26-07 02.00.02 Added IR Configuration Change List Event. ++ * 08-31-07 02.00.03 Removed SystemReplyQueueDepth field from the IOCInit ++ * request and replaced it with ++ * ReplyDescriptorPostQueueDepth and ReplyFreeQueueDepth. ++ * Replaced the MinReplyQueueDepth field of the IOCFacts ++ * reply with MaxReplyDescriptorPostQueueDepth. ++ * Added MPI2_RDPQ_DEPTH_MIN define to specify the minimum ++ * depth for the Reply Descriptor Post Queue. ++ * Added SASAddress field to Initiator Device Table ++ * Overflow Event data. ++ * 10-31-07 02.00.04 Added ReasonCode MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING ++ * for SAS Initiator Device Status Change Event data. ++ * Modified Reason Code defines for SAS Topology Change ++ * List Event data, including adding a bit for PHY Vacant ++ * status, and adding a mask for the Reason Code. ++ * Added define for ++ * MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING. ++ * Added define for MPI2_EXT_IMAGE_TYPE_MEGARAID. ++ * 12-18-07 02.00.05 Added Boot Status defines for the IOCExceptions field of ++ * the IOCFacts Reply. ++ * Removed MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. ++ * Moved MPI2_VERSION_UNION to mpi2.h. ++ * Changed MPI2_EVENT_NOTIFICATION_REQUEST to use masks ++ * instead of enables, and added SASBroadcastPrimitiveMasks ++ * field. ++ * Added Log Entry Added Event and related structure. ++ * 02-29-08 02.00.06 Added define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID. ++ * Removed define MPI2_IOCFACTS_PROTOCOL_SMP_TARGET. ++ * Added MaxVolumes and MaxPersistentEntries fields to ++ * IOCFacts reply. ++ * Added ProtocalFlags and IOCCapabilities fields to ++ * MPI2_FW_IMAGE_HEADER. ++ * Removed MPI2_PORTENABLE_FLAGS_ENABLE_SINGLE_PORT. ++ * 03-03-08 02.00.07 Fixed MPI2_FW_IMAGE_HEADER by changing Reserved26 to ++ * a U16 (from a U32). ++ * Removed extra 's' from EventMasks name. ++ * 06-27-08 02.00.08 Fixed an offset in a comment. ++ * 10-02-08 02.00.09 Removed SystemReplyFrameSize from MPI2_IOC_INIT_REQUEST. ++ * Removed CurReplyFrameSize from MPI2_IOC_FACTS_REPLY and ++ * renamed MinReplyFrameSize to ReplyFrameSize. ++ * Added MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX. ++ * Added two new RAIDOperation values for Integrated RAID ++ * Operations Status Event data. ++ * Added four new IR Configuration Change List Event data ++ * ReasonCode values. ++ * Added two new ReasonCode defines for SAS Device Status ++ * Change Event data. ++ * Added three new DiscoveryStatus bits for the SAS ++ * Discovery event data. ++ * Added Multiplexing Status Change bit to the PhyStatus ++ * field of the SAS Topology Change List event data. ++ * Removed define for MPI2_INIT_IMAGE_BOOTFLAGS_XMEMCOPY. ++ * BootFlags are now product-specific. ++ * Added defines for the indivdual signature bytes ++ * for MPI2_INIT_IMAGE_FOOTER. ++ * 01-19-09 02.00.10 Added MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY define. ++ * Added MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR ++ * define. ++ * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE ++ * define. ++ * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define. ++ * 05-06-09 02.00.11 Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define. ++ * Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define. ++ * Added two new reason codes for SAS Device Status Change ++ * Event. ++ * Added new event: SAS PHY Counter. ++ * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure. ++ * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. ++ * Added new product id family for 2208. ++ * 10-28-09 02.00.13 Added HostMSIxVectors field to MPI2_IOC_INIT_REQUEST. ++ * Added MaxMSIxVectors field to MPI2_IOC_FACTS_REPLY. ++ * Added MinDevHandle field to MPI2_IOC_FACTS_REPLY. ++ * Added MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY. ++ * Added MPI2_EVENT_HOST_BASED_DISCOVERY_PHY define. ++ * Added MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER define. ++ * Added Host Based Discovery Phy Event data. ++ * Added defines for ProductID Product field ++ * (MPI2_FW_HEADER_PID_). ++ * Modified values for SAS ProductID Family ++ * (MPI2_FW_HEADER_PID_FAMILY_). ++ * 02-10-10 02.00.14 Added SAS Quiesce Event structure and defines. ++ * Added PowerManagementControl Request structures and ++ * defines. ++ * 05-12-10 02.00.15 Marked Task Set Full Event as obsolete. ++ * Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define. ++ * 11-10-10 02.00.16 Added MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC. ++ * 02-23-11 02.00.17 Added SAS NOTIFY Primitive event, and added ++ * SASNotifyPrimitiveMasks field to ++ * MPI2_EVENT_NOTIFICATION_REQUEST. ++ * Added Temperature Threshold Event. ++ * Added Host Message Event. ++ * Added Send Host Message request and reply. ++ * 05-25-11 02.00.18 For Extended Image Header, added ++ * MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC and ++ * MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC defines. ++ * Deprecated MPI2_EXT_IMAGE_TYPE_MAX define. ++ * 08-24-11 02.00.19 Added PhysicalPort field to ++ * MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure. ++ * Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete. ++ * 11-18-11 02.00.20 Incorporating additions for MPI v2.5. ++ * 03-29-12 02.00.21 Added a product specific range to event values. ++ * 07-26-12 02.00.22 Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE. ++ * Added ElapsedSeconds field to ++ * MPI2_EVENT_DATA_IR_OPERATION_STATUS. ++ * 08-19-13 02.00.23 For IOCInit, added MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE ++ * and MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY. ++ * Added MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE. ++ * Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY. ++ * Added Encrypted Hash Extended Image. ++ * 12-05-13 02.00.24 Added MPI25_HASH_IMAGE_TYPE_BIOS. ++ * 11-18-14 02.00.25 Updated copyright information. ++ * 03-16-15 02.00.26 Updated for MPI v2.6. ++ * Added MPI2_EVENT_ACTIVE_CABLE_EXCEPTION and ++ * MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT. ++ * Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and ++ * MPI26_FW_HEADER_PID_FAMILY_3516_SAS. ++ * Added MPI26_CTRL_OP_SHUTDOWN. ++ * 08-25-15 02.00.27 Added IC ARCH Class based signature defines ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_IOC_H ++#define MPI2_IOC_H ++ ++/***************************************************************************** ++* ++* IOC Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* IOCInit message ++****************************************************************************/ ++ ++/*IOCInit Request message */ ++typedef struct _MPI2_IOC_INIT_REQUEST { ++ U8 WhoInit; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 MsgVersion; /*0x0C */ ++ U16 HeaderVersion; /*0x0E */ ++ U32 Reserved5; /*0x10 */ ++ U16 ConfigurationFlags; /* 0x14 */ ++ U8 HostPageSize; /*0x16 */ ++ U8 HostMSIxVectors; /*0x17 */ ++ U16 Reserved8; /*0x18 */ ++ U16 SystemRequestFrameSize; /*0x1A */ ++ U16 ReplyDescriptorPostQueueDepth; /*0x1C */ ++ U16 ReplyFreeQueueDepth; /*0x1E */ ++ U32 SenseBufferAddressHigh; /*0x20 */ ++ U32 SystemReplyAddressHigh; /*0x24 */ ++ U64 SystemRequestFrameBaseAddress; /*0x28 */ ++ U64 ReplyDescriptorPostQueueAddress; /*0x30 */ ++ U64 ReplyFreeQueueAddress; /*0x38 */ ++ U64 TimeStamp; /*0x40 */ ++} MPI2_IOC_INIT_REQUEST, *PTR_MPI2_IOC_INIT_REQUEST, ++ Mpi2IOCInitRequest_t, *pMpi2IOCInitRequest_t; ++ ++/*WhoInit values */ ++#define MPI2_WHOINIT_NOT_INITIALIZED (0x00) ++#define MPI2_WHOINIT_SYSTEM_BIOS (0x01) ++#define MPI2_WHOINIT_ROM_BIOS (0x02) ++#define MPI2_WHOINIT_PCI_PEER (0x03) ++#define MPI2_WHOINIT_HOST_DRIVER (0x04) ++#define MPI2_WHOINIT_MANUFACTURER (0x05) ++ ++/* MsgFlags */ ++#define MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE (0x01) ++ ++ ++/*MsgVersion */ ++#define MPI2_IOCINIT_MSGVERSION_MAJOR_MASK (0xFF00) ++#define MPI2_IOCINIT_MSGVERSION_MAJOR_SHIFT (8) ++#define MPI2_IOCINIT_MSGVERSION_MINOR_MASK (0x00FF) ++#define MPI2_IOCINIT_MSGVERSION_MINOR_SHIFT (0) ++ ++/*HeaderVersion */ ++#define MPI2_IOCINIT_HDRVERSION_UNIT_MASK (0xFF00) ++#define MPI2_IOCINIT_HDRVERSION_UNIT_SHIFT (8) ++#define MPI2_IOCINIT_HDRVERSION_DEV_MASK (0x00FF) ++#define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT (0) ++ ++/*minimum depth for a Reply Descriptor Post Queue */ ++#define MPI2_RDPQ_DEPTH_MIN (16) ++ ++/* Reply Descriptor Post Queue Array Entry */ ++typedef struct _MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY { ++ U64 RDPQBaseAddress; /* 0x00 */ ++ U32 Reserved1; /* 0x08 */ ++ U32 Reserved2; /* 0x0C */ ++} MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY, ++*PTR_MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY, ++Mpi2IOCInitRDPQArrayEntry, *pMpi2IOCInitRDPQArrayEntry; ++ ++ ++/*IOCInit Reply message */ ++typedef struct _MPI2_IOC_INIT_REPLY { ++ U8 WhoInit; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_IOC_INIT_REPLY, *PTR_MPI2_IOC_INIT_REPLY, ++ Mpi2IOCInitReply_t, *pMpi2IOCInitReply_t; ++ ++/**************************************************************************** ++* IOCFacts message ++****************************************************************************/ ++ ++/*IOCFacts Request message */ ++typedef struct _MPI2_IOC_FACTS_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++} MPI2_IOC_FACTS_REQUEST, *PTR_MPI2_IOC_FACTS_REQUEST, ++ Mpi2IOCFactsRequest_t, *pMpi2IOCFactsRequest_t; ++ ++/*IOCFacts Reply message */ ++typedef struct _MPI2_IOC_FACTS_REPLY { ++ U16 MsgVersion; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 HeaderVersion; /*0x04 */ ++ U8 IOCNumber; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U16 IOCExceptions; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 MaxChainDepth; /*0x14 */ ++ U8 WhoInit; /*0x15 */ ++ U8 NumberOfPorts; /*0x16 */ ++ U8 MaxMSIxVectors; /*0x17 */ ++ U16 RequestCredit; /*0x18 */ ++ U16 ProductID; /*0x1A */ ++ U32 IOCCapabilities; /*0x1C */ ++ MPI2_VERSION_UNION FWVersion; /*0x20 */ ++ U16 IOCRequestFrameSize; /*0x24 */ ++ U16 IOCMaxChainSegmentSize; /*0x26 */ ++ U16 MaxInitiators; /*0x28 */ ++ U16 MaxTargets; /*0x2A */ ++ U16 MaxSasExpanders; /*0x2C */ ++ U16 MaxEnclosures; /*0x2E */ ++ U16 ProtocolFlags; /*0x30 */ ++ U16 HighPriorityCredit; /*0x32 */ ++ U16 MaxReplyDescriptorPostQueueDepth; /*0x34 */ ++ U8 ReplyFrameSize; /*0x36 */ ++ U8 MaxVolumes; /*0x37 */ ++ U16 MaxDevHandle; /*0x38 */ ++ U16 MaxPersistentEntries; /*0x3A */ ++ U16 MinDevHandle; /*0x3C */ ++ U8 CurrentHostPageSize; /* 0x3E */ ++ U8 Reserved4; /* 0x3F */ ++} MPI2_IOC_FACTS_REPLY, *PTR_MPI2_IOC_FACTS_REPLY, ++ Mpi2IOCFactsReply_t, *pMpi2IOCFactsReply_t; ++ ++/*MsgVersion */ ++#define MPI2_IOCFACTS_MSGVERSION_MAJOR_MASK (0xFF00) ++#define MPI2_IOCFACTS_MSGVERSION_MAJOR_SHIFT (8) ++#define MPI2_IOCFACTS_MSGVERSION_MINOR_MASK (0x00FF) ++#define MPI2_IOCFACTS_MSGVERSION_MINOR_SHIFT (0) ++ ++/*HeaderVersion */ ++#define MPI2_IOCFACTS_HDRVERSION_UNIT_MASK (0xFF00) ++#define MPI2_IOCFACTS_HDRVERSION_UNIT_SHIFT (8) ++#define MPI2_IOCFACTS_HDRVERSION_DEV_MASK (0x00FF) ++#define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0) ++ ++/*IOCExceptions */ ++#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE (0x0200) ++#define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100) ++ ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK (0x00E0) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_GOOD (0x0000) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_BACKUP (0x0020) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_RESTORED (0x0040) ++#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_CORRUPT_BACKUP (0x0060) ++ ++#define MPI2_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED (0x0010) ++#define MPI2_IOCFACTS_EXCEPT_MANUFACT_CHECKSUM_FAIL (0x0008) ++#define MPI2_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004) ++#define MPI2_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002) ++#define MPI2_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL (0x0001) ++ ++/*defines for WhoInit field are after the IOCInit Request */ ++ ++/*ProductID field uses MPI2_FW_HEADER_PID_ */ ++ ++/*IOCCapabilities */ ++#define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000) ++#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000) ++#define MPI25_IOCFACTS_CAPABILITY_FAST_PATH_CAPABLE (0x00020000) ++#define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY (0x00010000) ++#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) ++#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) ++#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) ++#define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID (0x00001000) ++#define MPI2_IOCFACTS_CAPABILITY_TLR (0x00000800) ++#define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) ++#define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080) ++#define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040) ++#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) ++#define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) ++#define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) ++#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004) ++ ++/*ProtocolFlags */ ++#define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR (0x0002) ++#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET (0x0001) ++ ++/**************************************************************************** ++* PortFacts message ++****************************************************************************/ ++ ++/*PortFacts Request message */ ++typedef struct _MPI2_PORT_FACTS_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 PortNumber; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++} MPI2_PORT_FACTS_REQUEST, *PTR_MPI2_PORT_FACTS_REQUEST, ++ Mpi2PortFactsRequest_t, *pMpi2PortFactsRequest_t; ++ ++/*PortFacts Reply message */ ++typedef struct _MPI2_PORT_FACTS_REPLY { ++ U16 Reserved1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 PortNumber; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 Reserved5; /*0x14 */ ++ U8 PortType; /*0x15 */ ++ U16 Reserved6; /*0x16 */ ++ U16 MaxPostedCmdBuffers; /*0x18 */ ++ U16 Reserved7; /*0x1A */ ++} MPI2_PORT_FACTS_REPLY, *PTR_MPI2_PORT_FACTS_REPLY, ++ Mpi2PortFactsReply_t, *pMpi2PortFactsReply_t; ++ ++/*PortType values */ ++#define MPI2_PORTFACTS_PORTTYPE_INACTIVE (0x00) ++#define MPI2_PORTFACTS_PORTTYPE_FC (0x10) ++#define MPI2_PORTFACTS_PORTTYPE_ISCSI (0x20) ++#define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL (0x30) ++#define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL (0x31) ++ ++/**************************************************************************** ++* PortEnable message ++****************************************************************************/ ++ ++/*PortEnable Request message */ ++typedef struct _MPI2_PORT_ENABLE_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Reserved2; /*0x04 */ ++ U8 PortFlags; /*0x05 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++} MPI2_PORT_ENABLE_REQUEST, *PTR_MPI2_PORT_ENABLE_REQUEST, ++ Mpi2PortEnableRequest_t, *pMpi2PortEnableRequest_t; ++ ++/*PortEnable Reply message */ ++typedef struct _MPI2_PORT_ENABLE_REPLY { ++ U16 Reserved1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U8 Reserved2; /*0x04 */ ++ U8 PortFlags; /*0x05 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_PORT_ENABLE_REPLY, *PTR_MPI2_PORT_ENABLE_REPLY, ++ Mpi2PortEnableReply_t, *pMpi2PortEnableReply_t; ++ ++/**************************************************************************** ++* EventNotification message ++****************************************************************************/ ++ ++/*EventNotification Request message */ ++#define MPI2_EVENT_NOTIFY_EVENTMASK_WORDS (4) ++ ++typedef struct _MPI2_EVENT_NOTIFICATION_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ U32 EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; /*0x14 */ ++ U16 SASBroadcastPrimitiveMasks; /*0x24 */ ++ U16 SASNotifyPrimitiveMasks; /*0x26 */ ++ U32 Reserved8; /*0x28 */ ++} MPI2_EVENT_NOTIFICATION_REQUEST, ++ *PTR_MPI2_EVENT_NOTIFICATION_REQUEST, ++ Mpi2EventNotificationRequest_t, ++ *pMpi2EventNotificationRequest_t; ++ ++/*EventNotification Reply message */ ++typedef struct _MPI2_EVENT_NOTIFICATION_REPLY { ++ U16 EventDataLength; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 AckRequired; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U16 Event; /*0x14 */ ++ U16 Reserved4; /*0x16 */ ++ U32 EventContext; /*0x18 */ ++ U32 EventData[1]; /*0x1C */ ++} MPI2_EVENT_NOTIFICATION_REPLY, *PTR_MPI2_EVENT_NOTIFICATION_REPLY, ++ Mpi2EventNotificationReply_t, ++ *pMpi2EventNotificationReply_t; ++ ++/*AckRequired */ ++#define MPI2_EVENT_NOTIFICATION_ACK_NOT_REQUIRED (0x00) ++#define MPI2_EVENT_NOTIFICATION_ACK_REQUIRED (0x01) ++ ++/*Event */ ++#define MPI2_EVENT_LOG_DATA (0x0001) ++#define MPI2_EVENT_STATE_CHANGE (0x0002) ++#define MPI2_EVENT_HARD_RESET_RECEIVED (0x0005) ++#define MPI2_EVENT_EVENT_CHANGE (0x000A) ++#define MPI2_EVENT_TASK_SET_FULL (0x000E) /*obsolete */ ++#define MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE (0x000F) ++#define MPI2_EVENT_IR_OPERATION_STATUS (0x0014) ++#define MPI2_EVENT_SAS_DISCOVERY (0x0016) ++#define MPI2_EVENT_SAS_BROADCAST_PRIMITIVE (0x0017) ++#define MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x0018) ++#define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW (0x0019) ++#define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST (0x001C) ++#define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE (0x001D) ++#define MPI2_EVENT_IR_VOLUME (0x001E) ++#define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F) ++#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) ++#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) ++#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) ++#define MPI2_EVENT_GPIO_INTERRUPT (0x0023) ++#define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY (0x0024) ++#define MPI2_EVENT_SAS_QUIESCE (0x0025) ++#define MPI2_EVENT_SAS_NOTIFY_PRIMITIVE (0x0026) ++#define MPI2_EVENT_TEMP_THRESHOLD (0x0027) ++#define MPI2_EVENT_HOST_MESSAGE (0x0028) ++#define MPI2_EVENT_POWER_PERFORMANCE_CHANGE (0x0029) ++#define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION (0x0034) ++#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC (0x006E) ++#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC (0x007F) ++ ++/*Log Entry Added Event data */ ++ ++/*the following structure matches MPI2_LOG_0_ENTRY in mpi2_cnfg.h */ ++#define MPI2_EVENT_DATA_LOG_DATA_LENGTH (0x1C) ++ ++typedef struct _MPI2_EVENT_DATA_LOG_ENTRY_ADDED { ++ U64 TimeStamp; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U16 LogSequence; /*0x0C */ ++ U16 LogEntryQualifier; /*0x0E */ ++ U8 VP_ID; /*0x10 */ ++ U8 VF_ID; /*0x11 */ ++ U16 Reserved2; /*0x12 */ ++ U8 LogData[MPI2_EVENT_DATA_LOG_DATA_LENGTH]; /*0x14 */ ++} MPI2_EVENT_DATA_LOG_ENTRY_ADDED, ++ *PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED, ++ Mpi2EventDataLogEntryAdded_t, ++ *pMpi2EventDataLogEntryAdded_t; ++ ++/*GPIO Interrupt Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT { ++ U8 GPIONum; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++} MPI2_EVENT_DATA_GPIO_INTERRUPT, ++ *PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT, ++ Mpi2EventDataGpioInterrupt_t, ++ *pMpi2EventDataGpioInterrupt_t; ++ ++/*Temperature Threshold Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_TEMPERATURE { ++ U16 Status; /*0x00 */ ++ U8 SensorNum; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U16 CurrentTemperature; /*0x04 */ ++ U16 Reserved2; /*0x06 */ ++ U32 Reserved3; /*0x08 */ ++ U32 Reserved4; /*0x0C */ ++} MPI2_EVENT_DATA_TEMPERATURE, ++ *PTR_MPI2_EVENT_DATA_TEMPERATURE, ++ Mpi2EventDataTemperature_t, *pMpi2EventDataTemperature_t; ++ ++/*Temperature Threshold Event data Status bits */ ++#define MPI2_EVENT_TEMPERATURE3_EXCEEDED (0x0008) ++#define MPI2_EVENT_TEMPERATURE2_EXCEEDED (0x0004) ++#define MPI2_EVENT_TEMPERATURE1_EXCEEDED (0x0002) ++#define MPI2_EVENT_TEMPERATURE0_EXCEEDED (0x0001) ++ ++/*Host Message Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE { ++ U8 SourceVF_ID; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Reserved3; /*0x04 */ ++ U32 HostData[1]; /*0x08 */ ++} MPI2_EVENT_DATA_HOST_MESSAGE, *PTR_MPI2_EVENT_DATA_HOST_MESSAGE, ++ Mpi2EventDataHostMessage_t, *pMpi2EventDataHostMessage_t; ++ ++/*Power Performance Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_POWER_PERF_CHANGE { ++ U8 CurrentPowerMode; /*0x00 */ ++ U8 PreviousPowerMode; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_EVENT_DATA_POWER_PERF_CHANGE, ++ *PTR_MPI2_EVENT_DATA_POWER_PERF_CHANGE, ++ Mpi2EventDataPowerPerfChange_t, ++ *pMpi2EventDataPowerPerfChange_t; ++ ++/*defines for CurrentPowerMode and PreviousPowerMode fields */ ++#define MPI2_EVENT_PM_INIT_MASK (0xC0) ++#define MPI2_EVENT_PM_INIT_UNAVAILABLE (0x00) ++#define MPI2_EVENT_PM_INIT_HOST (0x40) ++#define MPI2_EVENT_PM_INIT_IO_UNIT (0x80) ++#define MPI2_EVENT_PM_INIT_PCIE_DPA (0xC0) ++ ++#define MPI2_EVENT_PM_MODE_MASK (0x07) ++#define MPI2_EVENT_PM_MODE_UNAVAILABLE (0x00) ++#define MPI2_EVENT_PM_MODE_UNKNOWN (0x01) ++#define MPI2_EVENT_PM_MODE_FULL_POWER (0x04) ++#define MPI2_EVENT_PM_MODE_REDUCED_POWER (0x05) ++#define MPI2_EVENT_PM_MODE_STANDBY (0x06) ++ ++/* Active Cable Exception Event data */ ++ ++typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT { ++ U32 ActiveCablePowerRequirement; /* 0x00 */ ++ U8 ReasonCode; /* 0x04 */ ++ U8 ReceptacleID; /* 0x05 */ ++ U16 Reserved1; /* 0x06 */ ++} MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT, ++ *PTR_MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT, ++ Mpi26EventDataActiveCableExcept_t, ++ *pMpi26EventDataActiveCableExcept_t; ++ ++/* defines for ReasonCode field */ ++#define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00) ++ ++/*Hard Reset Received Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED { ++ U8 Reserved1; /*0x00 */ ++ U8 Port; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++} MPI2_EVENT_DATA_HARD_RESET_RECEIVED, ++ *PTR_MPI2_EVENT_DATA_HARD_RESET_RECEIVED, ++ Mpi2EventDataHardResetReceived_t, ++ *pMpi2EventDataHardResetReceived_t; ++ ++/*Task Set Full Event data */ ++/* this event is obsolete */ ++ ++typedef struct _MPI2_EVENT_DATA_TASK_SET_FULL { ++ U16 DevHandle; /*0x00 */ ++ U16 CurrentDepth; /*0x02 */ ++} MPI2_EVENT_DATA_TASK_SET_FULL, *PTR_MPI2_EVENT_DATA_TASK_SET_FULL, ++ Mpi2EventDataTaskSetFull_t, *pMpi2EventDataTaskSetFull_t; ++ ++/*SAS Device Status Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE { ++ U16 TaskTag; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 PhysicalPort; /*0x03 */ ++ U8 ASC; /*0x04 */ ++ U8 ASCQ; /*0x05 */ ++ U16 DevHandle; /*0x06 */ ++ U32 Reserved2; /*0x08 */ ++ U64 SASAddress; /*0x0C */ ++ U8 LUN[8]; /*0x14 */ ++} MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, ++ *PTR_MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE, ++ Mpi2EventDataSasDeviceStatusChange_t, ++ *pMpi2EventDataSasDeviceStatusChange_t; ++ ++/*SAS Device Status Change Event data ReasonCode values */ ++#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY (0x11) ++#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY (0x12) ++ ++/*Integrated RAID Operation Status Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS { ++ U16 VolDevHandle; /*0x00 */ ++ U16 Reserved1; /*0x02 */ ++ U8 RAIDOperation; /*0x04 */ ++ U8 PercentComplete; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U32 ElapsedSeconds; /*0x08 */ ++} MPI2_EVENT_DATA_IR_OPERATION_STATUS, ++ *PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS, ++ Mpi2EventDataIrOperationStatus_t, ++ *pMpi2EventDataIrOperationStatus_t; ++ ++/*Integrated RAID Operation Status Event data RAIDOperation values */ ++#define MPI2_EVENT_IR_RAIDOP_RESYNC (0x00) ++#define MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION (0x01) ++#define MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK (0x02) ++#define MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT (0x03) ++#define MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT (0x04) ++ ++/*Integrated RAID Volume Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_IR_VOLUME { ++ U16 VolDevHandle; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U32 NewValue; /*0x04 */ ++ U32 PreviousValue; /*0x08 */ ++} MPI2_EVENT_DATA_IR_VOLUME, *PTR_MPI2_EVENT_DATA_IR_VOLUME, ++ Mpi2EventDataIrVolume_t, *pMpi2EventDataIrVolume_t; ++ ++/*Integrated RAID Volume Event data ReasonCode values */ ++#define MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED (0x01) ++#define MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED (0x02) ++#define MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED (0x03) ++ ++/*Integrated RAID Physical Disk Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_IR_PHYSICAL_DISK { ++ U16 Reserved1; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 PhysDiskNum; /*0x03 */ ++ U16 PhysDiskDevHandle; /*0x04 */ ++ U16 Reserved2; /*0x06 */ ++ U16 Slot; /*0x08 */ ++ U16 EnclosureHandle; /*0x0A */ ++ U32 NewValue; /*0x0C */ ++ U32 PreviousValue; /*0x10 */ ++} MPI2_EVENT_DATA_IR_PHYSICAL_DISK, ++ *PTR_MPI2_EVENT_DATA_IR_PHYSICAL_DISK, ++ Mpi2EventDataIrPhysicalDisk_t, ++ *pMpi2EventDataIrPhysicalDisk_t; ++ ++/*Integrated RAID Physical Disk Event data ReasonCode values */ ++#define MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED (0x01) ++#define MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED (0x02) ++#define MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED (0x03) ++ ++/*Integrated RAID Configuration Change List Event data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumElements at runtime. ++ */ ++#ifndef MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT ++#define MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT (1) ++#endif ++ ++typedef struct _MPI2_EVENT_IR_CONFIG_ELEMENT { ++ U16 ElementFlags; /*0x00 */ ++ U16 VolDevHandle; /*0x02 */ ++ U8 ReasonCode; /*0x04 */ ++ U8 PhysDiskNum; /*0x05 */ ++ U16 PhysDiskDevHandle; /*0x06 */ ++} MPI2_EVENT_IR_CONFIG_ELEMENT, *PTR_MPI2_EVENT_IR_CONFIG_ELEMENT, ++ Mpi2EventIrConfigElement_t, *pMpi2EventIrConfigElement_t; ++ ++/*IR Configuration Change List Event data ElementFlags values */ ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK (0x000F) ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT (0x0000) ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT (0x0001) ++#define MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT (0x0002) ++ ++/*IR Configuration Change List Event data ReasonCode values */ ++#define MPI2_EVENT_IR_CHANGE_RC_ADDED (0x01) ++#define MPI2_EVENT_IR_CHANGE_RC_REMOVED (0x02) ++#define MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE (0x03) ++#define MPI2_EVENT_IR_CHANGE_RC_HIDE (0x04) ++#define MPI2_EVENT_IR_CHANGE_RC_UNHIDE (0x05) ++#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED (0x06) ++#define MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED (0x07) ++#define MPI2_EVENT_IR_CHANGE_RC_PD_CREATED (0x08) ++#define MPI2_EVENT_IR_CHANGE_RC_PD_DELETED (0x09) ++ ++typedef struct _MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST { ++ U8 NumElements; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 Reserved2; /*0x02 */ ++ U8 ConfigNum; /*0x03 */ ++ U32 Flags; /*0x04 */ ++ MPI2_EVENT_IR_CONFIG_ELEMENT ++ ConfigElement[MPI2_EVENT_IR_CONFIG_ELEMENT_COUNT];/*0x08 */ ++} MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST, ++ *PTR_MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST, ++ Mpi2EventDataIrConfigChangeList_t, ++ *pMpi2EventDataIrConfigChangeList_t; ++ ++/*IR Configuration Change List Event data Flags values */ ++#define MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG (0x00000001) ++ ++/*SAS Discovery Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_DISCOVERY { ++ U8 Flags; /*0x00 */ ++ U8 ReasonCode; /*0x01 */ ++ U8 PhysicalPort; /*0x02 */ ++ U8 Reserved1; /*0x03 */ ++ U32 DiscoveryStatus; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_DISCOVERY, ++ *PTR_MPI2_EVENT_DATA_SAS_DISCOVERY, ++ Mpi2EventDataSasDiscovery_t, *pMpi2EventDataSasDiscovery_t; ++ ++/*SAS Discovery Event data Flags values */ ++#define MPI2_EVENT_SAS_DISC_DEVICE_CHANGE (0x02) ++#define MPI2_EVENT_SAS_DISC_IN_PROGRESS (0x01) ++ ++/*SAS Discovery Event data ReasonCode values */ ++#define MPI2_EVENT_SAS_DISC_RC_STARTED (0x01) ++#define MPI2_EVENT_SAS_DISC_RC_COMPLETED (0x02) ++ ++/*SAS Discovery Event data DiscoveryStatus values */ ++#define MPI2_EVENT_SAS_DISC_DS_MAX_ENCLOSURES_EXCEED (0x80000000) ++#define MPI2_EVENT_SAS_DISC_DS_MAX_EXPANDERS_EXCEED (0x40000000) ++#define MPI2_EVENT_SAS_DISC_DS_MAX_DEVICES_EXCEED (0x20000000) ++#define MPI2_EVENT_SAS_DISC_DS_MAX_TOPO_PHYS_EXCEED (0x10000000) ++#define MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR (0x08000000) ++#define MPI2_EVENT_SAS_DISC_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE (0x00008000) ++#define MPI2_EVENT_SAS_DISC_DS_EXP_MULTI_SUBTRACTIVE (0x00004000) ++#define MPI2_EVENT_SAS_DISC_DS_MULTI_PORT_DOMAIN (0x00002000) ++#define MPI2_EVENT_SAS_DISC_DS_TABLE_TO_SUBTRACTIVE_LINK (0x00001000) ++#define MPI2_EVENT_SAS_DISC_DS_UNSUPPORTED_DEVICE (0x00000800) ++#define MPI2_EVENT_SAS_DISC_DS_TABLE_LINK (0x00000400) ++#define MPI2_EVENT_SAS_DISC_DS_SUBTRACTIVE_LINK (0x00000200) ++#define MPI2_EVENT_SAS_DISC_DS_SMP_CRC_ERROR (0x00000100) ++#define MPI2_EVENT_SAS_DISC_DS_SMP_FUNCTION_FAILED (0x00000080) ++#define MPI2_EVENT_SAS_DISC_DS_INDEX_NOT_EXIST (0x00000040) ++#define MPI2_EVENT_SAS_DISC_DS_OUT_ROUTE_ENTRIES (0x00000020) ++#define MPI2_EVENT_SAS_DISC_DS_SMP_TIMEOUT (0x00000010) ++#define MPI2_EVENT_SAS_DISC_DS_MULTIPLE_PORTS (0x00000004) ++#define MPI2_EVENT_SAS_DISC_DS_UNADDRESSABLE_DEVICE (0x00000002) ++#define MPI2_EVENT_SAS_DISC_DS_LOOP_DETECTED (0x00000001) ++ ++/*SAS Broadcast Primitive Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE { ++ U8 PhyNum; /*0x00 */ ++ U8 Port; /*0x01 */ ++ U8 PortWidth; /*0x02 */ ++ U8 Primitive; /*0x03 */ ++} MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, ++ *PTR_MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE, ++ Mpi2EventDataSasBroadcastPrimitive_t, ++ *pMpi2EventDataSasBroadcastPrimitive_t; ++ ++/*defines for the Primitive field */ ++#define MPI2_EVENT_PRIMITIVE_CHANGE (0x01) ++#define MPI2_EVENT_PRIMITIVE_SES (0x02) ++#define MPI2_EVENT_PRIMITIVE_EXPANDER (0x03) ++#define MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT (0x04) ++#define MPI2_EVENT_PRIMITIVE_RESERVED3 (0x05) ++#define MPI2_EVENT_PRIMITIVE_RESERVED4 (0x06) ++#define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED (0x07) ++#define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED (0x08) ++ ++/*SAS Notify Primitive Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE { ++ U8 PhyNum; /*0x00 */ ++ U8 Port; /*0x01 */ ++ U8 Reserved1; /*0x02 */ ++ U8 Primitive; /*0x03 */ ++} MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE, ++ *PTR_MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE, ++ Mpi2EventDataSasNotifyPrimitive_t, ++ *pMpi2EventDataSasNotifyPrimitive_t; ++ ++/*defines for the Primitive field */ ++#define MPI2_EVENT_NOTIFY_ENABLE_SPINUP (0x01) ++#define MPI2_EVENT_NOTIFY_POWER_LOSS_EXPECTED (0x02) ++#define MPI2_EVENT_NOTIFY_RESERVED1 (0x03) ++#define MPI2_EVENT_NOTIFY_RESERVED2 (0x04) ++ ++/*SAS Initiator Device Status Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE { ++ U8 ReasonCode; /*0x00 */ ++ U8 PhysicalPort; /*0x01 */ ++ U16 DevHandle; /*0x02 */ ++ U64 SASAddress; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, ++ *PTR_MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE, ++ Mpi2EventDataSasInitDevStatusChange_t, ++ *pMpi2EventDataSasInitDevStatusChange_t; ++ ++/*SAS Initiator Device Status Change event ReasonCode values */ ++#define MPI2_EVENT_SAS_INIT_RC_ADDED (0x01) ++#define MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING (0x02) ++ ++/*SAS Initiator Device Table Overflow Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW { ++ U16 MaxInit; /*0x00 */ ++ U16 CurrentInit; /*0x02 */ ++ U64 SASAddress; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, ++ *PTR_MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, ++ Mpi2EventDataSasInitTableOverflow_t, ++ *pMpi2EventDataSasInitTableOverflow_t; ++ ++/*SAS Topology Change List Event data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumEntries at runtime. ++ */ ++#ifndef MPI2_EVENT_SAS_TOPO_PHY_COUNT ++#define MPI2_EVENT_SAS_TOPO_PHY_COUNT (1) ++#endif ++ ++typedef struct _MPI2_EVENT_SAS_TOPO_PHY_ENTRY { ++ U16 AttachedDevHandle; /*0x00 */ ++ U8 LinkRate; /*0x02 */ ++ U8 PhyStatus; /*0x03 */ ++} MPI2_EVENT_SAS_TOPO_PHY_ENTRY, *PTR_MPI2_EVENT_SAS_TOPO_PHY_ENTRY, ++ Mpi2EventSasTopoPhyEntry_t, *pMpi2EventSasTopoPhyEntry_t; ++ ++typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST { ++ U16 EnclosureHandle; /*0x00 */ ++ U16 ExpanderDevHandle; /*0x02 */ ++ U8 NumPhys; /*0x04 */ ++ U8 Reserved1; /*0x05 */ ++ U16 Reserved2; /*0x06 */ ++ U8 NumEntries; /*0x08 */ ++ U8 StartPhyNum; /*0x09 */ ++ U8 ExpStatus; /*0x0A */ ++ U8 PhysicalPort; /*0x0B */ ++ MPI2_EVENT_SAS_TOPO_PHY_ENTRY ++ PHY[MPI2_EVENT_SAS_TOPO_PHY_COUNT]; /*0x0C */ ++} MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST, ++ *PTR_MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST, ++ Mpi2EventDataSasTopologyChangeList_t, ++ *pMpi2EventDataSasTopologyChangeList_t; ++ ++/*values for the ExpStatus field */ ++#define MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER (0x00) ++#define MPI2_EVENT_SAS_TOPO_ES_ADDED (0x01) ++#define MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02) ++#define MPI2_EVENT_SAS_TOPO_ES_RESPONDING (0x03) ++#define MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING (0x04) ++ ++/*defines for the LinkRate field */ ++#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK (0xF0) ++#define MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT (4) ++#define MPI2_EVENT_SAS_TOPO_LR_PREV_MASK (0x0F) ++#define MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT (0) ++ ++#define MPI2_EVENT_SAS_TOPO_LR_UNKNOWN_LINK_RATE (0x00) ++#define MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED (0x01) ++#define MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED (0x02) ++#define MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE (0x03) ++#define MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR (0x04) ++#define MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS (0x05) ++#define MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY (0x06) ++#define MPI2_EVENT_SAS_TOPO_LR_RATE_1_5 (0x08) ++#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09) ++#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A) ++#define MPI25_EVENT_SAS_TOPO_LR_RATE_12_0 (0x0B) ++ ++/*values for the PhyStatus field */ ++#define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT (0x80) ++#define MPI2_EVENT_SAS_TOPO_PS_MULTIPLEX_CHANGE (0x10) ++/*values for the PhyStatus ReasonCode sub-field */ ++#define MPI2_EVENT_SAS_TOPO_RC_MASK (0x0F) ++#define MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED (0x01) ++#define MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING (0x02) ++#define MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED (0x03) ++#define MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE (0x04) ++#define MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING (0x05) ++ ++/*SAS Enclosure Device Status Change Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE { ++ U16 EnclosureHandle; /*0x00 */ ++ U8 ReasonCode; /*0x02 */ ++ U8 PhysicalPort; /*0x03 */ ++ U64 EnclosureLogicalID; /*0x04 */ ++ U16 NumSlots; /*0x0C */ ++ U16 StartSlot; /*0x0E */ ++ U32 PhyBits; /*0x10 */ ++} MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE, ++ *PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE, ++ Mpi2EventDataSasEnclDevStatusChange_t, ++ *pMpi2EventDataSasEnclDevStatusChange_t; ++ ++/*SAS Enclosure Device Status Change event ReasonCode values */ ++#define MPI2_EVENT_SAS_ENCL_RC_ADDED (0x01) ++#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02) ++ ++/*SAS PHY Counter Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER { ++ U64 TimeStamp; /*0x00 */ ++ U32 Reserved1; /*0x08 */ ++ U8 PhyEventCode; /*0x0C */ ++ U8 PhyNum; /*0x0D */ ++ U16 Reserved2; /*0x0E */ ++ U32 PhyEventInfo; /*0x10 */ ++ U8 CounterType; /*0x14 */ ++ U8 ThresholdWindow; /*0x15 */ ++ U8 TimeUnits; /*0x16 */ ++ U8 Reserved3; /*0x17 */ ++ U32 EventThreshold; /*0x18 */ ++ U16 ThresholdFlags; /*0x1C */ ++ U16 Reserved4; /*0x1E */ ++} MPI2_EVENT_DATA_SAS_PHY_COUNTER, ++ *PTR_MPI2_EVENT_DATA_SAS_PHY_COUNTER, ++ Mpi2EventDataSasPhyCounter_t, ++ *pMpi2EventDataSasPhyCounter_t; ++ ++/*use MPI2_SASPHY3_EVENT_CODE_ values from mpi2_cnfg.h ++ *for the PhyEventCode field */ ++ ++/*use MPI2_SASPHY3_COUNTER_TYPE_ values from mpi2_cnfg.h ++ *for the CounterType field */ ++ ++/*use MPI2_SASPHY3_TIME_UNITS_ values from mpi2_cnfg.h ++ *for the TimeUnits field */ ++ ++/*use MPI2_SASPHY3_TFLAGS_ values from mpi2_cnfg.h ++ *for the ThresholdFlags field */ ++ ++/*SAS Quiesce Event data */ ++ ++typedef struct _MPI2_EVENT_DATA_SAS_QUIESCE { ++ U8 ReasonCode; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Reserved3; /*0x04 */ ++} MPI2_EVENT_DATA_SAS_QUIESCE, ++ *PTR_MPI2_EVENT_DATA_SAS_QUIESCE, ++ Mpi2EventDataSasQuiesce_t, *pMpi2EventDataSasQuiesce_t; ++ ++/*SAS Quiesce Event data ReasonCode values */ ++#define MPI2_EVENT_SAS_QUIESCE_RC_STARTED (0x01) ++#define MPI2_EVENT_SAS_QUIESCE_RC_COMPLETED (0x02) ++ ++/*Host Based Discovery Phy Event data */ ++ ++typedef struct _MPI2_EVENT_HBD_PHY_SAS { ++ U8 Flags; /*0x00 */ ++ U8 NegotiatedLinkRate; /*0x01 */ ++ U8 PhyNum; /*0x02 */ ++ U8 PhysicalPort; /*0x03 */ ++ U32 Reserved1; /*0x04 */ ++ U8 InitialFrame[28]; /*0x08 */ ++} MPI2_EVENT_HBD_PHY_SAS, *PTR_MPI2_EVENT_HBD_PHY_SAS, ++ Mpi2EventHbdPhySas_t, *pMpi2EventHbdPhySas_t; ++ ++/*values for the Flags field */ ++#define MPI2_EVENT_HBD_SAS_FLAGS_FRAME_VALID (0x02) ++#define MPI2_EVENT_HBD_SAS_FLAGS_SATA_FRAME (0x01) ++ ++/*use MPI2_SAS_NEG_LINK_RATE_ defines from mpi2_cnfg.h ++ *for the NegotiatedLinkRate field */ ++ ++typedef union _MPI2_EVENT_HBD_DESCRIPTOR { ++ MPI2_EVENT_HBD_PHY_SAS Sas; ++} MPI2_EVENT_HBD_DESCRIPTOR, *PTR_MPI2_EVENT_HBD_DESCRIPTOR, ++ Mpi2EventHbdDescriptor_t, *pMpi2EventHbdDescriptor_t; ++ ++typedef struct _MPI2_EVENT_DATA_HBD_PHY { ++ U8 DescriptorType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Reserved3; /*0x04 */ ++ MPI2_EVENT_HBD_DESCRIPTOR Descriptor; /*0x08 */ ++} MPI2_EVENT_DATA_HBD_PHY, *PTR_MPI2_EVENT_DATA_HBD_PHY, ++ Mpi2EventDataHbdPhy_t, ++ *pMpi2EventDataMpi2EventDataHbdPhy_t; ++ ++/*values for the DescriptorType field */ ++#define MPI2_EVENT_HBD_DT_SAS (0x01) ++ ++/**************************************************************************** ++* EventAck message ++****************************************************************************/ ++ ++/*EventAck Request message */ ++typedef struct _MPI2_EVENT_ACK_REQUEST { ++ U16 Reserved1; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Event; /*0x0C */ ++ U16 Reserved5; /*0x0E */ ++ U32 EventContext; /*0x10 */ ++} MPI2_EVENT_ACK_REQUEST, *PTR_MPI2_EVENT_ACK_REQUEST, ++ Mpi2EventAckRequest_t, *pMpi2EventAckRequest_t; ++ ++/*EventAck Reply message */ ++typedef struct _MPI2_EVENT_ACK_REPLY { ++ U16 Reserved1; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_EVENT_ACK_REPLY, *PTR_MPI2_EVENT_ACK_REPLY, ++ Mpi2EventAckReply_t, *pMpi2EventAckReply_t; ++ ++/**************************************************************************** ++* SendHostMessage message ++****************************************************************************/ ++ ++/*SendHostMessage Request message */ ++typedef struct _MPI2_SEND_HOST_MESSAGE_REQUEST { ++ U16 HostDataLength; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U8 Reserved4; /*0x0C */ ++ U8 DestVF_ID; /*0x0D */ ++ U16 Reserved5; /*0x0E */ ++ U32 Reserved6; /*0x10 */ ++ U32 Reserved7; /*0x14 */ ++ U32 Reserved8; /*0x18 */ ++ U32 Reserved9; /*0x1C */ ++ U32 Reserved10; /*0x20 */ ++ U32 HostData[1]; /*0x24 */ ++} MPI2_SEND_HOST_MESSAGE_REQUEST, ++ *PTR_MPI2_SEND_HOST_MESSAGE_REQUEST, ++ Mpi2SendHostMessageRequest_t, ++ *pMpi2SendHostMessageRequest_t; ++ ++/*SendHostMessage Reply message */ ++typedef struct _MPI2_SEND_HOST_MESSAGE_REPLY { ++ U16 HostDataLength; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved1; /*0x04 */ ++ U8 Reserved2; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_SEND_HOST_MESSAGE_REPLY, *PTR_MPI2_SEND_HOST_MESSAGE_REPLY, ++ Mpi2SendHostMessageReply_t, *pMpi2SendHostMessageReply_t; ++ ++/**************************************************************************** ++* FWDownload message ++****************************************************************************/ ++ ++/*MPI v2.0 FWDownload Request message */ ++typedef struct _MPI2_FW_DOWNLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 TotalImageSize; /*0x0C */ ++ U32 Reserved5; /*0x10 */ ++ MPI2_MPI_SGE_UNION SGL; /*0x14 */ ++} MPI2_FW_DOWNLOAD_REQUEST, *PTR_MPI2_FW_DOWNLOAD_REQUEST, ++ Mpi2FWDownloadRequest, *pMpi2FWDownloadRequest; ++ ++#define MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT (0x01) ++ ++#define MPI2_FW_DOWNLOAD_ITYPE_FW (0x01) ++#define MPI2_FW_DOWNLOAD_ITYPE_BIOS (0x02) ++#define MPI2_FW_DOWNLOAD_ITYPE_MANUFACTURING (0x06) ++#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07) ++#define MPI2_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08) ++#define MPI2_FW_DOWNLOAD_ITYPE_MEGARAID (0x09) ++#define MPI2_FW_DOWNLOAD_ITYPE_COMPLETE (0x0A) ++#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B) ++#define MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY (0x0C) ++#define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0) ++ ++/*MPI v2.0 FWDownload TransactionContext Element */ ++typedef struct _MPI2_FW_DOWNLOAD_TCSGE { ++ U8 Reserved1; /*0x00 */ ++ U8 ContextSize; /*0x01 */ ++ U8 DetailsLength; /*0x02 */ ++ U8 Flags; /*0x03 */ ++ U32 Reserved2; /*0x04 */ ++ U32 ImageOffset; /*0x08 */ ++ U32 ImageSize; /*0x0C */ ++} MPI2_FW_DOWNLOAD_TCSGE, *PTR_MPI2_FW_DOWNLOAD_TCSGE, ++ Mpi2FWDownloadTCSGE_t, *pMpi2FWDownloadTCSGE_t; ++ ++/*MPI v2.5 FWDownload Request message */ ++typedef struct _MPI25_FW_DOWNLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 TotalImageSize; /*0x0C */ ++ U32 Reserved5; /*0x10 */ ++ U32 Reserved6; /*0x14 */ ++ U32 ImageOffset; /*0x18 */ ++ U32 ImageSize; /*0x1C */ ++ MPI25_SGE_IO_UNION SGL; /*0x20 */ ++} MPI25_FW_DOWNLOAD_REQUEST, *PTR_MPI25_FW_DOWNLOAD_REQUEST, ++ Mpi25FWDownloadRequest, *pMpi25FWDownloadRequest; ++ ++/*FWDownload Reply message */ ++typedef struct _MPI2_FW_DOWNLOAD_REPLY { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_FW_DOWNLOAD_REPLY, *PTR_MPI2_FW_DOWNLOAD_REPLY, ++ Mpi2FWDownloadReply_t, *pMpi2FWDownloadReply_t; ++ ++/**************************************************************************** ++* FWUpload message ++****************************************************************************/ ++ ++/*MPI v2.0 FWUpload Request message */ ++typedef struct _MPI2_FW_UPLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ MPI2_MPI_SGE_UNION SGL; /*0x14 */ ++} MPI2_FW_UPLOAD_REQUEST, *PTR_MPI2_FW_UPLOAD_REQUEST, ++ Mpi2FWUploadRequest_t, *pMpi2FWUploadRequest_t; ++ ++#define MPI2_FW_UPLOAD_ITYPE_FW_CURRENT (0x00) ++#define MPI2_FW_UPLOAD_ITYPE_FW_FLASH (0x01) ++#define MPI2_FW_UPLOAD_ITYPE_BIOS_FLASH (0x02) ++#define MPI2_FW_UPLOAD_ITYPE_FW_BACKUP (0x05) ++#define MPI2_FW_UPLOAD_ITYPE_MANUFACTURING (0x06) ++#define MPI2_FW_UPLOAD_ITYPE_CONFIG_1 (0x07) ++#define MPI2_FW_UPLOAD_ITYPE_CONFIG_2 (0x08) ++#define MPI2_FW_UPLOAD_ITYPE_MEGARAID (0x09) ++#define MPI2_FW_UPLOAD_ITYPE_COMPLETE (0x0A) ++#define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B) ++#define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP (0x0D) ++ ++/*MPI v2.0 FWUpload TransactionContext Element */ ++typedef struct _MPI2_FW_UPLOAD_TCSGE { ++ U8 Reserved1; /*0x00 */ ++ U8 ContextSize; /*0x01 */ ++ U8 DetailsLength; /*0x02 */ ++ U8 Flags; /*0x03 */ ++ U32 Reserved2; /*0x04 */ ++ U32 ImageOffset; /*0x08 */ ++ U32 ImageSize; /*0x0C */ ++} MPI2_FW_UPLOAD_TCSGE, *PTR_MPI2_FW_UPLOAD_TCSGE, ++ Mpi2FWUploadTCSGE_t, *pMpi2FWUploadTCSGE_t; ++ ++/*MPI v2.5 FWUpload Request message */ ++typedef struct _MPI25_FW_UPLOAD_REQUEST { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ U32 Reserved7; /*0x14 */ ++ U32 ImageOffset; /*0x18 */ ++ U32 ImageSize; /*0x1C */ ++ MPI25_SGE_IO_UNION SGL; /*0x20 */ ++} MPI25_FW_UPLOAD_REQUEST, *PTR_MPI25_FW_UPLOAD_REQUEST, ++ Mpi25FWUploadRequest_t, *pMpi25FWUploadRequest_t; ++ ++/*FWUpload Reply message */ ++typedef struct _MPI2_FW_UPLOAD_REPLY { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 ActualImageSize; /*0x14 */ ++} MPI2_FW_UPLOAD_REPLY, *PTR_MPI2_FW_UPLOAD_REPLY, ++ Mpi2FWUploadReply_t, *pMPi2FWUploadReply_t; ++ ++/*FW Image Header */ ++typedef struct _MPI2_FW_IMAGE_HEADER { ++ U32 Signature; /*0x00 */ ++ U32 Signature0; /*0x04 */ ++ U32 Signature1; /*0x08 */ ++ U32 Signature2; /*0x0C */ ++ MPI2_VERSION_UNION MPIVersion; /*0x10 */ ++ MPI2_VERSION_UNION FWVersion; /*0x14 */ ++ MPI2_VERSION_UNION NVDATAVersion; /*0x18 */ ++ MPI2_VERSION_UNION PackageVersion; /*0x1C */ ++ U16 VendorID; /*0x20 */ ++ U16 ProductID; /*0x22 */ ++ U16 ProtocolFlags; /*0x24 */ ++ U16 Reserved26; /*0x26 */ ++ U32 IOCCapabilities; /*0x28 */ ++ U32 ImageSize; /*0x2C */ ++ U32 NextImageHeaderOffset; /*0x30 */ ++ U32 Checksum; /*0x34 */ ++ U32 Reserved38; /*0x38 */ ++ U32 Reserved3C; /*0x3C */ ++ U32 Reserved40; /*0x40 */ ++ U32 Reserved44; /*0x44 */ ++ U32 Reserved48; /*0x48 */ ++ U32 Reserved4C; /*0x4C */ ++ U32 Reserved50; /*0x50 */ ++ U32 Reserved54; /*0x54 */ ++ U32 Reserved58; /*0x58 */ ++ U32 Reserved5C; /*0x5C */ ++ U32 BootFlags; /*0x60 */ ++ U32 FirmwareVersionNameWhat; /*0x64 */ ++ U8 FirmwareVersionName[32]; /*0x68 */ ++ U32 VendorNameWhat; /*0x88 */ ++ U8 VendorName[32]; /*0x8C */ ++ U32 PackageNameWhat; /*0x88 */ ++ U8 PackageName[32]; /*0x8C */ ++ U32 ReservedD0; /*0xD0 */ ++ U32 ReservedD4; /*0xD4 */ ++ U32 ReservedD8; /*0xD8 */ ++ U32 ReservedDC; /*0xDC */ ++ U32 ReservedE0; /*0xE0 */ ++ U32 ReservedE4; /*0xE4 */ ++ U32 ReservedE8; /*0xE8 */ ++ U32 ReservedEC; /*0xEC */ ++ U32 ReservedF0; /*0xF0 */ ++ U32 ReservedF4; /*0xF4 */ ++ U32 ReservedF8; /*0xF8 */ ++ U32 ReservedFC; /*0xFC */ ++} MPI2_FW_IMAGE_HEADER, *PTR_MPI2_FW_IMAGE_HEADER, ++ Mpi2FWImageHeader_t, *pMpi2FWImageHeader_t; ++ ++/*Signature field */ ++#define MPI2_FW_HEADER_SIGNATURE_OFFSET (0x00) ++#define MPI2_FW_HEADER_SIGNATURE_MASK (0xFF000000) ++#define MPI2_FW_HEADER_SIGNATURE (0xEA000000) ++#define MPI26_FW_HEADER_SIGNATURE (0xEB000000) ++ ++/*Signature0 field */ ++#define MPI2_FW_HEADER_SIGNATURE0_OFFSET (0x04) ++#define MPI2_FW_HEADER_SIGNATURE0 (0x5AFAA55A) ++/* Last byte is defined by architecture */ ++#define MPI26_FW_HEADER_SIGNATURE0_BASE (0x5AEAA500) ++#define MPI26_FW_HEADER_SIGNATURE0_ARC_0 (0x5A) ++#define MPI26_FW_HEADER_SIGNATURE0_ARC_1 (0x00) ++#define MPI26_FW_HEADER_SIGNATURE0_ARC_2 (0x01) ++/* legacy (0x5AEAA55A) */ ++#define MPI26_FW_HEADER_SIGNATURE0 \ ++ (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0) ++#define MPI26_FW_HEADER_SIGNATURE0_3516 \ ++ (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1) ++ ++/*Signature1 field */ ++#define MPI2_FW_HEADER_SIGNATURE1_OFFSET (0x08) ++#define MPI2_FW_HEADER_SIGNATURE1 (0xA55AFAA5) ++#define MPI26_FW_HEADER_SIGNATURE1 (0xA55AEAA5) ++ ++/*Signature2 field */ ++#define MPI2_FW_HEADER_SIGNATURE2_OFFSET (0x0C) ++#define MPI2_FW_HEADER_SIGNATURE2 (0x5AA55AFA) ++#define MPI26_FW_HEADER_SIGNATURE2 (0x5AA55AEA) ++ ++/*defines for using the ProductID field */ ++#define MPI2_FW_HEADER_PID_TYPE_MASK (0xF000) ++#define MPI2_FW_HEADER_PID_TYPE_SAS (0x2000) ++ ++#define MPI2_FW_HEADER_PID_PROD_MASK (0x0F00) ++#define MPI2_FW_HEADER_PID_PROD_A (0x0000) ++#define MPI2_FW_HEADER_PID_PROD_TARGET_INITIATOR_SCSI (0x0200) ++#define MPI2_FW_HEADER_PID_PROD_IR_SCSI (0x0700) ++ ++#define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) ++/*SAS ProductID Family bits */ ++#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0013) ++#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0014) ++#define MPI25_FW_HEADER_PID_FAMILY_3108_SAS (0x0021) ++#define MPI26_FW_HEADER_PID_FAMILY_3324_SAS (0x0028) ++#define MPI26_FW_HEADER_PID_FAMILY_3516_SAS (0x0031) ++ ++/*use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */ ++ ++/*use MPI2_IOCFACTS_CAPABILITY_ defines for IOCCapabilities field */ ++ ++#define MPI2_FW_HEADER_IMAGESIZE_OFFSET (0x2C) ++#define MPI2_FW_HEADER_NEXTIMAGE_OFFSET (0x30) ++#define MPI26_FW_HEADER_BOOTFLAGS_OFFSET (0x60) ++#define MPI2_FW_HEADER_VERNMHWAT_OFFSET (0x64) ++ ++#define MPI2_FW_HEADER_WHAT_SIGNATURE (0x29232840) ++ ++#define MPI2_FW_HEADER_SIZE (0x100) ++ ++/*Extended Image Header */ ++typedef struct _MPI2_EXT_IMAGE_HEADER { ++ U8 ImageType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 Checksum; /*0x04 */ ++ U32 ImageSize; /*0x08 */ ++ U32 NextImageHeaderOffset; /*0x0C */ ++ U32 PackageVersion; /*0x10 */ ++ U32 Reserved3; /*0x14 */ ++ U32 Reserved4; /*0x18 */ ++ U32 Reserved5; /*0x1C */ ++ U8 IdentifyString[32]; /*0x20 */ ++} MPI2_EXT_IMAGE_HEADER, *PTR_MPI2_EXT_IMAGE_HEADER, ++ Mpi2ExtImageHeader_t, *pMpi2ExtImageHeader_t; ++ ++/*useful offsets */ ++#define MPI2_EXT_IMAGE_IMAGETYPE_OFFSET (0x00) ++#define MPI2_EXT_IMAGE_IMAGESIZE_OFFSET (0x08) ++#define MPI2_EXT_IMAGE_NEXTIMAGE_OFFSET (0x0C) ++ ++#define MPI2_EXT_IMAGE_HEADER_SIZE (0x40) ++ ++/*defines for the ImageType field */ ++#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00) ++#define MPI2_EXT_IMAGE_TYPE_FW (0x01) ++#define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03) ++#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04) ++#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05) ++#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06) ++#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07) ++#define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08) ++#define MPI2_EXT_IMAGE_TYPE_ENCRYPTED_HASH (0x09) ++#define MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC (0x80) ++#define MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++#define MPI2_EXT_IMAGE_TYPE_MAX (MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC) ++ ++/*FLASH Layout Extended Image Data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check RegionsPerLayout at runtime. ++ */ ++#ifndef MPI2_FLASH_NUMBER_OF_REGIONS ++#define MPI2_FLASH_NUMBER_OF_REGIONS (1) ++#endif ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumberOfLayouts at runtime. ++ */ ++#ifndef MPI2_FLASH_NUMBER_OF_LAYOUTS ++#define MPI2_FLASH_NUMBER_OF_LAYOUTS (1) ++#endif ++ ++typedef struct _MPI2_FLASH_REGION { ++ U8 RegionType; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 RegionOffset; /*0x04 */ ++ U32 RegionSize; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++} MPI2_FLASH_REGION, *PTR_MPI2_FLASH_REGION, ++ Mpi2FlashRegion_t, *pMpi2FlashRegion_t; ++ ++typedef struct _MPI2_FLASH_LAYOUT { ++ U32 FlashSize; /*0x00 */ ++ U32 Reserved1; /*0x04 */ ++ U32 Reserved2; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++ MPI2_FLASH_REGION Region[MPI2_FLASH_NUMBER_OF_REGIONS]; /*0x10 */ ++} MPI2_FLASH_LAYOUT, *PTR_MPI2_FLASH_LAYOUT, ++ Mpi2FlashLayout_t, *pMpi2FlashLayout_t; ++ ++typedef struct _MPI2_FLASH_LAYOUT_DATA { ++ U8 ImageRevision; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 SizeOfRegion; /*0x02 */ ++ U8 Reserved2; /*0x03 */ ++ U16 NumberOfLayouts; /*0x04 */ ++ U16 RegionsPerLayout; /*0x06 */ ++ U16 MinimumSectorAlignment; /*0x08 */ ++ U16 Reserved3; /*0x0A */ ++ U32 Reserved4; /*0x0C */ ++ MPI2_FLASH_LAYOUT Layout[MPI2_FLASH_NUMBER_OF_LAYOUTS]; /*0x10 */ ++} MPI2_FLASH_LAYOUT_DATA, *PTR_MPI2_FLASH_LAYOUT_DATA, ++ Mpi2FlashLayoutData_t, *pMpi2FlashLayoutData_t; ++ ++/*defines for the RegionType field */ ++#define MPI2_FLASH_REGION_UNUSED (0x00) ++#define MPI2_FLASH_REGION_FIRMWARE (0x01) ++#define MPI2_FLASH_REGION_BIOS (0x02) ++#define MPI2_FLASH_REGION_NVDATA (0x03) ++#define MPI2_FLASH_REGION_FIRMWARE_BACKUP (0x05) ++#define MPI2_FLASH_REGION_MFG_INFORMATION (0x06) ++#define MPI2_FLASH_REGION_CONFIG_1 (0x07) ++#define MPI2_FLASH_REGION_CONFIG_2 (0x08) ++#define MPI2_FLASH_REGION_MEGARAID (0x09) ++#define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK (0x0A) ++#define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK) ++#define MPI2_FLASH_REGION_CBB_BACKUP (0x0D) ++ ++/*ImageRevision */ ++#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00) ++ ++/*Supported Devices Extended Image Data */ ++ ++/* ++ *Host code (drivers, BIOS, utilities, etc.) should leave this define set to ++ *one and check NumberOfDevices at runtime. ++ */ ++#ifndef MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES ++#define MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES (1) ++#endif ++ ++typedef struct _MPI2_SUPPORTED_DEVICE { ++ U16 DeviceID; /*0x00 */ ++ U16 VendorID; /*0x02 */ ++ U16 DeviceIDMask; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++ U8 LowPCIRev; /*0x08 */ ++ U8 HighPCIRev; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U32 Reserved3; /*0x0C */ ++} MPI2_SUPPORTED_DEVICE, *PTR_MPI2_SUPPORTED_DEVICE, ++ Mpi2SupportedDevice_t, *pMpi2SupportedDevice_t; ++ ++typedef struct _MPI2_SUPPORTED_DEVICES_DATA { ++ U8 ImageRevision; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 NumberOfDevices; /*0x02 */ ++ U8 Reserved2; /*0x03 */ ++ U32 Reserved3; /*0x04 */ ++ MPI2_SUPPORTED_DEVICE ++ SupportedDevice[MPI2_SUPPORTED_DEVICES_IMAGE_NUM_DEVICES];/*0x08 */ ++} MPI2_SUPPORTED_DEVICES_DATA, *PTR_MPI2_SUPPORTED_DEVICES_DATA, ++ Mpi2SupportedDevicesData_t, *pMpi2SupportedDevicesData_t; ++ ++/*ImageRevision */ ++#define MPI2_SUPPORTED_DEVICES_IMAGE_REVISION (0x00) ++ ++/*Init Extended Image Data */ ++ ++typedef struct _MPI2_INIT_IMAGE_FOOTER { ++ U32 BootFlags; /*0x00 */ ++ U32 ImageSize; /*0x04 */ ++ U32 Signature0; /*0x08 */ ++ U32 Signature1; /*0x0C */ ++ U32 Signature2; /*0x10 */ ++ U32 ResetVector; /*0x14 */ ++} MPI2_INIT_IMAGE_FOOTER, *PTR_MPI2_INIT_IMAGE_FOOTER, ++ Mpi2InitImageFooter_t, *pMpi2InitImageFooter_t; ++ ++/*defines for the BootFlags field */ ++#define MPI2_INIT_IMAGE_BOOTFLAGS_OFFSET (0x00) ++ ++/*defines for the ImageSize field */ ++#define MPI2_INIT_IMAGE_IMAGESIZE_OFFSET (0x04) ++ ++/*defines for the Signature0 field */ ++#define MPI2_INIT_IMAGE_SIGNATURE0_OFFSET (0x08) ++#define MPI2_INIT_IMAGE_SIGNATURE0 (0x5AA55AEA) ++ ++/*defines for the Signature1 field */ ++#define MPI2_INIT_IMAGE_SIGNATURE1_OFFSET (0x0C) ++#define MPI2_INIT_IMAGE_SIGNATURE1 (0xA55AEAA5) ++ ++/*defines for the Signature2 field */ ++#define MPI2_INIT_IMAGE_SIGNATURE2_OFFSET (0x10) ++#define MPI2_INIT_IMAGE_SIGNATURE2 (0x5AEAA55A) ++ ++/*Signature fields as individual bytes */ ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_0 (0xEA) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_1 (0x5A) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_2 (0xA5) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_3 (0x5A) ++ ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_4 (0xA5) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_5 (0xEA) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_6 (0x5A) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_7 (0xA5) ++ ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_8 (0x5A) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_9 (0xA5) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_A (0xEA) ++#define MPI2_INIT_IMAGE_SIGNATURE_BYTE_B (0x5A) ++ ++/*defines for the ResetVector field */ ++#define MPI2_INIT_IMAGE_RESETVECTOR_OFFSET (0x14) ++ ++ ++/* Encrypted Hash Extended Image Data */ ++ ++typedef struct _MPI25_ENCRYPTED_HASH_ENTRY { ++ U8 HashImageType; /* 0x00 */ ++ U8 HashAlgorithm; /* 0x01 */ ++ U8 EncryptionAlgorithm; /* 0x02 */ ++ U8 Reserved1; /* 0x03 */ ++ U32 Reserved2; /* 0x04 */ ++ U32 EncryptedHash[1]; /* 0x08 */ /* variable length */ ++} MPI25_ENCRYPTED_HASH_ENTRY, *PTR_MPI25_ENCRYPTED_HASH_ENTRY, ++Mpi25EncryptedHashEntry_t, *pMpi25EncryptedHashEntry_t; ++ ++/* values for HashImageType */ ++#define MPI25_HASH_IMAGE_TYPE_UNUSED (0x00) ++#define MPI25_HASH_IMAGE_TYPE_FIRMWARE (0x01) ++#define MPI25_HASH_IMAGE_TYPE_BIOS (0x02) ++ ++/* values for HashAlgorithm */ ++#define MPI25_HASH_ALGORITHM_UNUSED (0x00) ++#define MPI25_HASH_ALGORITHM_SHA256 (0x01) ++ ++/* values for EncryptionAlgorithm */ ++#define MPI25_ENCRYPTION_ALG_UNUSED (0x00) ++#define MPI25_ENCRYPTION_ALG_RSA256 (0x01) ++ ++typedef struct _MPI25_ENCRYPTED_HASH_DATA { ++ U8 ImageVersion; /* 0x00 */ ++ U8 NumHash; /* 0x01 */ ++ U16 Reserved1; /* 0x02 */ ++ U32 Reserved2; /* 0x04 */ ++ MPI25_ENCRYPTED_HASH_ENTRY EncryptedHashEntry[1]; /* 0x08 */ ++} MPI25_ENCRYPTED_HASH_DATA, *PTR_MPI25_ENCRYPTED_HASH_DATA, ++Mpi25EncryptedHashData_t, *pMpi25EncryptedHashData_t; ++ ++ ++/**************************************************************************** ++* PowerManagementControl message ++****************************************************************************/ ++ ++/*PowerManagementControl Request message */ ++typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST { ++ U8 Feature; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 Parameter1; /*0x0C */ ++ U8 Parameter2; /*0x0D */ ++ U8 Parameter3; /*0x0E */ ++ U8 Parameter4; /*0x0F */ ++ U32 Reserved5; /*0x10 */ ++ U32 Reserved6; /*0x14 */ ++} MPI2_PWR_MGMT_CONTROL_REQUEST, *PTR_MPI2_PWR_MGMT_CONTROL_REQUEST, ++ Mpi2PwrMgmtControlRequest_t, *pMpi2PwrMgmtControlRequest_t; ++ ++/*defines for the Feature field */ ++#define MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND (0x01) ++#define MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION (0x02) ++#define MPI2_PM_CONTROL_FEATURE_PCIE_LINK (0x03) /*obsolete */ ++#define MPI2_PM_CONTROL_FEATURE_IOC_SPEED (0x04) ++#define MPI2_PM_CONTROL_FEATURE_GLOBAL_PWR_MGMT_MODE (0x05) ++#define MPI2_PM_CONTROL_FEATURE_MIN_PRODUCT_SPECIFIC (0x80) ++#define MPI2_PM_CONTROL_FEATURE_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND Feature */ ++/*Parameter1 contains a PHY number */ ++/*Parameter2 indicates power condition action using these defines */ ++#define MPI2_PM_CONTROL_PARAM2_PARTIAL (0x01) ++#define MPI2_PM_CONTROL_PARAM2_SLUMBER (0x02) ++#define MPI2_PM_CONTROL_PARAM2_EXIT_PWR_MGMT (0x03) ++/*Parameter3 and Parameter4 are reserved */ ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION ++ * Feature */ ++/*Parameter1 contains SAS port width modulation group number */ ++/*Parameter2 indicates IOC action using these defines */ ++#define MPI2_PM_CONTROL_PARAM2_REQUEST_OWNERSHIP (0x01) ++#define MPI2_PM_CONTROL_PARAM2_CHANGE_MODULATION (0x02) ++#define MPI2_PM_CONTROL_PARAM2_RELINQUISH_OWNERSHIP (0x03) ++/*Parameter3 indicates desired modulation level using these defines */ ++#define MPI2_PM_CONTROL_PARAM3_25_PERCENT (0x00) ++#define MPI2_PM_CONTROL_PARAM3_50_PERCENT (0x01) ++#define MPI2_PM_CONTROL_PARAM3_75_PERCENT (0x02) ++#define MPI2_PM_CONTROL_PARAM3_100_PERCENT (0x03) ++/*Parameter4 is reserved */ ++ ++/*this next set (_PCIE_LINK) is obsolete */ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_PCIE_LINK Feature */ ++/*Parameter1 indicates desired PCIe link speed using these defines */ ++#define MPI2_PM_CONTROL_PARAM1_PCIE_2_5_GBPS (0x00) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM1_PCIE_5_0_GBPS (0x01) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM1_PCIE_8_0_GBPS (0x02) /*obsolete */ ++/*Parameter2 indicates desired PCIe link width using these defines */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X1 (0x01) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X2 (0x02) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X4 (0x04) /*obsolete */ ++#define MPI2_PM_CONTROL_PARAM2_WIDTH_X8 (0x08) /*obsolete */ ++/*Parameter3 and Parameter4 are reserved */ ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_IOC_SPEED Feature */ ++/*Parameter1 indicates desired IOC hardware clock speed using these defines */ ++#define MPI2_PM_CONTROL_PARAM1_FULL_IOC_SPEED (0x01) ++#define MPI2_PM_CONTROL_PARAM1_HALF_IOC_SPEED (0x02) ++#define MPI2_PM_CONTROL_PARAM1_QUARTER_IOC_SPEED (0x04) ++#define MPI2_PM_CONTROL_PARAM1_EIGHTH_IOC_SPEED (0x08) ++/*Parameter2, Parameter3, and Parameter4 are reserved */ ++ ++/*parameter usage for the MPI2_PM_CONTROL_FEATURE_GLOBAL_PWR_MGMT_MODE Feature*/ ++/*Parameter1 indicates host action regarding global power management mode */ ++#define MPI2_PM_CONTROL_PARAM1_TAKE_CONTROL (0x01) ++#define MPI2_PM_CONTROL_PARAM1_CHANGE_GLOBAL_MODE (0x02) ++#define MPI2_PM_CONTROL_PARAM1_RELEASE_CONTROL (0x03) ++/*Parameter2 indicates the requested global power management mode */ ++#define MPI2_PM_CONTROL_PARAM2_FULL_PWR_PERF (0x01) ++#define MPI2_PM_CONTROL_PARAM2_REDUCED_PWR_PERF (0x08) ++#define MPI2_PM_CONTROL_PARAM2_STANDBY (0x40) ++/*Parameter3 and Parameter4 are reserved */ ++ ++/*PowerManagementControl Reply message */ ++typedef struct _MPI2_PWR_MGMT_CONTROL_REPLY { ++ U8 Feature; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_PWR_MGMT_CONTROL_REPLY, *PTR_MPI2_PWR_MGMT_CONTROL_REPLY, ++ Mpi2PwrMgmtControlReply_t, *pMpi2PwrMgmtControlReply_t; ++ ++/**************************************************************************** ++* IO Unit Control messages (MPI v2.6 and later only.) ++****************************************************************************/ ++ ++/* IO Unit Control Request Message */ ++typedef struct _MPI26_IOUNIT_CONTROL_REQUEST { ++ U8 Operation; /* 0x00 */ ++ U8 Reserved1; /* 0x01 */ ++ U8 ChainOffset; /* 0x02 */ ++ U8 Function; /* 0x03 */ ++ U16 DevHandle; /* 0x04 */ ++ U8 IOCParameter; /* 0x06 */ ++ U8 MsgFlags; /* 0x07 */ ++ U8 VP_ID; /* 0x08 */ ++ U8 VF_ID; /* 0x09 */ ++ U16 Reserved3; /* 0x0A */ ++ U16 Reserved4; /* 0x0C */ ++ U8 PhyNum; /* 0x0E */ ++ U8 PrimFlags; /* 0x0F */ ++ U32 Primitive; /* 0x10 */ ++ U8 LookupMethod; /* 0x14 */ ++ U8 Reserved5; /* 0x15 */ ++ U16 SlotNumber; /* 0x16 */ ++ U64 LookupAddress; /* 0x18 */ ++ U32 IOCParameterValue; /* 0x20 */ ++ U32 Reserved7; /* 0x24 */ ++ U32 Reserved8; /* 0x28 */ ++} MPI26_IOUNIT_CONTROL_REQUEST, ++ *PTR_MPI26_IOUNIT_CONTROL_REQUEST, ++ Mpi26IoUnitControlRequest_t, ++ *pMpi26IoUnitControlRequest_t; ++ ++/* values for the Operation field */ ++#define MPI26_CTRL_OP_CLEAR_ALL_PERSISTENT (0x02) ++#define MPI26_CTRL_OP_SAS_PHY_LINK_RESET (0x06) ++#define MPI26_CTRL_OP_SAS_PHY_HARD_RESET (0x07) ++#define MPI26_CTRL_OP_PHY_CLEAR_ERROR_LOG (0x08) ++#define MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG (0x09) ++#define MPI26_CTRL_OP_SAS_SEND_PRIMITIVE (0x0A) ++#define MPI26_CTRL_OP_FORCE_FULL_DISCOVERY (0x0B) ++#define MPI26_CTRL_OP_REMOVE_DEVICE (0x0D) ++#define MPI26_CTRL_OP_LOOKUP_MAPPING (0x0E) ++#define MPI26_CTRL_OP_SET_IOC_PARAMETER (0x0F) ++#define MPI26_CTRL_OP_ENABLE_FP_DEVICE (0x10) ++#define MPI26_CTRL_OP_DISABLE_FP_DEVICE (0x11) ++#define MPI26_CTRL_OP_ENABLE_FP_ALL (0x12) ++#define MPI26_CTRL_OP_DISABLE_FP_ALL (0x13) ++#define MPI26_CTRL_OP_DEV_ENABLE_NCQ (0x14) ++#define MPI26_CTRL_OP_DEV_DISABLE_NCQ (0x15) ++#define MPI26_CTRL_OP_SHUTDOWN (0x16) ++#define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION (0x17) ++#define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION (0x18) ++#define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION (0x19) ++#define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN (0x80) ++ ++/* values for the PrimFlags field */ ++#define MPI26_CTRL_PRIMFLAGS_SINGLE (0x08) ++#define MPI26_CTRL_PRIMFLAGS_TRIPLE (0x02) ++#define MPI26_CTRL_PRIMFLAGS_REDUNDANT (0x01) ++ ++/* values for the LookupMethod field */ ++#define MPI26_CTRL_LOOKUP_METHOD_WWID_ADDRESS (0x01) ++#define MPI26_CTRL_LOOKUP_METHOD_ENCLOSURE_SLOT (0x02) ++#define MPI26_CTRL_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03) ++ ++ ++/* IO Unit Control Reply Message */ ++typedef struct _MPI26_IOUNIT_CONTROL_REPLY { ++ U8 Operation; /* 0x00 */ ++ U8 Reserved1; /* 0x01 */ ++ U8 MsgLength; /* 0x02 */ ++ U8 Function; /* 0x03 */ ++ U16 DevHandle; /* 0x04 */ ++ U8 IOCParameter; /* 0x06 */ ++ U8 MsgFlags; /* 0x07 */ ++ U8 VP_ID; /* 0x08 */ ++ U8 VF_ID; /* 0x09 */ ++ U16 Reserved3; /* 0x0A */ ++ U16 Reserved4; /* 0x0C */ ++ U16 IOCStatus; /* 0x0E */ ++ U32 IOCLogInfo; /* 0x10 */ ++} MPI26_IOUNIT_CONTROL_REPLY, ++ *PTR_MPI26_IOUNIT_CONTROL_REPLY, ++ Mpi26IoUnitControlReply_t, ++ *pMpi26IoUnitControlReply_t; ++ ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_raid.h b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h +new file mode 100644 +index 0000000..1c0eeee +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_raid.h +@@ -0,0 +1,355 @@ ++/* ++ * Copyright 2000-2014 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_raid.h ++ * Title: MPI Integrated RAID messages and structures ++ * Creation Date: April 26, 2007 ++ * ++ * mpi2_raid.h Version: 02.00.11 ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 08-31-07 02.00.01 Modifications to RAID Action request and reply, ++ * including the Actions and ActionData. ++ * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD. ++ * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that ++ * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT ++ * can be sized by the build environment. ++ * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of ++ * VolumeCreationFlags and marked the old one as obsolete. ++ * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define. ++ * 08-24-10 02.00.06 Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with ++ * related structures and defines. ++ * Added product-specific range to RAID Action values. ++ * 11-18-11 02.00.07 Incorporating additions for MPI v2.5. ++ * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN. ++ * 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR. ++ * Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define. ++ * 04-17-13 02.00.10 Added MPI25_RAID_ACTION_ADATA_ALLOW_PI. ++ * 11-18-14 02.00.11 Updated copyright information. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_RAID_H ++#define MPI2_RAID_H ++ ++/***************************************************************************** ++* ++* Integrated RAID Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* RAID Action messages ++****************************************************************************/ ++ ++/* ActionDataWord defines for use with MPI2_RAID_ACTION_CREATE_VOLUME action */ ++#define MPI25_RAID_ACTION_ADATA_ALLOW_PI (0x80000000) ++ ++/*ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */ ++#define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) ++#define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001) ++ ++/*use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for ++ *MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ ++ ++/*ActionDataWord defines for use with ++ *MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */ ++#define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD (0x00000001) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */ ++typedef struct _MPI2_RAID_ACTION_RATE_DATA { ++ U8 RateToChange; /*0x00 */ ++ U8 RateOrMode; /*0x01 */ ++ U16 DataScrubDuration; /*0x02 */ ++} MPI2_RAID_ACTION_RATE_DATA, *PTR_MPI2_RAID_ACTION_RATE_DATA, ++ Mpi2RaidActionRateData_t, *pMpi2RaidActionRateData_t; ++ ++#define MPI2_RAID_ACTION_SET_RATE_RESYNC (0x00) ++#define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB (0x01) ++#define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE (0x02) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */ ++typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION { ++ U8 RAIDFunction; /*0x00 */ ++ U8 Flags; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_RAID_ACTION_START_RAID_FUNCTION, ++ *PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION, ++ Mpi2RaidActionStartRaidFunction_t, ++ *pMpi2RaidActionStartRaidFunction_t; ++ ++/*defines for the RAIDFunction field */ ++#define MPI2_RAID_ACTION_START_BACKGROUND_INIT (0x00) ++#define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01) ++#define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK (0x02) ++ ++/*defines for the Flags field */ ++#define MPI2_RAID_ACTION_START_NEW (0x00) ++#define MPI2_RAID_ACTION_START_RESUME (0x01) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */ ++typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION { ++ U8 RAIDFunction; /*0x00 */ ++ U8 Flags; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_RAID_ACTION_STOP_RAID_FUNCTION, ++ *PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION, ++ Mpi2RaidActionStopRaidFunction_t, ++ *pMpi2RaidActionStopRaidFunction_t; ++ ++/*defines for the RAIDFunction field */ ++#define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT (0x00) ++#define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION (0x01) ++#define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK (0x02) ++ ++/*defines for the Flags field */ ++#define MPI2_RAID_ACTION_STOP_ABORT (0x00) ++#define MPI2_RAID_ACTION_STOP_PAUSE (0x01) ++ ++/*ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */ ++typedef struct _MPI2_RAID_ACTION_HOT_SPARE { ++ U8 HotSparePool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 DevHandle; /*0x02 */ ++} MPI2_RAID_ACTION_HOT_SPARE, *PTR_MPI2_RAID_ACTION_HOT_SPARE, ++ Mpi2RaidActionHotSpare_t, *pMpi2RaidActionHotSpare_t; ++ ++/*ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */ ++typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE { ++ U8 Flags; /*0x00 */ ++ U8 DeviceFirmwareUpdateModeTimeout; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++} MPI2_RAID_ACTION_FW_UPDATE_MODE, ++ *PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE, ++ Mpi2RaidActionFwUpdateMode_t, ++ *pMpi2RaidActionFwUpdateMode_t; ++ ++/*ActionDataWord defines for use with ++ *MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */ ++#define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE (0x00) ++#define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE (0x01) ++ ++typedef union _MPI2_RAID_ACTION_DATA { ++ U32 Word; ++ MPI2_RAID_ACTION_RATE_DATA Rates; ++ MPI2_RAID_ACTION_START_RAID_FUNCTION StartRaidFunction; ++ MPI2_RAID_ACTION_STOP_RAID_FUNCTION StopRaidFunction; ++ MPI2_RAID_ACTION_HOT_SPARE HotSpare; ++ MPI2_RAID_ACTION_FW_UPDATE_MODE FwUpdateMode; ++} MPI2_RAID_ACTION_DATA, *PTR_MPI2_RAID_ACTION_DATA, ++ Mpi2RaidActionData_t, *pMpi2RaidActionData_t; ++ ++/*RAID Action Request Message */ ++typedef struct _MPI2_RAID_ACTION_REQUEST { ++ U8 Action; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 VolDevHandle; /*0x04 */ ++ U8 PhysDiskNum; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U32 Reserved3; /*0x0C */ ++ MPI2_RAID_ACTION_DATA ActionDataWord; /*0x10 */ ++ MPI2_SGE_SIMPLE_UNION ActionDataSGE; /*0x14 */ ++} MPI2_RAID_ACTION_REQUEST, *PTR_MPI2_RAID_ACTION_REQUEST, ++ Mpi2RaidActionRequest_t, *pMpi2RaidActionRequest_t; ++ ++/*RAID Action request Action values */ ++ ++#define MPI2_RAID_ACTION_INDICATOR_STRUCT (0x01) ++#define MPI2_RAID_ACTION_CREATE_VOLUME (0x02) ++#define MPI2_RAID_ACTION_DELETE_VOLUME (0x03) ++#define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES (0x04) ++#define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES (0x05) ++#define MPI2_RAID_ACTION_PHYSDISK_OFFLINE (0x0A) ++#define MPI2_RAID_ACTION_PHYSDISK_ONLINE (0x0B) ++#define MPI2_RAID_ACTION_FAIL_PHYSDISK (0x0F) ++#define MPI2_RAID_ACTION_ACTIVATE_VOLUME (0x11) ++#define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15) ++#define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE (0x17) ++#define MPI2_RAID_ACTION_SET_VOLUME_NAME (0x18) ++#define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE (0x19) ++#define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME (0x1C) ++#define MPI2_RAID_ACTION_CREATE_HOT_SPARE (0x1D) ++#define MPI2_RAID_ACTION_DELETE_HOT_SPARE (0x1E) ++#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20) ++#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21) ++#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22) ++#define MPI2_RAID_ACTION_COMPATIBILITY_CHECK (0x23) ++#define MPI2_RAID_ACTION_PHYSDISK_HIDDEN (0x24) ++#define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC (0x80) ++#define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC (0xFF) ++ ++/*RAID Volume Creation Structure */ ++ ++/* ++ *The following define can be customized for the targeted product. ++ */ ++#ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS ++#define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS (1) ++#endif ++ ++typedef struct _MPI2_RAID_VOLUME_PHYSDISK { ++ U8 RAIDSetNum; /*0x00 */ ++ U8 PhysDiskMap; /*0x01 */ ++ U16 PhysDiskDevHandle; /*0x02 */ ++} MPI2_RAID_VOLUME_PHYSDISK, *PTR_MPI2_RAID_VOLUME_PHYSDISK, ++ Mpi2RaidVolumePhysDisk_t, *pMpi2RaidVolumePhysDisk_t; ++ ++/*defines for the PhysDiskMap field */ ++#define MPI2_RAIDACTION_PHYSDISK_PRIMARY (0x01) ++#define MPI2_RAIDACTION_PHYSDISK_SECONDARY (0x02) ++ ++typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT { ++ U8 NumPhysDisks; /*0x00 */ ++ U8 VolumeType; /*0x01 */ ++ U16 Reserved1; /*0x02 */ ++ U32 VolumeCreationFlags; /*0x04 */ ++ U32 VolumeSettings; /*0x08 */ ++ U8 Reserved2; /*0x0C */ ++ U8 ResyncRate; /*0x0D */ ++ U16 DataScrubDuration; /*0x0E */ ++ U64 VolumeMaxLBA; /*0x10 */ ++ U32 StripeSize; /*0x18 */ ++ U8 Name[16]; /*0x1C */ ++ MPI2_RAID_VOLUME_PHYSDISK ++ PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS]; /*0x2C */ ++} MPI2_RAID_VOLUME_CREATION_STRUCT, ++ *PTR_MPI2_RAID_VOLUME_CREATION_STRUCT, ++ Mpi2RaidVolumeCreationStruct_t, ++ *pMpi2RaidVolumeCreationStruct_t; ++ ++/*use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */ ++ ++/*defines for the VolumeCreationFlags field */ ++#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS (0x80000000) ++#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x00000004) ++#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x00000002) ++#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x00000001) ++/*The following is an obsolete define. ++ *It must be shifted left 24 bits in order to set the proper bit. ++ */ ++#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80) ++ ++/*RAID Online Capacity Expansion Structure */ ++ ++typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION { ++ U32 Flags; /*0x00 */ ++ U16 DevHandle0; /*0x04 */ ++ U16 Reserved1; /*0x06 */ ++ U16 DevHandle1; /*0x08 */ ++ U16 Reserved2; /*0x0A */ ++} MPI2_RAID_ONLINE_CAPACITY_EXPANSION, ++ *PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION, ++ Mpi2RaidOnlineCapacityExpansion_t, ++ *pMpi2RaidOnlineCapacityExpansion_t; ++ ++/*RAID Compatibility Input Structure */ ++ ++typedef struct _MPI2_RAID_COMPATIBILITY_INPUT_STRUCT { ++ U16 SourceDevHandle; /*0x00 */ ++ U16 CandidateDevHandle; /*0x02 */ ++ U32 Flags; /*0x04 */ ++ U32 Reserved1; /*0x08 */ ++ U32 Reserved2; /*0x0C */ ++} MPI2_RAID_COMPATIBILITY_INPUT_STRUCT, ++ *PTR_MPI2_RAID_COMPATIBILITY_INPUT_STRUCT, ++ Mpi2RaidCompatibilityInputStruct_t, ++ *pMpi2RaidCompatibilityInputStruct_t; ++ ++/*defines for RAID Compatibility Structure Flags field */ ++#define MPI2_RAID_COMPAT_SOURCE_IS_VOLUME_FLAG (0x00000002) ++#define MPI2_RAID_COMPAT_REPORT_SOURCE_INFO_FLAG (0x00000001) ++ ++/*RAID Volume Indicator Structure */ ++ ++typedef struct _MPI2_RAID_VOL_INDICATOR { ++ U64 TotalBlocks; /*0x00 */ ++ U64 BlocksRemaining; /*0x08 */ ++ U32 Flags; /*0x10 */ ++ U32 ElapsedSeconds; /* 0x14 */ ++} MPI2_RAID_VOL_INDICATOR, *PTR_MPI2_RAID_VOL_INDICATOR, ++ Mpi2RaidVolIndicator_t, *pMpi2RaidVolIndicator_t; ++ ++/*defines for RAID Volume Indicator Flags field */ ++#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000) ++#define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F) ++#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000) ++#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) ++#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002) ++#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003) ++#define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004) ++ ++/*RAID Compatibility Result Structure */ ++ ++typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT { ++ U8 State; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U16 Reserved2; /*0x02 */ ++ U32 GenericAttributes; /*0x04 */ ++ U32 OEMSpecificAttributes; /*0x08 */ ++ U32 Reserved3; /*0x0C */ ++ U32 Reserved4; /*0x10 */ ++} MPI2_RAID_COMPATIBILITY_RESULT_STRUCT, ++ *PTR_MPI2_RAID_COMPATIBILITY_RESULT_STRUCT, ++ Mpi2RaidCompatibilityResultStruct_t, ++ *pMpi2RaidCompatibilityResultStruct_t; ++ ++/*defines for RAID Compatibility Result Structure State field */ ++#define MPI2_RAID_COMPAT_STATE_COMPATIBLE (0x00) ++#define MPI2_RAID_COMPAT_STATE_NOT_COMPATIBLE (0x01) ++ ++/*defines for RAID Compatibility Result Structure GenericAttributes field */ ++#define MPI2_RAID_COMPAT_GENATTRIB_4K_SECTOR (0x00000010) ++ ++#define MPI2_RAID_COMPAT_GENATTRIB_MEDIA_MASK (0x0000000C) ++#define MPI2_RAID_COMPAT_GENATTRIB_SOLID_STATE_DRIVE (0x00000008) ++#define MPI2_RAID_COMPAT_GENATTRIB_HARD_DISK_DRIVE (0x00000004) ++ ++#define MPI2_RAID_COMPAT_GENATTRIB_PROTOCOL_MASK (0x00000003) ++#define MPI2_RAID_COMPAT_GENATTRIB_SAS_PROTOCOL (0x00000002) ++#define MPI2_RAID_COMPAT_GENATTRIB_SATA_PROTOCOL (0x00000001) ++ ++/*RAID Action Reply ActionData union */ ++typedef union _MPI2_RAID_ACTION_REPLY_DATA { ++ U32 Word[6]; ++ MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; ++ U16 VolDevHandle; ++ U8 VolumeState; ++ U8 PhysDiskNum; ++ MPI2_RAID_COMPATIBILITY_RESULT_STRUCT RaidCompatibilityResult; ++} MPI2_RAID_ACTION_REPLY_DATA, *PTR_MPI2_RAID_ACTION_REPLY_DATA, ++ Mpi2RaidActionReplyData_t, *pMpi2RaidActionReplyData_t; ++ ++/*use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for ++ *MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ ++ ++/*RAID Action Reply Message */ ++typedef struct _MPI2_RAID_ACTION_REPLY { ++ U8 Action; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 VolDevHandle; /*0x04 */ ++ U8 PhysDiskNum; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved2; /*0x0A */ ++ U16 Reserved3; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ MPI2_RAID_ACTION_REPLY_DATA ActionData; /*0x14 */ ++} MPI2_RAID_ACTION_REPLY, *PTR_MPI2_RAID_ACTION_REPLY, ++ Mpi2RaidActionReply_t, *pMpi2RaidActionReply_t; ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_sas.h b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h +new file mode 100644 +index 0000000..c10c2c0 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_sas.h +@@ -0,0 +1,303 @@ ++/* ++ * Copyright 2000-2015 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_sas.h ++ * Title: MPI Serial Attached SCSI structures and definitions ++ * Creation Date: February 9, 2007 ++ * ++ * mpi2_sas.h Version: 02.00.10 ++ * ++ * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 ++ * prefix are for use only on MPI v2.5 products, and must not be used ++ * with MPI v2.0 products. Unless otherwise noted, names beginning with ++ * MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products. ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit ++ * Control Request. ++ * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control ++ * Request. ++ * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST ++ * to MPI2_SGE_IO_UNION since it supports chained SGLs. ++ * 05-12-10 02.00.04 Modified some comments. ++ * 08-11-10 02.00.05 Added NCQ operations to SAS IO Unit Control. ++ * 11-18-11 02.00.06 Incorporating additions for MPI v2.5. ++ * 07-10-12 02.00.07 Added MPI2_SATA_PT_SGE_UNION for use in the SATA ++ * Passthrough Request message. ++ * 08-19-13 02.00.08 Made MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL obsolete ++ * for anything newer than MPI v2.0. ++ * 11-18-14 02.00.09 Updated copyright information. ++ * 03-16-15 02.00.10 Updated for MPI v2.6. ++ * Added MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_SAS_H ++#define MPI2_SAS_H ++ ++/* ++ *Values for SASStatus. ++ */ ++#define MPI2_SASSTATUS_SUCCESS (0x00) ++#define MPI2_SASSTATUS_UNKNOWN_ERROR (0x01) ++#define MPI2_SASSTATUS_INVALID_FRAME (0x02) ++#define MPI2_SASSTATUS_UTC_BAD_DEST (0x03) ++#define MPI2_SASSTATUS_UTC_BREAK_RECEIVED (0x04) ++#define MPI2_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05) ++#define MPI2_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06) ++#define MPI2_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07) ++#define MPI2_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08) ++#define MPI2_SASSTATUS_UTC_WRONG_DESTINATION (0x09) ++#define MPI2_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A) ++#define MPI2_SASSTATUS_LONG_INFORMATION_UNIT (0x0B) ++#define MPI2_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C) ++#define MPI2_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D) ++#define MPI2_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E) ++#define MPI2_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F) ++#define MPI2_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10) ++#define MPI2_SASSTATUS_DATA_OFFSET_ERROR (0x11) ++#define MPI2_SASSTATUS_SDSF_NAK_RECEIVED (0x12) ++#define MPI2_SASSTATUS_SDSF_CONNECTION_FAILED (0x13) ++#define MPI2_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14) ++ ++/* ++ *Values for the SAS DeviceInfo field used in SAS Device Status Change Event ++ *data and SAS Configuration pages. ++ */ ++#define MPI2_SAS_DEVICE_INFO_SEP (0x00004000) ++#define MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) ++#define MPI2_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) ++#define MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800) ++#define MPI2_SAS_DEVICE_INFO_SSP_TARGET (0x00000400) ++#define MPI2_SAS_DEVICE_INFO_STP_TARGET (0x00000200) ++#define MPI2_SAS_DEVICE_INFO_SMP_TARGET (0x00000100) ++#define MPI2_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080) ++#define MPI2_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040) ++#define MPI2_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020) ++#define MPI2_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010) ++#define MPI2_SAS_DEVICE_INFO_SATA_HOST (0x00000008) ++ ++#define MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007) ++#define MPI2_SAS_DEVICE_INFO_NO_DEVICE (0x00000000) ++#define MPI2_SAS_DEVICE_INFO_END_DEVICE (0x00000001) ++#define MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002) ++#define MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003) ++ ++/***************************************************************************** ++* ++* SAS Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* SMP Passthrough messages ++****************************************************************************/ ++ ++/*SMP Passthrough Request Message */ ++typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST { ++ U8 PassthroughFlags; /*0x00 */ ++ U8 PhysicalPort; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 RequestDataLength; /*0x04 */ ++ U8 SGLFlags; /*0x06*//*MPI v2.0 only. Reserved on MPI v2.5*/ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Reserved2; /*0x0C */ ++ U64 SASAddress; /*0x10 */ ++ U32 Reserved3; /*0x18 */ ++ U32 Reserved4; /*0x1C */ ++ MPI2_SIMPLE_SGE_UNION SGL;/*0x20 */ ++} MPI2_SMP_PASSTHROUGH_REQUEST, *PTR_MPI2_SMP_PASSTHROUGH_REQUEST, ++ Mpi2SmpPassthroughRequest_t, *pMpi2SmpPassthroughRequest_t; ++ ++/*values for PassthroughFlags field */ ++#define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) ++ ++/*MPI v2.0: use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*SMP Passthrough Reply Message */ ++typedef struct _MPI2_SMP_PASSTHROUGH_REPLY { ++ U8 PassthroughFlags; /*0x00 */ ++ U8 PhysicalPort; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 ResponseDataLength; /*0x04 */ ++ U8 SGLFlags; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U8 Reserved2; /*0x0C */ ++ U8 SASStatus; /*0x0D */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 Reserved3; /*0x14 */ ++ U8 ResponseData[4]; /*0x18 */ ++} MPI2_SMP_PASSTHROUGH_REPLY, *PTR_MPI2_SMP_PASSTHROUGH_REPLY, ++ Mpi2SmpPassthroughReply_t, *pMpi2SmpPassthroughReply_t; ++ ++/*values for PassthroughFlags field */ ++#define MPI2_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80) ++ ++/*values for SASStatus field are at the top of this file */ ++ ++/**************************************************************************** ++* SATA Passthrough messages ++****************************************************************************/ ++ ++typedef union _MPI2_SATA_PT_SGE_UNION { ++ MPI2_SGE_SIMPLE_UNION MpiSimple; /*MPI v2.0 only */ ++ MPI2_SGE_CHAIN_UNION MpiChain; /*MPI v2.0 only */ ++ MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; ++ MPI2_IEEE_SGE_CHAIN_UNION IeeeChain; /*MPI v2.0 only */ ++ MPI25_IEEE_SGE_CHAIN64 IeeeChain64; /*MPI v2.5 only */ ++} MPI2_SATA_PT_SGE_UNION, *PTR_MPI2_SATA_PT_SGE_UNION, ++ Mpi2SataPTSGEUnion_t, *pMpi2SataPTSGEUnion_t; ++ ++/*SATA Passthrough Request Message */ ++typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST { ++ U16 DevHandle; /*0x00 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 PassthroughFlags; /*0x04 */ ++ U8 SGLFlags; /*0x06*//*MPI v2.0 only. Reserved on MPI v2.5*/ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U32 Reserved2; /*0x0C */ ++ U32 Reserved3; /*0x10 */ ++ U32 Reserved4; /*0x14 */ ++ U32 DataLength; /*0x18 */ ++ U8 CommandFIS[20]; /*0x1C */ ++ MPI2_SATA_PT_SGE_UNION SGL;/*0x30*//*MPI v2.5: IEEE 64 elements only*/ ++} MPI2_SATA_PASSTHROUGH_REQUEST, *PTR_MPI2_SATA_PASSTHROUGH_REQUEST, ++ Mpi2SataPassthroughRequest_t, ++ *pMpi2SataPassthroughRequest_t; ++ ++/*values for PassthroughFlags field */ ++#define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA (0x0040) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_DMA (0x0020) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_PIO (0x0010) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002) ++#define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001) ++ ++/*MPI v2.0: use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*SATA Passthrough Reply Message */ ++typedef struct _MPI2_SATA_PASSTHROUGH_REPLY { ++ U16 DevHandle; /*0x00 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 PassthroughFlags; /*0x04 */ ++ U8 SGLFlags; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved1; /*0x0A */ ++ U8 Reserved2; /*0x0C */ ++ U8 SASStatus; /*0x0D */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 StatusFIS[20]; /*0x14 */ ++ U32 StatusControlRegisters; /*0x28 */ ++ U32 TransferCount; /*0x2C */ ++} MPI2_SATA_PASSTHROUGH_REPLY, *PTR_MPI2_SATA_PASSTHROUGH_REPLY, ++ Mpi2SataPassthroughReply_t, *pMpi2SataPassthroughReply_t; ++ ++/*values for SASStatus field are at the top of this file */ ++ ++/**************************************************************************** ++* SAS IO Unit Control messages ++* (MPI v2.5 and earlier only. ++* Replaced by IO Unit Control messages in MPI v2.6 and later.) ++****************************************************************************/ ++ ++/*SAS IO Unit Control Request Message */ ++typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST { ++ U8 Operation; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 DevHandle; /*0x04 */ ++ U8 IOCParameter; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U8 PhyNum; /*0x0E */ ++ U8 PrimFlags; /*0x0F */ ++ U32 Primitive; /*0x10 */ ++ U8 LookupMethod; /*0x14 */ ++ U8 Reserved5; /*0x15 */ ++ U16 SlotNumber; /*0x16 */ ++ U64 LookupAddress; /*0x18 */ ++ U32 IOCParameterValue; /*0x20 */ ++ U32 Reserved7; /*0x24 */ ++ U32 Reserved8; /*0x28 */ ++} MPI2_SAS_IOUNIT_CONTROL_REQUEST, ++ *PTR_MPI2_SAS_IOUNIT_CONTROL_REQUEST, ++ Mpi2SasIoUnitControlRequest_t, ++ *pMpi2SasIoUnitControlRequest_t; ++ ++/*values for the Operation field */ ++#define MPI2_SAS_OP_CLEAR_ALL_PERSISTENT (0x02) ++#define MPI2_SAS_OP_PHY_LINK_RESET (0x06) ++#define MPI2_SAS_OP_PHY_HARD_RESET (0x07) ++#define MPI2_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) ++#define MPI2_SAS_OP_SEND_PRIMITIVE (0x0A) ++#define MPI2_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) ++#define MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) /* MPI v2.0 only */ ++#define MPI2_SAS_OP_REMOVE_DEVICE (0x0D) ++#define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E) ++#define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F) ++#define MPI25_SAS_OP_ENABLE_FP_DEVICE (0x10) ++#define MPI25_SAS_OP_DISABLE_FP_DEVICE (0x11) ++#define MPI25_SAS_OP_ENABLE_FP_ALL (0x12) ++#define MPI25_SAS_OP_DISABLE_FP_ALL (0x13) ++#define MPI2_SAS_OP_DEV_ENABLE_NCQ (0x14) ++#define MPI2_SAS_OP_DEV_DISABLE_NCQ (0x15) ++#define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80) ++ ++/*values for the PrimFlags field */ ++#define MPI2_SAS_PRIMFLAGS_SINGLE (0x08) ++#define MPI2_SAS_PRIMFLAGS_TRIPLE (0x02) ++#define MPI2_SAS_PRIMFLAGS_REDUNDANT (0x01) ++ ++/*values for the LookupMethod field */ ++#define MPI2_SAS_LOOKUP_METHOD_SAS_ADDRESS (0x01) ++#define MPI2_SAS_LOOKUP_METHOD_SAS_ENCLOSURE_SLOT (0x02) ++#define MPI2_SAS_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03) ++ ++/*SAS IO Unit Control Reply Message */ ++typedef struct _MPI2_SAS_IOUNIT_CONTROL_REPLY { ++ U8 Operation; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 DevHandle; /*0x04 */ ++ U8 IOCParameter; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved3; /*0x0A */ ++ U16 Reserved4; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_SAS_IOUNIT_CONTROL_REPLY, ++ *PTR_MPI2_SAS_IOUNIT_CONTROL_REPLY, ++ Mpi2SasIoUnitControlReply_t, *pMpi2SasIoUnitControlReply_t; ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +new file mode 100644 +index 0000000..5f9289a +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h +@@ -0,0 +1,483 @@ ++/* ++ * Copyright 2000-2014 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_tool.h ++ * Title: MPI diagnostic tool structures and definitions ++ * Creation Date: March 26, 2007 ++ * ++ * mpi2_tool.h Version: 02.00.13 ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release ++ * structures and defines. ++ * 02-29-08 02.00.02 Modified various names to make them 32-character unique. ++ * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. ++ * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request ++ * and reply messages. ++ * Added MPI2_DIAG_BUF_TYPE_EXTENDED. ++ * Incremented MPI2_DIAG_BUF_TYPE_COUNT. ++ * 05-12-10 02.00.05 Added Diagnostic Data Upload tool. ++ * 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer ++ * Post Request. ++ * 05-25-11 02.00.07 Added Flags field and related defines to ++ * MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST. ++ * 11-18-11 02.00.08 Incorporating additions for MPI v2.5. ++ * 07-10-12 02.00.09 Add MPI v2.5 Toolbox Diagnostic CLI Tool Request ++ * message. ++ * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that ++ * it uses MPI Chain SGE as well as MPI Simple SGE. ++ * 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info. ++ * 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC. ++ * 11-18-14 02.00.13 Updated copyright information. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_TOOL_H ++#define MPI2_TOOL_H ++ ++/***************************************************************************** ++* ++* Toolbox Messages ++* ++*****************************************************************************/ ++ ++/*defines for the Tools */ ++#define MPI2_TOOLBOX_CLEAN_TOOL (0x00) ++#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) ++#define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) ++#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) ++#define MPI2_TOOLBOX_BEACON_TOOL (0x05) ++#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) ++#define MPI2_TOOLBOX_TEXT_DISPLAY_TOOL (0x07) ++ ++/**************************************************************************** ++* Toolbox reply ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_REPLY { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_TOOLBOX_REPLY, *PTR_MPI2_TOOLBOX_REPLY, ++ Mpi2ToolboxReply_t, *pMpi2ToolboxReply_t; ++ ++/**************************************************************************** ++* Toolbox Clean Tool request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Flags; /*0x0C */ ++} MPI2_TOOLBOX_CLEAN_REQUEST, *PTR_MPI2_TOOLBOX_CLEAN_REQUEST, ++ Mpi2ToolboxCleanRequest_t, *pMpi2ToolboxCleanRequest_t; ++ ++/*values for the Flags field */ ++#define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000) ++#define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000) ++#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) ++#define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) ++#define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) ++#define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000) ++#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000) ++#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000) ++#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004) ++#define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002) ++#define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001) ++ ++/**************************************************************************** ++* Toolbox Memory Move request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ MPI2_SGE_SIMPLE_UNION SGL; /*0x0C */ ++} MPI2_TOOLBOX_MEM_MOVE_REQUEST, *PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST, ++ Mpi2ToolboxMemMoveRequest_t, *pMpi2ToolboxMemMoveRequest_t; ++ ++/**************************************************************************** ++* Toolbox Diagnostic Data Upload request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 SGLFlags; /*0x0C */ ++ U8 Reserved5; /*0x0D */ ++ U16 Reserved6; /*0x0E */ ++ U32 Flags; /*0x10 */ ++ U32 DataLength; /*0x14 */ ++ MPI2_SGE_SIMPLE_UNION SGL; /*0x18 */ ++} MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, ++ *PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, ++ Mpi2ToolboxDiagDataUploadRequest_t, ++ *pMpi2ToolboxDiagDataUploadRequest_t; ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER { ++ U32 DiagDataLength; /*00h */ ++ U8 FormatCode; /*04h */ ++ U8 Reserved1; /*05h */ ++ U16 Reserved2; /*06h */ ++} MPI2_DIAG_DATA_UPLOAD_HEADER, *PTR_MPI2_DIAG_DATA_UPLOAD_HEADER, ++ Mpi2DiagDataUploadHeader_t, *pMpi2DiagDataUploadHeader_t; ++ ++/**************************************************************************** ++* Toolbox ISTWI Read Write Tool ++****************************************************************************/ ++ ++/*Toolbox ISTWI Read Write Tool request message */ ++typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 Reserved6; /*0x10 */ ++ U8 DevIndex; /*0x14 */ ++ U8 Action; /*0x15 */ ++ U8 SGLFlags; /*0x16 */ ++ U8 Flags; /*0x17 */ ++ U16 TxDataLength; /*0x18 */ ++ U16 RxDataLength; /*0x1A */ ++ U32 Reserved8; /*0x1C */ ++ U32 Reserved9; /*0x20 */ ++ U32 Reserved10; /*0x24 */ ++ U32 Reserved11; /*0x28 */ ++ U32 Reserved12; /*0x2C */ ++ MPI2_SGE_SIMPLE_UNION SGL; /*0x30 */ ++} MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, ++ *PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, ++ Mpi2ToolboxIstwiReadWriteRequest_t, ++ *pMpi2ToolboxIstwiReadWriteRequest_t; ++ ++/*values for the Action field */ ++#define MPI2_TOOL_ISTWI_ACTION_READ_DATA (0x01) ++#define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA (0x02) ++#define MPI2_TOOL_ISTWI_ACTION_SEQUENCE (0x03) ++#define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS (0x10) ++#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) ++#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*values for the Flags field */ ++#define MPI2_TOOL_ISTWI_FLAG_AUTO_RESERVE_RELEASE (0x80) ++#define MPI2_TOOL_ISTWI_FLAG_PAGE_ADDR_MASK (0x07) ++ ++/*Toolbox ISTWI Read Write Tool reply message */ ++typedef struct _MPI2_TOOLBOX_ISTWI_REPLY { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U8 DevIndex; /*0x14 */ ++ U8 Action; /*0x15 */ ++ U8 IstwiStatus; /*0x16 */ ++ U8 Reserved6; /*0x17 */ ++ U16 TxDataCount; /*0x18 */ ++ U16 RxDataCount; /*0x1A */ ++} MPI2_TOOLBOX_ISTWI_REPLY, *PTR_MPI2_TOOLBOX_ISTWI_REPLY, ++ Mpi2ToolboxIstwiReply_t, *pMpi2ToolboxIstwiReply_t; ++ ++/**************************************************************************** ++* Toolbox Beacon Tool request ++****************************************************************************/ ++ ++typedef struct _MPI2_TOOLBOX_BEACON_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 Reserved5; /*0x0C */ ++ U8 PhysicalPort; /*0x0D */ ++ U8 Reserved6; /*0x0E */ ++ U8 Flags; /*0x0F */ ++} MPI2_TOOLBOX_BEACON_REQUEST, *PTR_MPI2_TOOLBOX_BEACON_REQUEST, ++ Mpi2ToolboxBeaconRequest_t, *pMpi2ToolboxBeaconRequest_t; ++ ++/*values for the Flags field */ ++#define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF (0x00) ++#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01) ++ ++/**************************************************************************** ++* Toolbox Diagnostic CLI Tool ++****************************************************************************/ ++ ++#define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C) ++ ++/*MPI v2.0 Toolbox Diagnostic CLI Tool request message */ ++typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U8 SGLFlags; /*0x0C */ ++ U8 Reserved5; /*0x0D */ ++ U16 Reserved6; /*0x0E */ ++ U32 DataLength; /*0x10 */ ++ U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */ ++ MPI2_MPI_SGE_IO_UNION SGL; /*0x70 */ ++} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ *PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ Mpi2ToolboxDiagnosticCliRequest_t, ++ *pMpi2ToolboxDiagnosticCliRequest_t; ++ ++/*use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ ++ ++/*MPI v2.5 Toolbox Diagnostic CLI Tool request message */ ++typedef struct _MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U32 Reserved5; /*0x0C */ ++ U32 DataLength; /*0x10 */ ++ U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */ ++ MPI25_SGE_IO_UNION SGL; /* 0x70 */ ++} MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ *PTR_MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, ++ Mpi25ToolboxDiagnosticCliRequest_t, ++ *pMpi25ToolboxDiagnosticCliRequest_t; ++ ++/*Toolbox Diagnostic CLI Tool reply message */ ++typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY { ++ U8 Tool; /*0x00 */ ++ U8 Reserved1; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 ReturnedDataLength; /*0x14 */ ++} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY, ++ *PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY, ++ Mpi2ToolboxDiagnosticCliReply_t, ++ *pMpi2ToolboxDiagnosticCliReply_t; ++ ++ ++/**************************************************************************** ++* Toolbox Console Text Display Tool ++****************************************************************************/ ++ ++/* Toolbox Console Text Display Tool request message */ ++typedef struct _MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST { ++ U8 Tool; /* 0x00 */ ++ U8 Reserved1; /* 0x01 */ ++ U8 ChainOffset; /* 0x02 */ ++ U8 Function; /* 0x03 */ ++ U16 Reserved2; /* 0x04 */ ++ U8 Reserved3; /* 0x06 */ ++ U8 MsgFlags; /* 0x07 */ ++ U8 VP_ID; /* 0x08 */ ++ U8 VF_ID; /* 0x09 */ ++ U16 Reserved4; /* 0x0A */ ++ U8 Console; /* 0x0C */ ++ U8 Flags; /* 0x0D */ ++ U16 Reserved6; /* 0x0E */ ++ U8 TextToDisplay[4]; /* 0x10 */ ++} MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, ++*PTR_MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, ++Mpi2ToolboxTextDisplayRequest_t, ++*pMpi2ToolboxTextDisplayRequest_t; ++ ++/* defines for the Console field */ ++#define MPI2_TOOLBOX_CONSOLE_TYPE_MASK (0xF0) ++#define MPI2_TOOLBOX_CONSOLE_TYPE_DEFAULT (0x00) ++#define MPI2_TOOLBOX_CONSOLE_TYPE_UART (0x10) ++#define MPI2_TOOLBOX_CONSOLE_TYPE_ETHERNET (0x20) ++ ++#define MPI2_TOOLBOX_CONSOLE_NUMBER_MASK (0x0F) ++ ++/* defines for the Flags field */ ++#define MPI2_TOOLBOX_CONSOLE_FLAG_TIMESTAMP (0x01) ++ ++ ++ ++/***************************************************************************** ++* ++* Diagnostic Buffer Messages ++* ++*****************************************************************************/ ++ ++/**************************************************************************** ++* Diagnostic Buffer Post request ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST { ++ U8 ExtendedType; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U64 BufferAddress; /*0x0C */ ++ U32 BufferLength; /*0x14 */ ++ U32 Reserved5; /*0x18 */ ++ U32 Reserved6; /*0x1C */ ++ U32 Flags; /*0x20 */ ++ U32 ProductSpecific[23]; /*0x24 */ ++} MPI2_DIAG_BUFFER_POST_REQUEST, *PTR_MPI2_DIAG_BUFFER_POST_REQUEST, ++ Mpi2DiagBufferPostRequest_t, *pMpi2DiagBufferPostRequest_t; ++ ++/*values for the ExtendedType field */ ++#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02) ++ ++/*values for the BufferType field */ ++#define MPI2_DIAG_BUF_TYPE_TRACE (0x00) ++#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01) ++#define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02) ++/*count of the number of buffer types */ ++#define MPI2_DIAG_BUF_TYPE_COUNT (0x03) ++ ++/*values for the Flags field */ ++#define MPI2_DIAG_BUF_FLAG_RELEASE_ON_FULL (0x00000002) ++#define MPI2_DIAG_BUF_FLAG_IMMEDIATE_RELEASE (0x00000001) ++ ++/**************************************************************************** ++* Diagnostic Buffer Post reply ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_BUFFER_POST_REPLY { ++ U8 ExtendedType; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++ U32 TransferLength; /*0x14 */ ++} MPI2_DIAG_BUFFER_POST_REPLY, *PTR_MPI2_DIAG_BUFFER_POST_REPLY, ++ Mpi2DiagBufferPostReply_t, *pMpi2DiagBufferPostReply_t; ++ ++/**************************************************************************** ++* Diagnostic Release request ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_RELEASE_REQUEST { ++ U8 Reserved1; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 ChainOffset; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++} MPI2_DIAG_RELEASE_REQUEST, *PTR_MPI2_DIAG_RELEASE_REQUEST, ++ Mpi2DiagReleaseRequest_t, *pMpi2DiagReleaseRequest_t; ++ ++/**************************************************************************** ++* Diagnostic Buffer Post reply ++****************************************************************************/ ++ ++typedef struct _MPI2_DIAG_RELEASE_REPLY { ++ U8 Reserved1; /*0x00 */ ++ U8 BufferType; /*0x01 */ ++ U8 MsgLength; /*0x02 */ ++ U8 Function; /*0x03 */ ++ U16 Reserved2; /*0x04 */ ++ U8 Reserved3; /*0x06 */ ++ U8 MsgFlags; /*0x07 */ ++ U8 VP_ID; /*0x08 */ ++ U8 VF_ID; /*0x09 */ ++ U16 Reserved4; /*0x0A */ ++ U16 Reserved5; /*0x0C */ ++ U16 IOCStatus; /*0x0E */ ++ U32 IOCLogInfo; /*0x10 */ ++} MPI2_DIAG_RELEASE_REPLY, *PTR_MPI2_DIAG_RELEASE_REPLY, ++ Mpi2DiagReleaseReply_t, *pMpi2DiagReleaseReply_t; ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_type.h b/drivers/scsi/mpt2sas/mpi/mpi2_type.h +new file mode 100644 +index 0000000..92a81ab +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpi/mpi2_type.h +@@ -0,0 +1,57 @@ ++/* ++ * Copyright 2000-2014 Avago Technologies. All rights reserved. ++ * ++ * ++ * Name: mpi2_type.h ++ * Title: MPI basic type definitions ++ * Creation Date: August 16, 2006 ++ * ++ * mpi2_type.h Version: 02.00.01 ++ * ++ * Version History ++ * --------------- ++ * ++ * Date Version Description ++ * -------- -------- ------------------------------------------------------ ++ * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. ++ * 11-18-14 02.00.01 Updated copyright information. ++ * -------------------------------------------------------------------------- ++ */ ++ ++#ifndef MPI2_TYPE_H ++#define MPI2_TYPE_H ++ ++/******************************************************************************* ++ * Define * if it hasn't already been defined. By default ++ * * is defined to be a near pointer. MPI2_POINTER can be defined as ++ * a far pointer by defining * as "far *" before this header file is ++ * included. ++ */ ++ ++/* the basic types may have already been included by mpi_type.h */ ++#ifndef MPI_TYPE_H ++/***************************************************************************** ++* ++* Basic Types ++* ++*****************************************************************************/ ++ ++typedef u8 U8; ++typedef __le16 U16; ++typedef __le32 U32; ++typedef __le64 U64 __attribute__ ((aligned(4))); ++ ++/***************************************************************************** ++* ++* Pointer Types ++* ++*****************************************************************************/ ++ ++typedef U8 *PU8; ++typedef U16 *PU16; ++typedef U32 *PU32; ++typedef U64 *PU64; ++ ++#endif ++ ++#endif +diff --git a/drivers/scsi/mpt2sas/mpt3sas_base.c b/drivers/scsi/mpt2sas/mpt3sas_base.c +new file mode 100644 +index 0000000..224bf9d +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_base.c +@@ -0,0 +1,5713 @@ ++/* ++ * This is the Fusion MPT base driver providing common API layer interface ++ * for access to MPT (Message Passing Technology) firmware. ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include "mpt3sas_base.h" ++ ++static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; ++ ++ ++#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ ++ ++ /* maximum controller queue depth */ ++#define MAX_HBA_QUEUE_DEPTH 30000 ++#define MAX_CHAIN_DEPTH 100000 ++static int max_queue_depth = -1; ++module_param(max_queue_depth, int, 0); ++MODULE_PARM_DESC(max_queue_depth, " max controller queue depth "); ++ ++static int max_sgl_entries = -1; ++module_param(max_sgl_entries, int, 0); ++MODULE_PARM_DESC(max_sgl_entries, " max sg entries "); ++ ++static int msix_disable = -1; ++module_param(msix_disable, int, 0); ++MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); ++ ++static int smp_affinity_enable = 1; ++module_param(smp_affinity_enable, int, S_IRUGO); ++MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disbale Default: enable(1)"); ++ ++static int max_msix_vectors = -1; ++module_param(max_msix_vectors, int, 0); ++MODULE_PARM_DESC(max_msix_vectors, ++ " max msix vectors"); ++ ++static int mpt2sas_fwfault_debug; ++MODULE_PARM_DESC(mpt2sas_fwfault_debug, ++ " enable detection of firmware fault and halt firmware - (default=0)"); ++ ++static int ++_base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag); ++ ++/** ++ * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. ++ * ++ */ ++static int ++_scsih_set_fwfault_debug(const char *val, struct kernel_param *kp) ++{ ++ int ret = param_set_int(val, kp); ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (ret) ++ return ret; ++ ++ /* global ioc spinlock to protect controller list on list operations */ ++ pr_info("setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) ++ ioc->fwfault_debug = mpt2sas_fwfault_debug; ++ spin_unlock(&gioc_lock_mpt2sas); ++ return 0; ++} ++module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug, ++ param_get_int, &mpt2sas_fwfault_debug, 0644); ++ ++/** ++ * mpt2sas_remove_dead_ioc_func - kthread context to remove dead ioc ++ * @arg: input argument, used to derive ioc ++ * ++ * Return 0 if controller is removed from pci subsystem. ++ * Return -1 for other case. ++ */ ++static int mpt2sas_remove_dead_ioc_func(void *arg) ++{ ++ struct MPT3SAS_ADAPTER *ioc = (struct MPT3SAS_ADAPTER *)arg; ++ struct pci_dev *pdev; ++ ++ if ((ioc == NULL)) ++ return -1; ++ ++ pdev = ioc->pdev; ++ if ((pdev == NULL)) ++ return -1; ++ pci_stop_and_remove_bus_device_locked(pdev); ++ return 0; ++} ++ ++/** ++ * _base_fault_reset_work - workq handling ioc fault conditions ++ * @work: input argument, used to derive ioc ++ * Context: sleep. ++ * ++ * Return nothing. ++ */ ++static void ++_base_fault_reset_work(struct work_struct *work) ++{ ++ struct MPT3SAS_ADAPTER *ioc = ++ container_of(work, struct MPT3SAS_ADAPTER, fault_reset_work.work); ++ unsigned long flags; ++ u32 doorbell; ++ int rc; ++ struct task_struct *p; ++ ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ if (ioc->shost_recovery || ioc->pci_error_recovery) ++ goto rearm_timer; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ ++ doorbell = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_MASK) { ++ pr_err(MPT3SAS_FMT "SAS host is non-operational !!!!\n", ++ ioc->name); ++ ++ /* It may be possible that EEH recovery can resolve some of ++ * pci bus failure issues rather removing the dead ioc function ++ * by considering controller is in a non-operational state. So ++ * here priority is given to the EEH recovery. If it doesn't ++ * not resolve this issue, mpt3sas driver will consider this ++ * controller to non-operational state and remove the dead ioc ++ * function. ++ */ ++ if (ioc->non_operational_loop++ < 5) { ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, ++ flags); ++ goto rearm_timer; ++ } ++ ++ /* ++ * Call _scsih_flush_pending_cmds callback so that we flush all ++ * pending commands back to OS. This call is required to aovid ++ * deadlock at block layer. Dead IOC will fail to do diag reset, ++ * and this call is safe since dead ioc will never return any ++ * command back from HW. ++ */ ++ ioc->schedule_dead_ioc_flush_running_cmds(ioc); ++ /* ++ * Set remove_host flag early since kernel thread will ++ * take some time to execute. ++ */ ++ ioc->remove_host = 1; ++ /*Remove the Dead Host */ ++ p = kthread_run(mpt2sas_remove_dead_ioc_func, ioc, ++ "%s_dead_ioc_%d", ioc->driver_name, ioc->id); ++ if (IS_ERR(p)) ++ pr_err(MPT3SAS_FMT ++ "%s: Running mpt2sas_dead_ioc thread failed !!!!\n", ++ ioc->name, __func__); ++ else ++ pr_err(MPT3SAS_FMT ++ "%s: Running mpt2sas_dead_ioc thread success !!!!\n", ++ ioc->name, __func__); ++ return; /* don't rearm timer */ ++ } ++ ++ ioc->non_operational_loop = 0; ++ ++ if ((doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) { ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ pr_warn(MPT3SAS_FMT "%s: hard reset: %s\n", ioc->name, ++ __func__, (rc == 0) ? "success" : "failed"); ++ doorbell = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) ++ mpt2sas_base_fault_info(ioc, doorbell & ++ MPI2_DOORBELL_DATA_MASK); ++ if (rc && (doorbell & MPI2_IOC_STATE_MASK) != ++ MPI2_IOC_STATE_OPERATIONAL) ++ return; /* don't rearm timer */ ++ } ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ rearm_timer: ++ if (ioc->fault_reset_work_q) ++ queue_delayed_work(ioc->fault_reset_work_q, ++ &ioc->fault_reset_work, ++ msecs_to_jiffies(FAULT_POLLING_INTERVAL)); ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++} ++ ++/** ++ * mpt2sas_base_start_watchdog - start the fault_reset_work_q ++ * @ioc: per adapter object ++ * Context: sleep. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned long flags; ++ ++ if (ioc->fault_reset_work_q) ++ return; ++ ++ /* initialize fault polling */ ++ ++ INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work); ++ snprintf(ioc->fault_reset_work_q_name, ++ sizeof(ioc->fault_reset_work_q_name), "poll_%s%d_status", ++ ioc->driver_name, ioc->id); ++ ioc->fault_reset_work_q = ++ create_singlethread_workqueue(ioc->fault_reset_work_q_name); ++ if (!ioc->fault_reset_work_q) { ++ pr_err(MPT3SAS_FMT "%s: failed (line=%d)\n", ++ ioc->name, __func__, __LINE__); ++ return; ++ } ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ if (ioc->fault_reset_work_q) ++ queue_delayed_work(ioc->fault_reset_work_q, ++ &ioc->fault_reset_work, ++ msecs_to_jiffies(FAULT_POLLING_INTERVAL)); ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++} ++ ++/** ++ * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q ++ * @ioc: per adapter object ++ * Context: sleep. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned long flags; ++ struct workqueue_struct *wq; ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ wq = ioc->fault_reset_work_q; ++ ioc->fault_reset_work_q = NULL; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ if (wq) { ++ if (!cancel_delayed_work_sync(&ioc->fault_reset_work)) ++ flush_workqueue(wq); ++ destroy_workqueue(wq); ++ } ++} ++ ++/** ++ * mpt2sas_base_fault_info - verbose translation of firmware FAULT code ++ * @ioc: per adapter object ++ * @fault_code: fault code ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code) ++{ ++ pr_err(MPT3SAS_FMT "fault_state(0x%04x)!\n", ++ ioc->name, fault_code); ++} ++ ++/** ++ * mpt2sas_halt_firmware - halt's mpt controller firmware ++ * @ioc: per adapter object ++ * ++ * For debugging timeout related issues. Writing 0xCOFFEE00 ++ * to the doorbell register will halt controller firmware. With ++ * the purpose to stop both driver and firmware, the enduser can ++ * obtain a ring buffer from controller UART. ++ */ ++void ++mpt2sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 doorbell; ++ ++ if (!ioc->fwfault_debug) ++ return; ++ ++ dump_stack(); ++ ++ doorbell = readl(&ioc->chip->Doorbell); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) ++ mpt2sas_base_fault_info(ioc , doorbell); ++ else { ++ writel(0xC0FFEE00, &ioc->chip->Doorbell); ++ pr_err(MPT3SAS_FMT "Firmware is halted due to command timeout\n", ++ ioc->name); ++ } ++ ++ if (ioc->fwfault_debug == 2) ++ for (;;) ++ ; ++ else ++ panic("panic in %s\n", __func__); ++} ++ ++/** ++ * _base_sas_ioc_info - verbose translation of the ioc status ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @request_hdr: request mf ++ * ++ * Return nothing. ++ */ ++static void ++_base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply, ++ MPI2RequestHeader_t *request_hdr) ++{ ++ u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ char *desc = NULL; ++ u16 frame_sz; ++ char *func_str = NULL; ++ ++ /* SCSI_IO, RAID_PASS are handled from _scsih_scsi_ioc_info */ ++ if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ request_hdr->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || ++ request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION) ++ return; ++ ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ return; ++ ++ switch (ioc_status) { ++ ++/**************************************************************************** ++* Common IOCStatus values for all replies ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_INVALID_FUNCTION: ++ desc = "invalid function"; ++ break; ++ case MPI2_IOCSTATUS_BUSY: ++ desc = "busy"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_SGL: ++ desc = "invalid sgl"; ++ break; ++ case MPI2_IOCSTATUS_INTERNAL_ERROR: ++ desc = "internal error"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_VPID: ++ desc = "invalid vpid"; ++ break; ++ case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: ++ desc = "insufficient resources"; ++ break; ++ case MPI2_IOCSTATUS_INSUFFICIENT_POWER: ++ desc = "insufficient power"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_FIELD: ++ desc = "invalid field"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_STATE: ++ desc = "invalid state"; ++ break; ++ case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED: ++ desc = "op state not supported"; ++ break; ++ ++/**************************************************************************** ++* Config IOCStatus values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION: ++ desc = "config invalid action"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE: ++ desc = "config invalid type"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE: ++ desc = "config invalid page"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_INVALID_DATA: ++ desc = "config invalid data"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS: ++ desc = "config no defaults"; ++ break; ++ case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT: ++ desc = "config cant commit"; ++ break; ++ ++/**************************************************************************** ++* SCSI IO Reply ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: ++ case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE: ++ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: ++ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: ++ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: ++ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: ++ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: ++ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: ++ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: ++ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED: ++ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: ++ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: ++ break; ++ ++/**************************************************************************** ++* For use by SCSI Initiator and SCSI Target end-to-end data protection ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ desc = "eedp guard error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ desc = "eedp ref tag error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ desc = "eedp app tag error"; ++ break; ++ ++/**************************************************************************** ++* SCSI Target values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX: ++ desc = "target invalid io index"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_ABORTED: ++ desc = "target aborted"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: ++ desc = "target no conn retryable"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_NO_CONNECTION: ++ desc = "target no connection"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: ++ desc = "target xfer count mismatch"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: ++ desc = "target data offset error"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: ++ desc = "target too much write data"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT: ++ desc = "target iu too short"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: ++ desc = "target ack nak timeout"; ++ break; ++ case MPI2_IOCSTATUS_TARGET_NAK_RECEIVED: ++ desc = "target nak received"; ++ break; ++ ++/**************************************************************************** ++* Serial Attached SCSI values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: ++ desc = "smp request failed"; ++ break; ++ case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: ++ desc = "smp data overrun"; ++ break; ++ ++/**************************************************************************** ++* Diagnostic Buffer Post / Diagnostic Release values ++****************************************************************************/ ++ ++ case MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED: ++ desc = "diagnostic released"; ++ break; ++ default: ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ switch (request_hdr->Function) { ++ case MPI2_FUNCTION_CONFIG: ++ frame_sz = sizeof(Mpi2ConfigRequest_t) + ioc->sge_size; ++ func_str = "config_page"; ++ break; ++ case MPI2_FUNCTION_SCSI_TASK_MGMT: ++ frame_sz = sizeof(Mpi2SCSITaskManagementRequest_t); ++ func_str = "task_mgmt"; ++ break; ++ case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: ++ frame_sz = sizeof(Mpi2SasIoUnitControlRequest_t); ++ func_str = "sas_iounit_ctl"; ++ break; ++ case MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: ++ frame_sz = sizeof(Mpi2SepRequest_t); ++ func_str = "enclosure"; ++ break; ++ case MPI2_FUNCTION_IOC_INIT: ++ frame_sz = sizeof(Mpi2IOCInitRequest_t); ++ func_str = "ioc_init"; ++ break; ++ case MPI2_FUNCTION_PORT_ENABLE: ++ frame_sz = sizeof(Mpi2PortEnableRequest_t); ++ func_str = "port_enable"; ++ break; ++ case MPI2_FUNCTION_SMP_PASSTHROUGH: ++ frame_sz = sizeof(Mpi2SmpPassthroughRequest_t) + ioc->sge_size; ++ func_str = "smp_passthru"; ++ break; ++ default: ++ frame_sz = 32; ++ func_str = "unknown"; ++ break; ++ } ++ ++ pr_warn(MPT3SAS_FMT "ioc_status: %s(0x%04x), request(0x%p),(%s)\n", ++ ioc->name, desc, ioc_status, request_hdr, func_str); ++ ++ _debug_dump_mf(request_hdr, frame_sz/4); ++} ++ ++/** ++ * _base_display_event_data - verbose translation of firmware asyn events ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_event_data(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventNotificationReply_t *mpi_reply) ++{ ++ char *desc = NULL; ++ u16 event; ++ ++ if (!(ioc->logging_level & MPT_DEBUG_EVENTS)) ++ return; ++ ++ event = le16_to_cpu(mpi_reply->Event); ++ ++ switch (event) { ++ case MPI2_EVENT_LOG_DATA: ++ desc = "Log Data"; ++ break; ++ case MPI2_EVENT_STATE_CHANGE: ++ desc = "Status Change"; ++ break; ++ case MPI2_EVENT_HARD_RESET_RECEIVED: ++ desc = "Hard Reset Received"; ++ break; ++ case MPI2_EVENT_EVENT_CHANGE: ++ desc = "Event Change"; ++ break; ++ case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: ++ desc = "Device Status Change"; ++ break; ++ case MPI2_EVENT_IR_OPERATION_STATUS: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Operation Status"; ++ break; ++ case MPI2_EVENT_SAS_DISCOVERY: ++ { ++ Mpi2EventDataSasDiscovery_t *event_data = ++ (Mpi2EventDataSasDiscovery_t *)mpi_reply->EventData; ++ pr_info(MPT3SAS_FMT "Discovery: (%s)", ioc->name, ++ (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? ++ "start" : "stop"); ++ if (event_data->DiscoveryStatus) ++ pr_info("discovery_status(0x%08x)", ++ le32_to_cpu(event_data->DiscoveryStatus)); ++ pr_info("\n"); ++ return; ++ } ++ case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: ++ desc = "SAS Broadcast Primitive"; ++ break; ++ case MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: ++ desc = "SAS Init Device Status Change"; ++ break; ++ case MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW: ++ desc = "SAS Init Table Overflow"; ++ break; ++ case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: ++ desc = "SAS Topology Change List"; ++ break; ++ case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: ++ desc = "SAS Enclosure Device Status Change"; ++ break; ++ case MPI2_EVENT_IR_VOLUME: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Volume"; ++ break; ++ case MPI2_EVENT_IR_PHYSICAL_DISK: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Physical Disk"; ++ break; ++ case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: ++ if (!ioc->hide_ir_msg) ++ desc = "IR Configuration Change List"; ++ break; ++ case MPI2_EVENT_LOG_ENTRY_ADDED: ++ if (!ioc->hide_ir_msg) ++ desc = "Log Entry Added"; ++ break; ++ case MPI2_EVENT_TEMP_THRESHOLD: ++ desc = "Temperature Threshold"; ++ break; ++ case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION: ++ desc = "Active cable exception"; ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, desc); ++} ++ ++/** ++ * _base_sas_log_info - verbose translation of firmware log info ++ * @ioc: per adapter object ++ * @log_info: log info ++ * ++ * Return nothing. ++ */ ++static void ++_base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info) ++{ ++ union loginfo_type { ++ u32 loginfo; ++ struct { ++ u32 subcode:16; ++ u32 code:8; ++ u32 originator:4; ++ u32 bus_type:4; ++ } dw; ++ }; ++ union loginfo_type sas_loginfo; ++ char *originator_str = NULL; ++ ++ sas_loginfo.loginfo = log_info; ++ if (sas_loginfo.dw.bus_type != 3 /*SAS*/) ++ return; ++ ++ /* each nexus loss loginfo */ ++ if (log_info == 0x31170000) ++ return; ++ ++ /* eat the loginfos associated with task aborts */ ++ if (ioc->ignore_loginfos && (log_info == 0x30050000 || log_info == ++ 0x31140000 || log_info == 0x31130000)) ++ return; ++ ++ switch (sas_loginfo.dw.originator) { ++ case 0: ++ originator_str = "IOP"; ++ break; ++ case 1: ++ originator_str = "PL"; ++ break; ++ case 2: ++ if (!ioc->hide_ir_msg) ++ originator_str = "IR"; ++ else ++ originator_str = "WarpDrive"; ++ break; ++ } ++ ++ pr_warn(MPT3SAS_FMT ++ "log_info(0x%08x): originator(%s), code(0x%02x), sub_code(0x%04x)\n", ++ ioc->name, log_info, ++ originator_str, sas_loginfo.dw.code, ++ sas_loginfo.dw.subcode); ++} ++ ++/** ++ * _base_display_reply_info - ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_reply_info(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ u16 ioc_status; ++ u32 loginfo = 0; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus); ++ ++ if ((ioc_status & MPI2_IOCSTATUS_MASK) && ++ (ioc->logging_level & MPT_DEBUG_REPLY)) { ++ _base_sas_ioc_info(ioc , mpi_reply, ++ mpt2sas_base_get_msg_frame(ioc, smid)); ++ } ++ ++ if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { ++ loginfo = le32_to_cpu(mpi_reply->IOCLogInfo); ++ _base_sas_log_info(ioc, loginfo); ++ } ++ ++ if (ioc_status || loginfo) { ++ ioc_status &= MPI2_IOCSTATUS_MASK; ++ mpt2sas_trigger_mpi(ioc, ioc_status, loginfo); ++ } ++} ++ ++/** ++ * mpt2sas_base_done - base internal command completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_base_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK) ++ return mpt2sas_check_for_pending_internal_cmds(ioc, smid); ++ ++ if (ioc->base_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ ++ ioc->base_cmds.status |= MPT3_CMD_COMPLETE; ++ if (mpi_reply) { ++ ioc->base_cmds.status |= MPT3_CMD_REPLY_VALID; ++ memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ } ++ ioc->base_cmds.status &= ~MPT3_CMD_PENDING; ++ ++ complete(&ioc->base_cmds.done); ++ return 1; ++} ++ ++/** ++ * _base_async_event - main callback handler for firmware asyn events ++ * @ioc: per adapter object ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply) ++{ ++ Mpi2EventNotificationReply_t *mpi_reply; ++ Mpi2EventAckRequest_t *ack_request; ++ u16 smid; ++ struct _event_ack_list *delayed_event_ack; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (!mpi_reply) ++ return 1; ++ if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION) ++ return 1; ++ ++ _base_display_event_data(ioc, mpi_reply); ++ ++ if (!(mpi_reply->AckRequired & MPI2_EVENT_NOTIFICATION_ACK_REQUIRED)) ++ goto out; ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ delayed_event_ack = kzalloc(sizeof(*delayed_event_ack), ++ GFP_ATOMIC); ++ if (!delayed_event_ack) ++ goto out; ++ INIT_LIST_HEAD(&delayed_event_ack->list); ++ delayed_event_ack->Event = mpi_reply->Event; ++ delayed_event_ack->EventContext = mpi_reply->EventContext; ++ list_add_tail(&delayed_event_ack->list, ++ &ioc->delayed_event_ack_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED: EVENT ACK: event (0x%04x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->Event))); ++ goto out; ++ } ++ ++ ack_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t)); ++ ack_request->Function = MPI2_FUNCTION_EVENT_ACK; ++ ack_request->Event = mpi_reply->Event; ++ ack_request->EventContext = mpi_reply->EventContext; ++ ack_request->VF_ID = 0; /* TODO */ ++ ack_request->VP_ID = 0; ++ mpt2sas_base_put_smid_default(ioc, smid); ++ ++ out: ++ ++ /* scsih callback handler */ ++ mpt2sas_scsih_event_callback(ioc, msix_index, reply); ++ ++ /* ctl callback handler */ ++ mpt2sas_ctl_event_callback(ioc, msix_index, reply); ++ ++ return 1; ++} ++ ++/** ++ * _base_get_cb_idx - obtain the callback index ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return callback index. ++ */ ++static u8 ++_base_get_cb_idx(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ int i; ++ u8 cb_idx; ++ ++ if (smid < ioc->hi_priority_smid) { ++ i = smid - 1; ++ cb_idx = ioc->scsi_lookup[i].cb_idx; ++ } else if (smid < ioc->internal_smid) { ++ i = smid - ioc->hi_priority_smid; ++ cb_idx = ioc->hpr_lookup[i].cb_idx; ++ } else if (smid <= ioc->hba_queue_depth) { ++ i = smid - ioc->internal_smid; ++ cb_idx = ioc->internal_lookup[i].cb_idx; ++ } else ++ cb_idx = 0xFF; ++ return cb_idx; ++} ++ ++/** ++ * _base_mask_interrupts - disable interrupts ++ * @ioc: per adapter object ++ * ++ * Disabling ResetIRQ, Reply and Doorbell Interrupts ++ * ++ * Return nothing. ++ */ ++static void ++_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 him_register; ++ ++ ioc->mask_interrupts = 1; ++ him_register = readl(&ioc->chip->HostInterruptMask); ++ him_register |= MPI2_HIM_DIM + MPI2_HIM_RIM + MPI2_HIM_RESET_IRQ_MASK; ++ writel(him_register, &ioc->chip->HostInterruptMask); ++ readl(&ioc->chip->HostInterruptMask); ++} ++ ++/** ++ * _base_unmask_interrupts - enable interrupts ++ * @ioc: per adapter object ++ * ++ * Enabling only Reply Interrupts ++ * ++ * Return nothing. ++ */ ++static void ++_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u32 him_register; ++ ++ him_register = readl(&ioc->chip->HostInterruptMask); ++ him_register &= ~MPI2_HIM_RIM; ++ writel(him_register, &ioc->chip->HostInterruptMask); ++ ioc->mask_interrupts = 0; ++} ++ ++union reply_descriptor { ++ u64 word; ++ struct { ++ u32 low; ++ u32 high; ++ } u; ++}; ++ ++/** ++ * _base_interrupt - MPT adapter (IOC) specific interrupt handler. ++ * @irq: irq number (not used) ++ * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure ++ * @r: pt_regs pointer (not used) ++ * ++ * Return IRQ_HANDLE if processed, else IRQ_NONE. ++ */ ++static irqreturn_t ++_base_interrupt(int irq, void *bus_id) ++{ ++ struct adapter_reply_queue *reply_q = bus_id; ++ union reply_descriptor rd; ++ u32 completed_cmds; ++ u8 request_desript_type; ++ u16 smid; ++ u8 cb_idx; ++ u32 reply; ++ u8 msix_index = reply_q->msix_index; ++ struct MPT3SAS_ADAPTER *ioc = reply_q->ioc; ++ Mpi2ReplyDescriptorsUnion_t *rpf; ++ u8 rc; ++ ++ if (ioc->mask_interrupts) ++ return IRQ_NONE; ++ ++ if (!atomic_add_unless(&reply_q->busy, 1, 1)) ++ return IRQ_NONE; ++ ++ rpf = &reply_q->reply_post_free[reply_q->reply_post_host_index]; ++ request_desript_type = rpf->Default.ReplyFlags ++ & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; ++ if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { ++ atomic_dec(&reply_q->busy); ++ return IRQ_NONE; ++ } ++ ++ completed_cmds = 0; ++ cb_idx = 0xFF; ++ do { ++ rd.word = le64_to_cpu(rpf->Words); ++ if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) ++ goto out; ++ reply = 0; ++ smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); ++ if (request_desript_type == ++ MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS || ++ request_desript_type == ++ MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { ++ cb_idx = _base_get_cb_idx(ioc, smid); ++ if ((likely(cb_idx < MPT_MAX_CALLBACKS)) && ++ (likely(mpt_callbacks[cb_idx] != NULL))) { ++ rc = mpt_callbacks[cb_idx](ioc, smid, ++ msix_index, 0); ++ if (rc) ++ mpt2sas_base_free_smid(ioc, smid); ++ } ++ } else if (request_desript_type == ++ MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { ++ reply = le32_to_cpu( ++ rpf->AddressReply.ReplyFrameAddress); ++ if (reply > ioc->reply_dma_max_address || ++ reply < ioc->reply_dma_min_address) ++ reply = 0; ++ if (smid) { ++ cb_idx = _base_get_cb_idx(ioc, smid); ++ if ((likely(cb_idx < MPT_MAX_CALLBACKS)) && ++ (likely(mpt_callbacks[cb_idx] != NULL))) { ++ rc = mpt_callbacks[cb_idx](ioc, smid, ++ msix_index, reply); ++ if (reply) ++ _base_display_reply_info(ioc, ++ smid, msix_index, reply); ++ if (rc) ++ mpt2sas_base_free_smid(ioc, ++ smid); ++ } ++ } else { ++ _base_async_event(ioc, msix_index, reply); ++ } ++ ++ /* reply free queue handling */ ++ if (reply) { ++ ioc->reply_free_host_index = ++ (ioc->reply_free_host_index == ++ (ioc->reply_free_queue_depth - 1)) ? ++ 0 : ioc->reply_free_host_index + 1; ++ ioc->reply_free[ioc->reply_free_host_index] = ++ cpu_to_le32(reply); ++ wmb(); ++ writel(ioc->reply_free_host_index, ++ &ioc->chip->ReplyFreeHostIndex); ++ } ++ } ++ ++ rpf->Words = cpu_to_le64(ULLONG_MAX); ++ reply_q->reply_post_host_index = ++ (reply_q->reply_post_host_index == ++ (ioc->reply_post_queue_depth - 1)) ? 0 : ++ reply_q->reply_post_host_index + 1; ++ request_desript_type = ++ reply_q->reply_post_free[reply_q->reply_post_host_index]. ++ Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; ++ completed_cmds++; ++ if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) ++ goto out; ++ if (!reply_q->reply_post_host_index) ++ rpf = reply_q->reply_post_free; ++ else ++ rpf++; ++ } while (1); ++ ++ out: ++ ++ if (!completed_cmds) { ++ atomic_dec(&reply_q->busy); ++ return IRQ_NONE; ++ } ++ ++ wmb(); ++ if (ioc->is_warpdrive) { ++ writel(reply_q->reply_post_host_index, ++ ioc->reply_post_host_index[msix_index]); ++ atomic_dec(&reply_q->busy); ++ return IRQ_HANDLED; ++ } ++ ++ /* Update Reply Post Host Index. ++ * For those HBA's which support combined reply queue feature ++ * 1. Get the correct Supplemental Reply Post Host Index Register. ++ * i.e. (msix_index / 8)th entry from Supplemental Reply Post Host ++ * Index Register address bank i.e replyPostRegisterIndex[], ++ * 2. Then update this register with new reply host index value ++ * in ReplyPostIndex field and the MSIxIndex field with ++ * msix_index value reduced to a value between 0 and 7, ++ * using a modulo 8 operation. Since each Supplemental Reply Post ++ * Host Index Register supports 8 MSI-X vectors. ++ * ++ * For other HBA's just update the Reply Post Host Index register with ++ * new reply host index value in ReplyPostIndex Field and msix_index ++ * value in MSIxIndex field. ++ */ ++ if (ioc->msix96_vector) ++ writel(reply_q->reply_post_host_index | ((msix_index & 7) << ++ MPI2_RPHI_MSIX_INDEX_SHIFT), ++ ioc->replyPostRegisterIndex[msix_index/8]); ++ else ++ writel(reply_q->reply_post_host_index | (msix_index << ++ MPI2_RPHI_MSIX_INDEX_SHIFT), ++ &ioc->chip->ReplyPostHostIndex); ++ atomic_dec(&reply_q->busy); ++ return IRQ_HANDLED; ++} ++ ++/** ++ * _base_is_controller_msix_enabled - is controller support muli-reply queues ++ * @ioc: per adapter object ++ * ++ */ ++static inline int ++_base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc) ++{ ++ return (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable; ++} ++ ++/** ++ * mpt2sas_base_sync_reply_irqs - flush pending MSIX interrupts ++ * @ioc: per adapter object ++ * Context: non ISR conext ++ * ++ * Called when a Task Management request has completed. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct adapter_reply_queue *reply_q; ++ ++ /* If MSIX capability is turned off ++ * then multi-queues are not enabled ++ */ ++ if (!_base_is_controller_msix_enabled(ioc)) ++ return; ++ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) ++ return; ++ /* TMs are on msix_index == 0 */ ++ if (reply_q->msix_index == 0) ++ continue; ++ synchronize_irq(reply_q->vector); ++ } ++} ++ ++/** ++ * mpt2sas_base_release_callback_handler - clear interrupt callback handler ++ * @cb_idx: callback index ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_release_callback_handler(u8 cb_idx) ++{ ++ mpt_callbacks[cb_idx] = NULL; ++} ++ ++/** ++ * mpt2sas_base_register_callback_handler - obtain index for the interrupt callback handler ++ * @cb_func: callback function ++ * ++ * Returns cb_func. ++ */ ++u8 ++mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func) ++{ ++ u8 cb_idx; ++ ++ for (cb_idx = MPT_MAX_CALLBACKS-1; cb_idx; cb_idx--) ++ if (mpt_callbacks[cb_idx] == NULL) ++ break; ++ ++ mpt_callbacks[cb_idx] = cb_func; ++ return cb_idx; ++} ++ ++/** ++ * mpt2sas_base_initialize_callback_handler - initialize the interrupt callback handler ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_initialize_callback_handler(void) ++{ ++ u8 cb_idx; ++ ++ for (cb_idx = 0; cb_idx < MPT_MAX_CALLBACKS; cb_idx++) ++ mpt2sas_base_release_callback_handler(cb_idx); ++} ++ ++ ++/** ++ * _base_build_zero_len_sge - build zero length sg entry ++ * @ioc: per adapter object ++ * @paddr: virtual address for SGE ++ * ++ * Create a zero length scatter gather entry to insure the IOCs hardware has ++ * something to use if the target device goes brain dead and tries ++ * to send data even when none is asked for. ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_zero_len_sge(struct MPT3SAS_ADAPTER *ioc, void *paddr) ++{ ++ u32 flags_length = (u32)((MPI2_SGE_FLAGS_LAST_ELEMENT | ++ MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST | ++ MPI2_SGE_FLAGS_SIMPLE_ELEMENT) << ++ MPI2_SGE_FLAGS_SHIFT); ++ ioc->base_add_sg_single(paddr, flags_length, -1); ++} ++ ++/** ++ * _base_add_sg_single_32 - Place a simple 32 bit SGE at address pAddr. ++ * @paddr: virtual address for SGE ++ * @flags_length: SGE flags and data transfer length ++ * @dma_addr: Physical address ++ * ++ * Return nothing. ++ */ ++static void ++_base_add_sg_single_32(void *paddr, u32 flags_length, dma_addr_t dma_addr) ++{ ++ Mpi2SGESimple32_t *sgel = paddr; ++ ++ flags_length |= (MPI2_SGE_FLAGS_32_BIT_ADDRESSING | ++ MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT; ++ sgel->FlagsLength = cpu_to_le32(flags_length); ++ sgel->Address = cpu_to_le32(dma_addr); ++} ++ ++ ++/** ++ * _base_add_sg_single_64 - Place a simple 64 bit SGE at address pAddr. ++ * @paddr: virtual address for SGE ++ * @flags_length: SGE flags and data transfer length ++ * @dma_addr: Physical address ++ * ++ * Return nothing. ++ */ ++static void ++_base_add_sg_single_64(void *paddr, u32 flags_length, dma_addr_t dma_addr) ++{ ++ Mpi2SGESimple64_t *sgel = paddr; ++ ++ flags_length |= (MPI2_SGE_FLAGS_64_BIT_ADDRESSING | ++ MPI2_SGE_FLAGS_SYSTEM_ADDRESS) << MPI2_SGE_FLAGS_SHIFT; ++ sgel->FlagsLength = cpu_to_le32(flags_length); ++ sgel->Address = cpu_to_le64(dma_addr); ++} ++ ++/** ++ * _base_get_chain_buffer_tracker - obtain chain tracker ++ * @ioc: per adapter object ++ * @smid: smid associated to an IO request ++ * ++ * Returns chain tracker(from ioc->free_chain_list) ++ */ ++static struct chain_tracker * ++_base_get_chain_buffer_tracker(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ struct chain_tracker *chain_req; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->free_chain_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "chain buffers not available\n", ioc->name)); ++ return NULL; ++ } ++ chain_req = list_entry(ioc->free_chain_list.next, ++ struct chain_tracker, tracker_list); ++ list_del_init(&chain_req->tracker_list); ++ list_add_tail(&chain_req->tracker_list, ++ &ioc->scsi_lookup[smid - 1].chain_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return chain_req; ++} ++ ++ ++/** ++ * _base_build_sg - build generic sg ++ * @ioc: per adapter object ++ * @psge: virtual address for SGE ++ * @data_out_dma: physical address for WRITES ++ * @data_out_sz: data xfer size for WRITES ++ * @data_in_dma: physical address for READS ++ * @data_in_sz: data xfer size for READS ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_sg(struct MPT3SAS_ADAPTER *ioc, void *psge, ++ dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma, ++ size_t data_in_sz) ++{ ++ u32 sgl_flags; ++ ++ if (!data_out_sz && !data_in_sz) { ++ _base_build_zero_len_sge(ioc, psge); ++ return; ++ } ++ ++ if (data_out_sz && data_in_sz) { ++ /* WRITE sgel first */ ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_out_sz, data_out_dma); ++ ++ /* incr sgel */ ++ psge += ioc->sge_size; ++ ++ /* READ sgel last */ ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | ++ MPI2_SGE_FLAGS_END_OF_LIST); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_in_sz, data_in_dma); ++ } else if (data_out_sz) /* WRITE */ { ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | ++ MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_out_sz, data_out_dma); ++ } else if (data_in_sz) /* READ */ { ++ sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | ++ MPI2_SGE_FLAGS_END_OF_LIST); ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ioc->base_add_sg_single(psge, sgl_flags | ++ data_in_sz, data_in_dma); ++ } ++} ++ ++/* IEEE format sgls */ ++ ++/** ++ * _base_add_sg_single_ieee - add sg element for IEEE format ++ * @paddr: virtual address for SGE ++ * @flags: SGE flags ++ * @chain_offset: number of 128 byte elements from start of segment ++ * @length: data transfer length ++ * @dma_addr: Physical address ++ * ++ * Return nothing. ++ */ ++static void ++_base_add_sg_single_ieee(void *paddr, u8 flags, u8 chain_offset, u32 length, ++ dma_addr_t dma_addr) ++{ ++ Mpi25IeeeSgeChain64_t *sgel = paddr; ++ ++ sgel->Flags = flags; ++ sgel->NextChainOffset = chain_offset; ++ sgel->Length = cpu_to_le32(length); ++ sgel->Address = cpu_to_le64(dma_addr); ++} ++ ++/** ++ * _base_build_zero_len_sge_ieee - build zero length sg entry for IEEE format ++ * @ioc: per adapter object ++ * @paddr: virtual address for SGE ++ * ++ * Create a zero length scatter gather entry to insure the IOCs hardware has ++ * something to use if the target device goes brain dead and tries ++ * to send data even when none is asked for. ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr) ++{ ++ u8 sgl_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST); ++ ++ _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); ++} ++ ++/** ++ * _base_build_sg_scmd - main sg creation routine ++ * @ioc: per adapter object ++ * @scmd: scsi command ++ * @smid: system request message index ++ * Context: none. ++ * ++ * The main routine that builds scatter gather table from a given ++ * scsi request sent via the .queuecommand main handler. ++ * ++ * Returns 0 success, anything else error ++ */ ++static int ++_base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_cmnd *scmd, u16 smid) ++{ ++ Mpi2SCSIIORequest_t *mpi_request; ++ dma_addr_t chain_dma; ++ struct scatterlist *sg_scmd; ++ void *sg_local, *chain; ++ u32 chain_offset; ++ u32 chain_length; ++ u32 chain_flags; ++ int sges_left; ++ u32 sges_in_segment; ++ u32 sgl_flags; ++ u32 sgl_flags_last_element; ++ u32 sgl_flags_end_buffer; ++ struct chain_tracker *chain_req; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ++ /* init scatter gather flags */ ++ sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT; ++ if (scmd->sc_data_direction == DMA_TO_DEVICE) ++ sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC; ++ sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT) ++ << MPI2_SGE_FLAGS_SHIFT; ++ sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT | ++ MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST) ++ << MPI2_SGE_FLAGS_SHIFT; ++ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; ++ ++ sg_scmd = scsi_sglist(scmd); ++ sges_left = scsi_dma_map(scmd); ++ if (sges_left < 0) { ++ sdev_printk(KERN_ERR, scmd->device, ++ "pci_map_sg failed: request for %d bytes!\n", ++ scsi_bufflen(scmd)); ++ return -ENOMEM; ++ } ++ ++ sg_local = &mpi_request->SGL; ++ sges_in_segment = ioc->max_sges_in_main_message; ++ if (sges_left <= sges_in_segment) ++ goto fill_in_last_segment; ++ ++ mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) + ++ (sges_in_segment * ioc->sge_size))/4; ++ ++ /* fill in main message segment when there is a chain following */ ++ while (sges_in_segment) { ++ if (sges_in_segment == 1) ++ ioc->base_add_sg_single(sg_local, ++ sgl_flags_last_element | sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ else ++ ioc->base_add_sg_single(sg_local, sgl_flags | ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ /* initializing the chain flags and pointers */ ++ chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT; ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ do { ++ sges_in_segment = (sges_left <= ++ ioc->max_sges_in_chain_message) ? sges_left : ++ ioc->max_sges_in_chain_message; ++ chain_offset = (sges_left == sges_in_segment) ? ++ 0 : (sges_in_segment * ioc->sge_size)/4; ++ chain_length = sges_in_segment * ioc->sge_size; ++ if (chain_offset) { ++ chain_offset = chain_offset << ++ MPI2_SGE_CHAIN_OFFSET_SHIFT; ++ chain_length += ioc->sge_size; ++ } ++ ioc->base_add_sg_single(sg_local, chain_flags | chain_offset | ++ chain_length, chain_dma); ++ sg_local = chain; ++ if (!chain_offset) ++ goto fill_in_last_segment; ++ ++ /* fill in chain segments */ ++ while (sges_in_segment) { ++ if (sges_in_segment == 1) ++ ioc->base_add_sg_single(sg_local, ++ sgl_flags_last_element | ++ sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ else ++ ioc->base_add_sg_single(sg_local, sgl_flags | ++ sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ } while (1); ++ ++ ++ fill_in_last_segment: ++ ++ /* fill the last segment */ ++ while (sges_left) { ++ if (sges_left == 1) ++ ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer | ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ else ++ ioc->base_add_sg_single(sg_local, sgl_flags | ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size; ++ sges_left--; ++ } ++ ++ return 0; ++} ++ ++/** ++ * _base_build_sg_scmd_ieee - main sg creation routine for IEEE format ++ * @ioc: per adapter object ++ * @scmd: scsi command ++ * @smid: system request message index ++ * Context: none. ++ * ++ * The main routine that builds scatter gather table from a given ++ * scsi request sent via the .queuecommand main handler. ++ * ++ * Returns 0 success, anything else error ++ */ ++static int ++_base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_cmnd *scmd, u16 smid) ++{ ++ Mpi2SCSIIORequest_t *mpi_request; ++ dma_addr_t chain_dma; ++ struct scatterlist *sg_scmd; ++ void *sg_local, *chain; ++ u32 chain_offset; ++ u32 chain_length; ++ int sges_left; ++ u32 sges_in_segment; ++ u8 simple_sgl_flags; ++ u8 simple_sgl_flags_last; ++ u8 chain_sgl_flags; ++ struct chain_tracker *chain_req; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ++ /* init scatter gather flags */ ++ simple_sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ simple_sgl_flags_last = simple_sgl_flags | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST; ++ chain_sgl_flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ ++ sg_scmd = scsi_sglist(scmd); ++ sges_left = scsi_dma_map(scmd); ++ if (sges_left < 0) { ++ sdev_printk(KERN_ERR, scmd->device, ++ "pci_map_sg failed: request for %d bytes!\n", ++ scsi_bufflen(scmd)); ++ return -ENOMEM; ++ } ++ ++ sg_local = &mpi_request->SGL; ++ sges_in_segment = (ioc->request_sz - ++ offsetof(Mpi2SCSIIORequest_t, SGL))/ioc->sge_size_ieee; ++ if (sges_left <= sges_in_segment) ++ goto fill_in_last_segment; ++ ++ mpi_request->ChainOffset = (sges_in_segment - 1 /* chain element */) + ++ (offsetof(Mpi2SCSIIORequest_t, SGL)/ioc->sge_size_ieee); ++ ++ /* fill in main message segment when there is a chain following */ ++ while (sges_in_segment > 1) { ++ _base_add_sg_single_ieee(sg_local, simple_sgl_flags, 0, ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size_ieee; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ /* initializing the pointers */ ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ do { ++ sges_in_segment = (sges_left <= ++ ioc->max_sges_in_chain_message) ? sges_left : ++ ioc->max_sges_in_chain_message; ++ chain_offset = (sges_left == sges_in_segment) ? ++ 0 : sges_in_segment; ++ chain_length = sges_in_segment * ioc->sge_size_ieee; ++ if (chain_offset) ++ chain_length += ioc->sge_size_ieee; ++ _base_add_sg_single_ieee(sg_local, chain_sgl_flags, ++ chain_offset, chain_length, chain_dma); ++ ++ sg_local = chain; ++ if (!chain_offset) ++ goto fill_in_last_segment; ++ ++ /* fill in chain segments */ ++ while (sges_in_segment) { ++ _base_add_sg_single_ieee(sg_local, simple_sgl_flags, 0, ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size_ieee; ++ sges_left--; ++ sges_in_segment--; ++ } ++ ++ chain_req = _base_get_chain_buffer_tracker(ioc, smid); ++ if (!chain_req) ++ return -1; ++ chain = chain_req->chain_buffer; ++ chain_dma = chain_req->chain_buffer_dma; ++ } while (1); ++ ++ ++ fill_in_last_segment: ++ ++ /* fill the last segment */ ++ while (sges_left > 0) { ++ if (sges_left == 1) ++ _base_add_sg_single_ieee(sg_local, ++ simple_sgl_flags_last, 0, sg_dma_len(sg_scmd), ++ sg_dma_address(sg_scmd)); ++ else ++ _base_add_sg_single_ieee(sg_local, simple_sgl_flags, 0, ++ sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); ++ sg_scmd = sg_next(sg_scmd); ++ sg_local += ioc->sge_size_ieee; ++ sges_left--; ++ } ++ ++ return 0; ++} ++ ++/** ++ * _base_build_sg_ieee - build generic sg for IEEE format ++ * @ioc: per adapter object ++ * @psge: virtual address for SGE ++ * @data_out_dma: physical address for WRITES ++ * @data_out_sz: data xfer size for WRITES ++ * @data_in_dma: physical address for READS ++ * @data_in_sz: data xfer size for READS ++ * ++ * Return nothing. ++ */ ++static void ++_base_build_sg_ieee(struct MPT3SAS_ADAPTER *ioc, void *psge, ++ dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma, ++ size_t data_in_sz) ++{ ++ u8 sgl_flags; ++ ++ if (!data_out_sz && !data_in_sz) { ++ _base_build_zero_len_sge_ieee(ioc, psge); ++ return; ++ } ++ ++ if (data_out_sz && data_in_sz) { ++ /* WRITE sgel first */ ++ sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_out_sz, ++ data_out_dma); ++ ++ /* incr sgel */ ++ psge += ioc->sge_size_ieee; ++ ++ /* READ sgel last */ ++ sgl_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_in_sz, ++ data_in_dma); ++ } else if (data_out_sz) /* WRITE */ { ++ sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_out_sz, ++ data_out_dma); ++ } else if (data_in_sz) /* READ */ { ++ sgl_flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | ++ MPI25_IEEE_SGE_FLAGS_END_OF_LIST | ++ MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; ++ _base_add_sg_single_ieee(psge, sgl_flags, 0, data_in_sz, ++ data_in_dma); ++ } ++} ++ ++#define convert_to_kb(x) ((x) << (PAGE_SHIFT - 10)) ++ ++/** ++ * _base_config_dma_addressing - set dma addressing ++ * @ioc: per adapter object ++ * @pdev: PCI device struct ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) ++{ ++ struct sysinfo s; ++ u64 consistent_dma_mask; ++ ++ if (ioc->dma_mask) ++ consistent_dma_mask = DMA_BIT_MASK(64); ++ else ++ consistent_dma_mask = DMA_BIT_MASK(32); ++ ++ if (sizeof(dma_addr_t) > 4) { ++ const uint64_t required_mask = ++ dma_get_required_mask(&pdev->dev); ++ if ((required_mask > DMA_BIT_MASK(32)) && ++ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && ++ !pci_set_consistent_dma_mask(pdev, consistent_dma_mask)) { ++ ioc->base_add_sg_single = &_base_add_sg_single_64; ++ ioc->sge_size = sizeof(Mpi2SGESimple64_t); ++ ioc->dma_mask = 64; ++ goto out; ++ } ++ } ++ ++ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ++ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { ++ ioc->base_add_sg_single = &_base_add_sg_single_32; ++ ioc->sge_size = sizeof(Mpi2SGESimple32_t); ++ ioc->dma_mask = 32; ++ } else ++ return -ENODEV; ++ ++ out: ++ si_meminfo(&s); ++ pr_info(MPT3SAS_FMT ++ "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", ++ ioc->name, ioc->dma_mask, convert_to_kb(s.totalram)); ++ ++ return 0; ++} ++ ++static int ++_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc, ++ struct pci_dev *pdev) ++{ ++ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { ++ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++/** ++ * _base_check_enable_msix - checks MSIX capabable. ++ * @ioc: per adapter object ++ * ++ * Check to see if card is capable of MSIX, and set number ++ * of available msix vectors ++ */ ++static int ++_base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int base; ++ u16 message_control; ++ ++ /* Check whether controller SAS2008 B0 controller, ++ * if it is SAS2008 B0 controller use IO-APIC instead of MSIX ++ */ ++ if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 && ++ ioc->pdev->revision == SAS2_PCI_DEVICE_B0_REVISION) { ++ return -EINVAL; ++ } ++ ++ base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX); ++ if (!base) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT "msix not supported\n", ++ ioc->name)); ++ return -EINVAL; ++ } ++ ++ /* get msix vector count */ ++ /* NUMA_IO not supported for older controllers */ ++ if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2004 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_1 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_2 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2108_3 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_1 || ++ ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2116_2) ++ ioc->msix_vector_count = 1; ++ else { ++ pci_read_config_word(ioc->pdev, base + 2, &message_control); ++ ioc->msix_vector_count = (message_control & 0x3FF) + 1; ++ } ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "msix is supported, vector_count(%d)\n", ++ ioc->name, ioc->msix_vector_count)); ++ return 0; ++} ++ ++/** ++ * _base_free_irq - free irq ++ * @ioc: per adapter object ++ * ++ * Freeing respective reply_queue from the list. ++ */ ++static void ++_base_free_irq(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct adapter_reply_queue *reply_q, *next; ++ ++ if (list_empty(&ioc->reply_queue_list)) ++ return; ++ ++ list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { ++ list_del(&reply_q->list); ++ if (smp_affinity_enable) { ++ irq_set_affinity_hint(reply_q->vector, NULL); ++ free_cpumask_var(reply_q->affinity_hint); ++ } ++ free_irq(reply_q->vector, reply_q); ++ kfree(reply_q); ++ } ++} ++ ++/** ++ * _base_request_irq - request irq ++ * @ioc: per adapter object ++ * @index: msix index into vector table ++ * @vector: irq vector ++ * ++ * Inserting respective reply_queue into the list. ++ */ ++static int ++_base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector) ++{ ++ struct adapter_reply_queue *reply_q; ++ int r; ++ ++ reply_q = kzalloc(sizeof(struct adapter_reply_queue), GFP_KERNEL); ++ if (!reply_q) { ++ pr_err(MPT3SAS_FMT "unable to allocate memory %d!\n", ++ ioc->name, (int)sizeof(struct adapter_reply_queue)); ++ return -ENOMEM; ++ } ++ reply_q->ioc = ioc; ++ reply_q->msix_index = index; ++ reply_q->vector = vector; ++ ++ if (smp_affinity_enable) { ++ if (!zalloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) { ++ kfree(reply_q); ++ return -ENOMEM; ++ } ++ } ++ ++ atomic_set(&reply_q->busy, 0); ++ if (ioc->msix_enable) ++ snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", ++ ioc->driver_name, ioc->id, index); ++ else ++ snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d", ++ ioc->driver_name, ioc->id); ++ r = request_irq(vector, _base_interrupt, IRQF_SHARED, reply_q->name, ++ reply_q); ++ if (r) { ++ pr_err(MPT3SAS_FMT "unable to allocate interrupt %d!\n", ++ reply_q->name, vector); ++ free_cpumask_var(reply_q->affinity_hint); ++ kfree(reply_q); ++ return -EBUSY; ++ } ++ ++ INIT_LIST_HEAD(&reply_q->list); ++ list_add_tail(&reply_q->list, &ioc->reply_queue_list); ++ return 0; ++} ++ ++/** ++ * _base_assign_reply_queues - assigning msix index for each cpu ++ * @ioc: per adapter object ++ * ++ * The enduser would need to set the affinity via /proc/irq/#/smp_affinity ++ * ++ * It would nice if we could call irq_set_affinity, however it is not ++ * an exported symbol ++ */ ++static void ++_base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned int cpu, nr_cpus, nr_msix, index = 0; ++ struct adapter_reply_queue *reply_q; ++ ++ if (!_base_is_controller_msix_enabled(ioc)) ++ return; ++ ++ memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz); ++ ++ nr_cpus = num_online_cpus(); ++ nr_msix = ioc->reply_queue_count = min(ioc->reply_queue_count, ++ ioc->facts.MaxMSIxVectors); ++ if (!nr_msix) ++ return; ++ ++ cpu = cpumask_first(cpu_online_mask); ++ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ ++ unsigned int i, group = nr_cpus / nr_msix; ++ ++ if (cpu >= nr_cpus) ++ break; ++ ++ if (index < nr_cpus % nr_msix) ++ group++; ++ ++ for (i = 0 ; i < group ; i++) { ++ ioc->cpu_msix_table[cpu] = index; ++ if (smp_affinity_enable) ++ cpumask_or(reply_q->affinity_hint, ++ reply_q->affinity_hint, get_cpu_mask(cpu)); ++ cpu = cpumask_next(cpu, cpu_online_mask); ++ } ++ if (smp_affinity_enable) ++ if (irq_set_affinity_hint(reply_q->vector, ++ reply_q->affinity_hint)) ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "Err setting affinity hint to irq vector %d\n", ++ ioc->name, reply_q->vector)); ++ index++; ++ } ++} ++ ++/** ++ * _base_disable_msix - disables msix ++ * @ioc: per adapter object ++ * ++ */ ++static void ++_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) ++{ ++ if (!ioc->msix_enable) ++ return; ++ pci_disable_msix(ioc->pdev); ++ ioc->msix_enable = 0; ++} ++ ++/** ++ * _base_enable_msix - enables msix, failback to io_apic ++ * @ioc: per adapter object ++ * ++ */ ++static int ++_base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct msix_entry *entries, *a; ++ int r; ++ int i; ++ u8 try_msix = 0; ++ ++ if (msix_disable == -1 || msix_disable == 0) ++ try_msix = 1; ++ ++ if (!try_msix) ++ goto try_ioapic; ++ ++ if (_base_check_enable_msix(ioc) != 0) ++ goto try_ioapic; ++ ++ ioc->reply_queue_count = min_t(int, ioc->cpu_count, ++ ioc->msix_vector_count); ++ ++ printk(MPT3SAS_FMT "MSI-X vectors supported: %d, no of cores" ++ ": %d, max_msix_vectors: %d\n", ioc->name, ioc->msix_vector_count, ++ ioc->cpu_count, max_msix_vectors); ++ ++ if (!ioc->rdpq_array_enable && max_msix_vectors == -1) ++ max_msix_vectors = 8; ++ ++ if (max_msix_vectors > 0) { ++ ioc->reply_queue_count = min_t(int, max_msix_vectors, ++ ioc->reply_queue_count); ++ ioc->msix_vector_count = ioc->reply_queue_count; ++ } else if (max_msix_vectors == 0) ++ goto try_ioapic; ++ ++ if (ioc->msix_vector_count < ioc->cpu_count) ++ smp_affinity_enable = 0; ++ ++ entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry), ++ GFP_KERNEL); ++ if (!entries) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT ++ "kcalloc failed @ at %s:%d/%s() !!!\n", ++ ioc->name, __FILE__, __LINE__, __func__)); ++ goto try_ioapic; ++ } ++ ++ for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) ++ a->entry = i; ++ ++ r = pci_enable_msix_exact(ioc->pdev, entries, ioc->reply_queue_count); ++ if (r) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT ++ "pci_enable_msix_exact failed (r=%d) !!!\n", ++ ioc->name, r)); ++ kfree(entries); ++ goto try_ioapic; ++ } ++ ++ ioc->msix_enable = 1; ++ for (i = 0, a = entries; i < ioc->reply_queue_count; i++, a++) { ++ r = _base_request_irq(ioc, i, a->vector); ++ if (r) { ++ _base_free_irq(ioc); ++ _base_disable_msix(ioc); ++ kfree(entries); ++ goto try_ioapic; ++ } ++ } ++ ++ kfree(entries); ++ return 0; ++ ++/* failback to io_apic interrupt routing */ ++ try_ioapic: ++ ++ ioc->reply_queue_count = 1; ++ r = _base_request_irq(ioc, 0, ioc->pdev->irq); ++ ++ return r; ++} ++ ++/** ++ * mpt2sas_base_unmap_resources - free controller resources ++ * @ioc: per adapter object ++ */ ++void ++mpt2sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct pci_dev *pdev = ioc->pdev; ++ ++ dexitprintk(ioc, printk(MPT3SAS_FMT "%s\n", ++ ioc->name, __func__)); ++ ++ _base_free_irq(ioc); ++ _base_disable_msix(ioc); ++ ++ if (ioc->msix96_vector) { ++ kfree(ioc->replyPostRegisterIndex); ++ ioc->replyPostRegisterIndex = NULL; ++ } ++ ++ if (ioc->chip_phys) { ++ iounmap(ioc->chip); ++ ioc->chip_phys = 0; ++ } ++ ++ if (pci_is_enabled(pdev)) { ++ pci_release_selected_regions(ioc->pdev, ioc->bars); ++ pci_disable_pcie_error_reporting(pdev); ++ pci_disable_device(pdev); ++ } ++} ++ ++/** ++ * mpt2sas_base_map_resources - map in controller resources (io/irq/memap) ++ * @ioc: per adapter object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct pci_dev *pdev = ioc->pdev; ++ u32 memap_sz; ++ u32 pio_sz; ++ int i, r = 0; ++ u64 pio_chip = 0; ++ u64 chip_phys = 0; ++ struct adapter_reply_queue *reply_q; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ++ ioc->name, __func__)); ++ ++ ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); ++ if (pci_enable_device_mem(pdev)) { ++ pr_warn(MPT3SAS_FMT "pci_enable_device_mem: failed\n", ++ ioc->name); ++ ioc->bars = 0; ++ return -ENODEV; ++ } ++ ++ ++ if (pci_request_selected_regions(pdev, ioc->bars, ++ ioc->driver_name)) { ++ pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n", ++ ioc->name); ++ ioc->bars = 0; ++ r = -ENODEV; ++ goto out_fail; ++ } ++ ++/* AER (Advanced Error Reporting) hooks */ ++ pci_enable_pcie_error_reporting(pdev); ++ ++ pci_set_master(pdev); ++ ++ ++ if (_base_config_dma_addressing(ioc, pdev) != 0) { ++ pr_warn(MPT3SAS_FMT "no suitable DMA mask for %s\n", ++ ioc->name, pci_name(pdev)); ++ r = -ENODEV; ++ goto out_fail; ++ } ++ ++ for (i = 0, memap_sz = 0, pio_sz = 0; (i < DEVICE_COUNT_RESOURCE) && ++ (!memap_sz || !pio_sz); i++) { ++ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { ++ if (pio_sz) ++ continue; ++ pio_chip = (u64)pci_resource_start(pdev, i); ++ pio_sz = pci_resource_len(pdev, i); ++ } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { ++ if (memap_sz) ++ continue; ++ ioc->chip_phys = pci_resource_start(pdev, i); ++ chip_phys = (u64)ioc->chip_phys; ++ memap_sz = pci_resource_len(pdev, i); ++ ioc->chip = ioremap(ioc->chip_phys, memap_sz); ++ } ++ } ++ ++ if (ioc->chip == NULL) { ++ pr_err(MPT3SAS_FMT "unable to map adapter memory! " ++ " or resource not found\n", ioc->name); ++ r = -EINVAL; ++ goto out_fail; ++ } ++ ++ _base_mask_interrupts(ioc); ++ ++ r = _base_get_ioc_facts(ioc, CAN_SLEEP); ++ if (r) ++ goto out_fail; ++ ++ if (!ioc->rdpq_array_enable_assigned) { ++ ioc->rdpq_array_enable = ioc->rdpq_array_capable; ++ ioc->rdpq_array_enable_assigned = 1; ++ } ++ ++ r = _base_enable_msix(ioc); ++ if (r) ++ goto out_fail; ++ ++ /* Use the Combined reply queue feature only for SAS3 C0 & higher ++ * revision HBAs and also only when reply queue count is greater than 8 ++ */ ++ if (ioc->msix96_vector && ioc->reply_queue_count > 8) { ++ /* Determine the Supplemental Reply Post Host Index Registers ++ * Addresse. Supplemental Reply Post Host Index Registers ++ * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and ++ * each register is at offset bytes of ++ * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one. ++ */ ++ ioc->replyPostRegisterIndex = kcalloc( ++ MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT, ++ sizeof(resource_size_t *), GFP_KERNEL); ++ if (!ioc->replyPostRegisterIndex) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "allocation for reply Post Register Index failed!!!\n", ++ ioc->name)); ++ r = -ENOMEM; ++ goto out_fail; ++ } ++ ++ for (i = 0; i < MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT; i++) { ++ ioc->replyPostRegisterIndex[i] = (resource_size_t *) ++ ((u8 *)&ioc->chip->Doorbell + ++ MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET + ++ (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET)); ++ } ++ } else ++ ioc->msix96_vector = 0; ++ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) ++ pr_info(MPT3SAS_FMT "%s: IRQ %d\n", ++ reply_q->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : ++ "IO-APIC enabled"), reply_q->vector); ++ ++ pr_info(MPT3SAS_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n", ++ ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz); ++ pr_info(MPT3SAS_FMT "ioport(0x%016llx), size(%d)\n", ++ ioc->name, (unsigned long long)pio_chip, pio_sz); ++ ++ /* Save PCI configuration state for recovery from PCI AER/EEH errors */ ++ pci_save_state(pdev); ++ return 0; ++ ++ out_fail: ++ mpt2sas_base_unmap_resources(ioc); ++ return r; ++} ++ ++/** ++ * mpt2sas_base_get_msg_frame - obtain request mf pointer ++ * @ioc: per adapter object ++ * @smid: system request message index(smid zero is invalid) ++ * ++ * Returns virt pointer to message frame. ++ */ ++void * ++mpt2sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return (void *)(ioc->request + (smid * ioc->request_sz)); ++} ++ ++/** ++ * mpt2sas_base_get_sense_buffer - obtain a sense buffer virt addr ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns virt pointer to sense buffer. ++ */ ++void * ++mpt2sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return (void *)(ioc->sense + ((smid - 1) * SCSI_SENSE_BUFFERSIZE)); ++} ++ ++/** ++ * mpt2sas_base_get_sense_buffer_dma - obtain a sense buffer dma addr ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns phys pointer to the low 32bit address of the sense buffer. ++ */ ++__le32 ++mpt2sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return cpu_to_le32(ioc->sense_dma + ((smid - 1) * ++ SCSI_SENSE_BUFFERSIZE)); ++} ++ ++/** ++ * mpt2sas_base_get_reply_virt_addr - obtain reply frames virt address ++ * @ioc: per adapter object ++ * @phys_addr: lower 32 physical addr of the reply ++ * ++ * Converts 32bit lower physical addr into a virt address. ++ */ ++void * ++mpt2sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr) ++{ ++ if (!phys_addr) ++ return NULL; ++ return ioc->reply + (phys_addr - (u32)ioc->reply_dma); ++} ++ ++static inline u8 ++_base_get_msix_index(struct MPT3SAS_ADAPTER *ioc) ++{ ++ return ioc->cpu_msix_table[raw_smp_processor_id()]; ++} ++ ++/** ++ * mpt2sas_base_get_smid - obtain a free smid from internal queue ++ * @ioc: per adapter object ++ * @cb_idx: callback index ++ * ++ * Returns smid (zero is invalid) ++ */ ++u16 ++mpt2sas_base_get_smid(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx) ++{ ++ unsigned long flags; ++ struct request_tracker *request; ++ u16 smid; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->internal_free_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ pr_err(MPT3SAS_FMT "%s: smid not available\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ request = list_entry(ioc->internal_free_list.next, ++ struct request_tracker, tracker_list); ++ request->cb_idx = cb_idx; ++ smid = request->smid; ++ list_del(&request->tracker_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * mpt2sas_base_get_smid_scsiio - obtain a free smid from scsiio queue ++ * @ioc: per adapter object ++ * @cb_idx: callback index ++ * @scmd: pointer to scsi command object ++ * ++ * Returns smid (zero is invalid) ++ */ ++u16 ++mpt2sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, ++ struct scsi_cmnd *scmd) ++{ ++ unsigned long flags; ++ struct scsiio_tracker *request; ++ u16 smid; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->free_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ pr_err(MPT3SAS_FMT "%s: smid not available\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ request = list_entry(ioc->free_list.next, ++ struct scsiio_tracker, tracker_list); ++ request->scmd = scmd; ++ request->cb_idx = cb_idx; ++ smid = request->smid; ++ request->msix_io = _base_get_msix_index(ioc); ++ list_del(&request->tracker_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * mpt2sas_base_get_smid_hpr - obtain a free smid from hi-priority queue ++ * @ioc: per adapter object ++ * @cb_idx: callback index ++ * ++ * Returns smid (zero is invalid) ++ */ ++u16 ++mpt2sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx) ++{ ++ unsigned long flags; ++ struct request_tracker *request; ++ u16 smid; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (list_empty(&ioc->hpr_free_list)) { ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return 0; ++ } ++ ++ request = list_entry(ioc->hpr_free_list.next, ++ struct request_tracker, tracker_list); ++ request->cb_idx = cb_idx; ++ smid = request->smid; ++ list_del(&request->tracker_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * mpt2sas_base_free_smid - put smid back on free_list ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ unsigned long flags; ++ int i; ++ struct chain_tracker *chain_req, *next; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ if (smid < ioc->hi_priority_smid) { ++ /* scsiio queue */ ++ i = smid - 1; ++ if (!list_empty(&ioc->scsi_lookup[i].chain_list)) { ++ list_for_each_entry_safe(chain_req, next, ++ &ioc->scsi_lookup[i].chain_list, tracker_list) { ++ list_del_init(&chain_req->tracker_list); ++ list_add(&chain_req->tracker_list, ++ &ioc->free_chain_list); ++ } ++ } ++ ioc->scsi_lookup[i].cb_idx = 0xFF; ++ ioc->scsi_lookup[i].scmd = NULL; ++ ioc->scsi_lookup[i].direct_io = 0; ++ list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list); ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ /* ++ * See _wait_for_commands_to_complete() call with regards ++ * to this code. ++ */ ++ if (ioc->shost_recovery && ioc->pending_io_count) { ++ if (ioc->pending_io_count == 1) ++ wake_up(&ioc->reset_wq); ++ ioc->pending_io_count--; ++ } ++ return; ++ } else if (smid < ioc->internal_smid) { ++ /* hi-priority */ ++ i = smid - ioc->hi_priority_smid; ++ ioc->hpr_lookup[i].cb_idx = 0xFF; ++ list_add(&ioc->hpr_lookup[i].tracker_list, &ioc->hpr_free_list); ++ } else if (smid <= ioc->hba_queue_depth) { ++ /* internal queue */ ++ i = smid - ioc->internal_smid; ++ ioc->internal_lookup[i].cb_idx = 0xFF; ++ list_add(&ioc->internal_lookup[i].tracker_list, ++ &ioc->internal_free_list); ++ } ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++} ++ ++/** ++ * _base_writeq - 64 bit write to MMIO ++ * @ioc: per adapter object ++ * @b: data payload ++ * @addr: address in MMIO space ++ * @writeq_lock: spin lock ++ * ++ * Glue for handling an atomic 64 bit word to MMIO. This special handling takes ++ * care of 32 bit environment where its not quarenteed to send the entire word ++ * in one transfer. ++ */ ++#if defined(writeq) && defined(CONFIG_64BIT) ++static inline void ++_base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) ++{ ++ writeq(cpu_to_le64(b), addr); ++} ++#else ++static inline void ++_base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) ++{ ++ unsigned long flags; ++ __u64 data_out = cpu_to_le64(b); ++ ++ spin_lock_irqsave(writeq_lock, flags); ++ writel((u32)(data_out), addr); ++ writel((u32)(data_out >> 32), (addr + 4)); ++ spin_unlock_irqrestore(writeq_lock, flags); ++} ++#endif ++ ++/** ++ * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ ++ descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; ++ descriptor.SCSIIO.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SCSIIO.SMID = cpu_to_le16(smid); ++ descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); ++ descriptor.SCSIIO.LMID = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * mpt2sas_base_put_smid_fast_path - send fast path request to firmware ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ descriptor.SCSIIO.RequestFlags = ++ MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; ++ descriptor.SCSIIO.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SCSIIO.SMID = cpu_to_le16(smid); ++ descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); ++ descriptor.SCSIIO.LMID = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0. ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 msix_task) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ descriptor.HighPriority.RequestFlags = ++ MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; ++ descriptor.HighPriority.MSIxIndex = msix_task; ++ descriptor.HighPriority.SMID = cpu_to_le16(smid); ++ descriptor.HighPriority.LMID = 0; ++ descriptor.HighPriority.Reserved1 = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * mpt2sas_base_put_smid_default - Default, primarily used for config pages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ Mpi2RequestDescriptorUnion_t descriptor; ++ u64 *request = (u64 *)&descriptor; ++ ++ descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; ++ descriptor.Default.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.Default.SMID = cpu_to_le16(smid); ++ descriptor.Default.LMID = 0; ++ descriptor.Default.DescriptorTypeDependent = 0; ++ _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, ++ &ioc->scsi_lookup_lock); ++} ++ ++/** ++ * _base_display_OEMs_branding - Display branding string ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_OEMs_branding(struct MPT3SAS_ADAPTER *ioc) ++{ ++ if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL) ++ return; ++ ++ switch (ioc->pdev->subsystem_vendor) { ++ case PCI_VENDOR_ID_INTEL: ++ switch (ioc->pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SAS2008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_INTEL_RMS2LL080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS2LL080_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS2LL040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS2LL040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_SSD910_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_SSD910_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ case MPI2_MFGPAGE_DEVID_SAS2308_2: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_INTEL_RS25GB008_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RS25GB008_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25JB080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25JB080_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25JB040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25JB040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25KB080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25KB080_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25KB040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25KB040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25LB040_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25LB040_BRANDING); ++ break; ++ case MPT2SAS_INTEL_RMS25LB080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_INTEL_RMS25LB080_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_INTEL_RMS3JC080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RMS3JC080_BRANDING); ++ break; ++ ++ case MPT3SAS_INTEL_RS3GC008_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RS3GC008_BRANDING); ++ break; ++ case MPT3SAS_INTEL_RS3FC044_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RS3FC044_BRANDING); ++ break; ++ case MPT3SAS_INTEL_RS3UC080_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_INTEL_RS3UC080_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Intel(R) Controller: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case PCI_VENDOR_ID_DELL: ++ switch (ioc->pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SAS2008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_MODULAR_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING); ++ break; ++ case MPT2SAS_DELL_PERC_H200_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_PERC_H200_BRANDING); ++ break; ++ case MPT2SAS_DELL_6GBPS_SAS_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_DELL_6GBPS_SAS_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Dell 6Gbps HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_DELL_12G_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_DELL_12G_HBA_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Dell HBA: Subsystem ID: 0x%X\n", ioc->name, ++ ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case PCI_VENDOR_ID_CISCO: ++ switch (ioc->pdev->device) { ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_CISCO_12G_8E_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_8E_HBA_BRANDING); ++ break; ++ case MPT3SAS_CISCO_12G_8I_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_8I_HBA_BRANDING); ++ break; ++ case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case MPI25_MFGPAGE_DEVID_SAS3108_1: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING); ++ break; ++ case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING ++ ); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "Cisco SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ break; ++ case MPT2SAS_HP_3PAR_SSVID: ++ switch (ioc->pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SAS2004: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ case MPI2_MFGPAGE_DEVID_SAS2308_2: ++ switch (ioc->pdev->subsystem_device) { ++ case MPT2SAS_HP_2_4_INTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_2_4_INTERNAL_BRANDING); ++ break; ++ case MPT2SAS_HP_2_4_EXTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_2_4_EXTERNAL_BRANDING); ++ break; ++ case MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING); ++ break; ++ case MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID: ++ pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING); ++ break; ++ default: ++ pr_info(MPT3SAS_FMT ++ "HP 6Gbps SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ default: ++ pr_info(MPT3SAS_FMT ++ "HP SAS HBA: Subsystem ID: 0x%X\n", ++ ioc->name, ioc->pdev->subsystem_device); ++ break; ++ } ++ default: ++ break; ++ } ++} ++ ++/** ++ * _base_display_ioc_capabilities - Disply IOC's capabilities. ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int i = 0; ++ char desc[16]; ++ u32 iounit_pg1_flags; ++ u32 bios_version; ++ ++ bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); ++ strncpy(desc, ioc->manu_pg0.ChipName, 16); ++ pr_info(MPT3SAS_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), "\ ++ "ChipRevision(0x%02x), BiosVersion(%02d.%02d.%02d.%02d)\n", ++ ioc->name, desc, ++ (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, ++ (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, ++ (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ++ ioc->facts.FWVersion.Word & 0x000000FF, ++ ioc->pdev->revision, ++ (bios_version & 0xFF000000) >> 24, ++ (bios_version & 0x00FF0000) >> 16, ++ (bios_version & 0x0000FF00) >> 8, ++ bios_version & 0x000000FF); ++ ++ _base_display_OEMs_branding(ioc); ++ ++ pr_info(MPT3SAS_FMT "Protocol=(", ioc->name); ++ ++ if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) { ++ pr_info("Initiator"); ++ i++; ++ } ++ ++ if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET) { ++ pr_info("%sTarget", i ? "," : ""); ++ i++; ++ } ++ ++ i = 0; ++ pr_info("), "); ++ pr_info("Capabilities=("); ++ ++ if (!ioc->hide_ir_msg) { ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { ++ pr_info("Raid"); ++ i++; ++ } ++ } ++ ++ if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { ++ pr_info("%sTLR", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_MULTICAST) { ++ pr_info("%sMulticast", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET) { ++ pr_info("%sBIDI Target", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP) { ++ pr_info("%sEEDP", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) { ++ pr_info("%sSnapshot Buffer", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) { ++ pr_info("%sDiag Trace Buffer", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) { ++ pr_info("%sDiag Extended Buffer", i ? "," : ""); ++ i++; ++ } ++ ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { ++ pr_info("%sTask Set Full", i ? "," : ""); ++ i++; ++ } ++ ++ iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags); ++ if (!(iounit_pg1_flags & MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE)) { ++ pr_info("%sNCQ", i ? "," : ""); ++ i++; ++ } ++ ++ pr_info(")\n"); ++} ++ ++/** ++ * mpt2sas_base_update_missing_delay - change the missing delay timers ++ * @ioc: per adapter object ++ * @device_missing_delay: amount of time till device is reported missing ++ * @io_missing_delay: interval IO is returned when there is a missing device ++ * ++ * Return nothing. ++ * ++ * Passed on the command line, this function will modify the device missing ++ * delay, as well as the io missing delay. This should be called at driver ++ * load time. ++ */ ++void ++mpt2sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc, ++ u16 device_missing_delay, u8 io_missing_delay) ++{ ++ u16 dmd, dmd_new, dmd_orignal; ++ u8 io_missing_delay_original; ++ u16 sz; ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2ConfigReply_t mpi_reply; ++ u8 num_phys = 0; ++ u16 ioc_status; ++ ++ mpt2sas_config_get_number_hba_phys(ioc, &num_phys); ++ if (!num_phys) ++ return; ++ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ /* device missing delay */ ++ dmd = sas_iounit_pg1->ReportDeviceMissingDelay; ++ if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) ++ dmd = (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; ++ else ++ dmd = dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; ++ dmd_orignal = dmd; ++ if (device_missing_delay > 0x7F) { ++ dmd = (device_missing_delay > 0x7F0) ? 0x7F0 : ++ device_missing_delay; ++ dmd = dmd / 16; ++ dmd |= MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16; ++ } else ++ dmd = device_missing_delay; ++ sas_iounit_pg1->ReportDeviceMissingDelay = dmd; ++ ++ /* io missing delay */ ++ io_missing_delay_original = sas_iounit_pg1->IODeviceMissingDelay; ++ sas_iounit_pg1->IODeviceMissingDelay = io_missing_delay; ++ ++ if (!mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, ++ sz)) { ++ if (dmd & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) ++ dmd_new = (dmd & ++ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; ++ else ++ dmd_new = ++ dmd & MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; ++ pr_info(MPT3SAS_FMT "device_missing_delay: old(%d), new(%d)\n", ++ ioc->name, dmd_orignal, dmd_new); ++ pr_info(MPT3SAS_FMT "ioc_missing_delay: old(%d), new(%d)\n", ++ ioc->name, io_missing_delay_original, ++ io_missing_delay); ++ ioc->device_missing_delay = dmd_new; ++ ioc->io_missing_delay = io_missing_delay; ++ } ++ ++out: ++ kfree(sas_iounit_pg1); ++} ++/** ++ * _base_static_config_pages - static start of day config pages ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ u32 iounit_pg1_flags; ++ ++ mpt2sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0); ++ if (ioc->ir_firmware) ++ mpt2sas_config_get_manufacturing_pg10(ioc, &mpi_reply, ++ &ioc->manu_pg10); ++ ++ /* ++ * Ensure correct T10 PI operation if vendor left EEDPTagMode ++ * flag unset in NVDATA. ++ */ ++ mpt2sas_config_get_manufacturing_pg11(ioc, &mpi_reply, &ioc->manu_pg11); ++ if (ioc->manu_pg11.EEDPTagMode == 0) { ++ pr_err("%s: overriding NVDATA EEDPTagMode setting\n", ++ ioc->name); ++ ioc->manu_pg11.EEDPTagMode &= ~0x3; ++ ioc->manu_pg11.EEDPTagMode |= 0x1; ++ mpt2sas_config_set_manufacturing_pg11(ioc, &mpi_reply, ++ &ioc->manu_pg11); ++ } ++ ++ mpt2sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2); ++ mpt2sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3); ++ mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); ++ mpt2sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0); ++ mpt2sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); ++ mpt2sas_config_get_iounit_pg8(ioc, &mpi_reply, &ioc->iounit_pg8); ++ _base_display_ioc_capabilities(ioc); ++ ++ /* ++ * Enable task_set_full handling in iounit_pg1 when the ++ * facts capabilities indicate that its supported. ++ */ ++ iounit_pg1_flags = le32_to_cpu(ioc->iounit_pg1.Flags); ++ if ((ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING)) ++ iounit_pg1_flags &= ++ ~MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; ++ else ++ iounit_pg1_flags |= ++ MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; ++ ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); ++ mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); ++ ++ if (ioc->iounit_pg8.NumSensors) ++ ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors; ++} ++ ++/** ++ * _base_release_memory_pools - release memory ++ * @ioc: per adapter object ++ * ++ * Free memory allocated from _base_allocate_memory_pools. ++ * ++ * Return nothing. ++ */ ++static void ++_base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int i = 0; ++ struct reply_post_struct *rps; ++ ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->request) { ++ pci_free_consistent(ioc->pdev, ioc->request_dma_sz, ++ ioc->request, ioc->request_dma); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "request_pool(0x%p): free\n", ++ ioc->name, ioc->request)); ++ ioc->request = NULL; ++ } ++ ++ if (ioc->sense) { ++ pci_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma); ++ if (ioc->sense_dma_pool) ++ pci_pool_destroy(ioc->sense_dma_pool); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "sense_pool(0x%p): free\n", ++ ioc->name, ioc->sense)); ++ ioc->sense = NULL; ++ } ++ ++ if (ioc->reply) { ++ pci_pool_free(ioc->reply_dma_pool, ioc->reply, ioc->reply_dma); ++ if (ioc->reply_dma_pool) ++ pci_pool_destroy(ioc->reply_dma_pool); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_pool(0x%p): free\n", ++ ioc->name, ioc->reply)); ++ ioc->reply = NULL; ++ } ++ ++ if (ioc->reply_free) { ++ pci_pool_free(ioc->reply_free_dma_pool, ioc->reply_free, ++ ioc->reply_free_dma); ++ if (ioc->reply_free_dma_pool) ++ pci_pool_destroy(ioc->reply_free_dma_pool); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_free_pool(0x%p): free\n", ++ ioc->name, ioc->reply_free)); ++ ioc->reply_free = NULL; ++ } ++ ++ if (ioc->reply_post) { ++ do { ++ rps = &ioc->reply_post[i]; ++ if (rps->reply_post_free) { ++ pci_pool_free( ++ ioc->reply_post_free_dma_pool, ++ rps->reply_post_free, ++ rps->reply_post_free_dma); ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_post_free_pool(0x%p): free\n", ++ ioc->name, rps->reply_post_free)); ++ rps->reply_post_free = NULL; ++ } ++ } while (ioc->rdpq_array_enable && ++ (++i < ioc->reply_queue_count)); ++ ++ if (ioc->reply_post_free_dma_pool) ++ pci_pool_destroy(ioc->reply_post_free_dma_pool); ++ kfree(ioc->reply_post); ++ } ++ ++ if (ioc->config_page) { ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT ++ "config_page(0x%p): free\n", ioc->name, ++ ioc->config_page)); ++ pci_free_consistent(ioc->pdev, ioc->config_page_sz, ++ ioc->config_page, ioc->config_page_dma); ++ } ++ ++ if (ioc->scsi_lookup) { ++ free_pages((ulong)ioc->scsi_lookup, ioc->scsi_lookup_pages); ++ ioc->scsi_lookup = NULL; ++ } ++ kfree(ioc->hpr_lookup); ++ kfree(ioc->internal_lookup); ++ if (ioc->chain_lookup) { ++ for (i = 0; i < ioc->chain_depth; i++) { ++ if (ioc->chain_lookup[i].chain_buffer) ++ pci_pool_free(ioc->chain_dma_pool, ++ ioc->chain_lookup[i].chain_buffer, ++ ioc->chain_lookup[i].chain_buffer_dma); ++ } ++ if (ioc->chain_dma_pool) ++ pci_pool_destroy(ioc->chain_dma_pool); ++ free_pages((ulong)ioc->chain_lookup, ioc->chain_pages); ++ ioc->chain_lookup = NULL; ++ } ++} ++ ++/** ++ * _base_allocate_memory_pools - allocate start of day memory pools ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 success, anything else error ++ */ ++static int ++_base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ struct mpt2sas_facts *facts; ++ u16 max_sge_elements; ++ u16 chains_needed_per_io; ++ u32 sz, total_sz, reply_post_free_sz; ++ u32 retry_sz; ++ u16 max_request_credit; ++ unsigned short sg_tablesize; ++ u16 sge_size; ++ int i; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ ++ retry_sz = 0; ++ facts = &ioc->facts; ++ ++ /* command line tunables for max sgl entries */ ++ if (max_sgl_entries != -1) ++ sg_tablesize = max_sgl_entries; ++ else { ++ if (ioc->hba_mpi_version_belonged == MPI2_VERSION) ++ sg_tablesize = MPT2SAS_SG_DEPTH; ++ else ++ sg_tablesize = MPT3SAS_SG_DEPTH; ++ } ++ ++ if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS) ++ sg_tablesize = MPT_MIN_PHYS_SEGMENTS; ++ else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) { ++ sg_tablesize = min_t(unsigned short, sg_tablesize, ++ SCSI_MAX_SG_CHAIN_SEGMENTS); ++ pr_warn(MPT3SAS_FMT ++ "sg_tablesize(%u) is bigger than kernel" ++ " defined SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name, ++ sg_tablesize, MPT_MAX_PHYS_SEGMENTS); ++ } ++ ioc->shost->sg_tablesize = sg_tablesize; ++ ++ ioc->internal_depth = min_t(int, (facts->HighPriorityCredit + (5)), ++ (facts->RequestCredit / 4)); ++ if (ioc->internal_depth < INTERNAL_CMDS_COUNT) { ++ if (facts->RequestCredit <= (INTERNAL_CMDS_COUNT + ++ INTERNAL_SCSIIO_CMDS_COUNT)) { ++ pr_err(MPT3SAS_FMT "IOC doesn't have enough Request \ ++ Credits, it has just %d number of credits\n", ++ ioc->name, facts->RequestCredit); ++ return -ENOMEM; ++ } ++ ioc->internal_depth = 10; ++ } ++ ++ ioc->hi_priority_depth = ioc->internal_depth - (5); ++ /* command line tunables for max controller queue depth */ ++ if (max_queue_depth != -1 && max_queue_depth != 0) { ++ max_request_credit = min_t(u16, max_queue_depth + ++ ioc->internal_depth, facts->RequestCredit); ++ if (max_request_credit > MAX_HBA_QUEUE_DEPTH) ++ max_request_credit = MAX_HBA_QUEUE_DEPTH; ++ } else ++ max_request_credit = min_t(u16, facts->RequestCredit, ++ MAX_HBA_QUEUE_DEPTH); ++ ++ /* Firmware maintains additional facts->HighPriorityCredit number of ++ * credits for HiPriprity Request messages, so hba queue depth will be ++ * sum of max_request_credit and high priority queue depth. ++ */ ++ ioc->hba_queue_depth = max_request_credit + ioc->hi_priority_depth; ++ ++ /* request frame size */ ++ ioc->request_sz = facts->IOCRequestFrameSize * 4; ++ ++ /* reply frame size */ ++ ioc->reply_sz = facts->ReplyFrameSize * 4; ++ ++ /* chain segment size */ ++ if (ioc->hba_mpi_version_belonged != MPI2_VERSION) { ++ if (facts->IOCMaxChainSegmentSize) ++ ioc->chain_segment_sz = ++ facts->IOCMaxChainSegmentSize * ++ MAX_CHAIN_ELEMT_SZ; ++ else ++ /* set to 128 bytes size if IOCMaxChainSegmentSize is zero */ ++ ioc->chain_segment_sz = DEFAULT_NUM_FWCHAIN_ELEMTS * ++ MAX_CHAIN_ELEMT_SZ; ++ } else ++ ioc->chain_segment_sz = ioc->request_sz; ++ ++ /* calculate the max scatter element size */ ++ sge_size = max_t(u16, ioc->sge_size, ioc->sge_size_ieee); ++ ++ retry_allocation: ++ total_sz = 0; ++ /* calculate number of sg elements left over in the 1st frame */ ++ max_sge_elements = ioc->request_sz - ((sizeof(Mpi2SCSIIORequest_t) - ++ sizeof(Mpi2SGEIOUnion_t)) + sge_size); ++ ioc->max_sges_in_main_message = max_sge_elements/sge_size; ++ ++ /* now do the same for a chain buffer */ ++ max_sge_elements = ioc->chain_segment_sz - sge_size; ++ ioc->max_sges_in_chain_message = max_sge_elements/sge_size; ++ ++ /* ++ * MPT3SAS_SG_DEPTH = CONFIG_FUSION_MAX_SGE ++ */ ++ chains_needed_per_io = ((ioc->shost->sg_tablesize - ++ ioc->max_sges_in_main_message)/ioc->max_sges_in_chain_message) ++ + 1; ++ if (chains_needed_per_io > facts->MaxChainDepth) { ++ chains_needed_per_io = facts->MaxChainDepth; ++ ioc->shost->sg_tablesize = min_t(u16, ++ ioc->max_sges_in_main_message + (ioc->max_sges_in_chain_message ++ * chains_needed_per_io), ioc->shost->sg_tablesize); ++ } ++ ioc->chains_needed_per_io = chains_needed_per_io; ++ ++ /* reply free queue sizing - taking into account for 64 FW events */ ++ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; ++ ++ /* calculate reply descriptor post queue depth */ ++ ioc->reply_post_queue_depth = ioc->hba_queue_depth + ++ ioc->reply_free_queue_depth + 1 ; ++ /* align the reply post queue on the next 16 count boundary */ ++ if (ioc->reply_post_queue_depth % 16) ++ ioc->reply_post_queue_depth += 16 - ++ (ioc->reply_post_queue_depth % 16); ++ ++ if (ioc->reply_post_queue_depth > ++ facts->MaxReplyDescriptorPostQueueDepth) { ++ ioc->reply_post_queue_depth = ++ facts->MaxReplyDescriptorPostQueueDepth - ++ (facts->MaxReplyDescriptorPostQueueDepth % 16); ++ ioc->hba_queue_depth = ++ ((ioc->reply_post_queue_depth - 64) / 2) - 1; ++ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; ++ } ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "scatter gather: " \ ++ "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), " ++ "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message, ++ ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, ++ ioc->chains_needed_per_io)); ++ ++ /* reply post queue, 16 byte align */ ++ reply_post_free_sz = ioc->reply_post_queue_depth * ++ sizeof(Mpi2DefaultReplyDescriptor_t); ++ ++ sz = reply_post_free_sz; ++ if (_base_is_controller_msix_enabled(ioc) && !ioc->rdpq_array_enable) ++ sz *= ioc->reply_queue_count; ++ ++ ioc->reply_post = kcalloc((ioc->rdpq_array_enable) ? ++ (ioc->reply_queue_count):1, ++ sizeof(struct reply_post_struct), GFP_KERNEL); ++ ++ if (!ioc->reply_post) { ++ pr_err(MPT3SAS_FMT "reply_post_free pool: kcalloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply_post_free_dma_pool = pci_pool_create("reply_post_free pool", ++ ioc->pdev, sz, 16, 0); ++ if (!ioc->reply_post_free_dma_pool) { ++ pr_err(MPT3SAS_FMT ++ "reply_post_free pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ i = 0; ++ do { ++ ioc->reply_post[i].reply_post_free = ++ pci_pool_alloc(ioc->reply_post_free_dma_pool, ++ GFP_KERNEL, ++ &ioc->reply_post[i].reply_post_free_dma); ++ if (!ioc->reply_post[i].reply_post_free) { ++ pr_err(MPT3SAS_FMT ++ "reply_post_free pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ memset(ioc->reply_post[i].reply_post_free, 0, sz); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply post free pool (0x%p): depth(%d)," ++ "element_size(%d), pool_size(%d kB)\n", ioc->name, ++ ioc->reply_post[i].reply_post_free, ++ ioc->reply_post_queue_depth, 8, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_post_free_dma = (0x%llx)\n", ioc->name, ++ (unsigned long long) ++ ioc->reply_post[i].reply_post_free_dma)); ++ total_sz += sz; ++ } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count)); ++ ++ if (ioc->dma_mask == 64) { ++ if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) { ++ pr_warn(MPT3SAS_FMT ++ "no suitable consistent DMA mask for %s\n", ++ ioc->name, pci_name(ioc->pdev)); ++ goto out; ++ } ++ } ++ ++ ioc->scsiio_depth = ioc->hba_queue_depth - ++ ioc->hi_priority_depth - ioc->internal_depth; ++ ++ /* set the scsi host can_queue depth ++ * with some internal commands that could be outstanding ++ */ ++ ioc->shost->can_queue = ioc->scsiio_depth - INTERNAL_SCSIIO_CMDS_COUNT; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "scsi host: can_queue depth (%d)\n", ++ ioc->name, ioc->shost->can_queue)); ++ ++ ++ /* contiguous pool for request and chains, 16 byte align, one extra " ++ * "frame for smid=0 ++ */ ++ ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth; ++ sz = ((ioc->scsiio_depth + 1) * ioc->request_sz); ++ ++ /* hi-priority queue */ ++ sz += (ioc->hi_priority_depth * ioc->request_sz); ++ ++ /* internal queue */ ++ sz += (ioc->internal_depth * ioc->request_sz); ++ ++ ioc->request_dma_sz = sz; ++ ioc->request = pci_alloc_consistent(ioc->pdev, sz, &ioc->request_dma); ++ if (!ioc->request) { ++ pr_err(MPT3SAS_FMT "request pool: pci_alloc_consistent " \ ++ "failed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), " ++ "total(%d kB)\n", ioc->name, ioc->hba_queue_depth, ++ ioc->chains_needed_per_io, ioc->request_sz, sz/1024); ++ if (ioc->scsiio_depth < MPT3SAS_SAS_QUEUE_DEPTH) ++ goto out; ++ retry_sz = 64; ++ ioc->hba_queue_depth -= retry_sz; ++ _base_release_memory_pools(ioc); ++ goto retry_allocation; ++ } ++ ++ if (retry_sz) ++ pr_err(MPT3SAS_FMT "request pool: pci_alloc_consistent " \ ++ "succeed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), " ++ "total(%d kb)\n", ioc->name, ioc->hba_queue_depth, ++ ioc->chains_needed_per_io, ioc->request_sz, sz/1024); ++ ++ /* hi-priority queue */ ++ ioc->hi_priority = ioc->request + ((ioc->scsiio_depth + 1) * ++ ioc->request_sz); ++ ioc->hi_priority_dma = ioc->request_dma + ((ioc->scsiio_depth + 1) * ++ ioc->request_sz); ++ ++ /* internal queue */ ++ ioc->internal = ioc->hi_priority + (ioc->hi_priority_depth * ++ ioc->request_sz); ++ ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * ++ ioc->request_sz); ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "request pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n", ++ ioc->name, ioc->request, ioc->hba_queue_depth, ioc->request_sz, ++ (ioc->hba_queue_depth * ioc->request_sz)/1024)); ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "request pool: dma(0x%llx)\n", ++ ioc->name, (unsigned long long) ioc->request_dma)); ++ total_sz += sz; ++ ++ sz = ioc->scsiio_depth * sizeof(struct scsiio_tracker); ++ ioc->scsi_lookup_pages = get_order(sz); ++ ioc->scsi_lookup = (struct scsiio_tracker *)__get_free_pages( ++ GFP_KERNEL, ioc->scsi_lookup_pages); ++ if (!ioc->scsi_lookup) { ++ pr_err(MPT3SAS_FMT "scsi_lookup: get_free_pages failed, sz(%d)\n", ++ ioc->name, (int)sz); ++ goto out; ++ } ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "scsiio(0x%p): depth(%d)\n", ++ ioc->name, ioc->request, ioc->scsiio_depth)); ++ ++ ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH); ++ sz = ioc->chain_depth * sizeof(struct chain_tracker); ++ ioc->chain_pages = get_order(sz); ++ ioc->chain_lookup = (struct chain_tracker *)__get_free_pages( ++ GFP_KERNEL, ioc->chain_pages); ++ if (!ioc->chain_lookup) { ++ pr_err(MPT3SAS_FMT "chain_lookup: __get_free_pages failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev, ++ ioc->chain_segment_sz, 16, 0); ++ if (!ioc->chain_dma_pool) { ++ pr_err(MPT3SAS_FMT "chain_dma_pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ for (i = 0; i < ioc->chain_depth; i++) { ++ ioc->chain_lookup[i].chain_buffer = pci_pool_alloc( ++ ioc->chain_dma_pool , GFP_KERNEL, ++ &ioc->chain_lookup[i].chain_buffer_dma); ++ if (!ioc->chain_lookup[i].chain_buffer) { ++ ioc->chain_depth = i; ++ goto chain_done; ++ } ++ total_sz += ioc->chain_segment_sz; ++ } ++ chain_done: ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n", ++ ioc->name, ioc->chain_depth, ioc->chain_segment_sz, ++ ((ioc->chain_depth * ioc->chain_segment_sz))/1024)); ++ ++ /* initialize hi-priority queue smid's */ ++ ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, ++ sizeof(struct request_tracker), GFP_KERNEL); ++ if (!ioc->hpr_lookup) { ++ pr_err(MPT3SAS_FMT "hpr_lookup: kcalloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->hi_priority_smid = ioc->scsiio_depth + 1; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "hi_priority(0x%p): depth(%d), start smid(%d)\n", ++ ioc->name, ioc->hi_priority, ++ ioc->hi_priority_depth, ioc->hi_priority_smid)); ++ ++ /* initialize internal queue smid's */ ++ ioc->internal_lookup = kcalloc(ioc->internal_depth, ++ sizeof(struct request_tracker), GFP_KERNEL); ++ if (!ioc->internal_lookup) { ++ pr_err(MPT3SAS_FMT "internal_lookup: kcalloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->internal_smid = ioc->hi_priority_smid + ioc->hi_priority_depth; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "internal(0x%p): depth(%d), start smid(%d)\n", ++ ioc->name, ioc->internal, ++ ioc->internal_depth, ioc->internal_smid)); ++ ++ /* sense buffers, 4 byte align */ ++ sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE; ++ ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4, ++ 0); ++ if (!ioc->sense_dma_pool) { ++ pr_err(MPT3SAS_FMT "sense pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->sense = pci_pool_alloc(ioc->sense_dma_pool , GFP_KERNEL, ++ &ioc->sense_dma); ++ if (!ioc->sense) { ++ pr_err(MPT3SAS_FMT "sense pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "sense pool(0x%p): depth(%d), element_size(%d), pool_size" ++ "(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth, ++ SCSI_SENSE_BUFFERSIZE, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "sense_dma(0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->sense_dma)); ++ total_sz += sz; ++ ++ /* reply pool, 4 byte align */ ++ sz = ioc->reply_free_queue_depth * ioc->reply_sz; ++ ioc->reply_dma_pool = pci_pool_create("reply pool", ioc->pdev, sz, 4, ++ 0); ++ if (!ioc->reply_dma_pool) { ++ pr_err(MPT3SAS_FMT "reply pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply = pci_pool_alloc(ioc->reply_dma_pool , GFP_KERNEL, ++ &ioc->reply_dma); ++ if (!ioc->reply) { ++ pr_err(MPT3SAS_FMT "reply pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply_dma_min_address = (u32)(ioc->reply_dma); ++ ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz; ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n", ++ ioc->name, ioc->reply, ++ ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "reply_dma(0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->reply_dma)); ++ total_sz += sz; ++ ++ /* reply free queue, 16 byte align */ ++ sz = ioc->reply_free_queue_depth * 4; ++ ioc->reply_free_dma_pool = pci_pool_create("reply_free pool", ++ ioc->pdev, sz, 16, 0); ++ if (!ioc->reply_free_dma_pool) { ++ pr_err(MPT3SAS_FMT "reply_free pool: pci_pool_create failed\n", ++ ioc->name); ++ goto out; ++ } ++ ioc->reply_free = pci_pool_alloc(ioc->reply_free_dma_pool , GFP_KERNEL, ++ &ioc->reply_free_dma); ++ if (!ioc->reply_free) { ++ pr_err(MPT3SAS_FMT "reply_free pool: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ memset(ioc->reply_free, 0, sz); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "reply_free pool(0x%p): " \ ++ "depth(%d), element_size(%d), pool_size(%d kB)\n", ioc->name, ++ ioc->reply_free, ioc->reply_free_queue_depth, 4, sz/1024)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "reply_free_dma (0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->reply_free_dma)); ++ total_sz += sz; ++ ++ ioc->config_page_sz = 512; ++ ioc->config_page = pci_alloc_consistent(ioc->pdev, ++ ioc->config_page_sz, &ioc->config_page_dma); ++ if (!ioc->config_page) { ++ pr_err(MPT3SAS_FMT ++ "config page: pci_pool_alloc failed\n", ++ ioc->name); ++ goto out; ++ } ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "config page(0x%p): size(%d)\n", ++ ioc->name, ioc->config_page, ioc->config_page_sz)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "config_page_dma(0x%llx)\n", ++ ioc->name, (unsigned long long)ioc->config_page_dma)); ++ total_sz += ioc->config_page_sz; ++ ++ pr_info(MPT3SAS_FMT "Allocated physical memory: size(%d kB)\n", ++ ioc->name, total_sz/1024); ++ pr_info(MPT3SAS_FMT ++ "Current Controller Queue Depth(%d),Max Controller Queue Depth(%d)\n", ++ ioc->name, ioc->shost->can_queue, facts->RequestCredit); ++ pr_info(MPT3SAS_FMT "Scatter Gather Elements per IO(%d)\n", ++ ioc->name, ioc->shost->sg_tablesize); ++ return 0; ++ ++ out: ++ return -ENOMEM; ++} ++ ++/** ++ * mpt2sas_base_get_iocstate - Get the current state of a MPT adapter. ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @cooked: Request raw or cooked IOC state ++ * ++ * Returns all IOC Doorbell register bits if cooked==0, else just the ++ * Doorbell bits in MPI_IOC_STATE_MASK. ++ */ ++u32 ++mpt2sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked) ++{ ++ u32 s, sc; ++ ++ s = readl(&ioc->chip->Doorbell); ++ sc = s & MPI2_IOC_STATE_MASK; ++ return cooked ? sc : s; ++} ++ ++/** ++ * _base_wait_on_iocstate - waiting on a particular ioc state ++ * @ioc_state: controller state { READY, OPERATIONAL, or RESET } ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, u32 ioc_state, int timeout, ++ int sleep_flag) ++{ ++ u32 count, cntdn; ++ u32 current_state; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ current_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (current_state == ioc_state) ++ return 0; ++ if (count && current_state == MPI2_IOC_STATE_FAULT) ++ break; ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ return current_state; ++} ++ ++/** ++ * _base_wait_for_doorbell_int - waiting for controller interrupt(generated by ++ * a write to the doorbell) ++ * @ioc: per adapter object ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ * Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell. ++ */ ++static int ++_base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag); ++ ++static int ++_base_wait_for_doorbell_int(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 cntdn, count; ++ u32 int_status; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ int_status = readl(&ioc->chip->HostInterruptStatus); ++ if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: successful count(%d), timeout(%d)\n", ++ ioc->name, __func__, count, timeout)); ++ return 0; ++ } ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to timeout count(%d), int_status(%x)!\n", ++ ioc->name, __func__, count, int_status); ++ return -EFAULT; ++} ++ ++/** ++ * _base_wait_for_doorbell_ack - waiting for controller to read the doorbell. ++ * @ioc: per adapter object ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ * Notes: MPI2_HIS_SYS2IOC_DB_STATUS - set to one when host writes to ++ * doorbell. ++ */ ++static int ++_base_wait_for_doorbell_ack(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 cntdn, count; ++ u32 int_status; ++ u32 doorbell; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ int_status = readl(&ioc->chip->HostInterruptStatus); ++ if (!(int_status & MPI2_HIS_SYS2IOC_DB_STATUS)) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: successful count(%d), timeout(%d)\n", ++ ioc->name, __func__, count, timeout)); ++ return 0; ++ } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { ++ doorbell = readl(&ioc->chip->Doorbell); ++ if ((doorbell & MPI2_IOC_STATE_MASK) == ++ MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc , doorbell); ++ return -EFAULT; ++ } ++ } else if (int_status == 0xFFFFFFFF) ++ goto out; ++ ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ out: ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to timeout count(%d), int_status(%x)!\n", ++ ioc->name, __func__, count, int_status); ++ return -EFAULT; ++} ++ ++/** ++ * _base_wait_for_doorbell_not_used - waiting for doorbell to not be in use ++ * @ioc: per adapter object ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_base_wait_for_doorbell_not_used(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 cntdn, count; ++ u32 doorbell_reg; ++ ++ count = 0; ++ cntdn = (sleep_flag == CAN_SLEEP) ? 1000*timeout : 2000*timeout; ++ do { ++ doorbell_reg = readl(&ioc->chip->Doorbell); ++ if (!(doorbell_reg & MPI2_DOORBELL_USED)) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: successful count(%d), timeout(%d)\n", ++ ioc->name, __func__, count, timeout)); ++ return 0; ++ } ++ if (sleep_flag == CAN_SLEEP) ++ usleep_range(1000, 1500); ++ else ++ udelay(500); ++ count++; ++ } while (--cntdn); ++ ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to timeout count(%d), doorbell_reg(%x)!\n", ++ ioc->name, __func__, count, doorbell_reg); ++ return -EFAULT; ++} ++ ++/** ++ * _base_send_ioc_reset - send doorbell reset ++ * @ioc: per adapter object ++ * @reset_type: currently only supports: MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_send_ioc_reset(struct MPT3SAS_ADAPTER *ioc, u8 reset_type, int timeout, ++ int sleep_flag) ++{ ++ u32 ioc_state; ++ int r = 0; ++ ++ if (reset_type != MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET) { ++ pr_err(MPT3SAS_FMT "%s: unknown reset_type\n", ++ ioc->name, __func__); ++ return -EFAULT; ++ } ++ ++ if (!(ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY)) ++ return -EFAULT; ++ ++ pr_info(MPT3SAS_FMT "sending message unit reset !!\n", ioc->name); ++ ++ writel(reset_type << MPI2_DOORBELL_FUNCTION_SHIFT, ++ &ioc->chip->Doorbell); ++ if ((_base_wait_for_doorbell_ack(ioc, 15, sleep_flag))) { ++ r = -EFAULT; ++ goto out; ++ } ++ ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, ++ timeout, sleep_flag); ++ if (ioc_state) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state); ++ r = -EFAULT; ++ goto out; ++ } ++ out: ++ pr_info(MPT3SAS_FMT "message unit reset: %s\n", ++ ioc->name, ((r == 0) ? "SUCCESS" : "FAILED")); ++ return r; ++} ++ ++/** ++ * _base_handshake_req_reply_wait - send request thru doorbell interface ++ * @ioc: per adapter object ++ * @request_bytes: request length ++ * @request: pointer having request payload ++ * @reply_bytes: reply length ++ * @reply: pointer to reply payload ++ * @timeout: timeout in second ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, ++ u32 *request, int reply_bytes, u16 *reply, int timeout, int sleep_flag) ++{ ++ MPI2DefaultReply_t *default_reply = (MPI2DefaultReply_t *)reply; ++ int i; ++ u8 failed; ++ u16 dummy; ++ __le32 *mfp; ++ ++ /* make sure doorbell is not in use */ ++ if ((readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { ++ pr_err(MPT3SAS_FMT ++ "doorbell is in use (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* clear pending doorbell interrupts from previous state changes */ ++ if (readl(&ioc->chip->HostInterruptStatus) & ++ MPI2_HIS_IOC2SYS_DB_STATUS) ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ /* send message to ioc */ ++ writel(((MPI2_FUNCTION_HANDSHAKE<chip->Doorbell); ++ ++ if ((_base_wait_for_doorbell_int(ioc, 5, NO_SLEEP))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake ack failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* send message 32-bits at a time */ ++ for (i = 0, failed = 0; i < request_bytes/4 && !failed; i++) { ++ writel(cpu_to_le32(request[i]), &ioc->chip->Doorbell); ++ if ((_base_wait_for_doorbell_ack(ioc, 5, sleep_flag))) ++ failed = 1; ++ } ++ ++ if (failed) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake sending request failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* now wait for the reply */ ++ if ((_base_wait_for_doorbell_int(ioc, timeout, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ ++ /* read the first two 16-bits, it gives the total length of the reply */ ++ reply[0] = le16_to_cpu(readl(&ioc->chip->Doorbell) ++ & MPI2_DOORBELL_DATA_MASK); ++ writel(0, &ioc->chip->HostInterruptStatus); ++ if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ reply[1] = le16_to_cpu(readl(&ioc->chip->Doorbell) ++ & MPI2_DOORBELL_DATA_MASK); ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ for (i = 2; i < default_reply->MsgLength * 2; i++) { ++ if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) { ++ pr_err(MPT3SAS_FMT ++ "doorbell handshake int failed (line=%d)\n", ++ ioc->name, __LINE__); ++ return -EFAULT; ++ } ++ if (i >= reply_bytes/2) /* overflow case */ ++ dummy = readl(&ioc->chip->Doorbell); ++ else ++ reply[i] = le16_to_cpu(readl(&ioc->chip->Doorbell) ++ & MPI2_DOORBELL_DATA_MASK); ++ writel(0, &ioc->chip->HostInterruptStatus); ++ } ++ ++ _base_wait_for_doorbell_int(ioc, 5, sleep_flag); ++ if (_base_wait_for_doorbell_not_used(ioc, 5, sleep_flag) != 0) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "doorbell is in use (line=%d)\n", ioc->name, __LINE__)); ++ } ++ writel(0, &ioc->chip->HostInterruptStatus); ++ ++ if (ioc->logging_level & MPT_DEBUG_INIT) { ++ mfp = (__le32 *)reply; ++ pr_info("\toffset:data\n"); ++ for (i = 0; i < reply_bytes/4; i++) ++ pr_info("\t[0x%02x]:%08x\n", i*4, ++ le32_to_cpu(mfp[i])); ++ } ++ return 0; ++} ++ ++/** ++ * mpt2sas_base_sas_iounit_control - send sas iounit control to FW ++ * @ioc: per adapter object ++ * @mpi_reply: the reply payload from FW ++ * @mpi_request: the request payload sent to FW ++ * ++ * The SAS IO Unit Control Request message allows the host to perform low-level ++ * operations, such as resets on the PHYs of the IO Unit, also allows the host ++ * to obtain the IOC assigned device handles for a device if it has other ++ * identifying information about the device, in addition allows the host to ++ * remove IOC resources associated with the device. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SasIoUnitControlReply_t *mpi_reply, ++ Mpi2SasIoUnitControlRequest_t *mpi_request) ++{ ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ bool issue_reset = false; ++ int rc; ++ void *request; ++ u16 wait_state_count; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mutex_lock(&ioc->base_cmds.mutex); ++ ++ if (ioc->base_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: base_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->base_cmds.status = MPT3_CMD_PENDING; ++ request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->base_cmds.smid = smid; ++ memcpy(request, mpi_request, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || ++ mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) ++ ioc->ioc_link_reset_in_progress = 1; ++ init_completion(&ioc->base_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, ++ msecs_to_jiffies(10000)); ++ if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || ++ mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) && ++ ioc->ioc_link_reset_in_progress) ++ ioc->ioc_link_reset_in_progress = 0; ++ if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SasIoUnitControlRequest_t)/4); ++ if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = true; ++ goto issue_host_reset; ++ } ++ if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) ++ memcpy(mpi_reply, ioc->base_cmds.reply, ++ sizeof(Mpi2SasIoUnitControlReply_t)); ++ else ++ memset(mpi_reply, 0, sizeof(Mpi2SasIoUnitControlReply_t)); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ goto out; ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ rc = -EFAULT; ++ out: ++ mutex_unlock(&ioc->base_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * mpt2sas_base_scsi_enclosure_processor - sending request to sep device ++ * @ioc: per adapter object ++ * @mpi_reply: the reply payload from FW ++ * @mpi_request: the request payload sent to FW ++ * ++ * The SCSI Enclosure Processor request message causes the IOC to ++ * communicate with SES devices to control LED status signals. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request) ++{ ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ bool issue_reset = false; ++ int rc; ++ void *request; ++ u16 wait_state_count; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mutex_lock(&ioc->base_cmds.mutex); ++ ++ if (ioc->base_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: base_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, ++ __func__, wait_state_count); ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->base_cmds.status = MPT3_CMD_PENDING; ++ request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->base_cmds.smid = smid; ++ memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); ++ init_completion(&ioc->base_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, ++ msecs_to_jiffies(10000)); ++ if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SepRequest_t)/4); ++ if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = false; ++ goto issue_host_reset; ++ } ++ if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) ++ memcpy(mpi_reply, ioc->base_cmds.reply, ++ sizeof(Mpi2SepReply_t)); ++ else ++ memset(mpi_reply, 0, sizeof(Mpi2SepReply_t)); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ goto out; ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ rc = -EFAULT; ++ out: ++ mutex_unlock(&ioc->base_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _base_get_port_facts - obtain port facts reply and save in ioc ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_get_port_facts(struct MPT3SAS_ADAPTER *ioc, int port, int sleep_flag) ++{ ++ Mpi2PortFactsRequest_t mpi_request; ++ Mpi2PortFactsReply_t mpi_reply; ++ struct mpt2sas_port_facts *pfacts; ++ int mpi_reply_sz, mpi_request_sz, r; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mpi_reply_sz = sizeof(Mpi2PortFactsReply_t); ++ mpi_request_sz = sizeof(Mpi2PortFactsRequest_t); ++ memset(&mpi_request, 0, mpi_request_sz); ++ mpi_request.Function = MPI2_FUNCTION_PORT_FACTS; ++ mpi_request.PortNumber = port; ++ r = _base_handshake_req_reply_wait(ioc, mpi_request_sz, ++ (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP); ++ ++ if (r != 0) { ++ pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", ++ ioc->name, __func__, r); ++ return r; ++ } ++ ++ pfacts = &ioc->pfacts[port]; ++ memset(pfacts, 0, sizeof(struct mpt2sas_port_facts)); ++ pfacts->PortNumber = mpi_reply.PortNumber; ++ pfacts->VP_ID = mpi_reply.VP_ID; ++ pfacts->VF_ID = mpi_reply.VF_ID; ++ pfacts->MaxPostedCmdBuffers = ++ le16_to_cpu(mpi_reply.MaxPostedCmdBuffers); ++ ++ return 0; ++} ++ ++/** ++ * _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL ++ * @ioc: per adapter object ++ * @timeout: ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_wait_for_iocstate(struct MPT3SAS_ADAPTER *ioc, int timeout, ++ int sleep_flag) ++{ ++ u32 ioc_state; ++ int rc; ++ ++ dinitprintk(ioc, printk(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->pci_error_recovery) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "%s: host in pci error recovery\n", ioc->name, __func__)); ++ return -EFAULT; ++ } ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ dhsprintk(ioc, printk(MPT3SAS_FMT "%s: ioc_state(0x%08x)\n", ++ ioc->name, __func__, ioc_state)); ++ ++ if (((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) || ++ (ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) ++ return 0; ++ ++ if (ioc_state & MPI2_DOORBELL_USED) { ++ dhsprintk(ioc, printk(MPT3SAS_FMT ++ "unexpected doorbell active!\n", ioc->name)); ++ goto issue_diag_reset; ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc, ioc_state & ++ MPI2_DOORBELL_DATA_MASK); ++ goto issue_diag_reset; ++ } ++ ++ ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, ++ timeout, sleep_flag); ++ if (ioc_state) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state)); ++ return -EFAULT; ++ } ++ ++ issue_diag_reset: ++ rc = _base_diag_reset(ioc, sleep_flag); ++ return rc; ++} ++ ++/** ++ * _base_get_ioc_facts - obtain ioc facts reply and save in ioc ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2IOCFactsRequest_t mpi_request; ++ Mpi2IOCFactsReply_t mpi_reply; ++ struct mpt2sas_facts *facts; ++ int mpi_reply_sz, mpi_request_sz, r; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ r = _base_wait_for_iocstate(ioc, 10, sleep_flag); ++ if (r) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "%s: failed getting to correct state\n", ++ ioc->name, __func__)); ++ return r; ++ } ++ mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); ++ mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t); ++ memset(&mpi_request, 0, mpi_request_sz); ++ mpi_request.Function = MPI2_FUNCTION_IOC_FACTS; ++ r = _base_handshake_req_reply_wait(ioc, mpi_request_sz, ++ (u32 *)&mpi_request, mpi_reply_sz, (u16 *)&mpi_reply, 5, CAN_SLEEP); ++ ++ if (r != 0) { ++ pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", ++ ioc->name, __func__, r); ++ return r; ++ } ++ ++ facts = &ioc->facts; ++ memset(facts, 0, sizeof(struct mpt2sas_facts)); ++ facts->MsgVersion = le16_to_cpu(mpi_reply.MsgVersion); ++ facts->HeaderVersion = le16_to_cpu(mpi_reply.HeaderVersion); ++ facts->VP_ID = mpi_reply.VP_ID; ++ facts->VF_ID = mpi_reply.VF_ID; ++ facts->IOCExceptions = le16_to_cpu(mpi_reply.IOCExceptions); ++ facts->MaxChainDepth = mpi_reply.MaxChainDepth; ++ facts->WhoInit = mpi_reply.WhoInit; ++ facts->NumberOfPorts = mpi_reply.NumberOfPorts; ++ facts->MaxMSIxVectors = mpi_reply.MaxMSIxVectors; ++ facts->RequestCredit = le16_to_cpu(mpi_reply.RequestCredit); ++ facts->MaxReplyDescriptorPostQueueDepth = ++ le16_to_cpu(mpi_reply.MaxReplyDescriptorPostQueueDepth); ++ facts->ProductID = le16_to_cpu(mpi_reply.ProductID); ++ facts->IOCCapabilities = le32_to_cpu(mpi_reply.IOCCapabilities); ++ if ((facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) ++ ioc->ir_firmware = 1; ++ if ((facts->IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE)) ++ ioc->rdpq_array_capable = 1; ++ facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); ++ facts->IOCRequestFrameSize = ++ le16_to_cpu(mpi_reply.IOCRequestFrameSize); ++ if (ioc->hba_mpi_version_belonged != MPI2_VERSION) { ++ facts->IOCMaxChainSegmentSize = ++ le16_to_cpu(mpi_reply.IOCMaxChainSegmentSize); ++ } ++ facts->MaxInitiators = le16_to_cpu(mpi_reply.MaxInitiators); ++ facts->MaxTargets = le16_to_cpu(mpi_reply.MaxTargets); ++ ioc->shost->max_id = -1; ++ facts->MaxSasExpanders = le16_to_cpu(mpi_reply.MaxSasExpanders); ++ facts->MaxEnclosures = le16_to_cpu(mpi_reply.MaxEnclosures); ++ facts->ProtocolFlags = le16_to_cpu(mpi_reply.ProtocolFlags); ++ facts->HighPriorityCredit = ++ le16_to_cpu(mpi_reply.HighPriorityCredit); ++ facts->ReplyFrameSize = mpi_reply.ReplyFrameSize; ++ facts->MaxDevHandle = le16_to_cpu(mpi_reply.MaxDevHandle); ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "hba queue depth(%d), max chains per io(%d)\n", ++ ioc->name, facts->RequestCredit, ++ facts->MaxChainDepth)); ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "request frame size(%d), reply frame size(%d)\n", ioc->name, ++ facts->IOCRequestFrameSize * 4, facts->ReplyFrameSize * 4)); ++ return 0; ++} ++ ++/** ++ * _base_send_ioc_init - send ioc_init to firmware ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2IOCInitRequest_t mpi_request; ++ Mpi2IOCInitReply_t mpi_reply; ++ int i, r = 0; ++ ktime_t current_time; ++ u16 ioc_status; ++ u32 reply_post_free_array_sz = 0; ++ Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL; ++ dma_addr_t reply_post_free_array_dma; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_IOC_INIT; ++ mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER; ++ mpi_request.VF_ID = 0; /* TODO */ ++ mpi_request.VP_ID = 0; ++ mpi_request.MsgVersion = cpu_to_le16(ioc->hba_mpi_version_belonged); ++ mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); ++ ++ if (_base_is_controller_msix_enabled(ioc)) ++ mpi_request.HostMSIxVectors = ioc->reply_queue_count; ++ mpi_request.SystemRequestFrameSize = cpu_to_le16(ioc->request_sz/4); ++ mpi_request.ReplyDescriptorPostQueueDepth = ++ cpu_to_le16(ioc->reply_post_queue_depth); ++ mpi_request.ReplyFreeQueueDepth = ++ cpu_to_le16(ioc->reply_free_queue_depth); ++ ++ mpi_request.SenseBufferAddressHigh = ++ cpu_to_le32((u64)ioc->sense_dma >> 32); ++ mpi_request.SystemReplyAddressHigh = ++ cpu_to_le32((u64)ioc->reply_dma >> 32); ++ mpi_request.SystemRequestFrameBaseAddress = ++ cpu_to_le64((u64)ioc->request_dma); ++ mpi_request.ReplyFreeQueueAddress = ++ cpu_to_le64((u64)ioc->reply_free_dma); ++ ++ if (ioc->rdpq_array_enable) { ++ reply_post_free_array_sz = ioc->reply_queue_count * ++ sizeof(Mpi2IOCInitRDPQArrayEntry); ++ reply_post_free_array = pci_alloc_consistent(ioc->pdev, ++ reply_post_free_array_sz, &reply_post_free_array_dma); ++ if (!reply_post_free_array) { ++ pr_err(MPT3SAS_FMT ++ "reply_post_free_array: pci_alloc_consistent failed\n", ++ ioc->name); ++ r = -ENOMEM; ++ goto out; ++ } ++ memset(reply_post_free_array, 0, reply_post_free_array_sz); ++ for (i = 0; i < ioc->reply_queue_count; i++) ++ reply_post_free_array[i].RDPQBaseAddress = ++ cpu_to_le64( ++ (u64)ioc->reply_post[i].reply_post_free_dma); ++ mpi_request.MsgFlags = MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE; ++ mpi_request.ReplyDescriptorPostQueueAddress = ++ cpu_to_le64((u64)reply_post_free_array_dma); ++ } else { ++ mpi_request.ReplyDescriptorPostQueueAddress = ++ cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma); ++ } ++ ++ /* This time stamp specifies number of milliseconds ++ * since epoch ~ midnight January 1, 1970. ++ */ ++ current_time = ktime_get_real(); ++ mpi_request.TimeStamp = cpu_to_le64(ktime_to_ms(current_time)); ++ ++ if (ioc->logging_level & MPT_DEBUG_INIT) { ++ __le32 *mfp; ++ int i; ++ ++ mfp = (__le32 *)&mpi_request; ++ pr_info("\toffset:data\n"); ++ for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) ++ pr_info("\t[0x%02x]:%08x\n", i*4, ++ le32_to_cpu(mfp[i])); ++ } ++ ++ r = _base_handshake_req_reply_wait(ioc, ++ sizeof(Mpi2IOCInitRequest_t), (u32 *)&mpi_request, ++ sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 10, ++ sleep_flag); ++ ++ if (r != 0) { ++ pr_err(MPT3SAS_FMT "%s: handshake failed (r=%d)\n", ++ ioc->name, __func__, r); ++ goto out; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS || ++ mpi_reply.IOCLogInfo) { ++ pr_err(MPT3SAS_FMT "%s: failed\n", ioc->name, __func__); ++ r = -EIO; ++ } ++ ++out: ++ if (reply_post_free_array) ++ pci_free_consistent(ioc->pdev, reply_post_free_array_sz, ++ reply_post_free_array, ++ reply_post_free_array_dma); ++ return r; ++} ++ ++/** ++ * mpt2sas_port_enable_done - command completion routine for port enable ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_port_enable_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ u16 ioc_status; ++ ++ if (ioc->port_enable_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (!mpi_reply) ++ return 1; ++ ++ if (mpi_reply->Function != MPI2_FUNCTION_PORT_ENABLE) ++ return 1; ++ ++ ioc->port_enable_cmds.status &= ~MPT3_CMD_PENDING; ++ ioc->port_enable_cmds.status |= MPT3_CMD_COMPLETE; ++ ioc->port_enable_cmds.status |= MPT3_CMD_REPLY_VALID; ++ memcpy(ioc->port_enable_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ ioc->port_enable_failed = 1; ++ ++ if (ioc->is_driver_loading) { ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ mpt2sas_port_enable_complete(ioc); ++ return 1; ++ } else { ++ ioc->start_scan_failed = ioc_status; ++ ioc->start_scan = 0; ++ return 1; ++ } ++ } ++ complete(&ioc->port_enable_cmds.done); ++ return 1; ++} ++ ++/** ++ * _base_send_port_enable - send port_enable(discovery stuff) to firmware ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_send_port_enable(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2PortEnableRequest_t *mpi_request; ++ Mpi2PortEnableReply_t *mpi_reply; ++ unsigned long timeleft; ++ int r = 0; ++ u16 smid; ++ u16 ioc_status; ++ ++ pr_info(MPT3SAS_FMT "sending port enable !!\n", ioc->name); ++ ++ if (ioc->port_enable_cmds.status & MPT3_CMD_PENDING) { ++ pr_err(MPT3SAS_FMT "%s: internal command already in use\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ ioc->port_enable_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->port_enable_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; ++ ++ init_completion(&ioc->port_enable_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done, ++ 300*HZ); ++ if (!(ioc->port_enable_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2PortEnableRequest_t)/4); ++ if (ioc->port_enable_cmds.status & MPT3_CMD_RESET) ++ r = -EFAULT; ++ else ++ r = -ETIME; ++ goto out; ++ } ++ ++ mpi_reply = ioc->port_enable_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "%s: failed with (ioc_status=0x%08x)\n", ++ ioc->name, __func__, ioc_status); ++ r = -EFAULT; ++ goto out; ++ } ++ ++ out: ++ ioc->port_enable_cmds.status = MPT3_CMD_NOT_USED; ++ pr_info(MPT3SAS_FMT "port enable: %s\n", ioc->name, ((r == 0) ? ++ "SUCCESS" : "FAILED")); ++ return r; ++} ++ ++/** ++ * mpt2sas_port_enable - initiate firmware discovery (don't wait for reply) ++ * @ioc: per adapter object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_port_enable(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2PortEnableRequest_t *mpi_request; ++ u16 smid; ++ ++ pr_info(MPT3SAS_FMT "sending port enable !!\n", ioc->name); ++ ++ if (ioc->port_enable_cmds.status & MPT3_CMD_PENDING) { ++ pr_err(MPT3SAS_FMT "%s: internal command already in use\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ ioc->port_enable_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->port_enable_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; ++ ++ mpt2sas_base_put_smid_default(ioc, smid); ++ return 0; ++} ++ ++/** ++ * _base_determine_wait_on_discovery - desposition ++ * @ioc: per adapter object ++ * ++ * Decide whether to wait on discovery to complete. Used to either ++ * locate boot device, or report volumes ahead of physical devices. ++ * ++ * Returns 1 for wait, 0 for don't wait ++ */ ++static int ++_base_determine_wait_on_discovery(struct MPT3SAS_ADAPTER *ioc) ++{ ++ /* We wait for discovery to complete if IR firmware is loaded. ++ * The sas topology events arrive before PD events, so we need time to ++ * turn on the bit in ioc->pd_handles to indicate PD ++ * Also, it maybe required to report Volumes ahead of physical ++ * devices when MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING is set. ++ */ ++ if (ioc->ir_firmware) ++ return 1; ++ ++ /* if no Bios, then we don't need to wait */ ++ if (!ioc->bios_pg3.BiosVersion) ++ return 0; ++ ++ /* Bios is present, then we drop down here. ++ * ++ * If there any entries in the Bios Page 2, then we wait ++ * for discovery to complete. ++ */ ++ ++ /* Current Boot Device */ ++ if ((ioc->bios_pg2.CurrentBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK) == ++ MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED && ++ /* Request Boot Device */ ++ (ioc->bios_pg2.ReqBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK) == ++ MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED && ++ /* Alternate Request Boot Device */ ++ (ioc->bios_pg2.ReqAltBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK) == ++ MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED) ++ return 0; ++ ++ return 1; ++} ++ ++/** ++ * _base_unmask_events - turn on notification for this event ++ * @ioc: per adapter object ++ * @event: firmware event ++ * ++ * The mask is stored in ioc->event_masks. ++ */ ++static void ++_base_unmask_events(struct MPT3SAS_ADAPTER *ioc, u16 event) ++{ ++ u32 desired_event; ++ ++ if (event >= 128) ++ return; ++ ++ desired_event = (1 << (event % 32)); ++ ++ if (event < 32) ++ ioc->event_masks[0] &= ~desired_event; ++ else if (event < 64) ++ ioc->event_masks[1] &= ~desired_event; ++ else if (event < 96) ++ ioc->event_masks[2] &= ~desired_event; ++ else if (event < 128) ++ ioc->event_masks[3] &= ~desired_event; ++} ++ ++/** ++ * _base_event_notification - send event notification ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_event_notification(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ Mpi2EventNotificationRequest_t *mpi_request; ++ unsigned long timeleft; ++ u16 smid; ++ int r = 0; ++ int i; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->base_cmds.status & MPT3_CMD_PENDING) { ++ pr_err(MPT3SAS_FMT "%s: internal command already in use\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ return -EAGAIN; ++ } ++ ioc->base_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->base_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2EventNotificationRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) ++ mpi_request->EventMasks[i] = ++ cpu_to_le32(ioc->event_masks[i]); ++ init_completion(&ioc->base_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); ++ if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2EventNotificationRequest_t)/4); ++ if (ioc->base_cmds.status & MPT3_CMD_RESET) ++ r = -EFAULT; ++ else ++ r = -ETIME; ++ } else ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s: complete\n", ++ ioc->name, __func__)); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ return r; ++} ++ ++/** ++ * mpt2sas_base_validate_event_type - validating event types ++ * @ioc: per adapter object ++ * @event: firmware event ++ * ++ * This will turn on firmware event notification when application ++ * ask for that event. We don't mask events that are already enabled. ++ */ ++void ++mpt2sas_base_validate_event_type(struct MPT3SAS_ADAPTER *ioc, u32 *event_type) ++{ ++ int i, j; ++ u32 event_mask, desired_event; ++ u8 send_update_to_fw; ++ ++ for (i = 0, send_update_to_fw = 0; i < ++ MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) { ++ event_mask = ~event_type[i]; ++ desired_event = 1; ++ for (j = 0; j < 32; j++) { ++ if (!(event_mask & desired_event) && ++ (ioc->event_masks[i] & desired_event)) { ++ ioc->event_masks[i] &= ~desired_event; ++ send_update_to_fw = 1; ++ } ++ desired_event = (desired_event << 1); ++ } ++ } ++ ++ if (!send_update_to_fw) ++ return; ++ ++ mutex_lock(&ioc->base_cmds.mutex); ++ _base_event_notification(ioc, CAN_SLEEP); ++ mutex_unlock(&ioc->base_cmds.mutex); ++} ++ ++/** ++ * _base_diag_reset - the "big hammer" start of day reset ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ u32 host_diagnostic; ++ u32 ioc_state; ++ u32 count; ++ u32 hcb_size; ++ ++ pr_info(MPT3SAS_FMT "sending diag reset !!\n", ioc->name); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT "clear interrupts\n", ++ ioc->name)); ++ ++ count = 0; ++ do { ++ /* Write magic sequence to WriteSequence register ++ * Loop until in diagnostic mode ++ */ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "write magic sequence\n", ioc->name)); ++ writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_1ST_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_2ND_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_3RD_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_4TH_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_5TH_KEY_VALUE, &ioc->chip->WriteSequence); ++ writel(MPI2_WRSEQ_6TH_KEY_VALUE, &ioc->chip->WriteSequence); ++ ++ /* wait 100 msec */ ++ if (sleep_flag == CAN_SLEEP) ++ msleep(100); ++ else ++ mdelay(100); ++ ++ if (count++ > 20) ++ goto out; ++ ++ host_diagnostic = readl(&ioc->chip->HostDiagnostic); ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "wrote magic sequence: count(%d), host_diagnostic(0x%08x)\n", ++ ioc->name, count, host_diagnostic)); ++ ++ } while ((host_diagnostic & MPI2_DIAG_DIAG_WRITE_ENABLE) == 0); ++ ++ hcb_size = readl(&ioc->chip->HCBSize); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT "diag reset: issued\n", ++ ioc->name)); ++ writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, ++ &ioc->chip->HostDiagnostic); ++ ++ /*This delay allows the chip PCIe hardware time to finish reset tasks*/ ++ if (sleep_flag == CAN_SLEEP) ++ msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); ++ else ++ mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); ++ ++ /* Approximately 300 second max wait */ ++ for (count = 0; count < (300000000 / ++ MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) { ++ ++ host_diagnostic = readl(&ioc->chip->HostDiagnostic); ++ ++ if (host_diagnostic == 0xFFFFFFFF) ++ goto out; ++ if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER)) ++ break; ++ ++ /* Wait to pass the second read delay window */ ++ if (sleep_flag == CAN_SLEEP) ++ msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC ++ / 1000); ++ else ++ mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC ++ / 1000); ++ } ++ ++ if (host_diagnostic & MPI2_DIAG_HCB_MODE) { ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "restart the adapter assuming the HCB Address points to good F/W\n", ++ ioc->name)); ++ host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK; ++ host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW; ++ writel(host_diagnostic, &ioc->chip->HostDiagnostic); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "re-enable the HCDW\n", ioc->name)); ++ writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE, ++ &ioc->chip->HCBSize); ++ } ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT "restart the adapter\n", ++ ioc->name)); ++ writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET, ++ &ioc->chip->HostDiagnostic); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "disable writes to the diagnostic register\n", ioc->name)); ++ writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &ioc->chip->WriteSequence); ++ ++ drsprintk(ioc, pr_info(MPT3SAS_FMT ++ "Wait for FW to go to the READY state\n", ioc->name)); ++ ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20, ++ sleep_flag); ++ if (ioc_state) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state); ++ goto out; ++ } ++ ++ pr_info(MPT3SAS_FMT "diag reset: SUCCESS\n", ioc->name); ++ return 0; ++ ++ out: ++ pr_err(MPT3SAS_FMT "diag reset: FAILED\n", ioc->name); ++ return -EFAULT; ++} ++ ++/** ++ * _base_make_ioc_ready - put controller in READY state ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * @type: FORCE_BIG_HAMMER or SOFT_RESET ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, ++ enum reset_type type) ++{ ++ u32 ioc_state; ++ int rc; ++ int count; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ if (ioc->pci_error_recovery) ++ return 0; ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT "%s: ioc_state(0x%08x)\n", ++ ioc->name, __func__, ioc_state)); ++ ++ /* if in RESET state, it should move to READY state shortly */ ++ count = 0; ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { ++ while ((ioc_state & MPI2_IOC_STATE_MASK) != ++ MPI2_IOC_STATE_READY) { ++ if (count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed going to ready state (ioc_state=0x%x)\n", ++ ioc->name, __func__, ioc_state); ++ return -EFAULT; ++ } ++ if (sleep_flag == CAN_SLEEP) ++ ssleep(1); ++ else ++ mdelay(1000); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ } ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) ++ return 0; ++ ++ if (ioc_state & MPI2_DOORBELL_USED) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "unexpected doorbell active!\n", ++ ioc->name)); ++ goto issue_diag_reset; ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc, ioc_state & ++ MPI2_DOORBELL_DATA_MASK); ++ goto issue_diag_reset; ++ } ++ ++ if (type == FORCE_BIG_HAMMER) ++ goto issue_diag_reset; ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) ++ if (!(_base_send_ioc_reset(ioc, ++ MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET, 15, CAN_SLEEP))) { ++ return 0; ++ } ++ ++ issue_diag_reset: ++ rc = _base_diag_reset(ioc, CAN_SLEEP); ++ return rc; ++} ++ ++/** ++ * _base_make_ioc_operational - put controller in OPERATIONAL state ++ * @ioc: per adapter object ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ int r, i, index; ++ unsigned long flags; ++ u32 reply_address; ++ u16 smid; ++ struct _tr_list *delayed_tr, *delayed_tr_next; ++ struct _sc_list *delayed_sc, *delayed_sc_next; ++ struct _event_ack_list *delayed_event_ack, *delayed_event_ack_next; ++ u8 hide_flag; ++ struct adapter_reply_queue *reply_q; ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free_contig; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ /* clean the delayed target reset list */ ++ list_for_each_entry_safe(delayed_tr, delayed_tr_next, ++ &ioc->delayed_tr_list, list) { ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ } ++ ++ ++ list_for_each_entry_safe(delayed_tr, delayed_tr_next, ++ &ioc->delayed_tr_volume_list, list) { ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ } ++ ++ list_for_each_entry_safe(delayed_sc, delayed_sc_next, ++ &ioc->delayed_sc_list, list) { ++ list_del(&delayed_sc->list); ++ kfree(delayed_sc); ++ } ++ ++ list_for_each_entry_safe(delayed_event_ack, delayed_event_ack_next, ++ &ioc->delayed_event_ack_list, list) { ++ list_del(&delayed_event_ack->list); ++ kfree(delayed_event_ack); ++ } ++ ++ /* initialize the scsi lookup free list */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ INIT_LIST_HEAD(&ioc->free_list); ++ smid = 1; ++ for (i = 0; i < ioc->scsiio_depth; i++, smid++) { ++ INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list); ++ ioc->scsi_lookup[i].cb_idx = 0xFF; ++ ioc->scsi_lookup[i].smid = smid; ++ ioc->scsi_lookup[i].scmd = NULL; ++ ioc->scsi_lookup[i].direct_io = 0; ++ list_add_tail(&ioc->scsi_lookup[i].tracker_list, ++ &ioc->free_list); ++ } ++ ++ /* hi-priority queue */ ++ INIT_LIST_HEAD(&ioc->hpr_free_list); ++ smid = ioc->hi_priority_smid; ++ for (i = 0; i < ioc->hi_priority_depth; i++, smid++) { ++ ioc->hpr_lookup[i].cb_idx = 0xFF; ++ ioc->hpr_lookup[i].smid = smid; ++ list_add_tail(&ioc->hpr_lookup[i].tracker_list, ++ &ioc->hpr_free_list); ++ } ++ ++ /* internal queue */ ++ INIT_LIST_HEAD(&ioc->internal_free_list); ++ smid = ioc->internal_smid; ++ for (i = 0; i < ioc->internal_depth; i++, smid++) { ++ ioc->internal_lookup[i].cb_idx = 0xFF; ++ ioc->internal_lookup[i].smid = smid; ++ list_add_tail(&ioc->internal_lookup[i].tracker_list, ++ &ioc->internal_free_list); ++ } ++ ++ /* chain pool */ ++ INIT_LIST_HEAD(&ioc->free_chain_list); ++ for (i = 0; i < ioc->chain_depth; i++) ++ list_add_tail(&ioc->chain_lookup[i].tracker_list, ++ &ioc->free_chain_list); ++ ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ /* initialize Reply Free Queue */ ++ for (i = 0, reply_address = (u32)ioc->reply_dma ; ++ i < ioc->reply_free_queue_depth ; i++, reply_address += ++ ioc->reply_sz) ++ ioc->reply_free[i] = cpu_to_le32(reply_address); ++ ++ /* initialize reply queues */ ++ if (ioc->is_driver_loading) ++ _base_assign_reply_queues(ioc); ++ ++ /* initialize Reply Post Free Queue */ ++ index = 0; ++ reply_post_free_contig = ioc->reply_post[0].reply_post_free; ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ /* ++ * If RDPQ is enabled, switch to the next allocation. ++ * Otherwise advance within the contiguous region. ++ */ ++ if (ioc->rdpq_array_enable) { ++ reply_q->reply_post_free = ++ ioc->reply_post[index++].reply_post_free; ++ } else { ++ reply_q->reply_post_free = reply_post_free_contig; ++ reply_post_free_contig += ioc->reply_post_queue_depth; ++ } ++ ++ reply_q->reply_post_host_index = 0; ++ for (i = 0; i < ioc->reply_post_queue_depth; i++) ++ reply_q->reply_post_free[i].Words = ++ cpu_to_le64(ULLONG_MAX); ++ if (!_base_is_controller_msix_enabled(ioc)) ++ goto skip_init_reply_post_free_queue; ++ } ++ skip_init_reply_post_free_queue: ++ ++ r = _base_send_ioc_init(ioc, sleep_flag); ++ if (r) ++ return r; ++ ++ /* initialize reply free host index */ ++ ioc->reply_free_host_index = ioc->reply_free_queue_depth - 1; ++ writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex); ++ ++ /* initialize reply post host index */ ++ list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { ++ if (ioc->msix96_vector) ++ writel((reply_q->msix_index & 7)<< ++ MPI2_RPHI_MSIX_INDEX_SHIFT, ++ ioc->replyPostRegisterIndex[reply_q->msix_index/8]); ++ else ++ writel(reply_q->msix_index << ++ MPI2_RPHI_MSIX_INDEX_SHIFT, ++ &ioc->chip->ReplyPostHostIndex); ++ ++ if (!_base_is_controller_msix_enabled(ioc)) ++ goto skip_init_reply_post_host_index; ++ } ++ ++ skip_init_reply_post_host_index: ++ ++ _base_unmask_interrupts(ioc); ++ r = _base_event_notification(ioc, sleep_flag); ++ if (r) ++ return r; ++ ++ if (sleep_flag == CAN_SLEEP) ++ _base_static_config_pages(ioc); ++ ++ ++ if (ioc->is_driver_loading) { ++ ++ if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier ++ == 0x80) { ++ hide_flag = (u8) ( ++ le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) & ++ MFG_PAGE10_HIDE_SSDS_MASK); ++ if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) ++ ioc->mfg_pg10_hide_flag = hide_flag; ++ } ++ ++ ioc->wait_for_discovery_to_complete = ++ _base_determine_wait_on_discovery(ioc); ++ ++ return r; /* scan_start and scan_finished support */ ++ } ++ ++ r = _base_send_port_enable(ioc, sleep_flag); ++ if (r) ++ return r; ++ ++ return r; ++} ++ ++/** ++ * mpt2sas_base_free_resources - free resources controller resources ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) ++{ ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ /* synchronizing freeing resource with pci_access_mutex lock */ ++ mutex_lock(&ioc->pci_access_mutex); ++ if (ioc->chip_phys && ioc->chip) { ++ _base_mask_interrupts(ioc); ++ ioc->shost_recovery = 1; ++ _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); ++ ioc->shost_recovery = 0; ++ } ++ ++ mpt2sas_base_unmap_resources(ioc); ++ mutex_unlock(&ioc->pci_access_mutex); ++ return; ++} ++ ++/** ++ * mpt2sas_base_attach - attach controller instance ++ * @ioc: per adapter object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int r, i; ++ int cpu_id, last_cpu_id = 0; ++ ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ /* setup cpu_msix_table */ ++ ioc->cpu_count = num_online_cpus(); ++ for_each_online_cpu(cpu_id) ++ last_cpu_id = cpu_id; ++ ioc->cpu_msix_table_sz = last_cpu_id + 1; ++ ioc->cpu_msix_table = kzalloc(ioc->cpu_msix_table_sz, GFP_KERNEL); ++ ioc->reply_queue_count = 1; ++ if (!ioc->cpu_msix_table) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT ++ "allocation for cpu_msix_table failed!!!\n", ++ ioc->name)); ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ if (ioc->is_warpdrive) { ++ ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz, ++ sizeof(resource_size_t *), GFP_KERNEL); ++ if (!ioc->reply_post_host_index) { ++ dfailprintk(ioc, pr_info(MPT3SAS_FMT "allocation " ++ "for cpu_msix_table failed!!!\n", ioc->name)); ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ } ++ ++ ioc->rdpq_array_enable_assigned = 0; ++ ioc->dma_mask = 0; ++ r = mpt2sas_base_map_resources(ioc); ++ if (r) ++ goto out_free_resources; ++ ++ if (ioc->is_warpdrive) { ++ ioc->reply_post_host_index[0] = (resource_size_t __iomem *) ++ &ioc->chip->ReplyPostHostIndex; ++ ++ for (i = 1; i < ioc->cpu_msix_table_sz; i++) ++ ioc->reply_post_host_index[i] = ++ (resource_size_t __iomem *) ++ ((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1) ++ * 4))); ++ } ++ ++ pci_set_drvdata(ioc->pdev, ioc->shost); ++ r = _base_get_ioc_facts(ioc, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ ioc->build_sg_scmd = &_base_build_sg_scmd; ++ ioc->build_sg = &_base_build_sg; ++ ioc->build_zero_len_sge = &_base_build_zero_len_sge; ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ /* ++ * In SAS3.0, ++ * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and ++ * Target Status - all require the IEEE formated scatter gather ++ * elements. ++ */ ++ ioc->build_sg_scmd = &_base_build_sg_scmd_ieee; ++ ioc->build_sg = &_base_build_sg_ieee; ++ ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; ++ ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); ++ break; ++ } ++ ++ /* ++ * These function pointers for other requests that don't ++ * the require IEEE scatter gather elements. ++ * ++ * For example Configuration Pages and SAS IOUNIT Control don't. ++ */ ++ ioc->build_sg_mpi = &_base_build_sg; ++ ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge; ++ ++ r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); ++ if (r) ++ goto out_free_resources; ++ ++ ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, ++ sizeof(struct mpt2sas_port_facts), GFP_KERNEL); ++ if (!ioc->pfacts) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) { ++ r = _base_get_port_facts(ioc, i, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ } ++ ++ r = _base_allocate_memory_pools(ioc, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ ++ init_waitqueue_head(&ioc->reset_wq); ++ ++ /* allocate memory pd handle bitmask list */ ++ ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); ++ if (ioc->facts.MaxDevHandle % 8) ++ ioc->pd_handles_sz++; ++ ioc->pd_handles = kzalloc(ioc->pd_handles_sz, ++ GFP_KERNEL); ++ if (!ioc->pd_handles) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ioc->blocking_handles = kzalloc(ioc->pd_handles_sz, ++ GFP_KERNEL); ++ if (!ioc->blocking_handles) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ ioc->fwfault_debug = mpt2sas_fwfault_debug; ++ ++ /* base internal command bits */ ++ mutex_init(&ioc->base_cmds.mutex); ++ ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ ++ /* port_enable command bits */ ++ ioc->port_enable_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->port_enable_cmds.status = MPT3_CMD_NOT_USED; ++ ++ /* transport internal command bits */ ++ ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->transport_cmds.mutex); ++ ++ /* scsih internal command bits */ ++ ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->scsih_cmds.mutex); ++ ++ /* task management internal command bits */ ++ ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->tm_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->tm_cmds.mutex); ++ ++ /* config page internal command bits */ ++ ioc->config_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->config_cmds.mutex); ++ ++ /* ctl module internal command bits */ ++ ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ++ ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_init(&ioc->ctl_cmds.mutex); ++ ++ if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || ++ !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || ++ !ioc->config_cmds.reply || !ioc->ctl_cmds.reply || ++ !ioc->ctl_cmds.sense) { ++ r = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) ++ ioc->event_masks[i] = -1; ++ ++ /* here we enable the events we care about */ ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_DISCOVERY); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_BROADCAST_PRIMITIVE); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE); ++ _base_unmask_events(ioc, MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_VOLUME); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); ++ _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); ++ _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); ++ _base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD); ++ if (ioc->hba_mpi_version_belonged == MPI26_VERSION) ++ _base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION); ++ ++ r = _base_make_ioc_operational(ioc, CAN_SLEEP); ++ if (r) ++ goto out_free_resources; ++ ++ ioc->non_operational_loop = 0; ++ return 0; ++ ++ out_free_resources: ++ ++ ioc->remove_host = 1; ++ ++ mpt2sas_base_free_resources(ioc); ++ _base_release_memory_pools(ioc); ++ pci_set_drvdata(ioc->pdev, NULL); ++ kfree(ioc->cpu_msix_table); ++ if (ioc->is_warpdrive) ++ kfree(ioc->reply_post_host_index); ++ kfree(ioc->pd_handles); ++ kfree(ioc->blocking_handles); ++ kfree(ioc->tm_cmds.reply); ++ kfree(ioc->transport_cmds.reply); ++ kfree(ioc->scsih_cmds.reply); ++ kfree(ioc->config_cmds.reply); ++ kfree(ioc->base_cmds.reply); ++ kfree(ioc->port_enable_cmds.reply); ++ kfree(ioc->ctl_cmds.reply); ++ kfree(ioc->ctl_cmds.sense); ++ kfree(ioc->pfacts); ++ ioc->ctl_cmds.reply = NULL; ++ ioc->base_cmds.reply = NULL; ++ ioc->tm_cmds.reply = NULL; ++ ioc->scsih_cmds.reply = NULL; ++ ioc->transport_cmds.reply = NULL; ++ ioc->config_cmds.reply = NULL; ++ ioc->pfacts = NULL; ++ return r; ++} ++ ++ ++/** ++ * mpt2sas_base_detach - remove controller instance ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_base_detach(struct MPT3SAS_ADAPTER *ioc) ++{ ++ dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ mpt2sas_base_stop_watchdog(ioc); ++ mpt2sas_base_free_resources(ioc); ++ _base_release_memory_pools(ioc); ++ pci_set_drvdata(ioc->pdev, NULL); ++ kfree(ioc->cpu_msix_table); ++ if (ioc->is_warpdrive) ++ kfree(ioc->reply_post_host_index); ++ kfree(ioc->pd_handles); ++ kfree(ioc->blocking_handles); ++ kfree(ioc->pfacts); ++ kfree(ioc->ctl_cmds.reply); ++ kfree(ioc->ctl_cmds.sense); ++ kfree(ioc->base_cmds.reply); ++ kfree(ioc->port_enable_cmds.reply); ++ kfree(ioc->tm_cmds.reply); ++ kfree(ioc->transport_cmds.reply); ++ kfree(ioc->scsih_cmds.reply); ++ kfree(ioc->config_cmds.reply); ++} ++ ++/** ++ * _base_reset_handler - reset callback handler (for base) ++ * @ioc: per adapter object ++ * @reset_phase: phase ++ * ++ * The handler for doing any required cleanup or initialization. ++ * ++ * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET, ++ * MPT3_IOC_DONE_RESET ++ * ++ * Return nothing. ++ */ ++static void ++_base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) ++{ ++ mpt2sas_scsih_reset_handler(ioc, reset_phase); ++ mpt2sas_ctl_reset_handler(ioc, reset_phase); ++ switch (reset_phase) { ++ case MPT3_IOC_PRE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__)); ++ break; ++ case MPT3_IOC_AFTER_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__)); ++ if (ioc->transport_cmds.status & MPT3_CMD_PENDING) { ++ ioc->transport_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->transport_cmds.smid); ++ complete(&ioc->transport_cmds.done); ++ } ++ if (ioc->base_cmds.status & MPT3_CMD_PENDING) { ++ ioc->base_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid); ++ complete(&ioc->base_cmds.done); ++ } ++ if (ioc->port_enable_cmds.status & MPT3_CMD_PENDING) { ++ ioc->port_enable_failed = 1; ++ ioc->port_enable_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->port_enable_cmds.smid); ++ if (ioc->is_driver_loading) { ++ ioc->start_scan_failed = ++ MPI2_IOCSTATUS_INTERNAL_ERROR; ++ ioc->start_scan = 0; ++ ioc->port_enable_cmds.status = ++ MPT3_CMD_NOT_USED; ++ } else ++ complete(&ioc->port_enable_cmds.done); ++ } ++ if (ioc->config_cmds.status & MPT3_CMD_PENDING) { ++ ioc->config_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); ++ ioc->config_cmds.smid = USHRT_MAX; ++ complete(&ioc->config_cmds.done); ++ } ++ break; ++ case MPT3_IOC_DONE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__)); ++ break; ++ } ++} ++ ++/** ++ * _wait_for_commands_to_complete - reset controller ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * ++ * This function waiting(3s) for all pending commands to complete ++ * prior to putting controller in reset. ++ */ ++static void ++_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ++{ ++ u32 ioc_state; ++ unsigned long flags; ++ u16 i; ++ ++ ioc->pending_io_count = 0; ++ if (sleep_flag != CAN_SLEEP) ++ return; ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((ioc_state & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) ++ return; ++ ++ /* pending command count */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ for (i = 0; i < ioc->scsiio_depth; i++) ++ if (ioc->scsi_lookup[i].cb_idx != 0xFF) ++ ioc->pending_io_count++; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ if (!ioc->pending_io_count) ++ return; ++ ++ /* wait for pending commands to complete */ ++ wait_event_timeout(ioc->reset_wq, ioc->pending_io_count == 0, 10 * HZ); ++} ++ ++/** ++ * mpt2sas_base_hard_reset_handler - reset controller ++ * @ioc: Pointer to MPT_ADAPTER structure ++ * @sleep_flag: CAN_SLEEP or NO_SLEEP ++ * @type: FORCE_BIG_HAMMER or SOFT_RESET ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, ++ enum reset_type type) ++{ ++ int r; ++ unsigned long flags; ++ u32 ioc_state; ++ u8 is_fault = 0, is_trigger = 0; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ if (ioc->pci_error_recovery) { ++ pr_err(MPT3SAS_FMT "%s: pci error recovery reset\n", ++ ioc->name, __func__); ++ r = 0; ++ goto out_unlocked; ++ } ++ ++ if (mpt2sas_fwfault_debug) ++ mpt2sas_halt_firmware(ioc); ++ ++ /* TODO - What we really should be doing is pulling ++ * out all the code associated with NO_SLEEP; its never used. ++ * That is legacy code from mpt fusion driver, ported over. ++ * I will leave this BUG_ON here for now till its been resolved. ++ */ ++ BUG_ON(sleep_flag == NO_SLEEP); ++ ++ /* wait for an active reset in progress to complete */ ++ if (!mutex_trylock(&ioc->reset_in_progress_mutex)) { ++ do { ++ ssleep(1); ++ } while (ioc->shost_recovery == 1); ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++ return ioc->ioc_reset_in_progress_status; ++ } ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ ioc->shost_recovery = 1; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) && ++ (!(ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED))) { ++ is_trigger = 1; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) ++ is_fault = 1; ++ } ++ _base_reset_handler(ioc, MPT3_IOC_PRE_RESET); ++ _wait_for_commands_to_complete(ioc, sleep_flag); ++ _base_mask_interrupts(ioc); ++ r = _base_make_ioc_ready(ioc, sleep_flag, type); ++ if (r) ++ goto out; ++ _base_reset_handler(ioc, MPT3_IOC_AFTER_RESET); ++ ++ /* If this hard reset is called while port enable is active, then ++ * there is no reason to call make_ioc_operational ++ */ ++ if (ioc->is_driver_loading && ioc->port_enable_failed) { ++ ioc->remove_host = 1; ++ r = -EFAULT; ++ goto out; ++ } ++ r = _base_get_ioc_facts(ioc, CAN_SLEEP); ++ if (r) ++ goto out; ++ ++ if (ioc->rdpq_array_enable && !ioc->rdpq_array_capable) ++ panic("%s: Issue occurred with flashing controller firmware." ++ "Please reboot the system and ensure that the correct" ++ " firmware version is running\n", ioc->name); ++ ++ r = _base_make_ioc_operational(ioc, sleep_flag); ++ if (!r) ++ _base_reset_handler(ioc, MPT3_IOC_DONE_RESET); ++ ++ out: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: %s\n", ++ ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED"))); ++ ++ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ++ ioc->ioc_reset_in_progress_status = r; ++ ioc->shost_recovery = 0; ++ spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ++ ioc->ioc_reset_count++; ++ mutex_unlock(&ioc->reset_in_progress_mutex); ++ ++ out_unlocked: ++ if ((r == 0) && is_trigger) { ++ if (is_fault) ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_FW_FAULT); ++ else ++ mpt2sas_trigger_master(ioc, ++ MASTER_TRIGGER_ADAPTER_RESET); ++ } ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++ return r; ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_base.h b/drivers/scsi/mpt2sas/mpt3sas_base.h +new file mode 100644 +index 0000000..a580770 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_base.h +@@ -0,0 +1,1462 @@ ++/* ++ * This is the Fusion MPT base driver providing common API layer interface ++ * for access to MPT (Message Passing Technology) firmware. ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#ifndef MPT3SAS_BASE_H_INCLUDED ++#define MPT3SAS_BASE_H_INCLUDED ++ ++#include "mpi/mpi2_type.h" ++#include "mpi/mpi2.h" ++#include "mpi/mpi2_ioc.h" ++#include "mpi/mpi2_cnfg.h" ++#include "mpi/mpi2_init.h" ++#include "mpi/mpi2_raid.h" ++#include "mpi/mpi2_tool.h" ++#include "mpi/mpi2_sas.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_debug.h" ++#include "mpt3sas_trigger_diag.h" ++ ++/* driver versioning info */ ++#define MPT3SAS_DRIVER_NAME "mpt3sas" ++#define MPT3SAS_AUTHOR "Avago Technologies " ++#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" ++#define MPT3SAS_DRIVER_VERSION "13.100.00.00" ++#define MPT3SAS_MAJOR_VERSION 13 ++#define MPT3SAS_MINOR_VERSION 100 ++#define MPT3SAS_BUILD_VERSION 0 ++#define MPT3SAS_RELEASE_VERSION 00 ++ ++#define MPT2SAS_DRIVER_NAME "mpt2sas" ++#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" ++#define MPT2SAS_DRIVER_VERSION "20.102.00.00" ++#define MPT2SAS_MAJOR_VERSION 20 ++#define MPT2SAS_MINOR_VERSION 102 ++#define MPT2SAS_BUILD_VERSION 0 ++#define MPT2SAS_RELEASE_VERSION 00 ++ ++/* ++ * Set MPT3SAS_SG_DEPTH value based on user input. ++ */ ++#define MPT_MAX_PHYS_SEGMENTS SCSI_MAX_SG_SEGMENTS ++#define MPT_MIN_PHYS_SEGMENTS 16 ++ ++#ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE ++#define MPT3SAS_SG_DEPTH CONFIG_SCSI_MPT3SAS_MAX_SGE ++#else ++#define MPT3SAS_SG_DEPTH MPT_MAX_PHYS_SEGMENTS ++#endif ++ ++#ifdef CONFIG_SCSI_MPT2SAS_MAX_SGE ++#define MPT2SAS_SG_DEPTH CONFIG_SCSI_MPT2SAS_MAX_SGE ++#else ++#define MPT2SAS_SG_DEPTH MPT_MAX_PHYS_SEGMENTS ++#endif ++ ++/* ++ * Generic Defines ++ */ ++#define MPT3SAS_SATA_QUEUE_DEPTH 32 ++#define MPT3SAS_SAS_QUEUE_DEPTH 254 ++#define MPT3SAS_RAID_QUEUE_DEPTH 128 ++ ++#define MPT3SAS_RAID_MAX_SECTORS 8192 ++ ++#define MPT_NAME_LENGTH 32 /* generic length of strings */ ++#define MPT_STRING_LENGTH 64 ++ ++#define MPT_MAX_CALLBACKS 32 ++ ++ ++#define CAN_SLEEP 1 ++#define NO_SLEEP 0 ++ ++#define INTERNAL_CMDS_COUNT 10 /* reserved cmds */ ++/* reserved for issuing internally framed scsi io cmds */ ++#define INTERNAL_SCSIIO_CMDS_COUNT 3 ++ ++#define MPI3_HIM_MASK 0xFFFFFFFF /* mask every bit*/ ++ ++#define MPT3SAS_INVALID_DEVICE_HANDLE 0xFFFF ++ ++#define MAX_CHAIN_ELEMT_SZ 16 ++#define DEFAULT_NUM_FWCHAIN_ELEMTS 8 ++ ++/* ++ * reset phases ++ */ ++#define MPT3_IOC_PRE_RESET 1 /* prior to host reset */ ++#define MPT3_IOC_AFTER_RESET 2 /* just after host reset */ ++#define MPT3_IOC_DONE_RESET 3 /* links re-initialized */ ++ ++/* ++ * logging format ++ */ ++#define MPT3SAS_FMT "%s: " ++ ++/* ++ * WarpDrive Specific Log codes ++ */ ++ ++#define MPT2_WARPDRIVE_LOGENTRY (0x8002) ++#define MPT2_WARPDRIVE_LC_SSDT (0x41) ++#define MPT2_WARPDRIVE_LC_SSDLW (0x43) ++#define MPT2_WARPDRIVE_LC_SSDLF (0x44) ++#define MPT2_WARPDRIVE_LC_BRMF (0x4D) ++ ++/* ++ * per target private data ++ */ ++#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 ++#define MPT_TARGET_FLAGS_VOLUME 0x02 ++#define MPT_TARGET_FLAGS_DELETED 0x04 ++#define MPT_TARGET_FASTPATH_IO 0x08 ++ ++#define SAS2_PCI_DEVICE_B0_REVISION (0x01) ++#define SAS3_PCI_DEVICE_C0_REVISION (0x02) ++ ++/* ++ * Intel HBA branding ++ */ ++#define MPT2SAS_INTEL_RMS25JB080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25JB080" ++#define MPT2SAS_INTEL_RMS25JB040_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25JB040" ++#define MPT2SAS_INTEL_RMS25KB080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25KB080" ++#define MPT2SAS_INTEL_RMS25KB040_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25KB040" ++#define MPT2SAS_INTEL_RMS25LB040_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25LB040" ++#define MPT2SAS_INTEL_RMS25LB080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS25LB080" ++#define MPT2SAS_INTEL_RMS2LL080_BRANDING \ ++ "Intel Integrated RAID Module RMS2LL080" ++#define MPT2SAS_INTEL_RMS2LL040_BRANDING \ ++ "Intel Integrated RAID Module RMS2LL040" ++#define MPT2SAS_INTEL_RS25GB008_BRANDING \ ++ "Intel(R) RAID Controller RS25GB008" ++#define MPT2SAS_INTEL_SSD910_BRANDING \ ++ "Intel(R) SSD 910 Series" ++ ++#define MPT3SAS_INTEL_RMS3JC080_BRANDING \ ++ "Intel(R) Integrated RAID Module RMS3JC080" ++#define MPT3SAS_INTEL_RS3GC008_BRANDING \ ++ "Intel(R) RAID Controller RS3GC008" ++#define MPT3SAS_INTEL_RS3FC044_BRANDING \ ++ "Intel(R) RAID Controller RS3FC044" ++#define MPT3SAS_INTEL_RS3UC080_BRANDING \ ++ "Intel(R) RAID Controller RS3UC080" ++ ++/* ++ * Intel HBA SSDIDs ++ */ ++#define MPT2SAS_INTEL_RMS25JB080_SSDID 0x3516 ++#define MPT2SAS_INTEL_RMS25JB040_SSDID 0x3517 ++#define MPT2SAS_INTEL_RMS25KB080_SSDID 0x3518 ++#define MPT2SAS_INTEL_RMS25KB040_SSDID 0x3519 ++#define MPT2SAS_INTEL_RMS25LB040_SSDID 0x351A ++#define MPT2SAS_INTEL_RMS25LB080_SSDID 0x351B ++#define MPT2SAS_INTEL_RMS2LL080_SSDID 0x350E ++#define MPT2SAS_INTEL_RMS2LL040_SSDID 0x350F ++#define MPT2SAS_INTEL_RS25GB008_SSDID 0x3000 ++#define MPT2SAS_INTEL_SSD910_SSDID 0x3700 ++ ++#define MPT3SAS_INTEL_RMS3JC080_SSDID 0x3521 ++#define MPT3SAS_INTEL_RS3GC008_SSDID 0x3522 ++#define MPT3SAS_INTEL_RS3FC044_SSDID 0x3523 ++#define MPT3SAS_INTEL_RS3UC080_SSDID 0x3524 ++ ++/* ++ * Dell HBA branding ++ */ ++#define MPT2SAS_DELL_BRANDING_SIZE 32 ++ ++#define MPT2SAS_DELL_6GBPS_SAS_HBA_BRANDING "Dell 6Gbps SAS HBA" ++#define MPT2SAS_DELL_PERC_H200_ADAPTER_BRANDING "Dell PERC H200 Adapter" ++#define MPT2SAS_DELL_PERC_H200_INTEGRATED_BRANDING "Dell PERC H200 Integrated" ++#define MPT2SAS_DELL_PERC_H200_MODULAR_BRANDING "Dell PERC H200 Modular" ++#define MPT2SAS_DELL_PERC_H200_EMBEDDED_BRANDING "Dell PERC H200 Embedded" ++#define MPT2SAS_DELL_PERC_H200_BRANDING "Dell PERC H200" ++#define MPT2SAS_DELL_6GBPS_SAS_BRANDING "Dell 6Gbps SAS" ++ ++#define MPT3SAS_DELL_12G_HBA_BRANDING \ ++ "Dell 12Gbps HBA" ++ ++/* ++ * Dell HBA SSDIDs ++ */ ++#define MPT2SAS_DELL_6GBPS_SAS_HBA_SSDID 0x1F1C ++#define MPT2SAS_DELL_PERC_H200_ADAPTER_SSDID 0x1F1D ++#define MPT2SAS_DELL_PERC_H200_INTEGRATED_SSDID 0x1F1E ++#define MPT2SAS_DELL_PERC_H200_MODULAR_SSDID 0x1F1F ++#define MPT2SAS_DELL_PERC_H200_EMBEDDED_SSDID 0x1F20 ++#define MPT2SAS_DELL_PERC_H200_SSDID 0x1F21 ++#define MPT2SAS_DELL_6GBPS_SAS_SSDID 0x1F22 ++ ++#define MPT3SAS_DELL_12G_HBA_SSDID 0x1F46 ++ ++/* ++ * Cisco HBA branding ++ */ ++#define MPT3SAS_CISCO_12G_8E_HBA_BRANDING \ ++ "Cisco 9300-8E 12G SAS HBA" ++#define MPT3SAS_CISCO_12G_8I_HBA_BRANDING \ ++ "Cisco 9300-8i 12G SAS HBA" ++#define MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING \ ++ "Cisco 12G Modular SAS Pass through Controller" ++#define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING \ ++ "UCS C3X60 12G SAS Pass through Controller" ++/* ++ * Cisco HBA SSSDIDs ++ */ ++#define MPT3SAS_CISCO_12G_8E_HBA_SSDID 0x14C ++#define MPT3SAS_CISCO_12G_8I_HBA_SSDID 0x154 ++#define MPT3SAS_CISCO_12G_AVILA_HBA_SSDID 0x155 ++#define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID 0x156 ++ ++/* ++ * status bits for ioc->diag_buffer_status ++ */ ++#define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01) ++#define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) ++#define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) ++ ++/* ++ * HP HBA branding ++ */ ++#define MPT2SAS_HP_3PAR_SSVID 0x1590 ++ ++#define MPT2SAS_HP_2_4_INTERNAL_BRANDING \ ++ "HP H220 Host Bus Adapter" ++#define MPT2SAS_HP_2_4_EXTERNAL_BRANDING \ ++ "HP H221 Host Bus Adapter" ++#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_BRANDING \ ++ "HP H222 Host Bus Adapter" ++#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_BRANDING \ ++ "HP H220i Host Bus Adapter" ++#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_BRANDING \ ++ "HP H210i Host Bus Adapter" ++ ++/* ++ * HO HBA SSDIDs ++ */ ++#define MPT2SAS_HP_2_4_INTERNAL_SSDID 0x0041 ++#define MPT2SAS_HP_2_4_EXTERNAL_SSDID 0x0042 ++#define MPT2SAS_HP_1_4_INTERNAL_1_4_EXTERNAL_SSDID 0x0043 ++#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID 0x0044 ++#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 ++ ++/* ++ * Combined Reply Queue constants, ++ * There are twelve Supplemental Reply Post Host Index Registers ++ * and each register is at offset 0x10 bytes from the previous one. ++ */ ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT 12 ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10) ++ ++/* OEM Identifiers */ ++#define MFG10_OEM_ID_INVALID (0x00000000) ++#define MFG10_OEM_ID_DELL (0x00000001) ++#define MFG10_OEM_ID_FSC (0x00000002) ++#define MFG10_OEM_ID_SUN (0x00000003) ++#define MFG10_OEM_ID_IBM (0x00000004) ++ ++/* GENERIC Flags 0*/ ++#define MFG10_GF0_OCE_DISABLED (0x00000001) ++#define MFG10_GF0_R1E_DRIVE_COUNT (0x00000002) ++#define MFG10_GF0_R10_DISPLAY (0x00000004) ++#define MFG10_GF0_SSD_DATA_SCRUB_DISABLE (0x00000008) ++#define MFG10_GF0_SINGLE_DRIVE_R0 (0x00000010) ++ ++#define VIRTUAL_IO_FAILED_RETRY (0x32010081) ++ ++/* OEM Specific Flags will come from OEM specific header files */ ++struct Mpi2ManufacturingPage10_t { ++ MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ ++ U8 OEMIdentifier; /* 04h */ ++ U8 Reserved1; /* 05h */ ++ U16 Reserved2; /* 08h */ ++ U32 Reserved3; /* 0Ch */ ++ U32 GenericFlags0; /* 10h */ ++ U32 GenericFlags1; /* 14h */ ++ U32 Reserved4; /* 18h */ ++ U32 OEMSpecificFlags0; /* 1Ch */ ++ U32 OEMSpecificFlags1; /* 20h */ ++ U32 Reserved5[18]; /* 24h - 60h*/ ++}; ++ ++ ++/* Miscellaneous options */ ++struct Mpi2ManufacturingPage11_t { ++ MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ ++ __le32 Reserved1; /* 04h */ ++ u8 Reserved2; /* 08h */ ++ u8 EEDPTagMode; /* 09h */ ++ u8 Reserved3; /* 0Ah */ ++ u8 Reserved4; /* 0Bh */ ++ __le32 Reserved5[23]; /* 0Ch-60h*/ ++}; ++ ++/** ++ * struct MPT3SAS_TARGET - starget private hostdata ++ * @starget: starget object ++ * @sas_address: target sas address ++ * @raid_device: raid_device pointer to access volume data ++ * @handle: device handle ++ * @num_luns: number luns ++ * @flags: MPT_TARGET_FLAGS_XXX flags ++ * @deleted: target flaged for deletion ++ * @tm_busy: target is busy with TM request. ++ * @sdev: The sas_device associated with this target ++ */ ++struct MPT3SAS_TARGET { ++ struct scsi_target *starget; ++ u64 sas_address; ++ struct _raid_device *raid_device; ++ u16 handle; ++ int num_luns; ++ u32 flags; ++ u8 deleted; ++ u8 tm_busy; ++ struct _sas_device *sdev; ++}; ++ ++ ++/* ++ * per device private data ++ */ ++#define MPT_DEVICE_FLAGS_INIT 0x01 ++#define MPT_DEVICE_TLR_ON 0x02 ++ ++#define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003) ++#define MFG_PAGE10_HIDE_ALL_DISKS (0x00) ++#define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01) ++#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02) ++ ++/** ++ * struct MPT3SAS_DEVICE - sdev private hostdata ++ * @sas_target: starget private hostdata ++ * @lun: lun number ++ * @flags: MPT_DEVICE_XXX flags ++ * @configured_lun: lun is configured ++ * @block: device is in SDEV_BLOCK state ++ * @tlr_snoop_check: flag used in determining whether to disable TLR ++ * @eedp_enable: eedp support enable bit ++ * @eedp_type: 0(type_1), 1(type_2), 2(type_3) ++ * @eedp_block_length: block size ++ */ ++struct MPT3SAS_DEVICE { ++ struct MPT3SAS_TARGET *sas_target; ++ unsigned int lun; ++ u32 flags; ++ u8 configured_lun; ++ u8 block; ++ u8 tlr_snoop_check; ++ u8 ignore_delay_remove; ++}; ++ ++#define MPT3_CMD_NOT_USED 0x8000 /* free */ ++#define MPT3_CMD_COMPLETE 0x0001 /* completed */ ++#define MPT3_CMD_PENDING 0x0002 /* pending */ ++#define MPT3_CMD_REPLY_VALID 0x0004 /* reply is valid */ ++#define MPT3_CMD_RESET 0x0008 /* host reset dropped the command */ ++ ++/** ++ * struct _internal_cmd - internal commands struct ++ * @mutex: mutex ++ * @done: completion ++ * @reply: reply message pointer ++ * @sense: sense data ++ * @status: MPT3_CMD_XXX status ++ * @smid: system message id ++ */ ++struct _internal_cmd { ++ struct mutex mutex; ++ struct completion done; ++ void *reply; ++ void *sense; ++ u16 status; ++ u16 smid; ++}; ++ ++ ++ ++/** ++ * struct _sas_device - attached device information ++ * @list: sas device list ++ * @starget: starget object ++ * @sas_address: device sas address ++ * @device_name: retrieved from the SAS IDENTIFY frame. ++ * @handle: device handle ++ * @sas_address_parent: sas address of parent expander or sas host ++ * @enclosure_handle: enclosure handle ++ * @enclosure_logical_id: enclosure logical identifier ++ * @volume_handle: volume handle (valid when hidden raid member) ++ * @volume_wwid: volume unique identifier ++ * @device_info: bitfield provides detailed info about the device ++ * @id: target id ++ * @channel: target channel ++ * @slot: number number ++ * @phy: phy identifier provided in sas device page 0 ++ * @responding: used in _scsih_sas_device_mark_responding ++ * @fast_path: fast path feature enable bit ++ * @pfa_led_on: flag for PFA LED status ++ * @pend_sas_rphy_add: flag to check if device is in sas_rphy_add() ++ * addition routine. ++ */ ++struct _sas_device { ++ struct list_head list; ++ struct scsi_target *starget; ++ u64 sas_address; ++ u64 device_name; ++ u16 handle; ++ u64 sas_address_parent; ++ u16 enclosure_handle; ++ u64 enclosure_logical_id; ++ u16 volume_handle; ++ u64 volume_wwid; ++ u32 device_info; ++ int id; ++ int channel; ++ u16 slot; ++ u8 phy; ++ u8 responding; ++ u8 fast_path; ++ u8 pfa_led_on; ++ u8 pend_sas_rphy_add; ++ u8 enclosure_level; ++ u8 connector_name[4]; ++ struct kref refcount; ++}; ++ ++static inline void sas_device_get(struct _sas_device *s) ++{ ++ kref_get(&s->refcount); ++} ++ ++static inline void sas_device_free(struct kref *r) ++{ ++ kfree(container_of(r, struct _sas_device, refcount)); ++} ++ ++static inline void sas_device_put(struct _sas_device *s) ++{ ++ kref_put(&s->refcount, sas_device_free); ++} ++ ++/** ++ * struct _raid_device - raid volume link list ++ * @list: sas device list ++ * @starget: starget object ++ * @sdev: scsi device struct (volumes are single lun) ++ * @wwid: unique identifier for the volume ++ * @handle: device handle ++ * @block_size: Block size of the volume ++ * @id: target id ++ * @channel: target channel ++ * @volume_type: the raid level ++ * @device_info: bitfield provides detailed info about the hidden components ++ * @num_pds: number of hidden raid components ++ * @responding: used in _scsih_raid_device_mark_responding ++ * @percent_complete: resync percent complete ++ * @direct_io_enabled: Whether direct io to PDs are allowed or not ++ * @stripe_exponent: X where 2powX is the stripe sz in blocks ++ * @block_exponent: X where 2powX is the block sz in bytes ++ * @max_lba: Maximum number of LBA in the volume ++ * @stripe_sz: Stripe Size of the volume ++ * @device_info: Device info of the volume member disk ++ * @pd_handle: Array of handles of the physical drives for direct I/O in le16 ++ */ ++#define MPT_MAX_WARPDRIVE_PDS 8 ++struct _raid_device { ++ struct list_head list; ++ struct scsi_target *starget; ++ struct scsi_device *sdev; ++ u64 wwid; ++ u16 handle; ++ u16 block_sz; ++ int id; ++ int channel; ++ u8 volume_type; ++ u8 num_pds; ++ u8 responding; ++ u8 percent_complete; ++ u8 direct_io_enabled; ++ u8 stripe_exponent; ++ u8 block_exponent; ++ u64 max_lba; ++ u32 stripe_sz; ++ u32 device_info; ++ u16 pd_handle[MPT_MAX_WARPDRIVE_PDS]; ++}; ++ ++/** ++ * struct _boot_device - boot device info ++ * @is_raid: flag to indicate whether this is volume ++ * @device: holds pointer for either struct _sas_device or ++ * struct _raid_device ++ */ ++struct _boot_device { ++ u8 is_raid; ++ void *device; ++}; ++ ++/** ++ * struct _sas_port - wide/narrow sas port information ++ * @port_list: list of ports belonging to expander ++ * @num_phys: number of phys belonging to this port ++ * @remote_identify: attached device identification ++ * @rphy: sas transport rphy object ++ * @port: sas transport wide/narrow port object ++ * @phy_list: _sas_phy list objects belonging to this port ++ */ ++struct _sas_port { ++ struct list_head port_list; ++ u8 num_phys; ++ struct sas_identify remote_identify; ++ struct sas_rphy *rphy; ++ struct sas_port *port; ++ struct list_head phy_list; ++}; ++ ++/** ++ * struct _sas_phy - phy information ++ * @port_siblings: list of phys belonging to a port ++ * @identify: phy identification ++ * @remote_identify: attached device identification ++ * @phy: sas transport phy object ++ * @phy_id: unique phy id ++ * @handle: device handle for this phy ++ * @attached_handle: device handle for attached device ++ * @phy_belongs_to_port: port has been created for this phy ++ */ ++struct _sas_phy { ++ struct list_head port_siblings; ++ struct sas_identify identify; ++ struct sas_identify remote_identify; ++ struct sas_phy *phy; ++ u8 phy_id; ++ u16 handle; ++ u16 attached_handle; ++ u8 phy_belongs_to_port; ++}; ++ ++/** ++ * struct _sas_node - sas_host/expander information ++ * @list: list of expanders ++ * @parent_dev: parent device class ++ * @num_phys: number phys belonging to this sas_host/expander ++ * @sas_address: sas address of this sas_host/expander ++ * @handle: handle for this sas_host/expander ++ * @sas_address_parent: sas address of parent expander or sas host ++ * @enclosure_handle: handle for this a member of an enclosure ++ * @device_info: bitwise defining capabilities of this sas_host/expander ++ * @responding: used in _scsih_expander_device_mark_responding ++ * @phy: a list of phys that make up this sas_host/expander ++ * @sas_port_list: list of ports attached to this sas_host/expander ++ */ ++struct _sas_node { ++ struct list_head list; ++ struct device *parent_dev; ++ u8 num_phys; ++ u64 sas_address; ++ u16 handle; ++ u64 sas_address_parent; ++ u16 enclosure_handle; ++ u64 enclosure_logical_id; ++ u8 responding; ++ struct _sas_phy *phy; ++ struct list_head sas_port_list; ++}; ++ ++/** ++ * enum reset_type - reset state ++ * @FORCE_BIG_HAMMER: issue diagnostic reset ++ * @SOFT_RESET: issue message_unit_reset, if fails to to big hammer ++ */ ++enum reset_type { ++ FORCE_BIG_HAMMER, ++ SOFT_RESET, ++}; ++ ++/** ++ * struct chain_tracker - firmware chain tracker ++ * @chain_buffer: chain buffer ++ * @chain_buffer_dma: physical address ++ * @tracker_list: list of free request (ioc->free_chain_list) ++ */ ++struct chain_tracker { ++ void *chain_buffer; ++ dma_addr_t chain_buffer_dma; ++ struct list_head tracker_list; ++}; ++ ++/** ++ * struct scsiio_tracker - scsi mf request tracker ++ * @smid: system message id ++ * @scmd: scsi request pointer ++ * @cb_idx: callback index ++ * @direct_io: To indicate whether I/O is direct (WARPDRIVE) ++ * @tracker_list: list of free request (ioc->free_list) ++ * @msix_io: IO's msix ++ */ ++struct scsiio_tracker { ++ u16 smid; ++ struct scsi_cmnd *scmd; ++ u8 cb_idx; ++ u8 direct_io; ++ struct list_head chain_list; ++ struct list_head tracker_list; ++ u16 msix_io; ++}; ++ ++/** ++ * struct request_tracker - firmware request tracker ++ * @smid: system message id ++ * @cb_idx: callback index ++ * @tracker_list: list of free request (ioc->free_list) ++ */ ++struct request_tracker { ++ u16 smid; ++ u8 cb_idx; ++ struct list_head tracker_list; ++}; ++ ++/** ++ * struct _tr_list - target reset list ++ * @handle: device handle ++ * @state: state machine ++ */ ++struct _tr_list { ++ struct list_head list; ++ u16 handle; ++ u16 state; ++}; ++ ++/** ++ * struct _sc_list - delayed SAS_IO_UNIT_CONTROL message list ++ * @handle: device handle ++ */ ++struct _sc_list { ++ struct list_head list; ++ u16 handle; ++}; ++ ++/** ++ * struct _event_ack_list - delayed event acknowledgment list ++ * @Event: Event ID ++ * @EventContext: used to track the event uniquely ++ */ ++struct _event_ack_list { ++ struct list_head list; ++ u16 Event; ++ u32 EventContext; ++}; ++ ++/** ++ * struct adapter_reply_queue - the reply queue struct ++ * @ioc: per adapter object ++ * @msix_index: msix index into vector table ++ * @vector: irq vector ++ * @reply_post_host_index: head index in the pool where FW completes IO ++ * @reply_post_free: reply post base virt address ++ * @name: the name registered to request_irq() ++ * @busy: isr is actively processing replies on another cpu ++ * @list: this list ++*/ ++struct adapter_reply_queue { ++ struct MPT3SAS_ADAPTER *ioc; ++ u8 msix_index; ++ unsigned int vector; ++ u32 reply_post_host_index; ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free; ++ char name[MPT_NAME_LENGTH]; ++ atomic_t busy; ++ cpumask_var_t affinity_hint; ++ struct list_head list; ++}; ++ ++typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); ++ ++/* SAS3.0 support */ ++typedef int (*MPT_BUILD_SG_SCMD)(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_cmnd *scmd, u16 smid); ++typedef void (*MPT_BUILD_SG)(struct MPT3SAS_ADAPTER *ioc, void *psge, ++ dma_addr_t data_out_dma, size_t data_out_sz, ++ dma_addr_t data_in_dma, size_t data_in_sz); ++typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc, ++ void *paddr); ++ ++ ++ ++/* IOC Facts and Port Facts converted from little endian to cpu */ ++union mpi3_version_union { ++ MPI2_VERSION_STRUCT Struct; ++ u32 Word; ++}; ++ ++struct mpt2sas_facts { ++ u16 MsgVersion; ++ u16 HeaderVersion; ++ u8 IOCNumber; ++ u8 VP_ID; ++ u8 VF_ID; ++ u16 IOCExceptions; ++ u16 IOCStatus; ++ u32 IOCLogInfo; ++ u8 MaxChainDepth; ++ u8 WhoInit; ++ u8 NumberOfPorts; ++ u8 MaxMSIxVectors; ++ u16 RequestCredit; ++ u16 ProductID; ++ u32 IOCCapabilities; ++ union mpi3_version_union FWVersion; ++ u16 IOCRequestFrameSize; ++ u16 IOCMaxChainSegmentSize; ++ u16 MaxInitiators; ++ u16 MaxTargets; ++ u16 MaxSasExpanders; ++ u16 MaxEnclosures; ++ u16 ProtocolFlags; ++ u16 HighPriorityCredit; ++ u16 MaxReplyDescriptorPostQueueDepth; ++ u8 ReplyFrameSize; ++ u8 MaxVolumes; ++ u16 MaxDevHandle; ++ u16 MaxPersistentEntries; ++ u16 MinDevHandle; ++}; ++ ++struct mpt2sas_port_facts { ++ u8 PortNumber; ++ u8 VP_ID; ++ u8 VF_ID; ++ u8 PortType; ++ u16 MaxPostedCmdBuffers; ++}; ++ ++struct reply_post_struct { ++ Mpi2ReplyDescriptorsUnion_t *reply_post_free; ++ dma_addr_t reply_post_free_dma; ++}; ++ ++/** ++ * enum mutex_type - task management mutex type ++ * @TM_MUTEX_OFF: mutex is not required becuase calling function is acquiring it ++ * @TM_MUTEX_ON: mutex is required ++ */ ++enum mutex_type { ++ TM_MUTEX_OFF = 0, ++ TM_MUTEX_ON = 1, ++}; ++ ++typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); ++/** ++ * struct MPT3SAS_ADAPTER - per adapter struct ++ * @list: ioc_list ++ * @shost: shost object ++ * @id: unique adapter id ++ * @cpu_count: number online cpus ++ * @name: generic ioc string ++ * @tmp_string: tmp string used for logging ++ * @pdev: pci pdev object ++ * @pio_chip: physical io register space ++ * @chip: memory mapped register space ++ * @chip_phys: physical addrss prior to mapping ++ * @logging_level: see mpt3sas_debug.h ++ * @fwfault_debug: debuging FW timeouts ++ * @ir_firmware: IR firmware present ++ * @bars: bitmask of BAR's that must be configured ++ * @mask_interrupts: ignore interrupt ++ * @dma_mask: used to set the consistent dma mask ++ * @fault_reset_work_q_name: fw fault work queue ++ * @fault_reset_work_q: "" ++ * @fault_reset_work: "" ++ * @firmware_event_name: fw event work queue ++ * @firmware_event_thread: "" ++ * @fw_event_lock: ++ * @fw_event_list: list of fw events ++ * @aen_event_read_flag: event log was read ++ * @broadcast_aen_busy: broadcast aen waiting to be serviced ++ * @shost_recovery: host reset in progress ++ * @ioc_reset_in_progress_lock: ++ * @ioc_link_reset_in_progress: phy/hard reset in progress ++ * @ignore_loginfos: ignore loginfos during task management ++ * @remove_host: flag for when driver unloads, to avoid sending dev resets ++ * @pci_error_recovery: flag to prevent ioc access until slot reset completes ++ * @wait_for_discovery_to_complete: flag set at driver load time when ++ * waiting on reporting devices ++ * @is_driver_loading: flag set at driver load time ++ * @port_enable_failed: flag set when port enable has failed ++ * @start_scan: flag set from scan_start callback, cleared from _mpt2sas_fw_work ++ * @start_scan_failed: means port enable failed, return's the ioc_status ++ * @msix_enable: flag indicating msix is enabled ++ * @msix_vector_count: number msix vectors ++ * @cpu_msix_table: table for mapping cpus to msix index ++ * @cpu_msix_table_sz: table size ++ * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands ++ * @scsi_io_cb_idx: shost generated commands ++ * @tm_cb_idx: task management commands ++ * @scsih_cb_idx: scsih internal commands ++ * @transport_cb_idx: transport internal commands ++ * @ctl_cb_idx: clt internal commands ++ * @base_cb_idx: base internal commands ++ * @config_cb_idx: base internal commands ++ * @tm_tr_cb_idx : device removal target reset handshake ++ * @tm_tr_volume_cb_idx : volume removal target reset ++ * @base_cmds: ++ * @transport_cmds: ++ * @scsih_cmds: ++ * @tm_cmds: ++ * @ctl_cmds: ++ * @config_cmds: ++ * @base_add_sg_single: handler for either 32/64 bit sgl's ++ * @event_type: bits indicating which events to log ++ * @event_context: unique id for each logged event ++ * @event_log: event log pointer ++ * @event_masks: events that are masked ++ * @facts: static facts data ++ * @pfacts: static port facts data ++ * @manu_pg0: static manufacturing page 0 ++ * @manu_pg10: static manufacturing page 10 ++ * @manu_pg11: static manufacturing page 11 ++ * @bios_pg2: static bios page 2 ++ * @bios_pg3: static bios page 3 ++ * @ioc_pg8: static ioc page 8 ++ * @iounit_pg0: static iounit page 0 ++ * @iounit_pg1: static iounit page 1 ++ * @iounit_pg8: static iounit page 8 ++ * @sas_hba: sas host object ++ * @sas_expander_list: expander object list ++ * @sas_node_lock: ++ * @sas_device_list: sas device object list ++ * @sas_device_init_list: sas device object list (used only at init time) ++ * @sas_device_lock: ++ * @io_missing_delay: time for IO completed by fw when PDR enabled ++ * @device_missing_delay: time for device missing by fw when PDR enabled ++ * @sas_id : used for setting volume target IDs ++ * @blocking_handles: bitmask used to identify which devices need blocking ++ * @pd_handles : bitmask for PD handles ++ * @pd_handles_sz : size of pd_handle bitmask ++ * @config_page_sz: config page size ++ * @config_page: reserve memory for config page payload ++ * @config_page_dma: ++ * @hba_queue_depth: hba request queue depth ++ * @sge_size: sg element size for either 32/64 bit ++ * @scsiio_depth: SCSI_IO queue depth ++ * @request_sz: per request frame size ++ * @request: pool of request frames ++ * @request_dma: ++ * @request_dma_sz: ++ * @scsi_lookup: firmware request tracker list ++ * @scsi_lookup_lock: ++ * @free_list: free list of request ++ * @pending_io_count: ++ * @reset_wq: ++ * @chain: pool of chains ++ * @chain_dma: ++ * @max_sges_in_main_message: number sg elements in main message ++ * @max_sges_in_chain_message: number sg elements per chain ++ * @chains_needed_per_io: max chains per io ++ * @chain_depth: total chains allocated ++ * @chain_segment_sz: gives the max number of ++ * SGEs accommodate on single chain buffer ++ * @hi_priority_smid: ++ * @hi_priority: ++ * @hi_priority_dma: ++ * @hi_priority_depth: ++ * @hpr_lookup: ++ * @hpr_free_list: ++ * @internal_smid: ++ * @internal: ++ * @internal_dma: ++ * @internal_depth: ++ * @internal_lookup: ++ * @internal_free_list: ++ * @sense: pool of sense ++ * @sense_dma: ++ * @sense_dma_pool: ++ * @reply_depth: hba reply queue depth: ++ * @reply_sz: per reply frame size: ++ * @reply: pool of replys: ++ * @reply_dma: ++ * @reply_dma_pool: ++ * @reply_free_queue_depth: reply free depth ++ * @reply_free: pool for reply free queue (32 bit addr) ++ * @reply_free_dma: ++ * @reply_free_dma_pool: ++ * @reply_free_host_index: tail index in pool to insert free replys ++ * @reply_post_queue_depth: reply post queue depth ++ * @reply_post_struct: struct for reply_post_free physical & virt address ++ * @rdpq_array_capable: FW supports multiple reply queue addresses in ioc_init ++ * @rdpq_array_enable: rdpq_array support is enabled in the driver ++ * @rdpq_array_enable_assigned: this ensures that rdpq_array_enable flag ++ * is assigned only ones ++ * @reply_queue_count: number of reply queue's ++ * @reply_queue_list: link list contaning the reply queue info ++ * @msix96_vector: 96 MSI-X vector support ++ * @replyPostRegisterIndex: index of next position in Reply Desc Post Queue ++ * @delayed_tr_list: target reset link list ++ * @delayed_tr_volume_list: volume target reset link list ++ * @delayed_sc_list: ++ * @delayed_event_ack_list: ++ * @temp_sensors_count: flag to carry the number of temperature sensors ++ * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and ++ * pci resource handling. PCI resource freeing will lead to free ++ * vital hardware/memory resource, which might be in use by cli/sysfs ++ * path functions resulting in Null pointer reference followed by kernel ++ * crash. To avoid the above race condition we use mutex syncrhonization ++ * which ensures the syncrhonization between cli/sysfs_show path. ++ */ ++struct MPT3SAS_ADAPTER { ++ struct list_head list; ++ struct Scsi_Host *shost; ++ u8 id; ++ int cpu_count; ++ char name[MPT_NAME_LENGTH]; ++ char driver_name[MPT_NAME_LENGTH]; ++ char tmp_string[MPT_STRING_LENGTH]; ++ struct pci_dev *pdev; ++ Mpi2SystemInterfaceRegs_t __iomem *chip; ++ resource_size_t chip_phys; ++ int logging_level; ++ int fwfault_debug; ++ u8 ir_firmware; ++ int bars; ++ u8 mask_interrupts; ++ int dma_mask; ++ ++ /* fw fault handler */ ++ char fault_reset_work_q_name[20]; ++ struct workqueue_struct *fault_reset_work_q; ++ struct delayed_work fault_reset_work; ++ ++ /* fw event handler */ ++ char firmware_event_name[20]; ++ struct workqueue_struct *firmware_event_thread; ++ spinlock_t fw_event_lock; ++ struct list_head fw_event_list; ++ ++ /* misc flags */ ++ int aen_event_read_flag; ++ u8 broadcast_aen_busy; ++ u16 broadcast_aen_pending; ++ u8 shost_recovery; ++ ++ struct mutex reset_in_progress_mutex; ++ spinlock_t ioc_reset_in_progress_lock; ++ u8 ioc_link_reset_in_progress; ++ u8 ioc_reset_in_progress_status; ++ ++ u8 ignore_loginfos; ++ u8 remove_host; ++ u8 pci_error_recovery; ++ u8 wait_for_discovery_to_complete; ++ u8 is_driver_loading; ++ u8 port_enable_failed; ++ u8 start_scan; ++ u16 start_scan_failed; ++ ++ u8 msix_enable; ++ u16 msix_vector_count; ++ u8 *cpu_msix_table; ++ u16 cpu_msix_table_sz; ++ resource_size_t __iomem **reply_post_host_index; ++ u32 ioc_reset_count; ++ MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; ++ u32 non_operational_loop; ++ ++ /* internal commands, callback index */ ++ u8 scsi_io_cb_idx; ++ u8 tm_cb_idx; ++ u8 transport_cb_idx; ++ u8 scsih_cb_idx; ++ u8 ctl_cb_idx; ++ u8 base_cb_idx; ++ u8 port_enable_cb_idx; ++ u8 config_cb_idx; ++ u8 tm_tr_cb_idx; ++ u8 tm_tr_volume_cb_idx; ++ u8 tm_sas_control_cb_idx; ++ struct _internal_cmd base_cmds; ++ struct _internal_cmd port_enable_cmds; ++ struct _internal_cmd transport_cmds; ++ struct _internal_cmd scsih_cmds; ++ struct _internal_cmd tm_cmds; ++ struct _internal_cmd ctl_cmds; ++ struct _internal_cmd config_cmds; ++ ++ MPT_ADD_SGE base_add_sg_single; ++ ++ /* function ptr for either IEEE or MPI sg elements */ ++ MPT_BUILD_SG_SCMD build_sg_scmd; ++ MPT_BUILD_SG build_sg; ++ MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge; ++ u16 sge_size_ieee; ++ u16 hba_mpi_version_belonged; ++ ++ /* function ptr for MPI sg elements only */ ++ MPT_BUILD_SG build_sg_mpi; ++ MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge_mpi; ++ ++ /* event log */ ++ u32 event_type[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; ++ u32 event_context; ++ void *event_log; ++ u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; ++ ++ /* static config pages */ ++ struct mpt2sas_facts facts; ++ struct mpt2sas_port_facts *pfacts; ++ Mpi2ManufacturingPage0_t manu_pg0; ++ struct Mpi2ManufacturingPage10_t manu_pg10; ++ struct Mpi2ManufacturingPage11_t manu_pg11; ++ Mpi2BiosPage2_t bios_pg2; ++ Mpi2BiosPage3_t bios_pg3; ++ Mpi2IOCPage8_t ioc_pg8; ++ Mpi2IOUnitPage0_t iounit_pg0; ++ Mpi2IOUnitPage1_t iounit_pg1; ++ Mpi2IOUnitPage8_t iounit_pg8; ++ ++ struct _boot_device req_boot_device; ++ struct _boot_device req_alt_boot_device; ++ struct _boot_device current_boot_device; ++ ++ /* sas hba, expander, and device list */ ++ struct _sas_node sas_hba; ++ struct list_head sas_expander_list; ++ spinlock_t sas_node_lock; ++ struct list_head sas_device_list; ++ struct list_head sas_device_init_list; ++ spinlock_t sas_device_lock; ++ struct list_head raid_device_list; ++ spinlock_t raid_device_lock; ++ u8 io_missing_delay; ++ u16 device_missing_delay; ++ int sas_id; ++ ++ void *blocking_handles; ++ void *pd_handles; ++ u16 pd_handles_sz; ++ ++ /* config page */ ++ u16 config_page_sz; ++ void *config_page; ++ dma_addr_t config_page_dma; ++ ++ /* scsiio request */ ++ u16 hba_queue_depth; ++ u16 sge_size; ++ u16 scsiio_depth; ++ u16 request_sz; ++ u8 *request; ++ dma_addr_t request_dma; ++ u32 request_dma_sz; ++ struct scsiio_tracker *scsi_lookup; ++ ulong scsi_lookup_pages; ++ spinlock_t scsi_lookup_lock; ++ struct list_head free_list; ++ int pending_io_count; ++ wait_queue_head_t reset_wq; ++ ++ /* chain */ ++ struct chain_tracker *chain_lookup; ++ struct list_head free_chain_list; ++ struct dma_pool *chain_dma_pool; ++ ulong chain_pages; ++ u16 max_sges_in_main_message; ++ u16 max_sges_in_chain_message; ++ u16 chains_needed_per_io; ++ u32 chain_depth; ++ u16 chain_segment_sz; ++ ++ /* hi-priority queue */ ++ u16 hi_priority_smid; ++ u8 *hi_priority; ++ dma_addr_t hi_priority_dma; ++ u16 hi_priority_depth; ++ struct request_tracker *hpr_lookup; ++ struct list_head hpr_free_list; ++ ++ /* internal queue */ ++ u16 internal_smid; ++ u8 *internal; ++ dma_addr_t internal_dma; ++ u16 internal_depth; ++ struct request_tracker *internal_lookup; ++ struct list_head internal_free_list; ++ ++ /* sense */ ++ u8 *sense; ++ dma_addr_t sense_dma; ++ struct dma_pool *sense_dma_pool; ++ ++ /* reply */ ++ u16 reply_sz; ++ u8 *reply; ++ dma_addr_t reply_dma; ++ u32 reply_dma_max_address; ++ u32 reply_dma_min_address; ++ struct dma_pool *reply_dma_pool; ++ ++ /* reply free queue */ ++ u16 reply_free_queue_depth; ++ __le32 *reply_free; ++ dma_addr_t reply_free_dma; ++ struct dma_pool *reply_free_dma_pool; ++ u32 reply_free_host_index; ++ ++ /* reply post queue */ ++ u16 reply_post_queue_depth; ++ struct reply_post_struct *reply_post; ++ u8 rdpq_array_capable; ++ u8 rdpq_array_enable; ++ u8 rdpq_array_enable_assigned; ++ struct dma_pool *reply_post_free_dma_pool; ++ u8 reply_queue_count; ++ struct list_head reply_queue_list; ++ ++ u8 msix96_vector; ++ /* reply post register index */ ++ resource_size_t **replyPostRegisterIndex; ++ ++ struct list_head delayed_tr_list; ++ struct list_head delayed_tr_volume_list; ++ struct list_head delayed_sc_list; ++ struct list_head delayed_event_ack_list; ++ u8 temp_sensors_count; ++ struct mutex pci_access_mutex; ++ ++ /* diag buffer support */ ++ u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT]; ++ dma_addr_t diag_buffer_dma[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u8 diag_buffer_status[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 unique_id[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23]; ++ u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; ++ u32 ring_buffer_offset; ++ u32 ring_buffer_sz; ++ u8 is_warpdrive; ++ u8 hide_ir_msg; ++ u8 mfg_pg10_hide_flag; ++ u8 hide_drives; ++ spinlock_t diag_trigger_lock; ++ u8 diag_trigger_active; ++ struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; ++ struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event; ++ struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi; ++ struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi; ++}; ++ ++typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++ ++ ++/* base shared API */ ++extern struct list_head mpt2sas_ioc_list; ++extern char driver_name[MPT_NAME_LENGTH]; ++/* spinlock on list operations over IOCs ++ * Case: when multiple warpdrive cards(IOCs) are in use ++ * Each IOC will added to the ioc list structure on initialization. ++ * Watchdog threads run at regular intervals to check IOC for any ++ * fault conditions which will trigger the dead_ioc thread to ++ * deallocate pci resource, resulting deleting the IOC netry from list, ++ * this deletion need to protected by spinlock to enusre that ++ * ioc removal is syncrhonized, if not synchronized it might lead to ++ * list_del corruption as the ioc list is traversed in cli path. ++ */ ++extern spinlock_t gioc_lock_mpt2sas; ++ ++void mpt2sas_base_start_watchdog(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc); ++ ++int mpt2sas_base_attach(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_base_detach(struct MPT3SAS_ADAPTER *ioc); ++int mpt2sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc); ++int mpt2sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, ++ enum reset_type type); ++ ++void *mpt2sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void *mpt2sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid); ++ ++void mpt2sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); ++ ++/* hi-priority queue */ ++u16 mpt2sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); ++u16 mpt2sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, ++ struct scsi_cmnd *scmd); ++ ++u16 mpt2sas_base_get_smid(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); ++void mpt2sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void mpt2sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle); ++void mpt2sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle); ++void mpt2sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid, u16 msix_task); ++void mpt2sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void mpt2sas_base_initialize_callback_handler(void); ++u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func); ++void mpt2sas_base_release_callback_handler(u8 cb_idx); ++ ++u8 mpt2sas_base_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++u8 mpt2sas_port_enable_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u8 msix_index, u32 reply); ++void *mpt2sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, ++ u32 phys_addr); ++ ++u32 mpt2sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked); ++ ++void mpt2sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code); ++int mpt2sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SasIoUnitControlReply_t *mpi_reply, ++ Mpi2SasIoUnitControlRequest_t *mpi_request); ++int mpt2sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request); ++ ++void mpt2sas_base_validate_event_type(struct MPT3SAS_ADAPTER *ioc, ++ u32 *event_type); ++ ++void mpt2sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc); ++ ++void mpt2sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc, ++ u16 device_missing_delay, u8 io_missing_delay); ++ ++int mpt2sas_port_enable(struct MPT3SAS_ADAPTER *ioc); ++ ++ ++/* scsih shared API */ ++u8 mpt2sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ++ u32 reply); ++void mpt2sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase); ++ ++int mpt2sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ uint channel, uint id, uint lun, u8 type, u16 smid_task, ++ ulong timeout, enum mutex_type m_type); ++void mpt2sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); ++void mpt2sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); ++void mpt2sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++void mpt2sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address); ++u8 mpt2sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid); ++ ++struct _sas_node *mpt2sas_scsih_expander_find_by_handle( ++ struct MPT3SAS_ADAPTER *ioc, u16 handle); ++struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address( ++ struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++struct _sas_device *mpt2sas_get_sdev_by_addr( ++ struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++struct _sas_device *__mpt2sas_get_sdev_by_addr( ++ struct MPT3SAS_ADAPTER *ioc, u64 sas_address); ++ ++void mpt2sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc); ++struct _raid_device * ++mpt2sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle); ++ ++/* config shared API */ ++u8 mpt2sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++int mpt2sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, ++ u8 *num_phys); ++int mpt2sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page); ++int mpt2sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, ++ u16 sz); ++int mpt2sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage10_t *config_page); ++ ++int mpt2sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page); ++int mpt2sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page); ++ ++int mpt2sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2BiosPage2_t *config_page); ++int mpt2sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2BiosPage3_t *config_page); ++int mpt2sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage0_t *config_page); ++int mpt2sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, ++ u16 sz); ++int mpt2sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage1_t *config_page); ++int mpt2sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz); ++int mpt2sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage1_t *config_page); ++int mpt2sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOUnitPage8_t *config_page); ++int mpt2sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz); ++int mpt2sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz); ++int mpt2sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2IOCPage8_t *config_page); ++int mpt2sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ExpanderPage0_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ExpanderPage1_t *config_page, ++ u32 phy_number, u16 handle); ++int mpt2sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, ++ u32 form, u32 handle); ++int mpt2sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number); ++int mpt2sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number); ++int mpt2sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, ++ u32 handle); ++int mpt2sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u8 *num_pds); ++int mpt2sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, ++ u32 handle, u16 sz); ++int mpt2sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, ++ u32 form, u32 form_specific); ++int mpt2sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, ++ u16 *volume_handle); ++int mpt2sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, ++ u16 volume_handle, u64 *wwid); ++ ++/* ctl shared API */ ++extern struct device_attribute *mpt2sas_host_attrs[]; ++extern struct device_attribute *mpt2sas_dev_attrs[]; ++void mpt2sas_ctl_init(ushort hbas_to_enumerate); ++void mpt2sas_ctl_exit(ushort hbas_to_enumerate); ++u8 mpt2sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++void mpt2sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase); ++u8 mpt2sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, ++ u8 msix_index, u32 reply); ++void mpt2sas_ctl_add_to_event_log(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventNotificationReply_t *mpi_reply); ++ ++void mpt2sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, ++ u8 bits_to_regsiter); ++int mpt2sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, ++ u8 *issue_reset); ++ ++/* transport shared API */ ++extern struct scsi_transport_template *mpt2sas_transport_template; ++u8 mpt2sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply); ++struct _sas_port *mpt2sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, ++ u16 handle, u64 sas_address); ++void mpt2sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u64 sas_address_parent); ++int mpt2sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy ++ *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); ++int mpt2sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_phy *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, ++ struct device *parent_dev); ++void mpt2sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); ++extern struct sas_function_template mpt2sas_transport_functions; ++extern struct scsi_transport_template *mpt2sas_transport_template; ++extern int scsi_internal_device_block(struct scsi_device *sdev); ++extern int scsi_internal_device_unblock(struct scsi_device *sdev, ++ enum scsi_device_state new_state); ++/* trigger data externs */ ++void mpt2sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); ++void mpt2sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); ++void mpt2sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, ++ u32 tigger_bitmask); ++void mpt2sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event, ++ u16 log_entry_qualifier); ++void mpt2sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, ++ u8 asc, u8 ascq); ++void mpt2sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status, ++ u32 loginfo); ++ ++/* warpdrive APIs */ ++u8 mpt2sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc); ++void mpt2sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device); ++u8 ++mpt2sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++void ++mpt2sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io); ++void ++mpt2sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, ++ u16 smid); ++ ++#endif /* MPT3SAS_BASE_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_config.c b/drivers/scsi/mpt2sas/mpt3sas_config.c +new file mode 100644 +index 0000000..0f67b2c +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_config.c +@@ -0,0 +1,1716 @@ ++/* ++ * This module provides common API for accessing firmware configuration pages ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/* local definitions */ ++ ++/* Timeout for config page request (in seconds) */ ++#define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15 ++ ++/* Common sgl flags for READING a config page. */ ++#define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ ++ | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT) ++ ++/* Common sgl flags for WRITING a config page. */ ++#define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \ ++ MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \ ++ | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \ ++ << MPI2_SGE_FLAGS_SHIFT) ++ ++/** ++ * struct config_request - obtain dma memory via routine ++ * @sz: size ++ * @page: virt pointer ++ * @page_dma: phys pointer ++ * ++ */ ++struct config_request { ++ u16 sz; ++ void *page; ++ dma_addr_t page_dma; ++}; ++ ++/** ++ * _config_display_some_debug - debug routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @calling_function_name: string pass from calling function ++ * @mpi_reply: reply message frame ++ * Context: none. ++ * ++ * Function for displaying debug info helpful when debugging issues ++ * in this module. ++ */ ++static void ++_config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ char *calling_function_name, MPI2DefaultReply_t *mpi_reply) ++{ ++ Mpi2ConfigRequest_t *mpi_request; ++ char *desc = NULL; ++ ++ if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) ++ return; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) { ++ case MPI2_CONFIG_PAGETYPE_IO_UNIT: ++ desc = "io_unit"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_IOC: ++ desc = "ioc"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_BIOS: ++ desc = "bios"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_RAID_VOLUME: ++ desc = "raid_volume"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_MANUFACTURING: ++ desc = "manufaucturing"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK: ++ desc = "physdisk"; ++ break; ++ case MPI2_CONFIG_PAGETYPE_EXTENDED: ++ switch (mpi_request->ExtPageType) { ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT: ++ desc = "sas_io_unit"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER: ++ desc = "sas_expander"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE: ++ desc = "sas_device"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY: ++ desc = "sas_phy"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_LOG: ++ desc = "log"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE: ++ desc = "enclosure"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG: ++ desc = "raid_config"; ++ break; ++ case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING: ++ desc = "driver_mapping"; ++ break; ++ } ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ pr_info(MPT3SAS_FMT ++ "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n", ++ ioc->name, calling_function_name, desc, ++ mpi_request->Header.PageNumber, mpi_request->Action, ++ le32_to_cpu(mpi_request->PageAddress), smid); ++ ++ if (!mpi_reply) ++ return; ++ ++ if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "\tiocstatus(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo)); ++} ++ ++/** ++ * _config_alloc_config_dma_memory - obtain physical memory ++ * @ioc: per adapter object ++ * @mem: struct config_request ++ * ++ * A wrapper for obtaining dma-able memory for config page request. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, ++ struct config_request *mem) ++{ ++ int r = 0; ++ ++ if (mem->sz > ioc->config_page_sz) { ++ mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz, ++ &mem->page_dma, GFP_KERNEL); ++ if (!mem->page) { ++ pr_err(MPT3SAS_FMT ++ "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n", ++ ioc->name, __func__, mem->sz); ++ r = -ENOMEM; ++ } ++ } else { /* use tmp buffer if less than 512 bytes */ ++ mem->page = ioc->config_page; ++ mem->page_dma = ioc->config_page_dma; ++ } ++ return r; ++} ++ ++/** ++ * _config_free_config_dma_memory - wrapper to free the memory ++ * @ioc: per adapter object ++ * @mem: struct config_request ++ * ++ * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static void ++_config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, ++ struct config_request *mem) ++{ ++ if (mem->sz > ioc->config_page_sz) ++ dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page, ++ mem->page_dma); ++} ++ ++/** ++ * mpt2sas_config_done - config page completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: none. ++ * ++ * The callback handler when using _config_request. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ if (ioc->config_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->config_cmds.smid != smid) ++ return 1; ++ ioc->config_cmds.status |= MPT3_CMD_COMPLETE; ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) { ++ ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID; ++ memcpy(ioc->config_cmds.reply, mpi_reply, ++ mpi_reply->MsgLength*4); ++ } ++ ioc->config_cmds.status &= ~MPT3_CMD_PENDING; ++ _config_display_some_debug(ioc, smid, "config_done", mpi_reply); ++ ioc->config_cmds.smid = USHRT_MAX; ++ complete(&ioc->config_cmds.done); ++ return 1; ++} ++ ++/** ++ * _config_request - main routine for sending config page requests ++ * @ioc: per adapter object ++ * @mpi_request: request message frame ++ * @mpi_reply: reply mf payload returned from firmware ++ * @timeout: timeout in seconds ++ * @config_page: contents of the config page ++ * @config_page_sz: size of config page ++ * Context: sleep ++ * ++ * A generic API for config page requests to firmware. ++ * ++ * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling ++ * this API. ++ * ++ * The callback index is set inside `ioc->config_cb_idx. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t ++ *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout, ++ void *config_page, u16 config_page_sz) ++{ ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ Mpi2ConfigRequest_t *config_request; ++ int r; ++ u8 retry_count, issue_host_reset = 0; ++ u16 wait_state_count; ++ struct config_request mem; ++ u32 ioc_status = UINT_MAX; ++ ++ mutex_lock(&ioc->config_cmds.mutex); ++ if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: config_cmd in use\n", ++ ioc->name, __func__); ++ mutex_unlock(&ioc->config_cmds.mutex); ++ return -EAGAIN; ++ } ++ ++ retry_count = 0; ++ memset(&mem, 0, sizeof(struct config_request)); ++ ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ if (config_page) { ++ mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion; ++ mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber; ++ mpi_request->Header.PageType = mpi_reply->Header.PageType; ++ mpi_request->Header.PageLength = mpi_reply->Header.PageLength; ++ mpi_request->ExtPageLength = mpi_reply->ExtPageLength; ++ mpi_request->ExtPageType = mpi_reply->ExtPageType; ++ if (mpi_request->Header.PageLength) ++ mem.sz = mpi_request->Header.PageLength * 4; ++ else ++ mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4; ++ r = _config_alloc_config_dma_memory(ioc, &mem); ++ if (r != 0) ++ goto out; ++ if (mpi_request->Action == ++ MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT || ++ mpi_request->Action == ++ MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { ++ ioc->base_add_sg_single(&mpi_request->PageBufferSGE, ++ MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, ++ mem.page_dma); ++ memcpy(mem.page, config_page, min_t(u16, mem.sz, ++ config_page_sz)); ++ } else { ++ memset(config_page, 0, config_page_sz); ++ ioc->base_add_sg_single(&mpi_request->PageBufferSGE, ++ MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma); ++ memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz)); ++ } ++ } ++ ++ retry_config: ++ if (retry_count) { ++ if (retry_count > 2) { /* attempt only 2 retries */ ++ r = -EFAULT; ++ goto free_mem; ++ } ++ pr_info(MPT3SAS_FMT "%s: attempting retry (%d)\n", ++ ioc->name, __func__, retry_count); ++ } ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ r = -EFAULT; ++ goto free_mem; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ r = -EAGAIN; ++ goto free_mem; ++ } ++ ++ r = 0; ++ memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t)); ++ ioc->config_cmds.status = MPT3_CMD_PENDING; ++ config_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->config_cmds.smid = smid; ++ memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); ++ _config_display_some_debug(ioc, smid, "config_request", NULL); ++ init_completion(&ioc->config_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->config_cmds.done, ++ timeout*HZ); ++ if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2ConfigRequest_t)/4); ++ retry_count++; ++ if (ioc->config_cmds.smid == smid) ++ mpt2sas_base_free_smid(ioc, smid); ++ if ((ioc->shost_recovery) || (ioc->config_cmds.status & ++ MPT3_CMD_RESET) || ioc->pci_error_recovery) ++ goto retry_config; ++ issue_host_reset = 1; ++ r = -EFAULT; ++ goto free_mem; ++ } ++ ++ if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) { ++ memcpy(mpi_reply, ioc->config_cmds.reply, ++ sizeof(Mpi2ConfigReply_t)); ++ ++ /* Reply Frame Sanity Checks to workaround FW issues */ ++ if ((mpi_request->Header.PageType & 0xF) != ++ (mpi_reply->Header.PageType & 0xF)) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \ ++ " mpi_reply mismatch: Requested PageType(0x%02x)" \ ++ " Reply PageType(0x%02x)\n", \ ++ ioc->name, __func__, ++ (mpi_request->Header.PageType & 0xF), ++ (mpi_reply->Header.PageType & 0xF)); ++ } ++ ++ if (((mpi_request->Header.PageType & 0xF) == ++ MPI2_CONFIG_PAGETYPE_EXTENDED) && ++ mpi_request->ExtPageType != mpi_reply->ExtPageType) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \ ++ " mpi_reply mismatch: Requested ExtPageType(0x%02x)" ++ " Reply ExtPageType(0x%02x)\n", ++ ioc->name, __func__, mpi_request->ExtPageType, ++ mpi_reply->ExtPageType); ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) ++ & MPI2_IOCSTATUS_MASK; ++ } ++ ++ if (retry_count) ++ pr_info(MPT3SAS_FMT "%s: retry (%d) completed!!\n", \ ++ ioc->name, __func__, retry_count); ++ ++ if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) && ++ config_page && mpi_request->Action == ++ MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) { ++ u8 *p = (u8 *)mem.page; ++ ++ /* Config Page Sanity Checks to workaround FW issues */ ++ if (p) { ++ if ((mpi_request->Header.PageType & 0xF) != ++ (p[3] & 0xF)) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ _debug_dump_config(p, min_t(u16, mem.sz, ++ config_page_sz)/4); ++ panic(KERN_WARNING MPT3SAS_FMT ++ "%s: Firmware BUG:" \ ++ " config page mismatch:" ++ " Requested PageType(0x%02x)" ++ " Reply PageType(0x%02x)\n", ++ ioc->name, __func__, ++ (mpi_request->Header.PageType & 0xF), ++ (p[3] & 0xF)); ++ } ++ ++ if (((mpi_request->Header.PageType & 0xF) == ++ MPI2_CONFIG_PAGETYPE_EXTENDED) && ++ (mpi_request->ExtPageType != p[6])) { ++ _debug_dump_mf(mpi_request, ioc->request_sz/4); ++ _debug_dump_reply(mpi_reply, ioc->request_sz/4); ++ _debug_dump_config(p, min_t(u16, mem.sz, ++ config_page_sz)/4); ++ panic(KERN_WARNING MPT3SAS_FMT ++ "%s: Firmware BUG:" \ ++ " config page mismatch:" ++ " Requested ExtPageType(0x%02x)" ++ " Reply ExtPageType(0x%02x)\n", ++ ioc->name, __func__, ++ mpi_request->ExtPageType, p[6]); ++ } ++ } ++ memcpy(config_page, mem.page, min_t(u16, mem.sz, ++ config_page_sz)); ++ } ++ ++ free_mem: ++ if (config_page) ++ _config_free_config_dma_memory(ioc, &mem); ++ out: ++ ioc->config_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->config_cmds.mutex); ++ ++ if (issue_host_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg7 - obtain manufacturing page 7 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 7; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage10_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 10; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_manufacturing_pg11 - obtain manufacturing page 11 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 11; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_set_manufacturing_pg11 - set manufacturing page 11 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, ++ struct Mpi2ManufacturingPage11_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; ++ mpi_request.Header.PageNumber = 11; ++ mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_bios_pg2 - obtain bios page 2 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; ++ mpi_request.Header.PageNumber = 2; ++ mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_bios_pg3 - obtain bios page 3 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2BiosPage3_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; ++ mpi_request.Header.PageNumber = 3; ++ mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_set_iounit_pg1 - set iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg3 - obtain iounit page 3 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 3; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_iounit_pg8 - obtain iounit page 8 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; ++ mpi_request.Header.PageNumber = 8; ++ mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; ++ mpi_request.Header.PageNumber = 8; ++ mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: device handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, ++ u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; ++ mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; ++ mpi_request.Header.PageNumber = 0; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: device handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, ++ u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; ++ mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION; ++ mpi_request.Header.PageNumber = 1; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host ++ * @ioc: per adapter object ++ * @num_phys: pointer returned with the number of phys ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ u16 ioc_status; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t config_page; ++ ++ *num_phys = 0; ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, ++ sizeof(Mpi2SasIOUnitPage0_t)); ++ if (!r) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) ++ *num_phys = config_page.NumPhys; ++ } ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Calling function should call config_get_number_hba_phys prior to ++ * this function, so enough memory is allocated for config_page. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Calling function should call config_get_number_hba_phys prior to ++ * this function, so enough memory is allocated for config_page. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Calling function should call config_get_number_hba_phys prior to ++ * this function, so enough memory is allocated for config_page. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, ++ u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; ++ _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_expander_pg0 - obtain expander page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: expander handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_expander_pg1 - obtain expander page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @phy_number: phy number ++ * @handle: expander handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, ++ u16 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | ++ (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: expander handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_phy_pg0 - obtain phy page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @phy_number: phy number ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_phy_pg1 - obtain phy page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @phy_number: phy number ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: volume handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, ++ u32 handle) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; ++ mpi_request.Header.PageNumber = 1; ++ mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume ++ * @ioc: per adapter object ++ * @handle: volume handle ++ * @num_pds: returns pds count ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u8 *num_pds) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ Mpi2RaidVolPage0_t config_page; ++ Mpi2ConfigReply_t mpi_reply; ++ int r; ++ u16 ioc_status; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ *num_pds = 0; ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = ++ cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, ++ sizeof(Mpi2RaidVolPage0_t)); ++ if (!r) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) ++ *num_pds = config_page.NumPhysDisks; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_HANDLE or HANDLE ++ * @handle: volume handle ++ * @sz: size of buffer passed in config_page ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, ++ u32 handle, u16 sz) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | handle); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0 ++ * @ioc: per adapter object ++ * @mpi_reply: reply mf payload returned from firmware ++ * @config_page: contents of the config page ++ * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE ++ * @form_specific: specific to the form ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t ++ *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, ++ u32 form_specific) ++{ ++ Mpi2ConfigRequest_t mpi_request; ++ int r; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; ++ mpi_request.Header.PageNumber = 0; ++ mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.PageAddress = cpu_to_le32(form | form_specific); ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ r = _config_request(ioc, &mpi_request, mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ sizeof(*config_page)); ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_volume_handle - returns volume handle for give hidden ++ * raid components ++ * @ioc: per adapter object ++ * @pd_handle: phys disk handle ++ * @volume_handle: volume handle ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle, ++ u16 *volume_handle) ++{ ++ Mpi2RaidConfigurationPage0_t *config_page = NULL; ++ Mpi2ConfigRequest_t mpi_request; ++ Mpi2ConfigReply_t mpi_reply; ++ int r, i, config_page_sz; ++ u16 ioc_status; ++ int config_num; ++ u16 element_type; ++ u16 phys_disk_dev_handle; ++ ++ *volume_handle = 0; ++ memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_CONFIG; ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; ++ mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; ++ mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; ++ mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; ++ mpi_request.Header.PageNumber = 0; ++ ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); ++ if (r) ++ goto out; ++ ++ mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; ++ config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); ++ config_page = kmalloc(config_page_sz, GFP_KERNEL); ++ if (!config_page) { ++ r = -1; ++ goto out; ++ } ++ ++ config_num = 0xff; ++ while (1) { ++ mpi_request.PageAddress = cpu_to_le32(config_num + ++ MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); ++ r = _config_request(ioc, &mpi_request, &mpi_reply, ++ MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, ++ config_page_sz); ++ if (r) ++ goto out; ++ r = -1; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ goto out; ++ for (i = 0; i < config_page->NumElements; i++) { ++ element_type = le16_to_cpu(config_page-> ++ ConfigElement[i].ElementFlags) & ++ MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; ++ if (element_type == ++ MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || ++ element_type == ++ MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { ++ phys_disk_dev_handle = ++ le16_to_cpu(config_page->ConfigElement[i]. ++ PhysDiskDevHandle); ++ if (phys_disk_dev_handle == pd_handle) { ++ *volume_handle = ++ le16_to_cpu(config_page-> ++ ConfigElement[i].VolDevHandle); ++ r = 0; ++ goto out; ++ } ++ } else if (element_type == ++ MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { ++ *volume_handle = 0; ++ r = 0; ++ goto out; ++ } ++ } ++ config_num = config_page->ConfigNum; ++ } ++ out: ++ kfree(config_page); ++ return r; ++} ++ ++/** ++ * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle ++ * @ioc: per adapter object ++ * @volume_handle: volume handle ++ * @wwid: volume wwid ++ * Context: sleep. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle, ++ u64 *wwid) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2RaidVolPage1_t raid_vol_pg1; ++ ++ *wwid = 0; ++ if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, ++ volume_handle))) { ++ *wwid = le64_to_cpu(raid_vol_pg1.WWID); ++ return 0; ++ } else ++ return -1; ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_ctl.c b/drivers/scsi/mpt2sas/mpt3sas_ctl.c +new file mode 100644 +index 0000000..5c0cc30 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_ctl.c +@@ -0,0 +1,3483 @@ ++/* ++ * Management Module Support for MPT (Message Passing Technology) based ++ * controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mpt3sas_base.h" ++#include "mpt3sas_ctl.h" ++ ++ ++static struct fasync_struct *async_queue; ++static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait); ++ ++ ++/** ++ * enum block_state - blocking state ++ * @NON_BLOCKING: non blocking ++ * @BLOCKING: blocking ++ * ++ * These states are for ioctls that need to wait for a response ++ * from firmware, so they probably require sleep. ++ */ ++enum block_state { ++ NON_BLOCKING, ++ BLOCKING, ++}; ++ ++/** ++ * _ctl_sas_device_find_by_handle - sas device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for sas_device based on sas_address, then return sas_device ++ * object. ++ */ ++static struct _sas_device * ++_ctl_sas_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if (sas_device->handle != handle) ++ continue; ++ r = sas_device; ++ goto out; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * _ctl_display_some_debug - debug routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @calling_function_name: string pass from calling function ++ * @mpi_reply: reply message frame ++ * Context: none. ++ * ++ * Function for displaying debug info helpful when debugging issues ++ * in this module. ++ */ ++static void ++_ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ char *calling_function_name, MPI2DefaultReply_t *mpi_reply) ++{ ++ Mpi2ConfigRequest_t *mpi_request; ++ char *desc = NULL; ++ ++ if (!(ioc->logging_level & MPT_DEBUG_IOCTL)) ++ return; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ switch (mpi_request->Function) { ++ case MPI2_FUNCTION_SCSI_IO_REQUEST: ++ { ++ Mpi2SCSIIORequest_t *scsi_request = ++ (Mpi2SCSIIORequest_t *)mpi_request; ++ ++ snprintf(ioc->tmp_string, MPT_STRING_LENGTH, ++ "scsi_io, cmd(0x%02x), cdb_len(%d)", ++ scsi_request->CDB.CDB32[0], ++ le16_to_cpu(scsi_request->IoFlags) & 0xF); ++ desc = ioc->tmp_string; ++ break; ++ } ++ case MPI2_FUNCTION_SCSI_TASK_MGMT: ++ desc = "task_mgmt"; ++ break; ++ case MPI2_FUNCTION_IOC_INIT: ++ desc = "ioc_init"; ++ break; ++ case MPI2_FUNCTION_IOC_FACTS: ++ desc = "ioc_facts"; ++ break; ++ case MPI2_FUNCTION_CONFIG: ++ { ++ Mpi2ConfigRequest_t *config_request = ++ (Mpi2ConfigRequest_t *)mpi_request; ++ ++ snprintf(ioc->tmp_string, MPT_STRING_LENGTH, ++ "config, type(0x%02x), ext_type(0x%02x), number(%d)", ++ (config_request->Header.PageType & ++ MPI2_CONFIG_PAGETYPE_MASK), config_request->ExtPageType, ++ config_request->Header.PageNumber); ++ desc = ioc->tmp_string; ++ break; ++ } ++ case MPI2_FUNCTION_PORT_FACTS: ++ desc = "port_facts"; ++ break; ++ case MPI2_FUNCTION_PORT_ENABLE: ++ desc = "port_enable"; ++ break; ++ case MPI2_FUNCTION_EVENT_NOTIFICATION: ++ desc = "event_notification"; ++ break; ++ case MPI2_FUNCTION_FW_DOWNLOAD: ++ desc = "fw_download"; ++ break; ++ case MPI2_FUNCTION_FW_UPLOAD: ++ desc = "fw_upload"; ++ break; ++ case MPI2_FUNCTION_RAID_ACTION: ++ desc = "raid_action"; ++ break; ++ case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: ++ { ++ Mpi2SCSIIORequest_t *scsi_request = ++ (Mpi2SCSIIORequest_t *)mpi_request; ++ ++ snprintf(ioc->tmp_string, MPT_STRING_LENGTH, ++ "raid_pass, cmd(0x%02x), cdb_len(%d)", ++ scsi_request->CDB.CDB32[0], ++ le16_to_cpu(scsi_request->IoFlags) & 0xF); ++ desc = ioc->tmp_string; ++ break; ++ } ++ case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: ++ desc = "sas_iounit_cntl"; ++ break; ++ case MPI2_FUNCTION_SATA_PASSTHROUGH: ++ desc = "sata_pass"; ++ break; ++ case MPI2_FUNCTION_DIAG_BUFFER_POST: ++ desc = "diag_buffer_post"; ++ break; ++ case MPI2_FUNCTION_DIAG_RELEASE: ++ desc = "diag_release"; ++ break; ++ case MPI2_FUNCTION_SMP_PASSTHROUGH: ++ desc = "smp_passthrough"; ++ break; ++ } ++ ++ if (!desc) ++ return; ++ ++ pr_info(MPT3SAS_FMT "%s: %s, smid(%d)\n", ++ ioc->name, calling_function_name, desc, smid); ++ ++ if (!mpi_reply) ++ return; ++ ++ if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "\tiocstatus(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo)); ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_request->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { ++ Mpi2SCSIIOReply_t *scsi_reply = ++ (Mpi2SCSIIOReply_t *)mpi_reply; ++ struct _sas_device *sas_device = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = _ctl_sas_device_find_by_handle(ioc, ++ le16_to_cpu(scsi_reply->DevHandle)); ++ if (sas_device) { ++ pr_warn(MPT3SAS_FMT "\tsas_address(0x%016llx), phy(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->sas_address, sas_device->phy); ++ pr_warn(MPT3SAS_FMT ++ "\tenclosure_logical_id(0x%016llx), slot(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (scsi_reply->SCSIState || scsi_reply->SCSIStatus) ++ pr_info(MPT3SAS_FMT ++ "\tscsi_state(0x%02x), scsi_status" ++ "(0x%02x)\n", ioc->name, ++ scsi_reply->SCSIState, ++ scsi_reply->SCSIStatus); ++ } ++} ++ ++/** ++ * mpt2sas_ctl_done - ctl module completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: none. ++ * ++ * The callback handler when using ioc->ctl_cb_idx. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ Mpi2SCSIIOReply_t *scsiio_reply; ++ const void *sense_data; ++ u32 sz; ++ ++ if (ioc->ctl_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->ctl_cmds.smid != smid) ++ return 1; ++ ioc->ctl_cmds.status |= MPT3_CMD_COMPLETE; ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) { ++ memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ ioc->ctl_cmds.status |= MPT3_CMD_REPLY_VALID; ++ /* get sense data */ ++ if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_reply->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { ++ scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply; ++ if (scsiio_reply->SCSIState & ++ MPI2_SCSI_STATE_AUTOSENSE_VALID) { ++ sz = min_t(u32, SCSI_SENSE_BUFFERSIZE, ++ le32_to_cpu(scsiio_reply->SenseCount)); ++ sense_data = mpt2sas_base_get_sense_buffer(ioc, ++ smid); ++ memcpy(ioc->ctl_cmds.sense, sense_data, sz); ++ } ++ } ++ } ++ _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); ++ ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->ctl_cmds.done); ++ return 1; ++} ++ ++/** ++ * _ctl_check_event_type - determines when an event needs logging ++ * @ioc: per adapter object ++ * @event: firmware event ++ * ++ * The bitmask in ioc->event_type[] indicates which events should be ++ * be saved in the driver event_log. This bitmask is set by application. ++ * ++ * Returns 1 when event should be captured, or zero means no match. ++ */ ++static int ++_ctl_check_event_type(struct MPT3SAS_ADAPTER *ioc, u16 event) ++{ ++ u16 i; ++ u32 desired_event; ++ ++ if (event >= 128 || !event || !ioc->event_log) ++ return 0; ++ ++ desired_event = (1 << (event % 32)); ++ if (!desired_event) ++ desired_event = 1; ++ i = event / 32; ++ return desired_event & ioc->event_type[i]; ++} ++ ++/** ++ * mpt2sas_ctl_add_to_event_log - add event ++ * @ioc: per adapter object ++ * @mpi_reply: reply message frame ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_ctl_add_to_event_log(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventNotificationReply_t *mpi_reply) ++{ ++ struct MPT3_IOCTL_EVENTS *event_log; ++ u16 event; ++ int i; ++ u32 sz, event_data_sz; ++ u8 send_aen = 0; ++ ++ if (!ioc->event_log) ++ return; ++ ++ event = le16_to_cpu(mpi_reply->Event); ++ ++ if (_ctl_check_event_type(ioc, event)) { ++ ++ /* insert entry into circular event_log */ ++ i = ioc->event_context % MPT3SAS_CTL_EVENT_LOG_SIZE; ++ event_log = ioc->event_log; ++ event_log[i].event = event; ++ event_log[i].context = ioc->event_context++; ++ ++ event_data_sz = le16_to_cpu(mpi_reply->EventDataLength)*4; ++ sz = min_t(u32, event_data_sz, MPT3_EVENT_DATA_SIZE); ++ memset(event_log[i].data, 0, MPT3_EVENT_DATA_SIZE); ++ memcpy(event_log[i].data, mpi_reply->EventData, sz); ++ send_aen = 1; ++ } ++ ++ /* This aen_event_read_flag flag is set until the ++ * application has read the event log. ++ * For MPI2_EVENT_LOG_ENTRY_ADDED, we always notify. ++ */ ++ if (event == MPI2_EVENT_LOG_ENTRY_ADDED || ++ (send_aen && !ioc->aen_event_read_flag)) { ++ ioc->aen_event_read_flag = 1; ++ wake_up_interruptible(&ctl_poll_wait); ++ if (async_queue) ++ kill_fasync(&async_queue, SIGIO, POLL_IN); ++ } ++} ++ ++/** ++ * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time) ++ * @ioc: per adapter object ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt. ++ * ++ * This function merely adds a new work task into ioc->firmware_event_thread. ++ * The tasks are worked from _firmware_event_work in user context. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ++ u32 reply) ++{ ++ Mpi2EventNotificationReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) ++ mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); ++ return 1; ++} ++ ++/** ++ * _ctl_verify_adapter - validates ioc_number passed from application ++ * @ioc: per adapter object ++ * @iocpp: The ioc pointer is returned in this. ++ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device & ++ * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device. ++ * ++ * Return (-1) means error, else ioc_number. ++ */ ++static int ++_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp, ++ int mpi_version) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ int version = 0; ++ /* global ioc lock to protect controller on list operations */ ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { ++ if (ioc->id != ioc_number) ++ continue; ++ /* Check whether this ioctl command is from right ++ * ioctl device or not, if not continue the search. ++ */ ++ version = ioc->hba_mpi_version_belonged; ++ /* MPI25_VERSION and MPI26_VERSION uses same ioctl ++ * device. ++ */ ++ if (mpi_version == (MPI25_VERSION | MPI26_VERSION)) { ++ if ((version == MPI25_VERSION) || ++ (version == MPI26_VERSION)) ++ goto out; ++ else ++ continue; ++ } else { ++ if (version != mpi_version) ++ continue; ++ } ++out: ++ spin_unlock(&gioc_lock_mpt2sas); ++ *iocpp = ioc; ++ return ioc_number; ++ } ++ spin_unlock(&gioc_lock_mpt2sas); ++ *iocpp = NULL; ++ return -1; ++} ++ ++/** ++ * mpt2sas_ctl_reset_handler - reset callback handler (for ctl) ++ * @ioc: per adapter object ++ * @reset_phase: phase ++ * ++ * The handler for doing any required cleanup or initialization. ++ * ++ * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET, ++ * MPT3_IOC_DONE_RESET ++ */ ++void ++mpt2sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) ++{ ++ int i; ++ u8 issue_reset; ++ ++ switch (reset_phase) { ++ case MPT3_IOC_PRE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__)); ++ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { ++ if (!(ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED)) ++ continue; ++ if ((ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ continue; ++ mpt2sas_send_diag_release(ioc, i, &issue_reset); ++ } ++ break; ++ case MPT3_IOC_AFTER_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__)); ++ if (ioc->ctl_cmds.status & MPT3_CMD_PENDING) { ++ ioc->ctl_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->ctl_cmds.smid); ++ complete(&ioc->ctl_cmds.done); ++ } ++ break; ++ case MPT3_IOC_DONE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__)); ++ ++ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { ++ if (!(ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED)) ++ continue; ++ if ((ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ continue; ++ ioc->diag_buffer_status[i] |= ++ MPT3_DIAG_BUFFER_IS_DIAG_RESET; ++ } ++ break; ++ } ++} ++ ++/** ++ * _ctl_fasync_mpt2sas - ++ * @fd - ++ * @filep - ++ * @mode - ++ * ++ * Called when application request fasyn callback handler. ++ */ ++int ++_ctl_fasync_mpt2sas(int fd, struct file *filep, int mode) ++{ ++ return fasync_helper(fd, filep, mode, &async_queue); ++} ++ ++/** ++ * _ctl_poll_mpt2sas - ++ * @file - ++ * @wait - ++ * ++ */ ++unsigned int ++_ctl_poll_mpt2sas(struct file *filep, poll_table *wait) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ poll_wait(filep, &ctl_poll_wait, wait); ++ ++ /* global ioc lock to protect controller on list operations */ ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { ++ if (ioc->aen_event_read_flag) { ++ spin_unlock(&gioc_lock_mpt2sas); ++ return POLLIN | POLLRDNORM; ++ } ++ } ++ spin_unlock(&gioc_lock_mpt2sas); ++ return 0; ++} ++ ++/** ++ * _ctl_set_task_mid - assign an active smid to tm request ++ * @ioc: per adapter object ++ * @karg - (struct mpt3_ioctl_command) ++ * @tm_request - pointer to mf from user space ++ * ++ * Returns 0 when an smid if found, else fail. ++ * during failure, the reply frame is filled. ++ */ ++static int ++_ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command *karg, ++ Mpi2SCSITaskManagementRequest_t *tm_request) ++{ ++ u8 found = 0; ++ u16 i; ++ u16 handle; ++ struct scsi_cmnd *scmd; ++ struct MPT3SAS_DEVICE *priv_data; ++ unsigned long flags; ++ Mpi2SCSITaskManagementReply_t *tm_reply; ++ u32 sz; ++ u32 lun; ++ char *desc = NULL; ++ ++ if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) ++ desc = "abort_task"; ++ else if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) ++ desc = "query_task"; ++ else ++ return 0; ++ ++ lun = scsilun_to_int((struct scsi_lun *)tm_request->LUN); ++ ++ handle = le16_to_cpu(tm_request->DevHandle); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ for (i = ioc->scsiio_depth; i && !found; i--) { ++ scmd = ioc->scsi_lookup[i - 1].scmd; ++ if (scmd == NULL || scmd->device == NULL || ++ scmd->device->hostdata == NULL) ++ continue; ++ if (lun != scmd->device->lun) ++ continue; ++ priv_data = scmd->device->hostdata; ++ if (priv_data->sas_target == NULL) ++ continue; ++ if (priv_data->sas_target->handle != handle) ++ continue; ++ tm_request->TaskMID = cpu_to_le16(ioc->scsi_lookup[i - 1].smid); ++ found = 1; ++ } ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ if (!found) { ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), lun(%d), no active mid!!\n", ++ ioc->name, ++ desc, le16_to_cpu(tm_request->DevHandle), lun)); ++ tm_reply = ioc->ctl_cmds.reply; ++ tm_reply->DevHandle = tm_request->DevHandle; ++ tm_reply->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ tm_reply->TaskType = tm_request->TaskType; ++ tm_reply->MsgLength = sizeof(Mpi2SCSITaskManagementReply_t)/4; ++ tm_reply->VP_ID = tm_request->VP_ID; ++ tm_reply->VF_ID = tm_request->VF_ID; ++ sz = min_t(u32, karg->max_reply_bytes, ioc->reply_sz); ++ if (copy_to_user(karg->reply_frame_buf_ptr, ioc->ctl_cmds.reply, ++ sz)) ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ return 1; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), lun(%d), task_mid(%d)\n", ioc->name, ++ desc, le16_to_cpu(tm_request->DevHandle), lun, ++ le16_to_cpu(tm_request->TaskMID))); ++ return 0; ++} ++ ++/** ++ * _ctl_do_mpt_command - main handler for MPT3COMMAND opcode ++ * @ioc: per adapter object ++ * @karg - (struct mpt3_ioctl_command) ++ * @mf - pointer to mf in user space ++ */ ++static long ++_ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ++ void __user *mf) ++{ ++ MPI2RequestHeader_t *mpi_request = NULL, *request; ++ MPI2DefaultReply_t *mpi_reply; ++ u32 ioc_state; ++ u16 ioc_status; ++ u16 smid; ++ unsigned long timeout, timeleft; ++ u8 issue_reset; ++ u32 sz; ++ void *psge; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma = 0; ++ size_t data_out_sz = 0; ++ void *data_in = NULL; ++ dma_addr_t data_in_dma = 0; ++ size_t data_in_sz = 0; ++ long ret; ++ u16 wait_state_count; ++ ++ issue_reset = 0; ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ ret = -EAGAIN; ++ goto out; ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ ret = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, ++ __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL); ++ if (!mpi_request) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed obtaining a memory for mpi_request\n", ++ ioc->name, __func__); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ /* Check for overflow and wraparound */ ++ if (karg.data_sge_offset * 4 > ioc->request_sz || ++ karg.data_sge_offset > (UINT_MAX / 4)) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ /* copy in request message frame from user */ ++ if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, __LINE__, ++ __func__); ++ ret = -EFAULT; ++ goto out; ++ } ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ret = -EAGAIN; ++ goto out; ++ } ++ } else { ++ ++ smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ret = -EAGAIN; ++ goto out; ++ } ++ } ++ ++ ret = 0; ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memcpy(request, mpi_request, karg.data_sge_offset*4); ++ ioc->ctl_cmds.smid = smid; ++ data_out_sz = karg.data_out_size; ++ data_in_sz = karg.data_in_size; ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { ++ if (!le16_to_cpu(mpi_request->FunctionDependent1) || ++ le16_to_cpu(mpi_request->FunctionDependent1) > ++ ioc->facts.MaxDevHandle) { ++ ret = -EINVAL; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ /* obtain dma-able memory for data transfer */ ++ if (data_out_sz) /* WRITE */ { ++ data_out = pci_alloc_consistent(ioc->pdev, data_out_sz, ++ &data_out_dma); ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ if (copy_from_user(data_out, karg.data_out_buf_ptr, ++ data_out_sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -EFAULT; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ if (data_in_sz) /* READ */ { ++ data_in = pci_alloc_consistent(ioc->pdev, data_in_sz, ++ &data_in_dma); ++ if (!data_in) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ psge = (void *)request + (karg.data_sge_offset*4); ++ ++ /* send command to firmware */ ++ _ctl_display_some_debug(ioc, smid, "ctl_request", NULL); ++ ++ init_completion(&ioc->ctl_cmds.done); ++ switch (mpi_request->Function) { ++ case MPI2_FUNCTION_SCSI_IO_REQUEST: ++ case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: ++ { ++ Mpi2SCSIIORequest_t *scsiio_request = ++ (Mpi2SCSIIORequest_t *)request; ++ scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; ++ scsiio_request->SenseBufferLowAddress = ++ mpt2sas_base_get_sense_buffer_dma(ioc, smid); ++ memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE); ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) ++ mpt2sas_base_put_smid_scsi_io(ioc, smid, ++ le16_to_cpu(mpi_request->FunctionDependent1)); ++ else ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_SCSI_TASK_MGMT: ++ { ++ Mpi2SCSITaskManagementRequest_t *tm_request = ++ (Mpi2SCSITaskManagementRequest_t *)request; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n", ++ ioc->name, ++ le16_to_cpu(tm_request->DevHandle), tm_request->TaskType)); ++ ++ if (tm_request->TaskType == ++ MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK || ++ tm_request->TaskType == ++ MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) { ++ if (_ctl_set_task_mid(ioc, &karg, tm_request)) { ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } ++ ++ mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu( ++ tm_request->DevHandle)); ++ ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, 0); ++ break; ++ } ++ case MPI2_FUNCTION_SMP_PASSTHROUGH: ++ { ++ Mpi2SmpPassthroughRequest_t *smp_request = ++ (Mpi2SmpPassthroughRequest_t *)mpi_request; ++ u8 *data; ++ ++ /* ioc determines which port to use */ ++ smp_request->PhysicalPort = 0xFF; ++ if (smp_request->PassthroughFlags & ++ MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE) ++ data = (u8 *)&smp_request->SGL; ++ else { ++ if (unlikely(data_out == NULL)) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ mpt2sas_base_free_smid(ioc, smid); ++ ret = -EINVAL; ++ goto out; ++ } ++ data = data_out; ++ } ++ ++ if (data[1] == 0x91 && (data[10] == 1 || data[10] == 2)) { ++ ioc->ioc_link_reset_in_progress = 1; ++ ioc->ignore_loginfos = 1; ++ } ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_SATA_PASSTHROUGH: ++ case MPI2_FUNCTION_FW_DOWNLOAD: ++ case MPI2_FUNCTION_FW_UPLOAD: ++ { ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_TOOLBOX: ++ { ++ Mpi2ToolboxCleanRequest_t *toolbox_request = ++ (Mpi2ToolboxCleanRequest_t *)mpi_request; ++ ++ if (toolbox_request->Tool == MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL) { ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ } else { ++ ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ } ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: ++ { ++ Mpi2SasIoUnitControlRequest_t *sasiounit_request = ++ (Mpi2SasIoUnitControlRequest_t *)mpi_request; ++ ++ if (sasiounit_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ++ || sasiounit_request->Operation == ++ MPI2_SAS_OP_PHY_LINK_RESET) { ++ ioc->ioc_link_reset_in_progress = 1; ++ ioc->ignore_loginfos = 1; ++ } ++ /* drop to default case for posting the request */ ++ } ++ default: ++ ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, ++ data_in_dma, data_in_sz); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ break; ++ } ++ ++ if (karg.timeout < MPT3_IOCTL_DEFAULT_TIMEOUT) ++ timeout = MPT3_IOCTL_DEFAULT_TIMEOUT; ++ else ++ timeout = karg.timeout; ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ timeout*HZ); ++ if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { ++ Mpi2SCSITaskManagementRequest_t *tm_request = ++ (Mpi2SCSITaskManagementRequest_t *)mpi_request; ++ mpt2sas_scsih_clear_tm_flag(ioc, le16_to_cpu( ++ tm_request->DevHandle)); ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); ++ } else if ((mpi_request->Function == MPI2_FUNCTION_SMP_PASSTHROUGH || ++ mpi_request->Function == MPI2_FUNCTION_SAS_IO_UNIT_CONTROL) && ++ ioc->ioc_link_reset_in_progress) { ++ ioc->ioc_link_reset_in_progress = 0; ++ ioc->ignore_loginfos = 0; ++ } ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, karg.data_sge_offset); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT && ++ (ioc->logging_level & MPT_DEBUG_TM)) { ++ Mpi2SCSITaskManagementReply_t *tm_reply = ++ (Mpi2SCSITaskManagementReply_t *)mpi_reply; ++ ++ pr_info(MPT3SAS_FMT "TASK_MGMT: " \ ++ "IOCStatus(0x%04x), IOCLogInfo(0x%08x), " ++ "TerminationCount(0x%08x)\n", ioc->name, ++ le16_to_cpu(tm_reply->IOCStatus), ++ le32_to_cpu(tm_reply->IOCLogInfo), ++ le32_to_cpu(tm_reply->TerminationCount)); ++ } ++ ++ /* copy out xdata to user */ ++ if (data_in_sz) { ++ if (copy_to_user(karg.data_in_buf_ptr, data_in, ++ data_in_sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENODATA; ++ goto out; ++ } ++ } ++ ++ /* copy out reply message frame to user */ ++ if (karg.max_reply_bytes) { ++ sz = min_t(u32, karg.max_reply_bytes, ioc->reply_sz); ++ if (copy_to_user(karg.reply_frame_buf_ptr, ioc->ctl_cmds.reply, ++ sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENODATA; ++ goto out; ++ } ++ } ++ ++ /* copy out sense to user */ ++ if (karg.max_sense_bytes && (mpi_request->Function == ++ MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { ++ sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE); ++ if (copy_to_user(karg.sense_data_ptr, ioc->ctl_cmds.sense, ++ sz)) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ ret = -ENODATA; ++ goto out; ++ } ++ } ++ ++ issue_host_reset: ++ if (issue_reset) { ++ ret = -ENODATA; ++ if ((mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || ++ mpi_request->Function == ++ MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || ++ mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH)) { ++ pr_info(MPT3SAS_FMT "issue target reset: handle = (0x%04x)\n", ++ ioc->name, ++ le16_to_cpu(mpi_request->FunctionDependent1)); ++ mpt2sas_halt_firmware(ioc); ++ mpt2sas_scsih_issue_tm(ioc, ++ le16_to_cpu(mpi_request->FunctionDependent1), 0, 0, ++ 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30, ++ TM_MUTEX_ON); ++ } else ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ } ++ ++ out: ++ ++ /* free memory associated with sg buffers */ ++ if (data_in) ++ pci_free_consistent(ioc->pdev, data_in_sz, data_in, ++ data_in_dma); ++ ++ if (data_out) ++ pci_free_consistent(ioc->pdev, data_out_sz, data_out, ++ data_out_dma); ++ ++ kfree(mpi_request); ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return ret; ++} ++ ++/** ++ * _ctl_getiocinfo - main handler for MPT3IOCINFO opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_iocinfo karg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ memset(&karg, 0 , sizeof(karg)); ++ if (ioc->pfacts) ++ karg.port_number = ioc->pfacts[0].PortNumber; ++ karg.hw_rev = ioc->pdev->revision; ++ karg.pci_id = ioc->pdev->device; ++ karg.subsystem_device = ioc->pdev->subsystem_device; ++ karg.subsystem_vendor = ioc->pdev->subsystem_vendor; ++ karg.pci_information.u.bits.bus = ioc->pdev->bus->number; ++ karg.pci_information.u.bits.device = PCI_SLOT(ioc->pdev->devfn); ++ karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn); ++ karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus); ++ karg.firmware_version = ioc->facts.FWVersion.Word; ++ strcpy(karg.driver_version, ioc->driver_name); ++ strcat(karg.driver_version, "-"); ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ if (ioc->is_warpdrive) ++ karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200; ++ else ++ karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; ++ strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3; ++ strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION); ++ break; ++ } ++ karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); ++ ++ if (copy_to_user(arg, &karg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_eventquery - main handler for MPT3EVENTQUERY opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_eventquery(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_eventquery karg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ karg.event_entries = MPT3SAS_CTL_EVENT_LOG_SIZE; ++ memcpy(karg.event_types, ioc->event_type, ++ MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32)); ++ ++ if (copy_to_user(arg, &karg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_eventenable - main handler for MPT3EVENTENABLE opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_eventenable(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_eventenable karg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ memcpy(ioc->event_type, karg.event_types, ++ MPI2_EVENT_NOTIFY_EVENTMASK_WORDS * sizeof(u32)); ++ mpt2sas_base_validate_event_type(ioc, ioc->event_type); ++ ++ if (ioc->event_log) ++ return 0; ++ /* initialize event_log */ ++ ioc->event_context = 0; ++ ioc->aen_event_read_flag = 0; ++ ioc->event_log = kcalloc(MPT3SAS_CTL_EVENT_LOG_SIZE, ++ sizeof(struct MPT3_IOCTL_EVENTS), GFP_KERNEL); ++ if (!ioc->event_log) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_eventreport - main handler for MPT3EVENTREPORT opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_eventreport(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_eventreport karg; ++ u32 number_bytes, max_events, max; ++ struct mpt3_ioctl_eventreport __user *uarg = arg; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ number_bytes = karg.hdr.max_data_size - ++ sizeof(struct mpt3_ioctl_header); ++ max_events = number_bytes/sizeof(struct MPT3_IOCTL_EVENTS); ++ max = min_t(u32, MPT3SAS_CTL_EVENT_LOG_SIZE, max_events); ++ ++ /* If fewer than 1 event is requested, there must have ++ * been some type of error. ++ */ ++ if (!max || !ioc->event_log) ++ return -ENODATA; ++ ++ number_bytes = max * sizeof(struct MPT3_IOCTL_EVENTS); ++ if (copy_to_user(uarg->event_data, ioc->event_log, number_bytes)) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ /* reset flag so SIGIO can restart */ ++ ioc->aen_event_read_flag = 0; ++ return 0; ++} ++ ++/** ++ * _ctl_do_reset - main handler for MPT3HARDRESET opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_diag_reset karg; ++ int retval; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery || ++ ioc->is_driver_loading) ++ return -EAGAIN; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name, ++ __func__)); ++ ++ retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ pr_info(MPT3SAS_FMT "host reset: %s\n", ++ ioc->name, ((!retval) ? "SUCCESS" : "FAILED")); ++ return 0; ++} ++ ++/** ++ * _ctl_btdh_search_sas_device - searching for sas device ++ * @ioc: per adapter object ++ * @btdh: btdh ioctl payload ++ */ ++static int ++_ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc, ++ struct mpt3_ioctl_btdh_mapping *btdh) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ int rc = 0; ++ ++ if (list_empty(&ioc->sas_device_list)) ++ return rc; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF && ++ btdh->handle == sas_device->handle) { ++ btdh->bus = sas_device->channel; ++ btdh->id = sas_device->id; ++ rc = 1; ++ goto out; ++ } else if (btdh->bus == sas_device->channel && btdh->id == ++ sas_device->id && btdh->handle == 0xFFFF) { ++ btdh->handle = sas_device->handle; ++ rc = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_btdh_search_raid_device - searching for raid device ++ * @ioc: per adapter object ++ * @btdh: btdh ioctl payload ++ */ ++static int ++_ctl_btdh_search_raid_device(struct MPT3SAS_ADAPTER *ioc, ++ struct mpt3_ioctl_btdh_mapping *btdh) ++{ ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ int rc = 0; ++ ++ if (list_empty(&ioc->raid_device_list)) ++ return rc; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (btdh->bus == 0xFFFFFFFF && btdh->id == 0xFFFFFFFF && ++ btdh->handle == raid_device->handle) { ++ btdh->bus = raid_device->channel; ++ btdh->id = raid_device->id; ++ rc = 1; ++ goto out; ++ } else if (btdh->bus == raid_device->channel && btdh->id == ++ raid_device->id && btdh->handle == 0xFFFF) { ++ btdh->handle = raid_device->handle; ++ rc = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_btdh_mapping - main handler for MPT3BTDHMAPPING opcode ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_btdh_mapping(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_ioctl_btdh_mapping karg; ++ int rc; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ rc = _ctl_btdh_search_sas_device(ioc, &karg); ++ if (!rc) ++ _ctl_btdh_search_raid_device(ioc, &karg); ++ ++ if (copy_to_user(arg, &karg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * _ctl_diag_capability - return diag buffer capability ++ * @ioc: per adapter object ++ * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED ++ * ++ * returns 1 when diag buffer support is enabled in firmware ++ */ ++static u8 ++_ctl_diag_capability(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type) ++{ ++ u8 rc = 0; ++ ++ switch (buffer_type) { ++ case MPI2_DIAG_BUF_TYPE_TRACE: ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) ++ rc = 1; ++ break; ++ case MPI2_DIAG_BUF_TYPE_SNAPSHOT: ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) ++ rc = 1; ++ break; ++ case MPI2_DIAG_BUF_TYPE_EXTENDED: ++ if (ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) ++ rc = 1; ++ } ++ ++ return rc; ++} ++ ++ ++/** ++ * _ctl_diag_register_2 - wrapper for registering diag buffer support ++ * @ioc: per adapter object ++ * @diag_register: the diag_register struct passed in from user space ++ * ++ */ ++static long ++_ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, ++ struct mpt3_diag_register *diag_register) ++{ ++ int rc, i; ++ void *request_data = NULL; ++ dma_addr_t request_data_dma; ++ u32 request_data_sz = 0; ++ Mpi2DiagBufferPostRequest_t *mpi_request; ++ Mpi2DiagBufferPostReply_t *mpi_reply; ++ u8 buffer_type; ++ unsigned long timeleft; ++ u16 smid; ++ u16 ioc_status; ++ u32 ioc_state; ++ u8 issue_reset = 0; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ buffer_type = diag_register->buffer_type; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if (ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) { ++ pr_err(MPT3SAS_FMT ++ "%s: already has a registered buffer for buffer_type(0x%02x)\n", ++ ioc->name, __func__, ++ buffer_type); ++ return -EINVAL; ++ } ++ ++ if (diag_register->requested_buffer_size % 4) { ++ pr_err(MPT3SAS_FMT ++ "%s: the requested_buffer_size is not 4 byte aligned\n", ++ ioc->name, __func__); ++ return -EINVAL; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->ctl_cmds.smid = smid; ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ request_data_sz = diag_register->requested_buffer_size; ++ ioc->unique_id[buffer_type] = diag_register->unique_id; ++ ioc->diag_buffer_status[buffer_type] = 0; ++ memcpy(ioc->product_specific[buffer_type], ++ diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS); ++ ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags; ++ ++ if (request_data) { ++ request_data_dma = ioc->diag_buffer_dma[buffer_type]; ++ if (request_data_sz != ioc->diag_buffer_sz[buffer_type]) { ++ pci_free_consistent(ioc->pdev, ++ ioc->diag_buffer_sz[buffer_type], ++ request_data, request_data_dma); ++ request_data = NULL; ++ } ++ } ++ ++ if (request_data == NULL) { ++ ioc->diag_buffer_sz[buffer_type] = 0; ++ ioc->diag_buffer_dma[buffer_type] = 0; ++ request_data = pci_alloc_consistent( ++ ioc->pdev, request_data_sz, &request_data_dma); ++ if (request_data == NULL) { ++ pr_err(MPT3SAS_FMT "%s: failed allocating memory" \ ++ " for diag buffers, requested size(%d)\n", ++ ioc->name, __func__, request_data_sz); ++ mpt2sas_base_free_smid(ioc, smid); ++ return -ENOMEM; ++ } ++ ioc->diag_buffer[buffer_type] = request_data; ++ ioc->diag_buffer_sz[buffer_type] = request_data_sz; ++ ioc->diag_buffer_dma[buffer_type] = request_data_dma; ++ } ++ ++ mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; ++ mpi_request->BufferType = diag_register->buffer_type; ++ mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags); ++ mpi_request->BufferAddress = cpu_to_le64(request_data_dma); ++ mpi_request->BufferLength = cpu_to_le32(request_data_sz); ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: diag_buffer(0x%p), dma(0x%llx), sz(%d)\n", ++ ioc->name, __func__, request_data, ++ (unsigned long long)request_data_dma, ++ le32_to_cpu(mpi_request->BufferLength))); ++ ++ for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) ++ mpi_request->ProductSpecific[i] = ++ cpu_to_le32(ioc->product_specific[buffer_type][i]); ++ ++ init_completion(&ioc->ctl_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); ++ ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2DiagBufferPostRequest_t)/4); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ /* process the completed Reply Message Frame */ ++ if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) { ++ pr_err(MPT3SAS_FMT "%s: no reply message\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_REGISTERED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: success\n", ++ ioc->name, __func__)); ++ } else { ++ pr_info(MPT3SAS_FMT ++ "%s: ioc_status(0x%04x) log_info(0x%08x)\n", ++ ioc->name, __func__, ++ ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); ++ rc = -EFAULT; ++ } ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ out: ++ ++ if (rc && request_data) ++ pci_free_consistent(ioc->pdev, request_data_sz, ++ request_data, request_data_dma); ++ ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return rc; ++} ++ ++/** ++ * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time ++ * @ioc: per adapter object ++ * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1 ++ * ++ * This is called when command line option diag_buffer_enable is enabled ++ * at driver load time. ++ */ ++void ++mpt2sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register) ++{ ++ struct mpt3_diag_register diag_register; ++ ++ memset(&diag_register, 0, sizeof(struct mpt3_diag_register)); ++ ++ if (bits_to_register & 1) { ++ pr_info(MPT3SAS_FMT "registering trace buffer support\n", ++ ioc->name); ++ ioc->diag_trigger_master.MasterData = ++ (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; ++ /* register for 2MB buffers */ ++ diag_register.requested_buffer_size = 2 * (1024 * 1024); ++ diag_register.unique_id = 0x7075900; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } ++ ++ if (bits_to_register & 2) { ++ pr_info(MPT3SAS_FMT "registering snapshot buffer support\n", ++ ioc->name); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT; ++ /* register for 2MB buffers */ ++ diag_register.requested_buffer_size = 2 * (1024 * 1024); ++ diag_register.unique_id = 0x7075901; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } ++ ++ if (bits_to_register & 4) { ++ pr_info(MPT3SAS_FMT "registering extended buffer support\n", ++ ioc->name); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED; ++ /* register for 2MB buffers */ ++ diag_register.requested_buffer_size = 2 * (1024 * 1024); ++ diag_register.unique_id = 0x7075901; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } ++} ++ ++/** ++ * _ctl_diag_register - application register with driver ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ * ++ * This will allow the driver to setup any required buffers that will be ++ * needed by firmware to communicate with the driver. ++ */ ++static long ++_ctl_diag_register(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_register karg; ++ long rc; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ rc = _ctl_diag_register_2(ioc, &karg); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_unregister - application unregister with driver ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ * ++ * This will allow the driver to cleanup any memory allocated for diag ++ * messages and to free up any resources. ++ */ ++static long ++_ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_unregister karg; ++ void *request_data; ++ dma_addr_t request_data_dma; ++ u32 request_data_sz; ++ u8 buffer_type; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ buffer_type = karg.unique_id & 0x000000ff; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is not registered\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) has not been released\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have memory allocated for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ request_data_sz = ioc->diag_buffer_sz[buffer_type]; ++ request_data_dma = ioc->diag_buffer_dma[buffer_type]; ++ pci_free_consistent(ioc->pdev, request_data_sz, ++ request_data, request_data_dma); ++ ioc->diag_buffer[buffer_type] = NULL; ++ ioc->diag_buffer_status[buffer_type] = 0; ++ return 0; ++} ++ ++/** ++ * _ctl_diag_query - query relevant info associated with diag buffers ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ * ++ * The application will send only buffer_type and unique_id. Driver will ++ * inspect unique_id first, if valid, fill in all the info. If unique_id is ++ * 0x00, the driver will return info specified by Buffer Type. ++ */ ++static long ++_ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_query karg; ++ void *request_data; ++ int i; ++ u8 buffer_type; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ karg.application_flags = 0; ++ buffer_type = karg.buffer_type; ++ ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is not registered\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ ++ if (karg.unique_id & 0xffffff00) { ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have buffer for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ if (ioc->diag_buffer_status[buffer_type] & MPT3_DIAG_BUFFER_IS_RELEASED) ++ karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | ++ MPT3_APP_FLAGS_BUFFER_VALID); ++ else ++ karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | ++ MPT3_APP_FLAGS_BUFFER_VALID | ++ MPT3_APP_FLAGS_FW_BUFFER_ACCESS); ++ ++ for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) ++ karg.product_specific[i] = ++ ioc->product_specific[buffer_type][i]; ++ ++ karg.total_buffer_size = ioc->diag_buffer_sz[buffer_type]; ++ karg.driver_added_buffer_size = 0; ++ karg.unique_id = ioc->unique_id[buffer_type]; ++ karg.diagnostic_flags = ioc->diagnostic_flags[buffer_type]; ++ ++ if (copy_to_user(arg, &karg, sizeof(struct mpt3_diag_query))) { ++ pr_err(MPT3SAS_FMT ++ "%s: unable to write mpt3_diag_query data @ %p\n", ++ ioc->name, __func__, arg); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++/** ++ * mpt2sas_send_diag_release - Diag Release Message ++ * @ioc: per adapter object ++ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED ++ * @issue_reset - specifies whether host reset is required. ++ * ++ */ ++int ++mpt2sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, ++ u8 *issue_reset) ++{ ++ Mpi2DiagReleaseRequest_t *mpi_request; ++ Mpi2DiagReleaseReply_t *mpi_reply; ++ u16 smid; ++ u16 ioc_status; ++ u32 ioc_state; ++ int rc; ++ unsigned long timeleft; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ rc = 0; ++ *issue_reset = 0; ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_RELEASED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: skipping due to FAULT state\n", ioc->name, ++ __func__)); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->ctl_cmds.smid = smid; ++ ++ mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE; ++ mpi_request->BufferType = buffer_type; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ init_completion(&ioc->ctl_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); ++ ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2DiagReleaseRequest_t)/4); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ *issue_reset = 1; ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ /* process the completed Reply Message Frame */ ++ if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) { ++ pr_err(MPT3SAS_FMT "%s: no reply message\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_RELEASED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: success\n", ++ ioc->name, __func__)); ++ } else { ++ pr_info(MPT3SAS_FMT ++ "%s: ioc_status(0x%04x) log_info(0x%08x)\n", ++ ioc->name, __func__, ++ ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); ++ rc = -EFAULT; ++ } ++ ++ out: ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return rc; ++} ++ ++/** ++ * _ctl_diag_release - request to send Diag Release Message to firmware ++ * @arg - user space buffer containing ioctl content ++ * ++ * This allows ownership of the specified buffer to returned to the driver, ++ * allowing an application to read the buffer without fear that firmware is ++ * overwritting information in the buffer. ++ */ ++static long ++_ctl_diag_release(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_release karg; ++ void *request_data; ++ int rc; ++ u8 buffer_type; ++ u8 issue_reset = 0; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ buffer_type = karg.unique_id & 0x000000ff; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is not registered\n", ++ ioc->name, __func__, buffer_type); ++ return -EINVAL; ++ } ++ ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ ++ if (ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is already released\n", ++ ioc->name, __func__, ++ buffer_type); ++ return 0; ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have memory allocated for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ /* buffers were released by due to host reset */ ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_DIAG_RESET)) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_RELEASED; ++ ioc->diag_buffer_status[buffer_type] &= ++ ~MPT3_DIAG_BUFFER_IS_DIAG_RESET; ++ pr_err(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) was released due to host reset\n", ++ ioc->name, __func__, buffer_type); ++ return 0; ++ } ++ ++ rc = mpt2sas_send_diag_release(ioc, buffer_type, &issue_reset); ++ ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ return rc; ++} ++ ++/** ++ * _ctl_diag_read_buffer - request for copy of the diag buffer ++ * @ioc: per adapter object ++ * @arg - user space buffer containing ioctl content ++ */ ++static long ++_ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ++{ ++ struct mpt3_diag_read_buffer karg; ++ struct mpt3_diag_read_buffer __user *uarg = arg; ++ void *request_data, *diag_data; ++ Mpi2DiagBufferPostRequest_t *mpi_request; ++ Mpi2DiagBufferPostReply_t *mpi_reply; ++ int rc, i; ++ u8 buffer_type; ++ unsigned long timeleft, request_size, copy_size; ++ u16 smid; ++ u16 ioc_status; ++ u8 issue_reset = 0; ++ ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, ++ __func__)); ++ ++ buffer_type = karg.unique_id & 0x000000ff; ++ if (!_ctl_diag_capability(ioc, buffer_type)) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have capability for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -EPERM; ++ } ++ ++ if (karg.unique_id != ioc->unique_id[buffer_type]) { ++ pr_err(MPT3SAS_FMT ++ "%s: unique_id(0x%08x) is not registered\n", ++ ioc->name, __func__, karg.unique_id); ++ return -EINVAL; ++ } ++ ++ request_data = ioc->diag_buffer[buffer_type]; ++ if (!request_data) { ++ pr_err(MPT3SAS_FMT ++ "%s: doesn't have buffer for buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type); ++ return -ENOMEM; ++ } ++ ++ request_size = ioc->diag_buffer_sz[buffer_type]; ++ ++ if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { ++ pr_err(MPT3SAS_FMT "%s: either the starting_offset " \ ++ "or bytes_to_read are not 4 byte aligned\n", ioc->name, ++ __func__); ++ return -EINVAL; ++ } ++ ++ if (karg.starting_offset > request_size) ++ return -EINVAL; ++ ++ diag_data = (void *)(request_data + karg.starting_offset); ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: diag_buffer(%p), offset(%d), sz(%d)\n", ++ ioc->name, __func__, ++ diag_data, karg.starting_offset, karg.bytes_to_read)); ++ ++ /* Truncate data on requests that are too large */ ++ if ((diag_data + karg.bytes_to_read < diag_data) || ++ (diag_data + karg.bytes_to_read > request_data + request_size)) ++ copy_size = request_size - karg.starting_offset; ++ else ++ copy_size = karg.bytes_to_read; ++ ++ if (copy_to_user((void __user *)uarg->diagnostic_data, ++ diag_data, copy_size)) { ++ pr_err(MPT3SAS_FMT ++ "%s: Unable to write mpt_diag_read_buffer_t data @ %p\n", ++ ioc->name, __func__, diag_data); ++ return -EFAULT; ++ } ++ ++ if ((karg.flags & MPT3_FLAGS_REREGISTER) == 0) ++ return 0; ++ ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: Reregister buffer_type(0x%02x)\n", ++ ioc->name, __func__, buffer_type)); ++ if ((ioc->diag_buffer_status[buffer_type] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: buffer_type(0x%02x) is still registered\n", ++ ioc->name, __func__, buffer_type)); ++ return 0; ++ } ++ /* Get a free request frame and save the message context. ++ */ ++ ++ if (ioc->ctl_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: ctl_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ ioc->ctl_cmds.status = MPT3_CMD_PENDING; ++ memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->ctl_cmds.smid = smid; ++ ++ mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; ++ mpi_request->BufferType = buffer_type; ++ mpi_request->BufferLength = ++ cpu_to_le32(ioc->diag_buffer_sz[buffer_type]); ++ mpi_request->BufferAddress = ++ cpu_to_le64(ioc->diag_buffer_dma[buffer_type]); ++ for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) ++ mpi_request->ProductSpecific[i] = ++ cpu_to_le32(ioc->product_specific[buffer_type][i]); ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ ++ init_completion(&ioc->ctl_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, ++ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); ++ ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ioc->name, ++ __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2DiagBufferPostRequest_t)/4); ++ if (!(ioc->ctl_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ /* process the completed Reply Message Frame */ ++ if ((ioc->ctl_cmds.status & MPT3_CMD_REPLY_VALID) == 0) { ++ pr_err(MPT3SAS_FMT "%s: no reply message\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ mpi_reply = ioc->ctl_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ ioc->diag_buffer_status[buffer_type] |= ++ MPT3_DIAG_BUFFER_IS_REGISTERED; ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT "%s: success\n", ++ ioc->name, __func__)); ++ } else { ++ pr_info(MPT3SAS_FMT ++ "%s: ioc_status(0x%04x) log_info(0x%08x)\n", ++ ioc->name, __func__, ++ ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo)); ++ rc = -EFAULT; ++ } ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ out: ++ ++ ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ++ return rc; ++} ++ ++ ++ ++#ifdef CONFIG_COMPAT ++/** ++ * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. ++ * @ioc: per adapter object ++ * @cmd - ioctl opcode ++ * @arg - (struct mpt3_ioctl_command32) ++ * ++ * MPT3COMMAND32 - Handle 32bit applications running on 64bit os. ++ */ ++static long ++_ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd, ++ void __user *arg) ++{ ++ struct mpt3_ioctl_command32 karg32; ++ struct mpt3_ioctl_command32 __user *uarg; ++ struct mpt3_ioctl_command karg; ++ ++ if (_IOC_SIZE(cmd) != sizeof(struct mpt3_ioctl_command32)) ++ return -EINVAL; ++ ++ uarg = (struct mpt3_ioctl_command32 __user *) arg; ++ ++ if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ memset(&karg, 0, sizeof(struct mpt3_ioctl_command)); ++ karg.hdr.ioc_number = karg32.hdr.ioc_number; ++ karg.hdr.port_number = karg32.hdr.port_number; ++ karg.hdr.max_data_size = karg32.hdr.max_data_size; ++ karg.timeout = karg32.timeout; ++ karg.max_reply_bytes = karg32.max_reply_bytes; ++ karg.data_in_size = karg32.data_in_size; ++ karg.data_out_size = karg32.data_out_size; ++ karg.max_sense_bytes = karg32.max_sense_bytes; ++ karg.data_sge_offset = karg32.data_sge_offset; ++ karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); ++ karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); ++ karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); ++ karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); ++ return _ctl_do_mpt_command(ioc, karg, &uarg->mf); ++} ++#endif ++ ++/** ++ * _ctl_ioctl_main - main ioctl entry point ++ * @file - (struct file) ++ * @cmd - ioctl opcode ++ * @arg - user space data buffer ++ * @compat - handles 32 bit applications in 64bit os ++ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device & ++ * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device. ++ */ ++static long ++_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, ++ u8 compat, u16 mpi_version) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ struct mpt3_ioctl_header ioctl_header; ++ enum block_state state; ++ long ret = -EINVAL; ++ ++ /* get IOCTL header */ ++ if (copy_from_user(&ioctl_header, (char __user *)arg, ++ sizeof(struct mpt3_ioctl_header))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ return -EFAULT; ++ } ++ ++ if (_ctl_verify_adapter(ioctl_header.ioc_number, ++ &ioc, mpi_version) == -1 || !ioc) ++ return -ENODEV; ++ ++ /* pci_access_mutex lock acquired by ioctl path */ ++ mutex_lock(&ioc->pci_access_mutex); ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery || ++ ioc->is_driver_loading || ioc->remove_host) { ++ ret = -EAGAIN; ++ goto out_unlock_pciaccess; ++ } ++ ++ state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; ++ if (state == NON_BLOCKING) { ++ if (!mutex_trylock(&ioc->ctl_cmds.mutex)) { ++ ret = -EAGAIN; ++ goto out_unlock_pciaccess; ++ } ++ } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { ++ ret = -ERESTARTSYS; ++ goto out_unlock_pciaccess; ++ } ++ ++ ++ switch (cmd) { ++ case MPT3IOCINFO: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_iocinfo)) ++ ret = _ctl_getiocinfo(ioc, arg); ++ break; ++#ifdef CONFIG_COMPAT ++ case MPT3COMMAND32: ++#endif ++ case MPT3COMMAND: ++ { ++ struct mpt3_ioctl_command __user *uarg; ++ struct mpt3_ioctl_command karg; ++ ++#ifdef CONFIG_COMPAT ++ if (compat) { ++ ret = _ctl_compat_mpt_command(ioc, cmd, arg); ++ break; ++ } ++#endif ++ if (copy_from_user(&karg, arg, sizeof(karg))) { ++ pr_err("failure at %s:%d/%s()!\n", ++ __FILE__, __LINE__, __func__); ++ ret = -EFAULT; ++ break; ++ } ++ ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_command)) { ++ uarg = arg; ++ ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf); ++ } ++ break; ++ } ++ case MPT3EVENTQUERY: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_eventquery)) ++ ret = _ctl_eventquery(ioc, arg); ++ break; ++ case MPT3EVENTENABLE: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_eventenable)) ++ ret = _ctl_eventenable(ioc, arg); ++ break; ++ case MPT3EVENTREPORT: ++ ret = _ctl_eventreport(ioc, arg); ++ break; ++ case MPT3HARDRESET: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_diag_reset)) ++ ret = _ctl_do_reset(ioc, arg); ++ break; ++ case MPT3BTDHMAPPING: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_btdh_mapping)) ++ ret = _ctl_btdh_mapping(ioc, arg); ++ break; ++ case MPT3DIAGREGISTER: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_register)) ++ ret = _ctl_diag_register(ioc, arg); ++ break; ++ case MPT3DIAGUNREGISTER: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_unregister)) ++ ret = _ctl_diag_unregister(ioc, arg); ++ break; ++ case MPT3DIAGQUERY: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_query)) ++ ret = _ctl_diag_query(ioc, arg); ++ break; ++ case MPT3DIAGRELEASE: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_release)) ++ ret = _ctl_diag_release(ioc, arg); ++ break; ++ case MPT3DIAGREADBUFFER: ++ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer)) ++ ret = _ctl_diag_read_buffer(ioc, arg); ++ break; ++ default: ++ dctlprintk(ioc, pr_info(MPT3SAS_FMT ++ "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); ++ break; ++ } ++ ++ mutex_unlock(&ioc->ctl_cmds.mutex); ++out_unlock_pciaccess: ++ mutex_unlock(&ioc->pci_access_mutex); ++ return ret; ++} ++ ++/** ++ * _ctl_ioctl_mpt2sas - mpt3ctl main ioctl entry point (unlocked) ++ * @file - (struct file) ++ * @cmd - ioctl opcode ++ * @arg - ++ */ ++long ++_ctl_ioctl_mpt2sas(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ /* pass MPI25_VERSION | MPI26_VERSION value, ++ * to indicate that this ioctl cmd ++ * came from mpt3ctl ioctl device. ++ */ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, ++ MPI25_VERSION | MPI26_VERSION); ++ return ret; ++} ++ ++/** ++ * _ctl_mpt2_ioctl_mpt2sas - mpt2ctl main ioctl entry point (unlocked) ++ * @file - (struct file) ++ * @cmd - ioctl opcode ++ * @arg - ++ */ ++long ++_ctl_mpt2_ioctl_mpt2sas(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long ret; ++ ++ /* pass MPI2_VERSION value, to indicate that this ioctl cmd ++ * came from mpt2ctl ioctl device. ++ */ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION); ++ return ret; ++} ++#ifdef CONFIG_COMPAT ++/** ++ *_ ctl_ioctl_compat - main ioctl entry point (compat) ++ * @file - ++ * @cmd - ++ * @arg - ++ * ++ * This routine handles 32 bit applications in 64bit os. ++ */ ++long ++_ctl_ioctl_compat_mpt2sas(struct file *file, unsigned cmd, unsigned long arg) ++{ ++ long ret; ++ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, ++ MPI25_VERSION | MPI26_VERSION); ++ return ret; ++} ++ ++/** ++ *_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat) ++ * @file - ++ * @cmd - ++ * @arg - ++ * ++ * This routine handles 32 bit applications in 64bit os. ++ */ ++long ++_ctl_mpt2_ioctl_compat_mpt2sas(struct file *file, unsigned cmd, unsigned long arg) ++{ ++ long ret; ++ ++ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION); ++ return ret; ++} ++#endif ++ ++/* scsi host attributes */ ++/** ++ * _ctl_version_fw_show - firmware version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_fw_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n", ++ (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, ++ (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, ++ (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ++ ioc->facts.FWVersion.Word & 0x000000FF); ++} ++static DEVICE_ATTR(version_fw, S_IRUGO, _ctl_version_fw_show, NULL); ++ ++/** ++ * _ctl_version_bios_show - bios version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_bios_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ u32 version = le32_to_cpu(ioc->bios_pg3.BiosVersion); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n", ++ (version & 0xFF000000) >> 24, ++ (version & 0x00FF0000) >> 16, ++ (version & 0x0000FF00) >> 8, ++ version & 0x000000FF); ++} ++static DEVICE_ATTR(version_bios, S_IRUGO, _ctl_version_bios_show, NULL); ++ ++/** ++ * _ctl_version_mpi_show - MPI (message passing interface) version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_mpi_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%03x.%02x\n", ++ ioc->facts.MsgVersion, ioc->facts.HeaderVersion >> 8); ++} ++static DEVICE_ATTR(version_mpi, S_IRUGO, _ctl_version_mpi_show, NULL); ++ ++/** ++ * _ctl_version_product_show - product name ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_product_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.ChipName); ++} ++static DEVICE_ATTR(version_product, S_IRUGO, _ctl_version_product_show, NULL); ++ ++/** ++ * _ctl_version_nvdata_persistent_show - ndvata persistent version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_nvdata_persistent_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%08xh\n", ++ le32_to_cpu(ioc->iounit_pg0.NvdataVersionPersistent.Word)); ++} ++static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO, ++ _ctl_version_nvdata_persistent_show, NULL); ++ ++/** ++ * _ctl_version_nvdata_default_show - nvdata default version ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_version_nvdata_default_show(struct device *cdev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%08xh\n", ++ le32_to_cpu(ioc->iounit_pg0.NvdataVersionDefault.Word)); ++} ++static DEVICE_ATTR(version_nvdata_default, S_IRUGO, ++ _ctl_version_nvdata_default_show, NULL); ++ ++/** ++ * _ctl_board_name_show - board name ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_board_name_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardName); ++} ++static DEVICE_ATTR(board_name, S_IRUGO, _ctl_board_name_show, NULL); ++ ++/** ++ * _ctl_board_assembly_show - board assembly name ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_board_assembly_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardAssembly); ++} ++static DEVICE_ATTR(board_assembly, S_IRUGO, _ctl_board_assembly_show, NULL); ++ ++/** ++ * _ctl_board_tracer_show - board tracer number ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_board_tracer_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, 16, "%s\n", ioc->manu_pg0.BoardTracerNumber); ++} ++static DEVICE_ATTR(board_tracer, S_IRUGO, _ctl_board_tracer_show, NULL); ++ ++/** ++ * _ctl_io_delay_show - io missing delay ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is for firmware implemention for deboucing device ++ * removal events. ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_io_delay_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay); ++} ++static DEVICE_ATTR(io_delay, S_IRUGO, _ctl_io_delay_show, NULL); ++ ++/** ++ * _ctl_device_delay_show - device missing delay ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is for firmware implemention for deboucing device ++ * removal events. ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_device_delay_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay); ++} ++static DEVICE_ATTR(device_delay, S_IRUGO, _ctl_device_delay_show, NULL); ++ ++/** ++ * _ctl_fw_queue_depth_show - global credits ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is firmware queue depth limit ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_fw_queue_depth_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->facts.RequestCredit); ++} ++static DEVICE_ATTR(fw_queue_depth, S_IRUGO, _ctl_fw_queue_depth_show, NULL); ++ ++/** ++ * _ctl_sas_address_show - sas address ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is the controller sas address ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_host_sas_address_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "0x%016llx\n", ++ (unsigned long long)ioc->sas_hba.sas_address); ++} ++static DEVICE_ATTR(host_sas_address, S_IRUGO, ++ _ctl_host_sas_address_show, NULL); ++ ++/** ++ * _ctl_logging_level_show - logging level ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_logging_level_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->logging_level); ++} ++static ssize_t ++_ctl_logging_level_store(struct device *cdev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int val = 0; ++ ++ if (sscanf(buf, "%x", &val) != 1) ++ return -EINVAL; ++ ++ ioc->logging_level = val; ++ pr_info(MPT3SAS_FMT "logging_level=%08xh\n", ioc->name, ++ ioc->logging_level); ++ return strlen(buf); ++} ++static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, _ctl_logging_level_show, ++ _ctl_logging_level_store); ++ ++/** ++ * _ctl_fwfault_debug_show - show/store fwfault_debug ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * mpt2sas_fwfault_debug is command line option ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_fwfault_debug_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug); ++} ++static ssize_t ++_ctl_fwfault_debug_store(struct device *cdev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int val = 0; ++ ++ if (sscanf(buf, "%d", &val) != 1) ++ return -EINVAL; ++ ++ ioc->fwfault_debug = val; ++ pr_info(MPT3SAS_FMT "fwfault_debug=%d\n", ioc->name, ++ ioc->fwfault_debug); ++ return strlen(buf); ++} ++static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR, ++ _ctl_fwfault_debug_show, _ctl_fwfault_debug_store); ++ ++/** ++ * _ctl_ioc_reset_count_show - ioc reset count ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is firmware queue depth limit ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", ioc->ioc_reset_count); ++} ++static DEVICE_ATTR(ioc_reset_count, S_IRUGO, _ctl_ioc_reset_count_show, NULL); ++ ++/** ++ * _ctl_ioc_reply_queue_count_show - number of reply queues ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is number of reply queues ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_ioc_reply_queue_count_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ u8 reply_queue_count; ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ if ((ioc->facts.IOCCapabilities & ++ MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable) ++ reply_queue_count = ioc->reply_queue_count; ++ else ++ reply_queue_count = 1; ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", reply_queue_count); ++} ++static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show, ++ NULL); ++ ++/** ++ * _ctl_BRM_status_show - Backup Rail Monitor Status ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is number of reply queues ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ Mpi2IOUnitPage3_t *io_unit_pg3 = NULL; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 backup_rail_monitor_status = 0; ++ u16 ioc_status; ++ int sz; ++ ssize_t rc = 0; ++ ++ if (!ioc->is_warpdrive) { ++ pr_err(MPT3SAS_FMT "%s: BRM attribute is only for" ++ " warpdrive\n", ioc->name, __func__); ++ goto out; ++ } ++ /* pci_access_mutex lock acquired by sysfs show path */ ++ mutex_lock(&ioc->pci_access_mutex); ++ if (ioc->pci_error_recovery || ioc->remove_host) { ++ mutex_unlock(&ioc->pci_access_mutex); ++ return 0; ++ } ++ ++ /* allocate upto GPIOVal 36 entries */ ++ sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); ++ io_unit_pg3 = kzalloc(sz, GFP_KERNEL); ++ if (!io_unit_pg3) { ++ pr_err(MPT3SAS_FMT "%s: failed allocating memory " ++ "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz); ++ goto out; ++ } ++ ++ if (mpt2sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) != ++ 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed reading iounit_pg3\n", ioc->name, ++ __func__); ++ goto out; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "%s: iounit_pg3 failed with " ++ "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status); ++ goto out; ++ } ++ ++ if (io_unit_pg3->GPIOCount < 25) { ++ pr_err(MPT3SAS_FMT "%s: iounit_pg3->GPIOCount less than " ++ "25 entries, detected (%d) entries\n", ioc->name, __func__, ++ io_unit_pg3->GPIOCount); ++ goto out; ++ } ++ ++ /* BRM status is in bit zero of GPIOVal[24] */ ++ backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]); ++ rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1)); ++ ++ out: ++ kfree(io_unit_pg3); ++ mutex_unlock(&ioc->pci_access_mutex); ++ return rc; ++} ++static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); ++ ++struct DIAG_BUFFER_START { ++ __le32 Size; ++ __le32 DiagVersion; ++ u8 BufferType; ++ u8 Reserved[3]; ++ __le32 Reserved1; ++ __le32 Reserved2; ++ __le32 Reserved3; ++}; ++ ++/** ++ * _ctl_host_trace_buffer_size_show - host buffer size (trace only) ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_host_trace_buffer_size_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ u32 size = 0; ++ struct DIAG_BUFFER_START *request_data; ++ ++ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ request_data = (struct DIAG_BUFFER_START *) ++ ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]; ++ if ((le32_to_cpu(request_data->DiagVersion) == 0x00000000 || ++ le32_to_cpu(request_data->DiagVersion) == 0x01000000 || ++ le32_to_cpu(request_data->DiagVersion) == 0x01010000) && ++ le32_to_cpu(request_data->Reserved3) == 0x4742444c) ++ size = le32_to_cpu(request_data->Size); ++ ++ ioc->ring_buffer_sz = size; ++ return snprintf(buf, PAGE_SIZE, "%d\n", size); ++} ++static DEVICE_ATTR(host_trace_buffer_size, S_IRUGO, ++ _ctl_host_trace_buffer_size_show, NULL); ++ ++/** ++ * _ctl_host_trace_buffer_show - firmware ring buffer (trace only) ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ * ++ * You will only be able to read 4k bytes of ring buffer at a time. ++ * In order to read beyond 4k bytes, you will have to write out the ++ * offset to the same attribute, it will move the pointer. ++ */ ++static ssize_t ++_ctl_host_trace_buffer_show(struct device *cdev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ void *request_data; ++ u32 size; ++ ++ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ pr_err(MPT3SAS_FMT ++ "%s: host_trace_buffer is not registered\n", ++ ioc->name, __func__); ++ return 0; ++ } ++ ++ if (ioc->ring_buffer_offset > ioc->ring_buffer_sz) ++ return 0; ++ ++ size = ioc->ring_buffer_sz - ioc->ring_buffer_offset; ++ size = (size >= PAGE_SIZE) ? (PAGE_SIZE - 1) : size; ++ request_data = ioc->diag_buffer[0] + ioc->ring_buffer_offset; ++ memcpy(buf, request_data, size); ++ return size; ++} ++ ++static ssize_t ++_ctl_host_trace_buffer_store(struct device *cdev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int val = 0; ++ ++ if (sscanf(buf, "%d", &val) != 1) ++ return -EINVAL; ++ ++ ioc->ring_buffer_offset = val; ++ return strlen(buf); ++} ++static DEVICE_ATTR(host_trace_buffer, S_IRUGO | S_IWUSR, ++ _ctl_host_trace_buffer_show, _ctl_host_trace_buffer_store); ++ ++ ++/*****************************************/ ++ ++/** ++ * _ctl_host_trace_buffer_enable_show - firmware ring buffer (trace only) ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ * ++ * This is a mechnism to post/release host_trace_buffers ++ */ ++static ssize_t ++_ctl_host_trace_buffer_enable_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ if ((!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) || ++ ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0)) ++ return snprintf(buf, PAGE_SIZE, "off\n"); ++ else if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ return snprintf(buf, PAGE_SIZE, "release\n"); ++ else ++ return snprintf(buf, PAGE_SIZE, "post\n"); ++} ++ ++static ssize_t ++_ctl_host_trace_buffer_enable_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ char str[10] = ""; ++ struct mpt3_diag_register diag_register; ++ u8 issue_reset = 0; ++ ++ /* don't allow post/release occurr while recovery is active */ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery || ioc->is_driver_loading) ++ return -EBUSY; ++ ++ if (sscanf(buf, "%9s", str) != 1) ++ return -EINVAL; ++ ++ if (!strcmp(str, "post")) { ++ /* exit out if host buffers are already posted */ ++ if ((ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) && ++ (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) && ++ ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0)) ++ goto out; ++ memset(&diag_register, 0, sizeof(struct mpt3_diag_register)); ++ pr_info(MPT3SAS_FMT "posting host trace buffers\n", ++ ioc->name); ++ diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; ++ diag_register.requested_buffer_size = (1024 * 1024); ++ diag_register.unique_id = 0x7075900; ++ ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0; ++ _ctl_diag_register_2(ioc, &diag_register); ++ } else if (!strcmp(str, "release")) { ++ /* exit out if host buffers are already released */ ++ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) ++ goto out; ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) ++ goto out; ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ goto out; ++ pr_info(MPT3SAS_FMT "releasing host trace buffer\n", ++ ioc->name); ++ mpt2sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, ++ &issue_reset); ++ } ++ ++ out: ++ return strlen(buf); ++} ++static DEVICE_ATTR(host_trace_buffer_enable, S_IRUGO | S_IWUSR, ++ _ctl_host_trace_buffer_enable_show, ++ _ctl_host_trace_buffer_enable_store); ++ ++/*********** diagnostic trigger suppport *********************************/ ++ ++/** ++ * _ctl_diag_trigger_master_show - show the diag_trigger_master attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_master_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_MASTER_TRIGGER_T); ++ memcpy(buf, &ioc->diag_trigger_master, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_master_store - store the diag_trigger_master attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_master_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = min(sizeof(struct SL_WH_MASTER_TRIGGER_T), count); ++ memset(&ioc->diag_trigger_master, 0, ++ sizeof(struct SL_WH_MASTER_TRIGGER_T)); ++ memcpy(&ioc->diag_trigger_master, buf, rc); ++ ioc->diag_trigger_master.MasterData |= ++ (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++static DEVICE_ATTR(diag_trigger_master, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_master_show, _ctl_diag_trigger_master_store); ++ ++ ++/** ++ * _ctl_diag_trigger_event_show - show the diag_trigger_event attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_event_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_EVENT_TRIGGERS_T); ++ memcpy(buf, &ioc->diag_trigger_event, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_event_store - store the diag_trigger_event attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_event_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++ ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t sz; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ sz = min(sizeof(struct SL_WH_EVENT_TRIGGERS_T), count); ++ memset(&ioc->diag_trigger_event, 0, ++ sizeof(struct SL_WH_EVENT_TRIGGERS_T)); ++ memcpy(&ioc->diag_trigger_event, buf, sz); ++ if (ioc->diag_trigger_event.ValidEntries > NUM_VALID_ENTRIES) ++ ioc->diag_trigger_event.ValidEntries = NUM_VALID_ENTRIES; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return sz; ++} ++static DEVICE_ATTR(diag_trigger_event, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_event_show, _ctl_diag_trigger_event_store); ++ ++ ++/** ++ * _ctl_diag_trigger_scsi_show - show the diag_trigger_scsi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_scsi_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_SCSI_TRIGGERS_T); ++ memcpy(buf, &ioc->diag_trigger_scsi, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_scsi_store - store the diag_trigger_scsi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_scsi_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t sz; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ sz = min(sizeof(struct SL_WH_SCSI_TRIGGERS_T), count); ++ memset(&ioc->diag_trigger_scsi, 0, ++ sizeof(struct SL_WH_EVENT_TRIGGERS_T)); ++ memcpy(&ioc->diag_trigger_scsi, buf, sz); ++ if (ioc->diag_trigger_scsi.ValidEntries > NUM_VALID_ENTRIES) ++ ioc->diag_trigger_scsi.ValidEntries = NUM_VALID_ENTRIES; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return sz; ++} ++static DEVICE_ATTR(diag_trigger_scsi, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_scsi_show, _ctl_diag_trigger_scsi_store); ++ ++ ++/** ++ * _ctl_diag_trigger_scsi_show - show the diag_trigger_mpi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_mpi_show(struct device *cdev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t rc; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ rc = sizeof(struct SL_WH_MPI_TRIGGERS_T); ++ memcpy(buf, &ioc->diag_trigger_mpi, rc); ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return rc; ++} ++ ++/** ++ * _ctl_diag_trigger_mpi_store - store the diag_trigger_mpi attribute ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * A sysfs 'read/write' shost attribute. ++ */ ++static ssize_t ++_ctl_diag_trigger_mpi_store(struct device *cdev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(cdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ unsigned long flags; ++ ssize_t sz; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ sz = min(sizeof(struct SL_WH_MPI_TRIGGERS_T), count); ++ memset(&ioc->diag_trigger_mpi, 0, ++ sizeof(ioc->diag_trigger_mpi)); ++ memcpy(&ioc->diag_trigger_mpi, buf, sz); ++ if (ioc->diag_trigger_mpi.ValidEntries > NUM_VALID_ENTRIES) ++ ioc->diag_trigger_mpi.ValidEntries = NUM_VALID_ENTRIES; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return sz; ++} ++ ++static DEVICE_ATTR(diag_trigger_mpi, S_IRUGO | S_IWUSR, ++ _ctl_diag_trigger_mpi_show, _ctl_diag_trigger_mpi_store); ++ ++/*********** diagnostic trigger suppport *** END ****************************/ ++ ++ ++ ++/*****************************************/ ++ ++struct device_attribute *mpt2sas_host_attrs[] = { ++ &dev_attr_version_fw, ++ &dev_attr_version_bios, ++ &dev_attr_version_mpi, ++ &dev_attr_version_product, ++ &dev_attr_version_nvdata_persistent, ++ &dev_attr_version_nvdata_default, ++ &dev_attr_board_name, ++ &dev_attr_board_assembly, ++ &dev_attr_board_tracer, ++ &dev_attr_io_delay, ++ &dev_attr_device_delay, ++ &dev_attr_logging_level, ++ &dev_attr_fwfault_debug, ++ &dev_attr_fw_queue_depth, ++ &dev_attr_host_sas_address, ++ &dev_attr_ioc_reset_count, ++ &dev_attr_host_trace_buffer_size, ++ &dev_attr_host_trace_buffer, ++ &dev_attr_host_trace_buffer_enable, ++ &dev_attr_reply_queue_count, ++ &dev_attr_diag_trigger_master, ++ &dev_attr_diag_trigger_event, ++ &dev_attr_diag_trigger_scsi, ++ &dev_attr_diag_trigger_mpi, ++ &dev_attr_BRM_status, ++ NULL, ++}; ++ ++/* device attributes */ ++ ++/** ++ * _ctl_device_sas_address_show - sas address ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is the sas address for the target ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_device_sas_address_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; ++ ++ return snprintf(buf, PAGE_SIZE, "0x%016llx\n", ++ (unsigned long long)sas_device_priv_data->sas_target->sas_address); ++} ++static DEVICE_ATTR(sas_address, S_IRUGO, _ctl_device_sas_address_show, NULL); ++ ++/** ++ * _ctl_device_handle_show - device handle ++ * @cdev - pointer to embedded class device ++ * @buf - the buffer returned ++ * ++ * This is the firmware assigned device handle ++ * ++ * A sysfs 'read-only' shost attribute. ++ */ ++static ssize_t ++_ctl_device_handle_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; ++ ++ return snprintf(buf, PAGE_SIZE, "0x%04x\n", ++ sas_device_priv_data->sas_target->handle); ++} ++static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL); ++ ++struct device_attribute *mpt2sas_dev_attrs[] = { ++ &dev_attr_sas_address, ++ &dev_attr_sas_device_handle, ++ NULL, ++}; ++ ++/* file operations table for mpt3ctl device */ ++static const struct file_operations ctl_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = _ctl_ioctl_mpt2sas, ++ .poll = _ctl_poll_mpt2sas, ++ .fasync = _ctl_fasync_mpt2sas, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = _ctl_ioctl_compat_mpt2sas, ++#endif ++}; ++ ++/* file operations table for mpt2ctl device */ ++static const struct file_operations ctl_gen2_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = _ctl_mpt2_ioctl_mpt2sas, ++ .poll = _ctl_poll_mpt2sas, ++ .fasync = _ctl_fasync_mpt2sas, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = _ctl_mpt2_ioctl_compat_mpt2sas, ++#endif ++}; ++ ++static struct miscdevice ctl_dev = { ++ .minor = MPT3SAS_MINOR, ++ .name = MPT3SAS_DEV_NAME, ++ .fops = &ctl_fops, ++}; ++ ++static struct miscdevice gen2_ctl_dev = { ++ .minor = MPT2SAS_MINOR, ++ .name = MPT2SAS_DEV_NAME, ++ .fops = &ctl_gen2_fops, ++}; ++ ++/** ++ * mpt2sas_ctl_init - main entry point for ctl. ++ * ++ */ ++void ++mpt2sas_ctl_init(ushort hbas_to_enumerate) ++{ ++ async_queue = NULL; ++ ++ /* Don't register mpt3ctl ioctl device if ++ * hbas_to_enumarate is one. ++ */ ++ if (hbas_to_enumerate != 1) ++ if (misc_register(&ctl_dev) < 0) ++ pr_err("%s can't register misc device [minor=%d]\n", ++ MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR); ++ ++ /* Don't register mpt3ctl ioctl device if ++ * hbas_to_enumarate is two. ++ */ ++ if (hbas_to_enumerate != 2) ++ if (misc_register(&gen2_ctl_dev) < 0) ++ pr_err("%s can't register misc device [minor=%d]\n", ++ MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR); ++ ++ init_waitqueue_head(&ctl_poll_wait); ++} ++ ++/** ++ * mpt2sas_ctl_exit - exit point for ctl ++ * ++ */ ++void ++mpt2sas_ctl_exit(ushort hbas_to_enumerate) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ int i; ++ ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { ++ ++ /* free memory associated to diag buffers */ ++ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { ++ if (!ioc->diag_buffer[i]) ++ continue; ++ if (!(ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED)) ++ continue; ++ if ((ioc->diag_buffer_status[i] & ++ MPT3_DIAG_BUFFER_IS_RELEASED)) ++ continue; ++ pci_free_consistent(ioc->pdev, ioc->diag_buffer_sz[i], ++ ioc->diag_buffer[i], ioc->diag_buffer_dma[i]); ++ ioc->diag_buffer[i] = NULL; ++ ioc->diag_buffer_status[i] = 0; ++ } ++ ++ kfree(ioc->event_log); ++ } ++ if (hbas_to_enumerate != 1) ++ misc_deregister(&ctl_dev); ++ if (hbas_to_enumerate != 2) ++ misc_deregister(&gen2_ctl_dev); ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_ctl.h b/drivers/scsi/mpt2sas/mpt3sas_ctl.h +new file mode 100644 +index 0000000..8940835 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_ctl.h +@@ -0,0 +1,423 @@ ++/* ++ * Management Module Support for MPT (Message Passing Technology) based ++ * controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.h ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#ifndef MPT3SAS_CTL_H_INCLUDED ++#define MPT3SAS_CTL_H_INCLUDED ++ ++#ifdef __KERNEL__ ++#include ++#endif ++ ++#ifndef MPT2SAS_MINOR ++#define MPT2SAS_MINOR (MPT_MINOR + 1) ++#endif ++#ifndef MPT3SAS_MINOR ++#define MPT3SAS_MINOR (MPT_MINOR + 2) ++#endif ++#define MPT2SAS_DEV_NAME "mpt2ctl" ++#define MPT3SAS_DEV_NAME "mpt3ctl" ++#define MPT3_MAGIC_NUMBER 'L' ++#define MPT3_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */ ++ ++/** ++ * IOCTL opcodes ++ */ ++#define MPT3IOCINFO _IOWR(MPT3_MAGIC_NUMBER, 17, \ ++ struct mpt3_ioctl_iocinfo) ++#define MPT3COMMAND _IOWR(MPT3_MAGIC_NUMBER, 20, \ ++ struct mpt3_ioctl_command) ++#ifdef CONFIG_COMPAT ++#define MPT3COMMAND32 _IOWR(MPT3_MAGIC_NUMBER, 20, \ ++ struct mpt3_ioctl_command32) ++#endif ++#define MPT3EVENTQUERY _IOWR(MPT3_MAGIC_NUMBER, 21, \ ++ struct mpt3_ioctl_eventquery) ++#define MPT3EVENTENABLE _IOWR(MPT3_MAGIC_NUMBER, 22, \ ++ struct mpt3_ioctl_eventenable) ++#define MPT3EVENTREPORT _IOWR(MPT3_MAGIC_NUMBER, 23, \ ++ struct mpt3_ioctl_eventreport) ++#define MPT3HARDRESET _IOWR(MPT3_MAGIC_NUMBER, 24, \ ++ struct mpt3_ioctl_diag_reset) ++#define MPT3BTDHMAPPING _IOWR(MPT3_MAGIC_NUMBER, 31, \ ++ struct mpt3_ioctl_btdh_mapping) ++ ++/* diag buffer support */ ++#define MPT3DIAGREGISTER _IOWR(MPT3_MAGIC_NUMBER, 26, \ ++ struct mpt3_diag_register) ++#define MPT3DIAGRELEASE _IOWR(MPT3_MAGIC_NUMBER, 27, \ ++ struct mpt3_diag_release) ++#define MPT3DIAGUNREGISTER _IOWR(MPT3_MAGIC_NUMBER, 28, \ ++ struct mpt3_diag_unregister) ++#define MPT3DIAGQUERY _IOWR(MPT3_MAGIC_NUMBER, 29, \ ++ struct mpt3_diag_query) ++#define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \ ++ struct mpt3_diag_read_buffer) ++ ++/** ++ * struct mpt3_ioctl_header - main header structure ++ * @ioc_number - IOC unit number ++ * @port_number - IOC port number ++ * @max_data_size - maximum number bytes to transfer on read ++ */ ++struct mpt3_ioctl_header { ++ uint32_t ioc_number; ++ uint32_t port_number; ++ uint32_t max_data_size; ++}; ++ ++/** ++ * struct mpt3_ioctl_diag_reset - diagnostic reset ++ * @hdr - generic header ++ */ ++struct mpt3_ioctl_diag_reset { ++ struct mpt3_ioctl_header hdr; ++}; ++ ++ ++/** ++ * struct mpt3_ioctl_pci_info - pci device info ++ * @device - pci device id ++ * @function - pci function id ++ * @bus - pci bus id ++ * @segment_id - pci segment id ++ */ ++struct mpt3_ioctl_pci_info { ++ union { ++ struct { ++ uint32_t device:5; ++ uint32_t function:3; ++ uint32_t bus:24; ++ } bits; ++ uint32_t word; ++ } u; ++ uint32_t segment_id; ++}; ++ ++ ++#define MPT2_IOCTL_INTERFACE_SCSI (0x00) ++#define MPT2_IOCTL_INTERFACE_FC (0x01) ++#define MPT2_IOCTL_INTERFACE_FC_IP (0x02) ++#define MPT2_IOCTL_INTERFACE_SAS (0x03) ++#define MPT2_IOCTL_INTERFACE_SAS2 (0x04) ++#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) ++#define MPT3_IOCTL_INTERFACE_SAS3 (0x06) ++#define MPT2_IOCTL_VERSION_LENGTH (32) ++ ++/** ++ * struct mpt3_ioctl_iocinfo - generic controller info ++ * @hdr - generic header ++ * @adapter_type - type of adapter (spi, fc, sas) ++ * @port_number - port number ++ * @pci_id - PCI Id ++ * @hw_rev - hardware revision ++ * @sub_system_device - PCI subsystem Device ID ++ * @sub_system_vendor - PCI subsystem Vendor ID ++ * @rsvd0 - reserved ++ * @firmware_version - firmware version ++ * @bios_version - BIOS version ++ * @driver_version - driver version - 32 ASCII characters ++ * @rsvd1 - reserved ++ * @scsi_id - scsi id of adapter 0 ++ * @rsvd2 - reserved ++ * @pci_information - pci info (2nd revision) ++ */ ++struct mpt3_ioctl_iocinfo { ++ struct mpt3_ioctl_header hdr; ++ uint32_t adapter_type; ++ uint32_t port_number; ++ uint32_t pci_id; ++ uint32_t hw_rev; ++ uint32_t subsystem_device; ++ uint32_t subsystem_vendor; ++ uint32_t rsvd0; ++ uint32_t firmware_version; ++ uint32_t bios_version; ++ uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH]; ++ uint8_t rsvd1; ++ uint8_t scsi_id; ++ uint16_t rsvd2; ++ struct mpt3_ioctl_pci_info pci_information; ++}; ++ ++ ++/* number of event log entries */ ++#define MPT3SAS_CTL_EVENT_LOG_SIZE (50) ++ ++/** ++ * struct mpt3_ioctl_eventquery - query event count and type ++ * @hdr - generic header ++ * @event_entries - number of events returned by get_event_report ++ * @rsvd - reserved ++ * @event_types - type of events currently being captured ++ */ ++struct mpt3_ioctl_eventquery { ++ struct mpt3_ioctl_header hdr; ++ uint16_t event_entries; ++ uint16_t rsvd; ++ uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; ++}; ++ ++/** ++ * struct mpt3_ioctl_eventenable - enable/disable event capturing ++ * @hdr - generic header ++ * @event_types - toggle off/on type of events to be captured ++ */ ++struct mpt3_ioctl_eventenable { ++ struct mpt3_ioctl_header hdr; ++ uint32_t event_types[4]; ++}; ++ ++#define MPT3_EVENT_DATA_SIZE (192) ++/** ++ * struct MPT3_IOCTL_EVENTS - ++ * @event - the event that was reported ++ * @context - unique value for each event assigned by driver ++ * @data - event data returned in fw reply message ++ */ ++struct MPT3_IOCTL_EVENTS { ++ uint32_t event; ++ uint32_t context; ++ uint8_t data[MPT3_EVENT_DATA_SIZE]; ++}; ++ ++/** ++ * struct mpt3_ioctl_eventreport - returing event log ++ * @hdr - generic header ++ * @event_data - (see struct MPT3_IOCTL_EVENTS) ++ */ ++struct mpt3_ioctl_eventreport { ++ struct mpt3_ioctl_header hdr; ++ struct MPT3_IOCTL_EVENTS event_data[1]; ++}; ++ ++/** ++ * struct mpt3_ioctl_command - generic mpt firmware passthru ioctl ++ * @hdr - generic header ++ * @timeout - command timeout in seconds. (if zero then use driver default ++ * value). ++ * @reply_frame_buf_ptr - reply location ++ * @data_in_buf_ptr - destination for read ++ * @data_out_buf_ptr - data source for write ++ * @sense_data_ptr - sense data location ++ * @max_reply_bytes - maximum number of reply bytes to be sent to app. ++ * @data_in_size - number bytes for data transfer in (read) ++ * @data_out_size - number bytes for data transfer out (write) ++ * @max_sense_bytes - maximum number of bytes for auto sense buffers ++ * @data_sge_offset - offset in words from the start of the request message to ++ * the first SGL ++ * @mf[1]; ++ */ ++struct mpt3_ioctl_command { ++ struct mpt3_ioctl_header hdr; ++ uint32_t timeout; ++ void __user *reply_frame_buf_ptr; ++ void __user *data_in_buf_ptr; ++ void __user *data_out_buf_ptr; ++ void __user *sense_data_ptr; ++ uint32_t max_reply_bytes; ++ uint32_t data_in_size; ++ uint32_t data_out_size; ++ uint32_t max_sense_bytes; ++ uint32_t data_sge_offset; ++ uint8_t mf[1]; ++}; ++ ++#ifdef CONFIG_COMPAT ++struct mpt3_ioctl_command32 { ++ struct mpt3_ioctl_header hdr; ++ uint32_t timeout; ++ uint32_t reply_frame_buf_ptr; ++ uint32_t data_in_buf_ptr; ++ uint32_t data_out_buf_ptr; ++ uint32_t sense_data_ptr; ++ uint32_t max_reply_bytes; ++ uint32_t data_in_size; ++ uint32_t data_out_size; ++ uint32_t max_sense_bytes; ++ uint32_t data_sge_offset; ++ uint8_t mf[1]; ++}; ++#endif ++ ++/** ++ * struct mpt3_ioctl_btdh_mapping - mapping info ++ * @hdr - generic header ++ * @id - target device identification number ++ * @bus - SCSI bus number that the target device exists on ++ * @handle - device handle for the target device ++ * @rsvd - reserved ++ * ++ * To obtain a bus/id the application sets ++ * handle to valid handle, and bus/id to 0xFFFF. ++ * ++ * To obtain the device handle the application sets ++ * bus/id valid value, and the handle to 0xFFFF. ++ */ ++struct mpt3_ioctl_btdh_mapping { ++ struct mpt3_ioctl_header hdr; ++ uint32_t id; ++ uint32_t bus; ++ uint16_t handle; ++ uint16_t rsvd; ++}; ++ ++ ++ ++/* application flags for mpt3_diag_register, mpt3_diag_query */ ++#define MPT3_APP_FLAGS_APP_OWNED (0x0001) ++#define MPT3_APP_FLAGS_BUFFER_VALID (0x0002) ++#define MPT3_APP_FLAGS_FW_BUFFER_ACCESS (0x0004) ++ ++/* flags for mpt3_diag_read_buffer */ ++#define MPT3_FLAGS_REREGISTER (0x0001) ++ ++#define MPT3_PRODUCT_SPECIFIC_DWORDS 23 ++ ++/** ++ * struct mpt3_diag_register - application register with driver ++ * @hdr - generic header ++ * @reserved - ++ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED ++ * @application_flags - misc flags ++ * @diagnostic_flags - specifies flags affecting command processing ++ * @product_specific - product specific information ++ * @requested_buffer_size - buffers size in bytes ++ * @unique_id - tag specified by application that is used to signal ownership ++ * of the buffer. ++ * ++ * This will allow the driver to setup any required buffers that will be ++ * needed by firmware to communicate with the driver. ++ */ ++struct mpt3_diag_register { ++ struct mpt3_ioctl_header hdr; ++ uint8_t reserved; ++ uint8_t buffer_type; ++ uint16_t application_flags; ++ uint32_t diagnostic_flags; ++ uint32_t product_specific[MPT3_PRODUCT_SPECIFIC_DWORDS]; ++ uint32_t requested_buffer_size; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_unregister - application unregister with driver ++ * @hdr - generic header ++ * @unique_id - tag uniquely identifies the buffer to be unregistered ++ * ++ * This will allow the driver to cleanup any memory allocated for diag ++ * messages and to free up any resources. ++ */ ++struct mpt3_diag_unregister { ++ struct mpt3_ioctl_header hdr; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_query - query relevant info associated with diag buffers ++ * @hdr - generic header ++ * @reserved - ++ * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED ++ * @application_flags - misc flags ++ * @diagnostic_flags - specifies flags affecting command processing ++ * @product_specific - product specific information ++ * @total_buffer_size - diag buffer size in bytes ++ * @driver_added_buffer_size - size of extra space appended to end of buffer ++ * @unique_id - unique id associated with this buffer. ++ * ++ * The application will send only buffer_type and unique_id. Driver will ++ * inspect unique_id first, if valid, fill in all the info. If unique_id is ++ * 0x00, the driver will return info specified by Buffer Type. ++ */ ++struct mpt3_diag_query { ++ struct mpt3_ioctl_header hdr; ++ uint8_t reserved; ++ uint8_t buffer_type; ++ uint16_t application_flags; ++ uint32_t diagnostic_flags; ++ uint32_t product_specific[MPT3_PRODUCT_SPECIFIC_DWORDS]; ++ uint32_t total_buffer_size; ++ uint32_t driver_added_buffer_size; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_release - request to send Diag Release Message to firmware ++ * @hdr - generic header ++ * @unique_id - tag uniquely identifies the buffer to be released ++ * ++ * This allows ownership of the specified buffer to returned to the driver, ++ * allowing an application to read the buffer without fear that firmware is ++ * overwritting information in the buffer. ++ */ ++struct mpt3_diag_release { ++ struct mpt3_ioctl_header hdr; ++ uint32_t unique_id; ++}; ++ ++/** ++ * struct mpt3_diag_read_buffer - request for copy of the diag buffer ++ * @hdr - generic header ++ * @status - ++ * @reserved - ++ * @flags - misc flags ++ * @starting_offset - starting offset within drivers buffer where to start ++ * reading data at into the specified application buffer ++ * @bytes_to_read - number of bytes to copy from the drivers buffer into the ++ * application buffer starting at starting_offset. ++ * @unique_id - unique id associated with this buffer. ++ * @diagnostic_data - data payload ++ */ ++struct mpt3_diag_read_buffer { ++ struct mpt3_ioctl_header hdr; ++ uint8_t status; ++ uint8_t reserved; ++ uint16_t flags; ++ uint32_t starting_offset; ++ uint32_t bytes_to_read; ++ uint32_t unique_id; ++ uint32_t diagnostic_data[1]; ++}; ++ ++#endif /* MPT3SAS_CTL_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_debug.h b/drivers/scsi/mpt2sas/mpt3sas_debug.h +new file mode 100644 +index 0000000..cceeb2c +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_debug.h +@@ -0,0 +1,206 @@ ++/* ++ * Logging Support for MPT (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_debug.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#ifndef MPT3SAS_DEBUG_H_INCLUDED ++#define MPT3SAS_DEBUG_H_INCLUDED ++ ++#define MPT_DEBUG 0x00000001 ++#define MPT_DEBUG_MSG_FRAME 0x00000002 ++#define MPT_DEBUG_SG 0x00000004 ++#define MPT_DEBUG_EVENTS 0x00000008 ++#define MPT_DEBUG_EVENT_WORK_TASK 0x00000010 ++#define MPT_DEBUG_INIT 0x00000020 ++#define MPT_DEBUG_EXIT 0x00000040 ++#define MPT_DEBUG_FAIL 0x00000080 ++#define MPT_DEBUG_TM 0x00000100 ++#define MPT_DEBUG_REPLY 0x00000200 ++#define MPT_DEBUG_HANDSHAKE 0x00000400 ++#define MPT_DEBUG_CONFIG 0x00000800 ++#define MPT_DEBUG_DL 0x00001000 ++#define MPT_DEBUG_RESET 0x00002000 ++#define MPT_DEBUG_SCSI 0x00004000 ++#define MPT_DEBUG_IOCTL 0x00008000 ++#define MPT_DEBUG_SAS 0x00020000 ++#define MPT_DEBUG_TRANSPORT 0x00040000 ++#define MPT_DEBUG_TASK_SET_FULL 0x00080000 ++ ++#define MPT_DEBUG_TRIGGER_DIAG 0x00200000 ++ ++ ++#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \ ++{ \ ++ if (IOC->logging_level & BITS) \ ++ CMD; \ ++} ++ ++/* ++ * debug macros ++ */ ++ ++#define dprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG) ++ ++#define dsgprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SG) ++ ++#define devtprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENTS) ++ ++#define dewtprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EVENT_WORK_TASK) ++ ++#define dinitprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_INIT) ++ ++#define dexitprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_EXIT) ++ ++#define dfailprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_FAIL) ++ ++#define dtmprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TM) ++ ++#define dreplyprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_REPLY) ++ ++#define dhsprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_HANDSHAKE) ++ ++#define dcprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_CONFIG) ++ ++#define ddlprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_DL) ++ ++#define drsprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_RESET) ++ ++#define dsprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SCSI) ++ ++#define dctlprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_IOCTL) ++ ++#define dsasprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS) ++ ++#define dsastransport(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_SAS_WIDE) ++ ++#define dmfprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_MSG_FRAME) ++ ++#define dtsfprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TASK_SET_FULL) ++ ++#define dtransportprintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRANSPORT) ++ ++#define dTriggerDiagPrintk(IOC, CMD) \ ++ MPT_CHECK_LOGGING(IOC, CMD, MPT_DEBUG_TRIGGER_DIAG) ++ ++ ++ ++/* inline functions for dumping debug data*/ ++ ++/** ++ * _debug_dump_mf - print message frame contents ++ * @mpi_request: pointer to message frame ++ * @sz: number of dwords ++ */ ++static inline void ++_debug_dump_mf(void *mpi_request, int sz) ++{ ++ int i; ++ __le32 *mfp = (__le32 *)mpi_request; ++ ++ pr_info("mf:\n\t"); ++ for (i = 0; i < sz; i++) { ++ if (i && ((i % 8) == 0)) ++ pr_info("\n\t"); ++ pr_info("%08x ", le32_to_cpu(mfp[i])); ++ } ++ pr_info("\n"); ++} ++/** ++ * _debug_dump_reply - print message frame contents ++ * @mpi_request: pointer to message frame ++ * @sz: number of dwords ++ */ ++static inline void ++_debug_dump_reply(void *mpi_request, int sz) ++{ ++ int i; ++ __le32 *mfp = (__le32 *)mpi_request; ++ ++ pr_info("reply:\n\t"); ++ for (i = 0; i < sz; i++) { ++ if (i && ((i % 8) == 0)) ++ pr_info("\n\t"); ++ pr_info("%08x ", le32_to_cpu(mfp[i])); ++ } ++ pr_info("\n"); ++} ++/** ++ * _debug_dump_config - print config page contents ++ * @mpi_request: pointer to message frame ++ * @sz: number of dwords ++ */ ++static inline void ++_debug_dump_config(void *mpi_request, int sz) ++{ ++ int i; ++ __le32 *mfp = (__le32 *)mpi_request; ++ ++ pr_info("config:\n\t"); ++ for (i = 0; i < sz; i++) { ++ if (i && ((i % 8) == 0)) ++ pr_info("\n\t"); ++ pr_info("%08x ", le32_to_cpu(mfp[i])); ++ } ++ pr_info("\n"); ++} ++ ++#endif /* MPT3SAS_DEBUG_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_scsih.c b/drivers/scsi/mpt2sas/mpt3sas_scsih.c +new file mode 100644 +index 0000000..0a3ad2b +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_scsih.c +@@ -0,0 +1,9356 @@ ++/* ++ * Scsi Host Layer for MPT (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++#define RAID_CHANNEL 1 ++/* forward proto's */ ++static void _scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander); ++static void _firmware_event_work(struct work_struct *work); ++ ++static void _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device); ++static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u8 retry_count, u8 is_pd); ++ ++static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid); ++ ++/* global parameters */ ++LIST_HEAD(mpt2sas_ioc_list); ++/* global ioc lock for list operations */ ++DEFINE_SPINLOCK(gioc_lock_mpt2sas); ++ ++MODULE_AUTHOR(MPT3SAS_AUTHOR); ++#ifdef MPT2SAS_SCSI ++MODULE_DESCRIPTION(MPT2SAS_DESCRIPTION); ++MODULE_VERSION(MPT2SAS_DRIVER_VERSION); ++#else ++MODULE_DESCRIPTION(MPT3SAS_DESCRIPTION); ++MODULE_VERSION(MPT3SAS_DRIVER_VERSION); ++#endif /* MPT2SAS_SCSI */ ++MODULE_LICENSE("GPL"); ++ ++/* local parameters */ ++static u8 scsi_io_cb_idx = -1; ++static u8 tm_cb_idx = -1; ++static u8 ctl_cb_idx = -1; ++static u8 base_cb_idx = -1; ++static u8 port_enable_cb_idx = -1; ++static u8 transport_cb_idx = -1; ++static u8 scsih_cb_idx = -1; ++static u8 config_cb_idx = -1; ++static int mpt2_ids; ++static int mpt3_ids; ++ ++static u8 tm_tr_cb_idx = -1 ; ++static u8 tm_tr_volume_cb_idx = -1 ; ++static u8 tm_sas_control_cb_idx = -1; ++ ++/* command line options */ ++static u32 logging_level; ++MODULE_PARM_DESC(logging_level, ++ " bits for enabling additional logging info (default=0)"); ++ ++ ++static ushort max_sectors = 0xFFFF; ++module_param(max_sectors, ushort, 0); ++MODULE_PARM_DESC(max_sectors, "max sectors, range 64 to 32767 default=32767"); ++ ++ ++static int missing_delay[2] = {-1, -1}; ++module_param_array(missing_delay, int, NULL, 0); ++MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); ++ ++/* scsi-mid layer global parmeter is max_report_luns, which is 511 */ ++#define MPT3SAS_MAX_LUN (16895) ++static int max_lun = MPT3SAS_MAX_LUN; ++module_param(max_lun, int, 0); ++MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); ++ ++/* diag_buffer_enable is bitwise ++ * bit 0 set = TRACE ++ * bit 1 set = SNAPSHOT ++ * bit 2 set = EXTENDED ++ * ++ * Either bit can be set, or both ++ */ ++static int diag_buffer_enable = -1; ++module_param(diag_buffer_enable, int, 0); ++MODULE_PARM_DESC(diag_buffer_enable, ++ " post diag buffers (TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); ++static int disable_discovery = -1; ++module_param(disable_discovery, int, 0); ++MODULE_PARM_DESC(disable_discovery, " disable discovery "); ++ ++ ++/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */ ++static int prot_mask = -1; ++module_param(prot_mask, int, 0); ++MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=7 "); ++ ++ ++/* raid transport support */ ++struct raid_template *mpt3sas_raid_template_mpt2sas; ++struct raid_template *mpt2sas_raid_template_mpt2sas; ++ ++ ++/** ++ * struct sense_info - common structure for obtaining sense keys ++ * @skey: sense key ++ * @asc: additional sense code ++ * @ascq: additional sense code qualifier ++ */ ++struct sense_info { ++ u8 skey; ++ u8 asc; ++ u8 ascq; ++}; ++ ++#define MPT3SAS_PROCESS_TRIGGER_DIAG (0xFFFB) ++#define MPT3SAS_TURN_ON_PFA_LED (0xFFFC) ++#define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD) ++#define MPT3SAS_ABRT_TASK_SET (0xFFFE) ++#define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) ++/** ++ * struct fw_event_work - firmware event struct ++ * @list: link list framework ++ * @work: work object (ioc->fault_reset_work_q) ++ * @ioc: per adapter object ++ * @device_handle: device handle ++ * @VF_ID: virtual function id ++ * @VP_ID: virtual port id ++ * @ignore: flag meaning this event has been marked to ignore ++ * @event: firmware event MPI2_EVENT_XXX defined in mpi2_ioc.h ++ * @refcount: kref for this event ++ * @event_data: reply event data payload follows ++ * ++ * This object stored on ioc->fw_event_list. ++ */ ++struct fw_event_work { ++ struct list_head list; ++ struct work_struct work; ++ ++ struct MPT3SAS_ADAPTER *ioc; ++ u16 device_handle; ++ u8 VF_ID; ++ u8 VP_ID; ++ u8 ignore; ++ u16 event; ++ struct kref refcount; ++ char event_data[0] __aligned(4); ++}; ++ ++static void fw_event_work_free(struct kref *r) ++{ ++ kfree(container_of(r, struct fw_event_work, refcount)); ++} ++ ++static void fw_event_work_get(struct fw_event_work *fw_work) ++{ ++ kref_get(&fw_work->refcount); ++} ++ ++static void fw_event_work_put(struct fw_event_work *fw_work) ++{ ++ kref_put(&fw_work->refcount, fw_event_work_free); ++} ++ ++static struct fw_event_work *alloc_fw_event_work(int len) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC); ++ if (!fw_event) ++ return NULL; ++ ++ kref_init(&fw_event->refcount); ++ return fw_event; ++} ++ ++/** ++ * struct _scsi_io_transfer - scsi io transfer ++ * @handle: sas device handle (assigned by firmware) ++ * @is_raid: flag set for hidden raid components ++ * @dir: DMA_TO_DEVICE, DMA_FROM_DEVICE, ++ * @data_length: data transfer length ++ * @data_dma: dma pointer to data ++ * @sense: sense data ++ * @lun: lun number ++ * @cdb_length: cdb length ++ * @cdb: cdb contents ++ * @timeout: timeout for this command ++ * @VF_ID: virtual function id ++ * @VP_ID: virtual port id ++ * @valid_reply: flag set for reply message ++ * @sense_length: sense length ++ * @ioc_status: ioc status ++ * @scsi_state: scsi state ++ * @scsi_status: scsi staus ++ * @log_info: log information ++ * @transfer_length: data length transfer when there is a reply message ++ * ++ * Used for sending internal scsi commands to devices within this module. ++ * Refer to _scsi_send_scsi_io(). ++ */ ++struct _scsi_io_transfer { ++ u16 handle; ++ u8 is_raid; ++ enum dma_data_direction dir; ++ u32 data_length; ++ dma_addr_t data_dma; ++ u8 sense[SCSI_SENSE_BUFFERSIZE]; ++ u32 lun; ++ u8 cdb_length; ++ u8 cdb[32]; ++ u8 timeout; ++ u8 VF_ID; ++ u8 VP_ID; ++ u8 valid_reply; ++ /* the following bits are only valid when 'valid_reply = 1' */ ++ u32 sense_length; ++ u16 ioc_status; ++ u8 scsi_state; ++ u8 scsi_status; ++ u32 log_info; ++ u32 transfer_length; ++}; ++ ++/** ++ * _scsih_set_debug_level - global setting of ioc->logging_level. ++ * ++ * Note: The logging levels are defined in mpt3sas_debug.h. ++ */ ++static int ++_scsih_set_debug_level(const char *val, struct kernel_param *kp) ++{ ++ int ret = param_set_int(val, kp); ++ struct MPT3SAS_ADAPTER *ioc; ++ ++ if (ret) ++ return ret; ++ ++ pr_info("setting logging_level(0x%08x)\n", logging_level); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_for_each_entry(ioc, &mpt2sas_ioc_list, list) ++ ioc->logging_level = logging_level; ++ spin_unlock(&gioc_lock_mpt2sas); ++ return 0; ++} ++module_param_call(logging_level, _scsih_set_debug_level, param_get_int, ++ &logging_level, 0644); ++ ++/** ++ * _scsih_srch_boot_sas_address - search based on sas_address ++ * @sas_address: sas address ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static inline int ++_scsih_srch_boot_sas_address(u64 sas_address, ++ Mpi2BootDeviceSasWwid_t *boot_device) ++{ ++ return (sas_address == le64_to_cpu(boot_device->SASAddress)) ? 1 : 0; ++} ++ ++/** ++ * _scsih_srch_boot_device_name - search based on device name ++ * @device_name: device name specified in INDENTIFY fram ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static inline int ++_scsih_srch_boot_device_name(u64 device_name, ++ Mpi2BootDeviceDeviceName_t *boot_device) ++{ ++ return (device_name == le64_to_cpu(boot_device->DeviceName)) ? 1 : 0; ++} ++ ++/** ++ * _scsih_srch_boot_encl_slot - search based on enclosure_logical_id/slot ++ * @enclosure_logical_id: enclosure logical id ++ * @slot_number: slot number ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static inline int ++_scsih_srch_boot_encl_slot(u64 enclosure_logical_id, u16 slot_number, ++ Mpi2BootDeviceEnclosureSlot_t *boot_device) ++{ ++ return (enclosure_logical_id == le64_to_cpu(boot_device-> ++ EnclosureLogicalID) && slot_number == le16_to_cpu(boot_device-> ++ SlotNumber)) ? 1 : 0; ++} ++ ++/** ++ * _scsih_is_boot_device - search for matching boot device. ++ * @sas_address: sas address ++ * @device_name: device name specified in INDENTIFY fram ++ * @enclosure_logical_id: enclosure logical id ++ * @slot_number: slot number ++ * @form: specifies boot device form ++ * @boot_device: boot device object from bios page 2 ++ * ++ * Returns 1 when there's a match, 0 means no match. ++ */ ++static int ++_scsih_is_boot_device(u64 sas_address, u64 device_name, ++ u64 enclosure_logical_id, u16 slot, u8 form, ++ Mpi2BiosPage2BootDevice_t *boot_device) ++{ ++ int rc = 0; ++ ++ switch (form) { ++ case MPI2_BIOSPAGE2_FORM_SAS_WWID: ++ if (!sas_address) ++ break; ++ rc = _scsih_srch_boot_sas_address( ++ sas_address, &boot_device->SasWwid); ++ break; ++ case MPI2_BIOSPAGE2_FORM_ENCLOSURE_SLOT: ++ if (!enclosure_logical_id) ++ break; ++ rc = _scsih_srch_boot_encl_slot( ++ enclosure_logical_id, ++ slot, &boot_device->EnclosureSlot); ++ break; ++ case MPI2_BIOSPAGE2_FORM_DEVICE_NAME: ++ if (!device_name) ++ break; ++ rc = _scsih_srch_boot_device_name( ++ device_name, &boot_device->DeviceName); ++ break; ++ case MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED: ++ break; ++ } ++ ++ return rc; ++} ++ ++/** ++ * _scsih_get_sas_address - set the sas_address for given device handle ++ * @handle: device handle ++ * @sas_address: sas address ++ * ++ * Returns 0 success, non-zero when failure ++ */ ++static int ++_scsih_get_sas_address(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u64 *sas_address) ++{ ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 ioc_status; ++ ++ *sas_address = 0; ++ ++ if (handle <= ioc->sas_hba.num_phys) { ++ *sas_address = ioc->sas_hba.sas_address; ++ return 0; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ++ *sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ return 0; ++ } ++ ++ /* we hit this becuase the given parent handle doesn't exist */ ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ return -ENXIO; ++ ++ /* else error case */ ++ pr_err(MPT3SAS_FMT ++ "handle(0x%04x), ioc_status(0x%04x), failure at %s:%d/%s()!\n", ++ ioc->name, handle, ioc_status, ++ __FILE__, __LINE__, __func__); ++ return -EIO; ++} ++ ++/** ++ * _scsih_determine_boot_device - determine boot device. ++ * @ioc: per adapter object ++ * @device: either sas_device or raid_device object ++ * @is_raid: [flag] 1 = raid object, 0 = sas object ++ * ++ * Determines whether this device should be first reported device to ++ * to scsi-ml or sas transport, this purpose is for persistent boot device. ++ * There are primary, alternate, and current entries in bios page 2. The order ++ * priority is primary, alternate, then current. This routine saves ++ * the corresponding device object and is_raid flag in the ioc object. ++ * The saved data to be used later in _scsih_probe_boot_devices(). ++ */ ++static void ++_scsih_determine_boot_device(struct MPT3SAS_ADAPTER *ioc, ++ void *device, u8 is_raid) ++{ ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ u64 sas_address; ++ u64 device_name; ++ u64 enclosure_logical_id; ++ u16 slot; ++ ++ /* only process this function when driver loads */ ++ if (!ioc->is_driver_loading) ++ return; ++ ++ /* no Bios, return immediately */ ++ if (!ioc->bios_pg3.BiosVersion) ++ return; ++ ++ if (!is_raid) { ++ sas_device = device; ++ sas_address = sas_device->sas_address; ++ device_name = sas_device->device_name; ++ enclosure_logical_id = sas_device->enclosure_logical_id; ++ slot = sas_device->slot; ++ } else { ++ raid_device = device; ++ sas_address = raid_device->wwid; ++ device_name = 0; ++ enclosure_logical_id = 0; ++ slot = 0; ++ } ++ ++ if (!ioc->req_boot_device.device) { ++ if (_scsih_is_boot_device(sas_address, device_name, ++ enclosure_logical_id, slot, ++ (ioc->bios_pg2.ReqBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK), ++ &ioc->bios_pg2.RequestedBootDevice)) { ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: req_boot_device(0x%016llx)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_address)); ++ ioc->req_boot_device.device = device; ++ ioc->req_boot_device.is_raid = is_raid; ++ } ++ } ++ ++ if (!ioc->req_alt_boot_device.device) { ++ if (_scsih_is_boot_device(sas_address, device_name, ++ enclosure_logical_id, slot, ++ (ioc->bios_pg2.ReqAltBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK), ++ &ioc->bios_pg2.RequestedAltBootDevice)) { ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: req_alt_boot_device(0x%016llx)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_address)); ++ ioc->req_alt_boot_device.device = device; ++ ioc->req_alt_boot_device.is_raid = is_raid; ++ } ++ } ++ ++ if (!ioc->current_boot_device.device) { ++ if (_scsih_is_boot_device(sas_address, device_name, ++ enclosure_logical_id, slot, ++ (ioc->bios_pg2.CurrentBootDeviceForm & ++ MPI2_BIOSPAGE2_FORM_MASK), ++ &ioc->bios_pg2.CurrentBootDevice)) { ++ dinitprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: current_boot_device(0x%016llx)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_address)); ++ ioc->current_boot_device.device = device; ++ ioc->current_boot_device.is_raid = is_raid; ++ } ++ } ++} ++ ++static struct _sas_device * ++__mpt2sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, ++ struct MPT3SAS_TARGET *tgt_priv) ++{ ++ struct _sas_device *ret; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ ret = tgt_priv->sdev; ++ if (ret) ++ sas_device_get(ret); ++ ++ return ret; ++} ++ ++static struct _sas_device * ++mpt2sas_get_sdev_from_target(struct MPT3SAS_ADAPTER *ioc, ++ struct MPT3SAS_TARGET *tgt_priv) ++{ ++ struct _sas_device *ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ ret = __mpt2sas_get_sdev_from_target(ioc, tgt_priv); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return ret; ++} ++ ++ ++struct _sas_device * ++__mpt2sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_device *sas_device; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) ++ if (sas_device->sas_address == sas_address) ++ goto found_device; ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) ++ if (sas_device->sas_address == sas_address) ++ goto found_device; ++ ++ return NULL; ++ ++found_device: ++ sas_device_get(sas_device); ++ return sas_device; ++} ++ ++/** ++ * mpt2sas_get_sdev_by_addr - sas device search ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for sas_device based on sas_address, then return sas_device ++ * object. ++ */ ++struct _sas_device * ++mpt2sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return sas_device; ++} ++ ++static struct _sas_device * ++__mpt2sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device; ++ ++ assert_spin_locked(&ioc->sas_device_lock); ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) ++ if (sas_device->handle == handle) ++ goto found_device; ++ ++ list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) ++ if (sas_device->handle == handle) ++ goto found_device; ++ ++ return NULL; ++ ++found_device: ++ sas_device_get(sas_device); ++ return sas_device; ++} ++ ++/** ++ * mpt2sas_get_sdev_by_handle - sas device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for sas_device based on sas_address, then return sas_device ++ * object. ++ */ ++static struct _sas_device * ++mpt2sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return sas_device; ++} ++ ++/** ++ * _scsih_sas_device_remove - remove sas_device from list. ++ * @ioc: per adapter object ++ * @sas_device: the sas_device object ++ * Context: This function will acquire ioc->sas_device_lock. ++ * ++ * If sas_device is on the list, remove it and decrement its reference count. ++ */ ++static void ++_scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ if (!sas_device) ++ return; ++ pr_info(MPT3SAS_FMT ++ "removing handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, sas_device->handle, ++ (unsigned long long) sas_device->sas_address); ++ ++ if (sas_device->enclosure_handle != 0) ++ pr_info(MPT3SAS_FMT ++ "removing enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot); ++ ++ if (sas_device->connector_name[0] != '\0') ++ pr_info(MPT3SAS_FMT ++ "removing enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ /* ++ * The lock serializes access to the list, but we still need to verify ++ * that nobody removed the entry while we were waiting on the lock. ++ */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ if (!list_empty(&sas_device->list)) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_device_remove_by_handle - removing device object by handle ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_device_remove_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (sas_device) { ++ _scsih_remove_device(ioc, sas_device); ++ sas_device_put(sas_device); ++ } ++} ++ ++/** ++ * mpt2sas_device_remove_by_sas_address - removing device object by sas address ++ * @ioc: per adapter object ++ * @sas_address: device sas_address ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, sas_address); ++ if (sas_device) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (sas_device) { ++ _scsih_remove_device(ioc, sas_device); ++ sas_device_put(sas_device); ++ } ++} ++ ++/** ++ * _scsih_sas_device_add - insert sas_device to the list. ++ * @ioc: per adapter object ++ * @sas_device: the sas_device object ++ * Context: This function will acquire ioc->sas_device_lock. ++ * ++ * Adding new object to the ioc->sas_device_list. ++ */ ++static void ++_scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, __func__, sas_device->handle, ++ (unsigned long long)sas_device->sas_address)); ++ ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure logical id(0x%016llx), slot( %d)\n", ++ ioc->name, __func__, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot)); ++ ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, __func__, ++ sas_device->enclosure_level, sas_device->connector_name)); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device_get(sas_device); ++ list_add_tail(&sas_device->list, &ioc->sas_device_list); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (!mpt2sas_transport_port_add(ioc, sas_device->handle, ++ sas_device->sas_address_parent)) { ++ _scsih_sas_device_remove(ioc, sas_device); ++ } else if (!sas_device->starget) { ++ /* ++ * When asyn scanning is enabled, its not possible to remove ++ * devices while scanning is turned on due to an oops in ++ * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start() ++ */ ++ if (!ioc->is_driver_loading) { ++ mpt2sas_transport_port_remove(ioc, ++ sas_device->sas_address, ++ sas_device->sas_address_parent); ++ _scsih_sas_device_remove(ioc, sas_device); ++ } ++ } ++} ++ ++/** ++ * _scsih_sas_device_init_add - insert sas_device to the list. ++ * @ioc: per adapter object ++ * @sas_device: the sas_device object ++ * Context: This function will acquire ioc->sas_device_lock. ++ * ++ * Adding new object at driver load time to the ioc->sas_device_init_list. ++ */ ++static void ++_scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ __func__, sas_device->handle, ++ (unsigned long long)sas_device->sas_address)); ++ ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure logical id(0x%016llx), slot( %d)\n", ++ ioc->name, __func__, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot)); ++ ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, __func__, sas_device->enclosure_level, ++ sas_device->connector_name)); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device_get(sas_device); ++ list_add_tail(&sas_device->list, &ioc->sas_device_init_list); ++ _scsih_determine_boot_device(ioc, sas_device, 0); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_raid_device_find_by_id - raid device search ++ * @ioc: per adapter object ++ * @id: sas device target id ++ * @channel: sas device channel ++ * Context: Calling function should acquire ioc->raid_device_lock ++ * ++ * This searches for raid_device based on target id, then return raid_device ++ * object. ++ */ ++static struct _raid_device * ++_scsih_raid_device_find_by_id(struct MPT3SAS_ADAPTER *ioc, int id, int channel) ++{ ++ struct _raid_device *raid_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->id == id && raid_device->channel == channel) { ++ r = raid_device; ++ goto out; ++ } ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_raid_device_find_by_handle - raid device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->raid_device_lock ++ * ++ * This searches for raid_device based on handle, then return raid_device ++ * object. ++ */ ++struct _raid_device * ++mpt2sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _raid_device *raid_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->handle != handle) ++ continue; ++ r = raid_device; ++ goto out; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * _scsih_raid_device_find_by_wwid - raid device search ++ * @ioc: per adapter object ++ * @handle: sas device handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->raid_device_lock ++ * ++ * This searches for raid_device based on wwid, then return raid_device ++ * object. ++ */ ++static struct _raid_device * ++_scsih_raid_device_find_by_wwid(struct MPT3SAS_ADAPTER *ioc, u64 wwid) ++{ ++ struct _raid_device *raid_device, *r; ++ ++ r = NULL; ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->wwid != wwid) ++ continue; ++ r = raid_device; ++ goto out; ++ } ++ ++ out: ++ return r; ++} ++ ++/** ++ * _scsih_raid_device_add - add raid_device object ++ * @ioc: per adapter object ++ * @raid_device: raid_device object ++ * ++ * This is added to the raid_device_list link list. ++ */ ++static void ++_scsih_raid_device_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ unsigned long flags; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), wwid(0x%016llx)\n", ioc->name, __func__, ++ raid_device->handle, (unsigned long long)raid_device->wwid)); ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_add_tail(&raid_device->list, &ioc->raid_device_list); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * _scsih_raid_device_remove - delete raid_device object ++ * @ioc: per adapter object ++ * @raid_device: raid_device object ++ * ++ */ ++static void ++_scsih_raid_device_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_del(&raid_device->list); ++ kfree(raid_device); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * mpt2sas_scsih_expander_find_by_handle - expander device search ++ * @ioc: per adapter object ++ * @handle: expander handle (assigned by firmware) ++ * Context: Calling function should acquire ioc->sas_device_lock ++ * ++ * This searches for expander device based on handle, then returns the ++ * sas_node object. ++ */ ++struct _sas_node * ++mpt2sas_scsih_expander_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_node *sas_expander, *r; ++ ++ r = NULL; ++ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { ++ if (sas_expander->handle != handle) ++ continue; ++ r = sas_expander; ++ goto out; ++ } ++ out: ++ return r; ++} ++ ++/** ++ * mpt2sas_scsih_expander_find_by_sas_address - expander device search ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * Context: Calling function should acquire ioc->sas_node_lock. ++ * ++ * This searches for expander device based on sas_address, then returns the ++ * sas_node object. ++ */ ++struct _sas_node * ++mpt2sas_scsih_expander_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ struct _sas_node *sas_expander, *r; ++ ++ r = NULL; ++ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { ++ if (sas_expander->sas_address != sas_address) ++ continue; ++ r = sas_expander; ++ goto out; ++ } ++ out: ++ return r; ++} ++ ++/** ++ * _scsih_expander_node_add - insert expander device to the list. ++ * @ioc: per adapter object ++ * @sas_expander: the sas_device object ++ * Context: This function will acquire ioc->sas_node_lock. ++ * ++ * Adding new object to the ioc->sas_expander_list. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_expander_node_add(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_add_tail(&sas_expander->list, &ioc->sas_expander_list); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++} ++ ++/** ++ * _scsih_is_end_device - determines if device is an end device ++ * @device_info: bitfield providing information about the device. ++ * Context: none ++ * ++ * Returns 1 if end device. ++ */ ++static int ++_scsih_is_end_device(u32 device_info) ++{ ++ if (device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE && ++ ((device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) | ++ (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) | ++ (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE))) ++ return 1; ++ else ++ return 0; ++} ++ ++/** ++ * _scsih_scsi_lookup_get - returns scmd entry ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns the smid stored scmd pointer. ++ */ ++static struct scsi_cmnd * ++_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return ioc->scsi_lookup[smid - 1].scmd; ++} ++ ++/** ++ * _scsih_scsi_lookup_get_clear - returns scmd entry ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns the smid stored scmd pointer. ++ * Then will derefrence the stored scmd pointer. ++ */ ++static inline struct scsi_cmnd * ++_scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ unsigned long flags; ++ struct scsi_cmnd *scmd; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ scmd = ioc->scsi_lookup[smid - 1].scmd; ++ ioc->scsi_lookup[smid - 1].scmd = NULL; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ return scmd; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_scmd - scmd lookup ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @scmd: pointer to scsi command object ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a scmd pointer in the scsi_lookup array, ++ * returning the revelent smid. A returned value of zero means invalid. ++ */ ++static u16 ++_scsih_scsi_lookup_find_by_scmd(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd ++ *scmd) ++{ ++ u16 smid; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ smid = 0; ++ for (i = 0; i < ioc->scsiio_depth; i++) { ++ if (ioc->scsi_lookup[i].scmd == scmd) { ++ smid = ioc->scsi_lookup[i].smid; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return smid; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_target - search for matching channel:id ++ * @ioc: per adapter object ++ * @id: target id ++ * @channel: channel ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a matching channel:id in the scsi_lookup array, ++ * returning 1 if found. ++ */ ++static u8 ++_scsih_scsi_lookup_find_by_target(struct MPT3SAS_ADAPTER *ioc, int id, ++ int channel) ++{ ++ u8 found; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ found = 0; ++ for (i = 0 ; i < ioc->scsiio_depth; i++) { ++ if (ioc->scsi_lookup[i].scmd && ++ (ioc->scsi_lookup[i].scmd->device->id == id && ++ ioc->scsi_lookup[i].scmd->device->channel == channel)) { ++ found = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return found; ++} ++ ++/** ++ * _scsih_scsi_lookup_find_by_lun - search for matching channel:id:lun ++ * @ioc: per adapter object ++ * @id: target id ++ * @lun: lun number ++ * @channel: channel ++ * Context: This function will acquire ioc->scsi_lookup_lock. ++ * ++ * This will search for a matching channel:id:lun in the scsi_lookup array, ++ * returning 1 if found. ++ */ ++static u8 ++_scsih_scsi_lookup_find_by_lun(struct MPT3SAS_ADAPTER *ioc, int id, ++ unsigned int lun, int channel) ++{ ++ u8 found; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ found = 0; ++ for (i = 0 ; i < ioc->scsiio_depth; i++) { ++ if (ioc->scsi_lookup[i].scmd && ++ (ioc->scsi_lookup[i].scmd->device->id == id && ++ ioc->scsi_lookup[i].scmd->device->channel == channel && ++ ioc->scsi_lookup[i].scmd->device->lun == lun)) { ++ found = 1; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ return found; ++} ++ ++static void ++_scsih_adjust_queue_depth(struct scsi_device *sdev, int qdepth) ++{ ++ struct Scsi_Host *shost = sdev->host; ++ int max_depth; ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ max_depth = shost->can_queue; ++ ++ /* limit max device queue for SATA to 32 */ ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ goto not_sata; ++ sas_target_priv_data = sas_device_priv_data->sas_target; ++ if (!sas_target_priv_data) ++ goto not_sata; ++ if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) ++ goto not_sata; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data); ++ if (sas_device) { ++ if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ max_depth = MPT3SAS_SATA_QUEUE_DEPTH; ++ ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ not_sata: ++ ++ if (!sdev->tagged_supported) ++ max_depth = 1; ++ if (qdepth > max_depth) ++ qdepth = max_depth; ++ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); ++} ++ ++/** ++ * scsih_change_queue_depth_mpt2sas - setting device queue depth ++ * @sdev: scsi device struct ++ * @qdepth: requested queue depth ++ * @reason: SCSI_QDEPTH_DEFAULT/SCSI_QDEPTH_QFULL/SCSI_QDEPTH_RAMP_UP ++ * (see include/scsi/scsi_host.h for definition) ++ * ++ * Returns queue depth. ++ */ ++int ++scsih_change_queue_depth_mpt2sas(struct scsi_device *sdev, int qdepth, int reason) ++{ ++ if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) ++ _scsih_adjust_queue_depth(sdev, qdepth); ++ else if (reason == SCSI_QDEPTH_QFULL) ++ scsi_track_queue_full(sdev, qdepth); ++ else ++ return -EOPNOTSUPP; ++ ++ if (sdev->inquiry_len > 7) ++ sdev_printk(KERN_INFO, sdev, "qdepth(%d), tagged(%d), " \ ++ "simple(%d), ordered(%d), scsi_level(%d), cmd_que(%d)\n", ++ sdev->queue_depth, sdev->tagged_supported, sdev->simple_tags, ++ sdev->ordered_tags, sdev->scsi_level, ++ (sdev->inquiry[7] & 2) >> 1); ++ ++ return sdev->queue_depth; ++} ++ ++/** ++ * _scsih_change_queue_type_mpt2sas - changing device queue tag type ++ * @sdev: scsi device struct ++ * @tag_type: requested tag type ++ * ++ * Returns queue tag type. ++ */ ++int ++_scsih_change_queue_type_mpt2sas(struct scsi_device *sdev, int tag_type) ++{ ++ if (sdev->tagged_supported) { ++ scsi_set_tag_type(sdev, tag_type); ++ if (tag_type) ++ scsi_activate_tcq(sdev, sdev->queue_depth); ++ else ++ scsi_deactivate_tcq(sdev, sdev->queue_depth); ++ } else ++ tag_type = 0; ++ ++ return tag_type; ++} ++ ++ ++/** ++ * scsih_target_alloc_mpt2sas - target add routine ++ * @starget: scsi target struct ++ * ++ * Returns 0 if ok. Any other return is assumed to be an error and ++ * the device is ignored. ++ */ ++int ++scsih_target_alloc_mpt2sas(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost = dev_to_shost(&starget->dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ struct sas_rphy *rphy; ++ ++ sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data), ++ GFP_KERNEL); ++ if (!sas_target_priv_data) ++ return -ENOMEM; ++ ++ starget->hostdata = sas_target_priv_data; ++ sas_target_priv_data->starget = starget; ++ sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; ++ ++ /* RAID volumes */ ++ if (starget->channel == RAID_CHANNEL) { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, starget->id, ++ starget->channel); ++ if (raid_device) { ++ sas_target_priv_data->handle = raid_device->handle; ++ sas_target_priv_data->sas_address = raid_device->wwid; ++ sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; ++ sas_target_priv_data->raid_device = raid_device; ++ if (ioc->is_warpdrive) ++ raid_device->starget = starget; ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ return 0; ++ } ++ ++ /* sas/sata devices */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ rphy = dev_to_rphy(starget->dev.parent); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ rphy->identify.sas_address); ++ ++ if (sas_device) { ++ sas_target_priv_data->handle = sas_device->handle; ++ sas_target_priv_data->sas_address = sas_device->sas_address; ++ sas_target_priv_data->sdev = sas_device; ++ sas_device->starget = starget; ++ sas_device->id = starget->id; ++ sas_device->channel = starget->channel; ++ if (test_bit(sas_device->handle, ioc->pd_handles)) ++ sas_target_priv_data->flags |= ++ MPT_TARGET_FLAGS_RAID_COMPONENT; ++ if (sas_device->fast_path) ++ sas_target_priv_data->flags |= MPT_TARGET_FASTPATH_IO; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return 0; ++} ++ ++/** ++ * scsih_target_destroy_mpt2sas - target destroy routine ++ * @starget: scsi target struct ++ * ++ * Returns nothing. ++ */ ++void ++scsih_target_destroy_mpt2sas(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost = dev_to_shost(&starget->dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ struct sas_rphy *rphy; ++ ++ sas_target_priv_data = starget->hostdata; ++ if (!sas_target_priv_data) ++ return; ++ ++ if (starget->channel == RAID_CHANNEL) { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, starget->id, ++ starget->channel); ++ if (raid_device) { ++ raid_device->starget = NULL; ++ raid_device->sdev = NULL; ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ goto out; ++ } ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ rphy = dev_to_rphy(starget->dev.parent); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data); ++ if (sas_device && (sas_device->starget == starget) && ++ (sas_device->id == starget->id) && ++ (sas_device->channel == starget->channel)) ++ sas_device->starget = NULL; ++ ++ if (sas_device) { ++ /* ++ * Corresponding get() is in _scsih_target_alloc_mpt2sas() ++ */ ++ sas_target_priv_data->sdev = NULL; ++ sas_device_put(sas_device); ++ ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ out: ++ kfree(sas_target_priv_data); ++ starget->hostdata = NULL; ++} ++ ++/** ++ * scsih_slave_alloc_mpt2sas - device add routine ++ * @sdev: scsi device struct ++ * ++ * Returns 0 if ok. Any other return is assumed to be an error and ++ * the device is ignored. ++ */ ++int ++scsih_slave_alloc_mpt2sas(struct scsi_device *sdev) ++{ ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_target *starget; ++ struct _raid_device *raid_device; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data), ++ GFP_KERNEL); ++ if (!sas_device_priv_data) ++ return -ENOMEM; ++ ++ sas_device_priv_data->lun = sdev->lun; ++ sas_device_priv_data->flags = MPT_DEVICE_FLAGS_INIT; ++ ++ starget = scsi_target(sdev); ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->num_luns++; ++ sas_device_priv_data->sas_target = sas_target_priv_data; ++ sdev->hostdata = sas_device_priv_data; ++ if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT)) ++ sdev->no_uld_attach = 1; ++ ++ shost = dev_to_shost(&starget->dev); ++ ioc = shost_priv(shost); ++ if (starget->channel == RAID_CHANNEL) { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, ++ starget->id, starget->channel); ++ if (raid_device) ++ raid_device->sdev = sdev; /* raid is single lun */ ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++ ++ if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_target_priv_data->sas_address); ++ if (sas_device && (sas_device->starget == NULL)) { ++ sdev_printk(KERN_INFO, sdev, ++ "%s : sas_device->starget set to starget @ %d\n", ++ __func__, __LINE__); ++ sas_device->starget = starget; ++ } ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ ++ return 0; ++} ++ ++/** ++ * scsih_slave_destroy_mpt2sas - device destroy routine ++ * @sdev: scsi device struct ++ * ++ * Returns nothing. ++ */ ++void ++scsih_slave_destroy_mpt2sas(struct scsi_device *sdev) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct scsi_target *starget; ++ struct Scsi_Host *shost; ++ struct MPT3SAS_ADAPTER *ioc; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ if (!sdev->hostdata) ++ return; ++ ++ starget = scsi_target(sdev); ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->num_luns--; ++ ++ shost = dev_to_shost(&starget->dev); ++ ioc = shost_priv(shost); ++ ++ if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, ++ sas_target_priv_data); ++ if (sas_device && !sas_target_priv_data->num_luns) ++ sas_device->starget = NULL; ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ ++ kfree(sdev->hostdata); ++ sdev->hostdata = NULL; ++} ++ ++/** ++ * _scsih_display_sata_capabilities - sata capabilities ++ * @ioc: per adapter object ++ * @handle: device handle ++ * @sdev: scsi device struct ++ */ ++static void ++_scsih_display_sata_capabilities(struct MPT3SAS_ADAPTER *ioc, ++ u16 handle, struct scsi_device *sdev) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ u32 ioc_status; ++ u16 flags; ++ u32 device_info; ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ flags = le16_to_cpu(sas_device_pg0.Flags); ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ ++ sdev_printk(KERN_INFO, sdev, ++ "atapi(%s), ncq(%s), asyn_notify(%s), smart(%s), fua(%s), " ++ "sw_preserve(%s)\n", ++ (device_info & MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY) ? "y" : ++ "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED) ? "y" : "n", ++ (flags & MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE) ? "y" : "n"); ++} ++ ++/* ++ * raid transport support - ++ * Enabled for SLES11 and newer, in older kernels the driver will panic when ++ * unloading the driver followed by a load - I beleive that the subroutine ++ * raid_class_release() is not cleaning up properly. ++ */ ++ ++/** ++ * scsih_is_raid_mpt2sas - return boolean indicating device is raid volume ++ * @dev the device struct object ++ */ ++int ++scsih_is_raid_mpt2sas(struct device *dev) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); ++ ++ if (ioc->is_warpdrive) ++ return 0; ++ return (sdev->channel == RAID_CHANNEL) ? 1 : 0; ++} ++ ++/** ++ * scsih_get_resync_mpt2sas - get raid volume resync percent complete ++ * @dev the device struct object ++ */ ++void ++scsih_get_resync_mpt2sas(struct device *dev) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); ++ static struct _raid_device *raid_device; ++ unsigned long flags; ++ Mpi2RaidVolPage0_t vol_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 volume_status_flags; ++ u8 percent_complete; ++ u16 handle; ++ ++ percent_complete = 0; ++ handle = 0; ++ if (ioc->is_warpdrive) ++ goto out; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, ++ sdev->channel); ++ if (raid_device) { ++ handle = raid_device->handle; ++ percent_complete = raid_device->percent_complete; ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (!handle) ++ goto out; ++ ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ percent_complete = 0; ++ goto out; ++ } ++ ++ volume_status_flags = le32_to_cpu(vol_pg0.VolumeStatusFlags); ++ if (!(volume_status_flags & ++ MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS)) ++ percent_complete = 0; ++ ++ out: ++ ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ raid_set_resync(mpt2sas_raid_template_mpt2sas, dev, percent_complete); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ raid_set_resync(mpt3sas_raid_template_mpt2sas, dev, percent_complete); ++ break; ++ } ++} ++ ++/** ++ * scsih_get_state_mpt2sas - get raid volume level ++ * @dev the device struct object ++ */ ++void ++scsih_get_state_mpt2sas(struct device *dev) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host); ++ static struct _raid_device *raid_device; ++ unsigned long flags; ++ Mpi2RaidVolPage0_t vol_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 volstate; ++ enum raid_state state = RAID_STATE_UNKNOWN; ++ u16 handle = 0; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_id(ioc, sdev->id, ++ sdev->channel); ++ if (raid_device) ++ handle = raid_device->handle; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (!raid_device) ++ goto out; ++ ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ volstate = le32_to_cpu(vol_pg0.VolumeStatusFlags); ++ if (volstate & MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { ++ state = RAID_STATE_RESYNCING; ++ goto out; ++ } ++ ++ switch (vol_pg0.VolumeState) { ++ case MPI2_RAID_VOL_STATE_OPTIMAL: ++ case MPI2_RAID_VOL_STATE_ONLINE: ++ state = RAID_STATE_ACTIVE; ++ break; ++ case MPI2_RAID_VOL_STATE_DEGRADED: ++ state = RAID_STATE_DEGRADED; ++ break; ++ case MPI2_RAID_VOL_STATE_FAILED: ++ case MPI2_RAID_VOL_STATE_MISSING: ++ state = RAID_STATE_OFFLINE; ++ break; ++ } ++ out: ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ raid_set_state(mpt2sas_raid_template_mpt2sas, dev, state); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ raid_set_state(mpt3sas_raid_template_mpt2sas, dev, state); ++ break; ++ } ++} ++ ++/** ++ * _scsih_set_level - set raid level ++ * @sdev: scsi device struct ++ * @volume_type: volume type ++ */ ++static void ++_scsih_set_level(struct MPT3SAS_ADAPTER *ioc, ++ struct scsi_device *sdev, u8 volume_type) ++{ ++ enum raid_level level = RAID_LEVEL_UNKNOWN; ++ ++ switch (volume_type) { ++ case MPI2_RAID_VOL_TYPE_RAID0: ++ level = RAID_LEVEL_0; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID10: ++ level = RAID_LEVEL_10; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1E: ++ level = RAID_LEVEL_1E; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1: ++ level = RAID_LEVEL_1; ++ break; ++ } ++ ++ switch (ioc->hba_mpi_version_belonged) { ++ case MPI2_VERSION: ++ raid_set_level(mpt2sas_raid_template_mpt2sas, ++ &sdev->sdev_gendev, level); ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ raid_set_level(mpt3sas_raid_template_mpt2sas, ++ &sdev->sdev_gendev, level); ++ break; ++ } ++} ++ ++ ++/** ++ * _scsih_get_volume_capabilities - volume capabilities ++ * @ioc: per adapter object ++ * @sas_device: the raid_device object ++ * ++ * Returns 0 for success, else 1 ++ */ ++static int ++_scsih_get_volume_capabilities(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ Mpi2RaidVolPage0_t *vol_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 sz; ++ u8 num_pds; ++ ++ if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, ++ &num_pds)) || !num_pds) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ return 1; ++ } ++ ++ raid_device->num_pds = num_pds; ++ sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * ++ sizeof(Mpi2RaidVol0PhysDisk_t)); ++ vol_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!vol_pg0) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ return 1; ++ } ++ ++ if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ kfree(vol_pg0); ++ return 1; ++ } ++ ++ raid_device->volume_type = vol_pg0->VolumeType; ++ ++ /* figure out what the underlying devices are by ++ * obtaining the device_info bits for the 1st device ++ */ ++ if (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, ++ vol_pg0->PhysDisk[0].PhysDiskNum))) { ++ if (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ++ le16_to_cpu(pd_pg0.DevHandle)))) { ++ raid_device->device_info = ++ le32_to_cpu(sas_device_pg0.DeviceInfo); ++ } ++ } ++ ++ kfree(vol_pg0); ++ return 0; ++} ++ ++/** ++ * _scsih_enable_tlr - setting TLR flags ++ * @ioc: per adapter object ++ * @sdev: scsi device struct ++ * ++ * Enabling Transaction Layer Retries for tape devices when ++ * vpd page 0x90 is present ++ * ++ */ ++static void ++_scsih_enable_tlr(struct MPT3SAS_ADAPTER *ioc, struct scsi_device *sdev) ++{ ++ ++ /* only for TAPE */ ++ if (sdev->type != TYPE_TAPE) ++ return; ++ ++ if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)) ++ return; ++ ++ sas_enable_tlr(sdev); ++ sdev_printk(KERN_INFO, sdev, "TLR %s\n", ++ sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled"); ++ return; ++ ++} ++ ++/** ++ * scsih_slave_configure_mpt2sas - device configure routine. ++ * @sdev: scsi device struct ++ * ++ * Returns 0 if ok. Any other return is assumed to be an error and ++ * the device is ignored. ++ */ ++int ++scsih_slave_configure_mpt2sas(struct scsi_device *sdev) ++{ ++ struct Scsi_Host *shost = sdev->host; ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ int qdepth; ++ u8 ssp_target = 0; ++ char *ds = ""; ++ char *r_level = ""; ++ u16 handle, volume_handle = 0; ++ u64 volume_wwid = 0; ++ ++ qdepth = 1; ++ sas_device_priv_data = sdev->hostdata; ++ sas_device_priv_data->configured_lun = 1; ++ sas_device_priv_data->flags &= ~MPT_DEVICE_FLAGS_INIT; ++ sas_target_priv_data = sas_device_priv_data->sas_target; ++ handle = sas_target_priv_data->handle; ++ ++ /* raid volume handling */ ++ if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) { ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ if (!raid_device) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, ++ __LINE__, __func__)); ++ return 1; ++ } ++ ++ if (_scsih_get_volume_capabilities(ioc, raid_device)) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, ++ __LINE__, __func__)); ++ return 1; ++ } ++ ++ /* ++ * WARPDRIVE: Initialize the required data for Direct IO ++ */ ++ mpt2sas_init_warpdrive_properties(ioc, raid_device); ++ ++ /* RAID Queue Depth Support ++ * IS volume = underlying qdepth of drive type, either ++ * MPT3SAS_SAS_QUEUE_DEPTH or MPT3SAS_SATA_QUEUE_DEPTH ++ * IM/IME/R10 = 128 (MPT3SAS_RAID_QUEUE_DEPTH) ++ */ ++ if (raid_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SSP_TARGET) { ++ qdepth = MPT3SAS_SAS_QUEUE_DEPTH; ++ ds = "SSP"; ++ } else { ++ qdepth = MPT3SAS_SATA_QUEUE_DEPTH; ++ if (raid_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ ds = "SATA"; ++ else ++ ds = "STP"; ++ } ++ ++ switch (raid_device->volume_type) { ++ case MPI2_RAID_VOL_TYPE_RAID0: ++ r_level = "RAID0"; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1E: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ if (ioc->manu_pg10.OEMIdentifier && ++ (le32_to_cpu(ioc->manu_pg10.GenericFlags0) & ++ MFG10_GF0_R10_DISPLAY) && ++ !(raid_device->num_pds % 2)) ++ r_level = "RAID10"; ++ else ++ r_level = "RAID1E"; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID1: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ r_level = "RAID1"; ++ break; ++ case MPI2_RAID_VOL_TYPE_RAID10: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ r_level = "RAID10"; ++ break; ++ case MPI2_RAID_VOL_TYPE_UNKNOWN: ++ default: ++ qdepth = MPT3SAS_RAID_QUEUE_DEPTH; ++ r_level = "RAIDX"; ++ break; ++ } ++ ++ if (!ioc->hide_ir_msg) ++ sdev_printk(KERN_INFO, sdev, ++ "%s: handle(0x%04x), wwid(0x%016llx)," ++ " pd_count(%d), type(%s)\n", ++ r_level, raid_device->handle, ++ (unsigned long long)raid_device->wwid, ++ raid_device->num_pds, ds); ++ ++ if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) { ++ blk_queue_max_hw_sectors(sdev->request_queue, ++ MPT3SAS_RAID_MAX_SECTORS); ++ sdev_printk(KERN_INFO, sdev, ++ "Set queue's max_sector to: %u\n", ++ MPT3SAS_RAID_MAX_SECTORS); ++ } ++ ++ scsih_change_queue_depth_mpt2sas(sdev, qdepth, SCSI_QDEPTH_DEFAULT); ++ ++ /* raid transport support */ ++ if (!ioc->is_warpdrive) ++ _scsih_set_level(ioc, sdev, raid_device->volume_type); ++ return 0; ++ } ++ ++ /* non-raid handling */ ++ if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ if (mpt2sas_config_get_volume_handle(ioc, handle, ++ &volume_handle)) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__)); ++ return 1; ++ } ++ if (volume_handle && mpt2sas_config_get_volume_wwid(ioc, ++ volume_handle, &volume_wwid)) { ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__)); ++ return 1; ++ } ++ } ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_device_priv_data->sas_target->sas_address); ++ if (!sas_device) { ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ dfailprintk(ioc, pr_warn(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, ++ __func__)); ++ return 1; ++ } ++ ++ sas_device->volume_handle = volume_handle; ++ sas_device->volume_wwid = volume_wwid; ++ if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { ++ qdepth = MPT3SAS_SAS_QUEUE_DEPTH; ++ ssp_target = 1; ++ if (sas_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SEP) { ++ sdev_printk(KERN_WARNING, sdev, ++ "set ignore_delay_remove for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle); ++ sas_device_priv_data->ignore_delay_remove = 1; ++ ds = "SES"; ++ } else ++ ds = "SSP"; ++ } else { ++ qdepth = MPT3SAS_SATA_QUEUE_DEPTH; ++ if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) ++ ds = "STP"; ++ else if (sas_device->device_info & ++ MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ ds = "SATA"; ++ } ++ ++ sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), " \ ++ "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", ++ ds, handle, (unsigned long long)sas_device->sas_address, ++ sas_device->phy, (unsigned long long)sas_device->device_name); ++ if (sas_device->enclosure_handle != 0) ++ sdev_printk(KERN_INFO, sdev, ++ "%s: enclosure_logical_id(0x%016llx), slot(%d)\n", ++ ds, (unsigned long long) ++ sas_device->enclosure_logical_id, sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ sdev_printk(KERN_INFO, sdev, ++ "%s: enclosure level(0x%04x), connector name( %s)\n", ++ ds, sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ sas_device_put(sas_device); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (!ssp_target) ++ _scsih_display_sata_capabilities(ioc, handle, sdev); ++ ++ ++ scsih_change_queue_depth_mpt2sas(sdev, qdepth, SCSI_QDEPTH_DEFAULT); ++ ++ if (ssp_target) { ++ sas_read_port_mode_page(sdev); ++ _scsih_enable_tlr(ioc, sdev); ++ } ++ ++ return 0; ++} ++ ++/** ++ * scsih_bios_param_mpt2sas - fetch head, sector, cylinder info for a disk ++ * @sdev: scsi device struct ++ * @bdev: pointer to block device context ++ * @capacity: device size (in 512 byte sectors) ++ * @params: three element array to place output: ++ * params[0] number of heads (max 255) ++ * params[1] number of sectors (max 63) ++ * params[2] number of cylinders ++ * ++ * Return nothing. ++ */ ++int ++scsih_bios_param_mpt2sas(struct scsi_device *sdev, struct block_device *bdev, ++ sector_t capacity, int params[]) ++{ ++ int heads; ++ int sectors; ++ sector_t cylinders; ++ ulong dummy; ++ ++ heads = 64; ++ sectors = 32; ++ ++ dummy = heads * sectors; ++ cylinders = capacity; ++ sector_div(cylinders, dummy); ++ ++ /* ++ * Handle extended translation size for logical drives ++ * > 1Gb ++ */ ++ if ((ulong)capacity >= 0x200000) { ++ heads = 255; ++ sectors = 63; ++ dummy = heads * sectors; ++ cylinders = capacity; ++ sector_div(cylinders, dummy); ++ } ++ ++ /* return result */ ++ params[0] = heads; ++ params[1] = sectors; ++ params[2] = cylinders; ++ ++ return 0; ++} ++ ++/** ++ * _scsih_response_code - translation of device response code ++ * @ioc: per adapter object ++ * @response_code: response code returned by the device ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_response_code(struct MPT3SAS_ADAPTER *ioc, u8 response_code) ++{ ++ char *desc; ++ ++ switch (response_code) { ++ case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE: ++ desc = "task management request completed"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME: ++ desc = "invalid frame"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED: ++ desc = "task management request not supported"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_FAILED: ++ desc = "task management request failed"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED: ++ desc = "task management request succeeded"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN: ++ desc = "invalid lun"; ++ break; ++ case 0xA: ++ desc = "overlapped tag attempted"; ++ break; ++ case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC: ++ desc = "task queued, however not sent to target"; ++ break; ++ default: ++ desc = "unknown"; ++ break; ++ } ++ pr_warn(MPT3SAS_FMT "response_code(0x%01x): %s\n", ++ ioc->name, response_code, desc); ++} ++ ++/** ++ * _scsih_tm_done - tm completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: none. ++ * ++ * The callback handler when using scsih_issue_tm. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ if (ioc->tm_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->tm_cmds.smid != smid) ++ return 1; ++ ioc->tm_cmds.status |= MPT3_CMD_COMPLETE; ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (mpi_reply) { ++ memcpy(ioc->tm_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); ++ ioc->tm_cmds.status |= MPT3_CMD_REPLY_VALID; ++ } ++ ioc->tm_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->tm_cmds.done); ++ return 1; ++} ++ ++/** ++ * mpt2sas_scsih_set_tm_flag - set per target tm_busy ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During taskmangement request, we need to freeze the device queue. ++ */ ++void ++mpt2sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ u8 skip = 0; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ if (skip) ++ continue; ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->handle == handle) { ++ sas_device_priv_data->sas_target->tm_busy = 1; ++ skip = 1; ++ ioc->ignore_loginfos = 1; ++ } ++ } ++} ++ ++/** ++ * mpt2sas_scsih_clear_tm_flag - clear per target tm_busy ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During taskmangement request, we need to freeze the device queue. ++ */ ++void ++mpt2sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ u8 skip = 0; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ if (skip) ++ continue; ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->handle == handle) { ++ sas_device_priv_data->sas_target->tm_busy = 0; ++ skip = 1; ++ ioc->ignore_loginfos = 0; ++ } ++ } ++} ++ ++/** ++ * mpt2sas_scsih_issue_tm - main routine for sending tm requests ++ * @ioc: per adapter struct ++ * @device_handle: device handle ++ * @channel: the channel assigned by the OS ++ * @id: the id assigned by the OS ++ * @lun: lun number ++ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) ++ * @smid_task: smid assigned to the task ++ * @timeout: timeout in seconds ++ * @m_type: TM_MUTEX_ON or TM_MUTEX_OFF ++ * Context: user ++ * ++ * A generic API for sending task management requests to firmware. ++ * ++ * The callback index is set inside `ioc->tm_cb_idx`. ++ * ++ * Return SUCCESS or FAILED. ++ */ ++int ++mpt2sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ++ uint id, uint lun, u8 type, u16 smid_task, ulong timeout, ++ enum mutex_type m_type) ++{ ++ Mpi2SCSITaskManagementRequest_t *mpi_request; ++ Mpi2SCSITaskManagementReply_t *mpi_reply; ++ u16 smid = 0; ++ u32 ioc_state; ++ unsigned long timeleft; ++ struct scsiio_tracker *scsi_lookup = NULL; ++ int rc; ++ u16 msix_task = 0; ++ ++ if (m_type == TM_MUTEX_ON) ++ mutex_lock(&ioc->tm_cmds.mutex); ++ if (ioc->tm_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_info(MPT3SAS_FMT "%s: tm_cmd busy!!!\n", ++ __func__, ioc->name); ++ rc = FAILED; ++ goto err_out; ++ } ++ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ rc = FAILED; ++ goto err_out; ++ } ++ ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 0); ++ if (ioc_state & MPI2_DOORBELL_USED) { ++ dhsprintk(ioc, pr_info(MPT3SAS_FMT ++ "unexpected doorbell active!\n", ioc->name)); ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = (!rc) ? SUCCESS : FAILED; ++ goto err_out; ++ } ++ ++ if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { ++ mpt2sas_base_fault_info(ioc, ioc_state & ++ MPI2_DOORBELL_DATA_MASK); ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = (!rc) ? SUCCESS : FAILED; ++ goto err_out; ++ } ++ ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = FAILED; ++ goto err_out; ++ } ++ ++ if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) ++ scsi_lookup = &ioc->scsi_lookup[smid_task - 1]; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "sending tm: handle(0x%04x), task_type(0x%02x), smid(%d)\n", ++ ioc->name, handle, type, smid_task)); ++ ioc->tm_cmds.status = MPT3_CMD_PENDING; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->tm_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); ++ memset(ioc->tm_cmds.reply, 0, sizeof(Mpi2SCSITaskManagementReply_t)); ++ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->TaskType = type; ++ mpi_request->TaskMID = cpu_to_le16(smid_task); ++ int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); ++ mpt2sas_scsih_set_tm_flag(ioc, handle); ++ init_completion(&ioc->tm_cmds.done); ++ if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) && ++ (scsi_lookup->msix_io < ioc->reply_queue_count)) ++ msix_task = scsi_lookup->msix_io; ++ else ++ msix_task = 0; ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, msix_task); ++ timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); ++ if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SCSITaskManagementRequest_t)/4); ++ if (!(ioc->tm_cmds.status & MPT3_CMD_RESET)) { ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = (!rc) ? SUCCESS : FAILED; ++ ioc->tm_cmds.status = MPT3_CMD_NOT_USED; ++ mpt2sas_scsih_clear_tm_flag(ioc, handle); ++ goto err_out; ++ } ++ } ++ ++ /* sync IRQs in case those were busy during flush. */ ++ mpt2sas_base_sync_reply_irqs(ioc); ++ ++ if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) { ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); ++ mpi_reply = ioc->tm_cmds.reply; ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "complete tm: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x), term_count(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo), ++ le32_to_cpu(mpi_reply->TerminationCount))); ++ if (ioc->logging_level & MPT_DEBUG_TM) { ++ _scsih_response_code(ioc, mpi_reply->ResponseCode); ++ if (mpi_reply->IOCStatus) ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SCSITaskManagementRequest_t)/4); ++ } ++ } ++ ++ switch (type) { ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: ++ rc = SUCCESS; ++ if (scsi_lookup->scmd == NULL) ++ break; ++ rc = FAILED; ++ break; ++ ++ case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: ++ if (_scsih_scsi_lookup_find_by_target(ioc, id, channel)) ++ rc = FAILED; ++ else ++ rc = SUCCESS; ++ break; ++ case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: ++ case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: ++ if (_scsih_scsi_lookup_find_by_lun(ioc, id, lun, channel)) ++ rc = FAILED; ++ else ++ rc = SUCCESS; ++ break; ++ case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: ++ rc = SUCCESS; ++ break; ++ default: ++ rc = FAILED; ++ break; ++ } ++ ++ mpt2sas_scsih_clear_tm_flag(ioc, handle); ++ ioc->tm_cmds.status = MPT3_CMD_NOT_USED; ++ if (m_type == TM_MUTEX_ON) ++ mutex_unlock(&ioc->tm_cmds.mutex); ++ ++ return rc; ++ ++ err_out: ++ if (m_type == TM_MUTEX_ON) ++ mutex_unlock(&ioc->tm_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _scsih_tm_display_info - displays info about the device ++ * @ioc: per adapter struct ++ * @scmd: pointer to scsi command object ++ * ++ * Called by task management callback handlers. ++ */ ++static void ++_scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) ++{ ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *priv_target = starget->hostdata; ++ struct _sas_device *sas_device = NULL; ++ unsigned long flags; ++ char *device_str = NULL; ++ ++ if (!priv_target) ++ return; ++ if (ioc->hide_ir_msg) ++ device_str = "WarpDrive"; ++ else ++ device_str = "volume"; ++ ++ scsi_print_command(scmd); ++ if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { ++ starget_printk(KERN_INFO, starget, ++ "%s handle(0x%04x), %s wwid(0x%016llx)\n", ++ device_str, priv_target->handle, ++ device_str, (unsigned long long)priv_target->sas_address); ++ } else { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_from_target(ioc, priv_target); ++ if (sas_device) { ++ if (priv_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ starget_printk(KERN_INFO, starget, ++ "volume handle(0x%04x), " ++ "volume wwid(0x%016llx)\n", ++ sas_device->volume_handle, ++ (unsigned long long)sas_device->volume_wwid); ++ } ++ starget_printk(KERN_INFO, starget, ++ "handle(0x%04x), sas_address(0x%016llx), phy(%d)\n", ++ sas_device->handle, ++ (unsigned long long)sas_device->sas_address, ++ sas_device->phy); ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, ++ "enclosure_logical_id(0x%016llx), slot(%d)\n", ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ starget_printk(KERN_INFO, starget, ++ "enclosure level(0x%04x),connector name(%s)\n", ++ sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++} ++ ++/** ++ * scsih_abort_mpt2sas - eh threads main abort routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_abort_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ u16 smid; ++ u16 handle; ++ int r; ++ ++ sdev_printk(KERN_INFO, scmd->device, ++ "attempting task abort! scmd(%p)\n", scmd); ++ _scsih_tm_display_info(ioc, scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ sdev_printk(KERN_INFO, scmd->device, ++ "device been deleted! scmd(%p)\n", scmd); ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* search for the command */ ++ smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd); ++ if (!smid) { ++ scmd->result = DID_RESET << 16; ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* for hidden raid components and volumes this is not supported */ ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT || ++ sas_device_priv_data->sas_target->flags & MPT_TARGET_FLAGS_VOLUME) { ++ scmd->result = DID_RESET << 16; ++ r = FAILED; ++ goto out; ++ } ++ ++ mpt2sas_halt_firmware(ioc); ++ ++ handle = sas_device_priv_data->sas_target->handle; ++ r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, scmd->device->lun, ++ MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON); ++ ++ out: ++ sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n", ++ ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ return r; ++} ++ ++/** ++ * scsih_dev_reset_mpt2sas - eh threads main device reset routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_dev_reset_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct _sas_device *sas_device = NULL; ++ u16 handle; ++ int r; ++ ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; ++ ++ sdev_printk(KERN_INFO, scmd->device, ++ "attempting device reset! scmd(%p)\n", scmd); ++ _scsih_tm_display_info(ioc, scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ sdev_printk(KERN_INFO, scmd->device, ++ "device been deleted! scmd(%p)\n", scmd); ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* for hidden raid components obtain the volume_handle */ ++ handle = 0; ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ sas_device = mpt2sas_get_sdev_from_target(ioc, ++ target_priv_data); ++ if (sas_device) ++ handle = sas_device->volume_handle; ++ } else ++ handle = sas_device_priv_data->sas_target->handle; ++ ++ if (!handle) { ++ scmd->result = DID_RESET << 16; ++ r = FAILED; ++ goto out; ++ } ++ ++ r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, scmd->device->lun, ++ MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON); ++ ++ out: ++ sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", ++ ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ return r; ++} ++ ++/** ++ * scsih_target_reset_mpt2sas - eh threads main target reset routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_target_reset_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct _sas_device *sas_device = NULL; ++ u16 handle; ++ int r; ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; ++ ++ starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n", ++ scmd); ++ _scsih_tm_display_info(ioc, scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", ++ scmd); ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ r = SUCCESS; ++ goto out; ++ } ++ ++ /* for hidden raid components obtain the volume_handle */ ++ handle = 0; ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) { ++ sas_device = mpt2sas_get_sdev_from_target(ioc, ++ target_priv_data); ++ if (sas_device) ++ handle = sas_device->volume_handle; ++ } else ++ handle = sas_device_priv_data->sas_target->handle; ++ ++ if (!handle) { ++ scmd->result = DID_RESET << 16; ++ r = FAILED; ++ goto out; ++ } ++ ++ r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel, ++ scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, ++ 30, TM_MUTEX_ON); ++ ++ out: ++ starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", ++ ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ return r; ++} ++ ++ ++/** ++ * scsih_host_reset_mpt2sas - eh threads main host reset routine ++ * @scmd: pointer to scsi command object ++ * ++ * Returns SUCCESS if command aborted else FAILED ++ */ ++int ++scsih_host_reset_mpt2sas(struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); ++ int r, retval; ++ ++ pr_info(MPT3SAS_FMT "attempting host reset! scmd(%p)\n", ++ ioc->name, scmd); ++ scsi_print_command(scmd); ++ ++ if (ioc->is_driver_loading) { ++ pr_info(MPT3SAS_FMT "Blocking the host reset\n", ++ ioc->name); ++ r = FAILED; ++ goto out; ++ } ++ ++ retval = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ r = (retval < 0) ? FAILED : SUCCESS; ++out: ++ pr_info(MPT3SAS_FMT "host reset: %s scmd(%p)\n", ++ ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ++ ++ return r; ++} ++ ++/** ++ * _scsih_fw_event_add - insert and queue up fw_event ++ * @ioc: per adapter object ++ * @fw_event: object describing the event ++ * Context: This function will acquire ioc->fw_event_lock. ++ * ++ * This adds the firmware event object into link list, then queues it up to ++ * be processed from user context. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_fw_event_add(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) ++{ ++ unsigned long flags; ++ ++ if (ioc->firmware_event_thread == NULL) ++ return; ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ fw_event_work_get(fw_event); ++ INIT_LIST_HEAD(&fw_event->list); ++ list_add_tail(&fw_event->list, &ioc->fw_event_list); ++ INIT_WORK(&fw_event->work, _firmware_event_work); ++ fw_event_work_get(fw_event); ++ queue_work(ioc->firmware_event_thread, &fw_event->work); ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++} ++ ++/** ++ * _scsih_fw_event_del_from_list - delete fw_event from the list ++ * @ioc: per adapter object ++ * @fw_event: object describing the event ++ * Context: This function will acquire ioc->fw_event_lock. ++ * ++ * If the fw_event is on the fw_event_list, remove it and do a put. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_fw_event_del_from_list(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work ++ *fw_event) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ if (!list_empty(&fw_event->list)) { ++ list_del_init(&fw_event->list); ++ fw_event_work_put(fw_event); ++ } ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++} ++ ++ ++ /** ++ * mpt2sas_send_trigger_data_event - send event for processing trigger data ++ * @ioc: per adapter object ++ * @event_data: trigger event data ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) ++{ ++ struct fw_event_work *fw_event; ++ u16 sz; ++ ++ if (ioc->is_driver_loading) ++ return; ++ sz = sizeof(*event_data); ++ fw_event = alloc_fw_event_work(sz); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG; ++ fw_event->ioc = ioc; ++ memcpy(fw_event->event_data, event_data, sizeof(*event_data)); ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * _scsih_error_recovery_delete_devices - remove devices not responding ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_error_recovery_delete_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct fw_event_work *fw_event; ++ ++ if (ioc->is_driver_loading) ++ return; ++ fw_event = alloc_fw_event_work(0); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_REMOVE_UNRESPONDING_DEVICES; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * mpt2sas_port_enable_complete - port enable completed (fake event) ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_port_enable_complete(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = alloc_fw_event_work(0); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_PORT_ENABLE_COMPLETE; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++static struct fw_event_work *dequeue_next_fw_event(struct MPT3SAS_ADAPTER *ioc) ++{ ++ unsigned long flags; ++ struct fw_event_work *fw_event = NULL; ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ if (!list_empty(&ioc->fw_event_list)) { ++ fw_event = list_first_entry(&ioc->fw_event_list, ++ struct fw_event_work, list); ++ list_del_init(&fw_event->list); ++ } ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++ ++ return fw_event; ++} ++ ++/** ++ * _scsih_fw_event_cleanup_queue - cleanup event queue ++ * @ioc: per adapter object ++ * ++ * Walk the firmware event queue, either killing timers, or waiting ++ * for outstanding events to complete ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct fw_event_work *fw_event; ++ ++ if (list_empty(&ioc->fw_event_list) || ++ !ioc->firmware_event_thread || in_interrupt()) ++ return; ++ ++ while ((fw_event = dequeue_next_fw_event(ioc))) { ++ /* ++ * Wait on the fw_event to complete. If this returns 1, then ++ * the event was never executed, and we need a put for the ++ * reference the work had on the fw_event. ++ * ++ * If it did execute, we wait for it to finish, and the put will ++ * happen from _firmware_event_work() ++ */ ++ if (cancel_work_sync(&fw_event->work)) ++ fw_event_work_put(fw_event); ++ ++ fw_event_work_put(fw_event); ++ } ++} ++ ++/** ++ * _scsih_internal_device_block - block the sdev device ++ * @sdev: per device object ++ * @sas_device_priv_data : per device driver private data ++ * ++ * make sure device is blocked without error, if not ++ * print an error ++ */ ++static void ++_scsih_internal_device_block(struct scsi_device *sdev, ++ struct MPT3SAS_DEVICE *sas_device_priv_data) ++{ ++ int r = 0; ++ ++ sdev_printk(KERN_INFO, sdev, "device_block, handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle); ++ sas_device_priv_data->block = 1; ++ ++ r = scsi_internal_device_block(sdev); ++ if (r == -EINVAL) ++ sdev_printk(KERN_WARNING, sdev, ++ "device_block failed with return(%d) for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle, r); ++} ++ ++/** ++ * _scsih_internal_device_unblock - unblock the sdev device ++ * @sdev: per device object ++ * @sas_device_priv_data : per device driver private data ++ * make sure device is unblocked without error, if not retry ++ * by blocking and then unblocking ++ */ ++ ++static void ++_scsih_internal_device_unblock(struct scsi_device *sdev, ++ struct MPT3SAS_DEVICE *sas_device_priv_data) ++{ ++ int r = 0; ++ ++ sdev_printk(KERN_WARNING, sdev, "device_unblock and setting to running, " ++ "handle(0x%04x)\n", sas_device_priv_data->sas_target->handle); ++ sas_device_priv_data->block = 0; ++ r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); ++ if (r == -EINVAL) { ++ /* The device has been set to SDEV_RUNNING by SD layer during ++ * device addition but the request queue is still stopped by ++ * our earlier block call. We need to perform a block again ++ * to get the device to SDEV_BLOCK and then to SDEV_RUNNING */ ++ ++ sdev_printk(KERN_WARNING, sdev, ++ "device_unblock failed with return(%d) for handle(0x%04x) " ++ "performing a block followed by an unblock\n", ++ sas_device_priv_data->sas_target->handle, r); ++ sas_device_priv_data->block = 1; ++ r = scsi_internal_device_block(sdev); ++ if (r) ++ sdev_printk(KERN_WARNING, sdev, "retried device_block " ++ "failed with return(%d) for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle, r); ++ ++ sas_device_priv_data->block = 0; ++ r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); ++ if (r) ++ sdev_printk(KERN_WARNING, sdev, "retried device_unblock" ++ " failed with return(%d) for handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle, r); ++ } ++} ++ ++/** ++ * _scsih_ublock_io_all_device - unblock every device ++ * @ioc: per adapter object ++ * ++ * change the device state from block to running ++ */ ++static void ++_scsih_ublock_io_all_device(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (!sas_device_priv_data->block) ++ continue; ++ ++ dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, ++ "device_running, handle(0x%04x)\n", ++ sas_device_priv_data->sas_target->handle)); ++ _scsih_internal_device_unblock(sdev, sas_device_priv_data); ++ } ++} ++ ++ ++/** ++ * _scsih_ublock_io_device - prepare device to be deleted ++ * @ioc: per adapter object ++ * @sas_addr: sas address ++ * ++ * unblock then put device in offline state ++ */ ++static void ++_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->sas_address ++ != sas_address) ++ continue; ++ if (sas_device_priv_data->block) ++ _scsih_internal_device_unblock(sdev, ++ sas_device_priv_data); ++ } ++} ++ ++/** ++ * _scsih_block_io_all_device - set the device state to SDEV_BLOCK ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During device pull we need to appropiately set the sdev state. ++ */ ++static void ++_scsih_block_io_all_device(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->block) ++ continue; ++ if (sas_device_priv_data->ignore_delay_remove) { ++ sdev_printk(KERN_INFO, sdev, ++ "%s skip device_block for SES handle(0x%04x)\n", ++ __func__, sas_device_priv_data->sas_target->handle); ++ continue; ++ } ++ _scsih_internal_device_block(sdev, sas_device_priv_data); ++ } ++} ++ ++/** ++ * _scsih_block_io_device - set the device state to SDEV_BLOCK ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * During device pull we need to appropiately set the sdev state. ++ */ ++static void ++_scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ struct _sas_device *sas_device; ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (!sas_device) ++ return; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data) ++ continue; ++ if (sas_device_priv_data->sas_target->handle != handle) ++ continue; ++ if (sas_device_priv_data->block) ++ continue; ++ if (sas_device->pend_sas_rphy_add) ++ continue; ++ if (sas_device_priv_data->ignore_delay_remove) { ++ sdev_printk(KERN_INFO, sdev, ++ "%s skip device_block for SES handle(0x%04x)\n", ++ __func__, sas_device_priv_data->sas_target->handle); ++ continue; ++ } ++ _scsih_internal_device_block(sdev, sas_device_priv_data); ++ } ++ ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_block_io_to_children_attached_to_ex ++ * @ioc: per adapter object ++ * @sas_expander: the sas_device object ++ * ++ * This routine set sdev state to SDEV_BLOCK for all devices ++ * attached to this expander. This function called when expander is ++ * pulled. ++ */ ++static void ++_scsih_block_io_to_children_attached_to_ex(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander) ++{ ++ struct _sas_port *mpt2sas_port; ++ struct _sas_device *sas_device; ++ struct _sas_node *expander_sibling; ++ unsigned long flags; ++ ++ if (!sas_expander) ++ return; ++ ++ list_for_each_entry(mpt2sas_port, ++ &sas_expander->sas_port_list, port_list) { ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_END_DEVICE) { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ if (sas_device) { ++ set_bit(sas_device->handle, ++ ioc->blocking_handles); ++ sas_device_put(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ } ++ } ++ ++ list_for_each_entry(mpt2sas_port, ++ &sas_expander->sas_port_list, port_list) { ++ ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_EDGE_EXPANDER_DEVICE || ++ mpt2sas_port->remote_identify.device_type == ++ SAS_FANOUT_EXPANDER_DEVICE) { ++ expander_sibling = ++ mpt2sas_scsih_expander_find_by_sas_address( ++ ioc, mpt2sas_port->remote_identify.sas_address); ++ _scsih_block_io_to_children_attached_to_ex(ioc, ++ expander_sibling); ++ } ++ } ++} ++ ++/** ++ * _scsih_block_io_to_children_attached_directly ++ * @ioc: per adapter object ++ * @event_data: topology change event data ++ * ++ * This routine set sdev state to SDEV_BLOCK for all devices ++ * direct attached during device pull. ++ */ ++static void ++_scsih_block_io_to_children_attached_directly(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasTopologyChangeList_t *event_data) ++{ ++ int i; ++ u16 handle; ++ u16 reason_code; ++ ++ for (i = 0; i < event_data->NumEntries; i++) { ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING) ++ _scsih_block_io_device(ioc, handle); ++ } ++} ++ ++/** ++ * _scsih_tm_tr_send - send task management request ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt time. ++ * ++ * This code is to initiate the device removal handshake protocol ++ * with controller firmware. This function will issue target reset ++ * using high priority request queue. It will send a sas iounit ++ * control request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. ++ * ++ * This is designed to send muliple task management request at the same ++ * time to the fifo. If the fifo is full, we will append the request, ++ * and process it in a future completion. ++ */ ++static void ++_scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ Mpi2SCSITaskManagementRequest_t *mpi_request; ++ u16 smid; ++ struct _sas_device *sas_device = NULL; ++ struct MPT3SAS_TARGET *sas_target_priv_data = NULL; ++ u64 sas_address = 0; ++ unsigned long flags; ++ struct _tr_list *delayed_tr; ++ u32 ioc_state; ++ ++ if (ioc->remove_host) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host has been removed: handle(0x%04x)\n", ++ __func__, ioc->name, handle)); ++ return; ++ } else if (ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host in pci error recovery: handle(0x%04x)\n", ++ __func__, ioc->name, ++ handle)); ++ return; ++ } ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host is not operational: handle(0x%04x)\n", ++ __func__, ioc->name, ++ handle)); ++ return; ++ } ++ ++ /* if PD, then return */ ++ if (test_bit(handle, ioc->pd_handles)) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device && sas_device->starget && ++ sas_device->starget->hostdata) { ++ sas_target_priv_data = sas_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ sas_address = sas_device->sas_address; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (sas_target_priv_data) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, handle, ++ (unsigned long long)sas_address)); ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag:enclosure logical id(0x%016llx)," ++ " slot(%d)\n", ioc->name, (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot)); ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag: enclosure level(0x%04x)," ++ " connector name( %s)\n", ioc->name, ++ sas_device->enclosure_level, ++ sas_device->connector_name)); ++ _scsih_ublock_io_device(ioc, sas_address); ++ sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; ++ } ++ ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); ++ if (!smid) { ++ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); ++ if (!delayed_tr) ++ goto out; ++ INIT_LIST_HEAD(&delayed_tr->list); ++ delayed_tr->handle = handle; ++ list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:tr:handle(0x%04x), (open)\n", ++ ioc->name, handle)); ++ goto out; ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, handle, smid, ++ ioc->tm_tr_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, 0); ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); ++ ++out: ++ if (sas_device) ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_tm_tr_complete - ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt time. ++ * ++ * This is the target reset completion routine. ++ * This code is part of the code to initiate the device removal ++ * handshake protocol with controller firmware. ++ * It will send a sas iounit control request (MPI2_SAS_OP_REMOVE_DEVICE) ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ u16 handle; ++ Mpi2SCSITaskManagementRequest_t *mpi_request_tm; ++ Mpi2SCSITaskManagementReply_t *mpi_reply = ++ mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ Mpi2SasIoUnitControlRequest_t *mpi_request; ++ u16 smid_sas_ctrl; ++ u32 ioc_state; ++ struct _sc_list *delayed_sc; ++ ++ if (ioc->remove_host) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host has been removed\n", __func__, ioc->name)); ++ return 1; ++ } else if (ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host in pci error recovery\n", __func__, ++ ioc->name)); ++ return 1; ++ } ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host is not operational\n", __func__, ioc->name)); ++ return 1; ++ } ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); ++ handle = le16_to_cpu(mpi_request_tm->DevHandle); ++ if (handle != le16_to_cpu(mpi_reply->DevHandle)) { ++ dewtprintk(ioc, pr_err(MPT3SAS_FMT ++ "spurious interrupt: handle(0x%04x:0x%04x), smid(%d)!!!\n", ++ ioc->name, handle, ++ le16_to_cpu(mpi_reply->DevHandle), smid)); ++ return 0; ++ } ++ ++ mpt2sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), " ++ "loginfo(0x%08x), completed(%d)\n", ioc->name, ++ handle, smid, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo), ++ le32_to_cpu(mpi_reply->TerminationCount))); ++ ++ smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); ++ if (!smid_sas_ctrl) { ++ delayed_sc = kzalloc(sizeof(*delayed_sc), GFP_ATOMIC); ++ if (!delayed_sc) ++ return _scsih_check_for_pending_tm(ioc, smid); ++ INIT_LIST_HEAD(&delayed_sc->list); ++ delayed_sc->handle = mpi_request_tm->DevHandle; ++ list_add_tail(&delayed_sc->list, &ioc->delayed_sc_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:sc:handle(0x%04x), (open)\n", ++ ioc->name, handle)); ++ return _scsih_check_for_pending_tm(ioc, smid); ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, handle, smid_sas_ctrl, ++ ioc->tm_sas_control_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); ++ memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; ++ mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; ++ mpi_request->DevHandle = mpi_request_tm->DevHandle; ++ mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); ++ ++ return _scsih_check_for_pending_tm(ioc, smid); ++} ++ ++ ++/** ++ * _scsih_sas_control_complete - completion routine ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt time. ++ * ++ * This is the sas iounit control completion routine. ++ * This code is part of the code to initiate the device removal ++ * handshake protocol with controller firmware. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_sas_control_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u8 msix_index, u32 reply) ++{ ++ Mpi2SasIoUnitControlReply_t *mpi_reply = ++ mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ ++ if (likely(mpi_reply)) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "sc_complete:handle(0x%04x), (open) " ++ "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid, ++ le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo))); ++ } else { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ } ++ return mpt2sas_check_for_pending_internal_cmds(ioc, smid); ++} ++ ++/** ++ * _scsih_tm_tr_volume_send - send target reset request for volumes ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt time. ++ * ++ * This is designed to send muliple task management request at the same ++ * time to the fifo. If the fifo is full, we will append the request, ++ * and process it in a future completion. ++ */ ++static void ++_scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ Mpi2SCSITaskManagementRequest_t *mpi_request; ++ u16 smid; ++ struct _tr_list *delayed_tr; ++ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host reset in progress!\n", ++ __func__, ioc->name)); ++ return; ++ } ++ ++ smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx); ++ if (!smid) { ++ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); ++ if (!delayed_tr) ++ return; ++ INIT_LIST_HEAD(&delayed_tr->list); ++ delayed_tr->handle = handle; ++ list_add_tail(&delayed_tr->list, &ioc->delayed_tr_volume_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:tr:handle(0x%04x), (open)\n", ++ ioc->name, handle)); ++ return; ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, handle, smid, ++ ioc->tm_tr_volume_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; ++ mpt2sas_base_put_smid_hi_priority(ioc, smid, 0); ++} ++ ++/** ++ * _scsih_tm_volume_tr_complete - target reset completion ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt time. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_tm_volume_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u8 msix_index, u32 reply) ++{ ++ u16 handle; ++ Mpi2SCSITaskManagementRequest_t *mpi_request_tm; ++ Mpi2SCSITaskManagementReply_t *mpi_reply = ++ mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ ++ if (ioc->shost_recovery || ioc->remove_host || ++ ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host reset in progress!\n", ++ __func__, ioc->name)); ++ return 1; ++ } ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ ++ mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); ++ handle = le16_to_cpu(mpi_request_tm->DevHandle); ++ if (handle != le16_to_cpu(mpi_reply->DevHandle)) { ++ dewtprintk(ioc, pr_err(MPT3SAS_FMT ++ "spurious interrupt: handle(0x%04x:0x%04x), smid(%d)!!!\n", ++ ioc->name, handle, ++ le16_to_cpu(mpi_reply->DevHandle), smid)); ++ return 0; ++ } ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), " ++ "loginfo(0x%08x), completed(%d)\n", ioc->name, ++ handle, smid, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo), ++ le32_to_cpu(mpi_reply->TerminationCount))); ++ ++ return _scsih_check_for_pending_tm(ioc, smid); ++} ++ ++/** ++ * _scsih_issue_delayed_event_ack_mpt2sas - issue delayed Event ACK messages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @event: Event ID ++ * @event_context: used to track events uniquely ++ * ++ * Context - processed in interrupt context. ++ */ ++void ++_scsih_issue_delayed_event_ack_mpt2sas(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event, ++ u32 event_context) ++{ ++ Mpi2EventAckRequest_t *ack_request; ++ int i = smid - ioc->internal_smid; ++ unsigned long flags; ++ ++ /* Without releasing the smid just update the ++ * call back index and reuse the same smid for ++ * processing this delayed request ++ */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ ioc->internal_lookup[i].cb_idx = ioc->base_cb_idx; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "EVENT ACK: event(0x%04x), smid(%d), cb(%d)\n", ++ ioc->name, le16_to_cpu(event), smid, ++ ioc->base_cb_idx)); ++ ack_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(ack_request, 0, sizeof(Mpi2EventAckRequest_t)); ++ ack_request->Function = MPI2_FUNCTION_EVENT_ACK; ++ ack_request->Event = event; ++ ack_request->EventContext = event_context; ++ ack_request->VF_ID = 0; /* TODO */ ++ ack_request->VP_ID = 0; ++ mpt2sas_base_put_smid_default(ioc, smid); ++} ++ ++/** ++ * _scsih_issue_delayed_sas_io_unit_ctrl_mpt2sas - issue delayed ++ * sas_io_unit_ctrl messages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle ++ * ++ * Context - processed in interrupt context. ++ */ ++void ++_scsih_issue_delayed_sas_io_unit_ctrl_mpt2sas(struct MPT3SAS_ADAPTER *ioc, ++ u16 smid, u16 handle) ++ { ++ Mpi2SasIoUnitControlRequest_t *mpi_request; ++ u32 ioc_state; ++ int i = smid - ioc->internal_smid; ++ unsigned long flags; ++ ++ if (ioc->remove_host) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host has been removed\n", ++ __func__, ioc->name)); ++ return; ++ } else if (ioc->pci_error_recovery) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host in pci error recovery\n", ++ __func__, ioc->name)); ++ return; ++ } ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: host is not operational\n", ++ __func__, ioc->name)); ++ return; ++ } ++ ++ /* Without releasing the smid just update the ++ * call back index and reuse the same smid for ++ * processing this delayed request ++ */ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ ioc->internal_lookup[i].cb_idx = ioc->tm_sas_control_cb_idx; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "sc_send:handle(0x%04x), (open), smid(%d), cb(%d)\n", ++ ioc->name, le16_to_cpu(handle), smid, ++ ioc->tm_sas_control_cb_idx)); ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; ++ mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; ++ mpi_request->DevHandle = handle; ++ mpt2sas_base_put_smid_default(ioc, smid); ++} ++ ++/** ++ * _scsih_check_for_pending_internal_cmds - check for pending internal messages ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Context: Executed in interrupt context ++ * ++ * This will check delayed internal messages list, and process the ++ * next request. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ struct _sc_list *delayed_sc; ++ struct _event_ack_list *delayed_event_ack; ++ ++ if (!list_empty(&ioc->delayed_event_ack_list)) { ++ delayed_event_ack = list_entry(ioc->delayed_event_ack_list.next, ++ struct _event_ack_list, list); ++ _scsih_issue_delayed_event_ack_mpt2sas(ioc, smid, ++ delayed_event_ack->Event, delayed_event_ack->EventContext); ++ list_del(&delayed_event_ack->list); ++ kfree(delayed_event_ack); ++ return 0; ++ } ++ ++ if (!list_empty(&ioc->delayed_sc_list)) { ++ delayed_sc = list_entry(ioc->delayed_sc_list.next, ++ struct _sc_list, list); ++ _scsih_issue_delayed_sas_io_unit_ctrl_mpt2sas(ioc, smid, ++ delayed_sc->handle); ++ list_del(&delayed_sc->list); ++ kfree(delayed_sc); ++ return 0; ++ } ++ return 1; ++} ++ ++/** ++ * _scsih_check_for_pending_tm - check for pending task management ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * This will check delayed target reset list, and feed the ++ * next reqeust. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ struct _tr_list *delayed_tr; ++ ++ if (!list_empty(&ioc->delayed_tr_volume_list)) { ++ delayed_tr = list_entry(ioc->delayed_tr_volume_list.next, ++ struct _tr_list, list); ++ mpt2sas_base_free_smid(ioc, smid); ++ _scsih_tm_tr_volume_send(ioc, delayed_tr->handle); ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ return 0; ++ } ++ ++ if (!list_empty(&ioc->delayed_tr_list)) { ++ delayed_tr = list_entry(ioc->delayed_tr_list.next, ++ struct _tr_list, list); ++ mpt2sas_base_free_smid(ioc, smid); ++ _scsih_tm_tr_send(ioc, delayed_tr->handle); ++ list_del(&delayed_tr->list); ++ kfree(delayed_tr); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/** ++ * _scsih_check_topo_delete_events - sanity check on topo events ++ * @ioc: per adapter object ++ * @event_data: the event data payload ++ * ++ * This routine added to better handle cable breaker. ++ * ++ * This handles the case where driver receives multiple expander ++ * add and delete events in a single shot. When there is a delete event ++ * the routine will void any pending add events waiting in the event queue. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_check_topo_delete_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasTopologyChangeList_t *event_data) ++{ ++ struct fw_event_work *fw_event; ++ Mpi2EventDataSasTopologyChangeList_t *local_event_data; ++ u16 expander_handle; ++ struct _sas_node *sas_expander; ++ unsigned long flags; ++ int i, reason_code; ++ u16 handle; ++ ++ for (i = 0 ; i < event_data->NumEntries; i++) { ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING) ++ _scsih_tm_tr_send(ioc, handle); ++ } ++ ++ expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); ++ if (expander_handle < ioc->sas_hba.num_phys) { ++ _scsih_block_io_to_children_attached_directly(ioc, event_data); ++ return; ++ } ++ if (event_data->ExpStatus == ++ MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING) { ++ /* put expander attached devices into blocking state */ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, ++ expander_handle); ++ _scsih_block_io_to_children_attached_to_ex(ioc, sas_expander); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ do { ++ handle = find_first_bit(ioc->blocking_handles, ++ ioc->facts.MaxDevHandle); ++ if (handle < ioc->facts.MaxDevHandle) ++ _scsih_block_io_device(ioc, handle); ++ } while (test_and_clear_bit(handle, ioc->blocking_handles)); ++ } else if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_RESPONDING) ++ _scsih_block_io_to_children_attached_directly(ioc, event_data); ++ ++ if (event_data->ExpStatus != MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING) ++ return; ++ ++ /* mark ignore flag for pending events */ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ list_for_each_entry(fw_event, &ioc->fw_event_list, list) { ++ if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST || ++ fw_event->ignore) ++ continue; ++ local_event_data = (Mpi2EventDataSasTopologyChangeList_t *) ++ fw_event->event_data; ++ if (local_event_data->ExpStatus == ++ MPI2_EVENT_SAS_TOPO_ES_ADDED || ++ local_event_data->ExpStatus == ++ MPI2_EVENT_SAS_TOPO_ES_RESPONDING) { ++ if (le16_to_cpu(local_event_data->ExpanderDevHandle) == ++ expander_handle) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting ignoring flag\n", ioc->name)); ++ fw_event->ignore = 1; ++ } ++ } ++ } ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++} ++ ++/** ++ * _scsih_set_volume_delete_flag - setting volume delete flag ++ * @ioc: per adapter object ++ * @handle: device handle ++ * ++ * This returns nothing. ++ */ ++static void ++_scsih_set_volume_delete_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _raid_device *raid_device; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device && raid_device->starget && ++ raid_device->starget->hostdata) { ++ sas_target_priv_data = ++ raid_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "setting delete flag: handle(0x%04x), " ++ "wwid(0x%016llx)\n", ioc->name, handle, ++ (unsigned long long) raid_device->wwid)); ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * _scsih_set_volume_handle_for_tr - set handle for target reset to volume ++ * @handle: input handle ++ * @a: handle for volume a ++ * @b: handle for volume b ++ * ++ * IR firmware only supports two raid volumes. The purpose of this ++ * routine is to set the volume handle in either a or b. When the given ++ * input handle is non-zero, or when a and b have not been set before. ++ */ ++static void ++_scsih_set_volume_handle_for_tr(u16 handle, u16 *a, u16 *b) ++{ ++ if (!handle || handle == *a || handle == *b) ++ return; ++ if (!*a) ++ *a = handle; ++ else if (!*b) ++ *b = handle; ++} ++ ++/** ++ * _scsih_check_ir_config_unhide_events - check for UNHIDE events ++ * @ioc: per adapter object ++ * @event_data: the event data payload ++ * Context: interrupt time. ++ * ++ * This routine will send target reset to volume, followed by target ++ * resets to the PDs. This is called when a PD has been removed, or ++ * volume has been deleted or removed. When the target reset is sent ++ * to volume, the PD target resets need to be queued to start upon ++ * completion of the volume target reset. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrConfigChangeList_t *event_data) ++{ ++ Mpi2EventIrConfigElement_t *element; ++ int i; ++ u16 handle, volume_handle, a, b; ++ struct _tr_list *delayed_tr; ++ ++ a = 0; ++ b = 0; ++ ++ if (ioc->is_warpdrive) ++ return; ++ ++ /* Volume Resets for Deleted or Removed */ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ++ continue; ++ if (element->ReasonCode == ++ MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED || ++ element->ReasonCode == ++ MPI2_EVENT_IR_CHANGE_RC_REMOVED) { ++ volume_handle = le16_to_cpu(element->VolDevHandle); ++ _scsih_set_volume_delete_flag(ioc, volume_handle); ++ _scsih_set_volume_handle_for_tr(volume_handle, &a, &b); ++ } ++ } ++ ++ /* Volume Resets for UNHIDE events */ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ++ continue; ++ if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_UNHIDE) { ++ volume_handle = le16_to_cpu(element->VolDevHandle); ++ _scsih_set_volume_handle_for_tr(volume_handle, &a, &b); ++ } ++ } ++ ++ if (a) ++ _scsih_tm_tr_volume_send(ioc, a); ++ if (b) ++ _scsih_tm_tr_volume_send(ioc, b); ++ ++ /* PD target resets */ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_UNHIDE) ++ continue; ++ handle = le16_to_cpu(element->PhysDiskDevHandle); ++ volume_handle = le16_to_cpu(element->VolDevHandle); ++ clear_bit(handle, ioc->pd_handles); ++ if (!volume_handle) ++ _scsih_tm_tr_send(ioc, handle); ++ else if (volume_handle == a || volume_handle == b) { ++ delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); ++ BUG_ON(!delayed_tr); ++ INIT_LIST_HEAD(&delayed_tr->list); ++ delayed_tr->handle = handle; ++ list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "DELAYED:tr:handle(0x%04x), (open)\n", ioc->name, ++ handle)); ++ } else ++ _scsih_tm_tr_send(ioc, handle); ++ } ++} ++ ++ ++/** ++ * _scsih_check_volume_delete_events - set delete flag for volumes ++ * @ioc: per adapter object ++ * @event_data: the event data payload ++ * Context: interrupt time. ++ * ++ * This will handle the case when the cable connected to entire volume is ++ * pulled. We will take care of setting the deleted flag so normal IO will ++ * not be sent. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_check_volume_delete_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrVolume_t *event_data) ++{ ++ u32 state; ++ ++ if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) ++ return; ++ state = le32_to_cpu(event_data->NewValue); ++ if (state == MPI2_RAID_VOL_STATE_MISSING || state == ++ MPI2_RAID_VOL_STATE_FAILED) ++ _scsih_set_volume_delete_flag(ioc, ++ le16_to_cpu(event_data->VolDevHandle)); ++} ++ ++/** ++ * _scsih_temp_threshold_events - display temperature threshold exceeded events ++ * @ioc: per adapter object ++ * @event_data: the temp threshold event data ++ * Context: interrupt time. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataTemperature_t *event_data) ++{ ++ if (ioc->temp_sensors_count >= event_data->SensorNum) { ++ pr_err(MPT3SAS_FMT "Temperature Threshold flags %s%s%s%s" ++ " exceeded for Sensor: %d !!!\n", ioc->name, ++ ((le16_to_cpu(event_data->Status) & 0x1) == 1) ? "0 " : " ", ++ ((le16_to_cpu(event_data->Status) & 0x2) == 2) ? "1 " : " ", ++ ((le16_to_cpu(event_data->Status) & 0x4) == 4) ? "2 " : " ", ++ ((le16_to_cpu(event_data->Status) & 0x8) == 8) ? "3 " : " ", ++ event_data->SensorNum); ++ pr_err(MPT3SAS_FMT "Current Temp In Celsius: %d\n", ++ ioc->name, event_data->CurrentTemperature); ++ } ++} ++ ++/** ++ * _scsih_flush_running_cmds - completing outstanding commands. ++ * @ioc: per adapter object ++ * ++ * The flushing out of all pending scmd commands following host reset, ++ * where all IO is dropped to the floor. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct scsi_cmnd *scmd; ++ u16 smid; ++ u16 count = 0; ++ ++ for (smid = 1; smid <= ioc->scsiio_depth; smid++) { ++ scmd = _scsih_scsi_lookup_get_clear(ioc, smid); ++ if (!scmd) ++ continue; ++ count++; ++ mpt2sas_base_free_smid(ioc, smid); ++ scsi_dma_unmap(scmd); ++ if (ioc->pci_error_recovery) ++ scmd->result = DID_NO_CONNECT << 16; ++ else ++ scmd->result = DID_RESET << 16; ++ scmd->scsi_done(scmd); ++ } ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT "completing %d cmds\n", ++ ioc->name, count)); ++} ++ ++/** ++ * _scsih_setup_eedp - setup MPI request for EEDP transfer ++ * @ioc: per adapter object ++ * @scmd: pointer to scsi command object ++ * @mpi_request: pointer to the SCSI_IO reqest message frame ++ * ++ * Supporting protection 1 and 3. ++ * ++ * Returns nothing ++ */ ++static void ++_scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ Mpi2SCSIIORequest_t *mpi_request) ++{ ++ u16 eedp_flags; ++ unsigned char prot_op = scsi_get_prot_op(scmd); ++ unsigned char prot_type = scsi_get_prot_type(scmd); ++ Mpi25SCSIIORequest_t *mpi_request_3v = ++ (Mpi25SCSIIORequest_t *)mpi_request; ++ ++ if (prot_type == SCSI_PROT_DIF_TYPE0 || prot_op == SCSI_PROT_NORMAL) ++ return; ++ ++ if (prot_op == SCSI_PROT_READ_STRIP) ++ eedp_flags = MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP; ++ else if (prot_op == SCSI_PROT_WRITE_INSERT) ++ eedp_flags = MPI2_SCSIIO_EEDPFLAGS_INSERT_OP; ++ else ++ return; ++ ++ switch (prot_type) { ++ case SCSI_PROT_DIF_TYPE1: ++ case SCSI_PROT_DIF_TYPE2: ++ ++ /* ++ * enable ref/guard checking ++ * auto increment ref tag ++ */ ++ eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | ++ MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | ++ MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; ++ mpi_request->CDB.EEDP32.PrimaryReferenceTag = ++ cpu_to_be32(scsi_get_lba(scmd)); ++ break; ++ ++ case SCSI_PROT_DIF_TYPE3: ++ ++ /* ++ * enable guard checking ++ */ ++ eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; ++ ++ break; ++ } ++ ++ mpi_request_3v->EEDPBlockSize = ++ cpu_to_le16(scmd->device->sector_size); ++ mpi_request->EEDPFlags = cpu_to_le16(eedp_flags); ++} ++ ++/** ++ * _scsih_eedp_error_handling - return sense code for EEDP errors ++ * @scmd: pointer to scsi command object ++ * @ioc_status: ioc status ++ * ++ * Returns nothing ++ */ ++static void ++_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) ++{ ++ u8 ascq; ++ ++ switch (ioc_status) { ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ ascq = 0x01; ++ break; ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ ascq = 0x02; ++ break; ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ ascq = 0x03; ++ break; ++ default: ++ ascq = 0x00; ++ break; ++ } ++ scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x10, ++ ascq); ++ scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) | ++ SAM_STAT_CHECK_CONDITION; ++} ++ ++ ++ ++/** ++ * scsih_qcmd_mpt2sas - main scsi request entry point ++ * @scmd: pointer to scsi command object ++ * @done: function pointer to be invoked on completion ++ * ++ * The callback index is set inside `ioc->scsi_io_cb_idx`. ++ * ++ * Returns 0 on success. If there's a failure, return either: ++ * SCSI_MLQUEUE_DEVICE_BUSY if the device queue is full, or ++ * SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full ++ */ ++int ++scsih_qcmd_mpt2sas(struct Scsi_Host *shost, struct scsi_cmnd *scmd) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct _raid_device *raid_device; ++ Mpi2SCSIIORequest_t *mpi_request; ++ u32 mpi_control; ++ u16 smid; ++ u16 handle; ++ ++ if (ioc->logging_level & MPT_DEBUG_SCSI) ++ scsi_print_command(scmd); ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ ++ if (ioc->pci_error_recovery || ioc->remove_host) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ ++ sas_target_priv_data = sas_device_priv_data->sas_target; ++ ++ /* invalid device handle */ ++ handle = sas_target_priv_data->handle; ++ if (handle == MPT3SAS_INVALID_DEVICE_HANDLE) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ ++ ++ /* host recovery or link resets sent via IOCTLs */ ++ if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ ++ /* device has been deleted */ ++ else if (sas_target_priv_data->deleted) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scmd->scsi_done(scmd); ++ return 0; ++ /* device busy with task managment */ ++ } else if (sas_target_priv_data->tm_busy || ++ sas_device_priv_data->block) ++ return SCSI_MLQUEUE_DEVICE_BUSY; ++ ++ if (scmd->sc_data_direction == DMA_FROM_DEVICE) ++ mpi_control = MPI2_SCSIIO_CONTROL_READ; ++ else if (scmd->sc_data_direction == DMA_TO_DEVICE) ++ mpi_control = MPI2_SCSIIO_CONTROL_WRITE; ++ else ++ mpi_control = MPI2_SCSIIO_CONTROL_NODATATRANSFER; ++ ++ /* set tags */ ++ if (!(sas_device_priv_data->flags & MPT_DEVICE_FLAGS_INIT)) { ++ if (scmd->device->tagged_supported) { ++ if (scmd->device->ordered_tags) ++ mpi_control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; ++ else ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; ++ } else ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; ++ } else ++ mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; ++ ++ /* Make sure Device is not raid volume. ++ * We do not expose raid functionality to upper layer for warpdrive. ++ */ ++ if (!ioc->is_warpdrive && !scsih_is_raid_mpt2sas(&scmd->device->sdev_gendev) ++ && sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) ++ mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; ++ ++ smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ goto out; ++ } ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t)); ++ _scsih_setup_eedp(ioc, scmd, mpi_request); ++ ++ if (scmd->cmd_len == 32) ++ mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT; ++ mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) ++ mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; ++ else ++ mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; ++ mpi_request->DevHandle = cpu_to_le16(handle); ++ mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); ++ mpi_request->Control = cpu_to_le32(mpi_control); ++ mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len); ++ mpi_request->MsgFlags = MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR; ++ mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; ++ mpi_request->SenseBufferLowAddress = ++ mpt2sas_base_get_sense_buffer_dma(ioc, smid); ++ mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; ++ int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *) ++ mpi_request->LUN); ++ memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); ++ ++ if (mpi_request->DataLength) { ++ if (ioc->build_sg_scmd(ioc, scmd, smid)) { ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ } else ++ ioc->build_zero_len_sge(ioc, &mpi_request->SGL); ++ ++ raid_device = sas_target_priv_data->raid_device; ++ if (raid_device && raid_device->direct_io_enabled) ++ mpt2sas_setup_direct_io(ioc, scmd, raid_device, mpi_request, ++ smid); ++ ++ if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) { ++ if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { ++ mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | ++ MPI25_SCSIIO_IOFLAGS_FAST_PATH); ++ mpt2sas_base_put_smid_fast_path(ioc, smid, handle); ++ } else ++ mpt2sas_base_put_smid_scsi_io(ioc, smid, ++ le16_to_cpu(mpi_request->DevHandle)); ++ } else ++ mpt2sas_base_put_smid_default(ioc, smid); ++ return 0; ++ ++ out: ++ return SCSI_MLQUEUE_HOST_BUSY; ++} ++ ++/** ++ * _scsih_normalize_sense - normalize descriptor and fixed format sense data ++ * @sense_buffer: sense data returned by target ++ * @data: normalized skey/asc/ascq ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_normalize_sense(char *sense_buffer, struct sense_info *data) ++{ ++ if ((sense_buffer[0] & 0x7F) >= 0x72) { ++ /* descriptor format */ ++ data->skey = sense_buffer[1] & 0x0F; ++ data->asc = sense_buffer[2]; ++ data->ascq = sense_buffer[3]; ++ } else { ++ /* fixed format */ ++ data->skey = sense_buffer[2] & 0x0F; ++ data->asc = sense_buffer[12]; ++ data->ascq = sense_buffer[13]; ++ } ++} ++ ++/** ++ * _scsih_scsi_ioc_info - translated non-succesfull SCSI_IO request ++ * @ioc: per adapter object ++ * @scmd: pointer to scsi command object ++ * @mpi_reply: reply mf payload returned from firmware ++ * ++ * scsi_status - SCSI Status code returned from target device ++ * scsi_state - state info associated with SCSI_IO determined by ioc ++ * ioc_status - ioc supplied status info ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ Mpi2SCSIIOReply_t *mpi_reply, u16 smid) ++{ ++ u32 response_info; ++ u8 *response_bytes; ++ u16 ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ u8 scsi_state = mpi_reply->SCSIState; ++ u8 scsi_status = mpi_reply->SCSIStatus; ++ char *desc_ioc_state = NULL; ++ char *desc_scsi_status = NULL; ++ char *desc_scsi_state = ioc->tmp_string; ++ u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); ++ struct _sas_device *sas_device = NULL; ++ struct scsi_target *starget = scmd->device->sdev_target; ++ struct MPT3SAS_TARGET *priv_target = starget->hostdata; ++ char *device_str = NULL; ++ ++ if (!priv_target) ++ return; ++ if (ioc->hide_ir_msg) ++ device_str = "WarpDrive"; ++ else ++ device_str = "volume"; ++ ++ if (log_info == 0x31170000) ++ return; ++ ++ switch (ioc_status) { ++ case MPI2_IOCSTATUS_SUCCESS: ++ desc_ioc_state = "success"; ++ break; ++ case MPI2_IOCSTATUS_INVALID_FUNCTION: ++ desc_ioc_state = "invalid function"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: ++ desc_ioc_state = "scsi recovered error"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE: ++ desc_ioc_state = "scsi invalid dev handle"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: ++ desc_ioc_state = "scsi device not there"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: ++ desc_ioc_state = "scsi data overrun"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: ++ desc_ioc_state = "scsi data underrun"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: ++ desc_ioc_state = "scsi io data error"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: ++ desc_ioc_state = "scsi protocol error"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: ++ desc_ioc_state = "scsi task terminated"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: ++ desc_ioc_state = "scsi residual mismatch"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED: ++ desc_ioc_state = "scsi task mgmt failed"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: ++ desc_ioc_state = "scsi ioc terminated"; ++ break; ++ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: ++ desc_ioc_state = "scsi ext terminated"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ desc_ioc_state = "eedp guard error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ desc_ioc_state = "eedp ref tag error"; ++ break; ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ desc_ioc_state = "eedp app tag error"; ++ break; ++ case MPI2_IOCSTATUS_INSUFFICIENT_POWER: ++ desc_ioc_state = "insufficient power"; ++ break; ++ default: ++ desc_ioc_state = "unknown"; ++ break; ++ } ++ ++ switch (scsi_status) { ++ case MPI2_SCSI_STATUS_GOOD: ++ desc_scsi_status = "good"; ++ break; ++ case MPI2_SCSI_STATUS_CHECK_CONDITION: ++ desc_scsi_status = "check condition"; ++ break; ++ case MPI2_SCSI_STATUS_CONDITION_MET: ++ desc_scsi_status = "condition met"; ++ break; ++ case MPI2_SCSI_STATUS_BUSY: ++ desc_scsi_status = "busy"; ++ break; ++ case MPI2_SCSI_STATUS_INTERMEDIATE: ++ desc_scsi_status = "intermediate"; ++ break; ++ case MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET: ++ desc_scsi_status = "intermediate condmet"; ++ break; ++ case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: ++ desc_scsi_status = "reservation conflict"; ++ break; ++ case MPI2_SCSI_STATUS_COMMAND_TERMINATED: ++ desc_scsi_status = "command terminated"; ++ break; ++ case MPI2_SCSI_STATUS_TASK_SET_FULL: ++ desc_scsi_status = "task set full"; ++ break; ++ case MPI2_SCSI_STATUS_ACA_ACTIVE: ++ desc_scsi_status = "aca active"; ++ break; ++ case MPI2_SCSI_STATUS_TASK_ABORTED: ++ desc_scsi_status = "task aborted"; ++ break; ++ default: ++ desc_scsi_status = "unknown"; ++ break; ++ } ++ ++ desc_scsi_state[0] = '\0'; ++ if (!scsi_state) ++ desc_scsi_state = " "; ++ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) ++ strcat(desc_scsi_state, "response info "); ++ if (scsi_state & MPI2_SCSI_STATE_TERMINATED) ++ strcat(desc_scsi_state, "state terminated "); ++ if (scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) ++ strcat(desc_scsi_state, "no status "); ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_FAILED) ++ strcat(desc_scsi_state, "autosense failed "); ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) ++ strcat(desc_scsi_state, "autosense valid "); ++ ++ scsi_print_command(scmd); ++ ++ if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { ++ pr_warn(MPT3SAS_FMT "\t%s wwid(0x%016llx)\n", ioc->name, ++ device_str, (unsigned long long)priv_target->sas_address); ++ } else { ++ sas_device = mpt2sas_get_sdev_from_target(ioc, priv_target); ++ if (sas_device) { ++ pr_warn(MPT3SAS_FMT ++ "\tsas_address(0x%016llx), phy(%d)\n", ++ ioc->name, (unsigned long long) ++ sas_device->sas_address, sas_device->phy); ++ if (sas_device->enclosure_handle != 0) ++ pr_warn(MPT3SAS_FMT ++ "\tenclosure_logical_id(0x%016llx)," ++ "slot(%d)\n", ioc->name, ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0]) ++ pr_warn(MPT3SAS_FMT ++ "\tenclosure level(0x%04x)," ++ " connector name( %s)\n", ioc->name, ++ sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ sas_device_put(sas_device); ++ } ++ } ++ ++ pr_warn(MPT3SAS_FMT ++ "\thandle(0x%04x), ioc_status(%s)(0x%04x), smid(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->DevHandle), ++ desc_ioc_state, ioc_status, smid); ++ pr_warn(MPT3SAS_FMT ++ "\trequest_len(%d), underflow(%d), resid(%d)\n", ++ ioc->name, scsi_bufflen(scmd), scmd->underflow, ++ scsi_get_resid(scmd)); ++ pr_warn(MPT3SAS_FMT ++ "\ttag(%d), transfer_count(%d), sc->result(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->TaskTag), ++ le32_to_cpu(mpi_reply->TransferCount), scmd->result); ++ pr_warn(MPT3SAS_FMT ++ "\tscsi_status(%s)(0x%02x), scsi_state(%s)(0x%02x)\n", ++ ioc->name, desc_scsi_status, ++ scsi_status, desc_scsi_state, scsi_state); ++ ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { ++ struct sense_info data; ++ _scsih_normalize_sense(scmd->sense_buffer, &data); ++ pr_warn(MPT3SAS_FMT ++ "\t[sense_key,asc,ascq]: [0x%02x,0x%02x,0x%02x], count(%d)\n", ++ ioc->name, data.skey, ++ data.asc, data.ascq, le32_to_cpu(mpi_reply->SenseCount)); ++ } ++ ++ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { ++ response_info = le32_to_cpu(mpi_reply->ResponseInfo); ++ response_bytes = (u8 *)&response_info; ++ _scsih_response_code(ioc, response_bytes[0]); ++ } ++} ++ ++/** ++ * _scsih_turn_on_pfa_led - illuminate PFA LED ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: process ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ Mpi2SepReply_t mpi_reply; ++ Mpi2SepRequest_t mpi_request; ++ struct _sas_device *sas_device; ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (!sas_device) ++ return; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; ++ mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; ++ mpi_request.SlotStatus = ++ cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); ++ mpi_request.DevHandle = cpu_to_le16(handle); ++ mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS; ++ if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, ++ &mpi_request)) != 0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ sas_device->pfa_led_on = 1; ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo))); ++ goto out; ++ } ++out: ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_turn_off_pfa_led - turn off Fault LED ++ * @ioc: per adapter object ++ * @sas_device: sas device whose PFA LED has to turned off ++ * Context: process ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_turn_off_pfa_led(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ Mpi2SepReply_t mpi_reply; ++ Mpi2SepRequest_t mpi_request; ++ ++ memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; ++ mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS; ++ mpi_request.SlotStatus = 0; ++ mpi_request.Slot = cpu_to_le16(sas_device->slot); ++ mpi_request.DevHandle = 0; ++ mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle); ++ mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; ++ if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply, ++ &mpi_request)) != 0) { ++ printk(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { ++ dewtprintk(ioc, printk(MPT3SAS_FMT ++ "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo))); ++ return; ++ } ++} ++ ++/** ++ * _scsih_send_event_to_turn_on_pfa_led - fire delayed event ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct fw_event_work *fw_event; ++ ++ fw_event = alloc_fw_event_work(0); ++ if (!fw_event) ++ return; ++ fw_event->event = MPT3SAS_TURN_ON_PFA_LED; ++ fw_event->device_handle = handle; ++ fw_event->ioc = ioc; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * _scsih_smart_predicted_fault - process smart errors ++ * @ioc: per adapter object ++ * @handle: device handle ++ * Context: interrupt. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct scsi_target *starget; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ Mpi2EventNotificationReply_t *event_reply; ++ Mpi2EventDataSasDeviceStatusChange_t *event_data; ++ struct _sas_device *sas_device; ++ ssize_t sz; ++ unsigned long flags; ++ ++ /* only handle non-raid devices */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (!sas_device) ++ goto out_unlock; ++ ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ ++ if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) || ++ ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) ++ goto out_unlock; ++ ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, "predicted fault, " ++ "enclosure logical id(0x%016llx), slot(%d)\n", ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ starget_printk(KERN_WARNING, starget, "predicted fault, " ++ "enclosure level(0x%04x), connector name( %s)\n", ++ sas_device->enclosure_level, ++ sas_device->connector_name); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) ++ _scsih_send_event_to_turn_on_pfa_led(ioc, handle); ++ ++ /* insert into event log */ ++ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + ++ sizeof(Mpi2EventDataSasDeviceStatusChange_t); ++ event_reply = kzalloc(sz, GFP_KERNEL); ++ if (!event_reply) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; ++ event_reply->Event = ++ cpu_to_le16(MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE); ++ event_reply->MsgLength = sz/4; ++ event_reply->EventDataLength = ++ cpu_to_le16(sizeof(Mpi2EventDataSasDeviceStatusChange_t)/4); ++ event_data = (Mpi2EventDataSasDeviceStatusChange_t *) ++ event_reply->EventData; ++ event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA; ++ event_data->ASC = 0x5D; ++ event_data->DevHandle = cpu_to_le16(handle); ++ event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); ++ mpt2sas_ctl_add_to_event_log(ioc, event_reply); ++ kfree(event_reply); ++out: ++ if (sas_device) ++ sas_device_put(sas_device); ++ return; ++ ++out_unlock: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ goto out; ++} ++ ++/** ++ * _scsih_io_done - scsi request callback ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Callback handler when using _scsih_qcmd_mpt2sas. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ++{ ++ Mpi2SCSIIORequest_t *mpi_request; ++ Mpi2SCSIIOReply_t *mpi_reply; ++ struct scsi_cmnd *scmd; ++ u16 ioc_status; ++ u32 xfer_cnt; ++ u8 scsi_state; ++ u8 scsi_status; ++ u32 log_info; ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ u32 response_code = 0; ++ unsigned long flags; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ scmd = _scsih_scsi_lookup_get_clear(ioc, smid); ++ if (scmd == NULL) ++ return 1; ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ++ if (mpi_reply == NULL) { ++ scmd->result = DID_OK << 16; ++ goto out; ++ } ++ ++ sas_device_priv_data = scmd->device->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target || ++ sas_device_priv_data->sas_target->deleted) { ++ scmd->result = DID_NO_CONNECT << 16; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus); ++ ++ /* ++ * WARPDRIVE: If direct_io is set then it is directIO, ++ * the failed direct I/O should be redirected to volume ++ */ ++ if (mpt2sas_scsi_direct_io_get(ioc, smid) && ++ ((ioc_status & MPI2_IOCSTATUS_MASK) ++ != MPI2_IOCSTATUS_SCSI_TASK_TERMINATED)) { ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ ioc->scsi_lookup[smid - 1].scmd = scmd; ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ mpt2sas_scsi_direct_io_set(ioc, smid, 0); ++ memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); ++ mpi_request->DevHandle = ++ cpu_to_le16(sas_device_priv_data->sas_target->handle); ++ mpt2sas_base_put_smid_scsi_io(ioc, smid, ++ sas_device_priv_data->sas_target->handle); ++ return 0; ++ } ++ /* turning off TLR */ ++ scsi_state = mpi_reply->SCSIState; ++ if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) ++ response_code = ++ le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; ++ if (!sas_device_priv_data->tlr_snoop_check) { ++ sas_device_priv_data->tlr_snoop_check++; ++ if (!ioc->is_warpdrive && ++ !scsih_is_raid_mpt2sas(&scmd->device->sdev_gendev) && ++ sas_is_tlr_enabled(scmd->device) && ++ response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { ++ sas_disable_tlr(scmd->device); ++ sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); ++ } ++ } ++ ++ xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); ++ scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt); ++ if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) ++ log_info = le32_to_cpu(mpi_reply->IOCLogInfo); ++ else ++ log_info = 0; ++ ioc_status &= MPI2_IOCSTATUS_MASK; ++ scsi_status = mpi_reply->SCSIStatus; ++ ++ if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && ++ (scsi_status == MPI2_SCSI_STATUS_BUSY || ++ scsi_status == MPI2_SCSI_STATUS_RESERVATION_CONFLICT || ++ scsi_status == MPI2_SCSI_STATUS_TASK_SET_FULL)) { ++ ioc_status = MPI2_IOCSTATUS_SUCCESS; ++ } ++ ++ if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { ++ struct sense_info data; ++ const void *sense_data = mpt2sas_base_get_sense_buffer(ioc, ++ smid); ++ u32 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE, ++ le32_to_cpu(mpi_reply->SenseCount)); ++ memcpy(scmd->sense_buffer, sense_data, sz); ++ _scsih_normalize_sense(scmd->sense_buffer, &data); ++ /* failure prediction threshold exceeded */ ++ if (data.asc == 0x5D) ++ _scsih_smart_predicted_fault(ioc, ++ le16_to_cpu(mpi_reply->DevHandle)); ++ mpt2sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); ++ ++ if (!(ioc->logging_level & MPT_DEBUG_REPLY) && ++ ((scmd->sense_buffer[2] == UNIT_ATTENTION) || ++ (scmd->sense_buffer[2] == MEDIUM_ERROR) || ++ (scmd->sense_buffer[2] == HARDWARE_ERROR))) ++ _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid); ++ } ++ switch (ioc_status) { ++ case MPI2_IOCSTATUS_BUSY: ++ case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: ++ scmd->result = SAM_STAT_BUSY; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: ++ scmd->result = DID_NO_CONNECT << 16; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: ++ if (sas_device_priv_data->block) { ++ scmd->result = DID_TRANSPORT_DISRUPTED << 16; ++ goto out; ++ } ++ if (log_info == 0x31110630) { ++ if (scmd->retries > 2) { ++ scmd->result = DID_NO_CONNECT << 16; ++ scsi_device_set_state(scmd->device, ++ SDEV_OFFLINE); ++ } else { ++ scmd->result = DID_SOFT_ERROR << 16; ++ scmd->device->expecting_cc_ua = 1; ++ } ++ break; ++ } else if (log_info == VIRTUAL_IO_FAILED_RETRY) { ++ scmd->result = DID_RESET << 16; ++ break; ++ } ++ scmd->result = DID_SOFT_ERROR << 16; ++ break; ++ case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: ++ case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: ++ scmd->result = DID_RESET << 16; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: ++ if ((xfer_cnt == 0) || (scmd->underflow > xfer_cnt)) ++ scmd->result = DID_SOFT_ERROR << 16; ++ else ++ scmd->result = (DID_OK << 16) | scsi_status; ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: ++ scmd->result = (DID_OK << 16) | scsi_status; ++ ++ if ((scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID)) ++ break; ++ ++ if (xfer_cnt < scmd->underflow) { ++ if (scsi_status == SAM_STAT_BUSY) ++ scmd->result = SAM_STAT_BUSY; ++ else ++ scmd->result = DID_SOFT_ERROR << 16; ++ } else if (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | ++ MPI2_SCSI_STATE_NO_SCSI_STATUS)) ++ scmd->result = DID_SOFT_ERROR << 16; ++ else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) ++ scmd->result = DID_RESET << 16; ++ else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) { ++ mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID; ++ mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION; ++ scmd->result = (DRIVER_SENSE << 24) | ++ SAM_STAT_CHECK_CONDITION; ++ scmd->sense_buffer[0] = 0x70; ++ scmd->sense_buffer[2] = ILLEGAL_REQUEST; ++ scmd->sense_buffer[12] = 0x20; ++ scmd->sense_buffer[13] = 0; ++ } ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: ++ scsi_set_resid(scmd, 0); ++ case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR: ++ case MPI2_IOCSTATUS_SUCCESS: ++ scmd->result = (DID_OK << 16) | scsi_status; ++ if (response_code == ++ MPI2_SCSITASKMGMT_RSP_INVALID_FRAME || ++ (scsi_state & (MPI2_SCSI_STATE_AUTOSENSE_FAILED | ++ MPI2_SCSI_STATE_NO_SCSI_STATUS))) ++ scmd->result = DID_SOFT_ERROR << 16; ++ else if (scsi_state & MPI2_SCSI_STATE_TERMINATED) ++ scmd->result = DID_RESET << 16; ++ break; ++ ++ case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: ++ case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: ++ case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: ++ _scsih_eedp_error_handling(scmd, ioc_status); ++ break; ++ ++ case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: ++ case MPI2_IOCSTATUS_INVALID_FUNCTION: ++ case MPI2_IOCSTATUS_INVALID_SGL: ++ case MPI2_IOCSTATUS_INTERNAL_ERROR: ++ case MPI2_IOCSTATUS_INVALID_FIELD: ++ case MPI2_IOCSTATUS_INVALID_STATE: ++ case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: ++ case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED: ++ case MPI2_IOCSTATUS_INSUFFICIENT_POWER: ++ default: ++ scmd->result = DID_SOFT_ERROR << 16; ++ break; ++ ++ } ++ ++ if (scmd->result && (ioc->logging_level & MPT_DEBUG_REPLY)) ++ _scsih_scsi_ioc_info(ioc , scmd, mpi_reply, smid); ++ ++ out: ++ ++ scsi_dma_unmap(scmd); ++ ++ scmd->scsi_done(scmd); ++ return 1; ++} ++ ++/** ++ * _scsih_sas_host_refresh - refreshing sas host object contents ++ * @ioc: per adapter object ++ * Context: user ++ * ++ * During port enable, fw will send topology events for every device. Its ++ * possible that the handles may change from the previous setting, so this ++ * code keeping handles updating if changed. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u16 sz; ++ u16 ioc_status; ++ int i; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ u16 attached_handle; ++ u8 link_rate; ++ ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "updating handles for sas_host(0x%016llx)\n", ++ ioc->name, (unsigned long long)ioc->sas_hba.sas_address)); ++ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys ++ * sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz)) != 0) ++ goto out; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ goto out; ++ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { ++ link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4; ++ if (i == 0) ++ ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> ++ PhyData[0].ControllerDevHandle); ++ ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; ++ attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. ++ AttachedDevHandle); ++ if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) ++ link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; ++ mpt2sas_transport_update_links(ioc, ioc->sas_hba.sas_address, ++ attached_handle, i, link_rate); ++ } ++ out: ++ kfree(sas_iounit_pg0); ++} ++ ++/** ++ * _scsih_sas_host_add - create sas host object ++ * @ioc: per adapter object ++ * ++ * Creating host side data object, stored in ioc->sas_hba ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) ++{ ++ int i; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2SasPhyPage0_t phy_pg0; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2SasEnclosurePage0_t enclosure_pg0; ++ u16 ioc_status; ++ u16 sz; ++ u8 device_missing_delay; ++ ++ mpt2sas_config_get_number_hba_phys(ioc, &ioc->sas_hba.num_phys); ++ if (!ioc->sas_hba.num_phys) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ /* sas_iounit page 0 */ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ /* sas_iounit page 1 */ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ ioc->io_missing_delay = ++ sas_iounit_pg1->IODeviceMissingDelay; ++ device_missing_delay = ++ sas_iounit_pg1->ReportDeviceMissingDelay; ++ if (device_missing_delay & MPI2_SASIOUNIT1_REPORT_MISSING_UNIT_16) ++ ioc->device_missing_delay = (device_missing_delay & ++ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16; ++ else ++ ioc->device_missing_delay = device_missing_delay & ++ MPI2_SASIOUNIT1_REPORT_MISSING_TIMEOUT_MASK; ++ ++ ioc->sas_hba.parent_dev = &ioc->shost->shost_gendev; ++ ioc->sas_hba.phy = kcalloc(ioc->sas_hba.num_phys, ++ sizeof(struct _sas_phy), GFP_KERNEL); ++ if (!ioc->sas_hba.phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { ++ if ((mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, ++ i))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ++ if (i == 0) ++ ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> ++ PhyData[0].ControllerDevHandle); ++ ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; ++ ioc->sas_hba.phy[i].phy_id = i; ++ mpt2sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], ++ phy_pg0, ioc->sas_hba.parent_dev); ++ } ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ioc->sas_hba.handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out; ++ } ++ ioc->sas_hba.enclosure_handle = ++ le16_to_cpu(sas_device_pg0.EnclosureHandle); ++ ioc->sas_hba.sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ pr_info(MPT3SAS_FMT ++ "host_add: handle(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ++ ioc->name, ioc->sas_hba.handle, ++ (unsigned long long) ioc->sas_hba.sas_address, ++ ioc->sas_hba.num_phys) ; ++ ++ if (ioc->sas_hba.enclosure_handle) { ++ if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, ++ &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ++ ioc->sas_hba.enclosure_handle))) ++ ioc->sas_hba.enclosure_logical_id = ++ le64_to_cpu(enclosure_pg0.EnclosureLogicalID); ++ } ++ ++ out: ++ kfree(sas_iounit_pg1); ++ kfree(sas_iounit_pg0); ++} ++ ++/** ++ * _scsih_expander_add - creating expander object ++ * @ioc: per adapter object ++ * @handle: expander handle ++ * ++ * Creating expander object, stored in ioc->sas_expander_list. ++ * ++ * Return 0 for success, else error. ++ */ ++static int ++_scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _sas_node *sas_expander; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2ExpanderPage0_t expander_pg0; ++ Mpi2ExpanderPage1_t expander_pg1; ++ Mpi2SasEnclosurePage0_t enclosure_pg0; ++ u32 ioc_status; ++ u16 parent_handle; ++ u64 sas_address, sas_address_parent = 0; ++ int i; ++ unsigned long flags; ++ struct _sas_port *mpt2sas_port = NULL; ++ ++ int rc = 0; ++ ++ if (!handle) ++ return -1; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) ++ return -1; ++ ++ if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, ++ MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ /* handle out of order topology events */ ++ parent_handle = le16_to_cpu(expander_pg0.ParentDevHandle); ++ if (_scsih_get_sas_address(ioc, parent_handle, &sas_address_parent) ++ != 0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ if (sas_address_parent != ioc->sas_hba.sas_address) { ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address_parent); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (!sas_expander) { ++ rc = _scsih_expander_add(ioc, parent_handle); ++ if (rc != 0) ++ return rc; ++ } ++ } ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_address = le64_to_cpu(expander_pg0.SASAddress); ++ sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (sas_expander) ++ return 0; ++ ++ sas_expander = kzalloc(sizeof(struct _sas_node), ++ GFP_KERNEL); ++ if (!sas_expander) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ sas_expander->handle = handle; ++ sas_expander->num_phys = expander_pg0.NumPhys; ++ sas_expander->sas_address_parent = sas_address_parent; ++ sas_expander->sas_address = sas_address; ++ ++ pr_info(MPT3SAS_FMT "expander_add: handle(0x%04x)," \ ++ " parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", ioc->name, ++ handle, parent_handle, (unsigned long long) ++ sas_expander->sas_address, sas_expander->num_phys); ++ ++ if (!sas_expander->num_phys) ++ goto out_fail; ++ sas_expander->phy = kcalloc(sas_expander->num_phys, ++ sizeof(struct _sas_phy), GFP_KERNEL); ++ if (!sas_expander->phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ ++ INIT_LIST_HEAD(&sas_expander->sas_port_list); ++ mpt2sas_port = mpt2sas_transport_port_add(ioc, handle, ++ sas_address_parent); ++ if (!mpt2sas_port) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ sas_expander->parent_dev = &mpt2sas_port->rphy->dev; ++ ++ for (i = 0 ; i < sas_expander->num_phys ; i++) { ++ if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply, ++ &expander_pg1, i, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ sas_expander->phy[i].handle = handle; ++ sas_expander->phy[i].phy_id = i; ++ ++ if ((mpt2sas_transport_add_expander_phy(ioc, ++ &sas_expander->phy[i], expander_pg1, ++ sas_expander->parent_dev))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -1; ++ goto out_fail; ++ } ++ } ++ ++ if (sas_expander->enclosure_handle) { ++ if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, ++ &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ++ sas_expander->enclosure_handle))) ++ sas_expander->enclosure_logical_id = ++ le64_to_cpu(enclosure_pg0.EnclosureLogicalID); ++ } ++ ++ _scsih_expander_node_add(ioc, sas_expander); ++ return 0; ++ ++ out_fail: ++ ++ if (mpt2sas_port) ++ mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, ++ sas_address_parent); ++ kfree(sas_expander); ++ return rc; ++} ++ ++/** ++ * mpt2sas_expander_remove - removing expander object ++ * @ioc: per adapter object ++ * @sas_address: expander sas_address ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) ++{ ++ struct _sas_node *sas_expander; ++ unsigned long flags; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address); ++ if (sas_expander) ++ list_del(&sas_expander->list); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (sas_expander) ++ _scsih_expander_node_remove(ioc, sas_expander); ++} ++ ++/** ++ * _scsih_done - internal SCSI_IO callback handler. ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Callback handler when sending internal generated SCSI_IO. ++ * The callback index passed is `ioc->scsih_cb_idx` ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++static u8 ++_scsih_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (ioc->scsih_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->scsih_cmds.smid != smid) ++ return 1; ++ ioc->scsih_cmds.status |= MPT3_CMD_COMPLETE; ++ if (mpi_reply) { ++ memcpy(ioc->scsih_cmds.reply, mpi_reply, ++ mpi_reply->MsgLength*4); ++ ioc->scsih_cmds.status |= MPT3_CMD_REPLY_VALID; ++ } ++ ioc->scsih_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->scsih_cmds.done); ++ return 1; ++} ++ ++ ++ ++ ++#define MPT3_MAX_LUNS (255) ++ ++ ++/** ++ * _scsih_check_access_status - check access flags ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * @handle: sas device handle ++ * @access_flags: errors returned during discovery of the device ++ * ++ * Return 0 for success, else failure ++ */ ++static u8 ++_scsih_check_access_status(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u16 handle, u8 access_status) ++{ ++ u8 rc = 1; ++ char *desc = NULL; ++ ++ switch (access_status) { ++ case MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS: ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION: ++ rc = 0; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED: ++ desc = "sata capability failed"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT: ++ desc = "sata affiliation conflict"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_ROUTE_NOT_ADDRESSABLE: ++ desc = "route not addressable"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SMP_ERROR_NOT_ADDRESSABLE: ++ desc = "smp error not addressable"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED: ++ desc = "device blocked"; ++ break; ++ case MPI2_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_DIAG: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_PIO_SN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE: ++ case MPI2_SAS_DEVICE0_ASTATUS_SIF_MAX: ++ desc = "sata initialization failed"; ++ break; ++ default: ++ desc = "unknown"; ++ break; ++ } ++ ++ if (!rc) ++ return 0; ++ ++ pr_err(MPT3SAS_FMT ++ "discovery errors(%s): sas_address(0x%016llx), handle(0x%04x)\n", ++ ioc->name, desc, (unsigned long long)sas_address, handle); ++ return rc; ++} ++ ++/** ++ * _scsih_check_device - checking device responsiveness ++ * @ioc: per adapter object ++ * @parent_sas_address: sas address of parent expander or sas host ++ * @handle: attached device handle ++ * @phy_numberv: phy number ++ * @link_rate: new link rate ++ * ++ * Returns nothing. ++ */ ++static void ++_scsih_check_device(struct MPT3SAS_ADAPTER *ioc, ++ u64 parent_sas_address, u16 handle, u8 phy_number, u8 link_rate) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ struct _sas_device *sas_device; ++ u32 ioc_status; ++ unsigned long flags; ++ u64 sas_address; ++ struct scsi_target *starget; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ u32 device_info; ++ ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) ++ return; ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ return; ++ ++ /* wide port handling ~ we need only handle device once for the phy that ++ * is matched in sas device page zero ++ */ ++ if (phy_number != sas_device_pg0.PhyNum) ++ return; ++ ++ /* check if this is end device */ ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ if (!(_scsih_is_end_device(device_info))) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ ++ if (!sas_device) ++ goto out_unlock; ++ ++ if (unlikely(sas_device->handle != handle)) { ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ starget_printk(KERN_INFO, starget, ++ "handle changed from(0x%04x) to (0x%04x)!!!\n", ++ sas_device->handle, handle); ++ sas_target_priv_data->handle = handle; ++ sas_device->handle = handle; ++ if (sas_device_pg0.Flags & ++ MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ le16_to_cpu(sas_device_pg0.EnclosureLevel); ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0.ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } ++ } ++ ++ /* check if device is present */ ++ if (!(le16_to_cpu(sas_device_pg0.Flags) & ++ MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { ++ pr_err(MPT3SAS_FMT ++ "device is not present handle(0x%04x), flags!!!\n", ++ ioc->name, handle); ++ goto out_unlock; ++ } ++ ++ /* check if there were any issues with discovery */ ++ if (_scsih_check_access_status(ioc, sas_address, handle, ++ sas_device_pg0.AccessStatus)) ++ goto out_unlock; ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ _scsih_ublock_io_device(ioc, sas_address); ++ ++ if (sas_device) ++ sas_device_put(sas_device); ++ return; ++ ++out_unlock: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (sas_device) ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_add_device - creating sas device object ++ * @ioc: per adapter object ++ * @handle: sas device handle ++ * @phy_num: phy number end device attached to ++ * @is_pd: is this hidden raid component ++ * ++ * Creating end device object, stored in ioc->sas_device_list. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, ++ u8 is_pd) ++{ ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2SasEnclosurePage0_t enclosure_pg0; ++ struct _sas_device *sas_device; ++ u32 ioc_status; ++ u64 sas_address; ++ u32 device_info; ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ ++ /* check if this is end device */ ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ if (!(_scsih_is_end_device(device_info))) ++ return -1; ++ sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ ++ /* check if device is present */ ++ if (!(le16_to_cpu(sas_device_pg0.Flags) & ++ MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { ++ pr_err(MPT3SAS_FMT "device is not present handle(0x04%x)!!!\n", ++ ioc->name, handle); ++ return -1; ++ } ++ ++ /* check if there were any issues with discovery */ ++ if (_scsih_check_access_status(ioc, sas_address, handle, ++ sas_device_pg0.AccessStatus)) ++ return -1; ++ ++ sas_device = mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ return -1; ++ } ++ ++ sas_device = kzalloc(sizeof(struct _sas_device), ++ GFP_KERNEL); ++ if (!sas_device) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 0; ++ } ++ ++ kref_init(&sas_device->refcount); ++ sas_device->handle = handle; ++ if (_scsih_get_sas_address(ioc, ++ le16_to_cpu(sas_device_pg0.ParentDevHandle), ++ &sas_device->sas_address_parent) != 0) ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_device->enclosure_handle = ++ le16_to_cpu(sas_device_pg0.EnclosureHandle); ++ if (sas_device->enclosure_handle != 0) ++ sas_device->slot = ++ le16_to_cpu(sas_device_pg0.Slot); ++ sas_device->device_info = device_info; ++ sas_device->sas_address = sas_address; ++ sas_device->phy = sas_device_pg0.PhyNum; ++ sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & ++ MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; ++ ++ if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ le16_to_cpu(sas_device_pg0.EnclosureLevel); ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0.ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } ++ /* get enclosure_logical_id */ ++ if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0( ++ ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, ++ sas_device->enclosure_handle))) ++ sas_device->enclosure_logical_id = ++ le64_to_cpu(enclosure_pg0.EnclosureLogicalID); ++ ++ /* get device name */ ++ sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); ++ ++ if (ioc->wait_for_discovery_to_complete) ++ _scsih_sas_device_init_add(ioc, sas_device); ++ else ++ _scsih_sas_device_add(ioc, sas_device); ++ ++ sas_device_put(sas_device); ++ return 0; ++} ++ ++/** ++ * _scsih_remove_device - removing sas device object ++ * @ioc: per adapter object ++ * @sas_device_delete: the sas_device object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ ++ if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) && ++ (sas_device->pfa_led_on)) { ++ _scsih_turn_off_pfa_led(ioc, sas_device); ++ sas_device->pfa_led_on = 0; ++ } ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, __func__, ++ sas_device->handle, (unsigned long long) ++ sas_device->sas_address)); ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot)); ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter: enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, __func__, ++ sas_device->enclosure_level, ++ sas_device->connector_name)); ++ ++ if (sas_device->starget && sas_device->starget->hostdata) { ++ sas_target_priv_data = sas_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ _scsih_ublock_io_device(ioc, sas_device->sas_address); ++ sas_target_priv_data->handle = ++ MPT3SAS_INVALID_DEVICE_HANDLE; ++ } ++ ++ if (!ioc->hide_drives) ++ mpt2sas_transport_port_remove(ioc, ++ sas_device->sas_address, ++ sas_device->sas_address_parent); ++ ++ pr_info(MPT3SAS_FMT ++ "removing handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, sas_device->handle, ++ (unsigned long long) sas_device->sas_address); ++ if (sas_device->enclosure_handle != 0) ++ pr_info(MPT3SAS_FMT ++ "removing : enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot); ++ if (sas_device->connector_name[0] != '\0') ++ pr_info(MPT3SAS_FMT ++ "removing enclosure level(0x%04x), connector name( %s)\n", ++ ioc->name, sas_device->enclosure_level, ++ sas_device->connector_name); ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: exit: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, __func__, ++ sas_device->handle, (unsigned long long) ++ sas_device->sas_address)); ++ if (sas_device->enclosure_handle != 0) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: exit: enclosure logical id(0x%016llx), slot(%d)\n", ++ ioc->name, __func__, ++ (unsigned long long)sas_device->enclosure_logical_id, ++ sas_device->slot)); ++ if (sas_device->connector_name[0] != '\0') ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: exit: enclosure level(0x%04x), connector name(%s)\n", ++ ioc->name, __func__, sas_device->enclosure_level, ++ sas_device->connector_name)); ++} ++ ++/** ++ * _scsih_sas_topology_change_event_debug - debug for topology event ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ */ ++static void ++_scsih_sas_topology_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasTopologyChangeList_t *event_data) ++{ ++ int i; ++ u16 handle; ++ u16 reason_code; ++ u8 phy_number; ++ char *status_str = NULL; ++ u8 link_rate, prev_link_rate; ++ ++ switch (event_data->ExpStatus) { ++ case MPI2_EVENT_SAS_TOPO_ES_ADDED: ++ status_str = "add"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: ++ status_str = "remove"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: ++ case 0: ++ status_str = "responding"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: ++ status_str = "remove delay"; ++ break; ++ default: ++ status_str = "unknown status"; ++ break; ++ } ++ pr_info(MPT3SAS_FMT "sas topology change: (%s)\n", ++ ioc->name, status_str); ++ pr_info("\thandle(0x%04x), enclosure_handle(0x%04x) " \ ++ "start_phy(%02d), count(%d)\n", ++ le16_to_cpu(event_data->ExpanderDevHandle), ++ le16_to_cpu(event_data->EnclosureHandle), ++ event_data->StartPhyNum, event_data->NumEntries); ++ for (i = 0; i < event_data->NumEntries; i++) { ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ phy_number = event_data->StartPhyNum + i; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ switch (reason_code) { ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: ++ status_str = "target add"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: ++ status_str = "target remove"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: ++ status_str = "delay target remove"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: ++ status_str = "link rate change"; ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: ++ status_str = "target responding"; ++ break; ++ default: ++ status_str = "unknown"; ++ break; ++ } ++ link_rate = event_data->PHY[i].LinkRate >> 4; ++ prev_link_rate = event_data->PHY[i].LinkRate & 0xF; ++ pr_info("\tphy(%02d), attached_handle(0x%04x): %s:" \ ++ " link rate: new(0x%02x), old(0x%02x)\n", phy_number, ++ handle, status_str, link_rate, prev_link_rate); ++ ++ } ++} ++ ++/** ++ * _scsih_sas_topology_change_event - handle topology changes ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ */ ++static int ++_scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ int i; ++ u16 parent_handle, handle; ++ u16 reason_code; ++ u8 phy_number, max_phys; ++ struct _sas_node *sas_expander; ++ u64 sas_address; ++ unsigned long flags; ++ u8 link_rate, prev_link_rate; ++ Mpi2EventDataSasTopologyChangeList_t *event_data = ++ (Mpi2EventDataSasTopologyChangeList_t *) ++ fw_event->event_data; ++ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) ++ _scsih_sas_topology_change_event_debug(ioc, event_data); ++ ++ if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery) ++ return 0; ++ ++ if (!ioc->sas_hba.num_phys) ++ _scsih_sas_host_add(ioc); ++ else ++ _scsih_sas_host_refresh(ioc); ++ ++ if (fw_event->ignore) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "ignoring expander event\n", ioc->name)); ++ return 0; ++ } ++ ++ parent_handle = le16_to_cpu(event_data->ExpanderDevHandle); ++ ++ /* handle expander add */ ++ if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) ++ if (_scsih_expander_add(ioc, parent_handle) != 0) ++ return 0; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, ++ parent_handle); ++ if (sas_expander) { ++ sas_address = sas_expander->sas_address; ++ max_phys = sas_expander->num_phys; ++ } else if (parent_handle < ioc->sas_hba.num_phys) { ++ sas_address = ioc->sas_hba.sas_address; ++ max_phys = ioc->sas_hba.num_phys; ++ } else { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* handle siblings events */ ++ for (i = 0; i < event_data->NumEntries; i++) { ++ if (fw_event->ignore) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "ignoring expander event\n", ioc->name)); ++ return 0; ++ } ++ if (ioc->remove_host || ioc->pci_error_recovery) ++ return 0; ++ phy_number = event_data->StartPhyNum + i; ++ if (phy_number >= max_phys) ++ continue; ++ reason_code = event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_RC_MASK; ++ if ((event_data->PHY[i].PhyStatus & ++ MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code != ++ MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) ++ continue; ++ handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); ++ if (!handle) ++ continue; ++ link_rate = event_data->PHY[i].LinkRate >> 4; ++ prev_link_rate = event_data->PHY[i].LinkRate & 0xF; ++ switch (reason_code) { ++ case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: ++ ++ if (ioc->shost_recovery) ++ break; ++ ++ if (link_rate == prev_link_rate) ++ break; ++ ++ mpt2sas_transport_update_links(ioc, sas_address, ++ handle, phy_number, link_rate); ++ ++ if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) ++ break; ++ ++ _scsih_check_device(ioc, sas_address, handle, ++ phy_number, link_rate); ++ ++ ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: ++ ++ if (ioc->shost_recovery) ++ break; ++ ++ mpt2sas_transport_update_links(ioc, sas_address, ++ handle, phy_number, link_rate); ++ ++ _scsih_add_device(ioc, handle, phy_number, 0); ++ ++ break; ++ case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: ++ ++ _scsih_device_remove_by_handle(ioc, handle); ++ break; ++ } ++ } ++ ++ /* handle expander removal */ ++ if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && ++ sas_expander) ++ mpt2sas_expander_remove(ioc, sas_address); ++ ++ return 0; ++} ++ ++/** ++ * _scsih_sas_device_status_change_event_debug - debug for device event ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasDeviceStatusChange_t *event_data) ++{ ++ char *reason_str = NULL; ++ ++ switch (event_data->ReasonCode) { ++ case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: ++ reason_str = "smart data"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: ++ reason_str = "unsupported device discovered"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: ++ reason_str = "internal device reset"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: ++ reason_str = "internal task abort"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: ++ reason_str = "internal task abort set"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: ++ reason_str = "internal clear task set"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: ++ reason_str = "internal query task"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE: ++ reason_str = "sata init failure"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: ++ reason_str = "internal device reset complete"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: ++ reason_str = "internal task abort complete"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: ++ reason_str = "internal async notification"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY: ++ reason_str = "expander reduced functionality"; ++ break; ++ case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY: ++ reason_str = "expander reduced functionality complete"; ++ break; ++ default: ++ reason_str = "unknown reason"; ++ break; ++ } ++ pr_info(MPT3SAS_FMT "device status change: (%s)\n" ++ "\thandle(0x%04x), sas address(0x%016llx), tag(%d)", ++ ioc->name, reason_str, le16_to_cpu(event_data->DevHandle), ++ (unsigned long long)le64_to_cpu(event_data->SASAddress), ++ le16_to_cpu(event_data->TaskTag)); ++ if (event_data->ReasonCode == MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA) ++ pr_info(MPT3SAS_FMT ", ASC(0x%x), ASCQ(0x%x)\n", ioc->name, ++ event_data->ASC, event_data->ASCQ); ++ pr_info("\n"); ++} ++ ++/** ++ * _scsih_sas_device_status_change_event - handle device status change ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ struct MPT3SAS_TARGET *target_priv_data; ++ struct _sas_device *sas_device; ++ u64 sas_address; ++ unsigned long flags; ++ Mpi2EventDataSasDeviceStatusChange_t *event_data = ++ (Mpi2EventDataSasDeviceStatusChange_t *) ++ fw_event->event_data; ++ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) ++ _scsih_sas_device_status_change_event_debug(ioc, ++ event_data); ++ ++ /* In MPI Revision K (0xC), the internal device reset complete was ++ * implemented, so avoid setting tm_busy flag for older firmware. ++ */ ++ if ((ioc->facts.HeaderVersion >> 8) < 0xC) ++ return; ++ ++ if (event_data->ReasonCode != ++ MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET && ++ event_data->ReasonCode != ++ MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_address = le64_to_cpu(event_data->SASAddress); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ sas_address); ++ ++ if (!sas_device || !sas_device->starget) ++ goto out; ++ ++ target_priv_data = sas_device->starget->hostdata; ++ if (!target_priv_data) ++ goto out; ++ ++ if (event_data->ReasonCode == ++ MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) ++ target_priv_data->tm_busy = 1; ++ else ++ target_priv_data->tm_busy = 0; ++ ++out: ++ if (sas_device) ++ sas_device_put(sas_device); ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++} ++ ++/** ++ * _scsih_sas_enclosure_dev_status_change_event_debug - debug for enclosure ++ * event ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_enclosure_dev_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataSasEnclDevStatusChange_t *event_data) ++{ ++ char *reason_str = NULL; ++ ++ switch (event_data->ReasonCode) { ++ case MPI2_EVENT_SAS_ENCL_RC_ADDED: ++ reason_str = "enclosure add"; ++ break; ++ case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: ++ reason_str = "enclosure remove"; ++ break; ++ default: ++ reason_str = "unknown reason"; ++ break; ++ } ++ ++ pr_info(MPT3SAS_FMT "enclosure status change: (%s)\n" ++ "\thandle(0x%04x), enclosure logical id(0x%016llx)" ++ " number slots(%d)\n", ioc->name, reason_str, ++ le16_to_cpu(event_data->EnclosureHandle), ++ (unsigned long long)le64_to_cpu(event_data->EnclosureLogicalID), ++ le16_to_cpu(event_data->StartSlot)); ++} ++ ++/** ++ * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) ++ _scsih_sas_enclosure_dev_status_change_event_debug(ioc, ++ (Mpi2EventDataSasEnclDevStatusChange_t *) ++ fw_event->event_data); ++} ++ ++/** ++ * _scsih_sas_broadcast_primitive_event - handle broadcast events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ struct scsi_cmnd *scmd; ++ struct scsi_device *sdev; ++ u16 smid, handle; ++ u32 lun; ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ u32 termination_count; ++ u32 query_count; ++ Mpi2SCSITaskManagementReply_t *mpi_reply; ++ Mpi2EventDataSasBroadcastPrimitive_t *event_data = ++ (Mpi2EventDataSasBroadcastPrimitive_t *) ++ fw_event->event_data; ++ u16 ioc_status; ++ unsigned long flags; ++ int r; ++ u8 max_retries = 0; ++ u8 task_abort_retries; ++ ++ mutex_lock(&ioc->tm_cmds.mutex); ++ pr_info(MPT3SAS_FMT ++ "%s: enter: phy number(%d), width(%d)\n", ++ ioc->name, __func__, event_data->PhyNum, ++ event_data->PortWidth); ++ ++ _scsih_block_io_all_device(ioc); ++ ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ mpi_reply = ioc->tm_cmds.reply; ++ broadcast_aen_retry: ++ ++ /* sanity checks for retrying this loop */ ++ if (max_retries++ == 5) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT "%s: giving up\n", ++ ioc->name, __func__)); ++ goto out; ++ } else if (max_retries > 1) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT "%s: %d retry\n", ++ ioc->name, __func__, max_retries - 1)); ++ ++ termination_count = 0; ++ query_count = 0; ++ for (smid = 1; smid <= ioc->scsiio_depth; smid++) { ++ if (ioc->shost_recovery) ++ goto out; ++ scmd = _scsih_scsi_lookup_get(ioc, smid); ++ if (!scmd) ++ continue; ++ sdev = scmd->device; ++ sas_device_priv_data = sdev->hostdata; ++ if (!sas_device_priv_data || !sas_device_priv_data->sas_target) ++ continue; ++ /* skip hidden raid components */ ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_RAID_COMPONENT) ++ continue; ++ /* skip volumes */ ++ if (sas_device_priv_data->sas_target->flags & ++ MPT_TARGET_FLAGS_VOLUME) ++ continue; ++ ++ handle = sas_device_priv_data->sas_target->handle; ++ lun = sas_device_priv_data->lun; ++ query_count++; ++ ++ if (ioc->shost_recovery) ++ goto out; ++ ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ r = mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun, ++ MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, ++ TM_MUTEX_OFF); ++ if (r == FAILED) { ++ sdev_printk(KERN_WARNING, sdev, ++ "mpt2sas_scsih_issue_tm: FAILED when sending " ++ "QUERY_TASK: scmd(%p)\n", scmd); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ goto broadcast_aen_retry; ++ } ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus) ++ & MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ sdev_printk(KERN_WARNING, sdev, ++ "query task: FAILED with IOCSTATUS(0x%04x), scmd(%p)\n", ++ ioc_status, scmd); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ goto broadcast_aen_retry; ++ } ++ ++ /* see if IO is still owned by IOC and target */ ++ if (mpi_reply->ResponseCode == ++ MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED || ++ mpi_reply->ResponseCode == ++ MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC) { ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ continue; ++ } ++ task_abort_retries = 0; ++ tm_retry: ++ if (task_abort_retries++ == 60) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: ABORT_TASK: giving up\n", ioc->name, ++ __func__)); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ goto broadcast_aen_retry; ++ } ++ ++ if (ioc->shost_recovery) ++ goto out_no_lock; ++ ++ r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, ++ sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, ++ TM_MUTEX_OFF); ++ if (r == FAILED) { ++ sdev_printk(KERN_WARNING, sdev, ++ "mpt2sas_scsih_issue_tm: ABORT_TASK: FAILED : " ++ "scmd(%p)\n", scmd); ++ goto tm_retry; ++ } ++ ++ if (task_abort_retries > 1) ++ sdev_printk(KERN_WARNING, sdev, ++ "mpt2sas_scsih_issue_tm: ABORT_TASK: RETRIES (%d):" ++ " scmd(%p)\n", ++ task_abort_retries - 1, scmd); ++ ++ termination_count += le32_to_cpu(mpi_reply->TerminationCount); ++ spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); ++ } ++ ++ if (ioc->broadcast_aen_pending) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: loop back due to pending AEN\n", ++ ioc->name, __func__)); ++ ioc->broadcast_aen_pending = 0; ++ goto broadcast_aen_retry; ++ } ++ ++ out: ++ spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); ++ out_no_lock: ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - exit, query_count = %d termination_count = %d\n", ++ ioc->name, __func__, query_count, termination_count)); ++ ++ ioc->broadcast_aen_busy = 0; ++ if (!ioc->shost_recovery) ++ _scsih_ublock_io_all_device(ioc); ++ mutex_unlock(&ioc->tm_cmds.mutex); ++} ++ ++/** ++ * _scsih_sas_discovery_event - handle discovery events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ Mpi2EventDataSasDiscovery_t *event_data = ++ (Mpi2EventDataSasDiscovery_t *) fw_event->event_data; ++ ++ if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { ++ pr_info(MPT3SAS_FMT "discovery event: (%s)", ioc->name, ++ (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? ++ "start" : "stop"); ++ if (event_data->DiscoveryStatus) ++ pr_info("discovery_status(0x%08x)", ++ le32_to_cpu(event_data->DiscoveryStatus)); ++ pr_info("\n"); ++ } ++ ++ if (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED && ++ !ioc->sas_hba.num_phys) { ++ if (disable_discovery > 0 && ioc->shost_recovery) { ++ /* Wait for the reset to complete */ ++ while (ioc->shost_recovery) ++ ssleep(1); ++ } ++ _scsih_sas_host_add(ioc); ++ } ++} ++ ++/** ++ * _scsih_ir_fastpath - turn on fastpath for IR physdisk ++ * @ioc: per adapter object ++ * @handle: device handle for physical disk ++ * @phys_disk_num: physical disk number ++ * ++ * Return 0 for success, else failure. ++ */ ++static int ++_scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num) ++{ ++ Mpi2RaidActionRequest_t *mpi_request; ++ Mpi2RaidActionReply_t *mpi_reply; ++ u16 smid; ++ u8 issue_reset = 0; ++ int rc = 0; ++ u16 ioc_status; ++ u32 log_info; ++ ++ if (ioc->hba_mpi_version_belonged == MPI2_VERSION) ++ return rc; ++ ++ mutex_lock(&ioc->scsih_cmds.mutex); ++ ++ if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: scsih_cmd in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->scsih_cmds.status = MPT3_CMD_PENDING; ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->scsih_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t)); ++ ++ mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; ++ mpi_request->Action = MPI2_RAID_ACTION_PHYSDISK_HIDDEN; ++ mpi_request->PhysDiskNum = phys_disk_num; ++ ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT "IR RAID_ACTION: turning fast "\ ++ "path on for handle(0x%04x), phys_disk_num (0x%02x)\n", ioc->name, ++ handle, phys_disk_num)); ++ ++ init_completion(&ioc->scsih_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); ++ ++ if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ if (!(ioc->scsih_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ rc = -EFAULT; ++ goto out; ++ } ++ ++ if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->scsih_cmds.reply; ++ ioc_status = le16_to_cpu(mpi_reply->IOCStatus); ++ if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) ++ log_info = le32_to_cpu(mpi_reply->IOCLogInfo); ++ else ++ log_info = 0; ++ ioc_status &= MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "IR RAID_ACTION: failed: ioc_status(0x%04x), " ++ "loginfo(0x%08x)!!!\n", ioc->name, ioc_status, ++ log_info)); ++ rc = -EFAULT; ++ } else ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "IR RAID_ACTION: completed successfully\n", ++ ioc->name)); ++ } ++ ++ out: ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->scsih_cmds.mutex); ++ ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ return rc; ++} ++ ++/** ++ * _scsih_reprobe_lun - reprobing lun ++ * @sdev: scsi device struct ++ * @no_uld_attach: sdev->no_uld_attach flag setting ++ * ++ **/ ++static void ++_scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach) ++{ ++ int rc; ++ sdev->no_uld_attach = no_uld_attach ? 1 : 0; ++ sdev_printk(KERN_INFO, sdev, "%s raid component\n", ++ sdev->no_uld_attach ? "hidding" : "exposing"); ++ rc = scsi_device_reprobe(sdev); ++} ++ ++/** ++ * _scsih_sas_volume_add - add new volume ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_volume_add(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ u64 wwid; ++ u16 handle = le16_to_cpu(element->VolDevHandle); ++ int rc; ++ ++ mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); ++ if (!wwid) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_wwid(ioc, wwid); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (raid_device) ++ return; ++ ++ raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL); ++ if (!raid_device) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ raid_device->id = ioc->sas_id++; ++ raid_device->channel = RAID_CHANNEL; ++ raid_device->handle = handle; ++ raid_device->wwid = wwid; ++ _scsih_raid_device_add(ioc, raid_device); ++ if (!ioc->wait_for_discovery_to_complete) { ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ } else { ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ _scsih_determine_boot_device(ioc, raid_device, 1); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++} ++ ++/** ++ * _scsih_sas_volume_delete - delete volume ++ * @ioc: per adapter object ++ * @handle: volume device handle ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_volume_delete(struct MPT3SAS_ADAPTER *ioc, u16 handle) ++{ ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct scsi_target *starget = NULL; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device) { ++ if (raid_device->starget) { ++ starget = raid_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ } ++ pr_info(MPT3SAS_FMT "removing handle(0x%04x), wwid(0x%016llx)\n", ++ ioc->name, raid_device->handle, ++ (unsigned long long) raid_device->wwid); ++ list_del(&raid_device->list); ++ kfree(raid_device); ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ if (starget) ++ scsi_remove_target(&starget->dev); ++} ++ ++/** ++ * _scsih_sas_pd_expose - expose pd component to /dev/sdX ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_expose(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _sas_device *sas_device; ++ struct scsi_target *starget = NULL; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ unsigned long flags; ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ sas_device->volume_handle = 0; ++ sas_device->volume_wwid = 0; ++ clear_bit(handle, ioc->pd_handles); ++ if (sas_device->starget && sas_device->starget->hostdata) { ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->flags &= ++ ~MPT_TARGET_FLAGS_RAID_COMPONENT; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (!sas_device) ++ return; ++ ++ /* exposing raid component */ ++ if (starget) ++ starget_for_each_device(starget, NULL, _scsih_reprobe_lun); ++ ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_sas_pd_hide - hide pd component from /dev/sdX ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_hide(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _sas_device *sas_device; ++ struct scsi_target *starget = NULL; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ unsigned long flags; ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ u16 volume_handle = 0; ++ u64 volume_wwid = 0; ++ ++ mpt2sas_config_get_volume_handle(ioc, handle, &volume_handle); ++ if (volume_handle) ++ mpt2sas_config_get_volume_wwid(ioc, volume_handle, ++ &volume_wwid); ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ set_bit(handle, ioc->pd_handles); ++ if (sas_device->starget && sas_device->starget->hostdata) { ++ starget = sas_device->starget; ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->flags |= ++ MPT_TARGET_FLAGS_RAID_COMPONENT; ++ sas_device->volume_handle = volume_handle; ++ sas_device->volume_wwid = volume_wwid; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ if (!sas_device) ++ return; ++ ++ /* hiding raid component */ ++ _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); ++ ++ if (starget) ++ starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); ++ ++ sas_device_put(sas_device); ++} ++ ++/** ++ * _scsih_sas_pd_delete - delete pd component ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_delete(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ ++ _scsih_device_remove_by_handle(ioc, handle); ++} ++ ++/** ++ * _scsih_sas_pd_add - remove pd component ++ * @ioc: per adapter object ++ * @element: IR config element data ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_pd_add(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventIrConfigElement_t *element) ++{ ++ struct _sas_device *sas_device; ++ u16 handle = le16_to_cpu(element->PhysDiskDevHandle); ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ u32 ioc_status; ++ u64 sas_address; ++ u16 parent_handle; ++ ++ set_bit(handle, ioc->pd_handles); ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); ++ sas_device_put(sas_device); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) ++ mpt2sas_transport_update_links(ioc, sas_address, handle, ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ ++ _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); ++ _scsih_add_device(ioc, handle, 0, 1); ++} ++ ++/** ++ * _scsih_sas_ir_config_change_event_debug - debug for IR Config Change events ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_config_change_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrConfigChangeList_t *event_data) ++{ ++ Mpi2EventIrConfigElement_t *element; ++ u8 element_type; ++ int i; ++ char *reason_str = NULL, *element_str = NULL; ++ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ ++ pr_info(MPT3SAS_FMT "raid config change: (%s), elements(%d)\n", ++ ioc->name, (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? ++ "foreign" : "native", event_data->NumElements); ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ switch (element->ReasonCode) { ++ case MPI2_EVENT_IR_CHANGE_RC_ADDED: ++ reason_str = "add"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_REMOVED: ++ reason_str = "remove"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE: ++ reason_str = "no change"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_HIDE: ++ reason_str = "hide"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: ++ reason_str = "unhide"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: ++ reason_str = "volume_created"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: ++ reason_str = "volume_deleted"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: ++ reason_str = "pd_created"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: ++ reason_str = "pd_deleted"; ++ break; ++ default: ++ reason_str = "unknown reason"; ++ break; ++ } ++ element_type = le16_to_cpu(element->ElementFlags) & ++ MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK; ++ switch (element_type) { ++ case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT: ++ element_str = "volume"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT: ++ element_str = "phys disk"; ++ break; ++ case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT: ++ element_str = "hot spare"; ++ break; ++ default: ++ element_str = "unknown element"; ++ break; ++ } ++ pr_info("\t(%s:%s), vol handle(0x%04x), " \ ++ "pd handle(0x%04x), pd num(0x%02x)\n", element_str, ++ reason_str, le16_to_cpu(element->VolDevHandle), ++ le16_to_cpu(element->PhysDiskDevHandle), ++ element->PhysDiskNum); ++ } ++} ++ ++/** ++ * _scsih_sas_ir_config_change_event - handle ir configuration change events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ Mpi2EventIrConfigElement_t *element; ++ int i; ++ u8 foreign_config; ++ Mpi2EventDataIrConfigChangeList_t *event_data = ++ (Mpi2EventDataIrConfigChangeList_t *) ++ fw_event->event_data; ++ ++ if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && ++ (!ioc->hide_ir_msg)) ++ _scsih_sas_ir_config_change_event_debug(ioc, event_data); ++ ++ foreign_config = (le32_to_cpu(event_data->Flags) & ++ MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0; ++ ++ element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; ++ if (ioc->shost_recovery && ++ ioc->hba_mpi_version_belonged != MPI2_VERSION) { ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_HIDE) ++ _scsih_ir_fastpath(ioc, ++ le16_to_cpu(element->PhysDiskDevHandle), ++ element->PhysDiskNum); ++ } ++ return; ++ } ++ ++ for (i = 0; i < event_data->NumElements; i++, element++) { ++ ++ switch (element->ReasonCode) { ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: ++ case MPI2_EVENT_IR_CHANGE_RC_ADDED: ++ if (!foreign_config) ++ _scsih_sas_volume_add(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: ++ case MPI2_EVENT_IR_CHANGE_RC_REMOVED: ++ if (!foreign_config) ++ _scsih_sas_volume_delete(ioc, ++ le16_to_cpu(element->VolDevHandle)); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_hide(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_expose(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_HIDE: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_add(ioc, element); ++ break; ++ case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: ++ if (!ioc->is_warpdrive) ++ _scsih_sas_pd_delete(ioc, element); ++ break; ++ } ++ } ++} ++ ++/** ++ * _scsih_sas_ir_volume_event - IR volume event ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ u64 wwid; ++ unsigned long flags; ++ struct _raid_device *raid_device; ++ u16 handle; ++ u32 state; ++ int rc; ++ Mpi2EventDataIrVolume_t *event_data = ++ (Mpi2EventDataIrVolume_t *) fw_event->event_data; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) ++ return; ++ ++ handle = le16_to_cpu(event_data->VolDevHandle); ++ state = le32_to_cpu(event_data->NewValue); ++ if (!ioc->hide_ir_msg) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", ++ ioc->name, __func__, handle, ++ le32_to_cpu(event_data->PreviousValue), state)); ++ switch (state) { ++ case MPI2_RAID_VOL_STATE_MISSING: ++ case MPI2_RAID_VOL_STATE_FAILED: ++ _scsih_sas_volume_delete(ioc, handle); ++ break; ++ ++ case MPI2_RAID_VOL_STATE_ONLINE: ++ case MPI2_RAID_VOL_STATE_DEGRADED: ++ case MPI2_RAID_VOL_STATE_OPTIMAL: ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ ++ if (raid_device) ++ break; ++ ++ mpt2sas_config_get_volume_wwid(ioc, handle, &wwid); ++ if (!wwid) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ break; ++ } ++ ++ raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL); ++ if (!raid_device) { ++ pr_err(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ioc->name, ++ __FILE__, __LINE__, __func__); ++ break; ++ } ++ ++ raid_device->id = ioc->sas_id++; ++ raid_device->channel = RAID_CHANNEL; ++ raid_device->handle = handle; ++ raid_device->wwid = wwid; ++ _scsih_raid_device_add(ioc, raid_device); ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ break; ++ ++ case MPI2_RAID_VOL_STATE_INITIALIZING: ++ default: ++ break; ++ } ++} ++ ++/** ++ * _scsih_sas_ir_physical_disk_event - PD event ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ u16 handle, parent_handle; ++ u32 state; ++ struct _sas_device *sas_device; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ u32 ioc_status; ++ Mpi2EventDataIrPhysicalDisk_t *event_data = ++ (Mpi2EventDataIrPhysicalDisk_t *) fw_event->event_data; ++ u64 sas_address; ++ ++ if (ioc->shost_recovery) ++ return; ++ ++ if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) ++ return; ++ ++ handle = le16_to_cpu(event_data->PhysDiskDevHandle); ++ state = le32_to_cpu(event_data->NewValue); ++ ++ if (!ioc->hide_ir_msg) ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: handle(0x%04x), old(0x%08x), new(0x%08x)\n", ++ ioc->name, __func__, handle, ++ le32_to_cpu(event_data->PreviousValue), state)); ++ ++ switch (state) { ++ case MPI2_RAID_PD_STATE_ONLINE: ++ case MPI2_RAID_PD_STATE_DEGRADED: ++ case MPI2_RAID_PD_STATE_REBUILDING: ++ case MPI2_RAID_PD_STATE_OPTIMAL: ++ case MPI2_RAID_PD_STATE_HOT_SPARE: ++ ++ if (!ioc->is_warpdrive) ++ set_bit(handle, ioc->pd_handles); ++ ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ++ handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) ++ mpt2sas_transport_update_links(ioc, sas_address, handle, ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ ++ _scsih_add_device(ioc, handle, 0, 1); ++ ++ break; ++ ++ case MPI2_RAID_PD_STATE_OFFLINE: ++ case MPI2_RAID_PD_STATE_NOT_CONFIGURED: ++ case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: ++ default: ++ break; ++ } ++} ++ ++/** ++ * _scsih_sas_ir_operation_status_event_debug - debug for IR op event ++ * @ioc: per adapter object ++ * @event_data: event data payload ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_operation_status_event_debug(struct MPT3SAS_ADAPTER *ioc, ++ Mpi2EventDataIrOperationStatus_t *event_data) ++{ ++ char *reason_str = NULL; ++ ++ switch (event_data->RAIDOperation) { ++ case MPI2_EVENT_IR_RAIDOP_RESYNC: ++ reason_str = "resync"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: ++ reason_str = "online capacity expansion"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: ++ reason_str = "consistency check"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT: ++ reason_str = "background init"; ++ break; ++ case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT: ++ reason_str = "make data consistent"; ++ break; ++ } ++ ++ if (!reason_str) ++ return; ++ ++ pr_info(MPT3SAS_FMT "raid operational status: (%s)" \ ++ "\thandle(0x%04x), percent complete(%d)\n", ++ ioc->name, reason_str, ++ le16_to_cpu(event_data->VolDevHandle), ++ event_data->PercentComplete); ++} ++ ++/** ++ * _scsih_sas_ir_operation_status_event - handle RAID operation events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc, ++ struct fw_event_work *fw_event) ++{ ++ Mpi2EventDataIrOperationStatus_t *event_data = ++ (Mpi2EventDataIrOperationStatus_t *) ++ fw_event->event_data; ++ static struct _raid_device *raid_device; ++ unsigned long flags; ++ u16 handle; ++ ++ if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) && ++ (!ioc->hide_ir_msg)) ++ _scsih_sas_ir_operation_status_event_debug(ioc, ++ event_data); ++ ++ /* code added for raid transport support */ ++ if (event_data->RAIDOperation == MPI2_EVENT_IR_RAIDOP_RESYNC) { ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ handle = le16_to_cpu(event_data->VolDevHandle); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device) ++ raid_device->percent_complete = ++ event_data->PercentComplete; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++} ++ ++/** ++ * _scsih_prep_device_scan - initialize parameters prior to device scan ++ * @ioc: per adapter object ++ * ++ * Set the deleted flag prior to device scan. If the device is found during ++ * the scan, then we clear the deleted flag. ++ */ ++static void ++_scsih_prep_device_scan(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct MPT3SAS_DEVICE *sas_device_priv_data; ++ struct scsi_device *sdev; ++ ++ shost_for_each_device(sdev, ioc->shost) { ++ sas_device_priv_data = sdev->hostdata; ++ if (sas_device_priv_data && sas_device_priv_data->sas_target) ++ sas_device_priv_data->sas_target->deleted = 1; ++ } ++} ++ ++/** ++ * _scsih_mark_responding_sas_device - mark a sas_devices as responding ++ * @ioc: per adapter object ++ * @sas_device_pg0: SAS Device page 0 ++ * ++ * After host reset, find out whether devices are still responding. ++ * Used in _scsih_remove_unresponsive_sas_devices. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc, ++Mpi2SasDevicePage0_t *sas_device_pg0) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data = NULL; ++ struct scsi_target *starget; ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ list_for_each_entry(sas_device, &ioc->sas_device_list, list) { ++ if ((sas_device->sas_address == sas_device_pg0->SASAddress) && ++ (sas_device->slot == sas_device_pg0->Slot)) { ++ sas_device->responding = 1; ++ starget = sas_device->starget; ++ if (starget && starget->hostdata) { ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->tm_busy = 0; ++ sas_target_priv_data->deleted = 0; ++ } else ++ sas_target_priv_data = NULL; ++ if (starget) { ++ starget_printk(KERN_INFO, starget, ++ "handle(0x%04x), sas_addr(0x%016llx)\n", ++ sas_device_pg0->DevHandle, ++ (unsigned long long) ++ sas_device->sas_address); ++ ++ if (sas_device->enclosure_handle != 0) ++ starget_printk(KERN_INFO, starget, ++ "enclosure logical id(0x%016llx)," ++ " slot(%d)\n", ++ (unsigned long long) ++ sas_device->enclosure_logical_id, ++ sas_device->slot); ++ } ++ if (sas_device_pg0->Flags & ++ MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ sas_device->enclosure_level = ++ le16_to_cpu(sas_device_pg0->EnclosureLevel); ++ memcpy(&sas_device->connector_name[0], ++ &sas_device_pg0->ConnectorName[0], 4); ++ } else { ++ sas_device->enclosure_level = 0; ++ sas_device->connector_name[0] = '\0'; ++ } ++ ++ if (sas_device->handle == sas_device_pg0->DevHandle) ++ goto out; ++ pr_info("\thandle changed from(0x%04x)!!!\n", ++ sas_device->handle); ++ sas_device->handle = sas_device_pg0->DevHandle; ++ if (sas_target_priv_data) ++ sas_target_priv_data->handle = ++ sas_device_pg0->DevHandle; ++ goto out; ++ } ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_search_responding_sas_devices - ++ * @ioc: per adapter object ++ * ++ * After host reset, find out whether devices are still responding. ++ * If not remove. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 handle; ++ u32 device_info; ++ ++ pr_info(MPT3SAS_FMT "search for end-devices: start\n", ioc->name); ++ ++ if (list_empty(&ioc->sas_device_list)) ++ goto out; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, ++ handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ handle = sas_device_pg0.DevHandle = ++ le16_to_cpu(sas_device_pg0.DevHandle); ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ if (!(_scsih_is_end_device(device_info))) ++ continue; ++ sas_device_pg0.SASAddress = ++ le64_to_cpu(sas_device_pg0.SASAddress); ++ sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot); ++ _scsih_mark_responding_sas_device(ioc, &sas_device_pg0); ++ } ++ ++ out: ++ pr_info(MPT3SAS_FMT "search for end-devices: complete\n", ++ ioc->name); ++} ++ ++/** ++ * _scsih_mark_responding_raid_device - mark a raid_device as responding ++ * @ioc: per adapter object ++ * @wwid: world wide identifier for raid volume ++ * @handle: device handle ++ * ++ * After host reset, find out whether devices are still responding. ++ * Used in _scsih_remove_unresponsive_raid_devices. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_mark_responding_raid_device(struct MPT3SAS_ADAPTER *ioc, u64 wwid, ++ u16 handle) ++{ ++ struct MPT3SAS_TARGET *sas_target_priv_data = NULL; ++ struct scsi_target *starget; ++ struct _raid_device *raid_device; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ list_for_each_entry(raid_device, &ioc->raid_device_list, list) { ++ if (raid_device->wwid == wwid && raid_device->starget) { ++ starget = raid_device->starget; ++ if (starget && starget->hostdata) { ++ sas_target_priv_data = starget->hostdata; ++ sas_target_priv_data->deleted = 0; ++ } else ++ sas_target_priv_data = NULL; ++ raid_device->responding = 1; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ starget_printk(KERN_INFO, raid_device->starget, ++ "handle(0x%04x), wwid(0x%016llx)\n", handle, ++ (unsigned long long)raid_device->wwid); ++ ++ /* ++ * WARPDRIVE: The handles of the PDs might have changed ++ * across the host reset so re-initialize the ++ * required data for Direct IO ++ */ ++ mpt2sas_init_warpdrive_properties(ioc, raid_device); ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ if (raid_device->handle == handle) { ++ spin_unlock_irqrestore(&ioc->raid_device_lock, ++ flags); ++ return; ++ } ++ pr_info("\thandle changed from(0x%04x)!!!\n", ++ raid_device->handle); ++ raid_device->handle = handle; ++ if (sas_target_priv_data) ++ sas_target_priv_data->handle = handle; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ return; ++ } ++ } ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++} ++ ++/** ++ * _scsih_search_responding_raid_devices - ++ * @ioc: per adapter object ++ * ++ * After host reset, find out whether devices are still responding. ++ * If not remove. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidVolPage1_t volume_pg1; ++ Mpi2RaidVolPage0_t volume_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 handle; ++ u8 phys_disk_num; ++ ++ if (!ioc->ir_firmware) ++ return; ++ ++ pr_info(MPT3SAS_FMT "search for raid volumes: start\n", ++ ioc->name); ++ ++ if (list_empty(&ioc->raid_device_list)) ++ goto out; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ handle = le16_to_cpu(volume_pg1.DevHandle); ++ ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, ++ &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) ++ continue; ++ ++ if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) ++ _scsih_mark_responding_raid_device(ioc, ++ le64_to_cpu(volume_pg1.WWID), handle); ++ } ++ ++ /* refresh the pd_handles */ ++ if (!ioc->is_warpdrive) { ++ phys_disk_num = 0xFF; ++ memset(ioc->pd_handles, 0, ioc->pd_handles_sz); ++ while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, ++ phys_disk_num))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ phys_disk_num = pd_pg0.PhysDiskNum; ++ handle = le16_to_cpu(pd_pg0.DevHandle); ++ set_bit(handle, ioc->pd_handles); ++ } ++ } ++ out: ++ pr_info(MPT3SAS_FMT "search for responding raid volumes: complete\n", ++ ioc->name); ++} ++ ++/** ++ * _scsih_mark_responding_expander - mark a expander as responding ++ * @ioc: per adapter object ++ * @sas_address: sas address ++ * @handle: ++ * ++ * After host reset, find out whether devices are still responding. ++ * Used in _scsih_remove_unresponsive_expanders. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_mark_responding_expander(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u16 handle) ++{ ++ struct _sas_node *sas_expander; ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { ++ if (sas_expander->sas_address != sas_address) ++ continue; ++ sas_expander->responding = 1; ++ if (sas_expander->handle == handle) ++ goto out; ++ pr_info("\texpander(0x%016llx): handle changed" \ ++ " from(0x%04x) to (0x%04x)!!!\n", ++ (unsigned long long)sas_expander->sas_address, ++ sas_expander->handle, handle); ++ sas_expander->handle = handle; ++ for (i = 0 ; i < sas_expander->num_phys ; i++) ++ sas_expander->phy[i].handle = handle; ++ goto out; ++ } ++ out: ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++} ++ ++/** ++ * _scsih_search_responding_expanders - ++ * @ioc: per adapter object ++ * ++ * After host reset, find out whether devices are still responding. ++ * If not remove. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2ExpanderPage0_t expander_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u64 sas_address; ++ u16 handle; ++ ++ pr_info(MPT3SAS_FMT "search for expanders: start\n", ioc->name); ++ ++ if (list_empty(&ioc->sas_expander_list)) ++ goto out; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, ++ MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) { ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) ++ break; ++ ++ handle = le16_to_cpu(expander_pg0.DevHandle); ++ sas_address = le64_to_cpu(expander_pg0.SASAddress); ++ pr_info("\texpander present: handle(0x%04x), sas_addr(0x%016llx)\n", ++ handle, ++ (unsigned long long)sas_address); ++ _scsih_mark_responding_expander(ioc, sas_address, handle); ++ } ++ ++ out: ++ pr_info(MPT3SAS_FMT "search for expanders: complete\n", ioc->name); ++} ++ ++/** ++ * _scsih_remove_unresponding_sas_devices - removing unresponding devices ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_remove_unresponding_sas_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _sas_device *sas_device, *sas_device_next; ++ struct _sas_node *sas_expander, *sas_expander_next; ++ struct _raid_device *raid_device, *raid_device_next; ++ struct list_head tmp_list; ++ unsigned long flags; ++ LIST_HEAD(head); ++ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: start\n", ++ ioc->name); ++ ++ /* removing unresponding end devices */ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: end-devices\n", ++ ioc->name); ++ /* ++ * Iterate, pulling off devices marked as non-responding. We become the ++ * owner for the reference the list had on any object we prune. ++ */ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ list_for_each_entry_safe(sas_device, sas_device_next, ++ &ioc->sas_device_list, list) { ++ if (!sas_device->responding) ++ list_move_tail(&sas_device->list, &head); ++ else ++ sas_device->responding = 0; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ /* ++ * Now, uninitialize and remove the unresponding devices we pruned. ++ */ ++ list_for_each_entry_safe(sas_device, sas_device_next, &head, list) { ++ _scsih_remove_device(ioc, sas_device); ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ ++ /* removing unresponding volumes */ ++ if (ioc->ir_firmware) { ++ pr_info(MPT3SAS_FMT "removing unresponding devices: volumes\n", ++ ioc->name); ++ list_for_each_entry_safe(raid_device, raid_device_next, ++ &ioc->raid_device_list, list) { ++ if (!raid_device->responding) ++ _scsih_sas_volume_delete(ioc, ++ raid_device->handle); ++ else ++ raid_device->responding = 0; ++ } ++ } ++ ++ /* removing unresponding expanders */ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: expanders\n", ++ ioc->name); ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ INIT_LIST_HEAD(&tmp_list); ++ list_for_each_entry_safe(sas_expander, sas_expander_next, ++ &ioc->sas_expander_list, list) { ++ if (!sas_expander->responding) ++ list_move_tail(&sas_expander->list, &tmp_list); ++ else ++ sas_expander->responding = 0; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ list_for_each_entry_safe(sas_expander, sas_expander_next, &tmp_list, ++ list) { ++ list_del(&sas_expander->list); ++ _scsih_expander_node_remove(ioc, sas_expander); ++ } ++ ++ pr_info(MPT3SAS_FMT "removing unresponding devices: complete\n", ++ ioc->name); ++ ++ /* unblock devices */ ++ _scsih_ublock_io_all_device(ioc); ++} ++ ++static void ++_scsih_refresh_expander_links(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander, u16 handle) ++{ ++ Mpi2ExpanderPage1_t expander_pg1; ++ Mpi2ConfigReply_t mpi_reply; ++ int i; ++ ++ for (i = 0 ; i < sas_expander->num_phys ; i++) { ++ if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply, ++ &expander_pg1, i, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return; ++ } ++ ++ mpt2sas_transport_update_links(ioc, sas_expander->sas_address, ++ le16_to_cpu(expander_pg1.AttachedDevHandle), i, ++ expander_pg1.NegotiatedLinkRate >> 4); ++ } ++} ++ ++/** ++ * _scsih_scan_for_devices_after_reset - scan for devices after host reset ++ * @ioc: per adapter object ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2ExpanderPage0_t expander_pg0; ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2RaidVolPage1_t volume_pg1; ++ Mpi2RaidVolPage0_t volume_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2EventIrConfigElement_t element; ++ Mpi2ConfigReply_t mpi_reply; ++ u8 phys_disk_num; ++ u16 ioc_status; ++ u16 handle, parent_handle; ++ u64 sas_address; ++ struct _sas_device *sas_device; ++ struct _sas_node *expander_device; ++ static struct _raid_device *raid_device; ++ u8 retry_count; ++ unsigned long flags; ++ ++ pr_info(MPT3SAS_FMT "scan devices: start\n", ioc->name); ++ ++ _scsih_sas_host_refresh(ioc); ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: expanders start\n", ioc->name); ++ ++ /* expanders */ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, ++ MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from expander scan: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ handle = le16_to_cpu(expander_pg0.DevHandle); ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ expander_device = mpt2sas_scsih_expander_find_by_sas_address( ++ ioc, le64_to_cpu(expander_pg0.SASAddress)); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (expander_device) ++ _scsih_refresh_expander_links(ioc, expander_device, ++ handle); ++ else { ++ pr_info(MPT3SAS_FMT "\tBEFORE adding expander: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(expander_pg0.SASAddress)); ++ _scsih_expander_add(ioc, handle); ++ pr_info(MPT3SAS_FMT "\tAFTER adding expander: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(expander_pg0.SASAddress)); ++ } ++ } ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: expanders complete\n", ++ ioc->name); ++ ++ if (!ioc->ir_firmware) ++ goto skip_to_sas; ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: phys disk start\n", ioc->name); ++ ++ /* phys disk */ ++ phys_disk_num = 0xFF; ++ while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, ++ phys_disk_num))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from phys disk scan: "\ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ phys_disk_num = pd_pg0.PhysDiskNum; ++ handle = le16_to_cpu(pd_pg0.DevHandle); ++ sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ continue; ++ } ++ if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, ++ handle) != 0) ++ continue; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from phys disk scan " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, ++ &sas_address)) { ++ pr_info(MPT3SAS_FMT "\tBEFORE adding phys disk: " \ ++ " handle (0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ mpt2sas_transport_update_links(ioc, sas_address, ++ handle, sas_device_pg0.PhyNum, ++ MPI2_SAS_NEG_LINK_RATE_1_5); ++ set_bit(handle, ioc->pd_handles); ++ retry_count = 0; ++ /* This will retry adding the end device. ++ * _scsih_add_device() will decide on retries and ++ * return "1" when it should be retried ++ */ ++ while (_scsih_add_device(ioc, handle, retry_count++, ++ 1)) { ++ ssleep(1); ++ } ++ pr_info(MPT3SAS_FMT "\tAFTER adding phys disk: " \ ++ " handle (0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ } ++ } ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: phys disk complete\n", ++ ioc->name); ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: volumes start\n", ioc->name); ++ ++ /* volumes */ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ handle = le16_to_cpu(volume_pg1.DevHandle); ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = _scsih_raid_device_find_by_wwid(ioc, ++ le64_to_cpu(volume_pg1.WWID)); ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ if (raid_device) ++ continue; ++ if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, ++ &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, ++ sizeof(Mpi2RaidVolPage0_t))) ++ continue; ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \ ++ "ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE || ++ volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) { ++ memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t)); ++ element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED; ++ element.VolDevHandle = volume_pg1.DevHandle; ++ pr_info(MPT3SAS_FMT ++ "\tBEFORE adding volume: handle (0x%04x)\n", ++ ioc->name, volume_pg1.DevHandle); ++ _scsih_sas_volume_add(ioc, &element); ++ pr_info(MPT3SAS_FMT ++ "\tAFTER adding volume: handle (0x%04x)\n", ++ ioc->name, volume_pg1.DevHandle); ++ } ++ } ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: volumes complete\n", ++ ioc->name); ++ ++ skip_to_sas: ++ ++ pr_info(MPT3SAS_FMT "\tscan devices: end devices start\n", ++ ioc->name); ++ ++ /* sas devices */ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, ++ &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, ++ handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_info(MPT3SAS_FMT "\tbreak from end device scan:"\ ++ " ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, ioc_status, ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ break; ++ } ++ handle = le16_to_cpu(sas_device_pg0.DevHandle); ++ if (!(_scsih_is_end_device( ++ le32_to_cpu(sas_device_pg0.DeviceInfo)))) ++ continue; ++ sas_device = mpt2sas_get_sdev_by_addr(ioc, ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ if (sas_device) { ++ sas_device_put(sas_device); ++ continue; ++ } ++ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); ++ if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { ++ pr_info(MPT3SAS_FMT "\tBEFORE adding end device: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ mpt2sas_transport_update_links(ioc, sas_address, handle, ++ sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); ++ retry_count = 0; ++ /* This will retry adding the end device. ++ * _scsih_add_device() will decide on retries and ++ * return "1" when it should be retried ++ */ ++ while (_scsih_add_device(ioc, handle, retry_count++, ++ 0)) { ++ ssleep(1); ++ } ++ pr_info(MPT3SAS_FMT "\tAFTER adding end device: " \ ++ "handle (0x%04x), sas_addr(0x%016llx)\n", ioc->name, ++ handle, (unsigned long long) ++ le64_to_cpu(sas_device_pg0.SASAddress)); ++ } ++ } ++ pr_info(MPT3SAS_FMT "\tscan devices: end devices complete\n", ++ ioc->name); ++ ++ pr_info(MPT3SAS_FMT "scan devices: complete\n", ioc->name); ++} ++/** ++ * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) ++ * @ioc: per adapter object ++ * @reset_phase: phase ++ * ++ * The handler for doing any required cleanup or initialization. ++ * ++ * The reset phase can be MPT3_IOC_PRE_RESET, MPT3_IOC_AFTER_RESET, ++ * MPT3_IOC_DONE_RESET ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) ++{ ++ switch (reset_phase) { ++ case MPT3_IOC_PRE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_PRE_RESET\n", ioc->name, __func__)); ++ break; ++ case MPT3_IOC_AFTER_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_AFTER_RESET\n", ioc->name, __func__)); ++ if (ioc->scsih_cmds.status & MPT3_CMD_PENDING) { ++ ioc->scsih_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->scsih_cmds.smid); ++ complete(&ioc->scsih_cmds.done); ++ } ++ if (ioc->tm_cmds.status & MPT3_CMD_PENDING) { ++ ioc->tm_cmds.status |= MPT3_CMD_RESET; ++ mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid); ++ complete(&ioc->tm_cmds.done); ++ } ++ ++ _scsih_fw_event_cleanup_queue(ioc); ++ _scsih_flush_running_cmds(ioc); ++ break; ++ case MPT3_IOC_DONE_RESET: ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: MPT3_IOC_DONE_RESET\n", ioc->name, __func__)); ++ if ((!ioc->is_driver_loading) && !(disable_discovery > 0 && ++ !ioc->sas_hba.num_phys)) { ++ _scsih_prep_device_scan(ioc); ++ _scsih_search_responding_sas_devices(ioc); ++ _scsih_search_responding_raid_devices(ioc); ++ _scsih_search_responding_expanders(ioc); ++ _scsih_error_recovery_delete_devices(ioc); ++ } ++ break; ++ } ++} ++ ++/** ++ * _mpt2sas_fw_work - delayed task for processing firmware events ++ * @ioc: per adapter object ++ * @fw_event: The fw_event_work object ++ * Context: user. ++ * ++ * Return nothing. ++ */ ++static void ++_mpt2sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) ++{ ++ _scsih_fw_event_del_from_list(ioc, fw_event); ++ ++ /* the queue is being flushed so ignore this event */ ++ if (ioc->remove_host || ioc->pci_error_recovery) { ++ fw_event_work_put(fw_event); ++ return; ++ } ++ ++ switch (fw_event->event) { ++ case MPT3SAS_PROCESS_TRIGGER_DIAG: ++ mpt2sas_process_trigger_data(ioc, ++ (struct SL_WH_TRIGGERS_EVENT_DATA_T *) ++ fw_event->event_data); ++ break; ++ case MPT3SAS_REMOVE_UNRESPONDING_DEVICES: ++ while (scsi_host_in_recovery(ioc->shost) || ++ ioc->shost_recovery) { ++ /* ++ * If we're unloading, bail. Otherwise, this can become ++ * an infinite loop. ++ */ ++ if (ioc->remove_host) ++ goto out; ++ ssleep(1); ++ } ++ _scsih_remove_unresponding_sas_devices(ioc); ++ _scsih_scan_for_devices_after_reset(ioc); ++ break; ++ case MPT3SAS_PORT_ENABLE_COMPLETE: ++ ioc->start_scan = 0; ++ if (missing_delay[0] != -1 && missing_delay[1] != -1) ++ mpt2sas_base_update_missing_delay(ioc, missing_delay[0], ++ missing_delay[1]); ++ dewtprintk(ioc, pr_info(MPT3SAS_FMT ++ "port enable: complete from worker thread\n", ++ ioc->name)); ++ break; ++ case MPT3SAS_TURN_ON_PFA_LED: ++ _scsih_turn_on_pfa_led(ioc, fw_event->device_handle); ++ break; ++ case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: ++ _scsih_sas_topology_change_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: ++ _scsih_sas_device_status_change_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_DISCOVERY: ++ _scsih_sas_discovery_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: ++ _scsih_sas_broadcast_primitive_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: ++ _scsih_sas_enclosure_dev_status_change_event(ioc, ++ fw_event); ++ break; ++ case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: ++ _scsih_sas_ir_config_change_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_IR_VOLUME: ++ _scsih_sas_ir_volume_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_IR_PHYSICAL_DISK: ++ _scsih_sas_ir_physical_disk_event(ioc, fw_event); ++ break; ++ case MPI2_EVENT_IR_OPERATION_STATUS: ++ _scsih_sas_ir_operation_status_event(ioc, fw_event); ++ break; ++ } ++out: ++ fw_event_work_put(fw_event); ++} ++ ++/** ++ * _firmware_event_work ++ * @ioc: per adapter object ++ * @work: The fw_event_work object ++ * Context: user. ++ * ++ * wrappers for the work thread handling firmware events ++ * ++ * Return nothing. ++ */ ++ ++static void ++_firmware_event_work(struct work_struct *work) ++{ ++ struct fw_event_work *fw_event = container_of(work, ++ struct fw_event_work, work); ++ ++ _mpt2sas_fw_work(fw_event->ioc, fw_event); ++} ++ ++/** ++ * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time) ++ * @ioc: per adapter object ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * Context: interrupt. ++ * ++ * This function merely adds a new work task into ioc->firmware_event_thread. ++ * The tasks are worked from _firmware_event_work in user context. ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ++ u32 reply) ++{ ++ struct fw_event_work *fw_event; ++ Mpi2EventNotificationReply_t *mpi_reply; ++ u16 event; ++ u16 sz; ++ Mpi26EventDataActiveCableExcept_t *ActiveCableEventData; ++ ++ /* events turned off due to host reset or driver unloading */ ++ if (ioc->remove_host || ioc->pci_error_recovery) ++ return 1; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ ++ if (unlikely(!mpi_reply)) { ++ pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ ++ event = le16_to_cpu(mpi_reply->Event); ++ ++ if (event != MPI2_EVENT_LOG_ENTRY_ADDED) ++ mpt2sas_trigger_event(ioc, event, 0); ++ ++ switch (event) { ++ /* handle these */ ++ case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: ++ { ++ Mpi2EventDataSasBroadcastPrimitive_t *baen_data = ++ (Mpi2EventDataSasBroadcastPrimitive_t *) ++ mpi_reply->EventData; ++ ++ if (baen_data->Primitive != ++ MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT) ++ return 1; ++ ++ if (ioc->broadcast_aen_busy) { ++ ioc->broadcast_aen_pending++; ++ return 1; ++ } else ++ ioc->broadcast_aen_busy = 1; ++ break; ++ } ++ ++ case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: ++ _scsih_check_topo_delete_events(ioc, ++ (Mpi2EventDataSasTopologyChangeList_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: ++ _scsih_check_ir_config_unhide_events(ioc, ++ (Mpi2EventDataIrConfigChangeList_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_IR_VOLUME: ++ _scsih_check_volume_delete_events(ioc, ++ (Mpi2EventDataIrVolume_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_LOG_ENTRY_ADDED: ++ { ++ Mpi2EventDataLogEntryAdded_t *log_entry; ++ u32 *log_code; ++ ++ if (!ioc->is_warpdrive) ++ break; ++ ++ log_entry = (Mpi2EventDataLogEntryAdded_t *) ++ mpi_reply->EventData; ++ log_code = (u32 *)log_entry->LogData; ++ ++ if (le16_to_cpu(log_entry->LogEntryQualifier) ++ != MPT2_WARPDRIVE_LOGENTRY) ++ break; ++ ++ switch (le32_to_cpu(*log_code)) { ++ case MPT2_WARPDRIVE_LC_SSDT: ++ pr_warn(MPT3SAS_FMT "WarpDrive Warning: " ++ "IO Throttling has occurred in the WarpDrive " ++ "subsystem. Check WarpDrive documentation for " ++ "additional details.\n", ioc->name); ++ break; ++ case MPT2_WARPDRIVE_LC_SSDLW: ++ pr_warn(MPT3SAS_FMT "WarpDrive Warning: " ++ "Program/Erase Cycles for the WarpDrive subsystem " ++ "in degraded range. Check WarpDrive documentation " ++ "for additional details.\n", ioc->name); ++ break; ++ case MPT2_WARPDRIVE_LC_SSDLF: ++ pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " ++ "There are no Program/Erase Cycles for the " ++ "WarpDrive subsystem. The storage device will be " ++ "in read-only mode. Check WarpDrive documentation " ++ "for additional details.\n", ioc->name); ++ break; ++ case MPT2_WARPDRIVE_LC_BRMF: ++ pr_err(MPT3SAS_FMT "WarpDrive Fatal Error: " ++ "The Backup Rail Monitor has failed on the " ++ "WarpDrive subsystem. Check WarpDrive " ++ "documentation for additional details.\n", ++ ioc->name); ++ break; ++ } ++ ++ break; ++ } ++ case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: ++ case MPI2_EVENT_IR_OPERATION_STATUS: ++ case MPI2_EVENT_SAS_DISCOVERY: ++ case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: ++ case MPI2_EVENT_IR_PHYSICAL_DISK: ++ break; ++ ++ case MPI2_EVENT_TEMP_THRESHOLD: ++ _scsih_temp_threshold_events(ioc, ++ (Mpi2EventDataTemperature_t *) ++ mpi_reply->EventData); ++ break; ++ case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION: ++ ActiveCableEventData = ++ (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData; ++ if (ActiveCableEventData->ReasonCode == ++ MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) ++ pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d", ++ ioc->name, ActiveCableEventData->ReceptacleID); ++ pr_info("cannot be powered and devices connected to this active cable"); ++ pr_info("will not be seen. This active cable"); ++ pr_info("requires %d mW of power", ++ ActiveCableEventData->ActiveCablePowerRequirement); ++ break; ++ ++ default: /* ignore the rest */ ++ return 1; ++ } ++ ++ sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; ++ fw_event = alloc_fw_event_work(sz); ++ if (!fw_event) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return 1; ++ } ++ ++ memcpy(fw_event->event_data, mpi_reply->EventData, sz); ++ fw_event->ioc = ioc; ++ fw_event->VF_ID = mpi_reply->VF_ID; ++ fw_event->VP_ID = mpi_reply->VP_ID; ++ fw_event->event = event; ++ _scsih_fw_event_add(ioc, fw_event); ++ fw_event_work_put(fw_event); ++ return 1; ++} ++ ++/** ++ * _scsih_expander_node_remove - removing expander device from list. ++ * @ioc: per adapter object ++ * @sas_expander: the sas_device object ++ * Context: Calling function should acquire ioc->sas_node_lock. ++ * ++ * Removing object and freeing associated memory from the ++ * ioc->sas_expander_list. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_expander_node_remove(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_expander) ++{ ++ struct _sas_port *mpt2sas_port, *next; ++ ++ /* remove sibling ports attached to this expander */ ++ list_for_each_entry_safe(mpt2sas_port, next, ++ &sas_expander->sas_port_list, port_list) { ++ if (ioc->shost_recovery) ++ return; ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_END_DEVICE) ++ mpt2sas_device_remove_by_sas_address(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ else if (mpt2sas_port->remote_identify.device_type == ++ SAS_EDGE_EXPANDER_DEVICE || ++ mpt2sas_port->remote_identify.device_type == ++ SAS_FANOUT_EXPANDER_DEVICE) ++ mpt2sas_expander_remove(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ } ++ ++ mpt2sas_transport_port_remove(ioc, sas_expander->sas_address, ++ sas_expander->sas_address_parent); ++ ++ pr_info(MPT3SAS_FMT ++ "expander_remove: handle(0x%04x), sas_addr(0x%016llx)\n", ++ ioc->name, ++ sas_expander->handle, (unsigned long long) ++ sas_expander->sas_address); ++ ++ kfree(sas_expander->phy); ++ kfree(sas_expander); ++} ++ ++/** ++ * _scsih_ir_shutdown - IR shutdown notification ++ * @ioc: per adapter object ++ * ++ * Sending RAID Action to alert the Integrated RAID subsystem of the IOC that ++ * the host system is shutting down. ++ * ++ * Return nothing. ++ */ ++static void ++_scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidActionRequest_t *mpi_request; ++ Mpi2RaidActionReply_t *mpi_reply; ++ u16 smid; ++ ++ /* is IR firmware build loaded ? */ ++ if (!ioc->ir_firmware) ++ return; ++ ++ /* are there any volumes ? */ ++ if (list_empty(&ioc->raid_device_list)) ++ return; ++ ++ mutex_lock(&ioc->scsih_cmds.mutex); ++ ++ if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: scsih_cmd in use\n", ++ ioc->name, __func__); ++ goto out; ++ } ++ ioc->scsih_cmds.status = MPT3_CMD_PENDING; ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->scsih_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->scsih_cmds.smid = smid; ++ memset(mpi_request, 0, sizeof(Mpi2RaidActionRequest_t)); ++ ++ mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; ++ mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; ++ ++ if (!ioc->hide_ir_msg) ++ pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); ++ init_completion(&ioc->scsih_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); ++ ++ if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ goto out; ++ } ++ ++ if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { ++ mpi_reply = ioc->scsih_cmds.reply; ++ if (!ioc->hide_ir_msg) ++ pr_info(MPT3SAS_FMT "IR shutdown " ++ "(complete): ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, le16_to_cpu(mpi_reply->IOCStatus), ++ le32_to_cpu(mpi_reply->IOCLogInfo)); ++ } ++ ++ out: ++ ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->scsih_cmds.mutex); ++} ++ ++/** ++ * scsih_remove_mpt2sas - detach and remove add host ++ * @pdev: PCI device struct ++ * ++ * Routine called when unloading the driver. ++ * Return nothing. ++ */ ++void scsih_remove_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct _sas_port *mpt2sas_port, *next_port; ++ struct _raid_device *raid_device, *next; ++ struct MPT3SAS_TARGET *sas_target_priv_data; ++ struct workqueue_struct *wq; ++ unsigned long flags; ++ ++ ioc->remove_host = 1; ++ _scsih_fw_event_cleanup_queue(ioc); ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ wq = ioc->firmware_event_thread; ++ ioc->firmware_event_thread = NULL; ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++ if (wq) ++ destroy_workqueue(wq); ++ ++ /* release all the volumes */ ++ _scsih_ir_shutdown(ioc); ++ list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, ++ list) { ++ if (raid_device->starget) { ++ sas_target_priv_data = ++ raid_device->starget->hostdata; ++ sas_target_priv_data->deleted = 1; ++ scsi_remove_target(&raid_device->starget->dev); ++ } ++ pr_info(MPT3SAS_FMT "removing handle(0x%04x), wwid(0x%016llx)\n", ++ ioc->name, raid_device->handle, ++ (unsigned long long) raid_device->wwid); ++ _scsih_raid_device_remove(ioc, raid_device); ++ } ++ ++ /* free ports attached to the sas_host */ ++ list_for_each_entry_safe(mpt2sas_port, next_port, ++ &ioc->sas_hba.sas_port_list, port_list) { ++ if (mpt2sas_port->remote_identify.device_type == ++ SAS_END_DEVICE) ++ mpt2sas_device_remove_by_sas_address(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ else if (mpt2sas_port->remote_identify.device_type == ++ SAS_EDGE_EXPANDER_DEVICE || ++ mpt2sas_port->remote_identify.device_type == ++ SAS_FANOUT_EXPANDER_DEVICE) ++ mpt2sas_expander_remove(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ } ++ ++ /* free phys attached to the sas_host */ ++ if (ioc->sas_hba.num_phys) { ++ kfree(ioc->sas_hba.phy); ++ ioc->sas_hba.phy = NULL; ++ ioc->sas_hba.num_phys = 0; ++ } ++ ++ sas_remove_host(shost); ++ scsi_remove_host(shost); ++ mpt2sas_base_detach(ioc); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_del(&ioc->list); ++ spin_unlock(&gioc_lock_mpt2sas); ++ scsi_host_put(shost); ++} ++ ++/** ++ * scsih_shutdown_mpt2sas - routine call during system shutdown ++ * @pdev: PCI device struct ++ * ++ * Return nothing. ++ */ ++void ++scsih_shutdown_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ struct workqueue_struct *wq; ++ unsigned long flags; ++ ++ ioc->remove_host = 1; ++ _scsih_fw_event_cleanup_queue(ioc); ++ ++ spin_lock_irqsave(&ioc->fw_event_lock, flags); ++ wq = ioc->firmware_event_thread; ++ ioc->firmware_event_thread = NULL; ++ spin_unlock_irqrestore(&ioc->fw_event_lock, flags); ++ if (wq) ++ destroy_workqueue(wq); ++ ++ _scsih_ir_shutdown(ioc); ++ mpt2sas_base_detach(ioc); ++} ++ ++ ++/** ++ * _scsih_probe_boot_devices - reports 1st device ++ * @ioc: per adapter object ++ * ++ * If specified in bios page 2, this routine reports the 1st ++ * device scsi-ml or sas transport for persistent boot device ++ * purposes. Please refer to function _scsih_determine_boot_device() ++ */ ++static void ++_scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u8 is_raid; ++ void *device; ++ struct _sas_device *sas_device; ++ struct _raid_device *raid_device; ++ u16 handle; ++ u64 sas_address_parent; ++ u64 sas_address; ++ unsigned long flags; ++ int rc; ++ ++ /* no Bios, return immediately */ ++ if (!ioc->bios_pg3.BiosVersion) ++ return; ++ ++ device = NULL; ++ is_raid = 0; ++ if (ioc->req_boot_device.device) { ++ device = ioc->req_boot_device.device; ++ is_raid = ioc->req_boot_device.is_raid; ++ } else if (ioc->req_alt_boot_device.device) { ++ device = ioc->req_alt_boot_device.device; ++ is_raid = ioc->req_alt_boot_device.is_raid; ++ } else if (ioc->current_boot_device.device) { ++ device = ioc->current_boot_device.device; ++ is_raid = ioc->current_boot_device.is_raid; ++ } ++ ++ if (!device) ++ return; ++ ++ if (is_raid) { ++ raid_device = device; ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ } else { ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = device; ++ handle = sas_device->handle; ++ sas_address_parent = sas_device->sas_address_parent; ++ sas_address = sas_device->sas_address; ++ list_move_tail(&sas_device->list, &ioc->sas_device_list); ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ if (ioc->hide_drives) ++ return; ++ if (!mpt2sas_transport_port_add(ioc, handle, ++ sas_address_parent)) { ++ _scsih_sas_device_remove(ioc, sas_device); ++ } else if (!sas_device->starget) { ++ if (!ioc->is_driver_loading) { ++ mpt2sas_transport_port_remove(ioc, ++ sas_address, ++ sas_address_parent); ++ _scsih_sas_device_remove(ioc, sas_device); ++ } ++ } ++ } ++} ++ ++/** ++ * _scsih_probe_raid - reporting raid volumes to scsi-ml ++ * @ioc: per adapter object ++ * ++ * Called during initial loading of the driver. ++ */ ++static void ++_scsih_probe_raid(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _raid_device *raid_device, *raid_next; ++ int rc; ++ ++ list_for_each_entry_safe(raid_device, raid_next, ++ &ioc->raid_device_list, list) { ++ if (raid_device->starget) ++ continue; ++ rc = scsi_add_device(ioc->shost, RAID_CHANNEL, ++ raid_device->id, 0); ++ if (rc) ++ _scsih_raid_device_remove(ioc, raid_device); ++ } ++} ++ ++static struct _sas_device *get_next_sas_device(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _sas_device *sas_device = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ if (!list_empty(&ioc->sas_device_init_list)) { ++ sas_device = list_first_entry(&ioc->sas_device_init_list, ++ struct _sas_device, list); ++ sas_device_get(sas_device); ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ ++ return sas_device; ++} ++ ++static void sas_device_make_active(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_device *sas_device) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ ++ /* ++ * Since we dropped the lock during the call to port_add(), we need to ++ * be careful here that somebody else didn't move or delete this item ++ * while we were busy with other things. ++ * ++ * If it was on the list, we need a put() for the reference the list ++ * had. Either way, we need a get() for the destination list. ++ */ ++ if (!list_empty(&sas_device->list)) { ++ list_del_init(&sas_device->list); ++ sas_device_put(sas_device); ++ } ++ ++ sas_device_get(sas_device); ++ list_add_tail(&sas_device->list, &ioc->sas_device_list); ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++} ++ ++/** ++ * _scsih_probe_sas - reporting sas devices to sas transport ++ * @ioc: per adapter object ++ * ++ * Called during initial loading of the driver. ++ */ ++static void ++_scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) ++{ ++ struct _sas_device *sas_device; ++ ++ if (ioc->hide_drives) ++ return; ++ ++ while ((sas_device = get_next_sas_device(ioc))) { ++ if (!mpt2sas_transport_port_add(ioc, sas_device->handle, ++ sas_device->sas_address_parent)) { ++ _scsih_sas_device_remove(ioc, sas_device); ++ sas_device_put(sas_device); ++ continue; ++ } else if (!sas_device->starget) { ++ /* ++ * When asyn scanning is enabled, its not possible to ++ * remove devices while scanning is turned on due to an ++ * oops in scsi_sysfs_add_sdev()->add_device()-> ++ * sysfs_addrm_start() ++ */ ++ if (!ioc->is_driver_loading) { ++ mpt2sas_transport_port_remove(ioc, ++ sas_device->sas_address, ++ sas_device->sas_address_parent); ++ _scsih_sas_device_remove(ioc, sas_device); ++ sas_device_put(sas_device); ++ continue; ++ } ++ } ++ sas_device_make_active(ioc, sas_device); ++ sas_device_put(sas_device); ++ } ++} ++ ++/** ++ * _scsih_probe_devices - probing for devices ++ * @ioc: per adapter object ++ * ++ * Called during initial loading of the driver. ++ */ ++static void ++_scsih_probe_devices(struct MPT3SAS_ADAPTER *ioc) ++{ ++ u16 volume_mapping_flags; ++ ++ if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR)) ++ return; /* return when IOC doesn't support initiator mode */ ++ ++ _scsih_probe_boot_devices(ioc); ++ ++ if (ioc->ir_firmware) { ++ volume_mapping_flags = ++ le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) & ++ MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE; ++ if (volume_mapping_flags == ++ MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) { ++ _scsih_probe_raid(ioc); ++ _scsih_probe_sas(ioc); ++ } else { ++ _scsih_probe_sas(ioc); ++ _scsih_probe_raid(ioc); ++ } ++ } else ++ _scsih_probe_sas(ioc); ++} ++ ++/** ++ * scsih_scan_start_mpt2sas - scsi lld callback for .scan_start ++ * @shost: SCSI host pointer ++ * ++ * The shost has the ability to discover targets on its own instead ++ * of scanning the entire bus. In our implemention, we will kick off ++ * firmware discovery. ++ */ ++void ++scsih_scan_start_mpt2sas(struct Scsi_Host *shost) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int rc; ++ if (diag_buffer_enable != -1 && diag_buffer_enable != 0) ++ mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); ++ ++ if (disable_discovery > 0) ++ return; ++ ++ ioc->start_scan = 1; ++ rc = mpt2sas_port_enable(ioc); ++ ++ if (rc != 0) ++ pr_info(MPT3SAS_FMT "port enable: FAILED\n", ioc->name); ++} ++ ++/** ++ * scsih_scan_finished_mpt2sas - scsi lld callback for .scan_finished ++ * @shost: SCSI host pointer ++ * @time: elapsed time of the scan in jiffies ++ * ++ * This function will be called periodicallyn until it returns 1 with the ++ * scsi_host and the elapsed time of the scan in jiffies. In our implemention, ++ * we wait for firmware discovery to complete, then return 1. ++ */ ++int ++scsih_scan_finished_mpt2sas(struct Scsi_Host *shost, unsigned long time) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ if (disable_discovery > 0) { ++ ioc->is_driver_loading = 0; ++ ioc->wait_for_discovery_to_complete = 0; ++ return 1; ++ } ++ ++ if (time >= (300 * HZ)) { ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ pr_info(MPT3SAS_FMT ++ "port enable: FAILED with timeout (timeout=300s)\n", ++ ioc->name); ++ ioc->is_driver_loading = 0; ++ return 1; ++ } ++ ++ if (ioc->start_scan) ++ return 0; ++ ++ if (ioc->start_scan_failed) { ++ pr_info(MPT3SAS_FMT ++ "port enable: FAILED with (ioc_status=0x%08x)\n", ++ ioc->name, ioc->start_scan_failed); ++ ioc->is_driver_loading = 0; ++ ioc->wait_for_discovery_to_complete = 0; ++ ioc->remove_host = 1; ++ return 1; ++ } ++ ++ pr_info(MPT3SAS_FMT "port enable: SUCCESS\n", ioc->name); ++ ioc->base_cmds.status = MPT3_CMD_NOT_USED; ++ ++ if (ioc->wait_for_discovery_to_complete) { ++ ioc->wait_for_discovery_to_complete = 0; ++ _scsih_probe_devices(ioc); ++ } ++ mpt2sas_base_start_watchdog(ioc); ++ ioc->is_driver_loading = 0; ++ return 1; ++} ++ ++/* shost template for SAS 2.0 HBA devices */ ++static struct scsi_host_template mpt2sas_driver_template_mpt2sas = { ++ .module = THIS_MODULE, ++ .name = "Fusion MPT SAS Host", ++ .proc_name = MPT2SAS_DRIVER_NAME, ++ .queuecommand = scsih_qcmd_mpt2sas, ++ .target_alloc = scsih_target_alloc_mpt2sas, ++ .slave_alloc = scsih_slave_alloc_mpt2sas, ++ .slave_configure = scsih_slave_configure_mpt2sas, ++ .target_destroy = scsih_target_destroy_mpt2sas, ++ .slave_destroy = scsih_slave_destroy_mpt2sas, ++ .scan_finished = scsih_scan_finished_mpt2sas, ++ .scan_start = scsih_scan_start_mpt2sas, ++ .change_queue_depth = scsih_change_queue_depth_mpt2sas, ++ .change_queue_type = _scsih_change_queue_type_mpt2sas, ++ .eh_abort_handler = scsih_abort_mpt2sas, ++ .eh_device_reset_handler = scsih_dev_reset_mpt2sas, ++ .eh_target_reset_handler = scsih_target_reset_mpt2sas, ++ .eh_host_reset_handler = scsih_host_reset_mpt2sas, ++ .bios_param = scsih_bios_param_mpt2sas, ++ .can_queue = 1, ++ .this_id = -1, ++ .sg_tablesize = MPT2SAS_SG_DEPTH, ++ .max_sectors = 32767, ++ .cmd_per_lun = 7, ++ .use_clustering = ENABLE_CLUSTERING, ++ .shost_attrs = mpt2sas_host_attrs, ++ .sdev_attrs = mpt2sas_dev_attrs, ++}; ++ ++#ifdef MPT2SAS_SCSI ++/* raid transport support for SAS 2.0 HBA devices */ ++static struct raid_function_template mpt2sas_raid_functions = { ++ .cookie = &mpt2sas_driver_template_mpt2sas, ++ .is_raid = scsih_is_raid_mpt2sas, ++ .get_resync = scsih_get_resync_mpt2sas, ++ .get_state = scsih_get_state_mpt2sas, ++}; ++#endif /* MPT2SAS_SCSI */ ++ ++/* shost template for SAS 3.0 HBA devices */ ++static struct scsi_host_template mpt3sas_driver_template_mpt2sas = { ++ .module = THIS_MODULE, ++ .name = "Fusion MPT SAS Host", ++ .proc_name = MPT3SAS_DRIVER_NAME, ++ .queuecommand = scsih_qcmd_mpt2sas, ++ .target_alloc = scsih_target_alloc_mpt2sas, ++ .slave_alloc = scsih_slave_alloc_mpt2sas, ++ .slave_configure = scsih_slave_configure_mpt2sas, ++ .target_destroy = scsih_target_destroy_mpt2sas, ++ .slave_destroy = scsih_slave_destroy_mpt2sas, ++ .scan_finished = scsih_scan_finished_mpt2sas, ++ .scan_start = scsih_scan_start_mpt2sas, ++ .change_queue_depth = scsih_change_queue_depth_mpt2sas, ++ .change_queue_type = _scsih_change_queue_type_mpt2sas, ++ .eh_abort_handler = scsih_abort_mpt2sas, ++ .eh_device_reset_handler = scsih_dev_reset_mpt2sas, ++ .eh_target_reset_handler = scsih_target_reset_mpt2sas, ++ .eh_host_reset_handler = scsih_host_reset_mpt2sas, ++ .bios_param = scsih_bios_param_mpt2sas, ++ .can_queue = 1, ++ .this_id = -1, ++ .sg_tablesize = MPT3SAS_SG_DEPTH, ++ .max_sectors = 32767, ++ .cmd_per_lun = 7, ++ .use_clustering = ENABLE_CLUSTERING, ++ .shost_attrs = mpt2sas_host_attrs, ++ .sdev_attrs = mpt2sas_dev_attrs, ++}; ++ ++#ifndef MPT2SAS_SCSI ++/* raid transport support for SAS 3.0 HBA devices */ ++static struct raid_function_template mpt3sas_raid_functions = { ++ .cookie = &mpt3sas_driver_template_mpt2sas, ++ .is_raid = scsih_is_raid_mpt2sas, ++ .get_resync = scsih_get_resync_mpt2sas, ++ .get_state = scsih_get_state_mpt2sas, ++}; ++#endif /* MPT2SAS_SCSI */ ++ ++/** ++ * _scsih_determine_hba_mpi_version_mpt2sas - determine in which MPI version class ++ * this device belongs to. ++ * @pdev: PCI device struct ++ * ++ * return MPI2_VERSION for SAS 2.0 HBA devices, ++ * MPI25_VERSION for SAS 3.0 HBA devices, and ++ * MPI26 VERSION for Cutlass & Invader SAS 3.0 HBA devices ++ */ ++u16 ++_scsih_determine_hba_mpi_version_mpt2sas(struct pci_dev *pdev) ++{ ++ ++ switch (pdev->device) { ++ case MPI2_MFGPAGE_DEVID_SSS6200: ++ case MPI2_MFGPAGE_DEVID_SAS2004: ++ case MPI2_MFGPAGE_DEVID_SAS2008: ++ case MPI2_MFGPAGE_DEVID_SAS2108_1: ++ case MPI2_MFGPAGE_DEVID_SAS2108_2: ++ case MPI2_MFGPAGE_DEVID_SAS2108_3: ++ case MPI2_MFGPAGE_DEVID_SAS2116_1: ++ case MPI2_MFGPAGE_DEVID_SAS2116_2: ++ case MPI2_MFGPAGE_DEVID_SAS2208_1: ++ case MPI2_MFGPAGE_DEVID_SAS2208_2: ++ case MPI2_MFGPAGE_DEVID_SAS2208_3: ++ case MPI2_MFGPAGE_DEVID_SAS2208_4: ++ case MPI2_MFGPAGE_DEVID_SAS2208_5: ++ case MPI2_MFGPAGE_DEVID_SAS2208_6: ++ case MPI2_MFGPAGE_DEVID_SAS2308_1: ++ case MPI2_MFGPAGE_DEVID_SAS2308_2: ++ case MPI2_MFGPAGE_DEVID_SAS2308_3: ++ return MPI2_VERSION; ++ case MPI25_MFGPAGE_DEVID_SAS3004: ++ case MPI25_MFGPAGE_DEVID_SAS3008: ++ case MPI25_MFGPAGE_DEVID_SAS3108_1: ++ case MPI25_MFGPAGE_DEVID_SAS3108_2: ++ case MPI25_MFGPAGE_DEVID_SAS3108_5: ++ case MPI25_MFGPAGE_DEVID_SAS3108_6: ++ return MPI25_VERSION; ++ case MPI26_MFGPAGE_DEVID_SAS3216: ++ case MPI26_MFGPAGE_DEVID_SAS3224: ++ case MPI26_MFGPAGE_DEVID_SAS3316_1: ++ case MPI26_MFGPAGE_DEVID_SAS3316_2: ++ case MPI26_MFGPAGE_DEVID_SAS3316_3: ++ case MPI26_MFGPAGE_DEVID_SAS3316_4: ++ case MPI26_MFGPAGE_DEVID_SAS3324_1: ++ case MPI26_MFGPAGE_DEVID_SAS3324_2: ++ case MPI26_MFGPAGE_DEVID_SAS3324_3: ++ case MPI26_MFGPAGE_DEVID_SAS3324_4: ++ return MPI26_VERSION; ++ } ++ return 0; ++} ++ ++/** ++ * _scsih_probe_mpt2sas - attach and add scsi host ++ * @pdev: PCI device struct ++ * @id: pci device id ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++_scsih_probe_mpt2sas(struct pci_dev *pdev, const struct pci_device_id *id) ++{ ++ struct MPT3SAS_ADAPTER *ioc; ++ struct Scsi_Host *shost = NULL; ++ int rv; ++ u16 hba_mpi_version; ++ ++ /* Determine in which MPI version class this pci device belongs */ ++ hba_mpi_version = _scsih_determine_hba_mpi_version_mpt2sas(pdev); ++ if (hba_mpi_version == 0) ++ return -ENODEV; ++ ++ switch (hba_mpi_version) { ++ case MPI2_VERSION: ++ /* Use mpt2sas driver host template for SAS 2.0 HBA's */ ++ shost = scsi_host_alloc(&mpt2sas_driver_template_mpt2sas, ++ sizeof(struct MPT3SAS_ADAPTER)); ++ if (!shost) ++ return -ENODEV; ++ ioc = shost_priv(shost); ++ memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); ++ ioc->hba_mpi_version_belonged = hba_mpi_version; ++ ioc->id = mpt2_ids++; ++ sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME); ++ if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) { ++ ioc->is_warpdrive = 1; ++ ioc->hide_ir_msg = 1; ++ } else ++ ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; ++ break; ++ case MPI25_VERSION: ++ case MPI26_VERSION: ++ /* Use mpt3sas driver host template for SAS 3.0 HBA's */ ++ shost = scsi_host_alloc(&mpt3sas_driver_template_mpt2sas, ++ sizeof(struct MPT3SAS_ADAPTER)); ++ if (!shost) ++ return -ENODEV; ++ ioc = shost_priv(shost); ++ memset(ioc, 0, sizeof(struct MPT3SAS_ADAPTER)); ++ ioc->hba_mpi_version_belonged = hba_mpi_version; ++ ioc->id = mpt3_ids++; ++ sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME); ++ if ((ioc->hba_mpi_version_belonged == MPI25_VERSION && ++ pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) || ++ (ioc->hba_mpi_version_belonged == MPI26_VERSION)) ++ ioc->msix96_vector = 1; ++ break; ++ default: ++ return -ENODEV; ++ } ++ ++ INIT_LIST_HEAD(&ioc->list); ++ spin_lock(&gioc_lock_mpt2sas); ++ list_add_tail(&ioc->list, &mpt2sas_ioc_list); ++ spin_unlock(&gioc_lock_mpt2sas); ++ ioc->shost = shost; ++ ioc->pdev = pdev; ++ ioc->scsi_io_cb_idx = scsi_io_cb_idx; ++ ioc->tm_cb_idx = tm_cb_idx; ++ ioc->ctl_cb_idx = ctl_cb_idx; ++ ioc->base_cb_idx = base_cb_idx; ++ ioc->port_enable_cb_idx = port_enable_cb_idx; ++ ioc->transport_cb_idx = transport_cb_idx; ++ ioc->scsih_cb_idx = scsih_cb_idx; ++ ioc->config_cb_idx = config_cb_idx; ++ ioc->tm_tr_cb_idx = tm_tr_cb_idx; ++ ioc->tm_tr_volume_cb_idx = tm_tr_volume_cb_idx; ++ ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; ++ ioc->logging_level = logging_level; ++ ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; ++ /* misc semaphores and spin locks */ ++ mutex_init(&ioc->reset_in_progress_mutex); ++ /* initializing pci_access_mutex lock */ ++ mutex_init(&ioc->pci_access_mutex); ++ spin_lock_init(&ioc->ioc_reset_in_progress_lock); ++ spin_lock_init(&ioc->scsi_lookup_lock); ++ spin_lock_init(&ioc->sas_device_lock); ++ spin_lock_init(&ioc->sas_node_lock); ++ spin_lock_init(&ioc->fw_event_lock); ++ spin_lock_init(&ioc->raid_device_lock); ++ spin_lock_init(&ioc->diag_trigger_lock); ++ ++ INIT_LIST_HEAD(&ioc->sas_device_list); ++ INIT_LIST_HEAD(&ioc->sas_device_init_list); ++ INIT_LIST_HEAD(&ioc->sas_expander_list); ++ INIT_LIST_HEAD(&ioc->fw_event_list); ++ INIT_LIST_HEAD(&ioc->raid_device_list); ++ INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); ++ INIT_LIST_HEAD(&ioc->delayed_tr_list); ++ INIT_LIST_HEAD(&ioc->delayed_sc_list); ++ INIT_LIST_HEAD(&ioc->delayed_event_ack_list); ++ INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); ++ INIT_LIST_HEAD(&ioc->reply_queue_list); ++ ++ sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id); ++ ++ /* init shost parameters */ ++ shost->max_cmd_len = 32; ++ shost->max_lun = max_lun; ++ shost->transportt = mpt2sas_transport_template; ++ shost->unique_id = ioc->id; ++ ++ if (max_sectors != 0xFFFF) { ++ if (max_sectors < 64) { ++ shost->max_sectors = 64; ++ pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ ++ "for max_sectors, range is 64 to 32767. Assigning " ++ "value of 64.\n", ioc->name, max_sectors); ++ } else if (max_sectors > 32767) { ++ shost->max_sectors = 32767; ++ pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ ++ "for max_sectors, range is 64 to 32767. Assigning " ++ "default value of 32767.\n", ioc->name, ++ max_sectors); ++ } else { ++ shost->max_sectors = max_sectors & 0xFFFE; ++ pr_info(MPT3SAS_FMT ++ "The max_sectors value is set to %d\n", ++ ioc->name, shost->max_sectors); ++ } ++ } ++ ++ /* register EEDP capabilities with SCSI layer */ ++ if (prot_mask > 0) ++ scsi_host_set_prot(shost, prot_mask); ++ else ++ scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION ++ | SHOST_DIF_TYPE2_PROTECTION ++ | SHOST_DIF_TYPE3_PROTECTION); ++ ++ scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC); ++ ++ /* event thread */ ++ snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), ++ "fw_event_%s%d", ioc->driver_name, ioc->id); ++ ioc->firmware_event_thread = alloc_ordered_workqueue( ++ ioc->firmware_event_name, WQ_MEM_RECLAIM); ++ if (!ioc->firmware_event_thread) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rv = -ENODEV; ++ goto out_thread_fail; ++ } ++ ++ ioc->is_driver_loading = 1; ++ if ((mpt2sas_base_attach(ioc))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rv = -ENODEV; ++ goto out_attach_fail; ++ } ++ ++ if (ioc->is_warpdrive) { ++ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) ++ ioc->hide_drives = 0; ++ else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS) ++ ioc->hide_drives = 1; ++ else { ++ if (mpt2sas_get_num_volumes(ioc)) ++ ioc->hide_drives = 1; ++ else ++ ioc->hide_drives = 0; ++ } ++ } else ++ ioc->hide_drives = 0; ++ ++ rv = scsi_add_host(shost, &pdev->dev); ++ if (rv) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_add_shost_fail; ++ } ++ ++ scsi_scan_host(shost); ++ return 0; ++out_add_shost_fail: ++ mpt2sas_base_detach(ioc); ++ out_attach_fail: ++ destroy_workqueue(ioc->firmware_event_thread); ++ out_thread_fail: ++ spin_lock(&gioc_lock_mpt2sas); ++ list_del(&ioc->list); ++ spin_unlock(&gioc_lock_mpt2sas); ++ scsi_host_put(shost); ++ return rv; ++} ++ ++#ifdef CONFIG_PM ++/** ++ * scsih_suspend_mpt2sas - power management suspend main entry point ++ * @pdev: PCI device struct ++ * @state: PM state change to (usually PCI_D3) ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++scsih_suspend_mpt2sas(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ pci_power_t device_state; ++ ++ mpt2sas_base_stop_watchdog(ioc); ++ flush_scheduled_work(); ++ scsi_block_requests(shost); ++ device_state = pci_choose_state(pdev, state); ++ pr_info(MPT3SAS_FMT ++ "pdev=0x%p, slot=%s, entering operating state [D%d]\n", ++ ioc->name, pdev, pci_name(pdev), device_state); ++ ++ pci_save_state(pdev); ++ mpt2sas_base_free_resources(ioc); ++ pci_set_power_state(pdev, device_state); ++ return 0; ++} ++ ++/** ++ * scsih_resume_mpt2sas - power management resume main entry point ++ * @pdev: PCI device struct ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++scsih_resume_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ pci_power_t device_state = pdev->current_state; ++ int r; ++ ++ pr_info(MPT3SAS_FMT ++ "pdev=0x%p, slot=%s, previous operating state [D%d]\n", ++ ioc->name, pdev, pci_name(pdev), device_state); ++ ++ pci_set_power_state(pdev, PCI_D0); ++ pci_enable_wake(pdev, PCI_D0, 0); ++ pci_restore_state(pdev); ++ ioc->pdev = pdev; ++ r = mpt2sas_base_map_resources(ioc); ++ if (r) ++ return r; ++ ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET); ++ scsi_unblock_requests(shost); ++ mpt2sas_base_start_watchdog(ioc); ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++/** ++ * scsih_pci_error_detected_mpt2sas - Called when a PCI error is detected. ++ * @pdev: PCI device struct ++ * @state: PCI channel state ++ * ++ * Description: Called when a PCI error is detected. ++ * ++ * Return value: ++ * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT ++ */ ++pci_ers_result_t ++scsih_pci_error_detected_mpt2sas(struct pci_dev *pdev, pci_channel_state_t state) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ pr_info(MPT3SAS_FMT "PCI error: detected callback, state(%d)!!\n", ++ ioc->name, state); ++ ++ switch (state) { ++ case pci_channel_io_normal: ++ return PCI_ERS_RESULT_CAN_RECOVER; ++ case pci_channel_io_frozen: ++ /* Fatal error, prepare for slot reset */ ++ ioc->pci_error_recovery = 1; ++ scsi_block_requests(ioc->shost); ++ mpt2sas_base_stop_watchdog(ioc); ++ mpt2sas_base_free_resources(ioc); ++ return PCI_ERS_RESULT_NEED_RESET; ++ case pci_channel_io_perm_failure: ++ /* Permanent error, prepare for device removal */ ++ ioc->pci_error_recovery = 1; ++ mpt2sas_base_stop_watchdog(ioc); ++ _scsih_flush_running_cmds(ioc); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ return PCI_ERS_RESULT_NEED_RESET; ++} ++ ++/** ++ * scsih_pci_slot_reset_mpt2sas - Called when PCI slot has been reset. ++ * @pdev: PCI device struct ++ * ++ * Description: This routine is called by the pci error recovery ++ * code after the PCI slot has been reset, just before we ++ * should resume normal operations. ++ */ ++pci_ers_result_t ++scsih_pci_slot_reset_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ int rc; ++ ++ pr_info(MPT3SAS_FMT "PCI error: slot reset callback!!\n", ++ ioc->name); ++ ++ ioc->pci_error_recovery = 0; ++ ioc->pdev = pdev; ++ pci_restore_state(pdev); ++ rc = mpt2sas_base_map_resources(ioc); ++ if (rc) ++ return PCI_ERS_RESULT_DISCONNECT; ++ ++ rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ ++ pr_warn(MPT3SAS_FMT "hard reset: %s\n", ioc->name, ++ (rc == 0) ? "success" : "failed"); ++ ++ if (!rc) ++ return PCI_ERS_RESULT_RECOVERED; ++ else ++ return PCI_ERS_RESULT_DISCONNECT; ++} ++ ++/** ++ * scsih_pci_resume_mpt2sas() - resume normal ops after PCI reset ++ * @pdev: pointer to PCI device ++ * ++ * Called when the error recovery driver tells us that its ++ * OK to resume normal operation. Use completion to allow ++ * halted scsi ops to resume. ++ */ ++void ++scsih_pci_resume_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ pr_info(MPT3SAS_FMT "PCI error: resume callback!!\n", ioc->name); ++ ++ pci_cleanup_aer_uncorrect_error_status(pdev); ++ mpt2sas_base_start_watchdog(ioc); ++ scsi_unblock_requests(ioc->shost); ++} ++ ++/** ++ * scsih_pci_mmio_enabled_mpt2sas - Enable MMIO and dump debug registers ++ * @pdev: pointer to PCI device ++ */ ++pci_ers_result_t ++scsih_pci_mmio_enabled_mpt2sas(struct pci_dev *pdev) ++{ ++ struct Scsi_Host *shost = pci_get_drvdata(pdev); ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ ++ pr_info(MPT3SAS_FMT "PCI error: mmio enabled callback!!\n", ++ ioc->name); ++ ++ /* TODO - dump whatever for debugging purposes */ ++ ++ /* This called only if scsih_pci_error_detected_mpt2sas returns ++ * PCI_ERS_RESULT_CAN_RECOVER. Read/write to the device still ++ * works, no need to reset slot. ++ */ ++ return PCI_ERS_RESULT_RECOVERED; ++} ++ ++/* ++ * The pci device ids are defined in mpi/mpi2_cnfg.h. ++ */ ++static const struct pci_device_id mpt2sas_pci_table[] = { ++#ifdef MPT2SAS_SCSI ++ /* Spitfire ~ 2004 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Falcon ~ 2008 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Liberator ~ 2108 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Meteor ~ 2116 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Thunderbolt ~ 2208 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Mustang ~ 2308 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* SSS6200 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, ++ PCI_ANY_ID, PCI_ANY_ID }, ++#else ++ /* Fury ~ 3004 and 3008 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Invader ~ 3108 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Cutlass ~ 3216 and 3224 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ /* Intruder ~ 3316 and 3324 */ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_4, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_3, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_4, ++ PCI_ANY_ID, PCI_ANY_ID }, ++#endif /* MPT2SAS_SCSI */ ++ {0} /* Terminating entry */ ++}; ++MODULE_DEVICE_TABLE(pci, mpt2sas_pci_table); ++ ++static struct pci_error_handlers _mpt2sas_err_handler = { ++ .error_detected = scsih_pci_error_detected_mpt2sas, ++ .mmio_enabled = scsih_pci_mmio_enabled_mpt2sas, ++ .slot_reset = scsih_pci_slot_reset_mpt2sas, ++ .resume = scsih_pci_resume_mpt2sas, ++}; ++ ++static struct pci_driver mpt3sas_driver = { ++#ifdef MPT2SAS_SCSI ++ .name = MPT2SAS_DRIVER_NAME, ++#else ++ .name = MPT3SAS_DRIVER_NAME, ++#endif /* MPT2SAS_SCSI */ ++ .id_table = mpt2sas_pci_table, ++ .probe = _scsih_probe_mpt2sas, ++ .remove = scsih_remove_mpt2sas, ++ .shutdown = scsih_shutdown_mpt2sas, ++ .err_handler = &_mpt2sas_err_handler, ++#ifdef CONFIG_PM ++ .suspend = scsih_suspend_mpt2sas, ++ .resume = scsih_resume_mpt2sas, ++#endif ++}; ++ ++/** ++ * scsih_init_mpt2sas - main entry point for this driver. ++ * ++ * Returns 0 success, anything else error. ++ */ ++int ++scsih_init_mpt2sas(void) ++{ ++ mpt2_ids = 0; ++ mpt3_ids = 0; ++ ++ mpt2sas_base_initialize_callback_handler(); ++ ++ /* queuecommand callback hander */ ++ scsi_io_cb_idx = mpt2sas_base_register_callback_handler(_scsih_io_done); ++ ++ /* task managment callback handler */ ++ tm_cb_idx = mpt2sas_base_register_callback_handler(_scsih_tm_done); ++ ++ /* base internal commands callback handler */ ++ base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done); ++ port_enable_cb_idx = mpt2sas_base_register_callback_handler( ++ mpt2sas_port_enable_done); ++ ++ /* transport internal commands callback handler */ ++ transport_cb_idx = mpt2sas_base_register_callback_handler( ++ mpt2sas_transport_done); ++ ++ /* scsih internal commands callback handler */ ++ scsih_cb_idx = mpt2sas_base_register_callback_handler(_scsih_done); ++ ++ /* configuration page API internal commands callback handler */ ++ config_cb_idx = mpt2sas_base_register_callback_handler( ++ mpt2sas_config_done); ++ ++ /* ctl module callback handler */ ++ ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); ++ ++ tm_tr_cb_idx = mpt2sas_base_register_callback_handler( ++ _scsih_tm_tr_complete); ++ ++ tm_tr_volume_cb_idx = mpt2sas_base_register_callback_handler( ++ _scsih_tm_volume_tr_complete); ++ ++ tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler( ++ _scsih_sas_control_complete); ++ ++ return 0; ++} ++ ++/** ++ * scsih_exit_mpt2sas - exit point for this driver (when it is a module). ++ * ++ * Returns 0 success, anything else error. ++ */ ++void ++scsih_exit_mpt2sas(void) ++{ ++ ++ mpt2sas_base_release_callback_handler(scsi_io_cb_idx); ++ mpt2sas_base_release_callback_handler(tm_cb_idx); ++ mpt2sas_base_release_callback_handler(base_cb_idx); ++ mpt2sas_base_release_callback_handler(port_enable_cb_idx); ++ mpt2sas_base_release_callback_handler(transport_cb_idx); ++ mpt2sas_base_release_callback_handler(scsih_cb_idx); ++ mpt2sas_base_release_callback_handler(config_cb_idx); ++ mpt2sas_base_release_callback_handler(ctl_cb_idx); ++ ++ mpt2sas_base_release_callback_handler(tm_tr_cb_idx); ++ mpt2sas_base_release_callback_handler(tm_tr_volume_cb_idx); ++ mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); ++ ++/* raid transport support */ ++#ifdef MPT2SAS_SCSI ++ raid_class_release(mpt2sas_raid_template_mpt2sas); ++#else ++ raid_class_release(mpt3sas_raid_template_mpt2sas); ++#endif /* MPT2SAS_SCSI */ ++ sas_release_transport(mpt2sas_transport_template); ++} ++ ++/** ++ * _mpt2sas_init - main entry point for this driver. ++ * ++ * Returns 0 success, anything else error. ++ */ ++static int __init ++_mpt2sas_init(void) ++{ ++ int error; ++ ++#ifdef MPT2SAS_SCSI ++ pr_info("%s version %s loaded\n", MPT2SAS_DRIVER_NAME, ++ MPT2SAS_DRIVER_VERSION); ++#else ++ pr_info("%s version %s loaded\n", MPT3SAS_DRIVER_NAME, ++ MPT3SAS_DRIVER_VERSION); ++#endif /* MPT2SAS_SCSI */ ++ ++ mpt2sas_transport_template = ++ sas_attach_transport(&mpt2sas_transport_functions); ++ if (!mpt2sas_transport_template) ++ return -ENODEV; ++ ++#ifdef MPT2SAS_SCSI ++ mpt2sas_raid_template_mpt2sas = raid_class_attach(&mpt2sas_raid_functions); ++ if (!mpt2sas_raid_template_mpt2sas) { ++ sas_release_transport(mpt2sas_transport_template); ++ return -ENODEV; ++ } ++#else ++ mpt3sas_raid_template_mpt2sas = raid_class_attach(&mpt3sas_raid_functions); ++ if (!mpt3sas_raid_template_mpt2sas) { ++ sas_release_transport(mpt2sas_transport_template); ++ return -ENODEV; ++ } ++#endif /* MPT2SAS_SCSI */ ++ ++ error = scsih_init_mpt2sas(); ++ if (error) { ++ scsih_exit_mpt2sas(); ++ return error; ++ } ++ ++ ++#ifdef MPT2SAS_SCSI ++ mpt2sas_ctl_init(1); ++#else ++ mpt2sas_ctl_init(2); ++#endif /* MPT2SAS_SCSI */ ++ ++ error = pci_register_driver(&mpt3sas_driver); ++ if (error) ++ scsih_exit_mpt2sas(); ++ ++ return error; ++} ++ ++/** ++ * _mpt2sas_exit - exit point for this driver (when it is a module). ++ * ++ */ ++static void __exit ++_mpt2sas_exit(void) ++{ ++ pr_info("mpt3sas version %s unloading\n", ++ MPT3SAS_DRIVER_VERSION); ++ ++ pci_unregister_driver(&mpt3sas_driver); ++ ++#ifdef MPT2SAS_SCSI ++ mpt2sas_ctl_exit(1); ++#else ++ mpt2sas_ctl_exit(2); ++#endif /* MPT2SAS_SCSI */ ++ ++ scsih_exit_mpt2sas(); ++} ++ ++module_init(_mpt2sas_init); ++module_exit(_mpt2sas_exit); +diff --git a/drivers/scsi/mpt2sas/mpt3sas_transport.c b/drivers/scsi/mpt2sas/mpt3sas_transport.c +new file mode 100644 +index 0000000..690afa5 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_transport.c +@@ -0,0 +1,2138 @@ ++/* ++ * SAS Transport Layer for MPT (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/** ++ * _transport_sas_node_find_by_sas_address - sas node search ++ * @ioc: per adapter object ++ * @sas_address: sas address of expander or sas host ++ * Context: Calling function should acquire ioc->sas_node_lock. ++ * ++ * Search for either hba phys or expander device based on handle, then returns ++ * the sas_node object. ++ */ ++static struct _sas_node * ++_transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address) ++{ ++ if (ioc->sas_hba.sas_address == sas_address) ++ return &ioc->sas_hba; ++ else ++ return mpt2sas_scsih_expander_find_by_sas_address(ioc, ++ sas_address); ++} ++ ++/** ++ * _transport_convert_phy_link_rate - ++ * @link_rate: link rate returned from mpt firmware ++ * ++ * Convert link_rate from mpi fusion into sas_transport form. ++ */ ++static enum sas_linkrate ++_transport_convert_phy_link_rate(u8 link_rate) ++{ ++ enum sas_linkrate rc; ++ ++ switch (link_rate) { ++ case MPI2_SAS_NEG_LINK_RATE_1_5: ++ rc = SAS_LINK_RATE_1_5_GBPS; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_3_0: ++ rc = SAS_LINK_RATE_3_0_GBPS; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_6_0: ++ rc = SAS_LINK_RATE_6_0_GBPS; ++ break; ++ case MPI25_SAS_NEG_LINK_RATE_12_0: ++ rc = SAS_LINK_RATE_12_0_GBPS; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED: ++ rc = SAS_PHY_DISABLED; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED: ++ rc = SAS_LINK_RATE_FAILED; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR: ++ rc = SAS_SATA_PORT_SELECTOR; ++ break; ++ case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS: ++ rc = SAS_PHY_RESET_IN_PROGRESS; ++ break; ++ ++ default: ++ case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE: ++ case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE: ++ rc = SAS_LINK_RATE_UNKNOWN; ++ break; ++ } ++ return rc; ++} ++ ++/** ++ * _transport_set_identify - set identify for phys and end devices ++ * @ioc: per adapter object ++ * @handle: device handle ++ * @identify: sas identify info ++ * ++ * Populates sas identify info. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_set_identify(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ struct sas_identify *identify) ++{ ++ Mpi2SasDevicePage0_t sas_device_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u32 device_info; ++ u32 ioc_status; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, ++ MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT ++ "handle(0x%04x), ioc_status(0x%04x)\nfailure at %s:%d/%s()!\n", ++ ioc->name, handle, ioc_status, ++ __FILE__, __LINE__, __func__); ++ return -EIO; ++ } ++ ++ memset(identify, 0, sizeof(struct sas_identify)); ++ device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); ++ ++ /* sas_address */ ++ identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress); ++ ++ /* phy number of the parent device this device is linked to */ ++ identify->phy_identifier = sas_device_pg0.PhyNum; ++ ++ /* device_type */ ++ switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) { ++ case MPI2_SAS_DEVICE_INFO_NO_DEVICE: ++ identify->device_type = SAS_PHY_UNUSED; ++ break; ++ case MPI2_SAS_DEVICE_INFO_END_DEVICE: ++ identify->device_type = SAS_END_DEVICE; ++ break; ++ case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER: ++ identify->device_type = SAS_EDGE_EXPANDER_DEVICE; ++ break; ++ case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER: ++ identify->device_type = SAS_FANOUT_EXPANDER_DEVICE; ++ break; ++ } ++ ++ /* initiator_port_protocols */ ++ if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_STP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST) ++ identify->initiator_port_protocols |= SAS_PROTOCOL_SATA; ++ ++ /* target_port_protocols */ ++ if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) ++ identify->target_port_protocols |= SAS_PROTOCOL_SSP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) ++ identify->target_port_protocols |= SAS_PROTOCOL_STP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) ++ identify->target_port_protocols |= SAS_PROTOCOL_SMP; ++ if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) ++ identify->target_port_protocols |= SAS_PROTOCOL_SATA; ++ ++ return 0; ++} ++ ++/** ++ * mpt2sas_transport_done - internal transport layer callback handler. ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_index: MSIX table index supplied by the OS ++ * @reply: reply message frame(lower 32bit addr) ++ * ++ * Callback handler when sending internal generated transport cmds. ++ * The callback index passed is `ioc->transport_cb_idx` ++ * ++ * Return 1 meaning mf should be freed from _base_interrupt ++ * 0 means the mf is freed from this function. ++ */ ++u8 ++mpt2sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ++ u32 reply) ++{ ++ MPI2DefaultReply_t *mpi_reply; ++ ++ mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); ++ if (ioc->transport_cmds.status == MPT3_CMD_NOT_USED) ++ return 1; ++ if (ioc->transport_cmds.smid != smid) ++ return 1; ++ ioc->transport_cmds.status |= MPT3_CMD_COMPLETE; ++ if (mpi_reply) { ++ memcpy(ioc->transport_cmds.reply, mpi_reply, ++ mpi_reply->MsgLength*4); ++ ioc->transport_cmds.status |= MPT3_CMD_REPLY_VALID; ++ } ++ ioc->transport_cmds.status &= ~MPT3_CMD_PENDING; ++ complete(&ioc->transport_cmds.done); ++ return 1; ++} ++ ++/* report manufacture request structure */ ++struct rep_manu_request { ++ u8 smp_frame_type; ++ u8 function; ++ u8 reserved; ++ u8 request_length; ++}; ++ ++/* report manufacture reply structure */ ++struct rep_manu_reply { ++ u8 smp_frame_type; /* 0x41 */ ++ u8 function; /* 0x01 */ ++ u8 function_result; ++ u8 response_length; ++ u16 expander_change_count; ++ u8 reserved0[2]; ++ u8 sas_format; ++ u8 reserved2[3]; ++ u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; ++ u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; ++ u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN]; ++ u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN]; ++ u16 component_id; ++ u8 component_revision_id; ++ u8 reserved3; ++ u8 vendor_specific[8]; ++}; ++ ++/** ++ * transport_expander_report_manufacture - obtain SMP report_manufacture ++ * @ioc: per adapter object ++ * @sas_address: expander sas address ++ * @edev: the sas_expander_device object ++ * ++ * Fills in the sas_expander_device object when SMP port is created. ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address, struct sas_expander_device *edev) ++{ ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ struct rep_manu_reply *manufacture_reply; ++ struct rep_manu_request *manufacture_request; ++ int rc; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma; ++ dma_addr_t data_in_dma; ++ size_t data_in_sz; ++ size_t data_out_sz; ++ u16 wait_state_count; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&ioc->transport_cmds.mutex); ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ rc = 0; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ data_out_sz = sizeof(struct rep_manu_request); ++ data_in_sz = sizeof(struct rep_manu_reply); ++ data_out = pci_alloc_consistent(ioc->pdev, data_out_sz + data_in_sz, ++ &data_out_dma); ++ ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ rc = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ ++ data_in_dma = data_out_dma + sizeof(struct rep_manu_request); ++ ++ manufacture_request = data_out; ++ manufacture_request->smp_frame_type = 0x40; ++ manufacture_request->function = 1; ++ manufacture_request->reserved = 0; ++ manufacture_request->request_length = 0; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->SASAddress = cpu_to_le64(sas_address); ++ mpi_request->RequestDataLength = cpu_to_le16(data_out_sz); ++ psge = &mpi_request->SGL; ++ ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - send to sas_addr(0x%016llx)\n", ++ ioc->name, (unsigned long long)sas_address)); ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - complete\n", ioc->name)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ u8 *tmp; ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - reply data transfer size(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ if (le16_to_cpu(mpi_reply->ResponseDataLength) != ++ sizeof(struct rep_manu_reply)) ++ goto out; ++ ++ manufacture_reply = data_out + sizeof(struct rep_manu_request); ++ strncpy(edev->vendor_id, manufacture_reply->vendor_id, ++ SAS_EXPANDER_VENDOR_ID_LEN); ++ strncpy(edev->product_id, manufacture_reply->product_id, ++ SAS_EXPANDER_PRODUCT_ID_LEN); ++ strncpy(edev->product_rev, manufacture_reply->product_rev, ++ SAS_EXPANDER_PRODUCT_REV_LEN); ++ edev->level = manufacture_reply->sas_format & 1; ++ if (edev->level) { ++ strncpy(edev->component_vendor_id, ++ manufacture_reply->component_vendor_id, ++ SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); ++ tmp = (u8 *)&manufacture_reply->component_id; ++ edev->component_id = tmp[0] << 8 | tmp[1]; ++ edev->component_revision_id = ++ manufacture_reply->component_revision_id; ++ } ++ } else ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "report_manufacture - no reply\n", ioc->name)); ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ if (data_out) ++ pci_free_consistent(ioc->pdev, data_out_sz + data_in_sz, ++ data_out, data_out_dma); ++ ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++ ++/** ++ * _transport_delete_port - helper function to removing a port ++ * @ioc: per adapter object ++ * @mpt2sas_port: mpt3sas per port object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_delete_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_port *mpt2sas_port) ++{ ++ u64 sas_address = mpt2sas_port->remote_identify.sas_address; ++ enum sas_device_type device_type = ++ mpt2sas_port->remote_identify.device_type; ++ ++ dev_printk(KERN_INFO, &mpt2sas_port->port->dev, ++ "remove: sas_addr(0x%016llx)\n", ++ (unsigned long long) sas_address); ++ ++ ioc->logging_level |= MPT_DEBUG_TRANSPORT; ++ if (device_type == SAS_END_DEVICE) ++ mpt2sas_device_remove_by_sas_address(ioc, sas_address); ++ else if (device_type == SAS_EDGE_EXPANDER_DEVICE || ++ device_type == SAS_FANOUT_EXPANDER_DEVICE) ++ mpt2sas_expander_remove(ioc, sas_address); ++ ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; ++} ++ ++/** ++ * _transport_delete_phy - helper function to removing single phy from port ++ * @ioc: per adapter object ++ * @mpt2sas_port: mpt3sas per port object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_delete_phy(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy) ++{ ++ u64 sas_address = mpt2sas_port->remote_identify.sas_address; ++ ++ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, ++ "remove: sas_addr(0x%016llx), phy(%d)\n", ++ (unsigned long long) sas_address, mpt2sas_phy->phy_id); ++ ++ list_del(&mpt2sas_phy->port_siblings); ++ mpt2sas_port->num_phys--; ++ sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); ++ mpt2sas_phy->phy_belongs_to_port = 0; ++} ++ ++/** ++ * _transport_add_phy - helper function to adding single phy to port ++ * @ioc: per adapter object ++ * @mpt2sas_port: mpt3sas per port object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_add_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port, ++ struct _sas_phy *mpt2sas_phy) ++{ ++ u64 sas_address = mpt2sas_port->remote_identify.sas_address; ++ ++ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, ++ "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long) ++ sas_address, mpt2sas_phy->phy_id); ++ ++ list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list); ++ mpt2sas_port->num_phys++; ++ sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy); ++ mpt2sas_phy->phy_belongs_to_port = 1; ++} ++ ++/** ++ * _transport_add_phy_to_an_existing_port - adding new phy to existing port ++ * @ioc: per adapter object ++ * @sas_node: sas node object (either expander or sas host) ++ * @mpt2sas_phy: mpt3sas per phy object ++ * @sas_address: sas address of device/expander were phy needs to be added to ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, ++ u64 sas_address) ++{ ++ struct _sas_port *mpt2sas_port; ++ struct _sas_phy *phy_srch; ++ ++ if (mpt2sas_phy->phy_belongs_to_port == 1) ++ return; ++ ++ list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, ++ port_list) { ++ if (mpt2sas_port->remote_identify.sas_address != ++ sas_address) ++ continue; ++ list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, ++ port_siblings) { ++ if (phy_srch == mpt2sas_phy) ++ return; ++ } ++ _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy); ++ return; ++ } ++ ++} ++ ++/** ++ * _transport_del_phy_from_an_existing_port - delete phy from existing port ++ * @ioc: per adapter object ++ * @sas_node: sas node object (either expander or sas host) ++ * @mpt2sas_phy: mpt3sas per phy object ++ * ++ * Returns nothing. ++ */ ++static void ++_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, ++ struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy) ++{ ++ struct _sas_port *mpt2sas_port, *next; ++ struct _sas_phy *phy_srch; ++ ++ if (mpt2sas_phy->phy_belongs_to_port == 0) ++ return; ++ ++ list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, ++ port_list) { ++ list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, ++ port_siblings) { ++ if (phy_srch != mpt2sas_phy) ++ continue; ++ ++ if (mpt2sas_port->num_phys == 1) ++ _transport_delete_port(ioc, mpt2sas_port); ++ else ++ _transport_delete_phy(ioc, mpt2sas_port, ++ mpt2sas_phy); ++ return; ++ } ++ } ++} ++ ++/** ++ * _transport_sanity_check - sanity check when adding a new port ++ * @ioc: per adapter object ++ * @sas_node: sas node object (either expander or sas host) ++ * @sas_address: sas address of device being added ++ * ++ * See the explanation above from _transport_delete_duplicate_port ++ */ ++static void ++_transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, ++ u64 sas_address) ++{ ++ int i; ++ ++ for (i = 0; i < sas_node->num_phys; i++) { ++ if (sas_node->phy[i].remote_identify.sas_address != sas_address) ++ continue; ++ if (sas_node->phy[i].phy_belongs_to_port == 1) ++ _transport_del_phy_from_an_existing_port(ioc, sas_node, ++ &sas_node->phy[i]); ++ } ++} ++ ++/** ++ * mpt2sas_transport_port_add - insert port to the list ++ * @ioc: per adapter object ++ * @handle: handle of attached device ++ * @sas_address: sas address of parent expander or sas host ++ * Context: This function will acquire ioc->sas_node_lock. ++ * ++ * Adding new port object to the sas_node->sas_port_list. ++ * ++ * Returns mpt2sas_port. ++ */ ++struct _sas_port * ++mpt2sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, ++ u64 sas_address) ++{ ++ struct _sas_phy *mpt2sas_phy, *next; ++ struct _sas_port *mpt2sas_port; ++ unsigned long flags; ++ struct _sas_node *sas_node; ++ struct sas_rphy *rphy; ++ struct _sas_device *sas_device = NULL; ++ int i; ++ struct sas_port *port; ++ ++ mpt2sas_port = kzalloc(sizeof(struct _sas_port), ++ GFP_KERNEL); ++ if (!mpt2sas_port) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return NULL; ++ } ++ ++ INIT_LIST_HEAD(&mpt2sas_port->port_list); ++ INIT_LIST_HEAD(&mpt2sas_port->phy_list); ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (!sas_node) { ++ pr_err(MPT3SAS_FMT ++ "%s: Could not find parent sas_address(0x%016llx)!\n", ++ ioc->name, __func__, (unsigned long long)sas_address); ++ goto out_fail; ++ } ++ ++ if ((_transport_set_identify(ioc, handle, ++ &mpt2sas_port->remote_identify))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ _transport_sanity_check(ioc, sas_node, ++ mpt2sas_port->remote_identify.sas_address); ++ ++ for (i = 0; i < sas_node->num_phys; i++) { ++ if (sas_node->phy[i].remote_identify.sas_address != ++ mpt2sas_port->remote_identify.sas_address) ++ continue; ++ list_add_tail(&sas_node->phy[i].port_siblings, ++ &mpt2sas_port->phy_list); ++ mpt2sas_port->num_phys++; ++ } ++ ++ if (!mpt2sas_port->num_phys) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ port = sas_port_alloc_num(sas_node->parent_dev); ++ if ((sas_port_add(port))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ goto out_fail; ++ } ++ ++ list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list, ++ port_siblings) { ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &port->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx), phy(%d)\n", ++ handle, (unsigned long long) ++ mpt2sas_port->remote_identify.sas_address, ++ mpt2sas_phy->phy_id); ++ sas_port_add_phy(port, mpt2sas_phy->phy); ++ mpt2sas_phy->phy_belongs_to_port = 1; ++ } ++ ++ mpt2sas_port->port = port; ++ if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) ++ rphy = sas_end_device_alloc(port); ++ else ++ rphy = sas_expander_alloc(port, ++ mpt2sas_port->remote_identify.device_type); ++ ++ rphy->identify = mpt2sas_port->remote_identify; ++ ++ if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) { ++ sas_device = mpt2sas_get_sdev_by_addr(ioc, ++ mpt2sas_port->remote_identify.sas_address); ++ if (!sas_device) { ++ dfailprintk(ioc, printk(MPT3SAS_FMT ++ "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__)); ++ goto out_fail; ++ } ++ sas_device->pend_sas_rphy_add = 1; ++ } ++ ++ if ((sas_rphy_add(rphy))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ } ++ ++ if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) { ++ sas_device->pend_sas_rphy_add = 0; ++ sas_device_put(sas_device); ++ } ++ ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &rphy->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx)\n", ++ handle, (unsigned long long) ++ mpt2sas_port->remote_identify.sas_address); ++ mpt2sas_port->rphy = rphy; ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list); ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* fill in report manufacture */ ++ if (mpt2sas_port->remote_identify.device_type == ++ MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || ++ mpt2sas_port->remote_identify.device_type == ++ MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) ++ _transport_expander_report_manufacture(ioc, ++ mpt2sas_port->remote_identify.sas_address, ++ rphy_to_expander_device(rphy)); ++ return mpt2sas_port; ++ ++ out_fail: ++ list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list, ++ port_siblings) ++ list_del(&mpt2sas_phy->port_siblings); ++ kfree(mpt2sas_port); ++ return NULL; ++} ++ ++/** ++ * mpt2sas_transport_port_remove - remove port from the list ++ * @ioc: per adapter object ++ * @sas_address: sas address of attached device ++ * @sas_address_parent: sas address of parent expander or sas host ++ * Context: This function will acquire ioc->sas_node_lock. ++ * ++ * Removing object and freeing associated memory from the ++ * ioc->sas_port_list. ++ * ++ * Return nothing. ++ */ ++void ++mpt2sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, ++ u64 sas_address_parent) ++{ ++ int i; ++ unsigned long flags; ++ struct _sas_port *mpt2sas_port, *next; ++ struct _sas_node *sas_node; ++ u8 found = 0; ++ struct _sas_phy *mpt2sas_phy, *next_phy; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_node = _transport_sas_node_find_by_sas_address(ioc, ++ sas_address_parent); ++ if (!sas_node) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return; ++ } ++ list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, ++ port_list) { ++ if (mpt2sas_port->remote_identify.sas_address != sas_address) ++ continue; ++ found = 1; ++ list_del(&mpt2sas_port->port_list); ++ goto out; ++ } ++ out: ++ if (!found) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return; ++ } ++ ++ for (i = 0; i < sas_node->num_phys; i++) { ++ if (sas_node->phy[i].remote_identify.sas_address == sas_address) ++ memset(&sas_node->phy[i].remote_identify, 0 , ++ sizeof(struct sas_identify)); ++ } ++ ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ list_for_each_entry_safe(mpt2sas_phy, next_phy, ++ &mpt2sas_port->phy_list, port_siblings) { ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &mpt2sas_port->port->dev, ++ "remove: sas_addr(0x%016llx), phy(%d)\n", ++ (unsigned long long) ++ mpt2sas_port->remote_identify.sas_address, ++ mpt2sas_phy->phy_id); ++ mpt2sas_phy->phy_belongs_to_port = 0; ++ sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); ++ list_del(&mpt2sas_phy->port_siblings); ++ } ++ sas_port_delete(mpt2sas_port->port); ++ kfree(mpt2sas_port); ++} ++ ++/** ++ * mpt2sas_transport_add_host_phy - report sas_host phy to transport ++ * @ioc: per adapter object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * @phy_pg0: sas phy page 0 ++ * @parent_dev: parent device class object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy ++ *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev) ++{ ++ struct sas_phy *phy; ++ int phy_index = mpt2sas_phy->phy_id; ++ ++ ++ INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); ++ phy = sas_phy_alloc(parent_dev, phy_index); ++ if (!phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ if ((_transport_set_identify(ioc, mpt2sas_phy->handle, ++ &mpt2sas_phy->identify))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ phy->identify = mpt2sas_phy->identify; ++ mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle); ++ if (mpt2sas_phy->attached_handle) ++ _transport_set_identify(ioc, mpt2sas_phy->attached_handle, ++ &mpt2sas_phy->remote_identify); ++ phy->identify.phy_identifier = mpt2sas_phy->phy_id; ++ phy->negotiated_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); ++ phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( ++ phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( ++ phy_pg0.HwLinkRate >> 4); ++ phy->minimum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate >> 4); ++ ++ if ((sas_phy_add(phy))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &phy->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx)\n" ++ "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", ++ mpt2sas_phy->handle, (unsigned long long) ++ mpt2sas_phy->identify.sas_address, ++ mpt2sas_phy->attached_handle, ++ (unsigned long long) ++ mpt2sas_phy->remote_identify.sas_address); ++ mpt2sas_phy->phy = phy; ++ return 0; ++} ++ ++ ++/** ++ * mpt2sas_transport_add_expander_phy - report expander phy to transport ++ * @ioc: per adapter object ++ * @mpt2sas_phy: mpt3sas per phy object ++ * @expander_pg1: expander page 1 ++ * @parent_dev: parent device class object ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++int ++mpt2sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy ++ *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, ++ struct device *parent_dev) ++{ ++ struct sas_phy *phy; ++ int phy_index = mpt2sas_phy->phy_id; ++ ++ INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); ++ phy = sas_phy_alloc(parent_dev, phy_index); ++ if (!phy) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -1; ++ } ++ if ((_transport_set_identify(ioc, mpt2sas_phy->handle, ++ &mpt2sas_phy->identify))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ phy->identify = mpt2sas_phy->identify; ++ mpt2sas_phy->attached_handle = ++ le16_to_cpu(expander_pg1.AttachedDevHandle); ++ if (mpt2sas_phy->attached_handle) ++ _transport_set_identify(ioc, mpt2sas_phy->attached_handle, ++ &mpt2sas_phy->remote_identify); ++ phy->identify.phy_identifier = mpt2sas_phy->phy_id; ++ phy->negotiated_linkrate = _transport_convert_phy_link_rate( ++ expander_pg1.NegotiatedLinkRate & ++ MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); ++ phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( ++ expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( ++ expander_pg1.HwLinkRate >> 4); ++ phy->minimum_linkrate = _transport_convert_phy_link_rate( ++ expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate = _transport_convert_phy_link_rate( ++ expander_pg1.ProgrammedLinkRate >> 4); ++ ++ if ((sas_phy_add(phy))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ sas_phy_free(phy); ++ return -1; ++ } ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &phy->dev, ++ "add: handle(0x%04x), sas_addr(0x%016llx)\n" ++ "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", ++ mpt2sas_phy->handle, (unsigned long long) ++ mpt2sas_phy->identify.sas_address, ++ mpt2sas_phy->attached_handle, ++ (unsigned long long) ++ mpt2sas_phy->remote_identify.sas_address); ++ mpt2sas_phy->phy = phy; ++ return 0; ++} ++ ++/** ++ * mpt2sas_transport_update_links - refreshing phy link changes ++ * @ioc: per adapter object ++ * @sas_address: sas address of parent expander or sas host ++ * @handle: attached device handle ++ * @phy_numberv: phy number ++ * @link_rate: new link rate ++ * ++ * Returns nothing. ++ */ ++void ++mpt2sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, ++ u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) ++{ ++ unsigned long flags; ++ struct _sas_node *sas_node; ++ struct _sas_phy *mpt2sas_phy; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) ++ return; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); ++ if (!sas_node) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return; ++ } ++ ++ mpt2sas_phy = &sas_node->phy[phy_number]; ++ mpt2sas_phy->attached_handle = handle; ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { ++ _transport_set_identify(ioc, handle, ++ &mpt2sas_phy->remote_identify); ++ _transport_add_phy_to_an_existing_port(ioc, sas_node, ++ mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address); ++ } else ++ memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct ++ sas_identify)); ++ ++ if (mpt2sas_phy->phy) ++ mpt2sas_phy->phy->negotiated_linkrate = ++ _transport_convert_phy_link_rate(link_rate); ++ ++ if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) ++ dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, ++ "refresh: parent sas_addr(0x%016llx),\n" ++ "\tlink_rate(0x%02x), phy(%d)\n" ++ "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", ++ (unsigned long long)sas_address, ++ link_rate, phy_number, handle, (unsigned long long) ++ mpt2sas_phy->remote_identify.sas_address); ++} ++ ++static inline void * ++phy_to_ioc(struct sas_phy *phy) ++{ ++ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); ++ return shost_priv(shost); ++} ++ ++static inline void * ++rphy_to_ioc(struct sas_rphy *rphy) ++{ ++ struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); ++ return shost_priv(shost); ++} ++ ++/* report phy error log structure */ ++struct phy_error_log_request { ++ u8 smp_frame_type; /* 0x40 */ ++ u8 function; /* 0x11 */ ++ u8 allocated_response_length; ++ u8 request_length; /* 02 */ ++ u8 reserved_1[5]; ++ u8 phy_identifier; ++ u8 reserved_2[2]; ++}; ++ ++/* report phy error log reply structure */ ++struct phy_error_log_reply { ++ u8 smp_frame_type; /* 0x41 */ ++ u8 function; /* 0x11 */ ++ u8 function_result; ++ u8 response_length; ++ __be16 expander_change_count; ++ u8 reserved_1[3]; ++ u8 phy_identifier; ++ u8 reserved_2[2]; ++ __be32 invalid_dword; ++ __be32 running_disparity_error; ++ __be32 loss_of_dword_sync; ++ __be32 phy_reset_problem; ++}; ++ ++/** ++ * _transport_get_expander_phy_error_log - return expander counters ++ * @ioc: per adapter object ++ * @phy: The sas phy object ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc, ++ struct sas_phy *phy) ++{ ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ struct phy_error_log_request *phy_error_log_request; ++ struct phy_error_log_reply *phy_error_log_reply; ++ int rc; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma; ++ u32 sz; ++ u16 wait_state_count; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&ioc->transport_cmds.mutex); ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ sz = sizeof(struct phy_error_log_request) + ++ sizeof(struct phy_error_log_reply); ++ data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ rc = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ ++ rc = -EINVAL; ++ memset(data_out, 0, sz); ++ phy_error_log_request = data_out; ++ phy_error_log_request->smp_frame_type = 0x40; ++ phy_error_log_request->function = 0x11; ++ phy_error_log_request->request_length = 2; ++ phy_error_log_request->allocated_response_length = 0; ++ phy_error_log_request->phy_identifier = phy->number; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); ++ mpi_request->RequestDataLength = ++ cpu_to_le16(sizeof(struct phy_error_log_request)); ++ psge = &mpi_request->SGL; ++ ++ ioc->build_sg(ioc, psge, data_out_dma, ++ sizeof(struct phy_error_log_request), ++ data_out_dma + sizeof(struct phy_error_log_request), ++ sizeof(struct phy_error_log_reply)); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - send to sas_addr(0x%016llx), phy(%d)\n", ++ ioc->name, (unsigned long long)phy->identify.sas_address, ++ phy->number)); ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - complete\n", ioc->name)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - reply data transfer size(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ if (le16_to_cpu(mpi_reply->ResponseDataLength) != ++ sizeof(struct phy_error_log_reply)) ++ goto out; ++ ++ phy_error_log_reply = data_out + ++ sizeof(struct phy_error_log_request); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - function_result(%d)\n", ++ ioc->name, phy_error_log_reply->function_result)); ++ ++ phy->invalid_dword_count = ++ be32_to_cpu(phy_error_log_reply->invalid_dword); ++ phy->running_disparity_error_count = ++ be32_to_cpu(phy_error_log_reply->running_disparity_error); ++ phy->loss_of_dword_sync_count = ++ be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); ++ phy->phy_reset_problem_count = ++ be32_to_cpu(phy_error_log_reply->phy_reset_problem); ++ rc = 0; ++ } else ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_error_log - no reply\n", ioc->name)); ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ if (data_out) ++ pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); ++ ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _transport_get_linkerrors - return phy counters for both hba and expanders ++ * @phy: The sas phy object ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_transport_get_linkerrors(struct sas_phy *phy) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ unsigned long flags; ++ Mpi2ConfigReply_t mpi_reply; ++ Mpi2SasPhyPage1_t phy_pg1; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) ++ return _transport_get_expander_phy_error_log(ioc, phy); ++ ++ /* get hba phy error logs */ ++ if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1, ++ phy->number))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "phy(%d), ioc_status (0x%04x), loginfo(0x%08x)\n", ++ ioc->name, phy->number, ++ le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ ++ phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount); ++ phy->running_disparity_error_count = ++ le32_to_cpu(phy_pg1.RunningDisparityErrorCount); ++ phy->loss_of_dword_sync_count = ++ le32_to_cpu(phy_pg1.LossDwordSynchCount); ++ phy->phy_reset_problem_count = ++ le32_to_cpu(phy_pg1.PhyResetProblemCount); ++ return 0; ++} ++ ++/** ++ * _transport_get_enclosure_identifier - ++ * @phy: The sas phy object ++ * ++ * Obtain the enclosure logical id for an expander. ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) ++{ ++ struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy); ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ int rc; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ rphy->identify.sas_address); ++ if (sas_device) { ++ *identifier = sas_device->enclosure_logical_id; ++ rc = 0; ++ sas_device_put(sas_device); ++ } else { ++ *identifier = 0; ++ rc = -ENXIO; ++ } ++ ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ return rc; ++} ++ ++/** ++ * _transport_get_bay_identifier - ++ * @phy: The sas phy object ++ * ++ * Returns the slot id for a device that resides inside an enclosure. ++ */ ++static int ++_transport_get_bay_identifier(struct sas_rphy *rphy) ++{ ++ struct MPT3SAS_ADAPTER *ioc = rphy_to_ioc(rphy); ++ struct _sas_device *sas_device; ++ unsigned long flags; ++ int rc; ++ ++ spin_lock_irqsave(&ioc->sas_device_lock, flags); ++ sas_device = __mpt2sas_get_sdev_by_addr(ioc, ++ rphy->identify.sas_address); ++ if (sas_device) { ++ rc = sas_device->slot; ++ sas_device_put(sas_device); ++ } else { ++ rc = -ENXIO; ++ } ++ spin_unlock_irqrestore(&ioc->sas_device_lock, flags); ++ return rc; ++} ++ ++/* phy control request structure */ ++struct phy_control_request { ++ u8 smp_frame_type; /* 0x40 */ ++ u8 function; /* 0x91 */ ++ u8 allocated_response_length; ++ u8 request_length; /* 0x09 */ ++ u16 expander_change_count; ++ u8 reserved_1[3]; ++ u8 phy_identifier; ++ u8 phy_operation; ++ u8 reserved_2[13]; ++ u64 attached_device_name; ++ u8 programmed_min_physical_link_rate; ++ u8 programmed_max_physical_link_rate; ++ u8 reserved_3[6]; ++}; ++ ++/* phy control reply structure */ ++struct phy_control_reply { ++ u8 smp_frame_type; /* 0x41 */ ++ u8 function; /* 0x11 */ ++ u8 function_result; ++ u8 response_length; ++}; ++ ++#define SMP_PHY_CONTROL_LINK_RESET (0x01) ++#define SMP_PHY_CONTROL_HARD_RESET (0x02) ++#define SMP_PHY_CONTROL_DISABLE (0x03) ++ ++/** ++ * _transport_expander_phy_control - expander phy control ++ * @ioc: per adapter object ++ * @phy: The sas phy object ++ * ++ * Returns 0 for success, non-zero for failure. ++ * ++ */ ++static int ++_transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc, ++ struct sas_phy *phy, u8 phy_operation) ++{ ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ struct phy_control_request *phy_control_request; ++ struct phy_control_reply *phy_control_reply; ++ int rc; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ void *data_out = NULL; ++ dma_addr_t data_out_dma; ++ u32 sz; ++ u16 wait_state_count; ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ mutex_lock(&ioc->transport_cmds.mutex); ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto out; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ sz = sizeof(struct phy_control_request) + ++ sizeof(struct phy_control_reply); ++ data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); ++ if (!data_out) { ++ pr_err("failure at %s:%d/%s()!\n", __FILE__, ++ __LINE__, __func__); ++ rc = -ENOMEM; ++ mpt2sas_base_free_smid(ioc, smid); ++ goto out; ++ } ++ ++ rc = -EINVAL; ++ memset(data_out, 0, sz); ++ phy_control_request = data_out; ++ phy_control_request->smp_frame_type = 0x40; ++ phy_control_request->function = 0x91; ++ phy_control_request->request_length = 9; ++ phy_control_request->allocated_response_length = 0; ++ phy_control_request->phy_identifier = phy->number; ++ phy_control_request->phy_operation = phy_operation; ++ phy_control_request->programmed_min_physical_link_rate = ++ phy->minimum_linkrate << 4; ++ phy_control_request->programmed_max_physical_link_rate = ++ phy->maximum_linkrate << 4; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->VF_ID = 0; /* TODO */ ++ mpi_request->VP_ID = 0; ++ mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); ++ mpi_request->RequestDataLength = ++ cpu_to_le16(sizeof(struct phy_error_log_request)); ++ psge = &mpi_request->SGL; ++ ++ ioc->build_sg(ioc, psge, data_out_dma, ++ sizeof(struct phy_control_request), ++ data_out_dma + sizeof(struct phy_control_request), ++ sizeof(struct phy_control_reply)); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ++ ioc->name, (unsigned long long)phy->identify.sas_address, ++ phy->number, phy_operation)); ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s: timeout\n", ++ ioc->name, __func__); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - complete\n", ioc->name)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - reply data transfer size(%d)\n", ++ ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ if (le16_to_cpu(mpi_reply->ResponseDataLength) != ++ sizeof(struct phy_control_reply)) ++ goto out; ++ ++ phy_control_reply = data_out + ++ sizeof(struct phy_control_request); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - function_result(%d)\n", ++ ioc->name, phy_control_reply->function_result)); ++ ++ rc = 0; ++ } else ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "phy_control - no reply\n", ioc->name)); ++ ++ issue_host_reset: ++ if (issue_reset) ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ if (data_out) ++ pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); ++ ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++/** ++ * _transport_phy_reset - ++ * @phy: The sas phy object ++ * @hard_reset: ++ * ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_phy_reset(struct sas_phy *phy, int hard_reset) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ Mpi2SasIoUnitControlReply_t mpi_reply; ++ Mpi2SasIoUnitControlRequest_t mpi_request; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* handle expander phys */ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) ++ return _transport_expander_phy_control(ioc, phy, ++ (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET : ++ SMP_PHY_CONTROL_LINK_RESET); ++ ++ /* handle hba phys */ ++ memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); ++ mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; ++ mpi_request.Operation = hard_reset ? ++ MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET; ++ mpi_request.PhyNum = phy->number; ++ ++ if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ return -ENXIO; ++ } ++ ++ if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) ++ pr_info(MPT3SAS_FMT ++ "phy(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", ++ ioc->name, phy->number, le16_to_cpu(mpi_reply.IOCStatus), ++ le32_to_cpu(mpi_reply.IOCLogInfo)); ++ ++ return 0; ++} ++ ++/** ++ * _transport_phy_enable - enable/disable phys ++ * @phy: The sas phy object ++ * @enable: enable phy when true ++ * ++ * Only support sas_host direct attached phys. ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_phy_enable(struct sas_phy *phy, int enable) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 sz; ++ int rc = 0; ++ unsigned long flags; ++ int i, discovery_active; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ /* handle expander phys */ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) ++ return _transport_expander_phy_control(ioc, phy, ++ (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET : ++ SMP_PHY_CONTROL_DISABLE); ++ ++ /* handle hba phys */ ++ ++ /* read sas_iounit page 0 */ ++ sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit0PhyData_t)); ++ sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg0) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, ++ sas_iounit_pg0, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -EIO; ++ goto out; ++ } ++ ++ /* unable to enable/disable phys when when discovery is active */ ++ for (i = 0, discovery_active = 0; i < ioc->sas_hba.num_phys ; i++) { ++ if (sas_iounit_pg0->PhyData[i].PortFlags & ++ MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) { ++ pr_err(MPT3SAS_FMT "discovery is active on " \ ++ "port = %d, phy = %d: unable to enable/disable " ++ "phys, try again later!\n", ioc->name, ++ sas_iounit_pg0->PhyData[i].Port, i); ++ discovery_active = 1; ++ } ++ } ++ ++ if (discovery_active) { ++ rc = -EAGAIN; ++ goto out; ++ } ++ ++ /* read sas_iounit page 1 */ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -EIO; ++ goto out; ++ } ++ ++ /* copy Port/PortFlags/PhyFlags from page 0 */ ++ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { ++ sas_iounit_pg1->PhyData[i].Port = ++ sas_iounit_pg0->PhyData[i].Port; ++ sas_iounit_pg1->PhyData[i].PortFlags = ++ (sas_iounit_pg0->PhyData[i].PortFlags & ++ MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG); ++ sas_iounit_pg1->PhyData[i].PhyFlags = ++ (sas_iounit_pg0->PhyData[i].PhyFlags & ++ (MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED + ++ MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED)); ++ } ++ ++ if (enable) ++ sas_iounit_pg1->PhyData[phy->number].PhyFlags ++ &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; ++ else ++ sas_iounit_pg1->PhyData[phy->number].PhyFlags ++ |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; ++ ++ mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz); ++ ++ /* link reset */ ++ if (enable) ++ _transport_phy_reset(phy, 0); ++ ++ out: ++ kfree(sas_iounit_pg1); ++ kfree(sas_iounit_pg0); ++ return rc; ++} ++ ++/** ++ * _transport_phy_speed - set phy min/max link rates ++ * @phy: The sas phy object ++ * @rates: rates defined in sas_phy_linkrates ++ * ++ * Only support sas_host direct attached phys. ++ * Returns 0 for success, non-zero for failure. ++ */ ++static int ++_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) ++{ ++ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); ++ Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; ++ Mpi2SasPhyPage0_t phy_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 ioc_status; ++ u16 sz; ++ int i; ++ int rc = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ioc->sas_node_lock, flags); ++ if (_transport_sas_node_find_by_sas_address(ioc, ++ phy->identify.sas_address) == NULL) { ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ return -EINVAL; ++ } ++ spin_unlock_irqrestore(&ioc->sas_node_lock, flags); ++ ++ if (!rates->minimum_linkrate) ++ rates->minimum_linkrate = phy->minimum_linkrate; ++ else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) ++ rates->minimum_linkrate = phy->minimum_linkrate_hw; ++ ++ if (!rates->maximum_linkrate) ++ rates->maximum_linkrate = phy->maximum_linkrate; ++ else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) ++ rates->maximum_linkrate = phy->maximum_linkrate_hw; ++ ++ /* handle expander phys */ ++ if (phy->identify.sas_address != ioc->sas_hba.sas_address) { ++ phy->minimum_linkrate = rates->minimum_linkrate; ++ phy->maximum_linkrate = rates->maximum_linkrate; ++ return _transport_expander_phy_control(ioc, phy, ++ SMP_PHY_CONTROL_LINK_RESET); ++ } ++ ++ /* handle hba phys */ ++ ++ /* sas_iounit page 1 */ ++ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * ++ sizeof(Mpi2SasIOUnit1PhyData_t)); ++ sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); ++ if (!sas_iounit_pg1) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, ++ sas_iounit_pg1, sz))) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -EIO; ++ goto out; ++ } ++ ++ for (i = 0; i < ioc->sas_hba.num_phys; i++) { ++ if (phy->number != i) { ++ sas_iounit_pg1->PhyData[i].MaxMinLinkRate = ++ (ioc->sas_hba.phy[i].phy->minimum_linkrate + ++ (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); ++ } else { ++ sas_iounit_pg1->PhyData[i].MaxMinLinkRate = ++ (rates->minimum_linkrate + ++ (rates->maximum_linkrate << 4)); ++ } ++ } ++ ++ if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, ++ sz)) { ++ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ++ ioc->name, __FILE__, __LINE__, __func__); ++ rc = -ENXIO; ++ goto out; ++ } ++ ++ /* link reset */ ++ _transport_phy_reset(phy, 0); ++ ++ /* read phy page 0, then update the rates in the sas transport phy */ ++ if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, ++ phy->number)) { ++ phy->minimum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); ++ phy->maximum_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.ProgrammedLinkRate >> 4); ++ phy->negotiated_linkrate = _transport_convert_phy_link_rate( ++ phy_pg0.NegotiatedLinkRate & ++ MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); ++ } ++ ++ out: ++ kfree(sas_iounit_pg1); ++ return rc; ++} ++ ++/** ++ * _transport_smp_handler - transport portal for smp passthru ++ * @shost: shost object ++ * @rphy: sas transport rphy object ++ * @req: ++ * ++ * This used primarily for smp_utils. ++ * Example: ++ * smp_rep_general /sys/class/bsg/expander-5:0 ++ */ ++static int ++_transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ++ struct request *req) ++{ ++ struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); ++ Mpi2SmpPassthroughRequest_t *mpi_request; ++ Mpi2SmpPassthroughReply_t *mpi_reply; ++ int rc, i; ++ u16 smid; ++ u32 ioc_state; ++ unsigned long timeleft; ++ void *psge; ++ u8 issue_reset = 0; ++ dma_addr_t dma_addr_in = 0; ++ dma_addr_t dma_addr_out = 0; ++ dma_addr_t pci_dma_in = 0; ++ dma_addr_t pci_dma_out = 0; ++ void *pci_addr_in = NULL; ++ void *pci_addr_out = NULL; ++ u16 wait_state_count; ++ struct request *rsp = req->next_rq; ++ struct bio_vec *bvec = NULL; ++ ++ if (!rsp) { ++ pr_err(MPT3SAS_FMT "%s: the smp response space is missing\n", ++ ioc->name, __func__); ++ return -EINVAL; ++ } ++ ++ if (ioc->shost_recovery || ioc->pci_error_recovery) { ++ pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", ++ __func__, ioc->name); ++ return -EFAULT; ++ } ++ ++ rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex); ++ if (rc) ++ return rc; ++ ++ if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { ++ pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ioc->name, ++ __func__); ++ rc = -EAGAIN; ++ goto out; ++ } ++ ioc->transport_cmds.status = MPT3_CMD_PENDING; ++ ++ /* Check if the request is split across multiple segments */ ++ if (req->bio->bi_vcnt > 1) { ++ u32 offset = 0; ++ ++ /* Allocate memory and copy the request */ ++ pci_addr_out = pci_alloc_consistent(ioc->pdev, ++ blk_rq_bytes(req), &pci_dma_out); ++ if (!pci_addr_out) { ++ pr_info(MPT3SAS_FMT "%s(): PCI Addr out = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto out; ++ } ++ ++ bio_for_each_segment(bvec, req->bio, i) { ++ memcpy(pci_addr_out + offset, ++ page_address(bvec->bv_page) + bvec->bv_offset, ++ bvec->bv_len); ++ offset += bvec->bv_len; ++ } ++ } else { ++ dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), ++ blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(ioc->pdev, dma_addr_out)) { ++ pr_info(MPT3SAS_FMT "%s(): DMA Addr out = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto free_pci; ++ } ++ } ++ ++ /* Check if the response needs to be populated across ++ * multiple segments */ ++ if (rsp->bio->bi_vcnt > 1) { ++ pci_addr_in = pci_alloc_consistent(ioc->pdev, blk_rq_bytes(rsp), ++ &pci_dma_in); ++ if (!pci_addr_in) { ++ pr_info(MPT3SAS_FMT "%s(): PCI Addr in = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto unmap; ++ } ++ } else { ++ dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), ++ blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(ioc->pdev, dma_addr_in)) { ++ pr_info(MPT3SAS_FMT "%s(): DMA Addr in = NULL\n", ++ ioc->name, __func__); ++ rc = -ENOMEM; ++ goto unmap; ++ } ++ } ++ ++ wait_state_count = 0; ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { ++ if (wait_state_count++ == 10) { ++ pr_err(MPT3SAS_FMT ++ "%s: failed due to ioc not operational\n", ++ ioc->name, __func__); ++ rc = -EFAULT; ++ goto unmap; ++ } ++ ssleep(1); ++ ioc_state = mpt2sas_base_get_iocstate(ioc, 1); ++ pr_info(MPT3SAS_FMT ++ "%s: waiting for operational state(count=%d)\n", ++ ioc->name, __func__, wait_state_count); ++ } ++ if (wait_state_count) ++ pr_info(MPT3SAS_FMT "%s: ioc is operational\n", ++ ioc->name, __func__); ++ ++ smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); ++ if (!smid) { ++ pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", ++ ioc->name, __func__); ++ rc = -EAGAIN; ++ goto unmap; ++ } ++ ++ rc = 0; ++ mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); ++ ioc->transport_cmds.smid = smid; ++ ++ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); ++ mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; ++ mpi_request->PhysicalPort = 0xFF; ++ mpi_request->SASAddress = (rphy) ? ++ cpu_to_le64(rphy->identify.sas_address) : ++ cpu_to_le64(ioc->sas_hba.sas_address); ++ mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); ++ psge = &mpi_request->SGL; ++ ++ if (req->bio->bi_vcnt > 1) ++ ioc->build_sg(ioc, psge, pci_dma_out, (blk_rq_bytes(req) - 4), ++ pci_dma_in, (blk_rq_bytes(rsp) + 4)); ++ else ++ ioc->build_sg(ioc, psge, dma_addr_out, (blk_rq_bytes(req) - 4), ++ dma_addr_in, (blk_rq_bytes(rsp) + 4)); ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - sending smp request\n", ioc->name, __func__)); ++ ++ init_completion(&ioc->transport_cmds.done); ++ mpt2sas_base_put_smid_default(ioc, smid); ++ timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, ++ 10*HZ); ++ ++ if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { ++ pr_err(MPT3SAS_FMT "%s : timeout\n", ++ __func__, ioc->name); ++ _debug_dump_mf(mpi_request, ++ sizeof(Mpi2SmpPassthroughRequest_t)/4); ++ if (!(ioc->transport_cmds.status & MPT3_CMD_RESET)) ++ issue_reset = 1; ++ goto issue_host_reset; ++ } ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - complete\n", ioc->name, __func__)); ++ ++ if (ioc->transport_cmds.status & MPT3_CMD_REPLY_VALID) { ++ ++ mpi_reply = ioc->transport_cmds.reply; ++ ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - reply data transfer size(%d)\n", ++ ioc->name, __func__, ++ le16_to_cpu(mpi_reply->ResponseDataLength))); ++ ++ memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); ++ req->sense_len = sizeof(*mpi_reply); ++ req->resid_len = 0; ++ rsp->resid_len -= ++ le16_to_cpu(mpi_reply->ResponseDataLength); ++ ++ /* check if the resp needs to be copied from the allocated ++ * pci mem */ ++ if (rsp->bio->bi_vcnt > 1) { ++ u32 offset = 0; ++ u32 bytes_to_copy = ++ le16_to_cpu(mpi_reply->ResponseDataLength); ++ bio_for_each_segment(bvec, rsp->bio, i) { ++ if (bytes_to_copy <= bvec->bv_len) { ++ memcpy(page_address(bvec->bv_page) + ++ bvec->bv_offset, pci_addr_in + ++ offset, bytes_to_copy); ++ break; ++ } else { ++ memcpy(page_address(bvec->bv_page) + ++ bvec->bv_offset, pci_addr_in + ++ offset, bvec->bv_len); ++ bytes_to_copy -= bvec->bv_len; ++ } ++ offset += bvec->bv_len; ++ } ++ } ++ } else { ++ dtransportprintk(ioc, pr_info(MPT3SAS_FMT ++ "%s - no reply\n", ioc->name, __func__)); ++ rc = -ENXIO; ++ } ++ ++ issue_host_reset: ++ if (issue_reset) { ++ mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, ++ FORCE_BIG_HAMMER); ++ rc = -ETIMEDOUT; ++ } ++ ++ unmap: ++ if (dma_addr_out) ++ pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req), ++ PCI_DMA_BIDIRECTIONAL); ++ if (dma_addr_in) ++ pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp), ++ PCI_DMA_BIDIRECTIONAL); ++ ++ free_pci: ++ if (pci_addr_out) ++ pci_free_consistent(ioc->pdev, blk_rq_bytes(req), pci_addr_out, ++ pci_dma_out); ++ ++ if (pci_addr_in) ++ pci_free_consistent(ioc->pdev, blk_rq_bytes(rsp), pci_addr_in, ++ pci_dma_in); ++ ++ out: ++ ioc->transport_cmds.status = MPT3_CMD_NOT_USED; ++ mutex_unlock(&ioc->transport_cmds.mutex); ++ return rc; ++} ++ ++struct sas_function_template mpt2sas_transport_functions = { ++ .get_linkerrors = _transport_get_linkerrors, ++ .get_enclosure_identifier = _transport_get_enclosure_identifier, ++ .get_bay_identifier = _transport_get_bay_identifier, ++ .phy_reset = _transport_phy_reset, ++ .phy_enable = _transport_phy_enable, ++ .set_phy_speed = _transport_phy_speed, ++ .smp_handler = _transport_smp_handler, ++}; ++ ++struct scsi_transport_template *mpt2sas_transport_template; +diff --git a/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c +new file mode 100644 +index 0000000..d5038ec +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.c +@@ -0,0 +1,434 @@ ++/* ++ * This module provides common API to set Diagnostic trigger for MPT ++ * (Message Passing Technology) based controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/** ++ * _mpt2sas_raise_sigio - notifiy app ++ * @ioc: per adapter object ++ * @event_data: ++ */ ++static void ++_mpt2sas_raise_sigio(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) ++{ ++ Mpi2EventNotificationReply_t *mpi_reply; ++ u16 sz, event_data_sz; ++ unsigned long flags; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ++ ioc->name, __func__)); ++ ++ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + ++ sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4; ++ mpi_reply = kzalloc(sz, GFP_KERNEL); ++ if (!mpi_reply) ++ goto out; ++ mpi_reply->Event = cpu_to_le16(MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED); ++ event_data_sz = (sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T) + 4) / 4; ++ mpi_reply->EventDataLength = cpu_to_le16(event_data_sz); ++ memcpy(&mpi_reply->EventData, event_data, ++ sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: add to driver event log\n", ++ ioc->name, __func__)); ++ mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); ++ kfree(mpi_reply); ++ out: ++ ++ /* clearing the diag_trigger_active flag */ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: clearing diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ ioc->diag_trigger_active = 0; ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_process_trigger_data - process the event data for the trigger ++ * @ioc: per adapter object ++ * @event_data: ++ */ ++void ++mpt2sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc, ++ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) ++{ ++ u8 issue_reset = 0; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: enter\n", ++ ioc->name, __func__)); ++ ++ /* release the diag buffer trace */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: release trace diag buffer\n", ioc->name, __func__)); ++ mpt2sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, ++ &issue_reset); ++ } ++ ++ _mpt2sas_raise_sigio(ioc, event_data); ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_master - Master trigger handler ++ * @ioc: per adapter object ++ * @trigger_bitmask: ++ * ++ */ ++void ++mpt2sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, u32 trigger_bitmask) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ unsigned long flags; ++ u8 found_match = 0; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT || ++ trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET) ++ goto by_pass_checks; ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ by_pass_checks: ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - trigger_bitmask = 0x%08x\n", ++ ioc->name, __func__, trigger_bitmask)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ if (ioc->diag_trigger_master.MasterData & trigger_bitmask) { ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_MASTER; ++ event_data.u.master.MasterData = trigger_bitmask; ++ ++ if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT || ++ trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET) ++ _mpt2sas_raise_sigio(ioc, &event_data); ++ else ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_event - Event trigger handler ++ * @ioc: per adapter object ++ * @event: ++ * @log_entry_qualifier: ++ * ++ */ ++void ++mpt2sas_trigger_event(struct MPT3SAS_ADAPTER *ioc, u16 event, ++ u16 log_entry_qualifier) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ struct SL_WH_EVENT_TRIGGER_T *event_trigger; ++ int i; ++ unsigned long flags; ++ u8 found_match; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - event = 0x%04x, log_entry_qualifier = 0x%04x\n", ++ ioc->name, __func__, event, log_entry_qualifier)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ event_trigger = ioc->diag_trigger_event.EventTriggerEntry; ++ for (i = 0 , found_match = 0; i < ioc->diag_trigger_event.ValidEntries ++ && !found_match; i++, event_trigger++) { ++ if (event_trigger->EventValue != event) ++ continue; ++ if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { ++ if (event_trigger->LogEntryQualifier == ++ log_entry_qualifier) ++ found_match = 1; ++ continue; ++ } ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_EVENT; ++ event_data.u.event.EventValue = event; ++ event_data.u.event.LogEntryQualifier = log_entry_qualifier; ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_scsi - SCSI trigger handler ++ * @ioc: per adapter object ++ * @sense_key: ++ * @asc: ++ * @ascq: ++ * ++ */ ++void ++mpt2sas_trigger_scsi(struct MPT3SAS_ADAPTER *ioc, u8 sense_key, u8 asc, ++ u8 ascq) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ struct SL_WH_SCSI_TRIGGER_T *scsi_trigger; ++ int i; ++ unsigned long flags; ++ u8 found_match; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - sense_key = 0x%02x, asc = 0x%02x, ascq = 0x%02x\n", ++ ioc->name, __func__, sense_key, asc, ascq)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ scsi_trigger = ioc->diag_trigger_scsi.SCSITriggerEntry; ++ for (i = 0 , found_match = 0; i < ioc->diag_trigger_scsi.ValidEntries ++ && !found_match; i++, scsi_trigger++) { ++ if (scsi_trigger->SenseKey != sense_key) ++ continue; ++ if (!(scsi_trigger->ASC == 0xFF || scsi_trigger->ASC == asc)) ++ continue; ++ if (!(scsi_trigger->ASCQ == 0xFF || scsi_trigger->ASCQ == ascq)) ++ continue; ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_SCSI; ++ event_data.u.scsi.SenseKey = sense_key; ++ event_data.u.scsi.ASC = asc; ++ event_data.u.scsi.ASCQ = ascq; ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} ++ ++/** ++ * mpt2sas_trigger_mpi - MPI trigger handler ++ * @ioc: per adapter object ++ * @ioc_status: ++ * @loginfo: ++ * ++ */ ++void ++mpt2sas_trigger_mpi(struct MPT3SAS_ADAPTER *ioc, u16 ioc_status, u32 loginfo) ++{ ++ struct SL_WH_TRIGGERS_EVENT_DATA_T event_data; ++ struct SL_WH_MPI_TRIGGER_T *mpi_trigger; ++ int i; ++ unsigned long flags; ++ u8 found_match; ++ ++ spin_lock_irqsave(&ioc->diag_trigger_lock, flags); ++ ++ /* check to see if trace buffers are currently registered */ ++ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ /* check to see if trace buffers are currently released */ ++ if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & ++ MPT3_DIAG_BUFFER_IS_RELEASED) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ return; ++ } ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: enter - ioc_status = 0x%04x, loginfo = 0x%08x\n", ++ ioc->name, __func__, ioc_status, loginfo)); ++ ++ /* don't send trigger if an trigger is currently active */ ++ if (ioc->diag_trigger_active) { ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ goto out; ++ } ++ ++ /* check for the trigger condition */ ++ mpi_trigger = ioc->diag_trigger_mpi.MPITriggerEntry; ++ for (i = 0 , found_match = 0; i < ioc->diag_trigger_mpi.ValidEntries ++ && !found_match; i++, mpi_trigger++) { ++ if (mpi_trigger->IOCStatus != ioc_status) ++ continue; ++ if (!(mpi_trigger->IocLogInfo == 0xFFFFFFFF || ++ mpi_trigger->IocLogInfo == loginfo)) ++ continue; ++ found_match = 1; ++ ioc->diag_trigger_active = 1; ++ } ++ spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags); ++ ++ if (!found_match) ++ goto out; ++ ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT ++ "%s: setting diag_trigger_active flag\n", ++ ioc->name, __func__)); ++ memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T)); ++ event_data.trigger_type = MPT3SAS_TRIGGER_MPI; ++ event_data.u.mpi.IOCStatus = ioc_status; ++ event_data.u.mpi.IocLogInfo = loginfo; ++ mpt2sas_send_trigger_data_event(ioc, &event_data); ++ out: ++ dTriggerDiagPrintk(ioc, pr_info(MPT3SAS_FMT "%s: exit\n", ioc->name, ++ __func__)); ++} +diff --git a/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h +new file mode 100644 +index 0000000..6586a46 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_trigger_diag.h +@@ -0,0 +1,194 @@ ++/* ++ * This is the Fusion MPT base driver providing common API layer interface ++ * to set Diagnostic triggers for MPT (Message Passing Technology) based ++ * controllers ++ * ++ * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2014 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA. ++ */ ++ /* Diagnostic Trigger Configuration Data Structures */ ++ ++#ifndef MPT3SAS_TRIGGER_DIAG_H_INCLUDED ++#define MPT3SAS_TRIGGER_DIAG_H_INCLUDED ++ ++/* limitation on number of entries */ ++#define NUM_VALID_ENTRIES (20) ++ ++/* trigger types */ ++#define MPT3SAS_TRIGGER_MASTER (1) ++#define MPT3SAS_TRIGGER_EVENT (2) ++#define MPT3SAS_TRIGGER_SCSI (3) ++#define MPT3SAS_TRIGGER_MPI (4) ++ ++/* trigger names */ ++#define MASTER_TRIGGER_FILE_NAME "diag_trigger_master" ++#define EVENT_TRIGGERS_FILE_NAME "diag_trigger_event" ++#define SCSI_TRIGGERS_FILE_NAME "diag_trigger_scsi" ++#define MPI_TRIGGER_FILE_NAME "diag_trigger_mpi" ++ ++/* master trigger bitmask */ ++#define MASTER_TRIGGER_FW_FAULT (0x00000001) ++#define MASTER_TRIGGER_ADAPTER_RESET (0x00000002) ++#define MASTER_TRIGGER_TASK_MANAGMENT (0x00000004) ++#define MASTER_TRIGGER_DEVICE_REMOVAL (0x00000008) ++ ++/* fake firmware event for tigger */ ++#define MPI3_EVENT_DIAGNOSTIC_TRIGGER_FIRED (0x6E) ++ ++/** ++ * MasterTrigger is a single U32 passed to/from sysfs. ++ * ++ * Bit Flags (enables) include: ++ * 1. FW Faults ++ * 2. Adapter Reset issued by driver ++ * 3. TMs ++ * 4. Device Remove Event sent by FW ++ */ ++ ++struct SL_WH_MASTER_TRIGGER_T { ++ uint32_t MasterData; ++}; ++ ++/** ++ * struct SL_WH_EVENT_TRIGGER_T - Definition of an event trigger element ++ * @EventValue: Event Code to trigger on ++ * @LogEntryQualifier: Type of FW event that logged (Log Entry Added Event only) ++ * ++ * Defines an event that should induce a DIAG_TRIGGER driver event if observed. ++ */ ++struct SL_WH_EVENT_TRIGGER_T { ++ uint16_t EventValue; ++ uint16_t LogEntryQualifier; ++}; ++ ++/** ++ * struct SL_WH_EVENT_TRIGGERS_T - Structure passed to/from sysfs containing a ++ * list of Event Triggers to be monitored for. ++ * @ValidEntries: Number of _SL_WH_EVENT_TRIGGER_T structures contained in this ++ * structure. ++ * @EventTriggerEntry: List of Event trigger elements. ++ * ++ * This binary structure is transferred via sysfs to get/set Event Triggers ++ * in the Linux Driver. ++ */ ++ ++struct SL_WH_EVENT_TRIGGERS_T { ++ uint32_t ValidEntries; ++ struct SL_WH_EVENT_TRIGGER_T EventTriggerEntry[NUM_VALID_ENTRIES]; ++}; ++ ++/** ++ * struct SL_WH_SCSI_TRIGGER_T - Definition of a SCSI trigger element ++ * @ASCQ: Additional Sense Code Qualifier. Can be specific or 0xFF for ++ * wildcard. ++ * @ASC: Additional Sense Code. Can be specific or 0xFF for wildcard ++ * @SenseKey: SCSI Sense Key ++ * ++ * Defines a sense key (single or many variants) that should induce a ++ * DIAG_TRIGGER driver event if observed. ++ */ ++struct SL_WH_SCSI_TRIGGER_T { ++ U8 ASCQ; ++ U8 ASC; ++ U8 SenseKey; ++ U8 Reserved; ++}; ++ ++/** ++ * struct SL_WH_SCSI_TRIGGERS_T - Structure passed to/from sysfs containing a ++ * list of SCSI sense codes that should trigger a DIAG_SERVICE event when ++ * observed. ++ * @ValidEntries: Number of _SL_WH_SCSI_TRIGGER_T structures contained in this ++ * structure. ++ * @SCSITriggerEntry: List of SCSI Sense Code trigger elements. ++ * ++ * This binary structure is transferred via sysfs to get/set SCSI Sense Code ++ * Triggers in the Linux Driver. ++ */ ++struct SL_WH_SCSI_TRIGGERS_T { ++ uint32_t ValidEntries; ++ struct SL_WH_SCSI_TRIGGER_T SCSITriggerEntry[NUM_VALID_ENTRIES]; ++}; ++ ++/** ++ * struct SL_WH_MPI_TRIGGER_T - Definition of an MPI trigger element ++ * @IOCStatus: MPI IOCStatus ++ * @IocLogInfo: MPI IocLogInfo. Can be specific or 0xFFFFFFFF for wildcard ++ * ++ * Defines a MPI IOCStatus/IocLogInfo pair that should induce a DIAG_TRIGGER ++ * driver event if observed. ++ */ ++struct SL_WH_MPI_TRIGGER_T { ++ uint16_t IOCStatus; ++ uint16_t Reserved; ++ uint32_t IocLogInfo; ++}; ++ ++/** ++ * struct SL_WH_MPI_TRIGGERS_T - Structure passed to/from sysfs containing a ++ * list of MPI IOCStatus/IocLogInfo pairs that should trigger a DIAG_SERVICE ++ * event when observed. ++ * @ValidEntries: Number of _SL_WH_MPI_TRIGGER_T structures contained in this ++ * structure. ++ * @MPITriggerEntry: List of MPI IOCStatus/IocLogInfo trigger elements. ++ * ++ * This binary structure is transferred via sysfs to get/set MPI Error Triggers ++ * in the Linux Driver. ++ */ ++struct SL_WH_MPI_TRIGGERS_T { ++ uint32_t ValidEntries; ++ struct SL_WH_MPI_TRIGGER_T MPITriggerEntry[NUM_VALID_ENTRIES]; ++}; ++ ++/** ++ * struct SL_WH_TRIGGERS_EVENT_DATA_T - event data for trigger ++ * @trigger_type: trigger type (see MPT3SAS_TRIGGER_XXXX) ++ * @u: trigger condition that caused trigger to be sent ++ */ ++struct SL_WH_TRIGGERS_EVENT_DATA_T { ++ uint32_t trigger_type; ++ union { ++ struct SL_WH_MASTER_TRIGGER_T master; ++ struct SL_WH_EVENT_TRIGGER_T event; ++ struct SL_WH_SCSI_TRIGGER_T scsi; ++ struct SL_WH_MPI_TRIGGER_T mpi; ++ } u; ++}; ++#endif /* MPT3SAS_TRIGGER_DIAG_H_INCLUDED */ +diff --git a/drivers/scsi/mpt2sas/mpt3sas_warpdrive.c b/drivers/scsi/mpt2sas/mpt3sas_warpdrive.c +new file mode 100644 +index 0000000..2542263 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/mpt3sas_warpdrive.c +@@ -0,0 +1,344 @@ ++/* ++ * Scsi Host Layer for MPT (Message Passing Technology) based controllers ++ * ++ * Copyright (C) 2012-2014 LSI Corporation ++ * Copyright (C) 2013-2015 Avago Technologies ++ * (mailto: MPT-FusionLinux.pdl@avagotech.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * NO WARRANTY ++ * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR ++ * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT ++ * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is ++ * solely responsible for determining the appropriateness of using and ++ * distributing the Program and assumes all risks associated with its ++ * exercise of rights under this Agreement, including but not limited to ++ * the risks and costs of program errors, damage to or loss of data, ++ * programs or equipment, and unavailability or interruption of operations. ++ ++ * DISCLAIMER OF LIABILITY ++ * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY ++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ++ * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED ++ * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES ++ ++ * You should have received a copy of the GNU General Public License ++ * along with this program. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "mpt3sas_base.h" ++ ++/** ++ * _warpdrive_disable_ddio - Disable direct I/O for all the volumes ++ * @ioc: per adapter object ++ */ ++static void ++_warpdrive_disable_ddio(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidVolPage1_t vol_pg1; ++ Mpi2ConfigReply_t mpi_reply; ++ struct _raid_device *raid_device; ++ u16 handle; ++ u16 ioc_status; ++ unsigned long flags; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ break; ++ handle = le16_to_cpu(vol_pg1.DevHandle); ++ spin_lock_irqsave(&ioc->raid_device_lock, flags); ++ raid_device = mpt2sas_raid_device_find_by_handle(ioc, handle); ++ if (raid_device) ++ raid_device->direct_io_enabled = 0; ++ spin_unlock_irqrestore(&ioc->raid_device_lock, flags); ++ } ++ return; ++} ++ ++ ++/** ++ * mpt2sas_get_num_volumes - Get number of volumes in the ioc ++ * @ioc: per adapter object ++ */ ++u8 ++mpt2sas_get_num_volumes(struct MPT3SAS_ADAPTER *ioc) ++{ ++ Mpi2RaidVolPage1_t vol_pg1; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 handle; ++ u8 vol_cnt = 0; ++ u16 ioc_status; ++ ++ handle = 0xFFFF; ++ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply, ++ &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ++ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & ++ MPI2_IOCSTATUS_MASK; ++ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) ++ break; ++ vol_cnt++; ++ handle = le16_to_cpu(vol_pg1.DevHandle); ++ } ++ return vol_cnt; ++} ++ ++ ++/** ++ * mpt2sas_init_warpdrive_properties - Set properties for warpdrive direct I/O. ++ * @ioc: per adapter object ++ * @raid_device: the raid_device object ++ */ ++void ++mpt2sas_init_warpdrive_properties(struct MPT3SAS_ADAPTER *ioc, ++ struct _raid_device *raid_device) ++{ ++ Mpi2RaidVolPage0_t *vol_pg0; ++ Mpi2RaidPhysDiskPage0_t pd_pg0; ++ Mpi2ConfigReply_t mpi_reply; ++ u16 sz; ++ u8 num_pds, count; ++ unsigned long stripe_sz, block_sz; ++ u8 stripe_exp, block_exp; ++ u64 dev_max_lba; ++ ++ if (!ioc->is_warpdrive) ++ return; ++ ++ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "globally as drives are exposed\n", ioc->name); ++ return; ++ } ++ if (mpt2sas_get_num_volumes(ioc) > 1) { ++ _warpdrive_disable_ddio(ioc); ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "globally as number of drives > 1\n", ioc->name); ++ return; ++ } ++ if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle, ++ &num_pds)) || !num_pds) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "Failure in computing number of drives\n", ioc->name); ++ return; ++ } ++ ++ sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds * ++ sizeof(Mpi2RaidVol0PhysDisk_t)); ++ vol_pg0 = kzalloc(sz, GFP_KERNEL); ++ if (!vol_pg0) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "Memory allocation failure for RVPG0\n", ioc->name); ++ return; ++ } ++ ++ if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0, ++ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "Failure in retrieving RVPG0\n", ioc->name); ++ kfree(vol_pg0); ++ return; ++ } ++ ++ /* ++ * WARPDRIVE:If number of physical disks in a volume exceeds the max pds ++ * assumed for WARPDRIVE, disable direct I/O ++ */ ++ if (num_pds > MPT_MAX_WARPDRIVE_PDS) { ++ pr_warn(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x): num_mem=%d, " ++ "max_mem_allowed=%d\n", ioc->name, raid_device->handle, ++ num_pds, MPT_MAX_WARPDRIVE_PDS); ++ kfree(vol_pg0); ++ return; ++ } ++ for (count = 0; count < num_pds; count++) { ++ if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, ++ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM, ++ vol_pg0->PhysDisk[count].PhysDiskNum) || ++ pd_pg0.DevHandle == MPT3SAS_INVALID_DEVICE_HANDLE) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is " ++ "disabled for the drive with handle(0x%04x) member" ++ "handle retrieval failed for member number=%d\n", ++ ioc->name, raid_device->handle, ++ vol_pg0->PhysDisk[count].PhysDiskNum); ++ goto out_error; ++ } ++ /* Disable direct I/O if member drive lba exceeds 4 bytes */ ++ dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA); ++ if (dev_max_lba >> 32) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is " ++ "disabled for the drive with handle(0x%04x) member" ++ " handle (0x%04x) unsupported max lba 0x%016llx\n", ++ ioc->name, raid_device->handle, ++ le16_to_cpu(pd_pg0.DevHandle), ++ (unsigned long long)dev_max_lba); ++ goto out_error; ++ } ++ ++ raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle); ++ } ++ ++ /* ++ * Assumption for WD: Direct I/O is not supported if the volume is ++ * not RAID0 ++ */ ++ if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x): type=%d, " ++ "s_sz=%uK, blk_size=%u\n", ioc->name, ++ raid_device->handle, raid_device->volume_type, ++ (le32_to_cpu(vol_pg0->StripeSize) * ++ le16_to_cpu(vol_pg0->BlockSize)) / 1024, ++ le16_to_cpu(vol_pg0->BlockSize)); ++ goto out_error; ++ } ++ ++ stripe_sz = le32_to_cpu(vol_pg0->StripeSize); ++ stripe_exp = find_first_bit(&stripe_sz, 32); ++ if (stripe_exp == 32) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x) invalid stripe sz %uK\n", ++ ioc->name, raid_device->handle, ++ (le32_to_cpu(vol_pg0->StripeSize) * ++ le16_to_cpu(vol_pg0->BlockSize)) / 1024); ++ goto out_error; ++ } ++ raid_device->stripe_exponent = stripe_exp; ++ block_sz = le16_to_cpu(vol_pg0->BlockSize); ++ block_exp = find_first_bit(&block_sz, 16); ++ if (block_exp == 16) { ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is disabled " ++ "for the drive with handle(0x%04x) invalid block sz %u\n", ++ ioc->name, raid_device->handle, ++ le16_to_cpu(vol_pg0->BlockSize)); ++ goto out_error; ++ } ++ raid_device->block_exponent = block_exp; ++ raid_device->direct_io_enabled = 1; ++ ++ pr_info(MPT3SAS_FMT "WarpDrive : Direct IO is Enabled for the drive" ++ " with handle(0x%04x)\n", ioc->name, raid_device->handle); ++ /* ++ * WARPDRIVE: Though the following fields are not used for direct IO, ++ * stored for future purpose: ++ */ ++ raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA); ++ raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize); ++ raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize); ++ ++ ++ kfree(vol_pg0); ++ return; ++ ++out_error: ++ raid_device->direct_io_enabled = 0; ++ for (count = 0; count < num_pds; count++) ++ raid_device->pd_handle[count] = 0; ++ kfree(vol_pg0); ++ return; ++} ++ ++/** ++ * mpt2sas_scsi_direct_io_get - returns direct io flag ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Returns the smid stored scmd pointer. ++ */ ++inline u8 ++mpt2sas_scsi_direct_io_get(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ return ioc->scsi_lookup[smid - 1].direct_io; ++} ++ ++/** ++ * mpt2sas_scsi_direct_io_set - sets direct io flag ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @direct_io: Zero or non-zero value to set in the direct_io flag ++ * ++ * Returns Nothing. ++ */ ++inline void ++mpt2sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io) ++{ ++ ioc->scsi_lookup[smid - 1].direct_io = direct_io; ++} ++ ++/** ++ * mpt2sas_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O ++ * @ioc: per adapter object ++ * @scmd: pointer to scsi command object ++ * @raid_device: pointer to raid device data structure ++ * @mpi_request: pointer to the SCSI_IO reqest message frame ++ * @smid: system request message index ++ * ++ * Returns nothing ++ */ ++void ++mpt2sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ++ struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, ++ u16 smid) ++{ ++ sector_t v_lba, p_lba, stripe_off, column, io_size; ++ u32 stripe_sz, stripe_exp; ++ u8 num_pds, cmd = scmd->cmnd[0]; ++ ++ if (cmd != READ_10 && cmd != WRITE_10 && ++ cmd != READ_16 && cmd != WRITE_16) ++ return; ++ ++ if (cmd == READ_10 || cmd == WRITE_10) ++ v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]); ++ else ++ v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]); ++ ++ io_size = scsi_bufflen(scmd) >> raid_device->block_exponent; ++ ++ if (v_lba + io_size - 1 > raid_device->max_lba) ++ return; ++ ++ stripe_sz = raid_device->stripe_sz; ++ stripe_exp = raid_device->stripe_exponent; ++ stripe_off = v_lba & (stripe_sz - 1); ++ ++ /* Return unless IO falls within a stripe */ ++ if (stripe_off + io_size > stripe_sz) ++ return; ++ ++ num_pds = raid_device->num_pds; ++ p_lba = v_lba >> stripe_exp; ++ column = sector_div(p_lba, num_pds); ++ p_lba = (p_lba << stripe_exp) + stripe_off; ++ mpi_request->DevHandle = cpu_to_le16(raid_device->pd_handle[column]); ++ ++ if (cmd == READ_10 || cmd == WRITE_10) ++ put_unaligned_be32(lower_32_bits(p_lba), ++ &mpi_request->CDB.CDB32[2]); ++ else ++ put_unaligned_be64(p_lba, &mpi_request->CDB.CDB32[2]); ++ ++ mpt2sas_scsi_direct_io_set(ioc, smid, 1); ++} +diff --git a/drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c b/drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c +new file mode 100644 +index 0000000..7852050 +--- /dev/null ++++ b/drivers/scsi/mpt2sas/wrapper_mpt3sas_scsih.c +@@ -0,0 +1,4 @@ ++#define MPT2SAS_SCSI ++/* This directive is used to create the mpt2sas driver from the mpt3sas sources */ ++ ++#include "mpt3sas_scsih.c" +diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig +index 5743420..9aa67e2 100644 +--- a/drivers/scsi/mpt3sas/Kconfig ++++ b/drivers/scsi/mpt3sas/Kconfig +@@ -40,14 +40,6 @@ + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + # USA. + +-config SCSI_MPT2SAS +- tristate "LSI MPT Fusion SAS 2.0 Device Driver" +- depends on PCI && SCSI +- select SCSI_SAS_ATTRS +- select RAID_ATTRS +- ---help--- +- This driver supports PCI-Express SAS 6Gb/s Host Adapters. +- + config SCSI_MPT3SAS + tristate "LSI MPT Fusion SAS 3.0 Device Driver" + depends on PCI && SCSI +@@ -56,18 +48,6 @@ config SCSI_MPT3SAS + ---help--- + This driver supports PCI-Express SAS 12Gb/s Host Adapters. + +-config SCSI_MPT2SAS_MAX_SGE +- int "LSI MPT Fusion SAS 2.0 Max number of SG Entries (16 - 256)" +- depends on PCI && SCSI && SCSI_MPT3SAS +- default "128" +- range 16 256 +- ---help--- +- This option allows you to specify the maximum number of scatter- +- gather entries per I/O. The driver default is 128, which matches +- MAX_PHYS_SEGMENTS in most kernels. However in SuSE kernels this +- can be 256. However, it may decreased down to 16. Decreasing this +- parameter will reduce memory requirements on a per controller instance. +- + config SCSI_MPT3SAS_MAX_SGE + int "LSI MPT Fusion SAS 3.0 Max number of SG Entries (16 - 256)" + depends on PCI && SCSI && SCSI_MPT3SAS +diff --git a/drivers/scsi/mpt3sas/Makefile b/drivers/scsi/mpt3sas/Makefile +index 0b90877..450b84b 100644 +--- a/drivers/scsi/mpt3sas/Makefile ++++ b/drivers/scsi/mpt3sas/Makefile +@@ -1,6 +1,5 @@ + # mpt2-3sas makefile + +-obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas.o + obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o + + obj-m += mpt3sas.o +@@ -12,11 +11,3 @@ mpt3sas-y += mpt3sas_base.o \ + mpt3sas_trigger_diag.o \ + mpt3sas_warpdrive.o + +-obj-m += mpt2sas.o +-mpt2sas-y += mpt3sas_base.o \ +- mpt3sas_config.o \ +- wrapper_mpt3sas_scsih.o \ +- mpt3sas_transport.o \ +- mpt3sas_ctl.o \ +- mpt3sas_trigger_diag.o \ +- mpt3sas_warpdrive.o +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch b/kernel-std/centos/patches/Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch new file mode 100644 index 000000000..007a36efc --- /dev/null +++ b/kernel-std/centos/patches/Fix-CentOS-mistake-thinking-that-Xen-is-always-enabl.patch @@ -0,0 +1,37 @@ +From 079d45fa50aedc61785a451a95455ea8e2cf12ff Mon Sep 17 00:00:00 2001 +Message-Id: <079d45fa50aedc61785a451a95455ea8e2cf12ff.1507326318.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Fri, 6 Oct 2017 17:44:05 -0400 +Subject: [PATCH 1/1] Fix CentOS mistake thinking that Xen is always enabled + +We just use the existing CONFIG definition to hook the +code compilation out. + +Signed-off-by: Jim Somerville +--- + arch/x86/kernel/smpboot.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 0e65ae4..420d2d8 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -338,6 +338,7 @@ static void __init smp_init_package_map(struct cpuinfo_x86 *c, unsigned int cpu) + */ + max_physical_pkg_id = DIV_ROUND_UP(MAX_LOCAL_APIC, ncpus); + ++#ifdef CONFIG_XEN_PVHVM + if (x86_hyper == &x86_hyper_xen_hvm) { + /* + * RHEL-only. Each logical package has not more than +@@ -348,6 +349,7 @@ static void __init smp_init_package_map(struct cpuinfo_x86 *c, unsigned int cpu) + */ + __max_logical_packages = min(max_physical_pkg_id, total_cpus); + } ++#endif + + size = max_physical_pkg_id * sizeof(unsigned int); + physical_to_logical_pkg = kmalloc(size, GFP_KERNEL); +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch b/kernel-std/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch new file mode 100644 index 000000000..d186be7f3 --- /dev/null +++ b/kernel-std/centos/patches/Fix-cacheinfo-compilation-issues-for-3.10.patch @@ -0,0 +1,114 @@ +From 5885bd771fe2ef468139178e3dd5a62bb3d355a6 Mon Sep 17 00:00:00 2001 +Message-Id: <5885bd771fe2ef468139178e3dd5a62bb3d355a6.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Wed, 19 Jul 2017 02:25:15 -0500 +Subject: [PATCH 18/24] Fix cacheinfo compilation issues for 3.10 + +Had to revert commit 7cc277b489b4fe91f42eb596b282879c2d13152e: +"Install the callbacks via the state machine and let the core invoke +the callbacks on the already online CPUs. No functional change." +There is no hotplug state machine in 3.10 kernel. +Also implemented cpumap_print_to_pagebuf() function in place. + +Signed-off-by: Jim Somerville +--- + drivers/base/cacheinfo.c | 65 ++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 49 insertions(+), 16 deletions(-) + +diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c +index eb3af27..c924f7e 100644 +--- a/drivers/base/cacheinfo.c ++++ b/drivers/base/cacheinfo.c +@@ -383,7 +383,12 @@ static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + const struct cpumask *mask = &this_leaf->shared_cpu_map; + +- return cpumap_print_to_pagebuf(list, buf, mask); ++ int len = list? ++ cpulist_scnprintf(buf, PAGE_SIZE-2, mask) : ++ cpumask_scnprintf(buf, PAGE_SIZE-2, mask); ++ buf[len++] = '\n'; ++ buf[len] = '\0'; ++ return len; + } + + static ssize_t shared_cpu_map_show(struct device *dev, +@@ -633,30 +638,58 @@ err: + return rc; + } + +-static int cacheinfo_cpu_online(unsigned int cpu) ++static void cache_remove_dev(unsigned int cpu) + { +- int rc = detect_cache_attributes(cpu); ++ if (!cpumask_test_cpu(cpu, &cache_dev_map)) ++ return; ++ cpumask_clear_cpu(cpu, &cache_dev_map); + +- if (rc) +- return rc; +- rc = cache_add_dev(cpu); +- if (rc) +- free_cache_attributes(cpu); +- return rc; ++ cpu_cache_sysfs_exit(cpu); + } + +-static int cacheinfo_cpu_pre_down(unsigned int cpu) ++static int cacheinfo_cpu_callback(struct notifier_block *nfb, ++ unsigned long action, void *hcpu) + { +- if (cpumask_test_and_clear_cpu(cpu, &cache_dev_map)) +- cpu_cache_sysfs_exit(cpu); ++ unsigned int cpu = (unsigned long)hcpu; ++ int rc = 0; + +- free_cache_attributes(cpu); +- return 0; ++ switch (action & ~CPU_TASKS_FROZEN) { ++ case CPU_ONLINE: ++ rc = detect_cache_attributes(cpu); ++ if (!rc) ++ rc = cache_add_dev(cpu); ++ break; ++ case CPU_DEAD: ++ cache_remove_dev(cpu); ++ if (per_cpu_cacheinfo(cpu)) ++ free_cache_attributes(cpu); ++ break; ++ } ++ return notifier_from_errno(rc); + } + + static int __init cacheinfo_sysfs_init(void) + { +- return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/cacheinfo:online", +- cacheinfo_cpu_online, cacheinfo_cpu_pre_down); ++ int cpu, rc = 0; ++ ++ cpu_notifier_register_begin(); ++ ++ for_each_online_cpu(cpu) { ++ rc = detect_cache_attributes(cpu); ++ if (rc) ++ goto out; ++ rc = cache_add_dev(cpu); ++ if (rc) { ++ free_cache_attributes(cpu); ++ pr_err("error populating cacheinfo..cpu%d\n", cpu); ++ goto out; ++ } ++ } ++ __hotcpu_notifier(cacheinfo_cpu_callback, 0); ++ ++out: ++ cpu_notifier_register_done(); ++ return rc; + } ++ + device_initcall(cacheinfo_sysfs_init); +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Fix-compile-issue-when-transparent-hugepages-are-off.patch b/kernel-std/centos/patches/Fix-compile-issue-when-transparent-hugepages-are-off.patch new file mode 100644 index 000000000..ee7faf8d4 --- /dev/null +++ b/kernel-std/centos/patches/Fix-compile-issue-when-transparent-hugepages-are-off.patch @@ -0,0 +1,29 @@ +From 2a9fb6a58e40e8604d97223603111e869bb774b1 Mon Sep 17 00:00:00 2001 +Message-Id: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Thu, 15 Dec 2016 14:27:48 -0500 +Subject: [PATCH 01/24] Fix compile issue when transparent hugepages are off + +Signed-off-by: Jim Somerville +--- + mm/swap.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/mm/swap.c b/mm/swap.c +index 83e2d7d..04a4453 100644 +--- a/mm/swap.c ++++ b/mm/swap.c +@@ -980,8 +980,10 @@ void release_pages(struct page **pages, int nr, bool cold) + if (!put_page_testzero(page)) + continue; + ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE + VM_BUG_ON_PAGE(check_mmu_gather && + trans_huge_mmu_gather_count(page), page); ++#endif + + if (PageLRU(page)) { + if (!was_thp) +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch b/kernel-std/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch new file mode 100644 index 000000000..df6007a2e --- /dev/null +++ b/kernel-std/centos/patches/KVM-x86-Fix-potential-preemption-when-get-the-curren.patch @@ -0,0 +1,91 @@ +From f944a307041bf3d43dbc9ca3484982dfec4340f5 Mon Sep 17 00:00:00 2001 +From: Wanpeng Li +Date: Thu, 11 May 2017 18:12:05 -0700 +Subject: [PATCH 1/1] KVM: x86: Fix potential preemption when get the current + kvmclock timestamp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + BUG: using __this_cpu_read() in preemptible [00000000] code: qemu-system-x86/2809 + caller is __this_cpu_preempt_check+0x13/0x20 + CPU: 2 PID: 2809 Comm: qemu-system-x86 Not tainted 4.11.0+ #13 + Call Trace: + dump_stack+0x99/0xce + check_preemption_disabled+0xf5/0x100 + __this_cpu_preempt_check+0x13/0x20 + get_kvmclock_ns+0x6f/0x110 [kvm] + get_time_ref_counter+0x5d/0x80 [kvm] + kvm_hv_process_stimers+0x2a1/0x8a0 [kvm] + ? kvm_hv_process_stimers+0x2a1/0x8a0 [kvm] + ? kvm_arch_vcpu_ioctl_run+0xac9/0x1ce0 [kvm] + kvm_arch_vcpu_ioctl_run+0x5bf/0x1ce0 [kvm] + kvm_vcpu_ioctl+0x384/0x7b0 [kvm] + ? kvm_vcpu_ioctl+0x384/0x7b0 [kvm] + ? __fget+0xf3/0x210 + do_vfs_ioctl+0xa4/0x700 + ? __fget+0x114/0x210 + SyS_ioctl+0x79/0x90 + entry_SYSCALL_64_fastpath+0x23/0xc2 + RIP: 0033:0x7f9d164ed357 + ? __this_cpu_preempt_check+0x13/0x20 + +This can be reproduced by run kvm-unit-tests/hyperv_stimer.flat w/ +CONFIG_PREEMPT and CONFIG_DEBUG_PREEMPT enabled. + +Safe access to per-CPU data requires a couple of constraints, though: the +thread working with the data cannot be preempted and it cannot be migrated +while it manipulates per-CPU variables. If the thread is preempted, the +thread that replaces it could try to work with the same variables; migration +to another CPU could also cause confusion. However there is no preemption +disable when reads host per-CPU tsc rate to calculate the current kvmclock +timestamp. + +This patch fixes it by utilizing get_cpu/put_cpu pair to guarantee both +__this_cpu_read() and rdtsc() are not preempted. + +Cc: Paolo Bonzini +Cc: Radim Krčmář +Signed-off-by: Wanpeng Li +Reviewed-by: Paolo Bonzini +Cc: stable@vger.kernel.org +Signed-off-by: Radim Krčmář +Signed-off-by: Alex Kozyrev +--- + arch/x86/kvm/x86.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 8babcb5..84925dc 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1743,6 +1743,7 @@ u64 get_kvmclock_ns(struct kvm *kvm) + { + struct kvm_arch *ka = &kvm->arch; + struct pvclock_vcpu_time_info hv_clock; ++ u64 ret; + + spin_lock(&ka->pvclock_gtod_sync_lock); + if (!ka->use_master_clock) { +@@ -1753,10 +1754,17 @@ u64 get_kvmclock_ns(struct kvm *kvm) + hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset; + spin_unlock(&ka->pvclock_gtod_sync_lock); + ++ /* both __this_cpu_read() and rdtsc() should be on the same cpu */ ++ get_cpu(); ++ + kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL, + &hv_clock.tsc_shift, + &hv_clock.tsc_to_system_mul); +- return __pvclock_read_cycles(&hv_clock, rdtsc()); ++ ret = __pvclock_read_cycles(&hv_clock, rdtsc()); ++ ++ put_cpu(); ++ ++ return ret; + } + + static int kvm_guest_time_update(struct kvm_vcpu *v) +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch b/kernel-std/centos/patches/KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch new file mode 100644 index 000000000..b4d529ac5 --- /dev/null +++ b/kernel-std/centos/patches/KVM-x86-remove-irq-disablement-around-KVM_SET_CLOCK-.patch @@ -0,0 +1,132 @@ +From cb6d2db0c89d3470b6f10bf77011bd2b33b956d1 Mon Sep 17 00:00:00 2001 +From: Marcelo Tosatti +Date: Mon, 17 Apr 2017 12:51:37 -0300 +Subject: [PATCH] KVM: x86: remove irq disablement around + KVM_SET_CLOCK/KVM_GET_CLOCK + +The disablement of interrupts at KVM_SET_CLOCK/KVM_GET_CLOCK +attempts to disable software suspend from causing "non atomic behaviour" of +the operation: + + Add a helper function to compute the kernel time and convert nanoseconds + back to CPU specific cycles. Note that these must not be called in preemptible + context, as that would mean the kernel could enter software suspend state, + which would cause non-atomic operation. + +However, assume the kernel can enter software suspend at the following 2 points: + + ktime_get_ts(&ts); +1. + hypothetical_ktime_get_ts(&ts) + monotonic_to_bootbased(&ts); +2. + +monotonic_to_bootbased() should be correct relative to a ktime_get_ts(&ts) +performed after point 1 (that is after resuming from software suspend), +hypothetical_ktime_get_ts() + +Therefore it is also correct for the ktime_get_ts(&ts) before point 1, +which is + + ktime_get_ts(&ts) = hypothetical_ktime_get_ts(&ts) + time-to-execute-suspend-code + +Note CLOCK_MONOTONIC does not count during suspension. + +So remove the irq disablement, which causes the following warning on +-RT kernels: + + With this reasoning, and the -RT bug that the irq disablement causes + (because spin_lock is now a sleeping lock), remove the IRQ protection as it + causes: + + [ 1064.668109] in_atomic(): 0, irqs_disabled(): 1, pid: 15296, name:m + [ 1064.668110] INFO: lockdep is turned off. + [ 1064.668110] irq event stamp: 0 + [ 1064.668112] hardirqs last enabled at (0): [< (null)>] ) + [ 1064.668116] hardirqs last disabled at (0): [] c0 + [ 1064.668118] softirqs last enabled at (0): [] c0 + [ 1064.668118] softirqs last disabled at (0): [< (null)>] ) + [ 1064.668121] CPU: 13 PID: 15296 Comm: qemu-kvm Not tainted 3.10.0-1 + [ 1064.668121] Hardware name: Dell Inc. PowerEdge R730/0H21J3, BIOS 5 + [ 1064.668123] ffff8c1796b88000 00000000afe7344c ffff8c179abf3c68 f3 + [ 1064.668125] ffff8c179abf3c90 ffffffff930ccb3d ffff8c1b992b3610 f0 + [ 1064.668126] 00007ffc1a26fbc0 ffff8c179abf3cb0 ffffffff9375f694 f0 + [ 1064.668126] Call Trace: + [ 1064.668132] [] dump_stack+0x19/0x1b + [ 1064.668135] [] __might_sleep+0x12d/0x1f0 + [ 1064.668138] [] rt_spin_lock+0x24/0x60 + [ 1064.668155] [] __get_kvmclock_ns+0x36/0x110 [k] + [ 1064.668159] [] ? futex_wait_queue_me+0x103/0x10 + [ 1064.668171] [] kvm_arch_vm_ioctl+0xa2/0xd70 [k] + [ 1064.668173] [] ? futex_wait+0x1ac/0x2a0 + +v2: notice get_kvmclock_ns with the same problem (Pankaj). +v3: remove useless helper function (Pankaj). + +Signed-off-by: Marcelo Tosatti +Signed-off-by: Paolo Bonzini +Signed-off-by: Alex Kozyrev +--- + arch/x86/kvm/x86.c | 22 +++------------------- + 1 file changed, 3 insertions(+), 19 deletions(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 08257ab..8babcb5 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -1739,7 +1739,7 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) + #endif + } + +-static u64 __get_kvmclock_ns(struct kvm *kvm) ++u64 get_kvmclock_ns(struct kvm *kvm) + { + struct kvm_arch *ka = &kvm->arch; + struct pvclock_vcpu_time_info hv_clock; +@@ -1759,18 +1759,6 @@ static u64 __get_kvmclock_ns(struct kvm *kvm) + return __pvclock_read_cycles(&hv_clock, rdtsc()); + } + +-u64 get_kvmclock_ns(struct kvm *kvm) +-{ +- unsigned long flags; +- s64 ns; +- +- local_irq_save(flags); +- ns = __get_kvmclock_ns(kvm); +- local_irq_restore(flags); +- +- return ns; +-} +- + static int kvm_guest_time_update(struct kvm_vcpu *v) + { + unsigned long flags, this_tsc_khz, tgt_tsc_khz; +@@ -4064,10 +4052,8 @@ long kvm_arch_vm_ioctl(struct file *filp, + goto out; + + r = 0; +- local_irq_disable(); +- now_ns = __get_kvmclock_ns(kvm); ++ now_ns = get_kvmclock_ns(kvm); + kvm->arch.kvmclock_offset += user_ns.clock - now_ns; +- local_irq_enable(); + kvm_gen_update_masterclock(kvm); + break; + } +@@ -4075,11 +4061,9 @@ long kvm_arch_vm_ioctl(struct file *filp, + struct kvm_clock_data user_ns; + u64 now_ns; + +- local_irq_disable(); +- now_ns = __get_kvmclock_ns(kvm); ++ now_ns = get_kvmclock_ns(kvm); + user_ns.clock = now_ns; + user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0; +- local_irq_enable(); + memset(&user_ns.pad, 0, sizeof(user_ns.pad)); + + r = -EFAULT; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Make-kernel-start-eth-devices-at-offset.patch b/kernel-std/centos/patches/Make-kernel-start-eth-devices-at-offset.patch new file mode 100644 index 000000000..541ce6dd6 --- /dev/null +++ b/kernel-std/centos/patches/Make-kernel-start-eth-devices-at-offset.patch @@ -0,0 +1,37 @@ +From be88bcf5edaddf40eb482b07ef81b00aa68bef07 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Thu, 12 May 2016 18:00:00 -0400 +Subject: [PATCH 07/24] Make kernel start eth devices at offset + +In order to avoid naming collisions, we want to make the kernel +start naming its "ethX" devices at eth1000 instead of eth0. This +will let us rename to a range starting at eth0. + +Signed-off-by: Jim Somerville +--- + net/core/dev.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 7e4cf91..c1b106b 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1055,6 +1055,12 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + set_bit(i, inuse); + } + ++ /* WRS extension, want kernel to start at eth1000 */ ++ if (strcmp(name, "eth%d") == 0) { ++ for (i=0; i < 1000; i++) ++ set_bit(i, inuse); ++ } ++ + i = find_first_zero_bit(inuse, max_netdevices); + free_page((unsigned long) inuse); + } +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Notification-of-death-of-arbitrary-processes.patch b/kernel-std/centos/patches/Notification-of-death-of-arbitrary-processes.patch new file mode 100644 index 000000000..0b44f9f06 --- /dev/null +++ b/kernel-std/centos/patches/Notification-of-death-of-arbitrary-processes.patch @@ -0,0 +1,537 @@ +From cb94dd408a78d64dd38e73c06e9866671ee7d6f4 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Chris Friesen +Date: Thu, 7 Apr 2016 11:16:19 -0600 +Subject: [PATCH 1/1] Notification of death of arbitrary processes + +Note: this commit was copied from Titanium Cloud Rel2 + +This exposes a new feature which may be called to request +notification when an arbitrary process changes state. The +caller specifies a pid, signal number, and event mask, and +when that pid dies, or is stopped, or anything else that +would normally cause a SIGCHLD, the kernel will send the +specified signal to the caller if the event is in the event +mask originally passed down. The siginfo_t struct will +contain the same information as would be included with SIGCHLD. + +This is exposed to userspace via the prctl() call with the +PR_DO_NOTIFY_TASK_STATE option. + +Signed-off-by: Jim Somerville +--- + include/linux/init_task.h | 9 ++ + include/linux/sched.h | 6 ++ + include/uapi/linux/prctl.h | 18 ++++ + init/Kconfig | 15 +++ + kernel/Makefile | 1 + + kernel/death_notify.c | 227 +++++++++++++++++++++++++++++++++++++++++++++ + kernel/death_notify.h | 45 +++++++++ + kernel/exit.c | 6 ++ + kernel/fork.c | 4 + + kernel/signal.c | 11 +++ + kernel/sys.c | 9 ++ + 11 files changed, 351 insertions(+) + create mode 100644 kernel/death_notify.c + create mode 100644 kernel/death_notify.h + +diff --git a/include/linux/init_task.h b/include/linux/init_task.h +index a05294b..cfb7197 100644 +--- a/include/linux/init_task.h ++++ b/include/linux/init_task.h +@@ -77,6 +77,14 @@ extern struct nsproxy init_nsproxy; + .signalfd_wqh = __WAIT_QUEUE_HEAD_INITIALIZER(sighand.signalfd_wqh), \ + } + ++#ifdef CONFIG_SIGEXIT ++#define INIT_SIGEXIT(tsk) \ ++ .notify = LIST_HEAD_INIT(tsk.notify), \ ++ .monitor = LIST_HEAD_INIT(tsk.monitor), ++#else ++#define INIT_SIGEXIT(tsk) ++#endif ++ + extern struct group_info init_groups; + + #define INIT_STRUCT_PID { \ +@@ -224,6 +232,7 @@ extern struct task_group root_task_group; + .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ + .journal_info = NULL, \ + .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ ++ INIT_SIGEXIT(tsk) \ + .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ + .timer_slack_ns = 50000, /* 50 usec default slack */ \ + .pids = { \ +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 17d2f0b..78ff960 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1627,6 +1627,12 @@ struct task_struct { + short il_next; + short pref_node_fork; + #endif ++#ifdef CONFIG_SIGEXIT ++ /* list of processes to notify on death */ ++ struct list_head notify; ++ /* list of outstanding monitor requests */ ++ struct list_head monitor; ++#endif + #ifdef CONFIG_NUMA_BALANCING + int numa_scan_seq; + unsigned int numa_scan_period; +diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h +index f818d08..3e0d502 100644 +--- a/include/uapi/linux/prctl.h ++++ b/include/uapi/linux/prctl.h +@@ -55,6 +55,24 @@ + #define PR_SET_NAME 15 /* Set process name */ + #define PR_GET_NAME 16 /* Get process name */ + ++#ifdef CONFIG_SIGEXIT ++#define PR_DO_NOTIFY_TASK_STATE 17 /* Set/get notification for task ++ state changes */ ++ ++/* This is the data structure for requestion process death ++ * (and other state change) information. Sig of -1 means ++ * query, sig of 0 means deregistration, positive sig means ++ * that you want to set it. sig and events are value-result ++ * and will be updated with the previous values on every ++ * successful call. ++ */ ++struct task_state_notify_info { ++ pid_t pid; ++ int sig; ++ unsigned int events; ++}; ++#endif ++ + /* Get/set process endian */ + #define PR_GET_ENDIAN 19 + #define PR_SET_ENDIAN 20 +diff --git a/init/Kconfig b/init/Kconfig +index e5f56f1..ae33fe8 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1537,6 +1537,21 @@ config VM_EVENT_COUNTERS + on EXPERT systems. /proc/vmstat will only show page counts + if VM event counters are disabled. + ++config SIGEXIT ++ bool "Notification of death of arbitrary processes" ++ default n ++ help ++ When enabled this exposes a new feature which may be called to request ++ notification when an arbitrary process changes state. The caller specifies ++ a pid, signal number, and event mask, and when that pid dies, or is ++ stopped, or anything else that would normally cause a SIGCHLD, the ++ kernel will send the specified signal to the caller if the event is in ++ the event mask originally passed down. The siginfo_t struct will ++ contain the same information as would be included with SIGCHLD. ++ ++ This is exposed to userspace via the prctl() ++ call with the PR_DO_NOTIFY_TASK_STATE option ++ + config SLUB_DEBUG + default y + bool "Enable SLUB debugging support" if EXPERT +diff --git a/kernel/Makefile b/kernel/Makefile +index b954c25..5701720 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -111,6 +111,7 @@ obj-$(CONFIG_RING_BUFFER) += trace/ + obj-$(CONFIG_TRACEPOINTS) += trace/ + obj-$(CONFIG_IRQ_WORK) += irq_work.o + obj-$(CONFIG_CPU_PM) += cpu_pm.o ++obj-$(CONFIG_SIGEXIT) += death_notify.o + + obj-$(CONFIG_PERF_EVENTS) += events/ + +diff --git a/kernel/death_notify.c b/kernel/death_notify.c +new file mode 100644 +index 0000000..889b929 +--- /dev/null ++++ b/kernel/death_notify.c +@@ -0,0 +1,227 @@ ++/* ++ * kernel/death_notify.c, Process death notification support ++ * ++ * Copyright (c) 2006-2014 Wind River Systems, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See the GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "death_notify.h" ++ ++static void unlink_status_notifier(struct signotifier *n) ++{ ++ list_del(&n->monitor_list); ++ list_del(&n->notify_list); ++ kfree(n); ++} ++ ++static void handle_already_monitoring(struct signotifier *node, ++ struct task_state_notify_info *args, ++ struct task_state_notify_info *oldargs) ++{ ++ /* Store the old values */ ++ oldargs->sig = node->sig; ++ oldargs->events = node->events; ++ ++ /* We know that args->sig is 0 or a valid signal. */ ++ if (args->sig > 0) { ++ /* Update the new values */ ++ node->sig = args->sig; ++ node->events = args->events; ++ } else if (!args->sig) { ++ /* args->sig of 0 means to deregister */ ++ unlink_status_notifier(node); ++ } ++} ++ ++static void setup_new_node(struct task_struct *p, ++ struct signotifier *node, ++ struct task_state_notify_info *args) ++{ ++ node->notify_tsk = current; ++ node->sig = args->sig; ++ node->events = args->events; ++ ++ /* Add this node to the list of notification requests ++ * for the specified process. ++ */ ++ list_add_tail(&node->notify_list, &p->notify); ++ ++ /* Also add this node to the list of monitor requests ++ * for the current process. ++ */ ++ list_add_tail(&node->monitor_list, ¤t->monitor); ++} ++ ++ ++/* Returns 0 if arguments are valid, 1 if they are not. */ ++static int invalid_args(struct task_state_notify_info *args) ++{ ++ int ret = 1; ++ ++ if (args->pid <= 0) ++ goto out; ++ ++ /* Sig of -1 implies query, sig of 0 implies deregistration. ++ * Otherwise sig must be positive and within range. ++ */ ++ if ((args->sig < -1) || (args->sig > _NSIG)) ++ goto out; ++ ++ /* If positive sig, must have valid events. */ ++ if (args->sig > 0) { ++ if (!args->events || (args->events >= (1 << (NSIGCHLD+1)))) ++ goto out; ++ } ++ ++ ret = 0; ++out: ++ return ret; ++} ++ ++/* Notify those registered for process state updates via do_notify_task_state(). ++ * If "del" is nonzero, the process is dying and we want to free ++ * the nodes in the list as we go. ++ * ++ * Note: we only notify processes for events in which they have registered ++ * interest. ++ * ++ * Must be called holding a lock on tasklist_lock. ++ */ ++void do_notify_others(struct task_struct *tsk, struct siginfo *info) ++{ ++ struct signotifier *node; ++ unsigned int events; ++ ++ /* This method of generating the event bit must be ++ * matched in the userspace library. ++ */ ++ events = 1 << (info->si_code & 0xFF); ++ ++ list_for_each_entry(node, &tsk->notify, notify_list) { ++ if (events & node->events) { ++ info->si_signo = node->sig; ++ group_send_sig_info(node->sig, info, node->notify_tsk); ++ } ++ } ++} ++ ++void release_notify_others(struct task_struct *p) ++{ ++ struct signotifier *n, *t; ++ ++ /* Need to clean up any outstanding requests where we ++ * wanted to be notified when others died. ++ */ ++ list_for_each_entry_safe(n, t, &p->monitor, monitor_list) { ++ unlink_status_notifier(n); ++ } ++ ++ /* Also need to clean up any outstanding requests where others ++ * wanted to be notified when we died. ++ */ ++ list_for_each_entry_safe(n, t, &p->notify, notify_list) { ++ unlink_status_notifier(n); ++ } ++} ++ ++/* If the config is defined, then processes can call this routine ++ * to request notification when the specified task's state changes. ++ * On the death (or other state change) of the specified process, ++ * we will send them the specified signal if the event is listed ++ * in their event bitfield. ++ * ++ * A sig of 0 means that we want to deregister. ++ * ++ * The sig/events fields are value/result. On success we update them ++ * to reflect what they were before the call. ++ * ++ * Returns error code on error, on success we return 0. ++ */ ++int do_notify_task_state(unsigned long arg) ++{ ++ int err; ++ struct task_struct *p; ++ struct signotifier *node, *tmp; ++ struct task_state_notify_info args, oldargs; ++ ++ if (copy_from_user(&args, (struct task_state_notify_info __user *)arg, ++ sizeof(args))) ++ return -EFAULT; ++ oldargs.pid = args.pid; ++ ++ /* Validate the arguments passed in. */ ++ err = -EINVAL; ++ if (invalid_args(&args)) ++ goto out; ++ ++ /* We must hold a write lock on tasklist_lock to add the notification ++ * later on, and we need some lock on tasklist_lock for ++ * find_task_by_pid(), so may as well take the write lock now. ++ * Must use write_lock_irq(). ++ */ ++ qwrite_lock_irq(&tasklist_lock); ++ ++ err = -ESRCH; ++ p = find_task_by_vpid(args.pid); ++ if (!p) ++ goto unlock_out; ++ ++ /* Now we know pid exists, unlikely to fail. */ ++ err = 0; ++ ++ /* Check if we're already monitoring the specified pid. If so, update ++ * the monitoring parameters and return the old ones. ++ */ ++ list_for_each_entry(tmp, &p->notify, notify_list) { ++ if (tmp->notify_tsk == current) { ++ handle_already_monitoring(tmp, &args, &oldargs); ++ goto unlock_out; ++ } ++ } ++ ++ /* If we get here, we're not currently monitoring the process. */ ++ oldargs.sig = 0; ++ oldargs.events = 0; ++ ++ /* If we wanted to set up a new monitor, do it now. If we didn't ++ * manage to allocate memory for the new node, then we return ++ * an appropriate error. ++ */ ++ if (args.sig > 0) { ++ node = kmalloc(sizeof(*node), GFP_ATOMIC); ++ if (node) ++ setup_new_node(p, node, &args); ++ else ++ err = -ENOMEM; ++ } ++ ++unlock_out: ++ qwrite_unlock_irq(&tasklist_lock); ++ ++ /* Copy the old values back to caller. */ ++ if (copy_to_user((struct task_state_notify_info __user *)arg, ++ &oldargs, sizeof(oldargs))) ++ err = -EFAULT; ++ ++out: ++ return err; ++} +diff --git a/kernel/death_notify.h b/kernel/death_notify.h +new file mode 100644 +index 0000000..b2b8e8c +--- /dev/null ++++ b/kernel/death_notify.h +@@ -0,0 +1,45 @@ ++/* ++ * kernel/death_notify.h, Process death notification support ++ * ++ * Copyright (c) 2006-2014 Wind River Systems, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ * See the GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++#ifndef _KERNEL_DEATH_NOTIFY_H ++#define _KERNEL_DEATH_NOTIFY_H ++ ++#ifdef CONFIG_SIGEXIT ++ ++struct signotifier { ++ struct task_struct *notify_tsk; ++ struct list_head notify_list; ++ struct list_head monitor_list; ++ int sig; ++ unsigned int events; ++}; ++ ++extern int do_notify_task_state(unsigned long arg); ++extern void do_notify_others(struct task_struct *tsk, ++ struct siginfo *info); ++extern void release_notify_others(struct task_struct *p); ++ ++#else /* !CONFIG_SIGEXIT */ ++ ++static inline void do_notify_others(struct task_struct *tsk, ++ struct siginfo *info) {} ++static inline void release_notify_others(struct task_struct *p) {} ++ ++#endif /* CONFIG_SIGEXIT */ ++#endif +diff --git a/kernel/exit.c b/kernel/exit.c +index 1afa799..a2ea26b 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -59,6 +59,9 @@ + #include + #include + #include ++#ifdef CONFIG_SIGEXIT ++#include "death_notify.h" ++#endif + + static void exit_mm(struct task_struct * tsk); + +@@ -184,6 +187,9 @@ repeat: + proc_flush_task(p); + + tasklist_write_lock_irq(); ++#ifdef CONFIG_SIGEXIT ++ release_notify_others(p); ++#endif + ptrace_release_task(p); + __exit_signal(p); + +diff --git a/kernel/fork.c b/kernel/fork.c +index d1ed92e..df06609 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1428,6 +1428,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, + p->sequential_io = 0; + p->sequential_io_avg = 0; + #endif ++#ifdef CONFIG_SIGEXIT ++ INIT_LIST_HEAD(&p->notify); ++ INIT_LIST_HEAD(&p->monitor); ++#endif + + /* Perform scheduler related setup. Assign this task to a CPU. */ + retval = sched_fork(clone_flags, p); +diff --git a/kernel/signal.c b/kernel/signal.c +index 2dec6a0..fac06fe 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -44,6 +44,9 @@ + #include + #include + #include "audit.h" /* audit_signal_info() */ ++#ifdef CONFIG_SIGEXIT ++#include "death_notify.h" ++#endif + + /* + * SLAB caches for signal bits. +@@ -1721,6 +1724,10 @@ bool do_notify_parent(struct task_struct *tsk, int sig) + __wake_up_parent(tsk, tsk->parent); + spin_unlock_irqrestore(&psig->siglock, flags); + ++#ifdef CONFIG_SIGEXIT ++ do_notify_others(tsk, &info); ++#endif ++ + return autoreap; + } + +@@ -1792,6 +1799,10 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, + */ + __wake_up_parent(tsk, parent); + spin_unlock_irqrestore(&sighand->siglock, flags); ++ ++#ifdef CONFIG_SIGEXIT ++ do_notify_others(tsk, &info); ++#endif + } + + static inline int may_ptrace_stop(void) +diff --git a/kernel/sys.c b/kernel/sys.c +index 20c59a4..b693e10 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -62,6 +62,10 @@ + #include + #include + ++#ifdef CONFIG_SIGEXIT ++#include "death_notify.h" ++#endif ++ + #ifndef SET_UNALIGN_CTL + # define SET_UNALIGN_CTL(a,b) (-EINVAL) + #endif +@@ -2462,6 +2466,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + else + error = PR_MCE_KILL_DEFAULT; + break; ++#ifdef CONFIG_SIGEXIT ++ case PR_DO_NOTIFY_TASK_STATE: ++ error = do_notify_task_state(arg2); ++ break; ++#endif + case PR_SET_MM: + error = prctl_set_mm(arg2, arg3, arg4, arg5); + break; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch b/kernel-std/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch new file mode 100644 index 000000000..2acf8947d --- /dev/null +++ b/kernel-std/centos/patches/PCI-Add-ACS-quirk-for-Intel-Fortville-NICs.patch @@ -0,0 +1,34 @@ +From 7f56a1c1ad4f6b1437165a73493a69eeea68fd95 Mon Sep 17 00:00:00 2001 +Message-Id: <7f56a1c1ad4f6b1437165a73493a69eeea68fd95.1507237258.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Dahir Osman +Date: Wed, 13 Jan 2016 10:01:11 -0500 +Subject: [PATCH 04/24] PCI: Add ACS quirk for Intel Fortville NICs + +Use quirks to determine isolation for now until a later kernel can +properly read the Fortville ACS capabilities. + +Signed-off-by: Jim Somerville +--- + drivers/pci/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index f6f2658..b5349eb 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4108,6 +4108,10 @@ static const struct pci_dev_acs_enabled { + /* I219 */ + { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs }, ++ /* I40 */ ++ { PCI_VENDOR_ID_INTEL, 0x1572, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_INTEL, 0x1586, pci_quirk_mf_endpoint_acs }, ++ { PCI_VENDOR_ID_INTEL, 0x1583, pci_quirk_mf_endpoint_acs }, + /* Intel PCH root ports */ + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch b/kernel-std/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch new file mode 100644 index 000000000..f53e49fa9 --- /dev/null +++ b/kernel-std/centos/patches/Porting-Cacheinfo-from-Kernel-4.10.17.patch @@ -0,0 +1,2120 @@ +From 9ba8854c1a69af4ac3751b0340d0f1fc26c4b6b9 Mon Sep 17 00:00:00 2001 +Message-Id: <9ba8854c1a69af4ac3751b0340d0f1fc26c4b6b9.1507321503.git.Jim.Somerville@windriver.com> +From: Alex Kozyrev +Date: Wed, 19 Jul 2017 02:21:59 -0500 +Subject: [PATCH 1/1] Porting Cacheinfo from Kernel 4.10.17 + +Original source code from tag v4.10.17 in Linux stable tree for: +intel_cacheinfo.c, cacheinfo.c and cacheinfo.h. +Main commit that we are interested for is 246246cbde5e840012f853e27630ebb59f409486: +This patch adds initial support for providing processor cache information +to userspace through sysfs interface. This is based on already existing +implementations(x86, ia64, s390 and powerpc) and hence the interface is +intended to be fully compatible. + +The main purpose of this generic support is to avoid further code +duplication to support new architectures and also to unify all the existing +different implementations. + +This implementation maintains the hierarchy of cache objects which reflects +the system's cache topology. Cache devices are instantiated as needed as +CPUs come online. The cache information is replicated per-cpu even if they are +shared. A per-cpu array of cache information maintained is used mainly for +sysfs-related book keeping. + +It also implements the shared_cpu_map attribute, which is essential for +enabling both kernel and user-space to discover the system's overall cache +topology. + +This patch also add the missing ABI documentation for the cacheinfo sysfs +interface already, which is well defined and widely used. + +sysfs-devices-system-cpu was nodified by taking commit 1d78dc59f5ab6f467e49882518453adc7e4caa44: +Add an ABI document entry for /sys/devices/system/cpu/cpu*/cache/index*/id. + +cpu.h and cpu.c was enhanced with commit 3d52943b3a51497a777e6d7d840a38596a92cee9: +This patch adds a new function to create per-cpu devices. +This helps in: +1. reusing the device infrastructure to create any cpu related + attributes and corresponding sysfs instead of creating and + dealing with raw kobjects directly +2. retaining the legacy path(/sys/devices/system/cpu/..) to support + existing sysfs ABI +3. avoiding to create links in the bus directory pointing to the + device as there would be per-cpu instance of these devices with + the same name since dev->bus is not populated to cpu_sysbus on + purpose + +Signed-off-by: Jim Somerville +--- + Documentation/ABI/testing/sysfs-devices-system-cpu | 65 ++ + arch/x86/kernel/cpu/intel_cacheinfo.c | 832 +++++++-------------- + drivers/base/Makefile | 2 +- + drivers/base/cacheinfo.c | 662 ++++++++++++++++ + drivers/base/cpu.c | 54 ++ + include/linux/cacheinfo.h | 104 +++ + include/linux/cpu.h | 3 + + 7 files changed, 1148 insertions(+), 574 deletions(-) + create mode 100644 drivers/base/cacheinfo.c + create mode 100644 include/linux/cacheinfo.h + +diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu +index 4a639ed..9e877e1 100644 +--- a/Documentation/ABI/testing/sysfs-devices-system-cpu ++++ b/Documentation/ABI/testing/sysfs-devices-system-cpu +@@ -201,6 +201,71 @@ Description: address and size of the percpu note. + + crash_notes_size: size of the note of cpu#. + ++ ++What: /sys/devices/system/cpu/cpu*/cache/index*/ ++Date: July 2014(documented, existed before August 2008) ++Contact: Sudeep Holla ++ Linux kernel mailing list ++Description: Parameters for the CPU cache attributes ++ ++ allocation_policy: ++ - WriteAllocate: allocate a memory location to a cache line ++ on a cache miss because of a write ++ - ReadAllocate: allocate a memory location to a cache line ++ on a cache miss because of a read ++ - ReadWriteAllocate: both writeallocate and readallocate ++ ++ attributes: LEGACY used only on IA64 and is same as write_policy ++ ++ coherency_line_size: the minimum amount of data in bytes that gets ++ transferred from memory to cache ++ ++ level: the cache hierarchy in the multi-level cache configuration ++ ++ number_of_sets: total number of sets in the cache, a set is a ++ collection of cache lines with the same cache index ++ ++ physical_line_partition: number of physical cache line per cache tag ++ ++ shared_cpu_list: the list of logical cpus sharing the cache ++ ++ shared_cpu_map: logical cpu mask containing the list of cpus sharing ++ the cache ++ ++ size: the total cache size in kB ++ ++ type: ++ - Instruction: cache that only holds instructions ++ - Data: cache that only caches data ++ - Unified: cache that holds both data and instructions ++ ++ ways_of_associativity: degree of freedom in placing a particular block ++ of memory in the cache ++ ++ write_policy: ++ - WriteThrough: data is written to both the cache line ++ and to the block in the lower-level memory ++ - WriteBack: data is written only to the cache line and ++ the modified cache line is written to main ++ memory only when it is replaced ++ ++ ++What: /sys/devices/system/cpu/cpu*/cache/index*/id ++Date: September 2016 ++Contact: Linux kernel mailing list ++Description: Cache id ++ ++ The id provides a unique number for a specific instance of ++ a cache of a particular type. E.g. there may be a level ++ 3 unified cache on each socket in a server and we may ++ assign them ids 0, 1, 2, ... ++ ++ Note that id value can be non-contiguous. E.g. level 1 ++ caches typically exist per core, but there may not be a ++ power of two cores on a socket, so these caches may be ++ numbered 0, 1, 2, 3, 4, 5, 8, 9, 10, ... ++ ++ + What: /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/turbo_stat + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/sub_turbo_stat +diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c +index 3182124..d8bb5bd 100644 +--- a/arch/x86/kernel/cpu/intel_cacheinfo.c ++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c +@@ -1,5 +1,5 @@ + /* +- * Routines to indentify caches on Intel CPU. ++ * Routines to identify caches on Intel CPU. + * + * Changes: + * Venkatesh Pallipadi : Adding cache identification through cpuid(4) +@@ -7,16 +7,14 @@ + * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD. + */ + +-#include + #include +-#include +-#include ++#include + #include + #include ++#include + #include + +-#include +-#include ++#include + #include + #include + +@@ -116,10 +114,10 @@ static const struct _cache_table cache_table[] = + + + enum _cache_type { +- CACHE_TYPE_NULL = 0, +- CACHE_TYPE_DATA = 1, +- CACHE_TYPE_INST = 2, +- CACHE_TYPE_UNIFIED = 3 ++ CTYPE_NULL = 0, ++ CTYPE_DATA = 1, ++ CTYPE_INST = 2, ++ CTYPE_UNIFIED = 3 + }; + + union _cpuid4_leaf_eax { +@@ -160,12 +158,7 @@ struct _cpuid4_info_regs { + struct amd_northbridge *nb; + }; + +-struct _cpuid4_info { +- struct _cpuid4_info_regs base; +- DECLARE_BITMAP(shared_cpu_map, NR_CPUS); +-}; +- +-unsigned short num_cache_leaves; ++static unsigned short num_cache_leaves; + + /* AMD doesn't have CPUID4. Emulate it here to report the same + information to the user. This makes some assumptions about the machine: +@@ -221,6 +214,13 @@ static const unsigned short assocs[] = { + static const unsigned char levels[] = { 1, 1, 2, 3 }; + static const unsigned char types[] = { 1, 2, 3, 3 }; + ++static const enum cache_type cache_type_map[] = { ++ [CTYPE_NULL] = CACHE_TYPE_NOCACHE, ++ [CTYPE_DATA] = CACHE_TYPE_DATA, ++ [CTYPE_INST] = CACHE_TYPE_INST, ++ [CTYPE_UNIFIED] = CACHE_TYPE_UNIFIED, ++}; ++ + static void + amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, + union _cpuid4_leaf_ebx *ebx, +@@ -292,14 +292,8 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, + (ebx->split.ways_of_associativity + 1) - 1; + } + +-struct _cache_attr { +- struct attribute attr; +- ssize_t (*show)(struct _cpuid4_info *, char *, unsigned int); +- ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count, +- unsigned int); +-}; +- + #if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS) ++ + /* + * L3 cache descriptors + */ +@@ -326,20 +320,6 @@ static void amd_calc_l3_indices(struct amd_northbridge *nb) + l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; + } + +-static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) +-{ +- int node; +- +- /* only for L3, and not in virtualized environments */ +- if (index < 3) +- return; +- +- node = amd_get_nb_id(smp_processor_id()); +- this_leaf->nb = node_to_amd_nb(node); +- if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) +- amd_calc_l3_indices(this_leaf->nb); +-} +- + /* + * check whether a slot used for disabling an L3 index is occupied. + * @l3: L3 cache descriptor +@@ -347,7 +327,7 @@ static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) + * + * @returns: the disabled index if used or negative value if slot free. + */ +-int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) ++static int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) + { + unsigned int reg = 0; + +@@ -360,15 +340,13 @@ int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) + return -1; + } + +-static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, ++static ssize_t show_cache_disable(struct cacheinfo *this_leaf, char *buf, + unsigned int slot) + { + int index; ++ struct amd_northbridge *nb = this_leaf->priv; + +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) +- return -EINVAL; +- +- index = amd_get_l3_disable_slot(this_leaf->base.nb, slot); ++ index = amd_get_l3_disable_slot(nb, slot); + if (index >= 0) + return sprintf(buf, "%d\n", index); + +@@ -377,9 +355,10 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, + + #define SHOW_CACHE_DISABLE(slot) \ + static ssize_t \ +-show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf, \ +- unsigned int cpu) \ ++cache_disable_##slot##_show(struct device *dev, \ ++ struct device_attribute *attr, char *buf) \ + { \ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ + return show_cache_disable(this_leaf, buf, slot); \ + } + SHOW_CACHE_DISABLE(0) +@@ -425,8 +404,8 @@ static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu, + * + * @return: 0 on success, error status on failure + */ +-int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, +- unsigned long index) ++static int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, ++ unsigned slot, unsigned long index) + { + int ret = 0; + +@@ -447,28 +426,26 @@ int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, + return 0; + } + +-static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, +- const char *buf, size_t count, +- unsigned int slot) ++static ssize_t store_cache_disable(struct cacheinfo *this_leaf, ++ const char *buf, size_t count, ++ unsigned int slot) + { + unsigned long val = 0; + int cpu, err = 0; ++ struct amd_northbridge *nb = this_leaf->priv; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) +- return -EINVAL; +- +- cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); ++ cpu = cpumask_first(&this_leaf->shared_cpu_map); + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + +- err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); ++ err = amd_set_l3_disable_slot(nb, cpu, slot, val); + if (err) { + if (err == -EEXIST) +- pr_warning("L3 slot %d in use/index already disabled!\n", ++ pr_warn("L3 slot %d in use/index already disabled!\n", + slot); + return err; + } +@@ -477,41 +454,36 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, + + #define STORE_CACHE_DISABLE(slot) \ + static ssize_t \ +-store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \ +- const char *buf, size_t count, \ +- unsigned int cpu) \ ++cache_disable_##slot##_store(struct device *dev, \ ++ struct device_attribute *attr, \ ++ const char *buf, size_t count) \ + { \ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ + return store_cache_disable(this_leaf, buf, count, slot); \ + } + STORE_CACHE_DISABLE(0) + STORE_CACHE_DISABLE(1) + +-static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644, +- show_cache_disable_0, store_cache_disable_0); +-static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, +- show_cache_disable_1, store_cache_disable_1); +- +-static ssize_t +-show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu) ++static ssize_t subcaches_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- return -EINVAL; ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ int cpu = cpumask_first(&this_leaf->shared_cpu_map); + + return sprintf(buf, "%x\n", amd_get_subcaches(cpu)); + } + +-static ssize_t +-store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, +- unsigned int cpu) ++static ssize_t subcaches_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) + { ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ int cpu = cpumask_first(&this_leaf->shared_cpu_map); + unsigned long val; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- return -EINVAL; +- + if (kstrtoul(buf, 16, &val) < 0) + return -EINVAL; + +@@ -521,9 +493,92 @@ store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, + return count; + } + +-static struct _cache_attr subcaches = +- __ATTR(subcaches, 0644, show_subcaches, store_subcaches); ++static DEVICE_ATTR_RW(cache_disable_0); ++static DEVICE_ATTR_RW(cache_disable_1); ++static DEVICE_ATTR_RW(subcaches); ++ ++static umode_t ++cache_private_attrs_is_visible(struct kobject *kobj, ++ struct attribute *attr, int unused) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ umode_t mode = attr->mode; ++ ++ if (!this_leaf->priv) ++ return 0; ++ ++ if ((attr == &dev_attr_subcaches.attr) && ++ amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ return mode; ++ ++ if ((attr == &dev_attr_cache_disable_0.attr || ++ attr == &dev_attr_cache_disable_1.attr) && ++ amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) ++ return mode; ++ ++ return 0; ++} ++ ++static struct attribute_group cache_private_group = { ++ .is_visible = cache_private_attrs_is_visible, ++}; ++ ++static void init_amd_l3_attrs(void) ++{ ++ int n = 1; ++ static struct attribute **amd_l3_attrs; ++ ++ if (amd_l3_attrs) /* already initialized */ ++ return; ++ ++ if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) ++ n += 2; ++ if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ n += 1; ++ ++ amd_l3_attrs = kcalloc(n, sizeof(*amd_l3_attrs), GFP_KERNEL); ++ if (!amd_l3_attrs) ++ return; ++ ++ n = 0; ++ if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) { ++ amd_l3_attrs[n++] = &dev_attr_cache_disable_0.attr; ++ amd_l3_attrs[n++] = &dev_attr_cache_disable_1.attr; ++ } ++ if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ amd_l3_attrs[n++] = &dev_attr_subcaches.attr; ++ ++ cache_private_group.attrs = amd_l3_attrs; ++} ++ ++const struct attribute_group * ++cache_get_priv_group(struct cacheinfo *this_leaf) ++{ ++ struct amd_northbridge *nb = this_leaf->priv; ++ ++ if (this_leaf->level < 3 || !nb) ++ return NULL; ++ ++ if (nb && nb->l3_cache.indices) ++ init_amd_l3_attrs(); ++ ++ return &cache_private_group; ++} ++ ++static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) ++{ ++ int node; ++ ++ /* only for L3, and not in virtualized environments */ ++ if (index < 3) ++ return; + ++ node = amd_get_nb_id(smp_processor_id()); ++ this_leaf->nb = node_to_amd_nb(node); ++ if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) ++ amd_calc_l3_indices(this_leaf->nb); ++} + #else + #define amd_init_l3_cache(x, y) + #endif /* CONFIG_AMD_NB && CONFIG_SYSFS */ +@@ -537,7 +592,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) + unsigned edx; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- if (cpu_has_topoext) ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) + cpuid_count(0x8000001d, index, &eax.full, + &ebx.full, &ecx.full, &edx); + else +@@ -547,7 +602,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) + cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); + } + +- if (eax.split.type == CACHE_TYPE_NULL) ++ if (eax.split.type == CTYPE_NULL) + return -EIO; /* better error ? */ + + this_leaf->eax = eax; +@@ -576,14 +631,14 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) + /* Do cpuid(op) loop to find out num_cache_leaves */ + cpuid_count(op, i, &eax, &ebx, &ecx, &edx); + cache_eax.full = eax; +- } while (cache_eax.split.type != CACHE_TYPE_NULL); ++ } while (cache_eax.split.type != CTYPE_NULL); + return i; + } + + void init_amd_cacheinfo(struct cpuinfo_x86 *c) + { + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + num_cache_leaves = find_num_cache_leaves(c); + } else if (c->extended_cpuid_level >= 0x80000006) { + if (cpuid_edx(0x80000006) & 0xf000) +@@ -600,7 +655,7 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) + unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ + unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ + unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; +-#ifdef CONFIG_X86_HT ++#ifdef CONFIG_SMP + unsigned int cpu = c->cpu_index; + #endif + +@@ -618,36 +673,34 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) + * parameters cpuid leaf to find the cache details + */ + for (i = 0; i < num_cache_leaves; i++) { +- struct _cpuid4_info_regs this_leaf; ++ struct _cpuid4_info_regs this_leaf = {}; + int retval; + + retval = cpuid4_cache_lookup_regs(i, &this_leaf); +- if (retval >= 0) { +- switch (this_leaf.eax.split.level) { +- case 1: +- if (this_leaf.eax.split.type == +- CACHE_TYPE_DATA) +- new_l1d = this_leaf.size/1024; +- else if (this_leaf.eax.split.type == +- CACHE_TYPE_INST) +- new_l1i = this_leaf.size/1024; +- break; +- case 2: +- new_l2 = this_leaf.size/1024; +- num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; +- index_msb = get_count_order(num_threads_sharing); +- l2_id = c->apicid & ~((1 << index_msb) - 1); +- break; +- case 3: +- new_l3 = this_leaf.size/1024; +- num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; +- index_msb = get_count_order( +- num_threads_sharing); +- l3_id = c->apicid & ~((1 << index_msb) - 1); +- break; +- default: +- break; +- } ++ if (retval < 0) ++ continue; ++ ++ switch (this_leaf.eax.split.level) { ++ case 1: ++ if (this_leaf.eax.split.type == CTYPE_DATA) ++ new_l1d = this_leaf.size/1024; ++ else if (this_leaf.eax.split.type == CTYPE_INST) ++ new_l1i = this_leaf.size/1024; ++ break; ++ case 2: ++ new_l2 = this_leaf.size/1024; ++ num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; ++ index_msb = get_count_order(num_threads_sharing); ++ l2_id = c->apicid & ~((1 << index_msb) - 1); ++ break; ++ case 3: ++ new_l3 = this_leaf.size/1024; ++ num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; ++ index_msb = get_count_order(num_threads_sharing); ++ l3_id = c->apicid & ~((1 << index_msb) - 1); ++ break; ++ default: ++ break; + } + } + } +@@ -721,72 +774,81 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) + + if (new_l2) { + l2 = new_l2; +-#ifdef CONFIG_X86_HT ++#ifdef CONFIG_SMP + per_cpu(cpu_llc_id, cpu) = l2_id; + #endif + } + + if (new_l3) { + l3 = new_l3; +-#ifdef CONFIG_X86_HT ++#ifdef CONFIG_SMP + per_cpu(cpu_llc_id, cpu) = l3_id; + #endif + } + ++#ifdef CONFIG_SMP ++ /* ++ * If cpu_llc_id is not yet set, this means cpuid_level < 4 which in ++ * turns means that the only possibility is SMT (as indicated in ++ * cpuid1). Since cpuid2 doesn't specify shared caches, and we know ++ * that SMT shares all caches, we can unconditionally set cpu_llc_id to ++ * c->phys_proc_id. ++ */ ++ if (per_cpu(cpu_llc_id, cpu) == BAD_APICID) ++ per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; ++#endif ++ + c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); + + return l2; + } + +-#ifdef CONFIG_SYSFS +- +-/* pointer to _cpuid4_info array (for each cache leaf) */ +-static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); +-#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) +- +-#ifdef CONFIG_SMP +- +-static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) ++static int __cache_amd_cpumap_setup(unsigned int cpu, int index, ++ struct _cpuid4_info_regs *base) + { +- struct _cpuid4_info *this_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf; + int i, sibling; + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + unsigned int apicid, nshared, first, last; + +- if (!per_cpu(ici_cpuid4_info, cpu)) +- return 0; +- +- this_leaf = CPUID4_INFO_IDX(cpu, index); +- nshared = this_leaf->base.eax.split.num_threads_sharing + 1; ++ this_leaf = this_cpu_ci->info_list + index; ++ nshared = base->eax.split.num_threads_sharing + 1; + apicid = cpu_data(cpu).apicid; + first = apicid - (apicid % nshared); + last = first + nshared - 1; + + for_each_online_cpu(i) { ++ this_cpu_ci = get_cpu_cacheinfo(i); ++ if (!this_cpu_ci->info_list) ++ continue; ++ + apicid = cpu_data(i).apicid; + if ((apicid < first) || (apicid > last)) + continue; +- if (!per_cpu(ici_cpuid4_info, i)) +- continue; +- this_leaf = CPUID4_INFO_IDX(i, index); ++ ++ this_leaf = this_cpu_ci->info_list + index; + + for_each_online_cpu(sibling) { + apicid = cpu_data(sibling).apicid; + if ((apicid < first) || (apicid > last)) + continue; +- set_bit(sibling, this_leaf->shared_cpu_map); ++ cpumask_set_cpu(sibling, ++ &this_leaf->shared_cpu_map); + } + } + } else if (index == 3) { + for_each_cpu(i, cpu_llc_shared_mask(cpu)) { +- if (!per_cpu(ici_cpuid4_info, i)) ++ this_cpu_ci = get_cpu_cacheinfo(i); ++ if (!this_cpu_ci->info_list) + continue; +- this_leaf = CPUID4_INFO_IDX(i, index); ++ this_leaf = this_cpu_ci->info_list + index; + for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { + if (!cpu_online(sibling)) + continue; +- set_bit(sibling, this_leaf->shared_cpu_map); ++ cpumask_set_cpu(sibling, ++ &this_leaf->shared_cpu_map); + } + } + } else +@@ -795,72 +857,70 @@ static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) + return 1; + } + +-static void cache_shared_cpu_map_setup(unsigned int cpu, int index) ++static void __cache_cpumap_setup(unsigned int cpu, int index, ++ struct _cpuid4_info_regs *base) + { +- struct _cpuid4_info *this_leaf, *sibling_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf, *sibling_leaf; + unsigned long num_threads_sharing; + int index_msb, i; + struct cpuinfo_x86 *c = &cpu_data(cpu); + + if (c->x86_vendor == X86_VENDOR_AMD) { +- if (cache_shared_amd_cpu_map_setup(cpu, index)) ++ if (__cache_amd_cpumap_setup(cpu, index, base)) + return; + } + +- this_leaf = CPUID4_INFO_IDX(cpu, index); +- num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; ++ this_leaf = this_cpu_ci->info_list + index; ++ num_threads_sharing = 1 + base->eax.split.num_threads_sharing; + ++ cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); + if (num_threads_sharing == 1) +- cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); +- else { +- index_msb = get_count_order(num_threads_sharing); ++ return; + +- for_each_online_cpu(i) { +- if (cpu_data(i).apicid >> index_msb == +- c->apicid >> index_msb) { +- cpumask_set_cpu(i, +- to_cpumask(this_leaf->shared_cpu_map)); +- if (i != cpu && per_cpu(ici_cpuid4_info, i)) { +- sibling_leaf = +- CPUID4_INFO_IDX(i, index); +- cpumask_set_cpu(cpu, to_cpumask( +- sibling_leaf->shared_cpu_map)); +- } +- } ++ index_msb = get_count_order(num_threads_sharing); ++ ++ for_each_online_cpu(i) ++ if (cpu_data(i).apicid >> index_msb == c->apicid >> index_msb) { ++ struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); ++ ++ if (i == cpu || !sib_cpu_ci->info_list) ++ continue;/* skip if itself or no cacheinfo */ ++ sibling_leaf = sib_cpu_ci->info_list + index; ++ cpumask_set_cpu(i, &this_leaf->shared_cpu_map); ++ cpumask_set_cpu(cpu, &sibling_leaf->shared_cpu_map); + } +- } +-} +-static void cache_remove_shared_cpu_map(unsigned int cpu, int index) +-{ +- struct _cpuid4_info *this_leaf, *sibling_leaf; +- int sibling; +- +- this_leaf = CPUID4_INFO_IDX(cpu, index); +- for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) { +- sibling_leaf = CPUID4_INFO_IDX(sibling, index); +- cpumask_clear_cpu(cpu, +- to_cpumask(sibling_leaf->shared_cpu_map)); +- } +-} +-#else +-static void cache_shared_cpu_map_setup(unsigned int cpu, int index) +-{ + } + +-static void cache_remove_shared_cpu_map(unsigned int cpu, int index) ++static void ci_leaf_init(struct cacheinfo *this_leaf, ++ struct _cpuid4_info_regs *base) + { ++ this_leaf->id = base->id; ++ this_leaf->attributes = CACHE_ID; ++ this_leaf->level = base->eax.split.level; ++ this_leaf->type = cache_type_map[base->eax.split.type]; ++ this_leaf->coherency_line_size = ++ base->ebx.split.coherency_line_size + 1; ++ this_leaf->ways_of_associativity = ++ base->ebx.split.ways_of_associativity + 1; ++ this_leaf->size = base->size; ++ this_leaf->number_of_sets = base->ecx.split.number_of_sets + 1; ++ this_leaf->physical_line_partition = ++ base->ebx.split.physical_line_partition + 1; ++ this_leaf->priv = base->nb; + } +-#endif + +-static void free_cache_attributes(unsigned int cpu) ++static int __init_cache_level(unsigned int cpu) + { +- int i; +- +- for (i = 0; i < num_cache_leaves; i++) +- cache_remove_shared_cpu_map(cpu, i); ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + +- kfree(per_cpu(ici_cpuid4_info, cpu)); +- per_cpu(ici_cpuid4_info, cpu) = NULL; ++ if (!num_cache_leaves) ++ return -ENOENT; ++ if (!this_cpu_ci) ++ return -EINVAL; ++ this_cpu_ci->num_levels = 3; ++ this_cpu_ci->num_leaves = num_cache_leaves; ++ return 0; + } + + /* +@@ -882,411 +942,37 @@ static void get_cache_id(int cpu, struct _cpuid4_info_regs *id4_regs) + int get_cpu_cache_id(int cpu, int level) + { + int i; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); + +- for (i = 0; i < num_cache_leaves; i++) { +- struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, i); ++ for (i = 0; i < this_cpu_ci->num_leaves; i++) { ++ struct cacheinfo *this_leaf = this_cpu_ci->info_list + i; + +- if (this_leaf->base.eax.split.level == level) +- return this_leaf->base.id; ++ if (this_leaf->level == level) ++ return this_leaf->id; + } + + return -1; + } + +-static void get_cpu_leaves(void *_retval) +-{ +- int j, *retval = _retval, cpu = smp_processor_id(); +- +- /* Do cpuid and store the results */ +- for (j = 0; j < num_cache_leaves; j++) { +- struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, j); +- +- *retval = cpuid4_cache_lookup_regs(j, &this_leaf->base); +- if (unlikely(*retval < 0)) { +- int i; +- +- for (i = 0; i < j; i++) +- cache_remove_shared_cpu_map(cpu, i); +- break; +- } +- cache_shared_cpu_map_setup(cpu, j); +- get_cache_id(cpu, &this_leaf->base); +- } +-} +- +-static int detect_cache_attributes(unsigned int cpu) +-{ +- int retval; +- +- if (num_cache_leaves == 0) +- return -ENOENT; +- +- per_cpu(ici_cpuid4_info, cpu) = kzalloc( +- sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); +- if (per_cpu(ici_cpuid4_info, cpu) == NULL) +- return -ENOMEM; +- +- smp_call_function_single(cpu, get_cpu_leaves, &retval, true); +- if (retval) { +- kfree(per_cpu(ici_cpuid4_info, cpu)); +- per_cpu(ici_cpuid4_info, cpu) = NULL; +- } +- +- return retval; +-} +- +-#include +-#include +-#include +- +-/* pointer to kobject for cpuX/cache */ +-static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject); +- +-struct _index_kobject { +- struct kobject kobj; +- unsigned int cpu; +- unsigned short index; +-}; +- +-/* pointer to array of kobjects for cpuX/cache/indexY */ +-static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject); +-#define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y])) +- +-#define show_one_plus(file_name, object, val) \ +-static ssize_t show_##file_name(struct _cpuid4_info *this_leaf, char *buf, \ +- unsigned int cpu) \ +-{ \ +- return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ +-} +- +-show_one_plus(level, base.eax.split.level, 0); +-show_one_plus(coherency_line_size, base.ebx.split.coherency_line_size, 1); +-show_one_plus(physical_line_partition, base.ebx.split.physical_line_partition, 1); +-show_one_plus(ways_of_associativity, base.ebx.split.ways_of_associativity, 1); +-show_one_plus(number_of_sets, base.ecx.split.number_of_sets, 1); +- +-static ssize_t show_id(struct _cpuid4_info *this_leaf, char *buf, +- unsigned int cpu) +-{ +- return sprintf(buf, "%u\n", this_leaf->base.id); +-} +- +-static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf, +- unsigned int cpu) +-{ +- return sprintf(buf, "%luK\n", this_leaf->base.size / 1024); +-} +- +-static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, +- int type, char *buf) +-{ +- ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; +- int n = 0; +- +- if (len > 1) { +- const struct cpumask *mask; +- +- mask = to_cpumask(this_leaf->shared_cpu_map); +- n = type ? +- cpulist_scnprintf(buf, len-2, mask) : +- cpumask_scnprintf(buf, len-2, mask); +- buf[n++] = '\n'; +- buf[n] = '\0'; +- } +- return n; +-} +- +-static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf, +- unsigned int cpu) +-{ +- return show_shared_cpu_map_func(leaf, 0, buf); +-} +- +-static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf, +- unsigned int cpu) +-{ +- return show_shared_cpu_map_func(leaf, 1, buf); +-} +- +-static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf, +- unsigned int cpu) +-{ +- switch (this_leaf->base.eax.split.type) { +- case CACHE_TYPE_DATA: +- return sprintf(buf, "Data\n"); +- case CACHE_TYPE_INST: +- return sprintf(buf, "Instruction\n"); +- case CACHE_TYPE_UNIFIED: +- return sprintf(buf, "Unified\n"); +- default: +- return sprintf(buf, "Unknown\n"); +- } +-} +- +-#define to_object(k) container_of(k, struct _index_kobject, kobj) +-#define to_attr(a) container_of(a, struct _cache_attr, attr) +- +-#define define_one_ro(_name) \ +-static struct _cache_attr _name = \ +- __ATTR(_name, 0444, show_##_name, NULL) +- +-define_one_ro(id); +-define_one_ro(level); +-define_one_ro(type); +-define_one_ro(coherency_line_size); +-define_one_ro(physical_line_partition); +-define_one_ro(ways_of_associativity); +-define_one_ro(number_of_sets); +-define_one_ro(size); +-define_one_ro(shared_cpu_map); +-define_one_ro(shared_cpu_list); +- +-static struct attribute *default_attrs[] = { +- &id.attr, +- &type.attr, +- &level.attr, +- &coherency_line_size.attr, +- &physical_line_partition.attr, +- &ways_of_associativity.attr, +- &number_of_sets.attr, +- &size.attr, +- &shared_cpu_map.attr, +- &shared_cpu_list.attr, +- NULL +-}; +- +-#ifdef CONFIG_AMD_NB +-static struct attribute **amd_l3_attrs(void) +-{ +- static struct attribute **attrs; +- int n; +- +- if (attrs) +- return attrs; +- +- n = ARRAY_SIZE(default_attrs); +- +- if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) +- n += 2; +- +- if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- n += 1; +- +- attrs = kzalloc(n * sizeof (struct attribute *), GFP_KERNEL); +- if (attrs == NULL) +- return attrs = default_attrs; +- +- for (n = 0; default_attrs[n]; n++) +- attrs[n] = default_attrs[n]; +- +- if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) { +- attrs[n++] = &cache_disable_0.attr; +- attrs[n++] = &cache_disable_1.attr; +- } +- +- if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) +- attrs[n++] = &subcaches.attr; +- +- return attrs; +-} +-#endif +- +-static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) +-{ +- struct _cache_attr *fattr = to_attr(attr); +- struct _index_kobject *this_leaf = to_object(kobj); +- ssize_t ret; +- +- ret = fattr->show ? +- fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), +- buf, this_leaf->cpu) : +- 0; +- return ret; +-} +- +-static ssize_t store(struct kobject *kobj, struct attribute *attr, +- const char *buf, size_t count) +-{ +- struct _cache_attr *fattr = to_attr(attr); +- struct _index_kobject *this_leaf = to_object(kobj); +- ssize_t ret; +- +- ret = fattr->store ? +- fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), +- buf, count, this_leaf->cpu) : +- 0; +- return ret; +-} +- +-static const struct sysfs_ops sysfs_ops = { +- .show = show, +- .store = store, +-}; +- +-static struct kobj_type ktype_cache = { +- .sysfs_ops = &sysfs_ops, +- .default_attrs = default_attrs, +-}; +- +-static struct kobj_type ktype_percpu_entry = { +- .sysfs_ops = &sysfs_ops, +-}; +- +-static void cpuid4_cache_sysfs_exit(unsigned int cpu) +-{ +- kfree(per_cpu(ici_cache_kobject, cpu)); +- kfree(per_cpu(ici_index_kobject, cpu)); +- per_cpu(ici_cache_kobject, cpu) = NULL; +- per_cpu(ici_index_kobject, cpu) = NULL; +- free_cache_attributes(cpu); +-} +- +-static int cpuid4_cache_sysfs_init(unsigned int cpu) +-{ +- int err; +- +- if (num_cache_leaves == 0) +- return -ENOENT; +- +- err = detect_cache_attributes(cpu); +- if (err) +- return err; +- +- /* Allocate all required memory */ +- per_cpu(ici_cache_kobject, cpu) = +- kzalloc(sizeof(struct kobject), GFP_KERNEL); +- if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL)) +- goto err_out; +- +- per_cpu(ici_index_kobject, cpu) = kzalloc( +- sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL); +- if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL)) +- goto err_out; +- +- return 0; +- +-err_out: +- cpuid4_cache_sysfs_exit(cpu); +- return -ENOMEM; +-} +- +-static DECLARE_BITMAP(cache_dev_map, NR_CPUS); +- +-/* Add/Remove cache interface for CPU device */ +-static int cache_add_dev(struct device *dev) ++static int __populate_cache_leaves(unsigned int cpu) + { +- unsigned int cpu = dev->id; +- unsigned long i, j; +- struct _index_kobject *this_object; +- struct _cpuid4_info *this_leaf; +- int retval; +- +- retval = cpuid4_cache_sysfs_init(cpu); +- if (unlikely(retval < 0)) +- return retval; +- +- retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu), +- &ktype_percpu_entry, +- &dev->kobj, "%s", "cache"); +- if (retval < 0) { +- cpuid4_cache_sysfs_exit(cpu); +- return retval; +- } +- +- for (i = 0; i < num_cache_leaves; i++) { +- this_object = INDEX_KOBJECT_PTR(cpu, i); +- this_object->cpu = cpu; +- this_object->index = i; ++ unsigned int idx, ret; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf = this_cpu_ci->info_list; ++ struct _cpuid4_info_regs id4_regs = {}; + +- this_leaf = CPUID4_INFO_IDX(cpu, i); +- +- ktype_cache.default_attrs = default_attrs; +-#ifdef CONFIG_AMD_NB +- if (this_leaf->base.nb) +- ktype_cache.default_attrs = amd_l3_attrs(); +-#endif +- retval = kobject_init_and_add(&(this_object->kobj), +- &ktype_cache, +- per_cpu(ici_cache_kobject, cpu), +- "index%1lu", i); +- if (unlikely(retval)) { +- for (j = 0; j < i; j++) +- kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj)); +- kobject_put(per_cpu(ici_cache_kobject, cpu)); +- cpuid4_cache_sysfs_exit(cpu); +- return retval; +- } +- kobject_uevent(&(this_object->kobj), KOBJ_ADD); ++ for (idx = 0; idx < this_cpu_ci->num_leaves; idx++) { ++ ret = cpuid4_cache_lookup_regs(idx, &id4_regs); ++ if (ret) ++ return ret; ++ get_cache_id(cpu, &id4_regs); ++ ci_leaf_init(this_leaf++, &id4_regs); ++ __cache_cpumap_setup(cpu, idx, &id4_regs); + } +- cpumask_set_cpu(cpu, to_cpumask(cache_dev_map)); ++ this_cpu_ci->cpu_map_populated = true; + +- kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD); + return 0; + } + +-static void cache_remove_dev(struct device *dev) +-{ +- unsigned int cpu = dev->id; +- unsigned long i; +- +- if (per_cpu(ici_cpuid4_info, cpu) == NULL) +- return; +- if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map))) +- return; +- cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); +- +- for (i = 0; i < num_cache_leaves; i++) +- kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj)); +- kobject_put(per_cpu(ici_cache_kobject, cpu)); +- cpuid4_cache_sysfs_exit(cpu); +-} +- +-static int cacheinfo_cpu_callback(struct notifier_block *nfb, +- unsigned long action, void *hcpu) +-{ +- unsigned int cpu = (unsigned long)hcpu; +- struct device *dev; +- +- dev = get_cpu_device(cpu); +- switch (action) { +- case CPU_ONLINE: +- case CPU_ONLINE_FROZEN: +- cache_add_dev(dev); +- break; +- case CPU_DEAD: +- case CPU_DEAD_FROZEN: +- cache_remove_dev(dev); +- break; +- } +- return NOTIFY_OK; +-} +- +-static struct notifier_block cacheinfo_cpu_notifier = { +- .notifier_call = cacheinfo_cpu_callback, +-}; +- +-static int __init cache_sysfs_init(void) +-{ +- int i, err = 0; +- +- if (num_cache_leaves == 0) +- return 0; +- +- cpu_notifier_register_begin(); +- for_each_online_cpu(i) { +- struct device *dev = get_cpu_device(i); +- +- err = cache_add_dev(dev); +- if (err) +- goto out; +- } +- __register_hotcpu_notifier(&cacheinfo_cpu_notifier); +- +-out: +- cpu_notifier_register_done(); +- return err; +-} +- +-device_initcall(cache_sysfs_init); +- +-#endif ++DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) ++DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) +diff --git a/drivers/base/Makefile b/drivers/base/Makefile +index 53c3fe1..527d291 100644 +--- a/drivers/base/Makefile ++++ b/drivers/base/Makefile +@@ -4,7 +4,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \ + driver.o class.o platform.o \ + cpu.o firmware.o init.o map.o devres.o \ + attribute_container.o transport_class.o \ +- topology.o container.o property.o ++ topology.o container.o property.o cacheinfo.o + obj-$(CONFIG_DEVTMPFS) += devtmpfs.o + obj-$(CONFIG_DMA_CMA) += dma-contiguous.o + obj-y += power/ +diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c +new file mode 100644 +index 0000000..eb3af27 +--- /dev/null ++++ b/drivers/base/cacheinfo.c +@@ -0,0 +1,662 @@ ++/* ++ * cacheinfo support - processor cache information via sysfs ++ * ++ * Based on arch/x86/kernel/cpu/intel_cacheinfo.c ++ * Author: Sudeep Holla ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* pointer to per cpu cacheinfo */ ++static DEFINE_PER_CPU(struct cpu_cacheinfo, ci_cpu_cacheinfo); ++#define ci_cacheinfo(cpu) (&per_cpu(ci_cpu_cacheinfo, cpu)) ++#define cache_leaves(cpu) (ci_cacheinfo(cpu)->num_leaves) ++#define per_cpu_cacheinfo(cpu) (ci_cacheinfo(cpu)->info_list) ++ ++struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu) ++{ ++ return ci_cacheinfo(cpu); ++} ++ ++#ifdef CONFIG_OF ++static int cache_setup_of_node(unsigned int cpu) ++{ ++ struct device_node *np; ++ struct cacheinfo *this_leaf; ++ struct device *cpu_dev = get_cpu_device(cpu); ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ unsigned int index = 0; ++ ++ /* skip if of_node is already populated */ ++ if (this_cpu_ci->info_list->of_node) ++ return 0; ++ ++ if (!cpu_dev) { ++ pr_err("No cpu device for CPU %d\n", cpu); ++ return -ENODEV; ++ } ++ np = cpu_dev->of_node; ++ if (!np) { ++ pr_err("Failed to find cpu%d device node\n", cpu); ++ return -ENOENT; ++ } ++ ++ while (index < cache_leaves(cpu)) { ++ this_leaf = this_cpu_ci->info_list + index; ++ if (this_leaf->level != 1) ++ np = of_find_next_cache_node(np); ++ else ++ np = of_node_get(np);/* cpu node itself */ ++ if (!np) ++ break; ++ this_leaf->of_node = np; ++ index++; ++ } ++ ++ if (index != cache_leaves(cpu)) /* not all OF nodes populated */ ++ return -ENOENT; ++ ++ return 0; ++} ++ ++static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, ++ struct cacheinfo *sib_leaf) ++{ ++ return sib_leaf->of_node == this_leaf->of_node; ++} ++ ++/* OF properties to query for a given cache type */ ++struct cache_type_info { ++ const char *size_prop; ++ const char *line_size_props[2]; ++ const char *nr_sets_prop; ++}; ++ ++static const struct cache_type_info cache_type_info[] = { ++ { ++ .size_prop = "cache-size", ++ .line_size_props = { "cache-line-size", ++ "cache-block-size", }, ++ .nr_sets_prop = "cache-sets", ++ }, { ++ .size_prop = "i-cache-size", ++ .line_size_props = { "i-cache-line-size", ++ "i-cache-block-size", }, ++ .nr_sets_prop = "i-cache-sets", ++ }, { ++ .size_prop = "d-cache-size", ++ .line_size_props = { "d-cache-line-size", ++ "d-cache-block-size", }, ++ .nr_sets_prop = "d-cache-sets", ++ }, ++}; ++ ++static inline int get_cacheinfo_idx(enum cache_type type) ++{ ++ if (type == CACHE_TYPE_UNIFIED) ++ return 0; ++ return type; ++} ++ ++static void cache_size(struct cacheinfo *this_leaf) ++{ ++ const char *propname; ++ const __be32 *cache_size; ++ int ct_idx; ++ ++ ct_idx = get_cacheinfo_idx(this_leaf->type); ++ propname = cache_type_info[ct_idx].size_prop; ++ ++ cache_size = of_get_property(this_leaf->of_node, propname, NULL); ++ if (cache_size) ++ this_leaf->size = of_read_number(cache_size, 1); ++} ++ ++/* not cache_line_size() because that's a macro in include/linux/cache.h */ ++static void cache_get_line_size(struct cacheinfo *this_leaf) ++{ ++ const __be32 *line_size; ++ int i, lim, ct_idx; ++ ++ ct_idx = get_cacheinfo_idx(this_leaf->type); ++ lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props); ++ ++ for (i = 0; i < lim; i++) { ++ const char *propname; ++ ++ propname = cache_type_info[ct_idx].line_size_props[i]; ++ line_size = of_get_property(this_leaf->of_node, propname, NULL); ++ if (line_size) ++ break; ++ } ++ ++ if (line_size) ++ this_leaf->coherency_line_size = of_read_number(line_size, 1); ++} ++ ++static void cache_nr_sets(struct cacheinfo *this_leaf) ++{ ++ const char *propname; ++ const __be32 *nr_sets; ++ int ct_idx; ++ ++ ct_idx = get_cacheinfo_idx(this_leaf->type); ++ propname = cache_type_info[ct_idx].nr_sets_prop; ++ ++ nr_sets = of_get_property(this_leaf->of_node, propname, NULL); ++ if (nr_sets) ++ this_leaf->number_of_sets = of_read_number(nr_sets, 1); ++} ++ ++static void cache_associativity(struct cacheinfo *this_leaf) ++{ ++ unsigned int line_size = this_leaf->coherency_line_size; ++ unsigned int nr_sets = this_leaf->number_of_sets; ++ unsigned int size = this_leaf->size; ++ ++ /* ++ * If the cache is fully associative, there is no need to ++ * check the other properties. ++ */ ++ if (!(nr_sets == 1) && (nr_sets > 0 && size > 0 && line_size > 0)) ++ this_leaf->ways_of_associativity = (size / nr_sets) / line_size; ++} ++ ++static void cache_of_override_properties(unsigned int cpu) ++{ ++ int index; ++ struct cacheinfo *this_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ ++ for (index = 0; index < cache_leaves(cpu); index++) { ++ this_leaf = this_cpu_ci->info_list + index; ++ cache_size(this_leaf); ++ cache_get_line_size(this_leaf); ++ cache_nr_sets(this_leaf); ++ cache_associativity(this_leaf); ++ } ++} ++#else ++static void cache_of_override_properties(unsigned int cpu) { } ++static inline int cache_setup_of_node(unsigned int cpu) { return 0; } ++static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, ++ struct cacheinfo *sib_leaf) ++{ ++ /* ++ * For non-DT systems, assume unique level 1 cache, system-wide ++ * shared caches for all other levels. This will be used only if ++ * arch specific code has not populated shared_cpu_map ++ */ ++ return !(this_leaf->level == 1); ++} ++#endif ++ ++static int cache_shared_cpu_map_setup(unsigned int cpu) ++{ ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf, *sib_leaf; ++ unsigned int index; ++ int ret = 0; ++ ++ if (this_cpu_ci->cpu_map_populated) ++ return 0; ++ ++ if (of_have_populated_dt()) ++ ret = cache_setup_of_node(cpu); ++ else if (!acpi_disabled) ++ /* No cache property/hierarchy support yet in ACPI */ ++ ret = -ENOTSUPP; ++ if (ret) ++ return ret; ++ ++ for (index = 0; index < cache_leaves(cpu); index++) { ++ unsigned int i; ++ ++ this_leaf = this_cpu_ci->info_list + index; ++ /* skip if shared_cpu_map is already populated */ ++ if (!cpumask_empty(&this_leaf->shared_cpu_map)) ++ continue; ++ ++ cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); ++ for_each_online_cpu(i) { ++ struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i); ++ ++ if (i == cpu || !sib_cpu_ci->info_list) ++ continue;/* skip if itself or no cacheinfo */ ++ sib_leaf = sib_cpu_ci->info_list + index; ++ if (cache_leaves_are_shared(this_leaf, sib_leaf)) { ++ cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map); ++ cpumask_set_cpu(i, &this_leaf->shared_cpu_map); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static void cache_shared_cpu_map_remove(unsigned int cpu) ++{ ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ struct cacheinfo *this_leaf, *sib_leaf; ++ unsigned int sibling, index; ++ ++ for (index = 0; index < cache_leaves(cpu); index++) { ++ this_leaf = this_cpu_ci->info_list + index; ++ for_each_cpu(sibling, &this_leaf->shared_cpu_map) { ++ struct cpu_cacheinfo *sib_cpu_ci; ++ ++ if (sibling == cpu) /* skip itself */ ++ continue; ++ ++ sib_cpu_ci = get_cpu_cacheinfo(sibling); ++ if (!sib_cpu_ci->info_list) ++ continue; ++ ++ sib_leaf = sib_cpu_ci->info_list + index; ++ cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map); ++ cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map); ++ } ++ of_node_put(this_leaf->of_node); ++ } ++} ++ ++static void cache_override_properties(unsigned int cpu) ++{ ++ if (of_have_populated_dt()) ++ return cache_of_override_properties(cpu); ++} ++ ++static void free_cache_attributes(unsigned int cpu) ++{ ++ if (!per_cpu_cacheinfo(cpu)) ++ return; ++ ++ cache_shared_cpu_map_remove(cpu); ++ ++ kfree(per_cpu_cacheinfo(cpu)); ++ per_cpu_cacheinfo(cpu) = NULL; ++} ++ ++int __weak init_cache_level(unsigned int cpu) ++{ ++ return -ENOENT; ++} ++ ++int __weak populate_cache_leaves(unsigned int cpu) ++{ ++ return -ENOENT; ++} ++ ++static int detect_cache_attributes(unsigned int cpu) ++{ ++ int ret; ++ ++ if (init_cache_level(cpu) || !cache_leaves(cpu)) ++ return -ENOENT; ++ ++ per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), ++ sizeof(struct cacheinfo), GFP_KERNEL); ++ if (per_cpu_cacheinfo(cpu) == NULL) ++ return -ENOMEM; ++ ++ ret = populate_cache_leaves(cpu); ++ if (ret) ++ goto free_ci; ++ /* ++ * For systems using DT for cache hierarchy, of_node and shared_cpu_map ++ * will be set up here only if they are not populated already ++ */ ++ ret = cache_shared_cpu_map_setup(cpu); ++ if (ret) { ++ pr_warn("Unable to detect cache hierarchy for CPU %d\n", cpu); ++ goto free_ci; ++ } ++ ++ cache_override_properties(cpu); ++ return 0; ++ ++free_ci: ++ free_cache_attributes(cpu); ++ return ret; ++} ++ ++/* pointer to cpuX/cache device */ ++static DEFINE_PER_CPU(struct device *, ci_cache_dev); ++#define per_cpu_cache_dev(cpu) (per_cpu(ci_cache_dev, cpu)) ++ ++static cpumask_t cache_dev_map; ++ ++/* pointer to array of devices for cpuX/cache/indexY */ ++static DEFINE_PER_CPU(struct device **, ci_index_dev); ++#define per_cpu_index_dev(cpu) (per_cpu(ci_index_dev, cpu)) ++#define per_cache_index_dev(cpu, idx) ((per_cpu_index_dev(cpu))[idx]) ++ ++#define show_one(file_name, object) \ ++static ssize_t file_name##_show(struct device *dev, \ ++ struct device_attribute *attr, char *buf) \ ++{ \ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); \ ++ return sprintf(buf, "%u\n", this_leaf->object); \ ++} ++ ++show_one(id, id); ++show_one(level, level); ++show_one(coherency_line_size, coherency_line_size); ++show_one(number_of_sets, number_of_sets); ++show_one(physical_line_partition, physical_line_partition); ++show_one(ways_of_associativity, ways_of_associativity); ++ ++static ssize_t size_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%uK\n", this_leaf->size >> 10); ++} ++ ++static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ const struct cpumask *mask = &this_leaf->shared_cpu_map; ++ ++ return cpumap_print_to_pagebuf(list, buf, mask); ++} ++ ++static ssize_t shared_cpu_map_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return shared_cpumap_show_func(dev, false, buf); ++} ++ ++static ssize_t shared_cpu_list_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return shared_cpumap_show_func(dev, true, buf); ++} ++ ++static ssize_t type_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ ++ switch (this_leaf->type) { ++ case CACHE_TYPE_DATA: ++ return sprintf(buf, "Data\n"); ++ case CACHE_TYPE_INST: ++ return sprintf(buf, "Instruction\n"); ++ case CACHE_TYPE_UNIFIED: ++ return sprintf(buf, "Unified\n"); ++ default: ++ return -EINVAL; ++ } ++} ++ ++static ssize_t allocation_policy_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ unsigned int ci_attr = this_leaf->attributes; ++ int n = 0; ++ ++ if ((ci_attr & CACHE_READ_ALLOCATE) && (ci_attr & CACHE_WRITE_ALLOCATE)) ++ n = sprintf(buf, "ReadWriteAllocate\n"); ++ else if (ci_attr & CACHE_READ_ALLOCATE) ++ n = sprintf(buf, "ReadAllocate\n"); ++ else if (ci_attr & CACHE_WRITE_ALLOCATE) ++ n = sprintf(buf, "WriteAllocate\n"); ++ return n; ++} ++ ++static ssize_t write_policy_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ unsigned int ci_attr = this_leaf->attributes; ++ int n = 0; ++ ++ if (ci_attr & CACHE_WRITE_THROUGH) ++ n = sprintf(buf, "WriteThrough\n"); ++ else if (ci_attr & CACHE_WRITE_BACK) ++ n = sprintf(buf, "WriteBack\n"); ++ return n; ++} ++ ++static DEVICE_ATTR_RO(id); ++static DEVICE_ATTR_RO(level); ++static DEVICE_ATTR_RO(type); ++static DEVICE_ATTR_RO(coherency_line_size); ++static DEVICE_ATTR_RO(ways_of_associativity); ++static DEVICE_ATTR_RO(number_of_sets); ++static DEVICE_ATTR_RO(size); ++static DEVICE_ATTR_RO(allocation_policy); ++static DEVICE_ATTR_RO(write_policy); ++static DEVICE_ATTR_RO(shared_cpu_map); ++static DEVICE_ATTR_RO(shared_cpu_list); ++static DEVICE_ATTR_RO(physical_line_partition); ++ ++static struct attribute *cache_default_attrs[] = { ++ &dev_attr_id.attr, ++ &dev_attr_type.attr, ++ &dev_attr_level.attr, ++ &dev_attr_shared_cpu_map.attr, ++ &dev_attr_shared_cpu_list.attr, ++ &dev_attr_coherency_line_size.attr, ++ &dev_attr_ways_of_associativity.attr, ++ &dev_attr_number_of_sets.attr, ++ &dev_attr_size.attr, ++ &dev_attr_allocation_policy.attr, ++ &dev_attr_write_policy.attr, ++ &dev_attr_physical_line_partition.attr, ++ NULL ++}; ++ ++static umode_t ++cache_default_attrs_is_visible(struct kobject *kobj, ++ struct attribute *attr, int unused) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct cacheinfo *this_leaf = dev_get_drvdata(dev); ++ const struct cpumask *mask = &this_leaf->shared_cpu_map; ++ umode_t mode = attr->mode; ++ ++ if ((attr == &dev_attr_id.attr) && (this_leaf->attributes & CACHE_ID)) ++ return mode; ++ if ((attr == &dev_attr_type.attr) && this_leaf->type) ++ return mode; ++ if ((attr == &dev_attr_level.attr) && this_leaf->level) ++ return mode; ++ if ((attr == &dev_attr_shared_cpu_map.attr) && !cpumask_empty(mask)) ++ return mode; ++ if ((attr == &dev_attr_shared_cpu_list.attr) && !cpumask_empty(mask)) ++ return mode; ++ if ((attr == &dev_attr_coherency_line_size.attr) && ++ this_leaf->coherency_line_size) ++ return mode; ++ if ((attr == &dev_attr_ways_of_associativity.attr) && ++ this_leaf->size) /* allow 0 = full associativity */ ++ return mode; ++ if ((attr == &dev_attr_number_of_sets.attr) && ++ this_leaf->number_of_sets) ++ return mode; ++ if ((attr == &dev_attr_size.attr) && this_leaf->size) ++ return mode; ++ if ((attr == &dev_attr_write_policy.attr) && ++ (this_leaf->attributes & CACHE_WRITE_POLICY_MASK)) ++ return mode; ++ if ((attr == &dev_attr_allocation_policy.attr) && ++ (this_leaf->attributes & CACHE_ALLOCATE_POLICY_MASK)) ++ return mode; ++ if ((attr == &dev_attr_physical_line_partition.attr) && ++ this_leaf->physical_line_partition) ++ return mode; ++ ++ return 0; ++} ++ ++static const struct attribute_group cache_default_group = { ++ .attrs = cache_default_attrs, ++ .is_visible = cache_default_attrs_is_visible, ++}; ++ ++static const struct attribute_group *cache_default_groups[] = { ++ &cache_default_group, ++ NULL, ++}; ++ ++static const struct attribute_group *cache_private_groups[] = { ++ &cache_default_group, ++ NULL, /* Place holder for private group */ ++ NULL, ++}; ++ ++const struct attribute_group * ++__weak cache_get_priv_group(struct cacheinfo *this_leaf) ++{ ++ return NULL; ++} ++ ++static const struct attribute_group ** ++cache_get_attribute_groups(struct cacheinfo *this_leaf) ++{ ++ const struct attribute_group *priv_group = ++ cache_get_priv_group(this_leaf); ++ ++ if (!priv_group) ++ return cache_default_groups; ++ ++ if (!cache_private_groups[1]) ++ cache_private_groups[1] = priv_group; ++ ++ return cache_private_groups; ++} ++ ++/* Add/Remove cache interface for CPU device */ ++static void cpu_cache_sysfs_exit(unsigned int cpu) ++{ ++ int i; ++ struct device *ci_dev; ++ ++ if (per_cpu_index_dev(cpu)) { ++ for (i = 0; i < cache_leaves(cpu); i++) { ++ ci_dev = per_cache_index_dev(cpu, i); ++ if (!ci_dev) ++ continue; ++ device_unregister(ci_dev); ++ } ++ kfree(per_cpu_index_dev(cpu)); ++ per_cpu_index_dev(cpu) = NULL; ++ } ++ device_unregister(per_cpu_cache_dev(cpu)); ++ per_cpu_cache_dev(cpu) = NULL; ++} ++ ++static int cpu_cache_sysfs_init(unsigned int cpu) ++{ ++ struct device *dev = get_cpu_device(cpu); ++ ++ if (per_cpu_cacheinfo(cpu) == NULL) ++ return -ENOENT; ++ ++ per_cpu_cache_dev(cpu) = cpu_device_create(dev, NULL, NULL, "cache"); ++ if (IS_ERR(per_cpu_cache_dev(cpu))) ++ return PTR_ERR(per_cpu_cache_dev(cpu)); ++ ++ /* Allocate all required memory */ ++ per_cpu_index_dev(cpu) = kcalloc(cache_leaves(cpu), ++ sizeof(struct device *), GFP_KERNEL); ++ if (unlikely(per_cpu_index_dev(cpu) == NULL)) ++ goto err_out; ++ ++ return 0; ++ ++err_out: ++ cpu_cache_sysfs_exit(cpu); ++ return -ENOMEM; ++} ++ ++static int cache_add_dev(unsigned int cpu) ++{ ++ unsigned int i; ++ int rc; ++ struct device *ci_dev, *parent; ++ struct cacheinfo *this_leaf; ++ struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); ++ const struct attribute_group **cache_groups; ++ ++ rc = cpu_cache_sysfs_init(cpu); ++ if (unlikely(rc < 0)) ++ return rc; ++ ++ parent = per_cpu_cache_dev(cpu); ++ for (i = 0; i < cache_leaves(cpu); i++) { ++ this_leaf = this_cpu_ci->info_list + i; ++ if (this_leaf->disable_sysfs) ++ continue; ++ cache_groups = cache_get_attribute_groups(this_leaf); ++ ci_dev = cpu_device_create(parent, this_leaf, cache_groups, ++ "index%1u", i); ++ if (IS_ERR(ci_dev)) { ++ rc = PTR_ERR(ci_dev); ++ goto err; ++ } ++ per_cache_index_dev(cpu, i) = ci_dev; ++ } ++ cpumask_set_cpu(cpu, &cache_dev_map); ++ ++ return 0; ++err: ++ cpu_cache_sysfs_exit(cpu); ++ return rc; ++} ++ ++static int cacheinfo_cpu_online(unsigned int cpu) ++{ ++ int rc = detect_cache_attributes(cpu); ++ ++ if (rc) ++ return rc; ++ rc = cache_add_dev(cpu); ++ if (rc) ++ free_cache_attributes(cpu); ++ return rc; ++} ++ ++static int cacheinfo_cpu_pre_down(unsigned int cpu) ++{ ++ if (cpumask_test_and_clear_cpu(cpu, &cache_dev_map)) ++ cpu_cache_sysfs_exit(cpu); ++ ++ free_cache_attributes(cpu); ++ return 0; ++} ++ ++static int __init cacheinfo_sysfs_init(void) ++{ ++ return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/cacheinfo:online", ++ cacheinfo_cpu_online, cacheinfo_cpu_pre_down); ++} ++device_initcall(cacheinfo_sysfs_init); +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index dfc7870..0ff0eff 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -338,6 +338,60 @@ struct device *get_cpu_device(unsigned cpu) + } + EXPORT_SYMBOL_GPL(get_cpu_device); + ++static void device_create_release(struct device *dev) ++{ ++ kfree(dev); ++} ++ ++static struct device * ++__cpu_device_create(struct device *parent, void *drvdata, ++ const struct attribute_group **groups, ++ const char *fmt, va_list args) ++{ ++ struct device *dev = NULL; ++ int retval = -ENODEV; ++ ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ if (!dev) { ++ retval = -ENOMEM; ++ goto error; ++ } ++ ++ device_initialize(dev); ++ dev->parent = parent; ++ dev->groups = groups; ++ dev->release = device_create_release; ++ dev_set_drvdata(dev, drvdata); ++ ++ retval = kobject_set_name_vargs(&dev->kobj, fmt, args); ++ if (retval) ++ goto error; ++ ++ retval = device_add(dev); ++ if (retval) ++ goto error; ++ ++ return dev; ++ ++error: ++ put_device(dev); ++ return ERR_PTR(retval); ++} ++ ++struct device *cpu_device_create(struct device *parent, void *drvdata, ++ const struct attribute_group **groups, ++ const char *fmt, ...) ++{ ++ va_list vargs; ++ struct device *dev; ++ ++ va_start(vargs, fmt); ++ dev = __cpu_device_create(parent, drvdata, groups, fmt, vargs); ++ va_end(vargs); ++ return dev; ++} ++EXPORT_SYMBOL_GPL(cpu_device_create); ++ + #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); + #endif +diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h +new file mode 100644 +index 0000000..6a524bf +--- /dev/null ++++ b/include/linux/cacheinfo.h +@@ -0,0 +1,104 @@ ++#ifndef _LINUX_CACHEINFO_H ++#define _LINUX_CACHEINFO_H ++ ++#include ++#include ++#include ++ ++struct device_node; ++struct attribute; ++ ++enum cache_type { ++ CACHE_TYPE_NOCACHE = 0, ++ CACHE_TYPE_INST = BIT(0), ++ CACHE_TYPE_DATA = BIT(1), ++ CACHE_TYPE_SEPARATE = CACHE_TYPE_INST | CACHE_TYPE_DATA, ++ CACHE_TYPE_UNIFIED = BIT(2), ++}; ++ ++/** ++ * struct cacheinfo - represent a cache leaf node ++ * @id: This cache's id. It is unique among caches with the same (type, level). ++ * @type: type of the cache - data, inst or unified ++ * @level: represents the hierarchy in the multi-level cache ++ * @coherency_line_size: size of each cache line usually representing ++ * the minimum amount of data that gets transferred from memory ++ * @number_of_sets: total number of sets, a set is a collection of cache ++ * lines sharing the same index ++ * @ways_of_associativity: number of ways in which a particular memory ++ * block can be placed in the cache ++ * @physical_line_partition: number of physical cache lines sharing the ++ * same cachetag ++ * @size: Total size of the cache ++ * @shared_cpu_map: logical cpumask representing all the cpus sharing ++ * this cache node ++ * @attributes: bitfield representing various cache attributes ++ * @of_node: if devicetree is used, this represents either the cpu node in ++ * case there's no explicit cache node or the cache node itself in the ++ * device tree ++ * @disable_sysfs: indicates whether this node is visible to the user via ++ * sysfs or not ++ * @priv: pointer to any private data structure specific to particular ++ * cache design ++ * ++ * While @of_node, @disable_sysfs and @priv are used for internal book ++ * keeping, the remaining members form the core properties of the cache ++ */ ++struct cacheinfo { ++ unsigned int id; ++ enum cache_type type; ++ unsigned int level; ++ unsigned int coherency_line_size; ++ unsigned int number_of_sets; ++ unsigned int ways_of_associativity; ++ unsigned int physical_line_partition; ++ unsigned int size; ++ cpumask_t shared_cpu_map; ++ unsigned int attributes; ++#define CACHE_WRITE_THROUGH BIT(0) ++#define CACHE_WRITE_BACK BIT(1) ++#define CACHE_WRITE_POLICY_MASK \ ++ (CACHE_WRITE_THROUGH | CACHE_WRITE_BACK) ++#define CACHE_READ_ALLOCATE BIT(2) ++#define CACHE_WRITE_ALLOCATE BIT(3) ++#define CACHE_ALLOCATE_POLICY_MASK \ ++ (CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE) ++#define CACHE_ID BIT(4) ++ ++ struct device_node *of_node; ++ bool disable_sysfs; ++ void *priv; ++}; ++ ++struct cpu_cacheinfo { ++ struct cacheinfo *info_list; ++ unsigned int num_levels; ++ unsigned int num_leaves; ++ bool cpu_map_populated; ++}; ++ ++/* ++ * Helpers to make sure "func" is executed on the cpu whose cache ++ * attributes are being detected ++ */ ++#define DEFINE_SMP_CALL_CACHE_FUNCTION(func) \ ++static inline void _##func(void *ret) \ ++{ \ ++ int cpu = smp_processor_id(); \ ++ *(int *)ret = __##func(cpu); \ ++} \ ++ \ ++int func(unsigned int cpu) \ ++{ \ ++ int ret; \ ++ smp_call_function_single(cpu, _##func, &ret, true); \ ++ return ret; \ ++} ++ ++struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu); ++int init_cache_level(unsigned int cpu); ++int populate_cache_leaves(unsigned int cpu); ++ ++const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf); ++ ++#endif /* _LINUX_CACHEINFO_H */ +diff --git a/include/linux/cpu.h b/include/linux/cpu.h +index e2bdd99..85e13e8 100644 +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -36,6 +36,9 @@ extern void cpu_remove_dev_attr(struct device_attribute *attr); + extern int cpu_add_dev_attr_group(struct attribute_group *attrs); + extern void cpu_remove_dev_attr_group(struct attribute_group *attrs); + ++extern struct device *cpu_device_create(struct device *parent, void *drvdata, ++ const struct attribute_group **groups, ++ const char *fmt, ...); + #ifdef CONFIG_HOTPLUG_CPU + extern void unregister_cpu(struct cpu *cpu); + extern ssize_t arch_cpu_probe(const char *, size_t); +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch b/kernel-std/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch new file mode 100644 index 000000000..14f64fe15 --- /dev/null +++ b/kernel-std/centos/patches/US101216-IMA-support-in-Titanium-kernel.patch @@ -0,0 +1,373 @@ +From 1243451d9dbc92ae5c67bfcc0c6c1d5eb02a8663 Mon Sep 17 00:00:00 2001 +Message-Id: <1243451d9dbc92ae5c67bfcc0c6c1d5eb02a8663.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Kam Nasim +Date: Wed, 23 Aug 2017 17:58:12 -0400 +Subject: [PATCH 23/24] US101216: IMA support in Titanium kernel + +facilitate building the IMA subsytem out-of-the-kernel tree as a Kernel +module (for which CONFIG_IMA and CONFIG_INTEGRITY will be undefined) by: +- exporting certain function symbols which will be linked to the kernel + module. This includes redefining the export symbols for kernel +functions such that when the kernel module loads, it dynamically points +to those new function definations and reverts to Kernel default +definitions on module deinit +- enabling inode readcount +- modification to ima_file_check to pass in file OPEN status + +Signed-off-by: Jim Somerville +--- + fs/namei.c | 2 +- + fs/nfsd/vfs.c | 2 +- + fs/xattr.c | 1 + + include/linux/fs.h | 15 +------ + include/linux/ima.h | 77 +++++++------------------------- + include/linux/integrity.h | 22 ++++----- + security/security.c | 111 +++++++++++++++++++++++++++++++++++++++++++++- + 7 files changed, 140 insertions(+), 90 deletions(-) + +diff --git a/fs/namei.c b/fs/namei.c +index 0a37e5a..db7455e 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -3198,7 +3198,7 @@ opened: + error = open_check_o_direct(file); + if (error) + goto exit_fput; +- error = ima_file_check(file, op->acc_mode); ++ error = ima_file_check(file, op->acc_mode, *opened); + if (error) + goto exit_fput; + +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index c439a9b..2f169fe 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -883,7 +883,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, + goto out_nfserr; + } + +- host_err = ima_file_check(file, may_flags); ++ host_err = ima_file_check(file, may_flags, 0); + if (host_err) { + fput(file); + goto out_nfserr; +diff --git a/fs/xattr.c b/fs/xattr.c +index 3377dff..59ee1c7 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, + *xattr_value = value; + return error; + } ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); + + /* Compare an extended attribute value with the given value */ + int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name, +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 5853208..0e8d7d5 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -666,9 +666,8 @@ struct inode { + struct hlist_head i_fsnotify_marks; + #endif + +-#ifdef CONFIG_IMA + atomic_t i_readcount; /* struct files open RO */ +-#endif ++ + void *i_private; /* fs or device private pointer */ + }; + +@@ -2765,7 +2764,6 @@ static inline bool inode_is_open_for_write(const struct inode *inode) + return atomic_read(&inode->i_writecount) > 0; + } + +-#ifdef CONFIG_IMA + static inline void i_readcount_dec(struct inode *inode) + { + BUG_ON(!atomic_read(&inode->i_readcount)); +@@ -2775,16 +2773,7 @@ static inline void i_readcount_inc(struct inode *inode) + { + atomic_inc(&inode->i_readcount); + } +-#else +-static inline void i_readcount_dec(struct inode *inode) +-{ +- return; +-} +-static inline void i_readcount_inc(struct inode *inode) +-{ +- return; +-} +-#endif ++ + extern int do_pipe_flags(int *, int); + + extern int kernel_read(struct file *, loff_t, char *, unsigned long); +diff --git a/include/linux/ima.h b/include/linux/ima.h +index 1b7f268..9fee45c 100644 +--- a/include/linux/ima.h ++++ b/include/linux/ima.h +@@ -13,64 +13,21 @@ + #include + struct linux_binprm; + +-#ifdef CONFIG_IMA +-extern int ima_bprm_check(struct linux_binprm *bprm); +-extern int ima_file_check(struct file *file, int mask); +-extern void ima_file_free(struct file *file); +-extern int ima_file_mmap(struct file *file, unsigned long prot); +-extern int ima_module_check(struct file *file); +- +-#else +-static inline int ima_bprm_check(struct linux_binprm *bprm) +-{ +- return 0; +-} +- +-static inline int ima_file_check(struct file *file, int mask) +-{ +- return 0; +-} +- +-static inline void ima_file_free(struct file *file) +-{ +- return; +-} +- +-static inline int ima_file_mmap(struct file *file, unsigned long prot) +-{ +- return 0; +-} +- +-static inline int ima_module_check(struct file *file) +-{ +- return 0; +-} +- +-#endif /* CONFIG_IMA */ +- +-#ifdef CONFIG_IMA_APPRAISE +-extern void ima_inode_post_setattr(struct dentry *dentry); +-extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, ++/* ++ * The IMA Kernel module has to redefine these symbols so that ++ * the kernel module can link a dynamic function, as a hook into ++ * the Kernel FS calls (which use these) ++ */ ++/* ifdef CONFIG_IMA */ ++extern int (*ima_bprm_check)(struct linux_binprm *bprm); ++extern int (*ima_file_check)(struct file *file, int mask, int opened); ++extern void (*ima_file_free)(struct file *file); ++extern int (*ima_file_mmap)(struct file *file, unsigned long prot); ++extern int (*ima_module_check)(struct file *file); ++ ++/* ifdef CONFIG_IMA_APPRAISE */ ++extern void (*ima_inode_post_setattr)(struct dentry *dentry); ++extern int (*ima_inode_setxattr)(struct dentry *dentry, const char *xattr_name, + const void *xattr_value, size_t xattr_value_len); +-extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name); +-#else +-static inline void ima_inode_post_setattr(struct dentry *dentry) +-{ +- return; +-} +- +-static inline int ima_inode_setxattr(struct dentry *dentry, +- const char *xattr_name, +- const void *xattr_value, +- size_t xattr_value_len) +-{ +- return 0; +-} +- +-static inline int ima_inode_removexattr(struct dentry *dentry, +- const char *xattr_name) +-{ +- return 0; +-} +-#endif /* CONFIG_IMA_APPRAISE */ +-#endif /* _LINUX_IMA_H */ ++extern int (*ima_inode_removexattr)(struct dentry *dentry, const char *xattr_name); ++#endif +diff --git a/include/linux/integrity.h b/include/linux/integrity.h +index 83222ce..a5040b6 100644 +--- a/include/linux/integrity.h ++++ b/include/linux/integrity.h +@@ -21,20 +21,14 @@ enum integrity_status { + }; + + /* List of EVM protected security xattrs */ +-#ifdef CONFIG_INTEGRITY +-extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode); +-extern void integrity_inode_free(struct inode *inode); ++/* ++ * The Integrity Kernel module has to redefine these symbols so that ++ * the kernel module can link a dynamic function, as a hook into ++ * the Kernel Security subsystem (which use these) ++ */ + +-#else +-static inline struct integrity_iint_cache * +- integrity_inode_get(struct inode *inode) +-{ +- return NULL; +-} ++/* #ifdef CONFIG_INTEGRITY */ ++extern struct integrity_iint_cache *(*integrity_inode_get)(struct inode *inode); ++extern void (*integrity_inode_free)(struct inode *inode); + +-static inline void integrity_inode_free(struct inode *inode) +-{ +- return; +-} +-#endif /* CONFIG_INTEGRITY */ + #endif /* _LINUX_INTEGRITY_H */ +diff --git a/security/security.c b/security/security.c +index 576b882..e7d33c9 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -135,6 +135,110 @@ int __init register_security(struct security_operations *ops) + + /* Security operations */ + ++/* ++ * Export these symbols since the IMA and Integrity ++ * modules will redefine it. We do this EXPORT in ++ * the security endpoint as this is the last Kernel ++ * hook into the Integrity / IMA modules ++ */ ++#ifndef CONFIG_INTEGRITY ++static struct integrity_iint_cache* integrity_inode_get_kmod(struct inode *inode) ++{ ++ return NULL; ++} ++ ++static void integrity_inode_free_kmod(struct inode *inode) ++{ ++ return; ++} ++ ++struct integrity_iint_cache * ++ (*integrity_inode_get)(struct inode *) = &integrity_inode_get_kmod; ++void ++ (*integrity_inode_free)(struct inode*) = &integrity_inode_free_kmod; ++ ++EXPORT_SYMBOL_GPL(integrity_inode_get); ++EXPORT_SYMBOL_GPL(integrity_inode_free); ++#endif ++ ++#ifndef CONFIG_IMA ++static int ima_bprm_check_kmod(struct linux_binprm *bprm) ++{ ++ return 0; ++} ++ ++static int ima_file_check_kmod(struct file *file, int mask, int opened) ++{ ++ return 0; ++} ++ ++static void ima_file_free_kmod(struct file *file) ++{ ++ return; ++} ++ ++static int ima_file_mmap_kmod(struct file *file, unsigned long prot) ++{ ++ return 0; ++} ++ ++static int ima_module_check_kmod(struct file *file) ++{ ++ return 0; ++} ++ ++int ++ (*ima_bprm_check)(struct linux_binprm *) = &ima_bprm_check_kmod; ++int ++ (*ima_file_check)(struct file *, int, int) = &ima_file_check_kmod; ++void ++ (*ima_file_free)(struct file *) = &ima_file_free_kmod; ++int ++ (*ima_file_mmap)(struct file*, unsigned long) = &ima_file_mmap_kmod; ++int ++ (*ima_module_check)(struct file *) = &ima_module_check_kmod; ++ ++EXPORT_SYMBOL_GPL(ima_bprm_check); ++EXPORT_SYMBOL_GPL(ima_file_check); ++EXPORT_SYMBOL_GPL(ima_file_free); ++EXPORT_SYMBOL_GPL(ima_file_mmap); ++EXPORT_SYMBOL_GPL(ima_module_check); ++#endif ++ ++#ifndef CONFIG_IMA_APPRAISE ++static void ima_inode_post_setattr_kmod(struct dentry *dentry) ++{ ++ return; ++} ++ ++static int ima_inode_setxattr_kmod(struct dentry *dentry, ++ const char *xattr_name, ++ const void *xattr_value, ++ size_t xattr_value_len) ++{ ++ return 0; ++} ++ ++static int ima_inode_removexattr_kmod(struct dentry *dentry, ++ const char *xattr_name) ++{ ++ return 0; ++} ++ ++void ++ (*ima_inode_post_setattr)(struct dentry *) = &ima_inode_post_setattr_kmod; ++int ++ (*ima_inode_setxattr)(struct dentry *, const char *, ++ const void *, size_t) = &ima_inode_setxattr_kmod; ++int ++ (*ima_inode_removexattr)(struct dentry *, ++ const char *) = &ima_inode_removexattr_kmod; ++ ++EXPORT_SYMBOL_GPL(ima_inode_post_setattr); ++EXPORT_SYMBOL_GPL(ima_inode_setxattr); ++EXPORT_SYMBOL_GPL(ima_inode_removexattr); ++#endif ++ + int security_ptrace_access_check(struct task_struct *child, unsigned int mode) + { + #ifdef CONFIG_SECURITY_YAMA_STACKED +@@ -694,8 +798,11 @@ EXPORT_SYMBOL(security_inode_listsecurity); + + void security_inode_getsecid(struct inode *inode, u32 *secid) + { +- security_ops->inode_getsecid(inode, secid); ++ if (unlikely(IS_PRIVATE(inode))) ++ return; ++ security_ops->inode_getsecid(inode, secid); + } ++EXPORT_SYMBOL_GPL(security_inode_getsecid); + + int security_inode_copy_up(struct dentry *src, struct cred **new) + { +@@ -1478,6 +1585,7 @@ int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) + { + return security_ops->audit_rule_init(field, op, rulestr, lsmrule); + } ++EXPORT_SYMBOL_GPL(security_audit_rule_init); + + int security_audit_rule_known(struct audit_krule *krule) + { +@@ -1494,5 +1602,6 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, + { + return security_ops->audit_rule_match(secid, field, op, lsmrule, actx); + } ++EXPORT_SYMBOL_GPL(security_audit_rule_match); + + #endif /* CONFIG_AUDIT */ +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/US103091-IMA-System-Configuration.patch b/kernel-std/centos/patches/US103091-IMA-System-Configuration.patch new file mode 100644 index 000000000..6c19c442b --- /dev/null +++ b/kernel-std/centos/patches/US103091-IMA-System-Configuration.patch @@ -0,0 +1,244 @@ +From f2c03d2e4f230aceaeb164ae97bec0dec05c0852 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Kam Nasim +Date: Wed, 4 Oct 2017 14:02:10 -0400 +Subject: [PATCH 1/1] US103091: IMA: System Configuration + +Normally (if trusted integrity keyring is disabled), the _ima keyring +needs to be created by user space (specifically systemd), but that has +the added disadvantage of requiring the IMA public key to reside on the +file system as opposed to being compiled in. Somebody could render some +serious Grade A damage by corrupting this public key on the FS. +Crippling the system if IMA 'enforce' action is enabled. + +We will therefore create the IMA keyring inside the kernel and load the +IMA public key as a compiled data blob, similar to how the Kernel loads +trusted X509 keys into the system truststore (.system_keyring) + +Signed-off-by: Jim Somerville +--- + .gitignore | 1 + + include/keys/system_keyring.h | 2 ++ + kernel/Makefile | 42 ++++++++++++++++++++-- + kernel/ima_certificate.S | 20 +++++++++++ + kernel/system_keyring.c | 82 +++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 145 insertions(+), 2 deletions(-) + create mode 100644 kernel/ima_certificate.S + +diff --git a/.gitignore b/.gitignore +index f73f35f..7148219 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -106,3 +106,4 @@ localversion + + # Red Hat key security + kernel/x509_certificate_list ++kernel/ima_x509_certificate +diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h +index 0e49b3c..6b2da90 100644 +--- a/include/keys/system_keyring.h ++++ b/include/keys/system_keyring.h +@@ -34,4 +34,6 @@ static inline struct key *get_system_trusted_keyring(void) + + #endif /* CONFIG_SYSTEM_TRUSTED_KEYRING */ + ++extern struct key *ima_keyring; ++ + #endif /* _KEYS_SYSTEM_KEYRING_H */ +diff --git a/kernel/Makefile b/kernel/Makefile +index 5701720..9c50e4b 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -56,7 +56,7 @@ obj-$(CONFIG_QUEUED_SPINLOCKS) += qspinlock.o + obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o qrwlock_gen.o + obj-$(CONFIG_LOCK_SPIN_ON_OWNER) += osq_lock.o + obj-$(CONFIG_UID16) += uid16.o +-obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o ++obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o ima_certificate.o + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_MODULE_SIG) += module_signing.o + obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o +@@ -196,7 +196,45 @@ targets += $(obj)/.x509.list + $(obj)/.x509.list: + @echo $(X509_CERTIFICATES) >$@ + +-clean-files := x509_certificate_list .x509.list ++ ++############################################################################### ++# ++# We will roll in the IMA X.509 certificate and pull it in the the kernel ++# so that it gets loaded into the _ima keyring during boot. ++# ++# Ideally, this should have been treated similar to other .x509 certificates ++# (X509_CERTIFICATES), but those all get loaded into the system trusted keyring ++# and since the canonical pathnames are not available in the x509_certificate_list ++# compiled data blob, there is no way to isolate the IMA certificate from the ++# rest. Therefore we treat the IMA certificate as a seperate blob all together. ++# ++# We look in the source root for the IMA certificate, of name "ima_signing_key.pub" ++# ++############################################################################### ++IMA_X509_CERTIFICATE := $(srctree)/ima_signing_key.pub ++ ++ifneq ($(wildcard $(obj)/.x509.ima),) ++ifneq ($(shell cat $(obj)/.x509.ima),$(IMA_X509_CERTIFICATE)) ++$(info IMA: X.509 certificate changed) ++$(shell rm $(obj)/.x509.ima) ++endif ++endif ++ ++kernel/ima_certificate.o: $(obj)/ima_x509_certificate ++ ++quiet_cmd_imacert = CERTS $@ ++ cmd_imacert = cat $(IMA_X509_CERTIFICATE) >$@ $(foreach IMA_X509,$(IMA_X509_CERTIFICATE),; echo " - Including cert $(IMA_X509)") ++ ++targets += $(obj)/ima_x509_certificate ++$(obj)/ima_x509_certificate: $(IMA_X509_CERTIFICATE) $(obj)/.x509.ima ++ $(call if_changed,imacert) ++ ++targets += $(obj)/.x509.ima ++$(obj)/.x509.ima: ++ @echo $(IMA_X509_CERTIFICATE) >$@ ++ ++ ++clean-files := x509_certificate_list .x509.list ima_x509_certificate .x509.ima + endif + + ifeq ($(CONFIG_MODULE_SIG),y) +diff --git a/kernel/ima_certificate.S b/kernel/ima_certificate.S +new file mode 100644 +index 0000000..0c665dd +--- /dev/null ++++ b/kernel/ima_certificate.S +@@ -0,0 +1,20 @@ ++#include ++#include ++ ++ __INITRODATA ++ ++ .align 8 ++ .globl VMLINUX_SYMBOL(ima_system_certificate) ++VMLINUX_SYMBOL(ima_system_certificate): ++__cert_list_start: ++ .incbin "kernel/ima_x509_certificate" ++__cert_list_end: ++ ++ .align 8 ++ .globl VMLINUX_SYMBOL(ima_system_certificate_size) ++VMLINUX_SYMBOL(ima_system_certificate_size): ++#ifdef CONFIG_64BIT ++ .quad __cert_list_end - __cert_list_start ++#else ++ .long __cert_list_end - __cert_list_start ++#endif +diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c +index c15e93f..92beb15 100644 +--- a/kernel/system_keyring.c ++++ b/kernel/system_keyring.c +@@ -23,10 +23,15 @@ EXPORT_SYMBOL_GPL(system_trusted_keyring); + #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING + struct key *system_blacklist_keyring; + #endif ++struct key *ima_keyring; ++EXPORT_SYMBOL_GPL(ima_keyring); + + extern __initconst const u8 system_certificate_list[]; + extern __initconst const unsigned long system_certificate_list_size; + ++extern __initconst const u8 ima_system_certificate[]; ++extern __initconst const unsigned long ima_system_certificate_size; ++ + /* + * Load the compiled-in keys + */ +@@ -57,6 +62,27 @@ static __init int system_trusted_keyring_init(void) + + set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags); + #endif ++ /* Normally (if trusted integrity keyring is disabled), the _ima ++ * keyring needs to be created by user space but that has the ++ * added disadvantage of requiring the IMA public key to reside on ++ * the file system as opposed to being compiled in. ++ * We will therefore form a _ima keyring here and load build ++ * the IMA X.509 certificate ++ * ++ * N.B: The IMA keyring only allows root userspace view & read ops ++ */ ++ pr_notice("Initializing system IMA keyring\n"); ++ ++ ima_keyring = keyring_alloc("_ima", ++ KUIDT_INIT(0), KGIDT_INIT(0), ++ current_cred(), ++ ((KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), ++ KEY_ALLOC_NOT_IN_QUOTA, NULL); ++ if (IS_ERR(ima_keyring)) ++ panic("Can't allocate system IMA keyring\n"); ++ ++ set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_keyring->flags); + + return 0; + } +@@ -121,3 +147,59 @@ dodgy_cert: + return 0; + } + late_initcall(load_system_certificate_list); ++ ++/* ++ * Load the compiled-in IMA certificate. ++ */ ++static __init int load_ima_system_certificate(void) ++{ ++ key_ref_t key; ++ const u8 *p, *end; ++ size_t plen; ++ ++ pr_notice("Loading compiled-in X.509 IMA certificate\n"); ++ ++ p = ima_system_certificate; ++ end = p + ima_system_certificate_size; ++ while (p < end) { ++ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more ++ * than 256 bytes in size. ++ */ ++ if (end - p < 4) ++ goto dodgy_cert; ++ if (p[0] != 0x30 && ++ p[1] != 0x82) ++ goto dodgy_cert; ++ plen = (p[2] << 8) | p[3]; ++ plen += 4; ++ if (plen > end - p) ++ goto dodgy_cert; ++ ++ key = key_create_or_update(make_key_ref(ima_keyring, 1), ++ "asymmetric", ++ NULL, ++ p, ++ plen, ++ ((KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ), ++ KEY_ALLOC_NOT_IN_QUOTA | ++ KEY_ALLOC_TRUSTED); ++ if (IS_ERR(key)) { ++ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", ++ PTR_ERR(key)); ++ } else { ++ set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags); ++ pr_notice("Loaded X.509 cert '%s'\n", ++ key_ref_to_ptr(key)->description); ++ key_ref_put(key); ++ } ++ p += plen; ++ } ++ ++ return 0; ++ ++dodgy_cert: ++ pr_err("Problem parsing in-kernel X.509 IMA certificate\n"); ++ return 0; ++} ++late_initcall(load_ima_system_certificate); +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/affine-compute-kernel-threads.patch b/kernel-std/centos/patches/affine-compute-kernel-threads.patch new file mode 100644 index 000000000..0c1fc4ce2 --- /dev/null +++ b/kernel-std/centos/patches/affine-compute-kernel-threads.patch @@ -0,0 +1,168 @@ +From ca2ccd52a7fd1e95801ee3a8e3cf6cd5a437473a Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Chris Friesen +Date: Tue, 24 Nov 2015 16:27:28 -0500 +Subject: [PATCH 05/24] affine compute kernel threads + +This is a kernel enhancement to configure the cpu affinity of kernel +threads via kernel boot option kthread_cpus=. The compute +kickstart file and compute-huge.sh scripts will update grub with the +new option. + +With kthread_cpus specified, the cpumask is immediately applied upon +thread launch. This does not affect kernel threads that specify cpu +and node. + +Note: this is based off of Christoph Lameter's patch at +https://lwn.net/Articles/565932/ with the only difference being +the kernel parameter changed from kthread to kthread_cpus. + +Signed-off-by: Christoph Lameter +Signed-off-by: Chris Friesen +[VT: The existing "isolcpus" + kernel bootarg, cgroup/cpuset, and taskset might provide the some + way to have cpu isolation. However none of them satisfies the requirements. + Replacing spaces with tabs. Combine two calls of set_cpus_allowed_ptr() + in kernel_init_freeable() in init/main.c into one. Performed tests] +Signed-off-by: Vu Tran + +Signed-off-by: Jim Somerville +--- + Documentation/kernel-parameters.txt | 10 ++++++++++ + include/linux/cpumask.h | 2 ++ + init/main.c | 6 ++---- + kernel/cpu.c | 13 +++++++++++++ + kernel/kmod.c | 3 +++ + kernel/kthread.c | 4 ++-- + 6 files changed, 32 insertions(+), 6 deletions(-) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index cbd5f28..9c29169 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -1482,6 +1482,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + kstack=N [X86] Print N words from the kernel stack + in oops dumps. + ++ kthread_cpus= [KNL, SMP] Only run kernel threads on the specified ++ list of processors. The kernel will start threads ++ on the indicated processors only (unless there ++ are specific reasons to run a thread with ++ different affinities). This can be used to make ++ init start on certain processors and also to ++ control where kmod and other user space threads ++ are being spawned. Allows to keep kernel threads ++ away from certain cores unless absoluteluy necessary. ++ + kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. + Default is 0 (don't ignore, but inject #GP) + +diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h +index ca6c077..1f1420d 100644 +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -52,6 +52,7 @@ extern int nr_cpu_ids; + * cpu_present_mask - has bit 'cpu' set iff cpu is populated + * cpu_online_mask - has bit 'cpu' set iff cpu available to scheduler + * cpu_active_mask - has bit 'cpu' set iff cpu available to migration ++ * cpu_kthread_mask - has bit 'cpu' set iff general kernel threads allowed + * + * If !CONFIG_HOTPLUG_CPU, present == possible, and active == online. + * +@@ -88,6 +89,7 @@ extern const struct cpumask *const cpu_possible_mask; + extern const struct cpumask *const cpu_online_mask; + extern const struct cpumask *const cpu_present_mask; + extern const struct cpumask *const cpu_active_mask; ++extern const struct cpumask *const cpu_kthread_mask; + + #if NR_CPUS > 1 + #define num_online_cpus() cpumask_weight(cpu_online_mask) +diff --git a/init/main.c b/init/main.c +index d7bc443..3efc7dd 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -943,10 +943,6 @@ static noinline void __init kernel_init_freeable(void) + * init can allocate pages on any node + */ + set_mems_allowed(node_states[N_MEMORY]); +- /* +- * init can run on any cpu. +- */ +- set_cpus_allowed_ptr(current, cpu_all_mask); + + cad_pid = task_pid(current); + +@@ -962,6 +958,8 @@ static noinline void __init kernel_init_freeable(void) + + do_basic_setup(); + ++ set_cpus_allowed_ptr(current, cpu_kthread_mask); ++ + /* Open the /dev/console on the rootfs, this should never fail */ + if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) + pr_err("Warning: unable to open an initial console.\n"); +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 6442ecf..c610377 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -713,6 +713,19 @@ static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly; + const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits); + EXPORT_SYMBOL(cpu_active_mask); + ++static DECLARE_BITMAP(cpu_kthread_bits, CONFIG_NR_CPUS) __read_mostly ++ = CPU_BITS_ALL; ++const struct cpumask *const cpu_kthread_mask = to_cpumask(cpu_kthread_bits); ++EXPORT_SYMBOL(cpu_kthread_mask); ++ ++static int __init kthread_setup(char *str) ++{ ++ cpulist_parse(str, (struct cpumask *)&cpu_kthread_bits); ++ return 1; ++} ++__setup("kthread_cpus=", kthread_setup); ++ ++ + void set_cpu_possible(unsigned int cpu, bool possible) + { + if (possible) +diff --git a/kernel/kmod.c b/kernel/kmod.c +index 86ab754..4bf584b 100644 +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -204,6 +204,9 @@ static int ____call_usermodehelper(void *data) + flush_signal_handlers(current, 1); + spin_unlock_irq(¤t->sighand->siglock); + ++ /* We can run only where init is allowed to run. */ ++ set_cpus_allowed_ptr(current, cpu_kthread_mask); ++ + /* + * Our parent is keventd, which runs with elevated scheduling priority. + * Avoid propagating that into the userspace child. +diff --git a/kernel/kthread.c b/kernel/kthread.c +index 703d910..7ea32eb 100644 +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -284,7 +284,7 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), + * The kernel thread should not inherit these properties. + */ + sched_setscheduler_nocheck(create.result, SCHED_NORMAL, ¶m); +- set_cpus_allowed_ptr(create.result, cpu_all_mask); ++ set_cpus_allowed_ptr(create.result, cpu_kthread_mask); + } + return create.result; + } +@@ -454,7 +454,7 @@ int kthreadd(void *unused) + /* Setup a clean context for our children to inherit. */ + set_task_comm(tsk, "kthreadd"); + ignore_signals(tsk); +- set_cpus_allowed_ptr(tsk, cpu_all_mask); ++ set_cpus_allowed_ptr(tsk, cpu_kthread_mask); + set_mems_allowed(node_states[N_MEMORY]); + + current->flags |= PF_NOFREEZE; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch b/kernel-std/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch new file mode 100644 index 000000000..1ef77dce7 --- /dev/null +++ b/kernel-std/centos/patches/aic94xx-Skip-reading-user-settings-if-flash-is-not-f.patch @@ -0,0 +1,52 @@ +From 36dd5acd196574d41de3e81d8264df475bbb7123 Mon Sep 17 00:00:00 2001 +Message-Id: <36dd5acd196574d41de3e81d8264df475bbb7123.1510260544.git.Jim.Somerville@windriver.com> +From: Hannes Reinecke +Date: Mon, 6 Jul 2015 13:07:58 +0200 +Subject: [PATCH 1/1] aic94xx: Skip reading user settings if flash is not found + +If no user settings are found it's pointless trying to +read them from flash. So skip that step. +This also fixes a compilation warning about uninitialized variables in +aic94xx. + +Signed-off-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Signed-off-by: James Bottomley +Signed-off-by: Jim Somerville +--- + drivers/scsi/aic94xx/aic94xx_sds.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c +index edb43fd..c831e30 100644 +--- a/drivers/scsi/aic94xx/aic94xx_sds.c ++++ b/drivers/scsi/aic94xx/aic94xx_sds.c +@@ -983,7 +983,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, + { + int err, i; + u32 offs, size; +- struct asd_ll_el *el; ++ struct asd_ll_el *el = NULL; + struct asd_ctrla_phy_settings *ps; + struct asd_ctrla_phy_settings dflt_ps; + +@@ -1004,6 +1004,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, + + size = sizeof(struct asd_ctrla_phy_settings); + ps = &dflt_ps; ++ goto out_process; + } + + if (size == 0) +@@ -1028,7 +1029,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, + ASD_DPRINTK("couldn't find ctrla phy settings struct\n"); + goto out2; + } +- ++out_process: + err = asd_process_ctrla_phy_settings(asd_ha, ps); + if (err) { + ASD_DPRINTK("couldn't process ctrla phy settings\n"); +-- +1.9.1 + diff --git a/kernel-std/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch b/kernel-std/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch new file mode 100644 index 000000000..914e5fa07 --- /dev/null +++ b/kernel-std/centos/patches/arch-x86-kernel-pci-dma.c-fix-dma_generic_alloc_cohe.patch @@ -0,0 +1,58 @@ +From 99d7fa8c3e61f8fe36b2fd4b09e94a871e3a55fe Mon Sep 17 00:00:00 2001 +Message-Id: <99d7fa8c3e61f8fe36b2fd4b09e94a871e3a55fe.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Wed, 4 Jun 2014 16:06:56 -0700 +Subject: [PATCH 15/24] arch/x86/kernel/pci-dma.c: fix + dma_generic_alloc_coherent() when CONFIG_DMA_CMA is enabled + +dma_generic_alloc_coherent() firstly attempts to allocate by +dma_alloc_from_contiguous() if CONFIG_DMA_CMA is enabled. But the +memory region allocated by it may not fit within the device's DMA mask. +This change makes it fall back to usual alloc_pages_node() allocation +for such cases. + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +(cherry picked from commit 38f7ea5a082bbde9e64b7ece389f20e71a9806f4) + +Conflicts: + arch/x86/kernel/pci-dma.c + +Signed-off-by: Jim Somerville +--- + arch/x86/kernel/pci-dma.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c +index 9d92ea8..dbc2c74 100644 +--- a/arch/x86/kernel/pci-dma.c ++++ b/arch/x86/kernel/pci-dma.c +@@ -100,8 +100,13 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, + flag &= ~__GFP_ZERO; + again: + page = NULL; +- if (!(flag & GFP_ATOMIC)) ++ if (!(flag & GFP_ATOMIC)) { + page = dma_alloc_from_contiguous(dev, count, get_order(size)); ++ if (page && page_to_phys(page) + size > dma_mask) { ++ dma_release_from_contiguous(dev, page, count); ++ page = NULL; ++ } ++ } + if (!page) + page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); + if (!page) +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch b/kernel-std/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch new file mode 100644 index 000000000..f228d0799 --- /dev/null +++ b/kernel-std/centos/patches/cma-add-placement-specifier-for-cma-kernel-parameter.patch @@ -0,0 +1,224 @@ +From a4a5171b7b664bb387aa05bcaaea3894534f15fe Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Tue, 31 May 2016 16:09:04 -0400 +Subject: [PATCH 10/24] cma: add placement specifier for "cma=" kernel + parameter + +Commit 5ea3b1b2f8ad9162684431ce6188102ca4c64b7a upstream +Backported-by: Nam Ninh + +Currently, "cma=" kernel parameter is used to specify the size of CMA, +but we can't specify where it is located. We want to locate CMA below +4GB for devices only supporting 32-bit addressing on 64-bit systems +without iommu. + +This enables to specify the placement of CMA by extending "cma=" kernel +parameter. + +Examples: + 1. locate 64MB CMA below 4GB by "cma=64M@0-4G" + 2. locate 64MB CMA exact at 512MB by "cma=64M@512M" + +Note that the DMA contiguous memory allocator on x86 assumes that +page_address() works for the pages to allocate. So this change requires +to limit end address of contiguous memory area upto max_pfn_mapped to +prevent from locating it on highmem area by the argument of +dma_contiguous_reserve(). + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + Documentation/kernel-parameters.txt | 7 +++++-- + arch/x86/kernel/setup.c | 2 +- + drivers/base/dma-contiguous.c | 42 ++++++++++++++++++++++++++++--------- + include/linux/dma-contiguous.h | 9 +++++--- + 4 files changed, 44 insertions(+), 16 deletions(-) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index e22bb2c..15ef1c8 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -560,8 +560,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + Also note the kernel might malfunction if you disable + some critical bits. + +- cma=nn[MG] [ARM,KNL] +- Sets the size of kernel global memory area for contiguous ++ cma=nn[MG]@[start[MG][-end[MG]]] ++ [ARM,X86,KNL] ++ Sets the size of kernel global memory area for ++ contiguous memory allocations and optionally the ++ placement constraint by the physical address range of + memory allocations. For more information, see + include/linux/dma-contiguous.h + +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index dcb7e8a..ab7c0c3 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1252,7 +1252,7 @@ void __init setup_arch(char **cmdline_p) + setup_real_mode(); + + memblock_set_current_limit(get_max_mapped()); +- dma_contiguous_reserve(0); ++ dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT); + + /* + * NOTE: On x86-32, only from this point on, fixmaps are ready for use. +diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c +index 99802d6..8f50513 100644 +--- a/drivers/base/dma-contiguous.c ++++ b/drivers/base/dma-contiguous.c +@@ -59,11 +59,22 @@ struct cma *dma_contiguous_default_area; + */ + static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M; + static phys_addr_t size_cmdline = -1; ++static phys_addr_t base_cmdline; ++static phys_addr_t limit_cmdline; + + static int __init early_cma(char *p) + { + pr_debug("%s(%s)\n", __func__, p); + size_cmdline = memparse(p, &p); ++ if (*p != '@') ++ return 0; ++ base_cmdline = memparse(p + 1, &p); ++ if (*p != '-') { ++ limit_cmdline = base_cmdline + size_cmdline; ++ return 0; ++ } ++ limit_cmdline = memparse(p + 1, &p); ++ + return 0; + } + early_param("cma", early_cma); +@@ -107,11 +118,18 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void) + void __init dma_contiguous_reserve(phys_addr_t limit) + { + phys_addr_t selected_size = 0; ++ phys_addr_t selected_base = 0; ++ phys_addr_t selected_limit = limit; ++ bool fixed = false; + + pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); + + if (size_cmdline != -1) { + selected_size = size_cmdline; ++ selected_base = base_cmdline; ++ selected_limit = min_not_zero(limit_cmdline, limit); ++ if (base_cmdline + size_cmdline == limit_cmdline) ++ fixed = true; + } else { + #ifdef CONFIG_CMA_SIZE_SEL_MBYTES + selected_size = size_bytes; +@@ -128,10 +146,12 @@ void __init dma_contiguous_reserve(phys_addr_t limit) + pr_debug("%s: reserving %ld MiB for global area\n", __func__, + (unsigned long)selected_size / SZ_1M); + +- dma_contiguous_reserve_area(selected_size, 0, limit, +- &dma_contiguous_default_area); ++ dma_contiguous_reserve_area(selected_size, selected_base, ++ selected_limit, ++ &dma_contiguous_default_area, ++ fixed); + } +-}; ++} + + static DEFINE_MUTEX(cma_mutex); + +@@ -187,15 +207,20 @@ core_initcall(cma_init_reserved_areas); + * @base: Base address of the reserved area optional, use 0 for any + * @limit: End address of the reserved memory (optional, 0 for any). + * @res_cma: Pointer to store the created cma region. ++ * @fixed: hint about where to place the reserved area + * + * This function reserves memory from early allocator. It should be + * called by arch specific code once the early allocator (memblock or bootmem) + * has been activated and all other subsystems have already allocated/reserved + * memory. This function allows to create custom reserved areas for specific + * devices. ++ * ++ * If @fixed is true, reserve contiguous area at exactly @base. If false, ++ * reserve in range from @base to @limit. + */ + int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, +- phys_addr_t limit, struct cma **res_cma) ++ phys_addr_t limit, struct cma **res_cma, ++ bool fixed) + { + struct cma *cma = &cma_areas[cma_area_count]; + phys_addr_t alignment; +@@ -221,18 +246,15 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + limit &= ~(alignment - 1); + + /* Reserve memory */ +- if (base) { ++ if (base && fixed) { + if (memblock_is_region_reserved(base, size) || + memblock_reserve(base, size) < 0) { + ret = -EBUSY; + goto err; + } + } else { +- /* +- * Use __memblock_alloc_base() since +- * memblock_alloc_base() panic()s. +- */ +- phys_addr_t addr = __memblock_alloc_base(size, alignment, limit); ++ phys_addr_t addr = memblock_alloc_range(size, alignment, base, ++ limit); + if (!addr) { + ret = -ENOMEM; + goto err; +diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h +index 3b28f93..772eab5 100644 +--- a/include/linux/dma-contiguous.h ++++ b/include/linux/dma-contiguous.h +@@ -88,7 +88,8 @@ static inline void dma_contiguous_set_default(struct cma *cma) + void dma_contiguous_reserve(phys_addr_t addr_limit); + + int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, +- phys_addr_t limit, struct cma **res_cma); ++ phys_addr_t limit, struct cma **res_cma, ++ bool fixed); + + /** + * dma_declare_contiguous() - reserve area for contiguous memory handling +@@ -108,7 +109,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, + { + struct cma *cma; + int ret; +- ret = dma_contiguous_reserve_area(size, base, limit, &cma); ++ ret = dma_contiguous_reserve_area(size, base, limit, &cma, true); + if (ret == 0) + dev_set_cma_area(dev, cma); + +@@ -136,7 +137,9 @@ static inline void dma_contiguous_set_default(struct cma *cma) { } + static inline void dma_contiguous_reserve(phys_addr_t limit) { } + + static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, +- phys_addr_t limit, struct cma **res_cma) { ++ phys_addr_t limit, struct cma **res_cma, ++ bool fixed) ++{ + return -ENOSYS; + } + +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch b/kernel-std/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch new file mode 100644 index 000000000..76141e55a --- /dev/null +++ b/kernel-std/centos/patches/cpuidle-menu-Avoid-taking-spinlock-for-accessing-QoS.patch @@ -0,0 +1,92 @@ +From 44285722649a364928853647fad5ad2d9be3b488 Mon Sep 17 00:00:00 2001 +Message-Id: <44285722649a364928853647fad5ad2d9be3b488.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: "Rafael J. Wysocki" +Date: Fri, 24 Feb 2017 13:25:14 +0100 +Subject: [PATCH 22/24] cpuidle: menu: Avoid taking spinlock for accessing QoS + values + +[commit 6dbf5cea05a7098a69f294c96b6d76f08562cae5 from linux-stable ] + +After commit 9908859acaa9 (cpuidle/menu: add per CPU PM QoS resume +latency consideration) the cpuidle menu governor calls +dev_pm_qos_read_value() on CPU devices to read the current resume latency QoS +constraint values for them. That function takes a spinlock to prevent the +device's power.qos pointer from becoming NULL during the access which is a +problem for the RT patchset where spinlocks are converted into mutexes and +the idle loop stops working. + +However, it is not even necessary for the menu governor to take +that spinlock, because the power.qos pointer accessed under it +cannot be modified during the access anyway. + +For this reason, introduce a "raw" routine for accessing device +QoS resume latency constraints without locking and use it in the +menu governor. + +Fixes: 9908859acaa9 (cpuidle/menu: add per CPU PM QoS resume latency consideration) +Acked-by: Alex Shi +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev +Signed-off-by: Jim Somerville +--- + drivers/base/power/qos.c | 3 +-- + drivers/cpuidle/governors/menu.c | 2 +- + include/linux/pm_qos.h | 6 ++++++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c +index 2f8ac59..08a4cec 100644 +--- a/drivers/base/power/qos.c ++++ b/drivers/base/power/qos.c +@@ -104,8 +104,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags); + */ + s32 __dev_pm_qos_read_value(struct device *dev) + { +- return IS_ERR_OR_NULL(dev->power.qos) ? +- 0 : pm_qos_read_value(&dev->power.qos->latency); ++ return dev_pm_qos_raw_read_value(dev); + } + + /** +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index fe2dcb8..f9861fd 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -265,7 +265,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + int i; + int multiplier; + struct timespec t; +- int resume_latency = dev_pm_qos_read_value(device); ++ int resume_latency = dev_pm_qos_raw_read_value(device); + + if (data->needs_update) { + menu_update(drv, dev); +diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h +index 5281e7f..1d8b629 100644 +--- a/include/linux/pm_qos.h ++++ b/include/linux/pm_qos.h +@@ -217,6 +217,11 @@ static inline s32 dev_pm_qos_requested_flags(struct device *dev) + { + return dev->power.qos->flags_req->data.flr.flags; + } ++static inline s32 dev_pm_qos_raw_read_value(struct device *dev) ++{ ++ return IS_ERR_OR_NULL(dev->power.qos) ? ++ 0 : pm_qos_read_value(&dev->power.qos->latency); ++} + #else + static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) + { return 0; } +@@ -236,6 +241,7 @@ static inline void dev_pm_qos_hide_latency_tolerance(struct device *dev) {} + + static inline s32 dev_pm_qos_requested_latency(struct device *dev) { return 0; } + static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; } ++static inline s32 dev_pm_qos_raw_read_value(struct device *dev) { return 0; } + #endif + + #endif +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch b/kernel-std/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch new file mode 100644 index 000000000..b62955c13 --- /dev/null +++ b/kernel-std/centos/patches/cpuidle-menu-add-per-CPU-PM-QoS-resume-latency-consi.patch @@ -0,0 +1,71 @@ +From 4350ccda4d2c67436aef0c702d61ca6d351ddbf6 Mon Sep 17 00:00:00 2001 +Message-Id: <4350ccda4d2c67436aef0c702d61ca6d351ddbf6.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Alex Shi +Date: Thu, 12 Jan 2017 21:27:04 +0800 +Subject: [PATCH 20/24] cpuidle/menu: add per CPU PM QoS resume latency + consideration + +[ commit 9908859acaa95640d4a07991a93f7cd5bfc18e02 from linux-stable ] + +There may be special requirements on CPU response time, like if +a interrupt is pinned to a CPU, that CPU should not go into excessively deep +idle states. For this reason, add a mechanism for adding PM QoS resume +latency constraints for individual CPUs and modify the menu governor to take +them into account. + +To that end, extend the device PM QoS pm_qos_resume_latency attribute +to CPUs, which is possible, because the exit latency for CPUs is +effectively equivalent to the resume latency for devices. + +Signed-off-by: Alex Shi +Acked-by: Rik van Riel +[ rjw : Subject & changelog ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev + +Signed-off-by: Jim Somerville +--- + drivers/cpuidle/governors/menu.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index eb9fb0e..fe2dcb8 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + #define BUCKETS 12 +@@ -259,10 +260,12 @@ again: + static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + { + struct menu_device *data = &__get_cpu_var(menu_devices); ++ struct device *device = get_cpu_device(dev->cpu); + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); + int i; + int multiplier; + struct timespec t; ++ int resume_latency = dev_pm_qos_read_value(device); + + if (data->needs_update) { + menu_update(drv, dev); +@@ -271,6 +274,10 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + + data->exit_us = 0; + ++ /* resume_latency is 0 means no restriction */ ++ if (resume_latency && resume_latency < latency_req) ++ latency_req = resume_latency; ++ + /* Special case when user has set very strict latency requirement */ + if (unlikely(latency_req == 0)) + return 0; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch b/kernel-std/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch new file mode 100644 index 000000000..1a7aed13d --- /dev/null +++ b/kernel-std/centos/patches/cpuidle-menu-stop-seeking-deeper-idle-if-current-sta.patch @@ -0,0 +1,52 @@ +From 63c705c3ed850ff5e620b3851a43d83ed8495fbb Mon Sep 17 00:00:00 2001 +Message-Id: <63c705c3ed850ff5e620b3851a43d83ed8495fbb.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Alex Shi +Date: Thu, 12 Jan 2017 21:27:02 +0800 +Subject: [PATCH 19/24] cpuidle/menu: stop seeking deeper idle if current state + is deep enough + +[ commit 8e37e1a2a3295f5d99e6dbe99eca24eca7a034ef from linux-stable ] + +Obsolete commit 71abbbf856a0 (cpuidle: extend cpuidle and menu +governor to handle dynamic states) wanted to introduce dynamic C-states, but +that idea was dropped long ago. The nonsense deeper C-state checking +remained, though. + +Since both target_residency and exit_latency are longer for deeper +idle state, there's no need to waste CPU time on useless checks. + +Signed-off-by: Alex Shi +Acked-by: Rik van Riel +[ rjw: Subject & changelog ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Alex Kozyrev + +Signed-off-by: Jim Somerville +--- + drivers/cpuidle/governors/menu.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index c99fee9..eb9fb0e 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -323,11 +323,11 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) + if (s->disabled || su->disable) + continue; + if (s->target_residency > data->predicted_us) +- continue; ++ break; + if (s->exit_latency > latency_req) +- continue; ++ break; + if (s->exit_latency * multiplier > data->predicted_us) +- continue; ++ break; + + data->last_state_idx = i; + data->exit_us = s->exit_latency; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/dpt_i2o-fix-build-warning.patch b/kernel-std/centos/patches/dpt_i2o-fix-build-warning.patch new file mode 100644 index 000000000..b865b44e9 --- /dev/null +++ b/kernel-std/centos/patches/dpt_i2o-fix-build-warning.patch @@ -0,0 +1,42 @@ +From f50abb9b63b1d8773e1ce32115701c06416e6f91 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sudip Mukherjee +Date: Thu, 18 Feb 2016 13:59:13 +0530 +Subject: [PATCH 1/1] dpt_i2o: fix build warning + +We were getting build warning about: +drivers/scsi/dpt_i2o.c:183:29: warning: 'dptids' defined but not used + +dptids[] is only used in the MODULE_DEVICE_TABLE so when MODULE is not +defined then dptids[] becomes unused. + +Signed-off-by: Sudip Mukherjee +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Jim Somerville +--- + drivers/scsi/dpt_i2o.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c +index d4cda5e..21c8d21 100644 +--- a/drivers/scsi/dpt_i2o.c ++++ b/drivers/scsi/dpt_i2o.c +@@ -180,11 +180,14 @@ static u8 adpt_read_blink_led(adpt_hba* host) + *============================================================================ + */ + ++#ifdef MODULE + static struct pci_device_id dptids[] = { + { PCI_DPT_VENDOR_ID, PCI_DPT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + { PCI_DPT_VENDOR_ID, PCI_DPT_RAPTOR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + { 0, } + }; ++#endif ++ + MODULE_DEVICE_TABLE(pci,dptids); + + static int adpt_detect(struct scsi_host_template* sht) +-- +1.9.1 + diff --git a/kernel-std/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch b/kernel-std/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch new file mode 100644 index 000000000..57b14eead --- /dev/null +++ b/kernel-std/centos/patches/intel-iommu-allow-ignoring-Ethernet-device-RMRR-with.patch @@ -0,0 +1,120 @@ +From 8abe9a4e18257222f84a2d3e275a5b5db775a297 Mon Sep 17 00:00:00 2001 +Message-Id: <8abe9a4e18257222f84a2d3e275a5b5db775a297.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Matt Peters +Date: Mon, 30 May 2016 10:51:02 -0400 +Subject: [PATCH 08/24] intel-iommu: allow ignoring Ethernet device RMRR with + IOMMU passthrough + +Some BIOS's are reporting DMAR RMRR entries for Ethernet devices +which is causing problems when PCI passthrough is enabled. These +devices should be able to use the static identity map since the +host should not be enforcing specific address ranges when IOMMU +passthrough is enabled. + +Originally-by: Matt Peters +[PG: Added bootarg wrapper and documentation entries.] +Signed-off-by: Paul Gortmaker +Signed-off-by: Nam Ninh + +Signed-off-by: Nam Ninh +Signed-off-by: Jim Somerville +--- + Documentation/Intel-IOMMU.txt | 18 ++++++++++++++++++ + Documentation/kernel-parameters.txt | 5 +++++ + drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++ + 3 files changed, 42 insertions(+) + +diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt +index cf9431d..1dcc349 100644 +--- a/Documentation/Intel-IOMMU.txt ++++ b/Documentation/Intel-IOMMU.txt +@@ -32,6 +32,24 @@ regions will fail. Hence BIOS uses RMRR to specify these regions along with + devices that need to access these regions. OS is expected to setup + unity mappings for these regions for these devices to access these regions. + ++RMRR for other devices? ++----------------------- ++ ++There are reports of BIOS out there that indicate RMRR regions for things ++like ethernet devices. As per mainline commit c875d2c1b8083 ("iommu/vt-d: ++ Exclude devices using RMRRs from IOMMU API domains") such a device is ++"fundamentally incompatible" with the IOMMU API and "we must prevent such ++devices from being used by the IOMMU API." However, in the event that ++the RMRR indicated by the BIOS is assumed to be just a reporting error, ++there is an additional iommu boot arg that can be used to ignore RMRR ++settings for ethernet, i.e. "intel_iommu=on,eth_no_rmrr iommu=pt". ++Note that iommu=pt is required in order to eth_no_rmrr to have effect. ++ ++If you use this setting, you should consult with your hardware vendor to ++confirm that it is just a reporting error, and that it truly is not ++actively using any DMA to/from RMRR, as otherwise system instability ++may result. ++ + How is IOVA generated? + --------------------- + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 9c29169..e22bb2c 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -1264,6 +1264,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + than 32-bit addressing. The default is to look + for translation below 32-bit and if not available + then look in the higher range. ++ eth_no_rmrr [Default Off] ++ With this option provided, the kernel will ignore ++ any specified RMRR regions specified by the BIOS ++ for PCI ethernet devices. Confirm with your hardware ++ vendor the RMRR regions are indeed invalid first. + strict [Default Off] + With this option on every unmap_single operation will + result in a hardware IOTLB flush operation as opposed +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index 171a8b2..e763e78 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -496,6 +496,7 @@ static int dmar_forcedac; + static int intel_iommu_strict; + static int intel_iommu_superpage = 1; + static int intel_iommu_ecs = 1; ++static int intel_iommu_ethrmrr = 1; + + /* We only actually use ECS when PASID support (on the new bit 40) + * is also advertised. Some early implementations — the ones with +@@ -555,6 +556,15 @@ static int __init intel_iommu_setup(char *str) + } else if (!strncmp(str, "forcedac", 8)) { + pr_info("Forcing DAC for PCI devices\n"); + dmar_forcedac = 1; ++ } else if (!strncmp(str, "eth_no_rmrr", 11)) { ++ if (!iommu_pass_through) { ++ printk(KERN_WARNING ++ "Intel-IOMMU: error - eth_no_rmrr requires iommu=pt\n"); ++ } else { ++ printk(KERN_INFO ++ "Intel-IOMMU: ignoring ethernet RMRR values\n"); ++ intel_iommu_ethrmrr = 0; ++ } + } else if (!strncmp(str, "strict", 6)) { + pr_info("Disable batched IOTLB flush\n"); + intel_iommu_strict = 1; +@@ -2674,6 +2684,15 @@ static bool device_is_rmrr_locked(struct device *dev) + + if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev)) + return false; ++ /* As a temporary workaround for issues seen on ProLiant DL380p, ++ * allow the operator to ignore the RMRR settings for ethernet ++ * devices. Ideally the end user should contact their vendor ++ * regarding why there are RMRR, as per mainline c875d2c1b8083 ++ * ("iommu/vt-d: Exclude devices using RMRRs from IOMMU API domains") ++ * it seems that these make no sense at all. ++ */ ++ if ((pdev->class >> 8) == PCI_CLASS_NETWORK_ETHERNET && !intel_iommu_ethrmrr) ++ return false; + } + + return true; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/kernel-3.10.0-x86_64.config.tis_extra b/kernel-std/centos/patches/kernel-3.10.0-x86_64.config.tis_extra new file mode 100644 index 000000000..f0c9b42f6 --- /dev/null +++ b/kernel-std/centos/patches/kernel-3.10.0-x86_64.config.tis_extra @@ -0,0 +1,826 @@ +# Add builtin +CONFIG_MAXSMP=n +CONFIG_NR_CPUS=256 +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_SAS_ATTRS=y +CONFIG_ISCSI_TCP=y +# SCSI Related Drivers +# Let's enable lots of them, pretty much anything RAID capable +CONFIG_ATA=y +CONFIG_SCSI_SAS_LIBSAS=y +CONFIG_SCSI_SAS_ATA=y +CONFIG_BLK_DEV_3W_XXXX_RAID=y +CONFIG_SCSI_3W_9XXX=y +CONFIG_SCSI_3W_SAS=y +CONFIG_SCSI_AACRAID=y +CONFIG_SCSI_DPT_I2O=y +CONFIG_SCSI_ARCMSR=y +CONFIG_SCSI_HPTIOP=y +CONFIG_SCSI_GDTH=y +CONFIG_SCSI_IPS=y +CONFIG_SCSI_STEX=y +CONFIG_SCSI_PMCRAID=y +CONFIG_SCSI_HPSA=y +CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_SMARTPQI=y +CONFIG_SCSI_MPT2SAS=y +CONFIG_SCSI_MPT3SAS=y +CONFIG_SCSI_VIRTIO=y +CONFIG_FUSION_SAS=y +CONFIG_SCSI_AIC94XX=y +CONFIG_SCSI_MVSAS=y +# +CONFIG_SOFT_WATCHDOG=y +CONFIG_VIRTIO=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_MMIO=y +CONFIG_ISO9660_FS=y +CONFIG_VFAT_FS=y +CONFIG_NLS_ISO8859_1=y +CONFIG_BLK_DEV_DRBD=m +CONFIG_DRBD_FAULT_INJECTION=y +CONFIG_MCORE2=y +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SIGEXIT=y +CONFIG_SCHEDSTATS=y + +# Enable runtime Huge TLB support +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_SIZE_SEL_MBYTES=y +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=7 + +# Turn on Intel IOMMU, EXT2_FS and EXT3_FS +CONFIG_INTEL_IOMMU_DEFAULT_ON=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=n +CONFIG_EXT3_FS=y +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y + +# Turn off network drivers that we want +# to build out-of-tree +CONFIG_E1000E=n +CONFIG_I40E=n +CONFIG_I40EVF=n +CONFIG_IXGB=n +CONFIG_IXGBE=n +CONFIG_IXGBEVF=n + +# Turn off TPM drivers that we want +# to build out-of-tree. This will +# disable the TPM HW-RandomNUmberGenerator(RNG) +# and TrustedKeys modules as well, since +# they require the in-kernel TPM driver. +# Both these modules will also need to be +# built out-of-tree when needed. +CONFIG_TCG_TPM=n +CONFIG_TCG_TIS=n +CONFIG_HW_RANDOM_TPM=n +CONFIG_TRUSTED_KEYS=n +CONFIG_TCG_TIS_I2C_ATMEL=n +CONFIG_TCG_TIS_I2C_INFINEON=n +CONFIG_TCG_TIS_I2C_NUVOTON=n +CONFIG_TCG_NSC=n +CONFIG_TCG_ATMEL=n +CONFIG_TCG_INFINEON=n +CONFIG_TCG_CRB=n +CONFIG_TCG_TIS_ST33ZP24=n +CONFIG_TCG_TIS_ST33ZP24_I2C=n +# Also disable TPM Integrity Measurement Architecture +# (IMA), as this will be built out of tree but ensure +# that all their dependencies (that comes from the base kernel) +# that are marked as "select" within the Integrity / IMA +# Kconfigs are still enabled +CONFIG_INTEGRITY=n +CONFIG_IMA=n +CONFIG_EVM=n +CONFIG_SIGNATURE=y +CONFIG_KEYS=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_SECURITYFS=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y + +# Remove unneeded stuff (including stuff exposed +# by saying y to new options above. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=n +CONFIG_PANIC_ON_OOPS=n +CONFIG_SOUND=n +CONFIG_FIREWIRE=n +CONFIG_KPROBES=n +CONFIG_XEN=n +CONFIG_IP_SET=n +CONFIG_IP_VS=n +CONFIG_BT=n +CONFIG_INTEL_MEI=n +CONFIG_USB_USBNET=n +CONFIG_MLX4_EN=n +CONFIG_MLX4_CORE=n +CONFIG_MLX5_EN=n +CONFIG_MLX5_CORE=n +CONFIG_RTL8187=n +CONFIG_MWL8K=n +CONFIG_CFG80211=n +CONFIG_WAN=n +CONFIG_ISDN=n +CONFIG_INPUT_TOUCHSCREEN=n +CONFIG_SSB=n +CONFIG_BCMA=n +CONFIG_MEDIA_SUPPORT=n +CONFIG_ACPI_PROCESSOR_AGGREGATOR=n +CONFIG_ACPI_EXTLOG=n +CONFIG_NET_FOU=n +CONFIG_NET_FOU_IP_TUNNELS=n +CONFIG_GENEVE=n +CONFIG_IPV6_VTI=n +CONFIG_NETFILTER_XT_TARGET_TPROXY=n +CONFIG_NETFILTER_XT_MATCH_CGROUP=n +CONFIG_NETFILTER_XT_MATCH_SOCKET=n +CONFIG_NET_SCH_FQ=n +CONFIG_NET_CLS_BPF=n +CONFIG_BLK_DEV_NULL_BLK=n +CONFIG_GENWQE=n +CONFIG_CXL_BASE=n +CONFIG_DM_ERA=n +CONFIG_DM_RAID=n +CONFIG_DM_SWITCH=n +CONFIG_NLMON=n +CONFIG_FM10K=n +CONFIG_CRASH=n +CONFIG_IPMI_SSIF=n +CONFIG_POWERCAP=n +CONFIG_DRM_BOCHS=n +CONFIG_HID_RMI=n +CONFIG_NET_DMA_RH_KABI=n +CONFIG_HP_WIRELESS=n +CONFIG_OVERLAY_FS=n +CONFIG_NFSD_V4_SECURITY_LABEL=n +CONFIG_DEBUG_SHIRQ=n +CONFIG_PERSISTENT_KEYRINGS=n +CONFIG_BIG_KEYS=n +CONFIG_SECURITY_SECURELEVEL=n +CONFIG_CRYPTO_MCRYPTD=n +CONFIG_CRYPTO_SHA1_MB=n +CONFIG_CRYPTO_DRBG_MENU=n +CONFIG_CRYPTO_DEV_QAT=n +CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=n +CONFIG_CRYPTO_DEV_QAT_DH895xCC=n +CONFIG_CRYPTO_DEV_QAT_C3XXX=n +CONFIG_CRYPTO_DEV_QAT_C62X=n +CONFIG_CRYPTO_DEV_QAT_C3XXXVF=n +CONFIG_CRYPTO_DEV_QAT_C62XVF=n +CONFIG_BPF_JIT=n +CONFIG_PARPORT=n +CONFIG_CDROM_PKTCDVD=n +CONFIG_SENSORS_LIS3LV02D=n +CONFIG_SGI_IOC4=n +CONFIG_TIFM_CORE=n +CONFIG_ENCLOSURE_SERVICES=n +CONFIG_APDS9802ALS=n +CONFIG_ISL29003=n +CONFIG_ISL29020=n +CONFIG_SENSORS_TSL2550=n +CONFIG_SENSORS_BH1770=n +CONFIG_SENSORS_APDS990X=n +CONFIG_PCH_PHUB=n +CONFIG_EEPROM_AT24=n +CONFIG_EEPROM_MAX6875=n +CONFIG_EEPROM_93CX6=n +CONFIG_CB710_CORE=n +CONFIG_SENSORS_LIS3_I2C=n +CONFIG_ALTERA_STAPL=n +CONFIG_VMWARE_VMCI=n +CONFIG_CHR_DEV_ST=n +CONFIG_CHR_DEV_OSST=n +CONFIG_CHR_DEV_SG=n +CONFIG_CHR_DEV_SCH=n +CONFIG_SCSI_CONSTANTS=n +CONFIG_SCSI_LOGGING=n +CONFIG_SCSI_CXGB3_ISCSI=n +CONFIG_SCSI_CXGB4_ISCSI=n +CONFIG_SCSI_AIC79XX=n +CONFIG_SCSI_MVUMI=n +CONFIG_SCSI_MPT2SAS_LOGGING=n +CONFIG_SCSI_MPT3SAS_LOGGING=n +CONFIG_SCSI_UFSHCD=n +CONFIG_VMWARE_PVSCSI=n +CONFIG_FCOE=n +CONFIG_FCOE_FNIC=n +CONFIG_SCSI_INITIO=n +CONFIG_SCSI_PM8001=n +CONFIG_SCSI_SRP=n +CONFIG_SCSI_DH=n +CONFIG_SATA_ACARD_AHCI=n +CONFIG_SATA_SIL24=n +CONFIG_PDC_ADMA=n +CONFIG_SATA_QSTOR=n +CONFIG_SATA_SX4=n +CONFIG_SATA_MV=n +CONFIG_SATA_NV=n +CONFIG_SATA_PROMISE=n +CONFIG_SATA_SIL=n +CONFIG_SATA_SIS=n +CONFIG_SATA_SVW=n +CONFIG_SATA_ULI=n +CONFIG_SATA_VIA=n +CONFIG_SATA_VITESSE=n +CONFIG_PATA_ALI=n +CONFIG_PATA_AMD=n +CONFIG_PATA_ARASAN_CF=n +CONFIG_PATA_ARTOP=n +CONFIG_PATA_ATIIXP=n +CONFIG_PATA_ATP867X=n +CONFIG_PATA_CMD64X=n +CONFIG_PATA_CS5536=n +CONFIG_PATA_HPT366=n +CONFIG_PATA_HPT37X=n +CONFIG_PATA_HPT3X2N=n +CONFIG_PATA_HPT3X3=n +CONFIG_PATA_IT8213=n +CONFIG_PATA_IT821X=n +CONFIG_PATA_JMICRON=n +CONFIG_PATA_MARVELL=n +CONFIG_PATA_NETCELL=n +CONFIG_PATA_NINJA32=n +CONFIG_PATA_OLDPIIX=n +CONFIG_PATA_PDC2027X=n +CONFIG_PATA_PDC_OLD=n +CONFIG_PATA_RDC=n +CONFIG_PATA_SCH=n +CONFIG_PATA_SERVERWORKS=n +CONFIG_PATA_SIL680=n +CONFIG_PATA_SIS=n +CONFIG_PATA_TOSHIBA=n +CONFIG_PATA_VIA=n +CONFIG_DM_DEBUG=n +CONFIG_MACINTOSH_DRIVERS=n +CONFIG_NET_FC=n +CONFIG_NET_TEAM=n +CONFIG_ATL2=n +CONFIG_ATL1=n +CONFIG_ATL1E=n +CONFIG_ATL1C=n +CONFIG_ALX=n +CONFIG_ARM_AT91_ETHER=n +CONFIG_MACB=n +CONFIG_B44=n +CONFIG_BNA=n +CONFIG_NET_CALXEDA_XGMAC=n +CONFIG_CHELSIO_T3=n +CONFIG_CHELSIO_T4=n +CONFIG_CHELSIO_T4VF=n +CONFIG_NET_TULIP=n +CONFIG_IP1000=n +CONFIG_JME=n +CONFIG_MVMDIO=n +CONFIG_SKGE=n +CONFIG_SKY2=n +CONFIG_MYRI10GE=n +CONFIG_PCH_GBE=n +CONFIG_ETHOC=n +CONFIG_QLCNIC=n +CONFIG_QLGE=n +CONFIG_NETXEN_NIC=n +CONFIG_SFC=n +CONFIG_EPIC100=n +CONFIG_SMSC9420=n +CONFIG_AT803X_PHY=n +CONFIG_DAVICOM_PHY=n +CONFIG_QSEMI_PHY=n +CONFIG_LXT_PHY=n +CONFIG_CICADA_PHY=n +CONFIG_VITESSE_PHY=n +CONFIG_SMSC_PHY=n +CONFIG_BCM87XX_PHY=n +CONFIG_ICPLUS_PHY=n +CONFIG_REALTEK_PHY=n +CONFIG_NATIONAL_PHY=n +CONFIG_STE10XP=n +CONFIG_LSI_ET1011C_PHY=n +CONFIG_MICREL_PHY=n +CONFIG_MDIO_BITBANG=n +CONFIG_RT_GROUP_SCHED=n +CONFIG_OPROFILE=n +CONFIG_JUMP_LABEL=n +CONFIG_SYSTEM_BLACKLIST_KEYRING=n +CONFIG_OSF_PARTITION=n +CONFIG_AMIGA_PARTITION=n +CONFIG_MAC_PARTITION=n +CONFIG_BSD_DISKLABEL=n +CONFIG_MINIX_SUBPARTITION=n +CONFIG_SOLARIS_X86_PARTITION=n +CONFIG_UNIXWARE_DISKLABEL=n +CONFIG_SGI_PARTITION=n +CONFIG_SUN_PARTITION=n +CONFIG_KARMA_PARTITION=n +CONFIG_X86_UV=n +CONFIG_I8K=n +CONFIG_MICROCODE_AMD=n +CONFIG_MICROCODE_AMD_EARLY=n +CONFIG_MOVABLE_NODE=n +CONFIG_MEMORY_HOTPLUG=n +CONFIG_BOOTPARAM_HOTPLUG_CPU0=n +CONFIG_X86_POWERNOW_K8=n +CONFIG_X86_AMD_FREQ_SENSITIVITY=n +CONFIG_X86_P4_CLOCKMOD=n +CONFIG_PCIE_ECRC=n +CONFIG_PCIEAER_INJECT=n +CONFIG_PCCARD=n +CONFIG_HOTPLUG_PCI_ACPI_IBM=n +CONFIG_HOTPLUG_PCI_SHPC=n +CONFIG_XFRM_STATISTICS=n +CONFIG_IP_FIB_TRIE_STATS=n +CONFIG_PPP_MPPE=n +CONFIG_USB_CATC=n +CONFIG_USB_KAWETH=n +CONFIG_USB_PEGASUS=n +CONFIG_USB_RTL8150=n +CONFIG_USB_RTL8152=n +CONFIG_USB_HSO=n +CONFIG_USB_IPHETH=n +CONFIG_INPUT_FF_MEMLESS=n +CONFIG_INPUT_POLLDEV=n +CONFIG_INPUT_SPARSEKMAP=n +CONFIG_MOUSE_PS2_ELANTECH=n +CONFIG_MOUSE_PS2_SENTELIC=n +CONFIG_MOUSE_APPLETOUCH=n +CONFIG_MOUSE_BCM5974=n +CONFIG_MOUSE_CYAPA=n +CONFIG_MOUSE_VSXXXAA=n +CONFIG_MOUSE_SYNAPTICS_I2C=n +CONFIG_MOUSE_SYNAPTICS_USB=n +CONFIG_INPUT_TABLET=n +CONFIG_INPUT_PCSPKR=n +CONFIG_INPUT_APANEL=n +CONFIG_INPUT_ATLAS_BTNS=n +CONFIG_INPUT_ATI_REMOTE2=n +CONFIG_INPUT_KEYSPAN_REMOTE=n +CONFIG_INPUT_POWERMATE=n +CONFIG_INPUT_YEALINK=n +CONFIG_INPUT_CM109=n +CONFIG_INPUT_UINPUT=n +CONFIG_SERIO_ALTERA_PS2=n +CONFIG_SERIO_ARC_PS2=n +CONFIG_NOZOMI=n +CONFIG_N_GSM=n +CONFIG_SERIAL_JSM=n +CONFIG_SERIAL_ARC=n +CONFIG_HANGCHECK_TIMER=n +CONFIG_TELCLOCK=n +CONFIG_I2C_AMD756=n +CONFIG_I2C_AMD8111=n +CONFIG_I2C_PIIX4=n +CONFIG_I2C_NFORCE2=n +CONFIG_I2C_SIS96X=n +CONFIG_I2C_VIA=n +CONFIG_I2C_VIAPRO=n +CONFIG_I2C_PCA_PLATFORM=n +CONFIG_I2C_SIMTEC=n +CONFIG_I2C_DIOLAN_U2C=n +CONFIG_I2C_PARPORT_LIGHT=n +CONFIG_PPS_CLIENT_LDISC=n +CONFIG_PPS_CLIENT_GPIO=n +CONFIG_PTP_1588_CLOCK_PCH=n +CONFIG_CHARGER_SMB347=n +CONFIG_SENSORS_ABITUGURU=n +CONFIG_SENSORS_ABITUGURU3=n +CONFIG_SENSORS_AD7414=n +CONFIG_SENSORS_AD7418=n +CONFIG_SENSORS_ADM1021=n +CONFIG_SENSORS_ADM1025=n +CONFIG_SENSORS_ADM1026=n +CONFIG_SENSORS_ADM1029=n +CONFIG_SENSORS_ADM1031=n +CONFIG_SENSORS_ADM9240=n +CONFIG_SENSORS_ADT7410=n +CONFIG_SENSORS_ADT7411=n +CONFIG_SENSORS_ADT7462=n +CONFIG_SENSORS_ADT7470=n +CONFIG_SENSORS_ADT7475=n +CONFIG_SENSORS_ASC7621=n +CONFIG_SENSORS_K8TEMP=n +CONFIG_SENSORS_K10TEMP=n +CONFIG_SENSORS_FAM15H_POWER=n +CONFIG_SENSORS_ASB100=n +CONFIG_SENSORS_ATXP1=n +CONFIG_SENSORS_DS620=n +CONFIG_SENSORS_DS1621=n +CONFIG_SENSORS_I5K_AMB=n +CONFIG_SENSORS_F71805F=n +CONFIG_SENSORS_F71882FG=n +CONFIG_SENSORS_F75375S=n +CONFIG_SENSORS_FSCHMD=n +CONFIG_SENSORS_G760A=n +CONFIG_SENSORS_GL518SM=n +CONFIG_SENSORS_GL520SM=n +CONFIG_SENSORS_IBMAEM=n +CONFIG_SENSORS_IBMPEX=n +CONFIG_SENSORS_IT87=n +CONFIG_SENSORS_LINEAGE=n +CONFIG_SENSORS_LM63=n +CONFIG_SENSORS_LM73=n +CONFIG_SENSORS_LM75=n +CONFIG_SENSORS_LM77=n +CONFIG_SENSORS_LM78=n +CONFIG_SENSORS_LM80=n +CONFIG_SENSORS_LM83=n +CONFIG_SENSORS_LM85=n +CONFIG_SENSORS_LM87=n +CONFIG_SENSORS_LM90=n +CONFIG_SENSORS_LM92=n +CONFIG_SENSORS_LM93=n +CONFIG_SENSORS_LTC4151=n +CONFIG_SENSORS_LTC4215=n +CONFIG_SENSORS_LTC4245=n +CONFIG_SENSORS_LTC4261=n +CONFIG_SENSORS_LM95234=n +CONFIG_SENSORS_LM95241=n +CONFIG_SENSORS_LM95245=n +CONFIG_SENSORS_MAX16065=n +CONFIG_SENSORS_MAX1619=n +CONFIG_SENSORS_MAX1668=n +CONFIG_SENSORS_MAX197=n +CONFIG_SENSORS_MAX6639=n +CONFIG_SENSORS_MAX6642=n +CONFIG_SENSORS_MAX6650=n +CONFIG_SENSORS_MAX6697=n +CONFIG_SENSORS_MCP3021=n +CONFIG_SENSORS_NCT6775=n +CONFIG_SENSORS_NTC_THERMISTOR=n +CONFIG_SENSORS_PC87360=n +CONFIG_SENSORS_PC87427=n +CONFIG_SENSORS_PCF8591=n +CONFIG_SENSORS_PMBUS=n +CONFIG_SENSORS_ADM1275=n +CONFIG_SENSORS_LM25066=n +CONFIG_SENSORS_LTC2978=n +CONFIG_SENSORS_MAX16064=n +CONFIG_SENSORS_MAX34440=n +CONFIG_SENSORS_MAX8688=n +CONFIG_SENSORS_UCD9000=n +CONFIG_SENSORS_UCD9200=n +CONFIG_SENSORS_ZL6100=n +CONFIG_SENSORS_SHT21=n +CONFIG_SENSORS_SIS5595=n +CONFIG_SENSORS_DME1737=n +CONFIG_SENSORS_EMC1403=n +CONFIG_SENSORS_EMC6W201=n +CONFIG_SENSORS_SMSC47M1=n +CONFIG_SENSORS_SMSC47M192=n +CONFIG_SENSORS_SMSC47B397=n +CONFIG_SENSORS_SCH56XX_COMMON=n +CONFIG_SENSORS_SCH5627=n +CONFIG_SENSORS_SCH5636=n +CONFIG_SENSORS_ADS1015=n +CONFIG_SENSORS_ADS7828=n +CONFIG_SENSORS_AMC6821=n +CONFIG_SENSORS_INA209=n +CONFIG_SENSORS_INA2XX=n +CONFIG_SENSORS_THMC50=n +CONFIG_SENSORS_TMP102=n +CONFIG_SENSORS_TMP401=n +CONFIG_SENSORS_TMP421=n +CONFIG_SENSORS_VIA_CPUTEMP=n +CONFIG_SENSORS_VIA686A=n +CONFIG_SENSORS_VT1211=n +CONFIG_SENSORS_VT8231=n +CONFIG_SENSORS_W83781D=n +CONFIG_SENSORS_W83791D=n +CONFIG_SENSORS_W83792D=n +CONFIG_SENSORS_W83793=n +CONFIG_SENSORS_W83795=n +CONFIG_SENSORS_W83L785TS=n +CONFIG_SENSORS_W83L786NG=n +CONFIG_SENSORS_W83627HF=n +CONFIG_SENSORS_W83627EHF=n +CONFIG_SENSORS_APPLESMC=n +CONFIG_SENSORS_ATK0110=n +CONFIG_ALIM1535_WDT=n +CONFIG_ALIM7101_WDT=n +CONFIG_F71808E_WDT=n +CONFIG_SP5100_TCO=n +CONFIG_SBC_FITPC2_WATCHDOG=n +CONFIG_IB700_WDT=n +CONFIG_IBMASR=n +CONFIG_IT8712F_WDT=n +CONFIG_IT87_WDT=n +CONFIG_NV_TCO=n +CONFIG_SMSC_SCH311X_WDT=n +CONFIG_VIA_WDT=n +CONFIG_W83627HF_WDT=n +CONFIG_W83697HF_WDT=n +CONFIG_W83697UG_WDT=n +CONFIG_W83877F_WDT=n +CONFIG_W83977F_WDT=n +CONFIG_MACHZ_WDT=n +CONFIG_PCIPCWATCHDOG=n +CONFIG_WDTPCI=n +CONFIG_USBPCWATCHDOG=n +CONFIG_MFD_VIPERBOARD=n +CONFIG_MFD_SM501=n +CONFIG_MFD_VX855=n +CONFIG_AGP_AMD64=n +CONFIG_AGP_SIS=n +CONFIG_AGP_VIA=n +CONFIG_VGA_SWITCHEROO=n +CONFIG_DRM_LOAD_EDID_FIRMWARE=n +CONFIG_DRM_I2C_CH7006=n +CONFIG_DRM_I2C_SIL164=n +CONFIG_DRM_I2C_NXP_TDA998X=n +CONFIG_DRM_RADEON=n +CONFIG_DRM_NOUVEAU=n +CONFIG_DRM_VMWGFX=n +CONFIG_DRM_GMA500=n +CONFIG_DRM_GMA600=n +CONFIG_DRM_GMA3600=n +CONFIG_DRM_UDL=n +CONFIG_DRM_AST=n +CONFIG_DRM_MGAG200=n +CONFIG_DRM_CIRRUS_QEMU=n +CONFIG_DRM_QXL=n +CONFIG_DRM_BOCHS=n +CONFIG_FB_SYS_FILLRECT=n +CONFIG_FB_SYS_COPYAREA=n +CONFIG_FB_SYS_IMAGEBLIT=n +CONFIG_FB_SYS_FOPS=n +CONFIG_FB_BACKLIGHT=n +CONFIG_LCD_PLATFORM=n +CONFIG_BACKLIGHT_APPLE=n +CONFIG_BACKLIGHT_LP855X=n +CONFIG_VGACON_SOFT_SCROLLBACK=n +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=n +CONFIG_LOGO=n +CONFIG_HID_BATTERY_STRENGTH=n +CONFIG_HIDRAW=n +CONFIG_UHID=n +CONFIG_HID_ACRUX=n +CONFIG_HID_APPLEIR=n +CONFIG_HID_AUREAL=n +CONFIG_HID_DRAGONRISE=n +CONFIG_HID_ELECOM=n +CONFIG_HID_HOLTEK=n +CONFIG_HID_KEYTOUCH=n +CONFIG_HID_KYE=n +CONFIG_HID_UCLOGIC=n +CONFIG_HID_WALTOP=n +CONFIG_HID_GYRATION=n +CONFIG_HID_ICADE=n +CONFIG_HID_TWINHAN=n +CONFIG_HID_LCPOWER=n +CONFIG_HID_LENOVO_TPKBD=n +CONFIG_HID_MAGICMOUSE=n +CONFIG_HID_NTRIG=n +CONFIG_HID_ORTEK=n +CONFIG_HID_PANTHERLORD=n +CONFIG_HID_PETALYNX=n +CONFIG_HID_PICOLCD=n +CONFIG_HID_PRIMAX=n +CONFIG_HID_PS3REMOTE=n +CONFIG_HID_ROCCAT=n +CONFIG_HID_SAITEK=n +CONFIG_HID_SAMSUNG=n +CONFIG_HID_SONY=n +CONFIG_HID_SPEEDLINK=n +CONFIG_HID_STEELSERIES=n +CONFIG_HID_SUNPLUS=n +CONFIG_HID_RMI=n +CONFIG_HID_GREENASIA=n +CONFIG_HID_SMARTJOYPLUS=n +CONFIG_HID_TIVO=n +CONFIG_HID_TOPSEED=n +CONFIG_HID_THINGM=n +CONFIG_HID_THRUSTMASTER=n +CONFIG_HID_WACOM=n +CONFIG_HID_WIIMOTE=n +CONFIG_HID_ZEROPLUS=n +CONFIG_HID_ZYDACRON=n +CONFIG_HID_PID=n +CONFIG_USB_HIDDEV=n +CONFIG_USB_ANNOUNCE_NEW_DEVICES=n +CONFIG_USB_MON=n +CONFIG_USB_WUSB_CBAF=n +CONFIG_USB_OHCI_HCD=n +CONFIG_USB_ACM=n +CONFIG_USB_PRINTER=n +CONFIG_USB_WDM=n +CONFIG_USB_TMC=n +CONFIG_USB_STORAGE_REALTEK=n +CONFIG_USB_STORAGE_DATAFAB=n +CONFIG_USB_STORAGE_FREECOM=n +CONFIG_USB_STORAGE_ISD200=n +CONFIG_USB_STORAGE_USBAT=n +CONFIG_USB_STORAGE_SDDR09=n +CONFIG_USB_STORAGE_SDDR55=n +CONFIG_USB_STORAGE_JUMPSHOT=n +CONFIG_USB_STORAGE_ALAUDA=n +CONFIG_USB_STORAGE_ONETOUCH=n +CONFIG_USB_STORAGE_KARMA=n +CONFIG_USB_STORAGE_CYPRESS_ATACB=n +CONFIG_USB_STORAGE_ENE_UB6250=n +CONFIG_USB_MDC800=n +CONFIG_USB_MICROTEK=n +CONFIG_USB_SERIAL_AIRCABLE=n +CONFIG_USB_SERIAL_ARK3116=n +CONFIG_USB_SERIAL_BELKIN=n +CONFIG_USB_SERIAL_WHITEHEAT=n +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=n +CONFIG_USB_SERIAL_CYPRESS_M8=n +CONFIG_USB_SERIAL_EMPEG=n +CONFIG_USB_SERIAL_VISOR=n +CONFIG_USB_SERIAL_IPAQ=n +CONFIG_USB_SERIAL_IR=n +CONFIG_USB_SERIAL_EDGEPORT=n +CONFIG_USB_SERIAL_EDGEPORT_TI=n +CONFIG_USB_SERIAL_GARMIN=n +CONFIG_USB_SERIAL_IPW=n +CONFIG_USB_SERIAL_IUU=n +CONFIG_USB_SERIAL_KEYSPAN_PDA=n +CONFIG_USB_SERIAL_KEYSPAN=n +CONFIG_USB_SERIAL_KLSI=n +CONFIG_USB_SERIAL_KOBIL_SCT=n +CONFIG_USB_SERIAL_MCT_U232=n +CONFIG_USB_SERIAL_MOS7720=n +CONFIG_USB_SERIAL_MOS7840=n +CONFIG_USB_SERIAL_NAVMAN=n +CONFIG_USB_SERIAL_OTI6858=n +CONFIG_USB_SERIAL_QCAUX=n +CONFIG_USB_SERIAL_QUALCOMM=n +CONFIG_USB_SERIAL_SPCP8X5=n +CONFIG_USB_SERIAL_SAFE=n +CONFIG_USB_SERIAL_SIERRAWIRELESS=n +CONFIG_USB_SERIAL_SYMBOL=n +CONFIG_USB_SERIAL_TI=n +CONFIG_USB_SERIAL_CYBERJACK=n +CONFIG_USB_SERIAL_XIRCOM=n +CONFIG_USB_SERIAL_OPTION=n +CONFIG_USB_SERIAL_OMNINET=n +CONFIG_USB_SERIAL_OPTICON=n +CONFIG_USB_SERIAL_XSENS_MT=n +CONFIG_USB_SERIAL_SSU100=n +CONFIG_USB_SERIAL_QT2=n +CONFIG_USB_SERIAL_DEBUG=n +CONFIG_USB_EMI62=n +CONFIG_USB_EMI26=n +CONFIG_USB_ADUTUX=n +CONFIG_USB_SEVSEG=n +CONFIG_USB_LEGOTOWER=n +CONFIG_USB_LCD=n +CONFIG_USB_LED=n +CONFIG_USB_IDMOUSE=n +CONFIG_USB_FTDI_ELAN=n +CONFIG_USB_APPLEDISPLAY=n +CONFIG_USB_SISUSBVGA=n +CONFIG_USB_LD=n +CONFIG_USB_IOWARRIOR=n +CONFIG_USB_ISIGHTFW=n +CONFIG_USB_EZUSB_FX2=n +CONFIG_USB_HSIC_USB3503=n +CONFIG_USB_ATM=n +CONFIG_UWB=n +CONFIG_MMC_RICOH_MMC=n +CONFIG_MMC_TIFM_SD=n +CONFIG_MMC_CB710=n +CONFIG_MMC_VIA_SDMMC=n +CONFIG_MMC_VUB300=n +CONFIG_MMC_USHC=n +CONFIG_MEMSTICK=n +CONFIG_LEDS_LM3530=n +CONFIG_LEDS_LP3944=n +CONFIG_LEDS_LP5521=n +CONFIG_LEDS_LP5523=n +CONFIG_LEDS_LP5562=n +CONFIG_LEDS_CLEVO_MAIL=n +CONFIG_LEDS_INTEL_SS4200=n +CONFIG_LEDS_BLINKM=n +CONFIG_LEDS_TRIGGER_TIMER=n +CONFIG_LEDS_TRIGGER_ONESHOT=n +CONFIG_LEDS_TRIGGER_HEARTBEAT=n +CONFIG_LEDS_TRIGGER_BACKLIGHT=n +CONFIG_LEDS_TRIGGER_TRANSIENT=n +CONFIG_LEDS_TRIGGER_CAMERA=n +CONFIG_INFINIBAND=n +CONFIG_EDAC=n +CONFIG_NET_DMA_RH_KABI=n +CONFIG_UIO_CIF=n +CONFIG_UIO_AEC=n +CONFIG_UIO_SERCOS3=n +CONFIG_STAGING=n +CONFIG_ACERHDF=n +CONFIG_ASUS_LAPTOP=n +CONFIG_CHROMEOS_LAPTOP=n +CONFIG_FUJITSU_LAPTOP=n +CONFIG_FUJITSU_TABLET=n +CONFIG_AMILO_RFKILL=n +CONFIG_HP_ACCEL=n +CONFIG_HP_WIRELESS=n +CONFIG_MSI_LAPTOP=n +CONFIG_PANASONIC_LAPTOP=n +CONFIG_COMPAL_LAPTOP=n +CONFIG_SONY_LAPTOP=n +CONFIG_IDEAPAD_LAPTOP=n +CONFIG_THINKPAD_ACPI=n +CONFIG_SENSORS_HDAPS=n +CONFIG_EEEPC_LAPTOP=n +CONFIG_ACPI_WMI=n +CONFIG_TOPSTAR_LAPTOP=n +CONFIG_TOSHIBA_BT_RFKILL=n +CONFIG_ACPI_CMPC=n +CONFIG_SAMSUNG_LAPTOP=n +CONFIG_INTEL_OAKTRAIL=n +CONFIG_SAMSUNG_Q10=n +CONFIG_APPLE_GMUX=n +CONFIG_PVPANIC=n +CONFIG_EDD=n +CONFIG_DELL_RBU=n +CONFIG_DCDBAS=n +CONFIG_JBD_DEBUG=n +CONFIG_FANOTIFY=n +CONFIG_JOLIET=n +CONFIG_UDF_FS=n +CONFIG_CRAMFS=n +CONFIG_SQUASHFS=y +CONFIG_EFIVAR_FS=n +CONFIG_SUNRPC_DEBUG=n +CONFIG_NLS_MAC_ROMAN=n +CONFIG_NLS_MAC_CELTIC=n +CONFIG_NLS_MAC_CENTEURO=n +CONFIG_NLS_MAC_CROATIAN=n +CONFIG_NLS_MAC_CYRILLIC=n +CONFIG_NLS_MAC_GAELIC=n +CONFIG_NLS_MAC_GREEK=n +CONFIG_NLS_MAC_ICELAND=n +CONFIG_NLS_MAC_INUIT=n +CONFIG_NLS_MAC_ROMANIAN=n +CONFIG_NLS_MAC_TURKISH=n +CONFIG_SCHED_TRACER=n +CONFIG_TRACER_SNAPSHOT=n +CONFIG_UPROBE_EVENT=n +CONFIG_PROBE_EVENTS=n +CONFIG_FUNCTION_PROFILER=n +CONFIG_RING_BUFFER_BENCHMARK=n +CONFIG_ATOMIC64_SELFTEST=n +CONFIG_ASYNC_RAID6_TEST=n +CONFIG_KGDB=n +CONFIG_TEST_KSTRTOX=n +CONFIG_STRICT_DEVMEM=n +CONFIG_DEBUG_SET_MODULE_RONX=n +CONFIG_DEBUG_NX_TEST=n +CONFIG_CRYPTO_BLOWFISH_X86_64=n +CONFIG_CRYPTO_CAMELLIA_X86_64=n +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=n +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=n +CONFIG_CRYPTO_CAST5_AVX_X86_64=n +CONFIG_CRYPTO_CAST6_AVX_X86_64=n +CONFIG_CRYPTO_SALSA20=n +CONFIG_CRYPTO_SALSA20_X86_64=n +CONFIG_CRYPTO_SERPENT_SSE2_X86_64=n +CONFIG_CRYPTO_SERPENT_AVX_X86_64=n +CONFIG_CRYPTO_SERPENT_AVX2_X86_64=n +CONFIG_CRYPTO_TWOFISH_X86_64=n +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=n +CONFIG_CRYPTO_TWOFISH_AVX_X86_64=n +CONFIG_CRYPTO_DRBG_MENU=n +CONFIG_CRYPTO_USER_API_HASH=n +CONFIG_CRYPTO_USER_API_SKCIPHER=n +CONFIG_CRYPTO_DEV_PADLOCK=n +CONFIG_BLK_DEV_NBD=m +CONFIG_AIC94XX_DEBUG=n + +# Turn on kernel preemption +CONFIG_PREEMPT=y +CONFIG_RCU_BOOST=n +CONFIG_DEBUG_PREEMPT=n +CONFIG_PROVE_RCU_DELAY=n +CONFIG_RCU_CPU_STALL_VERBOSE=n +CONFIG_PREEMPT_TRACER=n + +# Disable transparent huge pages +CONFIG_TRANSPARENT_HUGEPAGE=n +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=n + +# Disable unused cgroups +CONFIG_CGROUP_HUGETLB=n +CONFIG_CGROUP_PERF=n +CONFIG_BLK_CGROUP=n + +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=n +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y + +CONFIG_GPIO_BT8XX=n + +CONFIG_KERNFS=y +CONFIG_INTEL_RDT_A=y diff --git a/kernel-std/centos/patches/memblock-introduce-memblock_alloc_range.patch b/kernel-std/centos/patches/memblock-introduce-memblock_alloc_range.patch new file mode 100644 index 000000000..d8198de20 --- /dev/null +++ b/kernel-std/centos/patches/memblock-introduce-memblock_alloc_range.patch @@ -0,0 +1,96 @@ +From 25e30e7113f141cf3b9573604806fcbd1233fc4c Mon Sep 17 00:00:00 2001 +Message-Id: <25e30e7113f141cf3b9573604806fcbd1233fc4c.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Tue, 31 May 2016 16:07:55 -0400 +Subject: [PATCH 09/24] memblock: introduce memblock_alloc_range() + +Commit 2bfc2862c4fe38379a2fb2cfba33fad32ccb4ff4 upstream +Backported-by: Nam Ninh + +This introduces memblock_alloc_range() which allocates memblock from the +specified range of physical address. I would like to use this function +to specify the location of CMA. + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + include/linux/memblock.h | 2 ++ + mm/memblock.c | 22 ++++++++++++++++++---- + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index 5a439c9..d6bcbef 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -304,6 +304,8 @@ static inline bool memblock_bottom_up(void) { return false; } + #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) + #define MEMBLOCK_ALLOC_ACCESSIBLE 0 + ++phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align, ++ phys_addr_t start, phys_addr_t end); + phys_addr_t memblock_alloc_base(phys_addr_t size, phys_addr_t align, + phys_addr_t max_addr); + phys_addr_t __memblock_alloc_base(phys_addr_t size, phys_addr_t align, +diff --git a/mm/memblock.c b/mm/memblock.c +index fbc8071..ff910a4 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -1120,9 +1120,9 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size, + } + #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ + +-static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, +- phys_addr_t align, phys_addr_t max_addr, +- int nid, ulong flags) ++static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, ++ phys_addr_t align, phys_addr_t start, ++ phys_addr_t end, int nid, ulong flags) + { + phys_addr_t found; + +@@ -1132,7 +1132,7 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, + /* align @size to avoid excessive fragmentation on reserved array */ + size = round_up(size, align); + +- found = memblock_find_in_range_node(size, align, 0, max_addr, nid, ++ found = memblock_find_in_range_node(size, align, start, end, nid, + flags); + if (found && !memblock_reserve(found, size)) + return found; +@@ -1140,6 +1140,20 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, + return 0; + } + ++phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align, ++ phys_addr_t start, phys_addr_t end) ++{ ++ ulong flags = choose_memblock_flags(); ++ return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE, flags); ++} ++ ++static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, ++ phys_addr_t align, phys_addr_t max_addr, ++ int nid, ulong flags) ++{ ++ return memblock_alloc_range_nid(size, align, 0, max_addr, nid, flags); ++} ++ + phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid) + { + ulong flags = choose_memblock_flags(); +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch b/kernel-std/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch new file mode 100644 index 000000000..742f98886 --- /dev/null +++ b/kernel-std/centos/patches/mqueue-fix-a-use-after-free-in-sys_mq_notify.patch @@ -0,0 +1,51 @@ +From 53908fc2863e375884f3a1f26b9ef5b070982758 Mon Sep 17 00:00:00 2001 +Message-Id: <53908fc2863e375884f3a1f26b9ef5b070982758.1517514213.git.Jim.Somerville@windriver.com> +From: Cong Wang +Date: Sun, 9 Jul 2017 13:19:55 -0700 +Subject: [PATCH 1/1] mqueue: fix a use-after-free in sys_mq_notify() + +The retry logic for netlink_attachskb() inside sys_mq_notify() +is nasty and vulnerable: + +1) The sock refcnt is already released when retry is needed +2) The fd is controllable by user-space because we already + release the file refcnt + +so we when retry but the fd has been just closed by user-space +during this small window, we end up calling netlink_detachskb() +on the error path which releases the sock again, later when +the user-space closes this socket a use-after-free could be +triggered. + +Setting 'sock' to NULL here should be sufficient to fix it. + +Reported-by: GeneBlue +Signed-off-by: Cong Wang +Cc: Andrew Morton +Cc: Manfred Spraul +Cc: stable@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + ipc/mqueue.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/ipc/mqueue.c b/ipc/mqueue.c +index b8d4aed..6f973f3 100644 +--- a/ipc/mqueue.c ++++ b/ipc/mqueue.c +@@ -1244,8 +1244,10 @@ retry: + + timeo = MAX_SCHEDULE_TIMEOUT; + ret = netlink_attachskb(sock, nc, &timeo, NULL); +- if (ret == 1) ++ if (ret == 1) { ++ sock = NULL; + goto retry; ++ } + if (ret) { + sock = NULL; + nc = NULL; +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch b/kernel-std/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch new file mode 100644 index 000000000..3c95ff46c --- /dev/null +++ b/kernel-std/centos/patches/rcu-Don-t-wake-rcuc-X-kthreads-on-NOCB-CPUs.patch @@ -0,0 +1,47 @@ +From dce89d8204b21fa1a93cb0a476750cd292617e79 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: "Paul E. McKenney" +Date: Thu, 15 Dec 2016 15:37:47 -0800 +Subject: [PATCH 16/24] rcu: Don't wake rcuc/X kthreads on NOCB CPUs + +[ upstream 630c7ed9ca0608912fa7c8591d05dfc8742dc9e6 in tip repo ] + +Chris Friesen notice that rcuc/X kthreads were consuming CPU even on +NOCB CPUs. This makes no sense because the only purpose or these +kthreads is to invoke normal (non-offloaded) callbacks, of which there +will never be any on NOCB CPUs. This problem was due to a bug in +cpu_has_callbacks_ready_to_invoke(), which should have been checking +->nxttail[RCU_NEXT_TAIL] for NULL, but which was instead (incorrectly) +checking ->nxttail[RCU_DONE_TAIL]. Because ->nxttail[RCU_DONE_TAIL] is +never NULL, the only effect is to cause the rcuc/X kthread to execute +when it should not do so. + +This commit therefore checks ->nxttail[RCU_NEXT_TAIL], which is NULL +for NOCB CPUs. + +Reported-by: Chris Friesen +Signed-off-by: Paul E. McKenney +Reviewed-by: Josh Triplett +Signed-off-by: Jim Somerville +--- + kernel/rcutree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/rcutree.c b/kernel/rcutree.c +index f46e3e4..ac3dfb7 100644 +--- a/kernel/rcutree.c ++++ b/kernel/rcutree.c +@@ -300,7 +300,7 @@ static int + cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp) + { + return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] && +- rdp->nxttail[RCU_DONE_TAIL] != NULL; ++ rdp->nxttail[RCU_NEXT_TAIL] != NULL; + } + + /* +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/turn-off-write-same-in-smartqpi-driver.patch b/kernel-std/centos/patches/turn-off-write-same-in-smartqpi-driver.patch new file mode 100644 index 000000000..095f4358f --- /dev/null +++ b/kernel-std/centos/patches/turn-off-write-same-in-smartqpi-driver.patch @@ -0,0 +1,26 @@ +From 88dc5da8815c32f80f1791c00fa4a435897b45f1 Mon Sep 17 00:00:00 2001 +Message-Id: <88dc5da8815c32f80f1791c00fa4a435897b45f1.1520358900.git.Jim.Somerville@windriver.com> +From: Jim Somerville +Date: Tue, 6 Mar 2018 12:54:40 -0500 +Subject: [PATCH 1/1] turn off write same in smartqpi driver + +Signed-off-by: Jim Somerville +--- + drivers/scsi/smartpqi/smartpqi_init.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 638af91..a891516 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -5155,6 +5155,7 @@ static struct scsi_host_template pqi_driver_template = { + .slave_configure = pqi_slave_configure, + .sdev_attrs = pqi_sdev_attrs, + .shost_attrs = pqi_shost_attrs, ++ .no_write_same = 1, + }; + + static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch b/kernel-std/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch new file mode 100644 index 000000000..e2dcff60e --- /dev/null +++ b/kernel-std/centos/patches/x86-enable-DMA-CMA-with-swiotlb.patch @@ -0,0 +1,182 @@ +From 623e04e1f1fb18b817e73cdb116b1eea5d145dc4 Mon Sep 17 00:00:00 2001 +Message-Id: <623e04e1f1fb18b817e73cdb116b1eea5d145dc4.1507237259.git.Jim.Somerville@windriver.com> +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Wed, 4 Jun 2014 16:06:50 -0700 +Subject: [PATCH 11/24] x86: enable DMA CMA with swiotlb + +commit 9c5a3621427da68afe6a078cadf807d2c8cc1d12 upstream. +Ported-by: Nam Ninh + +The DMA Contiguous Memory Allocator support on x86 is disabled when +swiotlb config option is enabled. So DMA CMA is always disabled on +x86_64 because swiotlb is always enabled. This attempts to support for +DMA CMA with enabling swiotlb config option. + +The contiguous memory allocator on x86 is integrated in the function +dma_generic_alloc_coherent() which is .alloc callback in nommu_dma_ops +for dma_alloc_coherent(). + +x86_swiotlb_alloc_coherent() which is .alloc callback in swiotlb_dma_ops +tries to allocate with dma_generic_alloc_coherent() firstly and then +swiotlb_alloc_coherent() is called as a fallback. + +The main part of supporting DMA CMA with swiotlb is that changing +x86_swiotlb_free_coherent() which is .free callback in swiotlb_dma_ops +for dma_free_coherent() so that it can distinguish memory allocated by +dma_generic_alloc_coherent() from one allocated by +swiotlb_alloc_coherent() and release it with dma_generic_free_coherent() +which can handle contiguous memory. This change requires making +is_swiotlb_buffer() global function. + +This also needs to change .free callback in the dma_map_ops for amd_gart +and sta2x11, because these dma_ops are also using +dma_generic_alloc_coherent(). + +Signed-off-by: Akinobu Mita +Acked-by: Marek Szyprowski +Acked-by: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Jim Somerville +--- + arch/x86/Kconfig | 2 +- + arch/x86/include/asm/swiotlb.h | 7 +++++++ + arch/x86/kernel/amd_gart_64.c | 2 +- + arch/x86/kernel/pci-swiotlb.c | 9 ++++++--- + arch/x86/pci/sta2x11-fixup.c | 6 ++---- + include/linux/swiotlb.h | 2 ++ + lib/swiotlb.c | 2 +- + 7 files changed, 20 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index c83b7a9..f943f01 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -43,7 +43,7 @@ config X86 + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARCH_WANT_FRAME_POINTERS + select HAVE_DMA_ATTRS +- select HAVE_DMA_CONTIGUOUS if !SWIOTLB ++ select HAVE_DMA_CONTIGUOUS + select HAVE_KRETPROBES + select HAVE_OPTPROBES + select HAVE_KPROBES_ON_FTRACE +diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h +index 977f176..ab05d73 100644 +--- a/arch/x86/include/asm/swiotlb.h ++++ b/arch/x86/include/asm/swiotlb.h +@@ -29,4 +29,11 @@ static inline void pci_swiotlb_late_init(void) + + static inline void dma_mark_clean(void *addr, size_t size) {} + ++extern void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, ++ dma_addr_t *dma_handle, gfp_t flags, ++ struct dma_attrs *attrs); ++extern void x86_swiotlb_free_coherent(struct device *dev, size_t size, ++ void *vaddr, dma_addr_t dma_addr, ++ struct dma_attrs *attrs); ++ + #endif /* _ASM_X86_SWIOTLB_H */ +diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c +index b574b29..8e3842f 100644 +--- a/arch/x86/kernel/amd_gart_64.c ++++ b/arch/x86/kernel/amd_gart_64.c +@@ -512,7 +512,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_addr, struct dma_attrs *attrs) + { + gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); +- free_pages((unsigned long)vaddr, get_order(size)); ++ dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs); + } + + static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr) +diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c +index 48f9755..23a71b6 100644 +--- a/arch/x86/kernel/pci-swiotlb.c ++++ b/arch/x86/kernel/pci-swiotlb.c +@@ -14,7 +14,7 @@ + #include + int swiotlb __read_mostly; + +-static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, ++void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) + { +@@ -28,11 +28,14 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, + return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); + } + +-static void x86_swiotlb_free_coherent(struct device *dev, size_t size, ++void x86_swiotlb_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_addr, + struct dma_attrs *attrs) + { +- swiotlb_free_coherent(dev, size, vaddr, dma_addr); ++ if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr))) ++ swiotlb_free_coherent(dev, size, vaddr, dma_addr); ++ else ++ dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs); + } + + static struct dma_map_ops swiotlb_dma_ops = { +diff --git a/arch/x86/pci/sta2x11-fixup.c b/arch/x86/pci/sta2x11-fixup.c +index 9d8a509..5ceda85 100644 +--- a/arch/x86/pci/sta2x11-fixup.c ++++ b/arch/x86/pci/sta2x11-fixup.c +@@ -173,9 +173,7 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev, + { + void *vaddr; + +- vaddr = dma_generic_alloc_coherent(dev, size, dma_handle, flags, attrs); +- if (!vaddr) +- vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, flags); ++ vaddr = x86_swiotlb_alloc_coherent(dev, size, dma_handle, flags, attrs); + *dma_handle = p2a(*dma_handle, to_pci_dev(dev)); + return vaddr; + } +@@ -183,7 +181,7 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev, + /* We have our own dma_ops: the same as swiotlb but from alloc (above) */ + static struct dma_map_ops sta2x11_dma_ops = { + .alloc = sta2x11_swiotlb_alloc_coherent, +- .free = swiotlb_free_coherent, ++ .free = x86_swiotlb_free_coherent, + .map_page = swiotlb_map_page, + .unmap_page = swiotlb_unmap_page, + .map_sg = swiotlb_map_sg_attrs, +diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h +index a5ffd32..e7a018e 100644 +--- a/include/linux/swiotlb.h ++++ b/include/linux/swiotlb.h +@@ -116,4 +116,6 @@ static inline void swiotlb_free(void) { } + #endif + + extern void swiotlb_print_info(void); ++extern int is_swiotlb_buffer(phys_addr_t paddr); ++ + #endif /* __LINUX_SWIOTLB_H */ +diff --git a/lib/swiotlb.c b/lib/swiotlb.c +index d23762e..eba74ec 100644 +--- a/lib/swiotlb.c ++++ b/lib/swiotlb.c +@@ -366,7 +366,7 @@ void __init swiotlb_free(void) + io_tlb_nslabs = 0; + } + +-static int is_swiotlb_buffer(phys_addr_t paddr) ++int is_swiotlb_buffer(phys_addr_t paddr) + { + return paddr >= io_tlb_start && paddr < io_tlb_end; + } +-- +1.8.3.1 + diff --git a/kernel-std/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch b/kernel-std/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch new file mode 100644 index 000000000..5f3e8fa5d --- /dev/null +++ b/kernel-std/centos/patches/x86-make-dma_alloc_coherent-return-zeroed-memory-if-.patch @@ -0,0 +1,87 @@ +From f29d73f4ff3ecc40356f39304da448e3495a10d8 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +References: <2a9fb6a58e40e8604d97223603111e869bb774b1.1507237258.git.Jim.Somerville@windriver.com> +From: Akinobu Mita +Date: Wed, 4 Jun 2014 16:06:48 -0700 +Subject: [PATCH 14/24] x86: make dma_alloc_coherent() return zeroed memory if + CMA is enabled + +This patchset enhances the DMA Contiguous Memory Allocator on x86. + +Currently the DMA CMA is only supported with pci-nommu dma_map_ops and +furthermore it can't be enabled on x86_64. But I would like to allocate +big contiguous memory with dma_alloc_coherent() and tell it to the device +that requires it, regardless of which dma mapping implementation is +actually used in the system. + +So this makes it work with swiotlb and intel-iommu dma_map_ops, too. And +this also extends "cma=" kernel parameter to specify placement constraint +by the physical address range of memory allocations. For example, CMA +allocates memory below 4GB by "cma=64M@0-4G", it is required for the +devices only supporting 32-bit addressing on 64-bit systems without iommu. + +This patch (of 5): + +Calling dma_alloc_coherent() with __GFP_ZERO must return zeroed memory. + +But when the contiguous memory allocator (CMA) is enabled on x86 and the +memory region is allocated by dma_alloc_from_contiguous(), it doesn't +return zeroed memory. Because dma_generic_alloc_coherent() forgot to fill +the memory region with zero if it was allocated by +dma_alloc_from_contiguous() + +Most implementations of dma_alloc_coherent() return zeroed memory +regardless of whether __GFP_ZERO is specified. So this fixes it by +unconditionally zeroing the allocated memory region. + +Alternatively, we could fix dma_alloc_from_contiguous() to return zeroed +out memory and remove memset() from all caller of it. But we can't simply +remove the memset on arm because __dma_clear_buffer() is used there for +ensuring cache flushing and it is used in many places. Of course we can +do redundant memset in dma_alloc_from_contiguous(), but I think this patch +is less impact for fixing this problem. + +Signed-off-by: Akinobu Mita +Cc: Marek Szyprowski +Cc: Konrad Rzeszutek Wilk +Cc: David Woodhouse +Cc: Don Dutile +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Andi Kleen +Cc: Yinghai Lu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +(cherry picked from commit d92ef66c4f8fdf7a24736b1ab6c48d32de9bfc07) +Signed-off-by: Jim Somerville +--- + arch/x86/kernel/pci-dma.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c +index 872079a..9d92ea8 100644 +--- a/arch/x86/kernel/pci-dma.c ++++ b/arch/x86/kernel/pci-dma.c +@@ -97,7 +97,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, + + dma_mask = dma_alloc_coherent_mask(dev, flag); + +- flag |= __GFP_ZERO; ++ flag &= ~__GFP_ZERO; + again: + page = NULL; + if (!(flag & GFP_ATOMIC)) +@@ -118,7 +118,7 @@ again: + + return NULL; + } +- ++ memset(page_address(page), 0, size); + *dma_addr = addr; + return page_address(page); + } +-- +1.8.3.1 + diff --git a/kernel-std/centos/srpm_path b/kernel-std/centos/srpm_path new file mode 100644 index 000000000..3fa0dfff2 --- /dev/null +++ b/kernel-std/centos/srpm_path @@ -0,0 +1,2 @@ +mirror:Source/kernel-3.10.0-693.2.2.el7.src.rpm + diff --git a/kernel-std/files/ima_signing_key.pub b/kernel-std/files/ima_signing_key.pub new file mode 100644 index 0000000000000000000000000000000000000000..dfffc0c4bb5a994c2ff154f8827dd3ecaf9478bb GIT binary patch literal 917 zcmXqLVxDNw#8kO}nTe5!iId@E8p~YaZr^tXylk9WZ60mkc^MhGSs4uC4Y>_C*_cCF z*o2v!9SsEx_&^*E9(Mn{lEk9Sd_#Vq4xk7-51W5UNn&}Tp}c`CNPvq+EIczWMIk7& zEVW1>xU#q;HMdy7GcVbY$AAl@fSZRoBs17RPMp`!!ob+j$k5ct(%3vooYw@%H86p4 zY43n0MkQoVGqN%;H!<=v7&I|*F*PwVGHm?#MVEQfyCouLEwoD3ueg{qU+~0*>kM`I zr}nE$KFer}GZf_=h$hnaWhcqFg)n{mU>w)xhX9RioTcg^4YuHaz!>bN_P zZ8E$M=>1|-n^AndGv{};N@exZjNOqrhb6o|Jm2?wT7&c|(eEy8+>3HcAxx<peSia$?zLS7phm!nLP^_de6kF6^&ev8Vlt?Yfu+ z`=w{SU3NTWcDA;{t;LhoWp51wc_d~-=?|bZ@nV1~r zWi=PHTvZ=)Pocj;$^Kg1(UZM`2d*zIdRO&g&7pG_C+LNHpOML!;92f(9>>sWX`dBV z^X#|&UBy~=(TD +Date: Fri, 5 Jan 2018 21:05:50 -0500 +Subject: [PATCH 1/3] upversion with release num + +Signed-off-by: eric zhang +--- + SPECS/libibverbs.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/libibverbs.spec b/SPECS/libibverbs.spec +index e55433c..74cb4d2 100644 +--- a/SPECS/libibverbs.spec ++++ b/SPECS/libibverbs.spec +@@ -12,7 +12,7 @@ + + Name: libibverbs + Version: 41mlnx1 +-Release: OFED.4.2.1.0.6.42120 ++Release: OFED.4.2.1.0.6.42120%{?_tis_dist}.%{tis_patch_ver} + Summary: A library for direct userspace use of RDMA (InfiniBand/iWARP) hardware + + Group: System Environment/Libraries +-- +1.8.3.1 + diff --git a/mellanox/libibverbs/centos/meta_patches/PATCH_ORDER b/mellanox/libibverbs/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..a46a12472 --- /dev/null +++ b/mellanox/libibverbs/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,3 @@ +add-build-dependency.patch +0001-Update-package-versioning-for-TIS-format.patch +fix-build-failures-due-to-unwanted-sgid.patch diff --git a/mellanox/libibverbs/centos/meta_patches/add-build-dependency.patch b/mellanox/libibverbs/centos/meta_patches/add-build-dependency.patch new file mode 100644 index 000000000..a86bdbec5 --- /dev/null +++ b/mellanox/libibverbs/centos/meta_patches/add-build-dependency.patch @@ -0,0 +1,25 @@ +From 0b4a6feba98f0e0bfc3db007463cd43a43797d45 Mon Sep 17 00:00:00 2001 +From: Dahir Osman +Date: Tue, 14 Jun 2016 14:55:39 -0400 +Subject: [PATCH] Add build dependency + +To fix package complaining that libnl is not available +--- + SPECS/libibverbs.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/libibverbs.spec b/SPECS/libibverbs.spec +index 4fc96d1..864c31c 100644 +--- a/SPECS/libibverbs.spec ++++ b/SPECS/libibverbs.spec +@@ -22,6 +22,7 @@ Source: http://openfabrics.org/downloads/verbs/libibverbs-%{version}.tar.gz + BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + Requires(post): /sbin/ldconfig + Requires(postun): /sbin/ldconfig ++BuildRequires: libnl-devel + %if %{_with_valgrind} + BuildRequires: valgrind-devel + %endif +-- +1.8.3.1 + diff --git a/mellanox/libibverbs/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch b/mellanox/libibverbs/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch new file mode 100644 index 000000000..2f3106002 --- /dev/null +++ b/mellanox/libibverbs/centos/meta_patches/fix-build-failures-due-to-unwanted-sgid.patch @@ -0,0 +1,24 @@ +From e78c78816e4e07f7c1ba8bd415195efb0cd27563 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Fri, 18 Nov 2016 13:53:47 -0500 +Subject: [PATCH 1/1] libibverbs: fix build failures due to unwanted sgid bit + +--- + SPECS/libibverbs.spec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/SPECS/libibverbs.spec b/SPECS/libibverbs.spec +index b8913c6..1e7b1eb 100644 +--- a/SPECS/libibverbs.spec ++++ b/SPECS/libibverbs.spec +@@ -106,6 +106,7 @@ rm -rf $RPM_BUILD_ROOT + %if %{_with_valgrind} + %{_libdir}/mlnx_ofed/valgrind/lib*.so + %endif ++%dir %attr(0755,root,root) %{_includedir}/infiniband + %{_includedir}/* + %{_mandir}/man3/* + %{_mandir}/man7/* +-- +1.8.3.1 + diff --git a/mellanox/libibverbs/centos/srpm_path b/mellanox/libibverbs/centos/srpm_path new file mode 100644 index 000000000..77244330c --- /dev/null +++ b/mellanox/libibverbs/centos/srpm_path @@ -0,0 +1 @@ +repo:addons/wr-avs/layers/avs/downloads/libibverbs-41mlnx1-OFED.4.2.1.0.6.42120.src.rpm diff --git a/mellanox/libmlx4/centos/build_srpm.data b/mellanox/libmlx4/centos/build_srpm.data new file mode 100644 index 000000000..d3f64f336 --- /dev/null +++ b/mellanox/libmlx4/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=3 diff --git a/mellanox/libmlx4/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/mellanox/libmlx4/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..a75e74061 --- /dev/null +++ b/mellanox/libmlx4/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 3d135a9e55dd497ab6d19f67078a85e0ef183fd7 Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Mon, 26 Sep 2016 17:14:46 -0400 +Subject: [PATCH 1/1] Update package versioning for TIS format + +--- + SPECS/libmlx4.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/libmlx4.spec b/SPECS/libmlx4.spec +index fc5101d..c1eb78d 100644 +--- a/SPECS/libmlx4.spec ++++ b/SPECS/libmlx4.spec +@@ -9,7 +9,7 @@ + + Name: libmlx4 + Version: 41mlnx1 +-Release: OFED.4.1.0.1.0.42120 ++Release: OFED.4.1.0.1.0.42120%{?_tis_dist}.%{tis_patch_ver} + Summary: Mellanox ConnectX InfiniBand HCA Userspace Driver + + Group: System Environment/Libraries +-- +1.8.3.1 + diff --git a/mellanox/libmlx4/centos/meta_patches/PATCH_ORDER b/mellanox/libmlx4/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..91f9a80ea --- /dev/null +++ b/mellanox/libmlx4/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Update-package-versioning-for-TIS-format.patch diff --git a/mellanox/libmlx4/centos/srpm_path b/mellanox/libmlx4/centos/srpm_path new file mode 100644 index 000000000..165206729 --- /dev/null +++ b/mellanox/libmlx4/centos/srpm_path @@ -0,0 +1 @@ +repo:addons/wr-avs/layers/avs/downloads/libmlx4-41mlnx1-OFED.4.1.0.1.0.42120.src.rpm diff --git a/mellanox/libmlx5/centos/build_srpm.data b/mellanox/libmlx5/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/mellanox/libmlx5/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/mellanox/libmlx5/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/mellanox/libmlx5/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..350a74e21 --- /dev/null +++ b/mellanox/libmlx5/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,26 @@ +From ce598a7645d2b75b9d9485a2810917f8e3e188aa Mon Sep 17 00:00:00 2001 +From: eric zhang +Date: Fri, 5 Jan 2018 22:24:21 -0500 +Subject: [PATCH 1/1] driver update + +Signed-off-by: eric zhang +--- + SPECS/libmlx5.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/libmlx5.spec b/SPECS/libmlx5.spec +index 3d27272..03a727d 100644 +--- a/SPECS/libmlx5.spec ++++ b/SPECS/libmlx5.spec +@@ -9,7 +9,7 @@ + + Name: libmlx5 + Version: 41mlnx1 +-Release: OFED.4.2.1.2.0.42120 ++Release: OFED.4.2.1.2.0.42120%{?_tis_dist}.%{tis_patch_ver} + Summary: Mellanox ConnectX-IB InfiniBand HCA Userspace Driver + + Group: System Environment/Libraries +-- +1.8.3.1 + diff --git a/mellanox/libmlx5/centos/meta_patches/PATCH_ORDER b/mellanox/libmlx5/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..91f9a80ea --- /dev/null +++ b/mellanox/libmlx5/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Update-package-versioning-for-TIS-format.patch diff --git a/mellanox/libmlx5/centos/srpm_path b/mellanox/libmlx5/centos/srpm_path new file mode 100644 index 000000000..7cb379ec3 --- /dev/null +++ b/mellanox/libmlx5/centos/srpm_path @@ -0,0 +1 @@ +repo:addons/wr-avs/layers/avs/downloads/libmlx5-41mlnx1-OFED.4.2.1.2.0.42120.src.rpm diff --git a/mellanox/mlnx-ofa_kernel/centos/build_srpm.data b/mellanox/mlnx-ofa_kernel/centos/build_srpm.data new file mode 100644 index 000000000..b2fc668ed --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/build_srpm.data @@ -0,0 +1,3 @@ +COPY_LIST="$PKG_BASE/files/modules-load.conf" +TIS_PATCH_VER=1 +BUILD_IS_SLOW=3 diff --git a/mellanox/mlnx-ofa_kernel/centos/meta_patches/0001-Support-TiS-system.patch b/mellanox/mlnx-ofa_kernel/centos/meta_patches/0001-Support-TiS-system.patch new file mode 100644 index 000000000..9cb97139b --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/meta_patches/0001-Support-TiS-system.patch @@ -0,0 +1,195 @@ +From 17d30a1fc606fce8d5636f6b418ef498944fdf9d Mon Sep 17 00:00:00 2001 +From: eric zhang +Date: Wed, 14 Mar 2018 15:52:15 -0400 +Subject: [PATCH 1/1] Support TiS system + +This patch added the following to support TiS system: +1. Support package versioning for TiS format +2. Add rt support +3. Compile fix in dcbnl.h +4. Fix compile for some ks stuff +5. Fix compile neuter some stats output +6. Load all kernel modules +7. Sign kernel module + +Signed-off-by: Allain Legacy +Signed-off-by: Jim Somerville +Signed-off-by: Kam Nasim +Signed-off-by: eric zhang +--- + SPECS/mlnx-ofa_kernel.spec | 49 +++++++++++++++++++++++++++++++--------------- + 1 file changed, 33 insertions(+), 16 deletions(-) + +diff --git a/SPECS/mlnx-ofa_kernel.spec b/SPECS/mlnx-ofa_kernel.spec +index 111cf4b..d094158 100644 +--- a/SPECS/mlnx-ofa_kernel.spec ++++ b/SPECS/mlnx-ofa_kernel.spec +@@ -27,8 +27,14 @@ + # + + # KMP is disabled by default +-%{!?KMP: %global KMP 0} ++%if "%{_tis_build_type}" == "rt" ++%define bt_ext -rt ++%else ++%undefine bt_ext ++%endif + ++%{!?KMP: %global KMP 0} ++BuildRequires: kernel%{?bt_ext}-devel, openssl + %global WITH_SYSTEMD %(if ( test -d "%{_unitdir}" > /dev/null); then echo -n '1'; else echo -n '0'; fi) + + %{!?configure_options: %global configure_options --with-core-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod --with-mlx4-mod --with-mlx4_en-mod --with-mlx5-mod --with-mlxfw-mod --with-ipoib-mod} +@@ -41,12 +47,11 @@ + %global BLUENIX %(if (grep -qiE "Bluenix" /etc/issue /etc/*release* 2>/dev/null); then echo -n '1'; else echo -n '0'; fi) + %global XENSERVER65 %(if (grep -qiE "XenServer.*6\.5" /etc/issue /etc/*release* 2>/dev/null); then echo -n '1'; else echo -n '0'; fi) + +-%{!?KVERSION: %global KVERSION %(uname -r)} ++%{!?KVERSION: %global KVERSION %(rpm -q kernel%{?bt_ext}-devel | sort --version-sort | tail -1 | sed 's/kernel%{?bt_ext}-devel-//')} + %global kernel_version %{KVERSION} + %global krelver %(echo -n %{KVERSION} | sed -e 's/-/_/g') + # take path to kernel sources if provided, otherwise look in default location (for non KMP rpms). +-%{!?K_SRC: %global K_SRC /lib/modules/%{KVERSION}/build} +- ++%{!?K_SRC: %global K_SRC /usr/src/kernels/%{KVERSION}} + # Select packages to build + + # Kernel module packages to be included into kernel-ib +@@ -62,7 +67,9 @@ + + %{!?KERNEL_SOURCES: %global KERNEL_SOURCES /lib/modules/%{KVERSION}/source} + +-%{!?_name: %global _name mlnx-ofa_kernel} ++ ++%define _basename mlnx-ofa_kernel ++%define _name %{_basename}%{?bt_ext} + %{!?_version: %global _version 4.3} + %{!?_release: %global _release OFED.4.3.1.0.1.1.g8509e41} + %global _kmp_rel %{_release}%{?_kmp_build_num}%{?_dist} +@@ -74,11 +81,16 @@ + Summary: Infiniband HCA Driver + Name: %{_name} + Version: %{_version} +-Release: %{_release}%{?_dist} ++Release: %{_release}%{?_tis_dist}.%{tis_patch_ver} + License: GPLv2 + Url: http://www.mellanox.com/ + Group: System Environment/Base +-Source: %{_name}-%{_version}.tgz ++Source: %{_basename}-%{_version}.tgz ++Source100: modules-load.conf ++Patch01: 0001-neuter-HAVE_IEEE_GETQCN.patch ++Patch02: 0001-neuter-a-bunch-of-ks-stuff.patch ++Patch03: 0001-neuter-some-stats-output.patch ++ + BuildRoot: %{?build_root:%{build_root}}%{!?build_root:/var/tmp/OFED} + Vendor: Mellanox Technologies + Obsoletes: kernel-ib +@@ -133,7 +145,6 @@ EOF) + %global kernel_release() %{KVERSION} + %global flavors_to_build default + %package -n %{non_kmp_pname} +-Requires: %{utils_pname} + Requires: coreutils + Requires: pciutils + Requires: grep +@@ -160,7 +171,7 @@ Obsoletes: mlnx-en-doc + Obsoletes: mlnx-en-debuginfo + Obsoletes: mlnx-en-sources + Version: %{_version} +-Release: %{_release}.kver.%{krelver} ++Release: %{_release}%{?_tis_dist}.%{tis_patch_ver} + Summary: Infiniband Driver and ULPs kernel modules + Group: System Environment/Libraries + %description -n %{non_kmp_pname} +@@ -172,7 +183,7 @@ The driver sources are located at: http://www.mellanox.com/downloads/ofed/mlnx-o + %package -n %{devel_pname} + Version: %{_version} + # build KMP rpms? +-Release: %{_release}%{?_dist} ++Release: %{_release}%{?_dist}%{?_tis_dist}.%{tis_patch_ver} + Obsoletes: kernel-ib-devel + Obsoletes: compat-rdma-devel + Obsoletes: kernel-ib +@@ -209,13 +220,12 @@ The driver sources are located at: http://www.mellanox.com/downloads/ofed/mlnx-o + else \ + echo -n '0'; fi) + +-%if "%{WITH_MOD_SIGN}" == "1" + # call module sign script + %global __modsign_install_post \ + %{_builddir}/$NAME-$VERSION/source/ofed_scripts/tools/sign-modules %{buildroot}/lib/modules/ %{kernel_source default} || exit 1 \ + %{nil} + +-%global __debug_package 1 ++%define debug_package %{nil} + %global buildsubdir %{_name}-%{version} + # Disgusting hack alert! We need to ensure we sign modules *after* all + # invocations of strip occur, which is in __debug_install_post if +@@ -228,7 +238,6 @@ The driver sources are located at: http://www.mellanox.com/downloads/ofed/mlnx-o + %{__modsign_install_post} \ + %{nil} + +-%endif # end of setup module sign scripts + # + %if "%{_vendor}" == "suse" + %debug_package +@@ -259,12 +268,16 @@ The driver sources are located at: http://www.mellanox.com/downloads/ofed/mlnx-o + %{!?install_mod_dir: %global install_mod_dir updates} + + %prep +-%setup -n %{_name}-%{_version} ++%setup -n %{_basename}-%{_version} + set -- * + mkdir source + mv "$@" source/ + mkdir obj + ++%patch01 -p1 ++%patch02 -p1 ++%patch03 -p1 ++ + %build + export EXTRA_CFLAGS='-DVERSION=\"%version\"' + export INSTALL_MOD_DIR=%{install_mod_dir} +@@ -279,7 +292,6 @@ for flavor in %flavors_to_build; do + find compat -type f -exec touch -t 200012201010 '{}' \; || true + ./configure --build-dummy-mods --prefix=%{_prefix} --kernel-version $KVERSION --kernel-sources $KSRC --modules-dir $LIB_MOD_DIR $CONF_OPTIONS %{?_smp_mflags} + make %{?_smp_mflags} kernel +- make build_py_scripts + cd - + done + +@@ -288,9 +300,11 @@ touch ofed-files + export RECORD_PY_FILES=1 + export INSTALL_MOD_PATH=%{buildroot} + export INSTALL_MOD_DIR=%{install_mod_dir} +-export NAME=%{name} ++export NAME=%{_basename} + export VERSION=%{version} + export PREFIX=%{_prefix} ++export MODULE_SIGN_PRIV_KEY=/usr/src/kernels/%{KVERSION}/signing_key.priv ++export MODULE_SIGN_PUB_KEY=/usr/src/kernels/%{KVERSION}/signing_key.x509 + for flavor in %flavors_to_build; do + export KSRC=%{kernel_source $flavor} + export KVERSION=%{kernel_release $KSRC} +@@ -340,6 +354,8 @@ echo "override ${mod_name} * weak-updates/%{_name}${mod_path}" >> %{buildroot}%{ + echo "override ${mod_name} * extra/%{_name}${mod_path}" >> %{buildroot}%{_sysconfdir}/depmod.d/zz01-%{_name}-${mod_name}.conf + done + %endif ++%{__install} -d %{buildroot}%{_sysconfdir}/modules-load.d ++%{__install} -m 644 %{SOURCE100} %{buildroot}%{_sysconfdir}/modules-load.d/mlnx.conf + %endif + + # copy sources +@@ -677,6 +693,7 @@ fi + %config(noreplace) %{_sysconfdir}/depmod.d/zz01-%{_name}-*.conf + %endif + %endif ++%{_sysconfdir}/modules-load.d/mlnx.conf + %endif + + %files -n %{devel_pname} +-- +1.8.3.1 + diff --git a/mellanox/mlnx-ofa_kernel/centos/meta_patches/PATCH_ORDER b/mellanox/mlnx-ofa_kernel/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..99ee2d189 --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Support-TiS-system.patch diff --git a/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-HAVE_IEEE_GETQCN.patch b/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-HAVE_IEEE_GETQCN.patch new file mode 100644 index 000000000..544213489 --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-HAVE_IEEE_GETQCN.patch @@ -0,0 +1,26 @@ +From e1b8dd12605b5654bd94011cb6c587fd0c0bc9af Mon Sep 17 00:00:00 2001 +From: Jim Somerville +Date: Tue, 20 Dec 2016 11:58:26 -0500 +Subject: [PATCH 2/3] neuter HAVE_IEEE_GETQCN + +Signed-off-by: Jim Somerville +--- + source/include/linux/dcbnl.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source/include/linux/dcbnl.h b/source/include/linux/dcbnl.h +index 2c8ca62..eabf6da 100644 +--- a/source/include/linux/dcbnl.h ++++ b/source/include/linux/dcbnl.h +@@ -5,7 +5,7 @@ + + #include_next + +-#ifndef HAVE_IEEE_GETQCN ++#if 0 + + #ifndef HAVE_STRUCT_IEEE_QCN + enum dcbnl_cndd_states { +-- +1.8.3.1 + diff --git a/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-a-bunch-of-ks-stuff.patch b/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-a-bunch-of-ks-stuff.patch new file mode 100644 index 000000000..f1bd7a20e --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-a-bunch-of-ks-stuff.patch @@ -0,0 +1,47 @@ +From 63f73a02fd73f6a01bce1fbf65ae2a6a628f0626 Mon Sep 17 00:00:00 2001 +From: Jim Somerville +Date: Tue, 20 Dec 2016 16:22:47 -0500 +Subject: [PATCH 1/3] neuter a bunch of ks stuff + +Signed-off-by: Jim Somerville +--- + source/include/linux/compat-3.17.h | 2 +- + source/include/linux/compat-4.0.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/source/include/linux/compat-3.17.h b/source/include/linux/compat-3.17.h +index 6a5ff3b..ad799f0 100644 +--- a/source/include/linux/compat-3.17.h ++++ b/source/include/linux/compat-3.17.h +@@ -6,7 +6,7 @@ + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)) + +-#ifndef HAVE_KTIME_GET_REAL_NS ++#if 0 + #include + #include + static inline u64 ktime_get_real_ns(void) { +diff --git a/source/include/linux/compat-4.0.h b/source/include/linux/compat-4.0.h +index b3c37aa..900d49a 100644 +--- a/source/include/linux/compat-4.0.h ++++ b/source/include/linux/compat-4.0.h +@@ -6,6 +6,7 @@ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)) + #include + ++#if 0 + #define kstrdup_const LINUX_BACKPORT(kstrdup_const) + static inline const char *kstrdup_const(const char *s, gfp_t gfp) + { +@@ -21,6 +22,7 @@ static inline void kfree_const(const void *x) + kfree(x); + } + #endif ++#endif + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)) */ + + #endif /* LINUX_4_0_COMPAT_H */ +-- +1.8.3.1 + diff --git a/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-some-stats-output.patch b/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-some-stats-output.patch new file mode 100644 index 000000000..ca709b984 --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/patches/0001-neuter-some-stats-output.patch @@ -0,0 +1,31 @@ +From 12de070f8f73794e45ee6956c9957d0ff0c5133f Mon Sep 17 00:00:00 2001 +From: Jim Somerville +Date: Tue, 20 Dec 2016 16:56:01 -0500 +Subject: [PATCH 3/3] neuter some stats output + +Signed-off-by: Jim Somerville +--- + source/drivers/net/ethernet/mellanox/mlx4/en_sysfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source/drivers/net/ethernet/mellanox/mlx4/en_sysfs.c b/source/drivers/net/ethernet/mellanox/mlx4/en_sysfs.c +index cb7c829..21f5fc6 100644 +--- a/source/drivers/net/ethernet/mellanox/mlx4/en_sysfs.c ++++ b/source/drivers/net/ethernet/mellanox/mlx4/en_sysfs.c +@@ -186,11 +186,13 @@ static ssize_t mlx4_en_show_qcnstats(struct device *d, + len += sprintf(buf + len, "%s %d %s", "priority", i, ": "); + len += sprintf(buf + len, "%lld ", qcn_stats.rppp_rp_centiseconds[i]); + len += sprintf(buf + len, "%u ", qcn_stats.rppp_created_rps[i]); ++#if 0 + len += sprintf(buf + len, "%u ", qcn_stats.ignored_cnm[i]); + len += sprintf(buf + len, "%u ", qcn_stats.estimated_total_rate[i]); + len += sprintf(buf + len, "%u ", qcn_stats.cnms_handled_successfully[i]); + len += sprintf(buf + len, "%u ", qcn_stats.min_total_limiters_rate[i]); + len += sprintf(buf + len, "%u ", qcn_stats.max_total_limiters_rate[i]); ++#endif + len += sprintf(buf + len, "%s", "|"); + } + len += sprintf(buf + len, "\n"); +-- +1.8.3.1 + diff --git a/mellanox/mlnx-ofa_kernel/centos/srpm_path b/mellanox/mlnx-ofa_kernel/centos/srpm_path new file mode 100644 index 000000000..5b9a129b1 --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/centos/srpm_path @@ -0,0 +1 @@ +repo:addons/wr-avs/layers/avs/downloads/mlnx-ofa_kernel-4.3-OFED.4.3.1.0.1.1.g8509e41.src.rpm diff --git a/mellanox/mlnx-ofa_kernel/files/modules-load.conf b/mellanox/mlnx-ofa_kernel/files/modules-load.conf new file mode 100644 index 000000000..0e35f5f64 --- /dev/null +++ b/mellanox/mlnx-ofa_kernel/files/modules-load.conf @@ -0,0 +1,22 @@ +mlx_compat +ib_cm +ib_core +ib_ucm +ib_uverbs +iw_cm +rdma_cm +rdma_ucm +mlx4_ib +mlx5_ib +rdma_rxe +ib_iser +ib_isert +ib_srp +mlx4_core +mlx4_en +mlx5_core +nvme-rdma +nvmet-rdma +rpcrdma +svcrdma +xprtrdma diff --git a/mellanox/rdma-core/centos/build_srpm.data b/mellanox/rdma-core/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/mellanox/rdma-core/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/mellanox/rdma-core/centos/meta_patches/0001-Add-build-dependencies-and-package-versioning-for-Ti.patch b/mellanox/rdma-core/centos/meta_patches/0001-Add-build-dependencies-and-package-versioning-for-Ti.patch new file mode 100644 index 000000000..4c3daa0c6 --- /dev/null +++ b/mellanox/rdma-core/centos/meta_patches/0001-Add-build-dependencies-and-package-versioning-for-Ti.patch @@ -0,0 +1,49 @@ +From 81dab3b88df4d86aef276b6936cb55c579db1c25 Mon Sep 17 00:00:00 2001 +From: eric zhang +Date: Wed, 14 Mar 2018 14:56:21 -0400 +Subject: [PATCH 1/1] Add build dependencies and package versioning for TiS + format + +Signed-off-by: eric zhang +--- + SPECS/rdma-core.spec | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/SPECS/rdma-core.spec b/SPECS/rdma-core.spec +index 8c3feaf..2ad7398 100644 +--- a/SPECS/rdma-core.spec ++++ b/SPECS/rdma-core.spec +@@ -1,3 +1,9 @@ ++%if "%{_tis_build_type}" == "rt" ++%define bt_ext -rt ++%else ++%undefine bt_ext ++%endif ++ + %{!?cmake: %global cmake cmake} + %{!?_udevrulesdir: %global _udevrulesdir /etc/udev/rules.d} + +@@ -8,7 +14,8 @@ + + Name: rdma-core + Version: 43mlnx1 +-Release: 1%{?dist}.43101 ++Release: 1.43101%{?_tis_dist}.%{tis_patch_ver} ++ + Summary: RDMA core userspace libraries and daemons + Group: System Environment/Libraries + +@@ -24,7 +31,9 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + BuildRequires: binutils + BuildRequires: gcc + BuildRequires: python +- ++BuildRequires: cmake ++BuildRequires: libnl3-devel ++BuildRequires: mlnx-ofa_kernel%{?bt_ext}-devel + # Red Hat/Fedora previously shipped redhat/ as a stand-alone + # package called 'rdma', which we're supplanting here. + Provides: rdma = %{version}-%{release} +-- +1.8.3.1 + diff --git a/mellanox/rdma-core/centos/meta_patches/PATCH_ORDER b/mellanox/rdma-core/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..1b04e9d9b --- /dev/null +++ b/mellanox/rdma-core/centos/meta_patches/PATCH_ORDER @@ -0,0 +1 @@ +0001-Add-build-dependencies-and-package-versioning-for-Ti.patch diff --git a/mellanox/rdma-core/centos/srpm_path b/mellanox/rdma-core/centos/srpm_path new file mode 100644 index 000000000..3288867fc --- /dev/null +++ b/mellanox/rdma-core/centos/srpm_path @@ -0,0 +1 @@ +repo:addons/wr-avs/layers/avs/downloads/rdma-core-43mlnx1-1.43101.src.rpm diff --git a/mwa-sparta.map b/mwa-sparta.map new file mode 100644 index 000000000..78cf86cf3 --- /dev/null +++ b/mwa-sparta.map @@ -0,0 +1,20 @@ +cgcs/recipes-3rdparty/python|python +cgcs/recipes-base|base +cgcs/common-bsp/recipes-kernel/linux|kernel-std +cgcs/common-bsp/recipes-kernel/linux-rt|kernel-rt +cgcs/recipes-cgi|cgi +cgcs/recipes-connectivity|connectivity +cgcs/recipes-core|core +cgcs/recipes-devtools|devtools +cgcs/recipes-extended|extended +cgcs/recipes-kernel|kernel +cgcs/recipes-networking|networking +cgcs/recipes-power|power +cgcs/recipes-restapi-doc/restapi-doc|restapi-doc +cgcs/recipes-security|security +cgcs/recipes-support|support +avs/drivers/mellanox/libibverbs|mellanox/libibverbs +avs/drivers/mellanox/libmlx4|mellanox/libmlx4 +avs/drivers/mellanox/libmlx5|mellanox/libmlx5 +avs/drivers/mellanox/mlnx-ofa_kernel|mellanox/mlnx-ofa_kernel +avs/drivers/mellanox/rdma-core|mellanox/rdma-core diff --git a/networking/mlx4-config/centos/build_srpm.data b/networking/mlx4-config/centos/build_srpm.data new file mode 100644 index 000000000..4b056a60d --- /dev/null +++ b/networking/mlx4-config/centos/build_srpm.data @@ -0,0 +1,4 @@ +COPY_LIST=" \ + $CGCS_BASE/mwa-sparta/networking/mlx4-config/files/* \ +" +TIS_PATCH_VER=2 diff --git a/networking/mlx4-config/centos/mlx4-config.spec b/networking/mlx4-config/centos/mlx4-config.spec new file mode 100644 index 000000000..6197766bd --- /dev/null +++ b/networking/mlx4-config/centos/mlx4-config.spec @@ -0,0 +1,48 @@ +Summary: Wind River Mellanox port-type configuration scripts +Name: mlx4-config +Version: 1.0.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: Wind River +URL: unknown + +Source1: mlx4-configure.sh +Source2: mlx4-config.service +Source3: LICENSE +Source4: mlx4_core_goenabled.sh +Source5: mlx4_core_config.sh + +BuildRequires: chkconfig +BuildRequires: systemd-devel + +%description +Wind River Mellanox port-type configuration scripts + +%install +%{__install} -d %{buildroot}%{_sysconfdir}/init.d +%{__install} -d %{buildroot}%{_unitdir} +%{__install} -d %{buildroot}%{_sysconfdir}/goenabled.d +%{__install} -d %{buildroot}%{_bindir} +%{__install} -m 755 %SOURCE1 %{buildroot}%{_sysconfdir}/init.d/ +%{__install} -m 644 %SOURCE2 %{buildroot}%{_unitdir}/ +%{__install} -m 555 %SOURCE4 %{buildroot}%{_sysconfdir}/goenabled.d/ +%{__install} -m 755 %SOURCE5 %{buildroot}%{_bindir}/ + +%clean +%{__rm} -rf %{buildroot} + +%post +/bin/systemctl enable mlx4-config.service >/dev/null 2>&1 + +%preun +/bin/systemctl disable mlx4-config.service >/dev/null 2>&1 + + +%files +%license ../SOURCES/LICENSE +%defattr(-,root,root,-) +%{_sysconfdir}/init.d/mlx4-configure.sh +%{_unitdir}/mlx4-config.service +%{_sysconfdir}/goenabled.d/mlx4_core_goenabled.sh +%{_bindir}/mlx4_core_config.sh diff --git a/networking/mlx4-config/files/LICENSE b/networking/mlx4-config/files/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/networking/mlx4-config/files/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/networking/mlx4-config/files/mlx4-config.service b/networking/mlx4-config/files/mlx4-config.service new file mode 100644 index 000000000..5a834f2c0 --- /dev/null +++ b/networking/mlx4-config/files/mlx4-config.service @@ -0,0 +1,12 @@ +[Unit] +Description=Wind River Mellanox port-type configuration scripts +Before=network.target + +[Service] +Type=oneshot +User=root +ExecStart=/etc/init.d/mlx4-configure.sh start +ExecStop=/etc/init.d/mlx4-configure.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/networking/mlx4-config/files/mlx4-configure.sh b/networking/mlx4-config/files/mlx4-configure.sh new file mode 100644 index 000000000..0953f0775 --- /dev/null +++ b/networking/mlx4-config/files/mlx4-configure.sh @@ -0,0 +1,119 @@ +#!/bin/bash +################################################################################ +# Copyright (c) 2015 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +################################################################################ + +PROGNAME=$(basename $0) +VENDOR_MLX4="0x15b3" +SYSFS_PCI_DEVICES=/sys/bus/pci/devices +DEBUG=${DEBUG:-0} + +# enable complex pattern matching so that in "configure_device()" we can get +# all files beginning in "mlx4_port" and ending in one or more digits. +shopt -s extglob + +function log() +{ + local MSG="${PROGNAME}: $1" + if [ ${DEBUG} -ne 0 ]; then + echo "${MSG}" + fi + echo "${MSG}" >> /var/log/mlx4-configure.log +} + +function configure_device() +{ + local DEVICE=$1 + local DEVICE_PATH=${SYSFS_PCI_DEVICES}/${DEVICE} + + if [ ! -d ${DEVICE_PATH} ]; then + log "device path ${DEVICE_PATH} not present for ${DEVICE}" + return 1 + fi + + local PORTS=$(ls -v1 ${DEVICE_PATH}/mlx4_port+([0-9])) + + local RESULT=0 + for PORT in ${PORTS}; do + local PORT_NAME=$(basename ${PORT}) + local PORT_TYPE=$(cat ${PORT}) + + if [ "${PORT_TYPE}" != "eth" ]; then + echo "eth" > ${PORT} + if [ $? -ne 0 ]; then + log "failed to change ${DEVICE}/${PORT_NAME} port type from \"${PORT_TYPE}\" to \"eth\"" + RESULT=1 + else + log "successfully changed ${DEVICE}/${PORT_NAME} port type from \"${PORT_TYPE}\" to \"eth\"" + fi + else + log "port type already set to \"eth\" for ${DEVICE}/${PORT_NAME}" + fi + done + + return ${RESULT} +} + + +function scan_devices() +{ + local DEVICES=$(ls -1 ${SYSFS_PCI_DEVICES}) + + for DEVICE in ${DEVICES}; do + local VENDOR=$(cat ${SYSFS_PCI_DEVICES}/${DEVICE}/vendor) + local CLASS=$(cat ${SYSFS_PCI_DEVICES}/${DEVICE}/class) + + if ((((${CLASS} & 0xff0000)) != 0x020000)); then + ## Not a networking controller + continue + fi + + if [ "${VENDOR}" != "${VENDOR_MLX4}" ]; then + ## Not a Mellanox device + continue + fi + + configure_device ${DEVICE} + done + + return 0 +} + + +function start() +{ + scan_devices + return $? +} + +function stop() +{ + return 0 +} + +function status() +{ + return 0 +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 +esac diff --git a/networking/mlx4-config/files/mlx4_core_config.sh b/networking/mlx4-config/files/mlx4_core_config.sh new file mode 100644 index 000000000..94816bff0 --- /dev/null +++ b/networking/mlx4-config/files/mlx4_core_config.sh @@ -0,0 +1,24 @@ +#!/bin/bash +################################################################################ +# Copyright (c) 2015-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +################################################################################ +# +# Purpose: +# create /var/run/.mlx4_cx3_reboot_required to indicate a reboot is required +# this way newly generated mlx4_core kernel options can be applied +# inject /etc/modprobe.d/mlx4_sriov.conf into initramfs, since when the system +# is booted, the mlx4_core kernel module in initramfs will be used, so we need +# to inject the newly created modprobe conf file into initramfs +# +# Usage: /usr/bin/mlx4_core_config.sh +# +# Define minimal path +PATH=/bin:/usr/bin:/usr/local/bin + +/usr/sbin/touch /var/run/.mlx4_cx3_reboot_required +/usr/bin/dracut --include /etc/modprobe.d/mlx4_sriov.conf /etc/modprobe.d/mlx4_sriov.conf --force + +exit 0 diff --git a/networking/mlx4-config/files/mlx4_core_goenabled.sh b/networking/mlx4-config/files/mlx4_core_goenabled.sh new file mode 100644 index 000000000..c1a3592d7 --- /dev/null +++ b/networking/mlx4-config/files/mlx4_core_goenabled.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# mlx4_core options "goenabled" check. +# If a /etc/modprobe.d/mlx_sriov.conf has been modified/created on this node, it should be rebooted to apply this options. + +NAME=$(basename $0) +OPTIONS_CHANGED_FLAG=/var/run/.mlx4_cx3_reboot_required +COMPUTE_CONFIG_COMPLETE=/var/run/.compute_config_complete + +function LOG() +{ + logger "$NAME: $*" +} + +if [ -f $OPTIONS_CHANGED_FLAG ] && [ -f $COMPUTE_CONFIG_COMPLETE ] +then + LOG "mlx4_core options has been changed. Failing goenabled check." + exit 1 +fi + +exit 0 + diff --git a/networking/net-snmp/PKG-INFO b/networking/net-snmp/PKG-INFO new file mode 100644 index 000000000..420722dd7 --- /dev/null +++ b/networking/net-snmp/PKG-INFO @@ -0,0 +1,23 @@ +Metadata-Version: 1.1 +Name: net-snmp +Version: 5.7.2 +Summary: A collection of SNMP protocol tools and libraries +Home-page: +Author: +Author-email: +License: BSD + +Description: +SNMP (Simple Network Management Protocol) is a protocol used for +network management. The NET-SNMP project includes various SNMP tools: +an extensible agent, an SNMP library, tools for requesting or setting +information from SNMP agents, tools for generating and handling SNMP +traps, a version of the netstat command which uses SNMP, and a Tk/Perl +mib browser. This package contains the snmpd and snmptrapd daemons, +documentation, etc. + +You will probably also want to install the net-snmp-utils package, +which contains NET-SNMP utilities. + + +Platform: UNKNOWN diff --git a/networking/net-snmp/centos/build_srpm.data b/networking/net-snmp/centos/build_srpm.data new file mode 100644 index 000000000..315c54e10 --- /dev/null +++ b/networking/net-snmp/centos/build_srpm.data @@ -0,0 +1,3 @@ +COPY_LIST="files/* patches/*" +TIS_PATCH_VER=10 +BUILD_IS_SLOW=3 diff --git a/networking/net-snmp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/networking/net-snmp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..f792b37c3 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 2b9054a9278f5b7a6af660eb5842b9ec32d50e74 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:59 -0400 +Subject: [PATCH 8/9] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/net-snmp.spec +--- + SPECS/net-snmp.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index 0ac1eef..8d109b8 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -14,7 +14,7 @@ + Summary: A collection of SNMP protocol tools and libraries + Name: net-snmp + Version: 5.7.2 +-Release: 28%{?dist}.1 ++Release: 28.el7%{?_tis_dist}.%{tis_patch_ver} + Epoch: 1 + + License: BSD +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/PATCH_ORDER b/networking/net-snmp/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..9edf471da --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,11 @@ +spec-include-TiS-patches.patch +snmpd-service-OPTIONS.patch +snmp-spec-add-init-script.patch +fix-snmpd-service.patch +fix-snmpd-initscript.patch +run-snmpd-as-non-root-user.patch +fix-snmpd-service-reload.patch +0001-Update-package-versioning-for-TIS-format.patch +snmp-spec-add-snmp-config.patch +snmp-spec-config-file-permission.patch +spec-configure-without-HOST-RESOURCES-MIB.patch diff --git a/networking/net-snmp/centos/meta_patches/fix-snmpd-initscript.patch b/networking/net-snmp/centos/meta_patches/fix-snmpd-initscript.patch new file mode 100644 index 000000000..a91b45c65 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/fix-snmpd-initscript.patch @@ -0,0 +1,24 @@ +From 294f4a58442180dc2787b3c67aaea8e83910ae6c Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:58 -0400 +Subject: [PATCH 5/9] WRS: fix-snmpd-initscript.patch + +--- + SPECS/net-snmp.spec | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index df248ac..a433f40 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -419,7 +419,6 @@ mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d + install -m 755 %SOURCE13 ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d/snmpd + + install -d ${RPM_BUILD_ROOT}%{_initrddir} +-install -m 755 %SOURCE2 ${RPM_BUILD_ROOT}%{_initrddir}/snmpd + install -m 755 %SOURCE3 ${RPM_BUILD_ROOT}%{_initrddir}/snmptrapd + + install -d ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/fix-snmpd-service-reload.patch b/networking/net-snmp/centos/meta_patches/fix-snmpd-service-reload.patch new file mode 100644 index 000000000..6c5234119 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/fix-snmpd-service-reload.patch @@ -0,0 +1,25 @@ +From 2b9059876d087843078b750d0d1dc0117e17d31a Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:59 -0400 +Subject: [PATCH 7/9] WRS: fix-snmpd-service-reload.patch + +--- + SOURCES/snmpd.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SOURCES/snmpd.service b/SOURCES/snmpd.service +index ad689c8..1319091 100644 +--- a/SOURCES/snmpd.service ++++ b/SOURCES/snmpd.service +@@ -8,7 +8,7 @@ Environment=OPTIONS="oamcontroller -u snmpd -Lsd -Lf /dev/null -p /var/run/snmpd + EnvironmentFile=-/etc/sysconfig/snmpd + ExecStart=/etc/init.d/snmpd start + ExecStop=/etc/init.d/snmpd stop +-ExecReload=/etc/init.d/snmpd restart ++ExecReload=/bin/kill -HUP $MAINPID + + [Install] + WantedBy=multi-user.target +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/fix-snmpd-service.patch b/networking/net-snmp/centos/meta_patches/fix-snmpd-service.patch new file mode 100644 index 000000000..69e62e7ee --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/fix-snmpd-service.patch @@ -0,0 +1,28 @@ +From 43036215d0f88d6c8789a596578ea7cc0002ff61 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:58 -0400 +Subject: [PATCH 4/9] WRS: fix-snmpd-service.patch + +--- + SOURCES/snmpd.service | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/SOURCES/snmpd.service b/SOURCES/snmpd.service +index 8ec215b..84b6ca3 100644 +--- a/SOURCES/snmpd.service ++++ b/SOURCES/snmpd.service +@@ -6,8 +6,9 @@ After=syslog.target network.target + Type=notify + Environment=OPTIONS="oamcontroller -Lsd -Lf /dev/null -p /var/run/snmpd.pid" + EnvironmentFile=-/etc/sysconfig/snmpd +-ExecStart=/usr/sbin/snmpd $OPTIONS -f +-ExecReload=/bin/kill -HUP $MAINPID ++ExecStart=/etc/init.d/snmpd start ++ExecStop=/etc/init.d/snmpd stop ++ExecReload=/etc/init.d/snmpd restart + + [Install] + WantedBy=multi-user.target +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/run-snmpd-as-non-root-user.patch b/networking/net-snmp/centos/meta_patches/run-snmpd-as-non-root-user.patch new file mode 100644 index 000000000..008c3be02 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/run-snmpd-as-non-root-user.patch @@ -0,0 +1,50 @@ +From d984ab4a020a20082190e8029f45f06031f320da Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:59 -0400 +Subject: [PATCH 6/9] WRS: run-snmpd-as-non-root-user.patch + +Conflicts: + SPECS/net-snmp.spec +--- + SOURCES/snmpd.service | 2 +- + SPECS/net-snmp.spec | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/SOURCES/snmpd.service b/SOURCES/snmpd.service +index 84b6ca3..ad689c8 100644 +--- a/SOURCES/snmpd.service ++++ b/SOURCES/snmpd.service +@@ -4,7 +4,7 @@ After=syslog.target network.target + + [Service] + Type=notify +-Environment=OPTIONS="oamcontroller -Lsd -Lf /dev/null -p /var/run/snmpd.pid" ++Environment=OPTIONS="oamcontroller -u snmpd -Lsd -Lf /dev/null -p /var/run/snmpd.pid" + EnvironmentFile=-/etc/sysconfig/snmpd + ExecStart=/etc/init.d/snmpd start + ExecStop=/etc/init.d/snmpd stop +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index a433f40..0ac1eef 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -14,7 +14,7 @@ + Summary: A collection of SNMP protocol tools and libraries + Name: net-snmp + Version: 5.7.2 +-Release: 28%{?dist} ++Release: 28%{?dist}.1 + Epoch: 1 + + License: BSD +@@ -413,7 +413,7 @@ install -m 644 %SOURCE6 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/snmptrapd.conf + + # WRS + install -m 644 %SOURCE12 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/snmpd.conf +-chmod 600 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/snmptrapd.conf ++chmod 660 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/* + + mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d + install -m 755 %SOURCE13 ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d/snmpd +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/snmp-spec-add-init-script.patch b/networking/net-snmp/centos/meta_patches/snmp-spec-add-init-script.patch new file mode 100644 index 000000000..30b5e0146 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/snmp-spec-add-init-script.patch @@ -0,0 +1,42 @@ +From 05124f2495f4173848cac245c6579247a0e255d6 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:58 -0400 +Subject: [PATCH 3/9] WRS: snmp-spec-add-init-script.patch + +--- + SPECS/net-snmp.spec | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index 85955d0..df248ac 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -41,6 +41,7 @@ Source11: snmptrapd.service + + # WRS + Source12: snmpd.conf.cgcs ++Source13: snmpd.cgcs + + Patch1: net-snmp-5.7.2-pie.patch + Patch2: net-snmp-5.5-dir-fix.patch +@@ -414,6 +415,9 @@ install -m 644 %SOURCE6 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/snmptrapd.conf + install -m 644 %SOURCE12 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/snmpd.conf + chmod 600 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/snmptrapd.conf + ++mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d ++install -m 755 %SOURCE13 ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d/snmpd ++ + install -d ${RPM_BUILD_ROOT}%{_initrddir} + install -m 755 %SOURCE2 ${RPM_BUILD_ROOT}%{_initrddir}/snmpd + install -m 755 %SOURCE3 ${RPM_BUILD_ROOT}%{_initrddir}/snmptrapd +@@ -553,6 +557,7 @@ rm -rf ${RPM_BUILD_ROOT} + %dir %{_localstatedir}/run/net-snmp + %{_prefix}/lib/tmpfiles.d/net-snmp.conf + %{_unitdir}/snmp* ++%{_sysconfdir}/rc.d/init.d/snmpd + %config(noreplace) %{_sysconfdir}/sysconfig/snmpd + %config(noreplace) %{_sysconfdir}/sysconfig/snmptrapd + +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/snmp-spec-add-snmp-config.patch b/networking/net-snmp/centos/meta_patches/snmp-spec-add-snmp-config.patch new file mode 100644 index 000000000..a5bb5c171 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/snmp-spec-add-snmp-config.patch @@ -0,0 +1,41 @@ +From 1e57fa5c972496c35b0b1e2aa6f7c9b906cec08c Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:59 -0400 +Subject: [PATCH 9/9] WRS: snmp-spec-add-snmp-config.patch + +--- + SPECS/net-snmp.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index 8d109b8..f0c1d48 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -42,6 +42,7 @@ Source11: snmptrapd.service + # WRS + Source12: snmpd.conf.cgcs + Source13: snmpd.cgcs ++Source14: snmp.conf.cgcs + + Patch1: net-snmp-5.7.2-pie.patch + Patch2: net-snmp-5.5-dir-fix.patch +@@ -418,6 +419,8 @@ chmod 660 ${RPM_BUILD_ROOT}%{_sysconfdir}/snmp/* + mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d + install -m 755 %SOURCE13 ${RPM_BUILD_ROOT}%{_sysconfdir}/rc.d/init.d/snmpd + ++install -m 660 %SOURCE14 ${RPM_BUILD_ROOT}%{_datadir}/snmp/snmp.conf ++ + install -d ${RPM_BUILD_ROOT}%{_initrddir} + install -m 755 %SOURCE3 ${RPM_BUILD_ROOT}%{_initrddir}/snmptrapd + +@@ -552,6 +555,7 @@ rm -rf ${RPM_BUILD_ROOT} + %attr(0644,root,root) %{_mandir}/man1/net-snmp-create-v3-user* + %attr(0644,root,root) %{_mandir}/man1/snmpconf.1.gz + %dir %{_datadir}/snmp ++%config(noreplace) %attr(0660,snmpd,snmpd) %{_datadir}/snmp/snmp.conf + %{_datadir}/snmp/snmpconf-data + %dir %{_localstatedir}/run/net-snmp + %{_prefix}/lib/tmpfiles.d/net-snmp.conf +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/snmp-spec-config-file-permission.patch b/networking/net-snmp/centos/meta_patches/snmp-spec-config-file-permission.patch new file mode 100644 index 000000000..cbbff7340 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/snmp-spec-config-file-permission.patch @@ -0,0 +1,27 @@ +From a2f64266f7423905b1fd718c405ad25890f6efb5 Mon Sep 17 00:00:00 2001 +From: Tao Liu +Date: Thu, 4 Jan 2018 11:43:15 -0500 +Subject: snmp spec change config file permission + +--- + SPECS/net-snmp.spec | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index 182265b..8600da9 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -545,8 +545,8 @@ rm -rf ${RPM_BUILD_ROOT} + %doc local/passtest local/ipf-mod.pl + %doc README.thread AGENT.txt PORTING local/README.mib2c + %dir %{_sysconfdir}/snmp +-%config(noreplace) %attr(0600,root,root) %{_sysconfdir}/snmp/snmpd.conf +-%config(noreplace) %attr(0600,root,root) %{_sysconfdir}/snmp/snmptrapd.conf ++%config(noreplace) %attr(0640,root,root) %{_sysconfdir}/snmp/snmpd.conf ++%config(noreplace) %attr(0640,root,root) %{_sysconfdir}/snmp/snmptrapd.conf + %{_bindir}/snmpconf + %{_bindir}/agentxtrap + %{_bindir}/net-snmp-create-v3-user +-- +1.8.3.1 + diff --git a/networking/net-snmp/centos/meta_patches/snmpd-service-OPTIONS.patch b/networking/net-snmp/centos/meta_patches/snmpd-service-OPTIONS.patch new file mode 100644 index 000000000..e3dce5dc8 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/snmpd-service-OPTIONS.patch @@ -0,0 +1,25 @@ +From d316d562a3adc3eca5952823d18687b208b1a065 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:58 -0400 +Subject: [PATCH 2/9] WRS: snmpd-service-OPTIONS.patch + +--- + SOURCES/snmpd.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SOURCES/snmpd.service b/SOURCES/snmpd.service +index adb394d..8ec215b 100644 +--- a/SOURCES/snmpd.service ++++ b/SOURCES/snmpd.service +@@ -4,7 +4,7 @@ After=syslog.target network.target + + [Service] + Type=notify +-Environment=OPTIONS="-LS0-6d" ++Environment=OPTIONS="oamcontroller -Lsd -Lf /dev/null -p /var/run/snmpd.pid" + EnvironmentFile=-/etc/sysconfig/snmpd + ExecStart=/usr/sbin/snmpd $OPTIONS -f + ExecReload=/bin/kill -HUP $MAINPID +-- +1.9.1 + diff --git a/networking/net-snmp/centos/meta_patches/spec-add-rpm-headerGetEntry-fix.patch b/networking/net-snmp/centos/meta_patches/spec-add-rpm-headerGetEntry-fix.patch new file mode 100644 index 000000000..2d128e957 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/spec-add-rpm-headerGetEntry-fix.patch @@ -0,0 +1,20 @@ +diff --git a/net-snmp.spec b/net-snmp.spec +index f0c1d48..182265b 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -47,6 +47,7 @@ Source14: snmp.conf.cgcs + Patch1: net-snmp-5.7.2-pie.patch + Patch2: net-snmp-5.5-dir-fix.patch + Patch3: net-snmp-5.6-multilib.patch ++Patch4: 0001-rpm-headerGetEntry.patch + Patch5: net-snmp-5.6-test-debug.patch + Patch6: net-snmp-5.7.2-systemd.patch + Patch7: net-snmp-5.7.2-fips.patch +@@ -262,6 +263,7 @@ The net-snmp-sysvinit package provides SysV init scripts for Net-SNMP daemons. + + %patch2 -p1 -b .dir-fix + %patch3 -p1 -b .multilib ++%patch4 -p1 + %patch5 -p1 + %patch6 -p1 -b .systemd + %patch7 -p1 -b .fips diff --git a/networking/net-snmp/centos/meta_patches/spec-configure-without-HOST-RESOURCES-MIB.patch b/networking/net-snmp/centos/meta_patches/spec-configure-without-HOST-RESOURCES-MIB.patch new file mode 100644 index 000000000..f50690027 --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/spec-configure-without-HOST-RESOURCES-MIB.patch @@ -0,0 +1,21 @@ +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index 12323a4..1e23fba 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -331,7 +331,7 @@ rm testing/fulltests/default/T200* + %endif + + %build +-MIBS="host agentx smux \ ++MIBS="agentx smux \ + ucd-snmp/diskio tcp-mib udp-mib mibII/mta_sendmail \ + ip-mib/ipv4InterfaceTable ip-mib/ipv6InterfaceTable \ + ip-mib/ipAddressPrefixTable/ipAddressPrefixTable \ +@@ -352,6 +352,7 @@ MIBS="$MIBS ucd-snmp/lmsensorsMib" + --with-logfile="/var/log/snmpd.log" \ + --with-persistent-directory="/var/lib/net-snmp" \ + --with-mib-modules="$MIBS" \ ++ --with-out-mib-modules=host \ + %if %{netsnmp_tcp_wrappers} + --with-libwrap=yes \ + %endif diff --git a/networking/net-snmp/centos/meta_patches/spec-include-TiS-patches.patch b/networking/net-snmp/centos/meta_patches/spec-include-TiS-patches.patch new file mode 100644 index 000000000..31c94c64e --- /dev/null +++ b/networking/net-snmp/centos/meta_patches/spec-include-TiS-patches.patch @@ -0,0 +1,59 @@ +From 7f219b321341d75f3caa233669b7ae623eb1f705 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:05:58 -0400 +Subject: [PATCH 1/9] WRS: spec-include-TiS-patches.patch + +--- + SPECS/net-snmp.spec | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/SPECS/net-snmp.spec b/SPECS/net-snmp.spec +index d15029f..85955d0 100644 +--- a/SPECS/net-snmp.spec ++++ b/SPECS/net-snmp.spec +@@ -1,3 +1,6 @@ ++# WRS: Disable check ++%global netsnmp_check 0 ++ + # use netsnmp_tcp_wrappers 0 to disable tcp_wrappers support + %{!?netsnmp_tcp_wrappers:%global netsnmp_tcp_wrappers 1} + # use nestnmp_check 0 to speed up packaging by disabling 'make test' +@@ -35,6 +38,10 @@ Source8: net-snmptrapd.sysconfig + Source9: net-snmp-tmpfs.conf + Source10: snmpd.service + Source11: snmptrapd.service ++ ++# WRS ++Source12: snmpd.conf.cgcs ++ + Patch1: net-snmp-5.7.2-pie.patch + Patch2: net-snmp-5.5-dir-fix.patch + Patch3: net-snmp-5.6-multilib.patch +@@ -357,6 +364,7 @@ MIBS="$MIBS ucd-snmp/lmsensorsMib" + --with-security-modules=tsm \ + --with-mysql \ + --with-systemd \ ++ --without-nl \ + --with-sys-contact="root@localhost" </dev/null + if [ $? -eq 0 ]; then + echo -n "is already running " + RETVAL=0 + elif [ -f ${SNMPDCONFIG} ]; then + start-stop-daemon -o --start --quiet --name ${SNMPDNAME} --pidfile "$PIDFILE" \ + --exec ${SNMPD} -- ${SNMPDOPTS} + RETVAL=$? + else + logger "${SNMPDCONFIG} is missing" + RETVAL=${GENERIC_ERROR} + fi + if [ ${RETVAL} -eq 0 ] ; then + pid=`pidof ${SNMPDNAME}` + echo "OK" + logger "${SNMPDNAME} (${pid})" + else + echo "FAIL" + RETVAL=${GENERIC_ERROR} + fi + + ;; + stop) + status ${SNMPD} >/dev/null + if [ $? -ne 0 ]; then + echo "$SNMPDNAME is not running" + RETVAL=0 + else + echo -n "Stopping network management services " + killproc ${SNMPDNAME} + if [ -n "`pidof ${SNMPDNAME}`" ] ; then + logger "Going to SIGKILL ${SNMPDNAME}" + killproc -KILL ${SNMPDNAME} + fi + /bin/rm -rf $PIDFILE + status ${SNMPD} >/dev/null + if [ $? -ne 0 ]; then + echo "Stopped" + RETVAL=0 + else + echo "Failed" + RETVAL=${GENERIC_ERROR} + fi + fi + ;; + status) + status ${SNMPD} >/dev/null + RETVAL=$? + if [ ! ${RETVAL} -eq 0 ] ; then + RETVAL=${NOT_RUNNING} + fi + + ;; + restart|reload|force-reload) + $0 stop + sleep 1 + $0 start + + ;; + *) + echo "Usage: /etc/init.d/snmpd {start|stop|status|restart|reload|force-reload}" + exit ${GENERIC_ERROR} +esac + +exit $RETVAL diff --git a/networking/net-snmp/files/snmpd.conf.cgcs b/networking/net-snmp/files/snmpd.conf.cgcs new file mode 100644 index 000000000..53eff7f7e --- /dev/null +++ b/networking/net-snmp/files/snmpd.conf.cgcs @@ -0,0 +1,24 @@ +########################################################################### +# +# snmpd.conf +# +# - created by the snmpconf configuration program +# +########################################################################### +# incl/excl subtree mask +view all included .1 80 + +sysDescr ? +sysObjectID 1.3.6.1.4.1.731.3 +sysContact ? +sysName ? +sysLocation ? +sysServices 72 + +[snmp] clientaddr oamcontroller +dlmod cgtsAgentPlugin /usr/lib64/libcgtsAgentPlugin.so.1 +dlmod snmpAuditPlugin /usr/lib64/libsnmpAuditPlugin.so.1 + +# Insert the snmpAudit hander into specific sections of the mib tree +injectHandler snmpAudit null +injectHandler snmpAudit bulk_to_next diff --git a/networking/net-snmp/patches/0001-rpm-headerGetEntry.patch b/networking/net-snmp/patches/0001-rpm-headerGetEntry.patch new file mode 100644 index 000000000..a769588c4 --- /dev/null +++ b/networking/net-snmp/patches/0001-rpm-headerGetEntry.patch @@ -0,0 +1,148 @@ +diff --git a/agent/mibgroup/host/data_access/swinst_rpm.c b/agent/mibgroup/host/data_access/swinst_rpm.c +index 71595be..e12d3c8 100644 +--- a/agent/mibgroup/host/data_access/swinst_rpm.c ++++ b/agent/mibgroup/host/data_access/swinst_rpm.c +@@ -96,14 +96,18 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) + + rpmdbMatchIterator mi; + Header h; +- char *n, *v, *r, *g; +- int32_t *t; ++ rpmtd td_n, td_v, td_r, td_g, td_t; + time_t install_time; + size_t date_len; + int i = 1; + netsnmp_swinst_entry *entry; + + ts = rpmtsCreate(); ++ td_n = rpmtdNew(); ++ td_v = rpmtdNew(); ++ td_r = rpmtdNew(); ++ td_g = rpmtdNew(); ++ td_t = rpmtdNew(); + rpmtsSetVSFlags( ts, (_RPMVSF_NOSIGNATURES|_RPMVSF_NODIGESTS)); + + mi = rpmtsInitIterator( ts, RPMDBI_PACKAGES, NULL, 0); +@@ -119,21 +123,21 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) + CONTAINER_INSERT(container, entry); + + h = headerLink( h ); +- headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL); +- headerGetEntry( h, RPMTAG_VERSION, NULL, (void**)&v, NULL); +- headerGetEntry( h, RPMTAG_RELEASE, NULL, (void**)&r, NULL); +- headerGetEntry( h, RPMTAG_GROUP, NULL, (void**)&g, NULL); +- headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL); ++ headerGet( h, RPMTAG_NAME, td_n, HEADERGET_EXT); ++ headerGet( h, RPMTAG_VERSION, td_v, HEADERGET_EXT); ++ headerGet( h, RPMTAG_RELEASE, td_r, HEADERGET_EXT); ++ headerGet( h, RPMTAG_GROUP, td_g, HEADERGET_EXT); ++ headerGet( h, RPMTAG_INSTALLTIME, td_t, HEADERGET_EXT); + + entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), +- "%s-%s-%s", n, v, r); ++ "%s-%s-%s", rpmtdGetString(td_n), rpmtdGetString(td_v), rpmtdGetString(td_r)); + if (entry->swName_len > sizeof(entry->swName)) + entry->swName_len = sizeof(entry->swName); +- entry->swType = (NULL != strstr( g, "System Environment")) ++ entry->swType = (NULL != strstr( rpmtdGetString(td_g), "System Environment")) + ? 2 /* operatingSystem */ + : 4; /* application */ + +- install_time = *t; ++ install_time = rpmtdGetUint32(td_t); + dt = date_n_time( &install_time, &date_len ); + if (date_len != 8 && date_len != 11) { + snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName); +@@ -148,6 +152,11 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) + } + rpmdbFreeIterator( mi ); + rpmtsFree( ts ); ++ rpmtdFree(td_t); ++ rpmtdFree(td_g); ++ rpmtdFree(td_r); ++ rpmtdFree(td_v); ++ rpmtdFree(td_n); + + DEBUGMSGTL(("swinst:load:arch", "loaded %d entries\n", + (int)CONTAINER_SIZE(container))); +diff --git a/agent/mibgroup/host/hr_swinst.c b/agent/mibgroup/host/hr_swinst.c +index 4aa4593..643d3fe 100644 +--- a/agent/mibgroup/host/hr_swinst.c ++++ b/agent/mibgroup/host/hr_swinst.c +@@ -484,15 +484,17 @@ var_hrswinst(struct variable * vp, + } + #else + # ifdef HAVE_LIBRPM +- char *rpm_groups; +- if ( headerGetEntry(swi->swi_h, RPMTAG_GROUP, NULL, (void **) &rpm_groups, NULL) ) { +- if ( strstr(rpm_groups, "System Environment") != NULL ) ++ rpmtd td; ++ td = rpmtdNew(); ++ if ( headerGet(swi->swi_h, RPMTAG_GROUP, td, HEADERGET_EXT) ) { ++ if ( strstr(rpmtdGetString(td), "System Environment") != NULL ) + long_return = 2; /* operatingSystem */ + else + long_return = 4; /* applcation */ + } else { + long_return = 1; /* unknown */ + } ++ rpmtdFree(td); + # else + long_return = 1; /* unknown */ + # endif +@@ -503,13 +505,15 @@ var_hrswinst(struct variable * vp, + case HRSWINST_DATE: + { + #ifdef HAVE_LIBRPM +- int32_t *rpm_data; +- if ( headerGetEntry(swi->swi_h, RPMTAG_INSTALLTIME, NULL, (void **) &rpm_data, NULL) ) { +- time_t installTime = *rpm_data; ++ rpmtd td; ++ td = rpmtdNew(); ++ if ( headerGet(swi->swi_h, RPMTAG_INSTALLTIME, td, HEADERGET_EXT) ) { ++ time_t installTime = rpmtdGetNumber(td); + ret = date_n_time(&installTime, var_len); + } else { + ret = date_n_time(NULL, var_len); + } ++ rpmtdFree(td); + #else + if (swi->swi_directory != NULL) { + snprintf(string, sizeof(string), "%s/%s", +@@ -662,7 +666,7 @@ Save_HR_SW_info(int ix) + if (1 <= ix && ix <= swi->swi_nrec && ix != swi->swi_prevx) { + int offset; + Header h; +- char *n, *v, *r; ++ rpmtd td_n, td_v, td_r; + + offset = swi->swi_recs[ix - 1]; + +@@ -687,13 +691,21 @@ Save_HR_SW_info(int ix) + swi->swi_h = h; + swi->swi_prevx = ix; + +- headerGetEntry(swi->swi_h, RPMTAG_NAME, NULL, (void **) &n, NULL); +- headerGetEntry(swi->swi_h, RPMTAG_VERSION, NULL, (void **) &v, +- NULL); +- headerGetEntry(swi->swi_h, RPMTAG_RELEASE, NULL, (void **) &r, +- NULL); +- snprintf(swi->swi_name, sizeof(swi->swi_name), "%s-%s-%s", n, v, r); ++ td_n = rpmtdNew{}; ++ td_v = rpmtdNew{}; ++ td_r = rpmtdNew{}; ++ ++ headerGet(swi->swi_h, RPMTAG_NAME, td_n, HEADERGET_EXT); ++ headerGet(swi->swi_h, RPMTAG_VERSION, td_v, HEADERGET_EXT); ++ headerGet(swi->swi_h, RPMTAG_RELEASE, td_r, HEADERGET_EXT); ++ ++ snprintf(swi->swi_name, sizeof(swi->swi_name), "%s-%s-%s", rpmtdGetString(td_n), rpmtdGetNumber(td_v), rpmtdGetNumber(td_r)); + swi->swi_name[ sizeof(swi->swi_name)-1 ] = 0; ++ ++ rpmtdFree(td_r); ++ rpmtdFree(td_v); ++ rpmtdFree(td_n); ++ + } + #else + snprintf(swi->swi_name, sizeof(swi->swi_name), "%s", swi->swi_dep->d_name); diff --git a/networking/openldap/PKG-INFO b/networking/openldap/PKG-INFO new file mode 100644 index 000000000..a2c07107c --- /dev/null +++ b/networking/openldap/PKG-INFO @@ -0,0 +1,15 @@ +Metadata-Version: 1.1 +Name: openldap +Version: 2.4.40 +Summary: OpenLDAP Directory Service +Home-page: +Author: +Author-email: +License: OLDAP-2.8 + +Description: +OpenLDAP Software is an open source implementation of the Lightweight +Directory Access Protocol. + + +Platform: UNKNOWN diff --git a/networking/openldap/centos/build_srpm.data b/networking/openldap/centos/build_srpm.data new file mode 100644 index 000000000..140f122b9 --- /dev/null +++ b/networking/openldap/centos/build_srpm.data @@ -0,0 +1,3 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=7 +BUILD_IS_SLOW=3 diff --git a/networking/openldap/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/networking/openldap/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..79b4a9b4a --- /dev/null +++ b/networking/openldap/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From d9b5bd4253c4c6965895adaceb08ade39f376165 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:11:22 -0400 +Subject: [PATCH 5/5] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/openldap.spec +--- + SPECS/openldap.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/openldap.spec b/SPECS/openldap.spec +index 973c2db..50bb499 100644 +--- a/SPECS/openldap.spec ++++ b/SPECS/openldap.spec +@@ -5,7 +5,7 @@ + + Name: openldap + Version: 2.4.44 +-Release: 5%{?dist} ++Release: 5.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: LDAP support libraries + Group: System Environment/Daemons + License: OpenLDAP +-- +1.9.1 + diff --git a/networking/openldap/centos/meta_patches/PATCH_ORDER b/networking/openldap/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..6935b97f1 --- /dev/null +++ b/networking/openldap/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,6 @@ +openldap-spec-file.patch +openldap-service-file.patch +openldap-sysconfig-file.patch +openldap-enable-password-policy.patch +openldap-remove-ldap-conf-cgcs-file.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/networking/openldap/centos/meta_patches/openldap-enable-password-policy.patch b/networking/openldap/centos/meta_patches/openldap-enable-password-policy.patch new file mode 100644 index 000000000..995c545b3 --- /dev/null +++ b/networking/openldap/centos/meta_patches/openldap-enable-password-policy.patch @@ -0,0 +1,55 @@ +From 7e79fd683d458499fbaef1d3cdbf5654cfccf4ff Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:11:22 -0400 +Subject: [PATCH 4/5] WRS: openldap-enable-password-policy.patch + +--- + SPECS/openldap.spec | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/SPECS/openldap.spec b/SPECS/openldap.spec +index 5121f8a..973c2db 100644 +--- a/SPECS/openldap.spec ++++ b/SPECS/openldap.spec +@@ -85,6 +85,9 @@ Patch92: check-password-loglevels.patch + Patch100: openldap-autoconf-pkgconfig-nss.patch + Patch102: openldap-fedora-systemd.patch + ++# WRS specific patches ++Patch200: rootdn-should-not-bypass-ppolicy.patch ++ + BuildRequires: cyrus-sasl-devel, nss-devel, krb5-devel, tcp_wrappers-devel, unixODBC-devel + BuildRequires: glibc-devel, libtool, libtool-ltdl-devel, groff, perl, perl-devel, perl(ExtUtils::Embed) + # smbk5pwd overlay: +@@ -215,6 +218,9 @@ AUTOMAKE=%{_bindir}/true autoreconf -fi + + %patch102 -p1 + ++# WRS ++%patch200 -p1 ++ + # build smbk5pwd with other overlays + ln -s ../../../contrib/slapd-modules/smbk5pwd/smbk5pwd.c servers/slapd/overlays + mv contrib/slapd-modules/smbk5pwd/README contrib/slapd-modules/smbk5pwd/README.smbk5pwd +@@ -338,12 +344,12 @@ install -d -m 740 %{buildroot}%{_sysconfdir}/openldap + cat > %{buildroot}%{_sysconfdir}/openldap/check_password.conf < +Date: Mon, 15 Jan 2018 13:59:26 -0500 +Subject: [PATCH 1/1] remove-ldap-conf-cgcs-file + +--- + SPECS/openldap.spec | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/SPECS/openldap.spec b/SPECS/openldap.spec +index 50bb499..50937c0 100644 +--- a/SPECS/openldap.spec ++++ b/SPECS/openldap.spec +@@ -25,7 +25,6 @@ Source54: libexec-create-certdb.sh + Source55: libexec-generate-server-cert.sh + + # WRS: +-Source56: ldap.conf.cgcs + Source57: slapd.conf.cgcs + Source58: initial_config.ldif + Source60: initscript +@@ -446,7 +445,7 @@ rm -f %{buildroot}%{_localstatedir}/openldap-data/DB_CONFIG.example + rmdir %{buildroot}%{_localstatedir}/openldap-data + + # WRS: slapd-config is backward compatible with slapd.conf +-install -m 600 %{SOURCE56} %{buildroot}%{_sysconfdir}/openldap/ldap.conf ++# WRS: SOURCE56 (ldap.conf.cgcs) is replaced by puppet template + install -m 600 %{SOURCE57} %{buildroot}%{_sysconfdir}/openldap/slapd.conf + install -m 600 %{SOURCE58} %{buildroot}%{_sysconfdir}/openldap/initial_config.ldif + +-- +1.8.3.1 + diff --git a/networking/openldap/centos/meta_patches/openldap-service-file.patch b/networking/openldap/centos/meta_patches/openldap-service-file.patch new file mode 100644 index 000000000..ee93a5a2c --- /dev/null +++ b/networking/openldap/centos/meta_patches/openldap-service-file.patch @@ -0,0 +1,42 @@ +From 4e88d0be6ebdd48f3d66840de5f142a660b8045a Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:11:21 -0400 +Subject: [PATCH 2/5] WRS: openldap-service-file.patch + +--- + SOURCES/slapd.service | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/SOURCES/slapd.service b/SOURCES/slapd.service +index 8a3a722..24b3938 100644 +--- a/SOURCES/slapd.service ++++ b/SOURCES/slapd.service +@@ -1,6 +1,7 @@ + [Unit] + Description=OpenLDAP Server Daemon +-After=syslog.target network-online.target ++Before=rsyncd.service ++After=network.target syslog-ng.target + Documentation=man:slapd + Documentation=man:slapd-config + Documentation=man:slapd-hdb +@@ -9,11 +10,14 @@ Documentation=file:///usr/share/doc/openldap-servers/guide.html + + [Service] + Type=forking +-PIDFile=/var/run/openldap/slapd.pid ++PIDFile=/var/run/slapd.pid + Environment="SLAPD_URLS=ldap:/// ldapi:///" "SLAPD_OPTIONS=" + EnvironmentFile=/etc/sysconfig/slapd + ExecStartPre=/usr/libexec/openldap/check-config.sh +-ExecStart=/usr/sbin/slapd -u ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS ++ExecStart=/etc/init.d/openldap start ++ExecStop=/etc/init.d/openldap stop ++ExecReload=/etc/init.d/openldap restart ++RemainAfterExit=yes + + [Install] + WantedBy=multi-user.target +-- +1.9.1 + diff --git a/networking/openldap/centos/meta_patches/openldap-spec-file.patch b/networking/openldap/centos/meta_patches/openldap-spec-file.patch new file mode 100644 index 000000000..b937cfb23 --- /dev/null +++ b/networking/openldap/centos/meta_patches/openldap-spec-file.patch @@ -0,0 +1,116 @@ +From cf6357eb12c87dd70fc675b9d0420234eb0317db Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:11:21 -0400 +Subject: [PATCH 1/5] WRS: openldap-spec-file.patch + +Conflicts: + SPECS/openldap.spec +--- + SPECS/openldap.spec | 33 ++++++++++++++++++++++++++++----- + 1 file changed, 28 insertions(+), 5 deletions(-) + +diff --git a/SPECS/openldap.spec b/SPECS/openldap.spec +index d8dbcbf..5121f8a 100644 +--- a/SPECS/openldap.spec ++++ b/SPECS/openldap.spec +@@ -24,6 +24,12 @@ Source53: libexec-upgrade-db.sh + Source54: libexec-create-certdb.sh + Source55: libexec-generate-server-cert.sh + ++# WRS: ++Source56: ldap.conf.cgcs ++Source57: slapd.conf.cgcs ++Source58: initial_config.ldif ++Source60: initscript ++ + # patches for 2.4 + Patch0: openldap-manpages.patch + Patch1: openldap-ppolicy-loglevels.patch +@@ -276,9 +282,11 @@ pushd openldap-%{version} + --enable-backends=mod \ + --enable-bdb=yes \ + --enable-hdb=yes \ +- --enable-mdb=yes \ ++ --enable-mdb=mod \ + --enable-monitor=yes \ + --disable-ndb \ ++ --enable-syncprov=mod \ ++ --enable-ppolicy=mod \ + \ + --enable-overlays=mod \ + \ +@@ -326,7 +334,7 @@ mv check_password.so check_password.so.%{check_password_version} + ln -s check_password.so.%{check_password_version} %{buildroot}%{_libdir}/openldap/check_password.so + install -m 755 check_password.so.%{check_password_version} %{buildroot}%{_libdir}/openldap/ + # install -m 644 README %{buildroot}%{_libdir}/openldap +-install -d -m 755 %{buildroot}%{_sysconfdir}/openldap ++install -d -m 740 %{buildroot}%{_sysconfdir}/openldap + cat > %{buildroot}%{_sysconfdir}/openldap/check_password.conf <&/dev/null || : +@@ -461,6 +478,7 @@ exit 0 + %post servers + + /sbin/ldconfig -n %{_libdir}/openldap ++mkdir -p /var/lib/openldap-data + + %systemd_post slapd.service + +@@ -471,7 +489,6 @@ exit 0 + if [ ! -f %{_sysconfdir}/openldap/slapd.d/cn=config.ldif ]; then + if [ -f %{_sysconfdir}/openldap/slapd.conf ]; then + %{_libexecdir}/openldap/convert-config.sh &>/dev/null +- mv %{_sysconfdir}/openldap/slapd.conf %{_sysconfdir}/openldap/slapd.conf.bak + else + %{_libexecdir}/openldap/convert-config.sh -f %{_datadir}/openldap-servers/slapd.ldif &>/dev/null + fi +@@ -615,6 +632,7 @@ exit 0 + %dir %attr(0700,ldap,ldap) %{_sharedstatedir}/ldap + %dir %attr(-,ldap,ldap) %{_localstatedir}/run/openldap + %{_unitdir}/slapd.service ++%{_sysconfdir}/rc.d/init.d/openldap + %{_datadir}/openldap-servers/ + %{_libdir}/openldap/accesslog* + %{_libdir}/openldap/auditlog* +@@ -661,8 +679,13 @@ exit 0 + %{_mandir}/man5/slapd*.5* + %{_mandir}/man5/slapo-*.5* + # obsolete configuration +-%ghost %config(noreplace,missingok) %attr(0640,ldap,ldap) %{_sysconfdir}/openldap/slapd.conf +-%ghost %config(noreplace,missingok) %attr(0640,ldap,ldap) %{_sysconfdir}/openldap/slapd.conf.bak ++# %ghost %config(noreplace,missingok) %attr(0640,ldap,ldap) %{_sysconfdir}/openldap/slapd.conf ++# %ghost %config(noreplace,missingok) %attr(0640,ldap,ldap) %{_sysconfdir}/openldap/slapd.conf.bak ++ ++# WRS ++%{_libdir}/openldap/back_mdb* ++%{_sysconfdir}/openldap/slapd.conf ++%{_sysconfdir}/openldap/initial_config.ldif + + %files servers-sql + %doc openldap-%{version}/servers/slapd/back-sql/docs/* +-- +1.9.1 + diff --git a/networking/openldap/centos/meta_patches/openldap-sysconfig-file.patch b/networking/openldap/centos/meta_patches/openldap-sysconfig-file.patch new file mode 100644 index 000000000..080162fe7 --- /dev/null +++ b/networking/openldap/centos/meta_patches/openldap-sysconfig-file.patch @@ -0,0 +1,25 @@ +From 9771ea4fdcbea1f4124564654b0541dcb8ccf780 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:11:21 -0400 +Subject: [PATCH 3/5] WRS: openldap-sysconfig-file.patch + +--- + SOURCES/slapd.sysconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SOURCES/slapd.sysconfig b/SOURCES/slapd.sysconfig +index 68091a5..573486d 100644 +--- a/SOURCES/slapd.sysconfig ++++ b/SOURCES/slapd.sysconfig +@@ -9,7 +9,7 @@ + SLAPD_URLS="ldapi:/// ldap:///" + + # Any custom options +-#SLAPD_OPTIONS="" ++SLAPD_OPTIONS="" + + # Keytab location for GSSAPI Kerberos authentication + #KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab" +-- +1.9.1 + diff --git a/networking/openldap/centos/srpm_path b/networking/openldap/centos/srpm_path new file mode 100644 index 000000000..fd5eb5036 --- /dev/null +++ b/networking/openldap/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/openldap-2.4.44-5.el7.src.rpm diff --git a/networking/openldap/files/initial_config.ldif b/networking/openldap/files/initial_config.ldif new file mode 100644 index 000000000..672e364b5 --- /dev/null +++ b/networking/openldap/files/initial_config.ldif @@ -0,0 +1,80 @@ +#ldapadd -D "cn=ldapadmin,dc=cgcs,dc=local" -W -f /etc/openldap/initial_config.ldif +#ldapsearch -x -b 'dc=cgcs,dc=local' '(objectclass=*)' +dn: dc=cgcs,dc=local +dc: cgcs +objectClass: top +objectClass: domain + +dn: ou=policies,dc=cgcs,dc=local +ou: policies +objectClass: top +objectClass: organizationalUnit + +dn: ou=People,dc=cgcs,dc=local +ou: People +objectClass: top +objectClass: organizationalUnit + +dn: ou=Group,dc=cgcs,dc=local +ou: Group +objectClass: top +objectClass: organizationalUnit + +dn: ou=SUDOers,dc=cgcs,dc=local +objectClass: top +objectClass: organizationalUnit +ou: SUDOers + +dn: cn=users,ou=Group,dc=cgcs,dc=local +objectClass: posixGroup +objectClass: top +cn: users +userPassword: {crypt}x +gidNumber: 100 + +dn: cn=cgcs,ou=Group,dc=cgcs,dc=local +objectClass: posixGroup +objectClass: top +cn: cgcs +userPassword: {crypt}x +gidNumber: 1000 + +dn: cn=default,ou=policies,dc=cgcs,dc=local +objectClass: top +objectClass: device +objectClass: pwdPolicy +objectClass: pwdPolicyChecker +cn: default +pwdAttribute: userPassword +pwdMaxAge: 0 +pwdExpireWarning: 432000 +pwdInHistory: 2 +pwdCheckModule: check_password.so +pwdCheckQuality: 1 +pwdMinLength: 7 +pwdMaxFailure: 5 +pwdLockout: TRUE +pwdLockoutDuration: 300 +pwdFailureCountInterval: 0 +pwdMustChange: TRUE +pwdAllowUserChange: TRUE +pwdSafeModify: FALSE +pwdGraceAuthNLimit: 0 + +dn: cn=defaults,ou=SUDOers,dc=cgcs,dc=local +objectClass: top +objectClass: sudoRole +cn: defaults +description: Default sudoOption's go here +sudoOrder: 1 + +dn: cn=admin,ou=SUDOers,dc=cgcs,dc=local +objectClass: top +objectClass: sudoRole +cn: admin +sudoUser: admin +sudoHost: ALL +sudoRunAsUser: ALL +sudoCommand: ALL +sudoOrder: 2 +sudoOption: secure_path=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin diff --git a/networking/openldap/files/initscript b/networking/openldap/files/initscript new file mode 100755 index 000000000..8c5c2035c --- /dev/null +++ b/networking/openldap/files/initscript @@ -0,0 +1,116 @@ +#! /bin/sh +# +# This is an init script for openembedded +# Copy it to /etc/init.d/openldap and type +# > update-rc.d openldap defaults 60 +# +. /etc/init.d/functions + +################################################################################ +# Wait for a process to stop running. +# +################################################################################ +function wait_for_proc_stop() +{ + PROGNAME=$1 + TIMEOUT=${2:-"5"} + + for I in $(seq 1 $TIMEOUT); do + PID=$(pidof $PROGNAME 2> /dev/null) + if [ $? -ne 0 ]; then + ## already dead + return 0 + fi + sleep 1 + done + + return 1 +} + +slapd=/usr/sbin/slapd +test -x "$slapd" || exit 0 + +RETVAL=0 + +case "$1" in + start) + echo -n "Starting SLAPD: " + if [ -f /etc/openldap/schema/cn=config.ldif ]; then + start-stop-daemon --start --oknodo --quiet --exec $slapd \ + -- -F /etc/openldap/schema/ + RETVAL=$? + else + start-stop-daemon --start --oknodo --quiet --exec $slapd + RETVAL=$? + fi + if [ $RETVAL -ne 0 ]; then + echo "Failed to start SLAPD." + exit $RETVAL + fi + + # we need to start nslcd and nscd services as part of this openldap + # init.d script since SM manages this as a service and all three + # daemons should be running on a controller host + systemctl status nscd.service + if [ $? -ne 0 ]; then + echo -n "Starting NSCD: " + systemctl start nscd.service + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + echo "Failed to start NSCD." + exit $RETVAL + fi + fi + + systemctl status nslcd.service + if [ $? -ne 0 ]; then + echo -n "Starting NSLCD: " + systemctl start nslcd.service + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + echo "Failed to start NSLCD." + fi + fi + + echo "." + ;; + stop) + echo -n "Stopping NSCD: " + systemctl stop nscd.service + rm -f /var/run/nscd/nscd.pid + + echo -n "Stopping NSLCD: " + systemctl stop nslcd.service + rm -f /var/run/nslcd/nslcd.pid + + echo -n "Stopping SLAPD: " + start-stop-daemon --retry 60 --stop --oknodo --quiet --pidfile /var/run/slapd.pid + RETVAL=$? + wait_for_proc_stop $slapd 10 + WRETVAL=$? + while [ $WRETVAL -eq 1 ]; do + killproc $slapd + wait_for_proc_stop $slapd 10 + WRETVAL=$? + done + rm -f /var/run/slapd.pid + echo "." + ;; + status) + status $slapd + [ $? -eq 0 ] || exit $? + systemctl status nscd.service + [ $? -eq 0 ] || exit $? + systemctl status nslcd.service + RETVAL=$? + ;; + restart) + $0 stop + $0 start + ;; + *) + echo "Usage: /etc/init.d/openldap {start|stop|status|restart}" + exit 1 +esac + +exit $RETVAL diff --git a/networking/openldap/files/rootdn-should-not-bypass-ppolicy.patch b/networking/openldap/files/rootdn-should-not-bypass-ppolicy.patch new file mode 100644 index 000000000..b57246fc0 --- /dev/null +++ b/networking/openldap/files/rootdn-should-not-bypass-ppolicy.patch @@ -0,0 +1,43 @@ +From 9456b0eee753d9fd368347b6974a2f6f8d941d4f Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Tue, 11 Apr 2017 17:23:03 -0400 +Subject: [PATCH] rootdn should not bypass ppolicy + +--- + servers/slapd/overlays/ppolicy.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c +index b446deb..fa79872 100644 +--- a/servers/slapd/overlays/ppolicy.c ++++ b/servers/slapd/overlays/ppolicy.c +@@ -1904,8 +1904,9 @@ ppolicy_modify( Operation *op, SlapReply *rs ) + } + for(p=tl; p; p=p->next, hsize++); /* count history size */ + } +- +- if (be_isroot( op )) goto do_modify; ++ ++ /* WRS UPDATE: Run ppolicy for all user password modify ops */ ++ //if (be_isroot( op )) goto do_modify; + + /* NOTE: according to draft-behera-ldap-password-policy + * pwdAllowUserChange == FALSE must only prevent pwd changes +@@ -2009,7 +2010,13 @@ ppolicy_modify( Operation *op, SlapReply *rs ) + } + + bv = newpw.bv_val ? &newpw : &addmod->sml_values[0]; +- if (pp.pwdCheckQuality > 0) { ++ ++ /* WRS UPDATE: ++ * If this is a rootDN op and this is the first password ++ * then bypass password policies as this is a new account ++ * creation ++ */ ++ if (pp.pwdCheckQuality > 0 && !(be_isroot( op ) && !pa)) { + + rc = check_password_quality( bv, &pp, &pErr, e, (char **)&txt ); + if (rc != LDAP_SUCCESS) { +-- +1.9.1 + diff --git a/networking/openldap/files/slapd.conf.cgcs b/networking/openldap/files/slapd.conf.cgcs new file mode 100644 index 000000000..3b6fcc545 --- /dev/null +++ b/networking/openldap/files/slapd.conf.cgcs @@ -0,0 +1,117 @@ +# +# See slapd.conf(5) for details on configuration options. +# This file should NOT be world readable. +# +include /etc/openldap/schema/core.schema +include /etc/openldap/schema/cosine.schema +include /etc/openldap/schema/inetorgperson.schema +include /etc/openldap/schema/nis.schema +include /etc/openldap/schema/ppolicy.schema +include /etc/openldap/schema/sudo.schema + +# Define global ACLs to disable default read access. + +# Do not enable referrals until AFTER you have a working directory +# service AND an understanding of referrals. +#referral ldap://root.openldap.org + +pidfile /var/run/slapd.pid +argsfile /var/run/slapd.args + +# uniquely identifies this server +serverID 001 + +# Load dynamic backend modules: +modulepath /usr/libexec/openldap +moduleload back_mdb.la +moduleload ppolicy.la +moduleload syncprov.la + +# Sample security restrictions +# Require integrity protection (prevent hijacking) +# Require 112-bit (3DES or better) encryption for updates +# Require 63-bit encryption for simple bind +# security ssf=1 update_ssf=112 simple_bind=64 + +# Sample access control policy: +# Root DSE: allow anyone to read it +# Subschema (sub)entry DSE: allow anyone to read it +# Other DSEs: +# Allow self write access +# Allow authenticated users read access +# Allow anonymous users to authenticate +# Directives needed to implement policy: +#access to dn.base="" by * read +#access to dn.base="cn=Subschema" by * read +#access to * +# by self write +# by anonymous auth +# by * read +# +# if no access controls are present, the default policy +# allows anyone and everyone to read anything but restricts +# updates to rootdn. (e.g., "access to * by * read") +# +# rootdn can always read and write EVERYTHING! + +####################################################################### +# BDB database definitions +####################################################################### + +database mdb +suffix "dc=cgcs,dc=local" +rootdn "cn=ldapadmin,dc=cgcs,dc=local" +# Cleartext passwords, especially for the rootdn, should +# be avoid. See slappasswd(8) and slapd.conf(5) for details. +# Use of strong authentication encouraged. +rootpw _LDAPADMIN_PW_ +# The database directory MUST exist prior to running slapd AND +# should only be accessible by the slapd and slap tools. +# Mode 700 recommended. +directory /var/lib/openldap-data +# Maximum size +maxsize 1073741824 +# Indices to maintain +index cn eq +index objectClass eq +index uid eq,pres,sub +index uidNumber eq +index gidNumber eq +index memberUid eq +index sudoUser eq,sub + +access to * + by self write + by * read + +loglevel none + +overlay ppolicy +ppolicy_default "cn=default,ou=policies,dc=cgcs,dc=local" +ppolicy_use_lockout + +# NOTE: +# syncrepl directives for each of the other masters +syncrepl rid=000 + provider=ldap://controller-1 + type=refreshAndPersist + retry="5 5 300 +" + searchbase="dc=cgcs,dc=local" + attrs="*,+" + bindmethod=simple + binddn="cn=ldapadmin,dc=cgcs,dc=local" + credentials=_LDAPADMIN_PW_ + +# syncprov specific indexing (add others as required) +index entryCSN eq +index entryUUID eq +# ... +# # mirror mode essential to allow writes +# # and must appear after all syncrepl directives +mirrormode TRUE +# +# # define the provider to use the syncprov overlay +# # (last directives in database section) +overlay syncprov +# # contextCSN saved to database every 100 updates or ten minutes +syncprov-checkpoint 1 1 diff --git a/networking/openvswitch/centos/build_srpm.data b/networking/openvswitch/centos/build_srpm.data new file mode 100644 index 000000000..f1c5fba8b --- /dev/null +++ b/networking/openvswitch/centos/build_srpm.data @@ -0,0 +1,4 @@ +COPY_LIST="$CGCS_BASE/downloads/openvswitch-2.8.1.tar.gz \ + $CGCS_BASE/downloads/dpdk-17.05.2.tar.gz \ + patches/*" +TIS_PATCH_VER=1 diff --git a/networking/openvswitch/centos/openvswitch.spec b/networking/openvswitch/centos/openvswitch.spec new file mode 100644 index 000000000..266b7fdb8 --- /dev/null +++ b/networking/openvswitch/centos/openvswitch.spec @@ -0,0 +1,1009 @@ +# Uncomment these for snapshot releases: +# snapshot is the date YYYYMMDD of the snapshot +# snap_git is the 8 git sha digits of the last commit +# Use ovs-snapshot.sh to create the tarball. +#% define snapshot .git20150730 +#% define snap_gitsha -git72bfa562 + +# If wants to run tests while building, specify the '--with check' +# option. For example: +# rpmbuild -bb --with check openvswitch.spec + +# To disable DPDK support, specify '--without dpdk' when building +%bcond_without dpdk +%bcond_without dpdkstatic + +# test-suite is broken for big endians +# https://bugzilla.redhat.com/show_bug.cgi?id=1105458#c10 +# "ofproto-dpif - select group with dp_hash selection method" test is broken on arm +%ifnarch ppc ppc64 ppc64p7 s390 s390x armv7hl +# wordaround(LLU) - 'make check' failed in mockchain environment, but succeeded in mock, +# needs to investigate why +%bcond_with check +%else +%bcond_with check +%endif + +# option to build with libcap-ng, needed for running OVS as regular user +%bcond_without libcapng + +# Enable PIE, bz#955181 +%global _hardened_build 1 + +%define dpdkver 17.05.2 +%define dpdkdir dpdk-stable +%define dpdksver %(echo %{dpdkver} | cut -d. -f-2) + +Name: openvswitch +Version: 2.8.1 +Release: 3%{?_tis_dist}.%{tis_patch_ver} +Summary: Open vSwitch daemon/database/utilities + +# Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the +# lib/sflow*.[ch] files are SISSL +# datapath/ is GPLv2 (although not built into any of the binary packages) +License: ASL 2.0 and LGPLv2+ and SISSL +URL: http://openvswitch.org +Source0: http://openvswitch.org/releases/%{name}-%{version}%{?snap_gitsha}.tar.gz +Source1: http://fast.dpdk.org/rel/dpdk-%{dpdkver}.tar.gz +#Source2: ovs-snapshot.sh + +%if %{with dpdk} +Patch1: ovs-vswitchd.system.service.patch +%endif + +%if %{with dpdk} +%define dpdkarches x86_64 i686 aarch64 ppc64le + +# machine_arch maps between rpm and dpdk arch name, often same as _target_cpu +# machine_tmpl is the config template machine name, often "native" +# machine is the actual machine name used in the dpdk make system +%ifarch x86_64 +%define machine_arch x86_64 +%define machine_tmpl native +%define machine default +%endif +%ifarch i686 +%define machine_arch i686 +%define machine_tmpl native +%define machine atm +%endif +%ifarch aarch64 +%define machine_arch arm64 +%define machine_tmpl armv8a +%define machine armv8a +%endif +%ifarch ppc64le +%define machine_arch ppc_64 +%define machine_tmpl power8 +%define machine power8 +%endif + +%define dpdktarget %{machine_arch}-%{machine_tmpl}-linuxapp-gcc +%endif +ExcludeArch: ppc + +BuildRequires: python-sphinx +BuildRequires: autoconf automake libtool +BuildRequires: systemd-units openssl openssl-devel +BuildRequires: python2-devel python2-six +BuildRequires: desktop-file-utils +BuildRequires: groff graphviz +# make check dependencies +%if %{with check} +BuildRequires: python2-twisted python-zope-interface +BuildRequires: procps-ng +%endif +%if %{with dpdk} +%ifarch %{dpdkarches} +# DPDK driver dependencies +%if %{with dpdkstatic} +BuildRequires: libpcap-devel numactl-devel +%else +BuildRequires: libpcap-devel numactl-devel dpdk-devel +%endif +%endif +%endif + +%if %{with libcapng} +BuildRequires: libcap-ng libcap-ng-devel +%endif + +Requires: openssl iproute module-init-tools +#Upstream kernel commit 4f647e0a3c37b8d5086214128614a136064110c3 +#Requires: kernel >= 3.15.0-0 +%if %{with dpdk} +%ifarch %{dpdkarches} +%if %{with dpdkstatic} +%else +Requires: dpdk +%endif +%endif +%endif + +Requires(post): /usr/bin/getent +Requires(post): /usr/sbin/useradd +Requires(post): /bin/sed +Requires(post): /usr/sbin/usermod +Requires(post): /usr/sbin/groupadd +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units +Obsoletes: openvswitch-controller <= 0:2.1.0-1 + +%description +Open vSwitch provides standard network bridging functions and +support for the OpenFlow protocol for remote per-flow control of +traffic. + +%package -n python2-openvswitch +Summary: Open vSwitch python2 bindings +License: ASL 2.0 +BuildArch: noarch +Requires: python2 python2-six +Obsoletes: python-openvswitch < 2.6.1-2 +Provides: python-openvswitch = %{version}-%{release} + +%description -n python2-openvswitch +Python bindings for the Open vSwitch database + +%package test +Summary: Open vSwitch testing utilities +License: ASL 2.0 +BuildArch: noarch +Requires: python2-openvswitch = %{version}-%{release} +Requires: python2 python2-twisted + +%description test +Utilities that are useful to diagnose performance and connectivity +issues in Open vSwitch setup. + +%package devel +Summary: Open vSwitch OpenFlow development package (library, headers) +License: ASL 2.0 +Provides: openvswitch-static = %{version}-%{release} + +%description devel +This provides static library, libopenswitch.a and the openvswitch header +files needed to build an external application. + +%package ovn-central +Summary: Open vSwitch - Open Virtual Network support +License: ASL 2.0 +Requires: openvswitch openvswitch-ovn-common +Requires: firewalld-filesystem + +%description ovn-central +OVN, the Open Virtual Network, is a system to support virtual network +abstraction. OVN complements the existing capabilities of OVS to add +native support for virtual network abstractions, such as virtual L2 and L3 +overlays and security groups. + +%package ovn-host +Summary: Open vSwitch - Open Virtual Network support +License: ASL 2.0 +Requires: openvswitch openvswitch-ovn-common +Requires: firewalld-filesystem + +%description ovn-host +OVN, the Open Virtual Network, is a system to support virtual network +abstraction. OVN complements the existing capabilities of OVS to add +native support for virtual network abstractions, such as virtual L2 and L3 +overlays and security groups. + +%package ovn-vtep +Summary: Open vSwitch - Open Virtual Network support +License: ASL 2.0 +Requires: openvswitch openvswitch-ovn-common + +%description ovn-vtep +OVN vtep controller + +%package ovn-common +Summary: Open vSwitch - Open Virtual Network support +License: ASL 2.0 +Requires: openvswitch + +%description ovn-common +Utilities that are use to diagnose and manage the OVN components. + +%package ovn-docker +Summary: Open vSwitch - Open Virtual Network support +License: ASL 2.0 +Requires: openvswitch openvswitch-ovn-common python2-openvswitch + +%description ovn-docker +Docker network plugins for OVN. + +%prep +%autosetup -n %{name}-%{version}%{?snap_gitsha} -a 1 -p 1 + +%build +%if %{with dpdk} +%ifarch %{dpdkarches} +%if %{with dpdkstatic} +# Lets build DPDK first +cd %{dpdkdir}-%{dpdkver} +function setconf() +{ + cf=%{dpdktarget}/.config + if grep -q $1 $cf; then + sed -i "s:^$1=.*$:$1=$2:g" $cf + else + echo $1=$2 >> $cf + fi +} + +# In case dpdk-devel is installed +unset RTE_SDK RTE_INCLUDE RTE_TARGET + +# Avoid appending second -Wall to everything, it breaks upstream warning +# disablers in makefiles. Strip explicit -march= from optflags since they +# will only guarantee build failures, DPDK is picky with that. +export EXTRA_CFLAGS="$(echo %{optflags} | sed -e 's:-Wall::g' -e 's:-march=[[:alnum:]]* ::g') -Wformat -fPIC" + +# DPDK defaults to using builder-specific compiler flags. However, +# the config has been changed by specifying CONFIG_RTE_MACHINE=default +# in order to build for a more generic host. NOTE: It is possible that +# the compiler flags used still won't work for all Fedora-supported +# machines, but runtime checks in DPDK will catch those situations. + +make V=1 O=%{dpdktarget} T=%{dpdktarget} %{?_smp_mflags} config + +# DPDK defaults to optimizing for the builder host we need generic binaries +setconf CONFIG_RTE_MACHINE '"%{machine}"' + +# Disable DPDK libraries not needed by OVS +setconf CONFIG_RTE_LIBRTE_TIMER n +setconf CONFIG_RTE_LIBRTE_CFGFILE n +setconf CONFIG_RTE_LIBRTE_JOBSTATS n +setconf CONFIG_RTE_LIBRTE_LPM n +setconf CONFIG_RTE_LIBRTE_ACL n +setconf CONFIG_RTE_LIBRTE_POWER n +setconf CONFIG_RTE_LIBRTE_DISTRIBUTOR n +setconf CONFIG_RTE_LIBRTE_REORDER n +setconf CONFIG_RTE_LIBRTE_PORT n +setconf CONFIG_RTE_LIBRTE_TABLE n +setconf CONFIG_RTE_LIBRTE_PIPELINE n +setconf CONFIG_RTE_LIBRTE_KNI n +setconf CONFIG_RTE_LIBRTE_CRYPTODEV n + +# Disable DPDK applications not needed by OVS +setconf CONFIG_RTE_APP_TEST n +setconf CONFIG_RTE_APP_CRYPTO_PERF n + +# Enable DPDK libraries needed by OVS +setconf CONFIG_RTE_LIBRTE_VHOST_NUMA y +setconf CONFIG_RTE_LIBRTE_PMD_PCAP y + +# Disable PMDs that are either not needed or not stable +setconf CONFIG_RTE_LIBRTE_PMD_VHOST n +setconf CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO n +# BNX2X driver is not stable +setconf CONFIG_RTE_LIBRTE_BNX2X_PMD n + +# Disable virtio user as not used by OVS +setconf CONFIG_RTE_VIRTIO_USER n + +# Disable kernel modules +setconf CONFIG_RTE_EAL_IGB_UIO n +setconf CONFIG_RTE_KNI_KMOD n + +# Disable experimental stuff +setconf CONFIG_RTE_NEXT_ABI n + +# Disable some PMDs on fdProd +setconf CONFIG_RTE_LIBRTE_BNXT_PMD n +setconf CONFIG_RTE_LIBRTE_ENA_PMD n +setconf CONFIG_RTE_LIBRTE_QEDE_PMD n + +make V=1 O=%{dpdktarget} %{?_smp_mflags} + +# Generate a list of supported drivers, its hard to tell otherwise. +cat << EOF > README.DPDK-PMDS +DPDK drivers included in this package: + +EOF + +for f in $(ls %{machine_arch}-%{machine_tmpl}-linuxapp-gcc/lib/lib*_pmd_*); do + basename ${f} | cut -c12- | cut -d. -f1 | tr [:lower:] [:upper:] +done >> README.DPDK-PMDS + +cat << EOF >> README.DPDK-PMDS + +For further information about the drivers, see +http://dpdk.org/doc/guides-%{dpdksver}/nics/index.html +EOF + +cd - +%endif +%endif +%endif + +%if 0%{?snap_gitsha:1} +# fix the snapshot unreleased version to be the released one. +sed -i.old -e "s/^AC_INIT(openvswitch,.*,/AC_INIT(openvswitch, %{version},/" configure.ac +./boot.sh +%endif + +%configure \ +%if %{with libcapng} + --enable-libcapng \ +%else + --disable-libcapng \ +%endif + --enable-ssl \ +%if %{with dpdk} +%ifarch %{dpdkarches} +%if %{with dpdkstatic} + --with-dpdk=$(pwd)/%{dpdkdir}-%{dpdkver}/%{dpdktarget} \ +%else + --with-dpdk=/usr \ +%endif +%endif +%endif + --with-pkidir=%{_sharedstatedir}/openvswitch/pki +/usr/bin/perl build-aux/dpdkstrip.pl \ + --dpdk \ + < rhel/usr_lib_systemd_system_ovs-vswitchd.service.in \ + > rhel/usr_lib_systemd_system_ovs-vswitchd.service +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT + +%if %{with dpdk} +%ifarch %{dpdkarches} +# install dpdk usertools + install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/openvswitch/dpdk-usertools +%if %{with dpdkstatic} + install -p -m 0755 $(pwd)/%{dpdkdir}-%{dpdkver}/usertools/* $RPM_BUILD_ROOT%{_datadir}/openvswitch/dpdk-usertools +%else + install -p -m 0755 %{_datadir}/dpdk/usertools/* $RPM_BUILD_ROOT%{_datadir}/openvswitch/dpdk-usertools +%endif +%endif +%endif + +install -d -m 0755 $RPM_BUILD_ROOT%{_rundir}/openvswitch +install -d -m 0750 $RPM_BUILD_ROOT%{_localstatedir}/log/openvswitch +install -d -m 0755 $RPM_BUILD_ROOT%{_sysconfdir}/openvswitch + +install -p -D -m 0644 rhel/usr_lib_udev_rules.d_91-vfio.rules \ + $RPM_BUILD_ROOT%{_udevrulesdir}/91-vfio.rules + +install -p -D -m 0644 \ + rhel/usr_share_openvswitch_scripts_systemd_sysconfig.template \ + $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/openvswitch +for service in openvswitch ovsdb-server ovs-vswitchd \ + ovn-controller ovn-controller-vtep ovn-northd; do + install -p -D -m 0644 \ + rhel/usr_lib_systemd_system_${service}.service \ + $RPM_BUILD_ROOT%{_unitdir}/${service}.service +done + +install -m 0755 rhel/etc_init.d_openvswitch \ + $RPM_BUILD_ROOT%{_datadir}/openvswitch/scripts/openvswitch.init + +install -p -D -m 0644 rhel/etc_openvswitch_default.conf \ + $RPM_BUILD_ROOT/%{_sysconfdir}/openvswitch/default.conf + +install -p -D -m 0644 rhel/etc_logrotate.d_openvswitch \ + $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d/openvswitch + +install -m 0644 vswitchd/vswitch.ovsschema \ + $RPM_BUILD_ROOT/%{_datadir}/openvswitch/vswitch.ovsschema + +install -d -m 0755 $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/network-scripts/ +install -p -m 0755 rhel/etc_sysconfig_network-scripts_ifdown-ovs \ + $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/network-scripts/ifdown-ovs +install -p -m 0755 rhel/etc_sysconfig_network-scripts_ifup-ovs \ + $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/network-scripts/ifup-ovs + +install -d -m 0755 $RPM_BUILD_ROOT%{python2_sitelib} +cp -a $RPM_BUILD_ROOT/%{_datadir}/openvswitch/python/* \ + $RPM_BUILD_ROOT%{python2_sitelib} +rm -rf $RPM_BUILD_ROOT/%{_datadir}/openvswitch/python/ + +install -d -m 0755 $RPM_BUILD_ROOT/%{_sharedstatedir}/openvswitch + +install -d -m 0755 $RPM_BUILD_ROOT%{_prefix}/lib/firewalld/services/ +install -p -m 0644 rhel/usr_lib_firewalld_services_ovn-central-firewall-service.xml \ + $RPM_BUILD_ROOT%{_prefix}/lib/firewalld/services/ovn-central-firewall-service.xml +install -p -m 0644 rhel/usr_lib_firewalld_services_ovn-host-firewall-service.xml \ + $RPM_BUILD_ROOT%{_prefix}/lib/firewalld/services/ovn-host-firewall-service.xml + +install -d -m 0755 $RPM_BUILD_ROOT%{_prefix}/lib/ocf/resource.d/ovn +ln -s %{_datadir}/openvswitch/scripts/ovndb-servers.ocf \ + $RPM_BUILD_ROOT%{_prefix}/lib/ocf/resource.d/ovn/ovndb-servers + +touch $RPM_BUILD_ROOT%{_sysconfdir}/openvswitch/conf.db +touch $RPM_BUILD_ROOT%{_sysconfdir}/openvswitch/system-id.conf + +# remove unpackaged files +rm -f $RPM_BUILD_ROOT/%{_bindir}/ovs-benchmark \ + $RPM_BUILD_ROOT/%{_bindir}/ovs-parse-backtrace \ + $RPM_BUILD_ROOT/%{_sbindir}/ovs-vlan-bug-workaround \ + $RPM_BUILD_ROOT/%{_mandir}/man1/ovs-benchmark.1* \ + $RPM_BUILD_ROOT/%{_mandir}/man8/ovs-vlan-bug-workaround.8* \ + $RPM_BUILD_ROOT/%{_datadir}/openvswitch/scripts/ovs-save + +%check +%if %{with check} + if make check TESTSUITEFLAGS='%{_smp_mflags}' || + make check TESTSUITEFLAGS='--recheck'; then :; + else + cat tests/testsuite.log + exit 1 + fi +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%preun +%if 0%{?systemd_preun:1} + %systemd_preun %{name}.service +%else + if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable %{name}.service >/dev/null 2>&1 || : + /bin/systemctl stop %{name}.service >/dev/null 2>&1 || : + fi +%endif + +%preun ovn-central +%if 0%{?systemd_preun:1} + %systemd_preun ovn-northd.service +%else + if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable ovn-northd.service >/dev/null 2>&1 || : + /bin/systemctl stop ovn-northd.service >/dev/null 2>&1 || : + fi +%endif + +%preun ovn-host +%if 0%{?systemd_preun:1} + %systemd_preun ovn-controller.service +%else + if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable ovn-controller.service >/dev/null 2>&1 || : + /bin/systemctl stop ovn-controller.service >/dev/null 2>&1 || : + fi +%endif + +%preun ovn-vtep +%if 0%{?systemd_preun:1} + %systemd_preun ovn-controller-vtep.service +%else + if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable ovn-controller-vtep.service >/dev/null 2>&1 || : + /bin/systemctl stop ovn-controller-vtep.service >/dev/null 2>&1 || : + fi +%endif + +%post +if [ $1 -eq 1 ]; then + getent passwd openvswitch >/dev/null || \ + useradd -r -d / -s /sbin/nologin -c "Open vSwitch Daemons" openvswitch + + sed -i 's:^#OVS_USER_ID=:OVS_USER_ID=:' /etc/sysconfig/openvswitch + + getent group hugetlbfs >/dev/null || \ + groupadd hugetlbfs + usermod -a -G hugetlbfs openvswitch + sed -i \ + 's@OVS_USER_ID="openvswitch:openvswitch"@OVS_USER_ID="openvswitch:hugetlbfs"@'\ + /etc/sysconfig/openvswitch + + # In the case of upgrade, this is not needed. + chown -R openvswitch:openvswitch /etc/openvswitch +fi + +%if 0%{?systemd_post:1} + %systemd_post %{name}.service +%else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi +%endif + +%post ovn-central +%if 0%{?systemd_post:1} + %systemd_post ovn-northd.service +%else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi +%endif + +%post ovn-host +%if 0%{?systemd_post:1} + %systemd_post ovn-controller.service +%else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi +%endif + +%post ovn-vtep +%if 0%{?systemd_post:1} + %systemd_post ovn-controller-vtep.service +%else + # Package install, not upgrade + if [ $1 -eq 1 ]; then + /bin/systemctl daemon-reload >dev/null || : + fi +%endif +%postun ovn-central +%if 0%{?systemd_postun_with_restart:1} + %systemd_postun_with_restart ovn-northd.service +%else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + if [ "$1" -ge "1" ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart ovn-northd.service >/dev/null 2>&1 || : + fi +%endif + +%postun ovn-host +%if 0%{?systemd_postun_with_restart:1} + %systemd_postun_with_restart ovn-controller.service +%else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + if [ "$1" -ge "1" ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart ovn-controller.service >/dev/null 2>&1 || : + fi +%endif + +%postun ovn-vtep +%if 0%{?systemd_postun_with_restart:1} + %systemd_postun_with_restart ovn-controller-vtep.service +%else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + if [ "$1" -ge "1" ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart ovn-controller-vtep.service >/dev/null 2>&1 || : + fi +%endif + +%postun +%if 0%{?systemd_postun_with_restart:1} + %systemd_postun_with_restart %{name}.service +%else + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + if [ "$1" -ge "1" ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || : + fi +%endif + + +%files -n python2-openvswitch +%{python2_sitelib}/ovs +%doc COPYING + +%files test +%{_bindir}/ovs-test +%{_bindir}/ovs-vlan-test +%{_bindir}/ovs-l3ping +%{_bindir}/ovs-pcap +%{_bindir}/ovs-tcpdump +%{_bindir}/ovs-tcpundump +%{_mandir}/man8/ovs-test.8* +%{_mandir}/man8/ovs-vlan-test.8* +%{_mandir}/man8/ovs-l3ping.8* +%{_mandir}/man1/ovs-pcap.1* +%{_mandir}/man8/ovs-tcpdump.8* +%{_mandir}/man1/ovs-tcpundump.1* +%{python2_sitelib}/ovstest + +%files devel +%{_libdir}/*.a +%{_libdir}/*.la +%{_libdir}/pkgconfig/*.pc +%{_includedir}/openvswitch/* +%{_includedir}/openflow/* +%{_includedir}/ovn/* + +%files +%defattr(-,root,root) +%{_sysconfdir}/bash_completion.d/ovs-appctl-bashcomp.bash +%{_sysconfdir}/bash_completion.d/ovs-vsctl-bashcomp.bash +%dir %{_sysconfdir}/openvswitch +%{_sysconfdir}/openvswitch/default.conf +%config %ghost %{_sysconfdir}/openvswitch/conf.db +%config %ghost %{_sysconfdir}/openvswitch/system-id.conf +%config(noreplace) %{_sysconfdir}/sysconfig/openvswitch +%config(noreplace) %{_sysconfdir}/logrotate.d/openvswitch +%{_unitdir}/openvswitch.service +%{_unitdir}/ovs-vswitchd.service +%{_unitdir}/ovsdb-server.service +%{_datadir}/openvswitch/scripts/openvswitch.init +%{_sysconfdir}/sysconfig/network-scripts/ifup-ovs +%{_sysconfdir}/sysconfig/network-scripts/ifdown-ovs +%if %{with dpdk} +%ifarch %{dpdkarches} +%{_datadir}/openvswitch/dpdk-usertools +%endif +%endif +%{_datadir}/openvswitch/bugtool-plugins/ +%{_datadir}/openvswitch/scripts/ovs-bugtool-* +%{_datadir}/openvswitch/scripts/ovs-check-dead-ifs +%{_datadir}/openvswitch/scripts/ovs-lib +%{_datadir}/openvswitch/scripts/ovs-vtep +%{_datadir}/openvswitch/scripts/ovs-ctl +%config %{_datadir}/openvswitch/vswitch.ovsschema +%config %{_datadir}/openvswitch/vtep.ovsschema +%{_bindir}/ovs-appctl +%{_bindir}/ovs-docker +%{_bindir}/ovs-dpctl +%{_bindir}/ovs-dpctl-top +%{_bindir}/ovs-ofctl +%{_bindir}/ovs-vsctl +%{_bindir}/ovsdb-client +%{_bindir}/ovsdb-tool +%{_bindir}/ovs-testcontroller +%{_bindir}/ovs-pki +%{_bindir}/vtep-ctl +%{_sbindir}/ovs-bugtool +%{_sbindir}/ovs-vswitchd +%{_sbindir}/ovsdb-server +%{_mandir}/man1/ovsdb-client.1* +%{_mandir}/man1/ovsdb-server.1* +%{_mandir}/man1/ovsdb-tool.1* +%{_mandir}/man5/ovs-vswitchd.conf.db.5* +%{_mandir}/man5/vtep.5* +%{_mandir}/man7/ovs-fields.7* +%{_mandir}/man8/vtep-ctl.8* +%{_mandir}/man8/ovs-appctl.8* +%{_mandir}/man8/ovs-bugtool.8* +%{_mandir}/man8/ovs-ctl.8* +%{_mandir}/man8/ovs-dpctl.8* +%{_mandir}/man8/ovs-dpctl-top.8* +%{_mandir}/man8/ovs-ofctl.8* +%{_mandir}/man8/ovs-pki.8* +%{_mandir}/man8/ovs-vsctl.8* +%{_mandir}/man8/ovs-vswitchd.8* +%{_mandir}/man8/ovs-parse-backtrace.8* +%{_mandir}/man8/ovs-testcontroller.8* +%{_udevrulesdir}/91-vfio.rules +%doc COPYING NOTICE README.rst NEWS rhel/README.RHEL.rst +/var/lib/openvswitch +/var/log/openvswitch +%ghost %attr(755,root,root) %{_rundir}/openvswitch + +%files ovn-docker +%{_bindir}/ovn-docker-overlay-driver +%{_bindir}/ovn-docker-underlay-driver + +%files ovn-common +%{_bindir}/ovn-detrace +%{_bindir}/ovn-nbctl +%{_bindir}/ovn-sbctl +%{_bindir}/ovn-trace +%{_datadir}/openvswitch/scripts/ovn-ctl +%{_datadir}/openvswitch/scripts/ovndb-servers.ocf +%{_datadir}/openvswitch/scripts/ovn-bugtool-nbctl-show +%{_datadir}/openvswitch/scripts/ovn-bugtool-sbctl-lflow-list +%{_datadir}/openvswitch/scripts/ovn-bugtool-sbctl-show +%{_mandir}/man1/ovn-detrace.1* +%{_mandir}/man8/ovn-ctl.8* +%{_mandir}/man8/ovn-nbctl.8* +%{_mandir}/man8/ovn-trace.8* +%{_mandir}/man7/ovn-architecture.7* +%{_mandir}/man8/ovn-sbctl.8* +%{_mandir}/man5/ovn-nb.5* +%{_mandir}/man5/ovn-sb.5* +%{_prefix}/lib/ocf/resource.d/ovn/ovndb-servers + +%files ovn-central +%{_bindir}/ovn-northd +%{_mandir}/man8/ovn-northd.8* +%config %{_datadir}/openvswitch/ovn-nb.ovsschema +%config %{_datadir}/openvswitch/ovn-sb.ovsschema +%{_unitdir}/ovn-northd.service +%{_prefix}/lib/firewalld/services/ovn-central-firewall-service.xml + +%files ovn-host +%{_bindir}/ovn-controller +%{_mandir}/man8/ovn-controller.8* +%{_unitdir}/ovn-controller.service +%{_prefix}/lib/firewalld/services/ovn-host-firewall-service.xml + +%files ovn-vtep +%{_bindir}/ovn-controller-vtep +%{_mandir}/man8/ovn-controller-vtep.8* +%{_unitdir}/ovn-controller-vtep.service + +%changelog +* Tue Jan 30 2018 Lianhao Lu - 2.8.1-3.tis.1 +- Adjusted for TiC +- Include dpdk usertools in the final package + +* Mon Oct 02 2017 Timothy Redaelli - 2.8.1-1 +- Update to Open vSwitch 2.8.1 + +* Tue Sep 19 2017 Timothy Redaelli - 2.8.0-2 +- Update DPDK to 17.05.2 (bugfixes) + +* Mon Sep 04 2017 Timothy Redaelli - 2.8.0-1 +- Update to Open vSwitch 2.8.0 and DPDK 17.05.1 (#1487971) + +* Thu Aug 03 2017 Fedora Release Engineering - 2.7.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 2.7.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 19 2017 Timothy Redaelli - 2.7.2-1 +- Update to Open vSwitch 2.7.2 +- Add a symlink of the OCF script in the OCF resources folder + +* Fri Jul 14 2017 Timothy Redaelli - 2.7.1-2 +- Backport fix for CVE-2017-9263 (#1457327) +- Backport fix for CVE-2017-9265 (#1457335) + +* Thu Jul 06 2017 Timothy Redaelli - 2.7.1-1 +- Updated to Open vSwitch 2.7.1 and DPDK 16.11.2 (#1468234) + +* Tue Jun 13 2017 Timothy Redaelli - 2.7.0-5 +- Backport fix for CVE-2017-9264 (#1457329) + +* Wed Jun 07 2017 Timothy Redaelli - 2.7.0-4 +- Remove PYTHONCOERCECLOCALE=0 workaround and backport upstream patch (#1454364) + +* Wed May 31 2017 Timothy Redaelli - 2.7.0-3 +- Backport fix for CVE-2017-9214 (#1456797) +- Use %%autosetup instead of %%setup + +* Mon May 29 2017 Timothy Redaelli - 2.7.0-2 +- Install OVN firewalld rules + +* Thu May 18 2017 Timothy Redaelli - 2.7.0-1 +- Link statically with DPDK 16.11.1 (#1451476) +- Build OVS without DPDK support on all architectures not supported by DPDK +- Added python3-six to BuildRequires in order to launch python3 tests too +- Export PYTHONCOERCECLOCALE=0 in order to workaround an incompatibility + between Python 3.6.0 (with PEP 538) on Fedora 26+ and testsuite (#1454364) +- Disable tests on armv7hl + +* Fri Feb 24 2017 Timothy Redaelli - 2.7.0-0 +- Updated to Open vSwitch 2.7.0 (#1426596) +- Enable DPDK support + +* Thu Feb 16 2017 Timothy Redaelli - 2.6.1-2 +- Added python3-openvswitch and renamed python-openvswitch to python2-openvswitch + +* Sat Feb 11 2017 Fedora Release Engineering - 2.6.1-1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Nov 24 2016 Flavio Leitner - 2.6.1-0 +- Updated to Open vSwitch 2.6.1 + +* Tue Nov 01 2016 Aaron Conole - 2.6.0-0 +- Update to Open vSwitch 2.6.0 +- Enable OVN + +* Wed Aug 24 2016 Dan Horák - 2.5.0-4 +- don't run the test-suite for big endian arches + +* Tue Jul 19 2016 Fedora Release Engineering - 2.5.0-3 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Tue Mar 15 2016 Panu Matilainen - 2.5.0-2 +- Remove unpackaged files instead of excluding (#1281913) + +* Wed Mar 02 2016 Panu Matilainen - 2.5.0-1 +- Update to 2.5.0 (#1312617) + +* Thu Feb 04 2016 Fedora Release Engineering - 2.4.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Aug 24 2015 Flavio Leitner - 2.4.0-1 +- updated to 2.4.0 (#1256171) + +* Thu Jun 18 2015 Flavio Leitner - 2.3.2-1 +- updated to 2.3.2 (#1233442) +- fixed to own /var/run/openvswitch directory (#1200887) + +* Thu Jun 18 2015 Fedora Release Engineering - 2.3.1-4.git20150327 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Mar 27 2015 Flavio Leitner - 2.3.1-3.git20150327 +- updated to 2.3.1-git4750c96 +- commented out kernel requires +- added requires to procps-ng (testsuite #84) + +* Wed Jan 14 2015 Flavio Leitner - 2.3.1-2.git20150113 +- updated to 2.3.1-git3282e51 + +* Fri Dec 05 2014 Flavio Leitner - 2.3.1-1 +- updated to 2.3.1 + +* Fri Nov 07 2014 Flavio Leitner - 2.3.0-3.git20141107 +- updated to 2.3.0-git39ebb203 + +* Thu Oct 23 2014 Flavio Leitner - 2.3.0-2 +- fixed to own conf.db and system-id.conf in /etc/openvswitch. + (#1132707) + +* Tue Aug 19 2014 Flavio Leitner - 2.3.0-1 +- updated to 2.3.0 + +* Sun Aug 17 2014 Fedora Release Engineering - 2.1.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jun 12 2014 Flavio Leitner - 2.1.2-4 +- moved README.RHEL to be in the standard doc dir. +- added FAQ and NEWS files to the doc list. +- excluded PPC arch + +* Thu Jun 12 2014 Flavio Leitner - 2.1.2-3 +- removed ovsdbmonitor packaging + +* Sat Jun 07 2014 Fedora Release Engineering - 2.1.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Mar 25 2014 Flavio Leitner - 2.1.2-1 +- updated to 2.1.2 + +* Tue Mar 25 2014 Flavio Leitner - 2.1.0-1 +- updated to 2.1.0 +- obsoleted openvswitch-controller package +- requires kernel 3.15.0-0 or newer + (kernel commit 4f647e0a3c37b8d5086214128614a136064110c3 + openvswitch: fix a possible deadlock and lockdep warning) +- ovs-lib: allow non-root users to check service status + (upstream commit 691e47554dd03dd6492e00bab5bd6d215f5cbd4f) +- rhel: Add Patch Port support to initscripts + (upstream commit e2bcc8ef49f5e51f48983b87ab1010f0f9ab1454) + +* Mon Jan 27 2014 Flavio Leitner - 2.0.1-1 +- updated to 2.0.1 + +* Mon Jan 27 2014 Flavio Leitner - 2.0.0-6 +- create a -devel package + (from Chris Wright ) + +* Wed Jan 15 2014 Flavio Leitner - 2.0.0-5 +- Enable DHCP support for internal ports + (upstream commit 490db96efaf89c63656b192d5ca287b0908a6c77) + +* Wed Jan 15 2014 Flavio Leitner - 2.0.0-4 +- disabled ovsdbmonitor packaging + (upstream has removed the component) + +* Wed Jan 15 2014 Flavio Leitner - 2.0.0-3 +- fedora package: fix systemd ordering and deps. + (upstream commit b49c106ef00438b1c59876dad90d00e8d6e7b627) + +* Wed Jan 15 2014 Flavio Leitner - 2.0.0-2 +- util: use gcc builtins to better check array sizes + (upstream commit 878f1972909b33f27b32ad2ded208eb465b98a9b) + +* Mon Oct 28 2013 Flavio Leitner - 2.0.0-1 +- updated to 2.0.0 (#1023184) + +* Mon Oct 28 2013 Flavio Leitner - 1.11.0-8 +- applied upstream commit 7b75828bf5654c494a53fa57be90713c625085e2 + rhel: Option to create tunnel through ifcfg scripts. + +* Mon Oct 28 2013 Flavio Leitner - 1.11.0-7 +- applied upstream commit 32aa46891af5e173144d672e15fec7c305f9a4f3 + rhel: Set STP of a bridge during bridge creation. + +* Mon Oct 28 2013 Flavio Leitner - 1.11.0-6 +- applied upstream commit 5b56f96aaad4a55a26576e0610fb49bde448dabe + rhel: Prevent duplicate ifup calls. + +* Mon Oct 28 2013 Flavio Leitner - 1.11.0-5 +- applied upstream commit 79416011612541d103a1d396d888bb8c84eb1da4 + rhel: Return an exit value of 0 for ifup-ovs. + +* Mon Oct 28 2013 Flavio Leitner - 1.11.0-4 +- applied upstream commit 2517bad92eec7e5625bc8b248db22fdeaa5fcde9 + Added RHEL ovs-ifup STP option handling + +* Tue Oct 1 2013 Flavio Leitner - 1.11.0-3 +- don't use /var/lock/subsys with systemd (#1006412) + +* Thu Sep 19 2013 Flavio Leitner - 1.11.0-2 +- ovsdbmonitor package is optional + +* Thu Aug 29 2013 Thomas Graf - 1.11.0-1 +- Update to 1.11.0 + +* Tue Aug 13 2013 Flavio Leitner - 1.10.0-7 +- Fixed openvswitch-nonetwork to start openvswitch.service (#996804) + +* Sat Aug 03 2013 Petr Pisar - 1.10.0-6 +- Perl 5.18 rebuild + +* Tue Jul 23 2013 Thomas Graf - 1.10.0-5 +- Typo + +* Tue Jul 23 2013 Thomas Graf - 1.10.0-4 +- Spec file fixes +- Maintain local copy of sysconfig.template + +* Thu Jul 18 2013 Petr Pisar - 1.10.0-3 +- Perl 5.18 rebuild + +* Mon Jul 01 2013 Thomas Graf - 1.10.0-2 +- Enable PIE (#955181) +- Provide native systemd unit files (#818754) + +* Thu May 02 2013 Thomas Graf - 1.10.0-1 +- Update to 1.10.0 (#958814) + +* Thu Feb 28 2013 Thomas Graf - 1.9.0-1 +- Update to 1.9.0 (#916537) + +* Tue Feb 12 2013 Thomas Graf - 1.7.3-8 +- Fix systemd service dependency loop (#818754) + +* Fri Jan 25 2013 Thomas Graf - 1.7.3-7 +- Auto-start openvswitch service on ifup/ifdown (#818754) +- Add OVSREQUIRES to allow defining OpenFlow interface dependencies + +* Thu Jan 24 2013 Thomas Graf - 1.7.3-6 +- Update to Open vSwitch 1.7.3 + +* Tue Nov 20 2012 Thomas Graf - 1.7.1-6 +- Increase max fd limit to support 256 bridges (#873072) + +* Thu Nov 1 2012 Thomas Graf - 1.7.1-5 +- Don't create world writable pki/*/incomming directory (#845351) + +* Thu Oct 25 2012 Thomas Graf - 1.7.1-4 +- Don't add iptables accept rule for -p GRE as GRE tunneling is unsupported + +* Tue Oct 16 2012 Thomas Graf - 1.7.1-3 +- require systemd instead of systemd-units to use macro helpers (#850258) + +* Tue Oct 9 2012 Thomas Graf - 1.7.1-2 +- make ovs-vsctl timeout if daemon is not running (#858722) + +* Mon Sep 10 2012 Thomas Graf - 1.7.1.-1 +- Update to 1.7.1 + +* Fri Sep 7 2012 Thomas Graf - 1.7.0.-3 +- add controller package containing ovs-controller + +* Thu Aug 23 2012 Tomas Hozza - 1.7.0-2 +- fixed SPEC file so it comply with new systemd-rpm macros guidelines (#850258) + +* Fri Aug 17 2012 Tomas Hozza - 1.7.0-1 +- Update to 1.7.0 +- Fixed openvswitch-configure-ovskmod-var-autoconfd.patch because + openvswitch kernel module name changed in 1.7.0 +- Removed Source8: ovsdbmonitor-move-to-its-own-data-directory.patch +- Patches merged: + - ovsdbmonitor-move-to-its-own-data-directory-automaked.patch + - openvswitch-rhel-initscripts-resync.patch + +* Fri Jul 20 2012 Fedora Release Engineering - 1.4.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Mar 15 2012 Chris Wright - 1.4.0-5 +- fix ovs network initscripts DHCP address acquisition (#803843) + +* Tue Mar 6 2012 Chris Wright - 1.4.0-4 +- make BuildRequires openssl explicit (needed on f18/rawhide now) + +* Tue Mar 6 2012 Chris Wright - 1.4.0-3 +- use glob to catch compressed manpages + +* Thu Mar 1 2012 Chris Wright - 1.4.0-2 +- Update License comment, use consitent macros as per review comments bz799171 + +* Wed Feb 29 2012 Chris Wright - 1.4.0-1 +- Initial package for Fedora diff --git a/networking/openvswitch/patches/ovs-vswitchd.system.service.patch b/networking/openvswitch/patches/ovs-vswitchd.system.service.patch new file mode 100644 index 000000000..6802dad7d --- /dev/null +++ b/networking/openvswitch/patches/ovs-vswitchd.system.service.patch @@ -0,0 +1,14 @@ +--- a/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in 2017-09-29 13:41:03.569697066 +0800 ++++ b/rhel/usr_lib_systemd_system_ovs-vswitchd.service.in 2018-02-05 18:42:08.183083617 +0800 +@@ -15,7 +15,11 @@ + EnvironmentFile=-/etc/sysconfig/openvswitch + @begin_dpdk@ + ExecStartPre=-/usr/bin/chown :hugetlbfs /dev/hugepages ++ExecStartPre=-/usr/bin/chown -R :hugetlbfs /mnt/huge-2048kB ++ExecStartPre=-/usr/bin/chown -R :hugetlbfs /mnt/huge-1048576kB + ExecStartPre=-/usr/bin/chmod 0775 /dev/hugepages ++ExecStartPre=-/usr/bin/chmod 0775 /mnt/huge-2048kB ++ExecStartPre=-/usr/bin/chmod 0775 /mnt/huge-1048576kB + @end_dpdk@ + ExecStart=/usr/share/openvswitch/scripts/ovs-ctl \ + --no-ovsdb-server --no-monitor --system-id=random \ diff --git a/networking/scapy/centos/build_srpm.data b/networking/scapy/centos/build_srpm.data new file mode 100644 index 000000000..8aeb55368 --- /dev/null +++ b/networking/scapy/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=1 diff --git a/networking/scapy/centos/meta_patches/0001-spec-update-package-versioning-for-tis-format.patch b/networking/scapy/centos/meta_patches/0001-spec-update-package-versioning-for-tis-format.patch new file mode 100644 index 000000000..d257fd4b1 --- /dev/null +++ b/networking/scapy/centos/meta_patches/0001-spec-update-package-versioning-for-tis-format.patch @@ -0,0 +1,28 @@ +From eb8036a5e84abe57f407e57f744532693fa49af3 Mon Sep 17 00:00:00 2001 +From: Allain Legacy +Date: Mon, 26 Feb 2018 08:03:04 -0600 +Subject: [PATCH 1/2] spec: update package versioning for tis format + +Updating the RPM version to align with TiS version format. + +Signed-off-by: Allain Legacy +--- + SPECS/scapy.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/scapy.spec b/SPECS/scapy.spec +index 9c04bae..add5a84 100644 +--- a/SPECS/scapy.spec ++++ b/SPECS/scapy.spec +@@ -5,7 +5,7 @@ + + Name: scapy + Version: 2.3.3 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Interactive packet manipulation tool and network scanner + + Group: Applications/Internet +-- +2.12.1 + diff --git a/networking/scapy/centos/meta_patches/0002-spec-include-ipv6-fixes-from-2.4-release-candidate.patch b/networking/scapy/centos/meta_patches/0002-spec-include-ipv6-fixes-from-2.4-release-candidate.patch new file mode 100644 index 000000000..b868366c3 --- /dev/null +++ b/networking/scapy/centos/meta_patches/0002-spec-include-ipv6-fixes-from-2.4-release-candidate.patch @@ -0,0 +1,36 @@ +From 6d23d7b91388213ff090159f52af3aa88a6684c8 Mon Sep 17 00:00:00 2001 +From: Allain Legacy +Date: Mon, 26 Feb 2018 08:04:47 -0600 +Subject: [PATCH 2/2] spec: include ipv6 fixes from 2.4 release candidate + +Pulling in patches from the 2.4 release candidate series in order to address +various IPv6 formatting/parsing issues. + +Signed-off-by: Allain Legacy +--- + SPECS/scapy.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/scapy.spec b/SPECS/scapy.spec +index add5a84..7afe35f 100644 +--- a/SPECS/scapy.spec ++++ b/SPECS/scapy.spec +@@ -15,6 +15,7 @@ URL: http://www.secdev.org/projects/scapy/ + # https://bitbucket.org/secdev/scapy/pull-request/80 + Source0: https://github.com/%{gituser}/%{gitname}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz + Patch0: scapy-2.2.0-xdg-open.patch ++Patch1: 0001-Use-socket.pton-socket.ntop-is-available.patch + + BuildArch: noarch + BuildRequires: python >= 2.5 +@@ -31,6 +32,7 @@ requests and replies, and much more. + %prep + %setup -q + %patch0 -p1 ++%patch1 -p1 + + %build + %{__python} setup.py build +-- +2.12.1 + diff --git a/networking/scapy/centos/meta_patches/PATCH_ORDER b/networking/scapy/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..19f68f851 --- /dev/null +++ b/networking/scapy/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-spec-update-package-versioning-for-tis-format.patch +0002-spec-include-ipv6-fixes-from-2.4-release-candidate.patch diff --git a/networking/scapy/centos/patches/0001-Use-socket.pton-socket.ntop-is-available.patch b/networking/scapy/centos/patches/0001-Use-socket.pton-socket.ntop-is-available.patch new file mode 100644 index 000000000..7625bc0a3 --- /dev/null +++ b/networking/scapy/centos/patches/0001-Use-socket.pton-socket.ntop-is-available.patch @@ -0,0 +1,64 @@ +From 333afaf9b1a30acbf5279b04e33d9469d97ee24d Mon Sep 17 00:00:00 2001 +From: Guillaume Valadon +Date: Thu, 24 Nov 2016 16:13:05 +0100 +Subject: [PATCH] Use socket.pton & socket.ntop is available + +Signed-off-by: Allain Legacy +--- + scapy/pton_ntop.py | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/scapy/pton_ntop.py b/scapy/pton_ntop.py +index ce93b67..8196b01 100644 +--- a/scapy/pton_ntop.py ++++ b/scapy/pton_ntop.py +@@ -17,6 +17,12 @@ def inet_pton(af, addr): + if af == socket.AF_INET: + return socket.inet_aton(addr) + elif af == socket.AF_INET6: ++ # Use inet_pton if available ++ try: ++ return socket.inet_pton(af, addr) ++ except AttributeError: ++ pass ++ + # IPv6: The use of "::" indicates one or more groups of 16 bits of zeros. + # We deal with this form of wildcard using a special marker. + JOKER = "*" +@@ -65,6 +71,12 @@ def inet_ntop(af, addr): + if af == socket.AF_INET: + return socket.inet_ntoa(addr) + elif af == socket.AF_INET6: ++ # Use inet_ntop if available ++ try: ++ return socket.inet_ntop(af, addr) ++ except AttributeError: ++ pass ++ + # IPv6 addresses have 128bits (16 bytes) + if len(addr) != 16: + raise Exception("Illegal syntax for IP address") +@@ -75,15 +87,9 @@ def inet_ntop(af, addr): + hexstr = hex(value)[2:] + except TypeError: + raise Exception("Illegal syntax for IP address") +- parts.append(hexstr.lstrip("0").lower()) +- result = ":".join(parts) +- while ":::" in result: +- result = result.replace(":::", "::") +- # Leaving out leading and trailing zeros is only allowed with :: +- if result.endswith(":") and not result.endswith("::"): +- result = result + "0" +- if result.startswith(":") and not result.startswith("::"): +- result = "0" + result +- return result ++ parts.append(hexstr.lower()) ++ ++ # Note: the returned address is never compact ++ return ":".join(parts) + else: +- raise Exception("Address family not supported yet") ++ raise Exception("Address family not supported yet") +-- +2.12.1 + diff --git a/networking/scapy/centos/srpm_path b/networking/scapy/centos/srpm_path new file mode 100644 index 000000000..1112cd7bf --- /dev/null +++ b/networking/scapy/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/scapy-2.3.3-1.el7.src.rpm diff --git a/python/python-3parclient/centos/build_srpm.data b/python/python-3parclient/centos/build_srpm.data new file mode 100644 index 000000000..1cbb5d3e7 --- /dev/null +++ b/python/python-3parclient/centos/build_srpm.data @@ -0,0 +1,3 @@ +SRC_DIR=$CGCS_BASE/git/python-3parclient +TIS_BASE_SRCREV=d0e6de393cecc765eba70312c466e91405fb2a69 +TIS_PATCH_VER=1 diff --git a/python/python-3parclient/centos/python-3parclient.spec b/python/python-3parclient/centos/python-3parclient.spec new file mode 100644 index 000000000..e0b287b25 --- /dev/null +++ b/python/python-3parclient/centos/python-3parclient.spec @@ -0,0 +1,35 @@ +%define name python-3parclient +%define version 4.2.3 +Summary: HPE 3PAR HTTP REST Client +Name: %{name} +Version: %{version} +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Source0: %{name}-%{version}.tar.gz +License: Apache License, Version 2.0 +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +Prefix: %{_prefix} +BuildArch: noarch +Vendor: Walter A. Boring IV +Url: http://packages.python.org/python-3parclient + +BuildRequires: python2-devel +BuildRequires: python-setuptools + +%description +HPE 3PAR HTTP REST Client + +%prep +%setup -q + +%build +%{__python2} setup.py build + +%install +%{__python2} setup.py install -O1 --skip-build --root %{buildroot} --record=INSTALLED_FILES + +%clean +rm -rf %{buildroot} + +%files -f INSTALLED_FILES +%defattr(-,root,root) diff --git a/python/python-cryptography/centos/meta_patches/0002-Turn-off-python-crypto-test-step.patch b/python/python-cryptography/centos/meta_patches/0002-Turn-off-python-crypto-test-step.patch new file mode 100644 index 000000000..b4efd2cc5 --- /dev/null +++ b/python/python-cryptography/centos/meta_patches/0002-Turn-off-python-crypto-test-step.patch @@ -0,0 +1,26 @@ +From 140bb75b69ed09ce80185c2e580dd3243110a4f5 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Thu, 9 Nov 2017 07:37:59 -0600 +Subject: [PATCH 2/2] Turn off python-crypto test step + +The build fails in an environment with python-coverage 3.6b3 problems with python-cov-core +--- + SPECS/python-cryptography.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/python-cryptography.spec b/SPECS/python-cryptography.spec +index 87095e2..4decf51 100644 +--- a/SPECS/python-cryptography.spec ++++ b/SPECS/python-cryptography.spec +@@ -128,7 +128,7 @@ popd + + + %check +-%{__python} setup.py test ++#%{__python} setup.py test + + %if 0%{?with_python3} + pushd %{py3dir} +-- +1.8.3.1 + diff --git a/python/python-eventlet/centos/build_srpm.data b/python/python-eventlet/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/python/python-eventlet/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/python/python-eventlet/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/python/python-eventlet/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..27155acbc --- /dev/null +++ b/python/python-eventlet/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,27 @@ +From 2ae1604b483c4aeb97c96cba2b6fd2d7c7bb0fce Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Tue, 24 Jan 2017 12:31:27 -0500 +Subject: [PATCH 2/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/python-eventlet.spec +--- + SPECS/python-eventlet.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/python-eventlet.spec b/SPECS/python-eventlet.spec +index d85d6c1..151fa56 100644 +--- a/SPECS/python-eventlet.spec ++++ b/SPECS/python-eventlet.spec +@@ -12,7 +12,7 @@ + + Name: python-%{pypi_name} + Version: 0.18.4 +-Release: 2%{?dist} ++Release: 2.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Highly concurrent networking library + License: MIT + URL: http://eventlet.net +-- +1.8.3.1 + diff --git a/python/python-eventlet/centos/meta_patches/PATCH_ORDER b/python/python-eventlet/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..f3792ef26 --- /dev/null +++ b/python/python-eventlet/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +spec-include-TiS-paches.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/python/python-eventlet/centos/meta_patches/spec-include-TiS-paches.patch b/python/python-eventlet/centos/meta_patches/spec-include-TiS-paches.patch new file mode 100644 index 000000000..09fd925a6 --- /dev/null +++ b/python/python-eventlet/centos/meta_patches/spec-include-TiS-paches.patch @@ -0,0 +1,34 @@ +From 869679b3dc8fb689e52cf51f2577aceb52fb8538 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Tue, 24 Jan 2017 12:31:27 -0500 +Subject: [PATCH 1/2] WRS: spec-include-TiS-paches.patch + +--- + SPECS/python-eventlet.spec | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/SPECS/python-eventlet.spec b/SPECS/python-eventlet.spec +index b33e617..d85d6c1 100644 +--- a/SPECS/python-eventlet.spec ++++ b/SPECS/python-eventlet.spec +@@ -25,6 +25,9 @@ BuildRequires: python-setuptools + + Requires: python-greenlet + ++# WRS patches ++Patch0: 0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch ++ + %description + Eventlet is a networking library written in Python. It achieves high + scalability by using non-blocking io while at the same time retaining +@@ -94,6 +97,7 @@ Documentation for the python-eventlet package. + + %prep + %setup -q -n %{pypi_name}-%{version} ++%patch0 -p1 + rm -rf *.egg-info + + # generate html docs +-- +1.8.3.1 + diff --git a/python/python-eventlet/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch b/python/python-eventlet/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch new file mode 100644 index 000000000..05a28b85c --- /dev/null +++ b/python/python-eventlet/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch @@ -0,0 +1,28 @@ +From bdbcd8615e1720b4098296752a2f4273a0947a8d Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Tue, 6 Sep 2016 15:09:39 +0000 +Subject: [PATCH] CGTS-2869 close connection on HTTP 413 Request Entity Too + Large + +Discard request body in case it's too large: close connection +wile request is in progress. +--- + eventlet/wsgi.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/eventlet/wsgi.py b/eventlet/wsgi.py +index 6af2b99..8eac966 100644 +--- a/eventlet/wsgi.py ++++ b/eventlet/wsgi.py +@@ -525,6 +525,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler): + finally: + if hasattr(result, 'close'): + result.close() ++ if str(status_code[0]) == '413': ++ self.close_connection = 1 + request_input = self.environ['eventlet.input'] + if (request_input.chunked_input or + request_input.position < (request_input.content_length or 0)): +-- +1.8.3.1 + diff --git a/python/python-eventlet/centos/srpm_path b/python/python-eventlet/centos/srpm_path new file mode 100644 index 000000000..973363ebc --- /dev/null +++ b/python/python-eventlet/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/python-eventlet-0.18.4-2.el7.src.rpm diff --git a/python/python-lefthandclient/centos/build_srpm.data b/python/python-lefthandclient/centos/build_srpm.data new file mode 100644 index 000000000..2cd7986b9 --- /dev/null +++ b/python/python-lefthandclient/centos/build_srpm.data @@ -0,0 +1,3 @@ +SRC_DIR=$CGCS_BASE/git/python-lefthandclient +TIS_BASE_SRCREV=db9773f0f97c5af04da89fcb7dca2a6ddf8d5e4a +TIS_PATCH_VER=1 diff --git a/python/python-lefthandclient/centos/python-lefthandclient.spec b/python/python-lefthandclient/centos/python-lefthandclient.spec new file mode 100644 index 000000000..21312d560 --- /dev/null +++ b/python/python-lefthandclient/centos/python-lefthandclient.spec @@ -0,0 +1,37 @@ +%define name python-lefthandclient +%define version 2.1.0 +%define release 1 + +Summary: HPE LeftHand/StoreVirtual HTTP REST Client +Name: %{name} +Version: %{version} +Release: 0%{?_tis_dist}.%{tis_patch_ver} +Source0: %{name}-%{version}.tar.gz +License: Apache License, Version 2.0 +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +Prefix: %{_prefix} +BuildArch: noarch +Vendor: Kurt Martin +Url: http://packages.python.org/python-lefthandclient + +BuildRequires: python2-devel +BuildRequires: python-setuptools + +%description +HPE LeftHand/StoreVirtual HTTP REST Client + +%prep +%setup -q + +%build +%{__python2} setup.py build + +%install +%{__python2} setup.py install -O1 --skip-build --root %{buildroot} --record=INSTALLED_FILES + +%clean +rm -rf %{buildroot} + +%files -f INSTALLED_FILES +%defattr(-,root,root) diff --git a/python/python-requests/centos/build_srpm.data b/python/python-requests/centos/build_srpm.data new file mode 100644 index 000000000..70b4b5dcb --- /dev/null +++ b/python/python-requests/centos/build_srpm.data @@ -0,0 +1 @@ +TIS_PATCH_VER=2 diff --git a/python/python-requests/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/python/python-requests/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..799455f13 --- /dev/null +++ b/python/python-requests/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 9e05fbda393fe0ed6cb581c33ba19a14ab07abb6 Mon Sep 17 00:00:00 2001 +From: jmckenna +Date: Wed, 13 Dec 2017 09:02:08 -0500 +Subject: [PATCH 1/2] Update package versioning for TIS format + +--- + SPECS/python-requests.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/python-requests.spec b/SPECS/python-requests.spec +index efe0966..111bab7 100644 +--- a/SPECS/python-requests.spec ++++ b/SPECS/python-requests.spec +@@ -11,7 +11,7 @@ + + Name: python-requests + Version: 2.14.2 +-Release: 1%{?dist} ++Release: 1.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: HTTP library, written in Python, for human beings + + License: ASL 2.0 +-- +1.8.3.1 + diff --git a/python/python-requests/centos/meta_patches/0002-include-patch-for-CGTS-2869.patch b/python/python-requests/centos/meta_patches/0002-include-patch-for-CGTS-2869.patch new file mode 100644 index 000000000..66f213fcb --- /dev/null +++ b/python/python-requests/centos/meta_patches/0002-include-patch-for-CGTS-2869.patch @@ -0,0 +1,25 @@ +From b99292ef32fdde60d2ec4181ee5963b93a97cdf2 Mon Sep 17 00:00:00 2001 +From: jmckenna +Date: Wed, 13 Dec 2017 09:02:40 -0500 +Subject: [PATCH 2/2] include patch for CGTS-2869 + +--- + SPECS/python-requests.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/SPECS/python-requests.spec b/SPECS/python-requests.spec +index 111bab7..8aab964 100644 +--- a/SPECS/python-requests.spec ++++ b/SPECS/python-requests.spec +@@ -39,6 +39,8 @@ Patch2: python-requests-urllib3-at-%{urllib3_unbundled_version}.patch + # a pretty odd one so this is a niche requirement. + Patch3: requests-2.12.4-tests_nonet.patch + ++Patch4: 0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch ++ + BuildArch: noarch + + %description +-- +1.8.3.1 + diff --git a/python/python-requests/centos/meta_patches/PATCH_ORDER b/python/python-requests/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..d19e7aa60 --- /dev/null +++ b/python/python-requests/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +0002-include-patch-for-CGTS-2869.patch diff --git a/python/python-requests/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch b/python/python-requests/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch new file mode 100644 index 000000000..56b7653c8 --- /dev/null +++ b/python/python-requests/centos/patches/0001-CGTS-2869-close-connection-on-HTTP-413-Request-Entit.patch @@ -0,0 +1,45 @@ +From 268a1f179e554027637bd2951b24ad44ecb4a1ee Mon Sep 17 00:00:00 2001 +From: Daniel Badea +Date: Wed, 7 Sep 2016 09:10:10 +0000 +Subject: [PATCH] CGTS-2869 close connection on HTTP 413 Request Entity Too + Large + +Allow low_conn to retrieve/handle unread response data buffers +in case ProtocolError or socket.error are raised while sending +request data. +--- + requests/adapters.py | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index fd46325..087258a 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -455,12 +455,18 @@ class HTTPAdapter(BaseAdapter): + + low_conn.endheaders() + +- for i in request.body: +- low_conn.send(hex(len(i))[2:].encode('utf-8')) +- low_conn.send(b'\r\n') +- low_conn.send(i) +- low_conn.send(b'\r\n') +- low_conn.send(b'0\r\n\r\n') ++ try: ++ for i in request.body: ++ low_conn.send(hex(len(i))[2:].encode('utf-8')) ++ low_conn.send(b'\r\n') ++ low_conn.send(i) ++ low_conn.send(b'\r\n') ++ low_conn.send(b'0\r\n\r\n') ++ except (ProtocolError, socket.error) as err: ++ # allow low_conn to retrieve/handle unread response ++ # data buffers in case ProtocolError or socket.error ++ # are raised while sending request data ++ pass + + # Receive the response from the server + try: +-- +1.8.3.1 + diff --git a/python/python-requests/centos/srpm_path b/python/python-requests/centos/srpm_path new file mode 100644 index 000000000..f57236e1b --- /dev/null +++ b/python/python-requests/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/python-requests-2.14.2-1.el7.src.rpm diff --git a/python/python-suds/centos/meta_patches/0002-BuildRequires-pythong-coverage.patch b/python/python-suds/centos/meta_patches/0002-BuildRequires-pythong-coverage.patch new file mode 100644 index 000000000..95cd94945 --- /dev/null +++ b/python/python-suds/centos/meta_patches/0002-BuildRequires-pythong-coverage.patch @@ -0,0 +1,25 @@ +From 3b902cb7fbcb32f7cba956a646a8236b2f8e3503 Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Tue, 31 Oct 2017 15:29:28 -0500 +Subject: [PATCH] WRS: 0002-BuildRequires-pythong-coverage.patch + +--- + SPECS/python-suds.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/python-suds.spec b/SPECS/python-suds.spec +index e1fb4b0..ed32ca7 100644 +--- a/SPECS/python-suds.spec ++++ b/SPECS/python-suds.spec +@@ -76,7 +76,7 @@ popd + + %check + pushd %{py2_builddir} +-%{__python2} setup.py test ++#%{__python2} setup.py test + popd + %if 0%{?with_python3} + pushd %{py3_builddir} +-- +1.8.3.1 + diff --git a/restapi-doc/centos/build_srpm b/restapi-doc/centos/build_srpm new file mode 100755 index 000000000..79662d42f --- /dev/null +++ b/restapi-doc/centos/build_srpm @@ -0,0 +1,252 @@ +#!/bin/bash +# set -x + +source "$SRC_BASE/build-tools/spec-utils" +source "$SRC_BASE/build-tools/srpm-utils" + +CUR_DIR=`pwd` +BUILD_DIR="$RPMBUILD_BASE" + +if [ "x$DATA" == "x" ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): Environment variable 'DATA' not defined." + exit 1 +fi + +srpm_source_build_data $DATA +if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): Failed to source build data from $DATA" + exit 1 +fi + +if [ "x$VERSION" == "x" ]; then + for SPEC in `find $SPECS_BASE -name '*.spec' | sort -V`; do + SPEC_PATH="$SPEC" + + VERSION_DERIVED=`spec_evaluate '%{version}' "$SPEC_PATH" 2>> /dev/null` + if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): '%{version}' not found in '$PKG_BASE/$SPEC_PATH'" + VERSION_DERIVED="" + fi + + if [ "x$VERSION_DERIVED" != "x" ]; then + if [ "x$VERSION" == "x" ]; then + VERSION=$VERSION_DERIVED + else + if [ "x$SRC_DIR" != "x" ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): multiple spec files found, can't set VERSION automatically" + exit 1 + fi + fi + fi + done + + if [ "x$VERSION" == "x" ]; then + if [ -f $SRC_DIR/PKG-INFO ]; then + VERSION=$(grep '^Version:' $SRC_DIR/PKG-INFO | awk -F ': ' '{print $2}' | sed -e 's/^[[:space:]]*//') + fi + fi + + if [ "x$VERSION" != "x" ]; then + echo "Derived VERSION=$VERSION" + else + echo "ERROR: restapi_build_srpm (${LINENO}): Failed to derive a good VERSION from SPEC file, and none provided." + exit 1 + fi +fi + +if [ "x$TAR_NAME" == "x" ]; then + for SPEC in `find $SPECS_BASE -name '*.spec' | sort -V`; do + SPEC_PATH="$SPEC" + + SERVICE=`spec_find_global service "$SPEC_PATH" 2>> /dev/null` + if [ $? -eq 0 ]; then + if [ "x$TAR_NAME" == "x" ]; then + TAR_NAME=$SERVICE + else + if [ "x$SRC_DIR" != "x" ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): multiple spec files found, can't set TAR_NAME automatically" + exit 1 + fi + fi + else + NAME=`spec_find_tag Name "$SPEC_PATH" 2>> /dev/null` + if [ $? -eq 0 ]; then + if [ "x$TAR_NAME" == "x" ]; then + TAR_NAME=$NAME + else + if [ "x$SRC_DIR" != "x" ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): multiple spec files found, can't set TAR_NAME automatically" + exit 1 + fi + fi + else + echo "WARNING: restapi_build_srpm (${LINENO}): 'Name' not found in '$PKG_BASE/$SPEC_PATH'" + NAME="" + fi + fi + done + + if [ "x$TAR_NAME" == "x" ]; then + if [ -f $SRC_DIR/PKG-INFO ]; then + TAR_NAME=$(grep '^Name:' $SRC_DIR/PKG-INFO | awk -F ': ' '{print $2}' | sed -e 's/^[[:space:]]*//') + fi + fi + + if [ "x$TAR_NAME" != "x" ]; then + echo "Derived TAR_NAME=$TAR_NAME" + else + echo "ERROR: restapi_build_srpm (${LINENO}): Failed to derive a good TAR_NAME from SPEC file, and none provided." + exit 1 + fi +fi + +if [ "x$TAR" == "x" ]; then + TAR="$TAR_NAME-$VERSION.tar.gz" +fi + +SOURCE_PATH="$BUILD_DIR/SOURCES" +TAR_PATH="$SOURCE_PATH/$TAR" +STAGING="" + +if [ "x$COPY_LIST_TO_TAR" != "x" ] || [ "x$EXCLUDE_LIST_FROM_TAR" != "x" ]; then + STAGING="$BUILD_DIR/staging" + mkdir -p $STAGING +fi + +mkdir -p "$BUILD_DIR/SRPMS" +mkdir -p "$SOURCE_PATH" + +if [ "x$SRC_DIR" == "x" -a "x$COPY_LIST" == "x" -a "$ALLOW_EMPTY_RPM" != "true" ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): '$PWD/$DATA' failed to provide at least one of 'SRC_DIR' or 'COPY_LIST'" + exit 1 +fi + +if [ "x$SRC_DIR" != "x" ]; then + if [ ! -d "$SRC_DIR" ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): directory not found: '$SRC_DIR'" + exit 1 + fi +fi + +if [ "x$COPY_LIST" != "x" ]; then + echo "COPY_LIST: $COPY_LIST" + for p in $COPY_LIST; do + # echo "COPY_LIST: $p" + cp -L -u -r -v $p $SOURCE_PATH + if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): COPY_LIST: file not found: '$p'" + exit 1 + fi + done +fi + +if [ "x$STAGING" != "x" ]; then + cp -L -u -r -v $SRC_DIR $STAGING + echo "COPY_LIST_TO_TAR: $COPY_LIST_TO_TAR" + for p in $COPY_LIST_TO_TAR; do + # echo "COPY_LIST_TO_TAR: $p" + cp -L -u -r -v $p $STAGING/$SRC_DIR + if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): COPY_LIST_TO_TAR: file not found: '$p'" + exit 1 + fi + done + echo "EXCLUDE_LIST_FROM_TAR: $EXCLUDE_LIST_FROM_TAR" + for p in $EXCLUDE_LIST_FROM_TAR; do + # echo "EXCLUDE_LIST_FROM_TAR: $p" + rm -rf $STAGING/$SRC_DIR/$p + if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): EXCLUDE_LIST_FROM_TAR: could not remove file: '$p'" + exit 1 + fi + done + +fi + +TRANSFORM=`echo "$SRC_DIR" | sed 's/^\./\\./' | sed 's:^/::'` + +if [ "x$STAGING" != "x" ]; then + pushd $STAGING +fi + +TAR_NEEDED=0 +if [ "x$SRC_DIR" != "x" ]; then + echo "SRC_DIR=$SRC_DIR" + if [ -f $TAR_PATH ]; then + n=`find . -cnewer $TAR_PATH -and ! -path './.git*' \ + -and ! -path './build/*' \ + -and ! -path './.pc/*' \ + -and ! -path './patches/*' \ + -and ! -path "./$DISTRO/*" \ + -and ! -path './pbr-*.egg/*' \ + | wc -l` + if [ $n -gt 0 ]; then + TAR_NEEDED=1 + fi + else + TAR_NEEDED=1 + fi +fi + +if [ $TAR_NEEDED -gt 0 ]; then + echo "Creating tar file: $TAR_PATH ..." + tar chzf $TAR_PATH $SRC_DIR --exclude '.git*' --exclude 'build' --exclude='.pc' --exclude='patches' --exclude="$SRC_DIR/$DISTRO" --exclude='pbr-*.egg' --transform "s,^$TRANSFORM,$TAR_NAME-$VERSION," + if [ $? -ne 0 ]; then + if [ "x$STAGING" != "x" ]; then + popd + fi + + echo "ERROR: restapi_build_srpm (${LINENO}): failed to create tar file, cmd: tar chzf $TAR_PATH $SRC_DIR --exclude '.git*' --exclude 'build' --exclude='.pc' --exclude='patches' --exclude="$SRC_DIR/$DISTRO" --exclude='pbr-*.egg' --transform \"s,^$TRANSFORM,$TAR_NAME-$VERSION,\"" + exit 1 + fi + echo "Created tar file: $TAR_PATH" +else + echo "Tar file not needed." +fi + +if [ "x$STAGING" != "x" ]; then + popd +fi + +for SPEC in `ls $BUILD_DIR/SPECS`; do + SPEC_PATH="$BUILD_DIR/SPECS/$SPEC" + RELEASE=`spec_find_tag Release "$SPEC_PATH" 2>> /dev/null` + if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): 'Release' not found in '$SPEC_PATH'" + fi + NAME=`spec_find_tag Name "$SPEC_PATH" 2>> /dev/null` + if [ $? -ne 0 ]; then + echo "ERROR: restapi_build_srpm (${LINENO}): 'Name' not found in '$SPEC_PATH'" + fi + SRPM="$NAME-$VERSION-$RELEASE.src.rpm" + SRPM_PATH="$BUILD_DIR/SRPMS/$SRPM" + + spec_validate_tis_release $SPEC_PATH + if [ $? -ne 0 ]; then + echo "TIS Validation of $SPEC_PATH failed" + exit 1 + fi + + BUILD_NEEDED=0 + if [ -f $SRPM_PATH ]; then + n=`find . -cnewer $SRPM_PATH | wc -l` + if [ $n -gt 0 ]; then + BUILD_NEEDED=1 + fi + else + BUILD_NEEDED=1 + fi + + if [ $BUILD_NEEDED -gt 0 ]; then + echo "SPEC file: $SPEC_PATH" + echo "SRPM build directory: $BUILD_DIR" + echo "TIS_PATCH_VER: $TIS_PATCH_VER" + + sed -i -e "1 i%define _tis_build_type $BUILD_TYPE" $SPEC_PATH + sed -i -e "1 i%define tis_patch_ver $TIS_PATCH_VER" $SPEC_PATH + rpmbuild -bs $SPEC_PATH --define="%_topdir $BUILD_DIR" --undefine=dist --define="_tis_dist .tis" + else + echo "SRPM build not needed" + fi +done + diff --git a/restapi-doc/centos/build_srpm.data b/restapi-doc/centos/build_srpm.data new file mode 100644 index 000000000..baedcd9dd --- /dev/null +++ b/restapi-doc/centos/build_srpm.data @@ -0,0 +1,7 @@ +SRC_DIR=restapi-doc +COPY_LIST="$SRC_DIR/* \ + $CGCS_BASE/downloads/mvn.repo.tgz \ + " + +TIS_PATCH_VER=22 +BUILD_IS_SLOW=3 diff --git a/restapi-doc/centos/restapi-doc.spec b/restapi-doc/centos/restapi-doc.spec new file mode 100644 index 000000000..719273140 --- /dev/null +++ b/restapi-doc/centos/restapi-doc.spec @@ -0,0 +1,32 @@ +Summary: RestAPI-Doc +Name: restapi-doc +Version: 1.8.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: devel +Packager: Wind River +URL: unknown +BuildRequires: git maven + +Source0: %{name}-%{version}.tar.gz +Source1: mvn.repo.tgz + +%define cgcs_sdk_deploy_dir /opt/deploy/cgcs_sdk +%define debug_package %{nil} + +%description +RestAPI-doc files + +%prep +%setup +cp %{SOURCE1} %{_builddir}/%{name}-%{version} + +%build +make -j"%(nproc)" + +%install +install -D -m 644 wrs-%{name}-%{version}.tgz %{buildroot}%{cgcs_sdk_deploy_dir}/wrs-%{name}-%{version}.tgz + +%files +%{cgcs_sdk_deploy_dir}/wrs-%{name}-%{version}.tgz + diff --git a/restapi-doc/restapi-doc/.gitignore b/restapi-doc/restapi-doc/.gitignore new file mode 100644 index 000000000..153aca65b --- /dev/null +++ b/restapi-doc/restapi-doc/.gitignore @@ -0,0 +1,21 @@ +.DS_Store +*.xpr +*.tgz + +# Build results +publish-docs/ +target/ +/build-*.log.gz +/generated + +# Packages +*.egg +*.egg-info + +# Testenvironment +.tox + +# Editors +*~ +.*.swp +.bak diff --git a/restapi-doc/restapi-doc/LICENSE b/restapi-doc/restapi-doc/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/restapi-doc/restapi-doc/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/restapi-doc/restapi-doc/Makefile b/restapi-doc/restapi-doc/Makefile new file mode 100644 index 000000000..1469590c4 --- /dev/null +++ b/restapi-doc/restapi-doc/Makefile @@ -0,0 +1,32 @@ +# increment this every release +API_VERSION := "1.8.0" + +build: + @git status > /dev/null ; \ + if [ $$? -ne 0 ] ; then \ + echo CREATING DUMMY GIT ; \ + git init ; \ + fi + + if [ ! -e mvn.repo.tgz ]; then \ + echo "Maven Cache Not Found!" ; \ + exit 1 ; \ + fi + + mkdir -p mvn.repo + tar -xvzf ./mvn.repo.tgz -C ./mvn.repo/ + mvn clean generate-sources -o -Dmaven.repo.local=./mvn.repo/ + + mkdir -p target/wrs-restapi-doc-$(API_VERSION)/ + cp rest-api-usage-example.pdf target/wrs-restapi-doc-$(API_VERSION)/ + cp -R api-ref-guides/target/docbkx/pdf target/wrs-restapi-doc-$(API_VERSION)/ + cp -R api-ref/target/docbkx/html target/wrs-restapi-doc-$(API_VERSION)/ + cd target; tar -czvf ../wrs-restapi-doc-$(API_VERSION).tgz wrs-restapi-doc-$(API_VERSION) + @echo 'wrs-restapi-doc-$(API_VERSION).tgz' is ready + +clean: + mvn clean -o -Dmaven.repo.local=./mvn.repo/ + rm -f wrs-restapi-doc-*.tgz + rm -rf target + + rm -rf mvn.repo diff --git a/restapi-doc/restapi-doc/Makefile.cache b/restapi-doc/restapi-doc/Makefile.cache new file mode 100644 index 000000000..e487a35f9 --- /dev/null +++ b/restapi-doc/restapi-doc/Makefile.cache @@ -0,0 +1,26 @@ +# increment this every release +API_VERSION := "1.6.0" + +build: + @git status > /dev/null ; \ + if [ $$? -ne 0 ] ; then \ + echo CREATING DUMMY GIT ; \ + git init ; \ + fi + + mvn clean generate-sources dependency:go-offline -Dmaven.repo.local=./mvn.repo/ + cd mvn.repo && tar -czvf ../mvn.repo.tgz . && cd .. + + mkdir -p target/wrs-restapi-doc-$(API_VERSION)/ + cp rest-api-usage-example.pdf target/wrs-restapi-doc-$(API_VERSION)/ + cp -R api-ref-guides/target/docbkx/pdf target/wrs-restapi-doc-$(API_VERSION)/ + cp -R api-ref/target/docbkx/html target/wrs-restapi-doc-$(API_VERSION)/ + cd target; tar -czvf ../wrs-restapi-doc-$(API_VERSION).tgz wrs-restapi-doc-$(API_VERSION) + @echo 'wrs-restapi-doc-$(API_VERSION).tgz' is ready + +clean: + mvn clean -o -Dmaven.repo.local=./mvn.repo/ + rm -f wrs-restapi-doc-*.tgz + rm -rf target + + rm -rf mvn.repo diff --git a/restapi-doc/restapi-doc/README.mvn_cache b/restapi-doc/restapi-doc/README.mvn_cache new file mode 100644 index 000000000..c5502472c --- /dev/null +++ b/restapi-doc/restapi-doc/README.mvn_cache @@ -0,0 +1,18 @@ +Steps to produce mvn.repo.tgz [Maven cache] +=================== + + +cd $MY_REPO/addons/wr-cgcs/layers/cgcs/recipes-restapi-doc/restapi-doc/restapi-doc +cp Makefile Makefile.backup +cp Makefile.mvn_cache Makefile +build_srpms restapi-doc +mock -r $MY_BUILD_CFG_STD "FILE_NAME_TO_THE_BUILT_SRPM" +mock -r $MY_BUILD_CFG_STD --copyout /builddir/build/BUILD/restapi-doc-1.6.0/mvn.repo.tgz ~/ +cp ~/mvn.repo.tgz $MY_REPO/addons/wr-cgcs/layers/cgcs/downloads/ +cd $MY_REPO/addons/wr-cgcs/layers/cgcs/downloads/ + +# only the first time +# ln -s ../../../downloads/mvn.repo.tgz mvn.repo.tgz + +cp Makefile.backup Makefile + diff --git a/restapi-doc/restapi-doc/api-ref-guides/pom.xml b/restapi-doc/restapi-doc/api-ref-guides/pom.xml new file mode 100644 index 000000000..b401e41ff --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/pom.xml @@ -0,0 +1,171 @@ + + + + org.openstack.docs + parent-pom + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + titanium-api-ref-guides + jar + Titanium REST API Reference Guide + + + local + 0 + + + + + + + src + + + locale + + + + + com.rackspace.cloud.api + clouddocs-maven-plugin + + + + + os-api-ref + + generate-pdf + + generate-sources + + bk-api-ref.xml + api-ref + + + + os-api-ref-compute-v2-cgcs-ext + + generate-pdf + + generate-sources + + bk-api-ref-compute-v2-cgcs-ext.xml + api-ref-compute-v2-cgcs-ext + + + + os-api-ref-networking-v2-cgcs-ext + + generate-pdf + + generate-sources + + bk-api-ref-networking-v2-cgcs-ext.xml + api-ref-networking-v2-cgcs-ext + + + + os-api-ref-telemetry-v2-cgcs-ext + + generate-pdf + + generate-sources + + bk-api-ref-telemetry-v2-cgcs-ext.xml + api-ref-telemetry-v2-cgcs-ext + + + + os-api-ref-image-v2-cgcs-ext + + generate-pdf + + generate-sources + + bk-api-ref-image-v2-cgcs-ext.xml + api-ref-image-v2-cgcs-ext + + + + os-api-ref-sysinv-v1 + + generate-pdf + + generate-sources + + bk-api-ref-sysinv-v1.xml + api-ref-sysinv-v1 + + + + os-api-ref-patching-v1 + + generate-pdf + + generate-sources + + bk-api-ref-patching-v1.xml + api-ref-patching-v1 + + + + os-api-ref-blockstorage-v2 + + generate-pdf + + generate-sources + + bk-api-ref-blockstorage-v2-cgcs-ext.xml + bk-api-ref-blockstorage-v2 + + + + os-api-ref-nfv-vim-v1 + + generate-pdf + + generate-sources + + bk-api-ref-nfv-vim-v1.xml + api-ref-nfv-vim-v1 + + + + + + api-ref-guides + appendix toc,title + article/appendix nop + article toc,title + book toc,title + part toc,title + qandadiv toc + qandaset to + reference toc,title + set toc,title + true + src + openstack + 1 + true + false + external + 0 + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-blockstorage-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-blockstorage-v2-cgcs-ext.xml new file mode 100644 index 000000000..40ed0ac7f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-blockstorage-v2-cgcs-ext.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + OpenStack Block Storage API v2 Titanium Extensions + API Reference + + + + + + + Wind River + + + + 2015 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-compute-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-compute-v2-cgcs-ext.xml new file mode 100644 index 000000000..0c1a5129b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-compute-v2-cgcs-ext.xml @@ -0,0 +1,56 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + OpenStack Compute API v2 Titanium extensions + API Reference + + + + + + + Wind River + + + + 2014 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-image-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-image-v2-cgcs-ext.xml new file mode 100644 index 000000000..6bf62e1ed --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-image-v2-cgcs-ext.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + OpenStack Image API v2 cgcs extensions + API Reference + + + + + + + Wind River + + + + 2016 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-networking-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-networking-v2-cgcs-ext.xml new file mode 100644 index 000000000..17c337e95 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-networking-v2-cgcs-ext.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + OpenStack Networking API v2 Titanium extensions + API Reference + + + + + + + Wind River + + + + 2014 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-nfv-vim-v1.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-nfv-vim-v1.xml new file mode 100644 index 000000000..c6cb7ff22 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-nfv-vim-v1.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + Titanium NFV VIM API v1 + API Reference + + + + + + + Wind River + + + + 2016 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-patching-v1.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-patching-v1.xml new file mode 100755 index 000000000..d8f304693 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-patching-v1.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + Titanium Patching API v1 + API Reference + + + + + + + Wind River + + + + 2014 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-sysinv-v1.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-sysinv-v1.xml new file mode 100644 index 000000000..b6882b29b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-sysinv-v1.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + Titanium SysInv API v1 + API Reference + + + + + + + Wind River + + + + 2014 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-telemetry-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-telemetry-v2-cgcs-ext.xml new file mode 100644 index 000000000..63690d8d1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref-telemetry-v2-cgcs-ext.xml @@ -0,0 +1,57 @@ + + + + + + + + + +GET'> +PUT'> +POST'> +DELETE'> +]> + + + OpenStack Telemetry API v2 cgcs extensions + API Reference + + + + + + + Wind River + + + + 2014 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref.xml b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref.xml new file mode 100644 index 000000000..79d73091f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/bk-api-ref.xml @@ -0,0 +1,51 @@ + + + + + Titanium Cloud REST API + Titanium Cloud REST API + + + + + + + Wind River + + + + 2014-2016 + Wind River + + Titanium Cloud + + + + Copyright details are filled in by the + template. + + + + + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref-guides/src/preface.xml b/restapi-doc/restapi-doc/api-ref-guides/src/preface.xml new file mode 100644 index 000000000..50736f031 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref-guides/src/preface.xml @@ -0,0 +1,35 @@ + + + + +]> + + Preface + Use the Titanium System Inventory APIs and the Titanium + extensions to OpenStack APIs to manager your Titnaium Server + cloud. + + After you authenticate through the Identity API, + you can use the other APIs and extensions to manage controller/compute/storage + nodes, launch server instances, create images, assign metadata to instances and + images, create containers and objects, and complete other + actions in your Titanium Cloud cloud. To get started with the APIs, + see the OpenStack API Quick Start. +   + diff --git a/restapi-doc/restapi-doc/api-ref/.htaccess b/restapi-doc/restapi-doc/api-ref/.htaccess new file mode 100644 index 000000000..e69de29bb diff --git a/restapi-doc/restapi-doc/api-ref/locale/api-ref.pot b/restapi-doc/restapi-doc/api-ref/locale/api-ref.pot new file mode 100644 index 000000000..22281b46a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/locale/api-ref.pot @@ -0,0 +1,1832 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2014-08-13 06:06+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ./api-ref/src/docbkx/api-ref-compute-v2-ext.xml:11(title) +msgid "OpenStack Compute API v2 extensions" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-compute-v2-ext.xml:13(year) ./api-ref/src/docbkx/api-ref-identity-v3.xml:13(year) ./api-ref/src/docbkx/api-ref-blockstorage-v1.xml:13(year) ./api-ref/src/docbkx/api-ref-objectstorage-v1.xml:13(year) ./api-ref/src/docbkx/api-ref.xml:13(year) ./api-ref/src/docbkx/api-ref-image-v2.xml:13(year) ./api-ref/src/docbkx/api-ref-orchestration-v1.xml:13(year) ./api-ref/src/docbkx/api-ref-networking-v2.xml:13(year) ./api-ref/src/docbkx/api-ref-compute-v2.xml:13(year) ./api-ref/src/docbkx/api-ref-image-v1.xml:13(year) ./api-ref/src/docbkx/api-ref-telemetry-v2.xml:13(year) ./api-ref/src/docbkx/api-ref-blockstorage-v2.xml:13(year) ./api-ref/src/docbkx/api-ref-identity-v2.xml:13(year) ./api-ref/src/docbkx/api-ref-databases-v1.xml:13(year) ./api-ref/src/docbkx/api-ref-compute-v3.xml:13(year) +msgid "2010-2014" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:7(title) +msgid "Identity admin API v2.0 (STABLE)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:8(para) +msgid "Get an authentication token that permits access to the Compute API." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:10(title) +msgid "Versions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:18(title) ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:8(title) ./api-ref/src/docbkx/ch_compute-v2.xml:38(title) ./api-ref/src/docbkx/ch_identity-v2.xml:27(title) +msgid "Extensions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:29(title) ./api-ref/src/docbkx/ch_identity-v2.xml:40(title) ./api-ref/src/docbkx/ch_identity-v3.xml:24(title) +msgid "Tokens" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:41(title) ./api-ref/src/docbkx/ch_identity-v3.xml:167(title) +msgid "Users" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml:62(title) +msgid "Tenants" +msgstr "" + +#: ./api-ref/src/docbkx/preface.xml:9(title) +msgid "OpenStack API Complete Reference" +msgstr "" + +#: ./api-ref/src/docbkx/preface.xml:10(para) +msgid "Use the OpenStack APIs and extensions to launch server instances, create images, assign metadata to instances and images, create containers and objects, and complete other actions in your OpenStack cloud." +msgstr "" + +#: ./api-ref/src/docbkx/preface.xml:14(para) +msgid "The API status reflects the state of the endpoint on the service. CURRENT is a stable version that is up-to-date, recent, and might receive future versions. This endpoint should be prioritized over all others. SUPPORTED is a stable version that is available on the server. However, it is not likely the most recent available and might not be updated or might be deprecated at some time in the future. DEPRECATED is a stable version that is still available but is being deprecated and might be removed in the future. EXPERIMENTAL is not a stable version. This version is under development or contains features that are otherwise subject to change. For more information about API status values and version information, see Version Discovery." +msgstr "" + +#: ./api-ref/src/docbkx/preface.xml:32(para) +msgid "You must install the packages for each API separately. You can use the APIs and extensions after you authenticate through the Identity API:" +msgstr "" + +#: ./api-ref/src/docbkx/preface.xml:41(para) +msgid "To get started with the APIs, see the OpenStack API Quick Start." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:10(title) ./api-ref/src/docbkx/itemizedlist-service-list.xml:48(link) +msgid "Image Service API v1 (SUPPORTED)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:11(para) +msgid "Load images for use at launch time by the Compute API. Also, assign metadata to images." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:13(para) +msgid "Some cloud implementations do not expose this API and offer pretested images only." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:15(para) ./api-ref/src/docbkx/ch_images-v2.xml:11(para) +msgid "Cloud providers can configure property protections that prevent non-administrative users from updating and deleting protected properties. For more information, see Image property protection in the OpenStack Cloud Administrator Guide." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:23(title) ./api-ref/src/docbkx/ch_compute-v2.xml:17(title) ./api-ref/src/docbkx/ch_netconn-v2.xml:20(title) ./api-ref/src/docbkx/ch_identity-v2.xml:14(title) ./api-ref/src/docbkx/ch_databases-v1.xml:11(title) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:14(title) ./api-ref/src/docbkx/ch_orchestration-v1.xml:13(title) ./api-ref/src/docbkx/ch_images-v2.xml:19(title) ./api-ref/src/docbkx/ch_compute-v3.xml:21(title) ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:45(title) ./api-ref/src/docbkx/ch_identity-v3.xml:11(title) +msgid "API versions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:37(title) ./api-ref/src/docbkx/ch_compute-v2.xml:230(title) ./api-ref/src/docbkx/ch_images-v2.xml:28(title) +msgid "Images" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:57(title) ./api-ref/src/docbkx/ch_images-v2.xml:69(title) +msgid "Members" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v1.xml:71(title) +msgid "Shared images" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-identity-v3.xml:11(title) +msgid "OpenStack Identity API v3 and extensions" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-blockstorage-v1.xml:11(title) +msgid "OpenStack Block Storage API v1" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:6(title) +msgid "Networking API v2.0 extensions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:9(para) +msgid "List available Networking API v2.0 extensions and show details for a specified extension." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:21(title) +msgid "Quotas extension (quotas)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:22(para) +msgid "List, show information for, update, and reset quotas." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:33(title) +msgid "Networks provider extended attributes (networks)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:34(para) +msgid "List, create, show information for, update, and delete networks." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:48(title) +msgid "Networks multiple provider extension (networks)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:49(para) +msgid "Enables administrative users to define multiple physical bindings for an OpenStack Networking network and list or show details for networks with multiple physical bindings." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:52(para) +msgid "You cannot update any provider attributes. If you try to do so, an error occurs." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:54(para) +msgid "To delete a network with multiple physical bindings, issue a normal delete network request." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:56(para) +msgid "To define multiple physical bindings for a network, include a segments list in the request body of a POST /v2.0/networks request. Each element in the segments list has the same structure as the provider network attributes. These attributes are provider:network_type, provider:physical_network, and provider:segmentation_id. The validation rules for these attributes are the same as for the Networks provider extended attributes. You cannot use both extensions at the same time." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:67(para) +msgid "The NSX and ML2 plug-ins support this extension. With the ML2 plug-in, you can specify multiple VLANs for a specified network, a VXLAN tunnel ID, and a VLAN." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:73(title) +msgid "Ports binding extended attributes (ports)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:74(para) +msgid "List, create, show information for, and update ports." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:87(title) +msgid "Security groups and rules (security-groups)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:88(para) +msgid "List, create, show information for, and delete security groups and security group rules." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:112(title) +msgid "Layer-3 networking" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:113(para) +msgid "Route packets between subnets, forward packets from internal networks to external ones, and access instances from external networks through floating IPs." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:115(para) +msgid "This extension introduces these resources:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:118(para) +msgid "router. A logical entity for forwarding packets across internal subnets and NATting them on external networks through an appropriate external gateway." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:123(para) +msgid "floatingip. An external IP address that is mapped to a port that is attached to an internal network." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:131(title) +msgid "Metering labels and rules" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:132(para) +msgid "Create, modify, and delete OpenStack Layer3 Metering labels and rules." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:137(title) +msgid "Load-Balancer-as-a-Service (LBaaS)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:138(para) +msgid "The LBaaS extension enables OpenStack tenants to load-balance their VM traffic. The extension enables you to load-balance client traffic from one network to application services, such as VMs, on the same or a different network. You can load-balance several protocols, such as TCP and HTTP and monitor the health of application services. The LBaaS extension supports session persistence." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:144(caption) +msgid "Load balancer statuses" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:150(th) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:45(th) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:147(th) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:266(th) +msgid "Status" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:151(th) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:46(th) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:148(th) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:267(th) +msgid "Description" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:152(th) +msgid "Operational" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:157(td) +msgid "DEFERRED" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:158(td) +msgid "An entity was created but is not yet linked to a load balancer." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:159(td) ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:164(td) ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:174(td) ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:184(td) +msgid "No" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:162(td) +msgid "PENDING_CREATE" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:163(td) +msgid "An entity is being created." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:167(td) +msgid "PENDING_UPDATE" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:168(td) +msgid "An entity was updated. It remains in an operational state." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:169(td) ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:179(td) +msgid "Yes" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:172(td) +msgid "PENDING_DELETE" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:173(td) +msgid "An entity is in the process of being deleted." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:177(td) +msgid "ACTIVE" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:178(td) +msgid "An entity is in a normal operational state." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:182(td) +msgid "INACTIVE" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:183(td) +msgid "Applies to members that fail health checks." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:187(td) +msgid "ERROR" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:188(td) +msgid "Something has gone wrong." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:189(td) +msgid "This might be in either an operational or non-operational state." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml:193(para) +msgid "Use this extension to create and manage load balancers, listeners, pools, members, and health monitors." +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-objectstorage-v1.xml:11(title) +msgid "OpenStack Object Storage API v1" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:12(link) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:10(title) +msgid "Block Storage API v2 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:16(link) ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:10(title) +msgid "Block Storage API v1 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:20(link) ./api-ref/src/docbkx/ch_compute-v2.xml:9(title) +msgid "Compute API v2 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:24(link) ./api-ref/src/docbkx/ch_compute-v2-ext.xml:13(title) +msgid "Compute API v2 extensions (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:28(link) ./api-ref/src/docbkx/ch_compute-v3.xml:14(title) +msgid "Compute API v3 (EXPERIMENTAL)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:32(link) +msgid "Database Service API v1.0 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:36(link) ./api-ref/src/docbkx/ch_identity-v3.xml:7(title) +msgid "Identity API v3 (STABLE)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:40(link) ./api-ref/src/docbkx/ch_identity-v2.xml:10(title) +msgid "Identity API v2.0 (STABLE)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:44(link) ./api-ref/src/docbkx/ch_images-v2.xml:9(title) +msgid "Image Service API v2 (SUPPORTED)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:52(link) ./api-ref/src/docbkx/ch_netconn-v2.xml:9(title) +msgid "Networking API v2.0 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:56(link) ./api-ref/src/docbkx/ch_objectstorage-v1.xml:9(title) +msgid "Object Storage API v1 (SUPPORTED)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:61(link) ./api-ref/src/docbkx/ch_orchestration-v1.xml:9(title) +msgid "Orchestration API v1 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml:64(link) ./api-ref/src/docbkx/ch_telemetry-v2.xml:9(title) +msgid "Telemetry API v2 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref.xml:11(title) +msgid "OpenStack API Reference" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:14(para) +msgid "Extensions add features, MIME types, actions, states, headers, parameters, and resources to the core Compute API without requiring a version change." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:17(para) ./api-ref/src/docbkx/ch_compute-v2.xml:13(para) +msgid "XML support in requests and responses has been deprecated for the Compute API v2." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:20(title) +msgid "Server admin actions (action)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:21(para) +msgid "Administrator only. Perform actions on a server. Specify the action in the request body." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:28(title) +msgid "Server diagnostics (diagnostics)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:29(para) +msgid "Get the usage data for a server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:35(title) +msgid "Flavor access (flavors)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:36(para) +msgid "Create and get details for private flavors. Also, list, add, and remove tenants' access to private flavors." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:43(title) +msgid "Flavors with FlavorDisabled attribute (flavors)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:44(para) +msgid "Get details for a flavor, and list details for available flavors. Includes the OS-FLV-DISABLED:disabled extended attribute." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:53(title) +msgid "Flavor extra-specs (os-extra-specs)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:54(para) +msgid "List, create, and update the extra-specs or keys for a flavor." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:61(title) +msgid "Flavors with rxtx_factor extended attribute (flavors)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:63(para) +msgid "Create, get details for, and list details for flavors. Includes the rxtx_factor extended attribute, related to configured bandwidth cap values." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:72(title) ./api-ref/src/docbkx/ch_compute-v3.xml:158(title) +msgid "Flavors with extended attributes (flavors)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:73(para) +msgid "Create, get details for, and list details for flavors. Includes the rxtx_factor, OS-FLV-EXT-DATA:ephemeral, and swap extended attributes." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:82(title) +msgid "Flavors create or delete (flavors)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:83(para) +msgid "Create or delete flavors." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:89(title) +msgid "Images with size attribute (images)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:90(para) +msgid "List details for available images or get details for a specified image. Includes the OS-EXT-IMG-SIZE:size extended attribute, which shows the image size." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:99(title) +msgid "Limits with project usage (limits)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:100(para) +msgid "Extend limits to show the project usage. Show information such as RAM or instance quotas usage." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:107(title) +msgid "Limits with project usage for administrators (limits)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:109(para) +msgid "Extend limits to enable administrators to show the project usage for a specified customer project ID. Show information such as RAM or instance quotas usage." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:117(title) ./api-ref/src/docbkx/ch_compute-v3.xml:43(title) +msgid "Guest agents (os-agents)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:118(para) +msgid "Create, update, and delete guest agents. Use guest agents to access files on the disk, configure networking, or run other applications or scripts in the guest while it runs. This hypervisor-specific extension is not currently enabled for KVM. Use of guest agents is possible only if the underlying service provider uses the Xen driver." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:130(title) ./api-ref/src/docbkx/ch_compute-v3.xml:55(title) +msgid "Host aggregates (os-aggregates)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:131(para) +msgid "Create and manage host aggregates. An aggregate assigns metadata to groups of compute nodes. Aggregates are only visible to the cloud provider." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:139(title) +msgid "Attach interfaces (os-interface)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:140(para) +msgid "Create, list, get details for, and delete port interfaces." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:147(title) ./api-ref/src/docbkx/ch_compute-v3.xml:73(title) +msgid "Root certificates (os-certificates)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:148(para) +msgid "Create and show details for a root certificate." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:154(title) +msgid "Cloudpipe (os-cloudpipe)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:155(para) +msgid "Manage virtual VPNs for projects." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:161(title) +msgid "Server console output (os-console-output)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:162(para) +msgid "Get console output for a server instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:168(title) +msgid "Server console (os-consoles)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:169(para) +msgid "Get a console for a server instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:175(title) +msgid "Coverage reports (os-coverage)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:181(title) ./api-ref/src/docbkx/ch_compute-v3.xml:88(title) +msgid "Server deferred delete (os-deferred-delete)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:182(para) +msgid "Force-delete a server or restore a deleted server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:189(title) +msgid "Fixed IPs (os-fixed-ips)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:190(para) +msgid "Show data for a specified fixed IP, such as host name, CIDR, and address. Also, reserve or free a fixed IP." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:198(title) +msgid "Floating IP DNS records (os-floating-ip-dns)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:199(para) +msgid "Manage DNS records associated with IP addresses allocated by the floating IPs extension. Requests are dispatched to a DNS driver selected at startup." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:207(title) +msgid "Floating IP pools (os-floating-ip-pools)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:208(para) +msgid "Manage groups of floating IPs." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:214(title) +msgid "Floating IPs (os-floating-ips)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:215(para) +msgid "Assign and allocate floating IP addresses to instances that run in an OpenStack cloud." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:222(title) +msgid "Floating IPs bulk (os-floating-ips-bulk)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:223(para) +msgid "Bulk-create, delete, and list floating IPs. By default, the pool is named nova. Use the os-floating-ip-pools extension to view available pools." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:232(title) ./api-ref/src/docbkx/ch_compute-v3.xml:165(title) +msgid "Hosts (os-hosts)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:233(para) +msgid "Manage physical hosts." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:239(title) ./api-ref/src/docbkx/ch_compute-v3.xml:172(title) +msgid "Hypervisors (os-hypervisors)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:240(para) +msgid "Display extra statistical information from the machine that hosts the hypervisor through the API for the hypervisor (XenAPI or KVM/libvirt)." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:267(title) +msgid "Server actions (os-instance-actions)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:268(para) +msgid "List available actions for a specified server. Administrators can get details for a specified action for a specified server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:276(title) +msgid "Keypairs (os-keypairs)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:277(para) +msgid "Generate, import, and delete SSH keys." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:283(title) ./api-ref/src/docbkx/ch_compute-v3.xml:205(title) +msgid "Migrations (os-migrations)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:284(para) +msgid "Administrators only. Fetch in-progress migrations for a region or a specified cell in a region." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:291(title) +msgid "Networks (os-networks)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:292(para) +msgid "Show network information for or delete networks. Also, disassociate a network from a project if you use vlan mode." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:300(title) ./api-ref/src/docbkx/ch_compute-v3.xml:226(title) +msgid "Quota sets (os-quota-sets)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:301(para) +msgid "Administrators only, depending on policy settings. View quotas for a tenant and view and update default quotas." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:309(title) +msgid "Rules for default security group (os-security-group-default-rules)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:311(para) +msgid "List, show information for, and create default security group rules." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:318(title) +msgid "Security groups (os-security-groups)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:319(para) +msgid "List, show information for, create, and delete security groups." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:326(title) +msgid "Server groups (os-server-groups)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:327(para) +msgid "List, show information for, create, and delete server groups." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:343(title) +msgid "Server password (os-server-password)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:344(para) +msgid "Get and reset the encrypted administrative password set through the metadata service." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:351(title) +msgid "Server shelve (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:352(para) +msgid "Shelve running servers, restore shelved servers, and remove shelved servers." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:354(para) +msgid "Shelving is useful when you have an instance that you are not using but would like retain in your list of servers. For example, you can stop an instance at the end of a work week and resume work at the start of the next week. Use the shelve action to shelve a server. All associated data and resources are kept; however, anything still in memory is not retained. You can restore a shelved instance by using the unshelve action. If a shelved instance is no longer needed, you can remove it by using the shelveOffload action." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:370(title) +msgid "Server start and stop (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:371(para) +msgid "Start a stopped server or stop a running server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:377(title) +msgid "Manage services (os-services)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:378(para) +msgid "List, enable, and disable Compute services in all hosts." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:385(title) ./api-ref/src/docbkx/ch_compute-v3.xml:249(title) +msgid "Usage reports (os-simple-tenant-usage)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:386(para) +msgid "Report usage statistics on compute and storage resources." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:393(title) +msgid "Virtual interfaces (os-virtual-interfaces)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:394(para) +msgid "List the virtual interfaces for a specified server instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:401(title) +msgid "Volume extension (os-volumes, os-snapshots)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:402(para) +msgid "Manage volumes and snapshots for use with the Compute API." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:409(title) +msgid "Volume attachments (os-volume_attachments)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:410(para) +msgid "Attach volumes created through the volume API to server instances. Also, list volume attachments for a server instance, get volume details for a volume attachment, and delete a volume attachment." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:419(title) +msgid "Servers with block device mapping format (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:421(para) +msgid "Create a server with a block device mapping." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:427(title) +msgid "Server OS-EXT-IPS-MAC:mac_addr extended attribute (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:429(para) +msgid "Add OS-EXT-IPS-MAC:mac_addr extended attribute when you create, show information for, or list servers." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:436(title) +msgid "Configuration drive (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:437(para) +msgid "Extend servers and images with a configuration drive." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:444(title) +msgid "Servers with extended availability zones (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:446(para) +msgid "Show the instance availability zone for compute nodes (nova-compute). Internal services appear in their own internal availability zone." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:455(title) +msgid "Servers and images with disk config (servers, images)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:457(para) +msgid "Extend servers with the diskConfig attribute." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:463(title) +msgid "Server IP type (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:464(para) +msgid "Show the type of the IP addresses assigned to an instance. Type is either fixed or floating." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:471(title) +msgid "Server extended attributes (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:472(para) +msgid "Show metadata for servers." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:478(title) +msgid "Server extended status (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:479(para) +msgid "Show extended status information, vm_state, task_state, and power_state, in detailed server responses." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:486(title) +msgid "Servers multiple create (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:487(para) +msgid "Create one or more servers with an optional reservation ID. The request and response examples show how to create multiple servers with or without a reservation ID." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:495(title) +msgid "Server rescue and unrescue (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:496(para) +msgid "Put a server into rescue mode or unrescue a server in rescue mode." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:503(title) +msgid "Servers with scheduler hints (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml:504(para) +msgid "Create a server with scheduler hints." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:10(para) +msgid "Launch virtual machines from images or images stored on persistent volumes. API v1.1 is identical to API v2." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:18(para) +msgid "List information for all API versions and show details about API v2." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:29(title) +msgid "Limits" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:30(para) +msgid "Get rate and absolute limits." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:39(para) +msgid "List available Compute API v2 extensions and show details for a specified extension." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:51(title) +msgid "Servers" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:52(para) +msgid "List, create, get details for, update, and delete servers." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:55(emphasis) +msgid "Passwords" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:56(para) +msgid "When you create a server, you can specify a password through the optional adminPass attribute. The specified password must meet the complexity requirements set by your OpenStack Compute provider. The server might enter an ERROR state if the complexity requirements are not met. In this case, a client might issue a change password action to reset the server password." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:62(para) +msgid "If you do not specify a password, a randomly generated password is assigned and returned in the response object. This password is guaranteed to meet the security requirements set by the compute provider. For security reasons, the password is not returned in subsequent calls." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:70(emphasis) ./api-ref/src/docbkx/ch_compute-v2.xml:172(title) +msgid "Server metadata" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:71(para) +msgid "You can specify custom server metadata at server launch time. The maximum size for each metadata key-value pair is 255 bytes. The maximum number of key-value pairs that can be supplied per server is determined by the compute provider. You can query this value through the maxServerMeta absolute limit." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:80(emphasis) +msgid "Server networks" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:81(para) +msgid "You can specify networks to which the server connects at launch time. You can specify one or more networks. Users can also specify a specific port on the network or the fixed IP address to assign to the server interface." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:85(para) +msgid "You can use both IPv4 and IPv6 addresses as access addresses and you can assign both addresses simultaneously. You can update access addresses after you create a server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:93(emphasis) +msgid "Server personality" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:94(para) +msgid "You can customize the personality of a server instance by injecting data into its file system. For example, you might want to insert ssh keys, set configuration files, or store data that you want to retrieve from inside the instance. This feature provides a minimal amount of launch-time personalization. If you require significant customization, create a custom image." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:99(para) +msgid "Follow these guidelines when you inject files:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:102(para) +msgid "The maximum size of the file path data is 255 bytes." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:105(para) +msgid "Encode the file contents as a Base64 string. The compute providers determines the maximum size of the file contents. This value can vary based on the image that is used to create the server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:109(para) +msgid "The maximum limit refers to the number of bytes in the decoded data and not to the number of characters in the encoded data." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:114(para) +msgid "You can inject text files only. You cannot inject binary or ZIP files into a new build." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:118(para) +msgid "The maximum number of file path/content pairs that you can supply is also determined by the compute provider and is defined by the maxPersonality absolute limit." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:123(para) +msgid "The absolute limit, maxPersonalitySize, is a byte limit that is guaranteed to apply to all images in the deployment. Providers can set additional per-image personality limits." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:128(para) +msgid "The file injection might not occur until after the server is built and booted." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:130(para) +msgid "During file injection, any existing files that match specified files are renamed to include the BAK extension appended with a time stamp. For example, if the /etc/passwd file exists, it is backed up as /etc/passwd.bak.1246036261.5785." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:134(para) +msgid "After file injection, personality files are accessible by only system administrators. For example, on Linux, all files have root and the root group as the owner and group owner, respectively, and allow user and group read access only ( )." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:142(emphasis) +msgid "Server access addresses" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:143(para) +msgid "In a hybrid environment, the IP address of a server might not be controlled by the underlying implementation. Instead, the access IP address might be part of the dedicated hardware; for example, a router/NAT device. In this case, the addresses provided by the implementation cannot actually be used to access the server (from outside the local LAN). Here, a separate access address might be assigned at creation time to provide access to the server. This address might not be directly bound to a network interface on the server and might not necessarily appear when you query the server addresses. See . Nonetheless, clients that must access the server directly are encouraged to do so through an access address." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:173(para) +msgid "Show details for, set, update, and delete server metadata or metadata items." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:189(title) +msgid "Server addresses" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:190(para) +msgid "List addresses for a specified server or a specified server and network." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:197(title) +msgid "Server actions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:198(para) +msgid "Perform actions for a specified server, including change administrator password, reboot, rebuild, resize, and create image from server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:213(title) +msgid "Flavors" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:214(para) +msgid "List available flavors and get details for a specified flavor. A flavor is a hardware configuration for a server. Each flavor is a unique combination of disk space and memory capacity." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:231(para) +msgid "List available images, get details for a specified image, and delete an image." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:232(para) +msgid "Also, set, list, get details for, and delete image metadata." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:233(para) +msgid "An image is a collection of files that you use to create or rebuild a server. By default, operators provide pre-built operating system images. You can also create custom images: See ." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:250(title) +msgid "Image metadata" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml:251(para) +msgid "Show details for, set, update, and delete image metadata or metadata items." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:10(para) +msgid "Use virtual networking services among devices that are managed by the OpenStack Compute service. The Networking (neutron) API v2.0 combines the API v1.1 functionality with some essential Internet Protocol Address Management (IPAM) functionality. Enables users to associate IP address blocks and other network configuration settings with an OpenStack Networking network. You can choose a specific IP address from the block or let OpenStack Networking choose the first available IP address." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:21(para) +msgid "List information for all Networking API versions and show details about API v2." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:34(title) +msgid "Networks" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:35(para) +msgid "List, show information for, create, update, and delete networks." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:42(title) +msgid "Subnets" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:43(para) +msgid "List, show information for, create, update, and delete subnet resources." +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:50(title) +msgid "Ports" +msgstr "" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml:51(para) +msgid "List, show information for, create, update, and delete ports." +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-image-v2.xml:11(title) +msgid "OpenStack Image Service API v2" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2.xml:11(para) ./api-ref/src/docbkx/ch_identity-v3.xml:8(para) +msgid "Get an authentication token that permits access to the OpenStack services REST API." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:13(title) +msgid "Identity API v2.0 extensions (STABLE)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:14(para) +msgid "Query the Identity API to list available extensions with a GET request to v2.0/extensions." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:17(title) +msgid "HP-IDM-serviceId extended parameter" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:23(title) +msgid "OS-KSADM admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:96(title) +msgid "OS-KSCATALOG admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:102(title) +msgid "OS-KSEC2 admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:108(title) +msgid "OS-KSS3 admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:114(title) +msgid "OS-KSVALIDATE admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:120(title) +msgid "RAX-GRPADM admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:126(title) +msgid "RAX-KSGRP admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:132(title) +msgid "RAX-KSKEY admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml:138(title) +msgid "RAX-KSQA admin extension" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-orchestration-v1.xml:11(title) +msgid "OpenStack Orchestration API v1" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-networking-v2.xml:11(title) +msgid "OpenStack Networking API v2.0" +msgstr "" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml:9(title) +msgid "Databases Service API v1.0 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml:25(title) +msgid "Database instances (instances)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml:45(title) +msgid "Database instance actions (action)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml:56(title) +msgid "Databases (databases)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml:70(title) +msgid "Users (users)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml:84(title) +msgid "Flavors (flavors)" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-compute-v2.xml:11(title) +msgid "OpenStack Compute API v2 (CURRENT)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:11(para) ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:11(para) +msgid "Manage volumes and snapshots for use with the Block Storage API, also known as cinder services." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:27(title) +msgid "API extensions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:36(title) ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:58(title) +msgid "Volumes" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:37(para) +msgid "A volume is a detachable block storage device. You can think of it as a USB hard drive. You can attach a volume to one instance at a time." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:40(para) +msgid "When you create, list, or delete volumes, these status values are possible:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:51(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:154(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:273(para) +msgid "creating" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:52(para) +msgid "The volume is being created." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:55(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:159(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:278(para) +msgid "available" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:56(para) +msgid "The volume is ready to be attached to an instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:60(para) +msgid "attaching" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:61(para) +msgid "The volume is attaching to an instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:65(para) +msgid "in-use" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:66(para) +msgid "The volume is attached to an instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:70(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:164(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:284(para) +msgid "deleting" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:71(para) +msgid "The volume is being deleted." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:74(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:169(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:289(para) +msgid "error" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:75(para) +msgid "An error occurred during volume creation." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:79(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:175(para) +msgid "error_deleting" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:80(para) +msgid "An error occurred during volume deletion." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:84(para) +msgid "backing-up" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:85(para) +msgid "The volume is being backed up." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:88(para) +msgid "restoring-backup" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:89(para) +msgid "A backup is being restored to the volume." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:93(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:301(para) +msgid "error_restoring" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:94(para) ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:302(para) +msgid "An error occurred during backup restoration to a volume." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:118(title) ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:77(title) +msgid "Volume types" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:139(title) ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:98(title) +msgid "Snapshots" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:140(para) +msgid "A snapshot is a point in time copy of the data that a volume contains." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:142(para) +msgid "When you create, list, or delete snapshots, these status values are possible:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:155(para) +msgid "The snapshot is being created." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:160(para) +msgid "The snapshot is ready to be used." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:165(para) +msgid "The snapshot is being deleted." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:170(para) +msgid "An error occurred during snapshot creation." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:176(para) +msgid "An error occurred during snapshot deletion." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:205(title) +msgid "Quality of service (QoS) specifications (qos-specs)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:207(para) +msgid "Administrators only, depending on policy settings. Create, list, show details for, associate, disassociate, and delete quality of service (QoS) specifications." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:237(title) +msgid "Quota sets extension (os-quota-sets)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:238(para) +msgid "Administrators only, depending on policy settings. View, update, and delete quotas for a tenant." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:245(title) +msgid "Limits extension (limits)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:246(para) +msgid "Show absolute limits for a tenant." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:252(title) +msgid "Backups" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:253(para) +msgid "A backup is a full copy of a volume stored in an external service. The service can be configured. The only supported service for now is Object Storage. A backup can subsequently be restored from the external service to either the same volume that the backup was originally taken from, or to a new volume. backup and restore operations can only be carried out on volumes which are in an unattached and available state." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:261(para) +msgid "When you create, list, or delete backups, these status values are possible:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:274(para) +msgid "The backup is being created." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:279(para) +msgid "The backup is ready to be restored to a volume." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:285(para) +msgid "The backup is being deleted." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:290(para) +msgid "An error has occurred with the backup." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:295(para) +msgid "restoring" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:296(para) +msgid "The backup is being restored to a volume." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml:307(para) +msgid "In the event of an error, more information about the error can be found in the fail_reason field for the backup." +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:10(para) +msgid "Use a template language to orchestrate OpenStack services." +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:22(title) +msgid "Stacks" +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:51(title) +msgid "Stack actions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:52(para) +msgid "Performs non-lifecycle operations on the stack. Specify the action in the request body." +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:63(title) +msgid "Stack resources" +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:96(title) +msgid "Stack events" +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:117(title) +msgid "Templates" +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:130(title) +msgid "Build info" +msgstr "" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml:139(title) +msgid "Software configuration" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-image-v1.xml:11(title) +msgid "OpenStack Image Service API v1" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:10(para) +msgid "Image Service API v2.0, API v2.1, and API v2.2." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:29(para) +msgid "Create, update, and delete image metadata records. Enable users to share images with each other. Also, upload and download raw image data." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:47(title) +msgid "Image data" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:48(para) +msgid "Upload and download raw image data." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:58(title) +msgid "Image tags" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:59(para) +msgid "Add and delete image tags." +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:85(title) +msgid "Image schemas" +msgstr "" + +#: ./api-ref/src/docbkx/ch_images-v2.xml:86(para) +msgid "Get a JSON-schema document that represents an images or image entity." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:15(para) +msgid "XML support in requests and responses has been deprecated for the Compute API v3." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:22(para) +msgid "List information for all API versions." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:35(title) +msgid "Server admin actions (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:36(para) +msgid "Administrators only. Perform actions on a server. Specify the action in the request body." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:44(para) +msgid "Creates, updates, and deletes guest agents. Use guest agents to access files on the disk, configure networking, or run other applications or scripts in the guest while it runs. This hypervisor-specific extension is not currently enabled for KVM. Use of guest agents is possible only if the underlying service provider uses the Xen driver." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:56(para) +msgid "Creates and manages host aggregates. An aggregate assigns metadata to groups of compute nodes. Aggregates are only visible to the cloud provider." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:64(title) +msgid "Cells (os-cells)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:65(para) +msgid "Enables cells-related functionality such as adding neighbor cells, listing neighbor cells, and getting the capabilities of the local cell." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:74(para) +msgid "Creates and shows details for a root certificate." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:80(title) +msgid "Configuration drive (os-config-drive)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:81(para) +msgid "Returns server details for a specific service ID or user." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:89(para) +msgid "Force-deletes a server or restores a deleted server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:95(title) +msgid "Evacuate (os-evacuate)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:96(para) +msgid "Enables server evacuation." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:102(title) +msgid "Servers with extended availability zones (os-extended-availability-zone)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:104(para) +msgid "Shows the instance availability zone for compute nodes (nova-compute). Internal services appear in their own internal availability zone." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:112(title) +msgid "Server extended attributes (os-extended-server-attributes)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:114(para) +msgid "Shows metadata for servers." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:120(title) +msgid "Server extended status (os-extended-status)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:121(para) +msgid "Shows extended status information, vm_state, task_state, and power_state, in detailed server responses." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:128(title) +msgid "Flavor access (os-flavor-access)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:129(para) +msgid "Flavor access support." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:135(title) +msgid "Flavor extra-specs (flavor-extra-specs)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:136(para) +msgid "Lists, creates, deletes, and updates the extra-specs or keys for a flavor." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:143(title) +msgid "Flavors manage (flavor-manage)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:144(para) +msgid "Support for creating and deleting flavor." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:150(title) +msgid "Flavors with rxtx_factor extended attribute (os-flavor-rxtx)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:152(para) +msgid "Support to show the rxtx status of a flavor." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:159(para) +msgid "Returns information about Flavors." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:166(para) +msgid "Manages physical hosts." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:173(para) +msgid "Displays extra statistical information from the machine that hosts the hypervisor through the API for the hypervisor (XenAPI or KVM/libvirt)." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:181(title) +msgid "Server actions (servers)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:182(para) +msgid "Permits all users to list available actions for a specified server. Permits administrators to get details for a specified action for a specified server." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:190(title) +msgid "Instance usage audit log (os-instance-usage-audit-log)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:192(para) +msgid "Admin-only task log monitoring." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:198(title) +msgid "Limits (limits)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:199(para) +msgid "Provide all global and rate limit information." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:206(para) +msgid "Provide data on migrations." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:212(title) +msgid "Multinic (os-multinic)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:213(para) +msgid "Multiple network support." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:219(title) +msgid "Quota class (os-quota-class-sets)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:220(para) +msgid "Quota classes management support." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:227(para) +msgid "Permits administrators, depending on policy settings, to view quotas for a tenant and view and update default quotas." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:235(title) +msgid "Server remote console (os-remote-consoles)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:236(para) +msgid "Interactive console support." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:242(title) +msgid "Server usage (os-server-usage)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:243(para) +msgid "Adds launched_at and terminated_at to servers." +msgstr "" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml:250(para) +msgid "Provide simple tenant usage for tenant." +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-telemetry-v2.xml:11(title) +msgid "OpenStack Telemetry API v2" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:13(para) +msgid "When making an API call to create, list, or delete volume(s), the following status values are possible:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:18(para) +msgid "CREATING: The volume is being created." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:21(para) +msgid "AVAILABLE: The volume is read to be attached to an instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:25(para) +msgid "ATTACHING: The volume is attaching to an instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:29(para) +msgid "IN-USE: The volume is attached to an instance." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:33(para) +msgid "DELETING: The volume is being deleted." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:36(para) +msgid "ERROR: An error has occurred with the volume." +msgstr "" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml:40(para) +msgid "ERROR_DELETING: There was an error deleting the volume." +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-blockstorage-v2.xml:11(title) +msgid "OpenStack Block Storage API v2" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-identity-v2.xml:11(title) +msgid "OpenStack Identity API v2 and extensions" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:25(para) +msgid "Manage tokens." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:38(title) +msgid "Service catalog" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:39(para) +msgid "Manage the catalog of services." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:56(title) +msgid "Endpoints" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:57(para) +msgid "Manage endpoints." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:67(title) +msgid "Domains" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:68(para) +msgid "Manage domains." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:69(para) +msgid "Domains represent collections of users, groups, and projects. Each is owned by exactly one domain. Users, however, can be associated with multiple projects by granting roles to the user on a project, including projects owned by other domains." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:72(para) +msgid "Each domain defines a namespace where certain API-visible name attributes exist, which affects whether those names must be globally unique or unique within that domain. In the Identity API, the uniqueness of the following attributes is as follows:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:77(para) +msgid "Domain Name. Globally unique across all domains." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:81(para) +msgid "Role Name. Globally unique across all domains." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:85(para) +msgid "User Name. Unique within the owning domain." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:89(para) +msgid "Project Name. Unique within the owning domain." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:93(para) +msgid "Group Name. Unique within the owning domain." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:132(title) +msgid "Projects" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:133(para) +msgid "Manage projects." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:168(para) +msgid "Manage users." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:196(title) +msgid "Groups" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:197(para) +msgid "Manage groups." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:225(title) +msgid "Credentials" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:226(para) +msgid "Manage credentials." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:244(title) +msgid "Roles" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:245(para) +msgid "Manage roles." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:267(title) +msgid "Policies" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml:268(para) +msgid "Manage policies." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:10(para) +msgid "Manage the accounts, containers, and objects in the Object Storage system." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:12(para) +msgid "To run the cURL command examples for these requests, set these environment variables:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:16(para) +msgid "publicURL. The public URL that is the HTTP endpoint from where you can access Object Storage. It includes the Object Storage API version number and your account name. For example, https://23.253.72.207/v1/my_account." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:23(para) +msgid "token. The authentication token for Object Storage." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:27(para) +msgid "To obtain these values, run the command." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:29(para) +msgid "As shown in this example, the public URL appears in the StorageURL field, and the token appears in the Auth Token field:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:43(para) +msgid "For a complete description of HTTP 1.1 header definitions, see Header Field Definitions." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:48(title) +msgid "Accounts" +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:49(para) +msgid "List containers for a specified account. Create, update, show, and delete account metadata." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:61(title) +msgid "Containers" +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:62(para) +msgid "List objects in a specified container. Create, show details for, and delete containers. Create, update, show, and delete container metadata." +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:77(title) +msgid "Objects" +msgstr "" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml:78(para) +msgid "Create, replace, show details for, and delete objects. Copy objects from another object with a new or different name. Update object metadata." +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-databases-v1.xml:11(title) +msgid "OpenStack Database Service API v1.0" +msgstr "" + +#: ./api-ref/src/docbkx/api-ref-compute-v3.xml:11(title) +msgid "OpenStack Compute API v3" +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:10(para) +msgid "Manage telemetry operations." +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:12(title) +msgid "Alarms" +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:13(para) +msgid "List, create, gets details for, update, and delete alarms." +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:39(title) +msgid "Meters" +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:40(para) +msgid "Get information for meters." +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:58(title) +msgid "Resources" +msgstr "" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml:59(para) +msgid "Get information for resources." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:13(title) +msgid "Identity API v3 extensions (STABLE)" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:15(title) +msgid "OS-OAUTH1 extension" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:16(para) +msgid "Enable users to delegate roles to third-party consumers through the OAuth 1.0a specification." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:19(para) +msgid "A user is an Identity API user who delegates its roles and who authorizes request tokens. A consumer is a third-party application that uses OAuth to access a protected resource. An OAuth-derived token enables admin users to act on behalf of the authorizing user. A request token is a token that the consumer uses to get authorization from the user and exchanges with an OAuth verifier for an access token. The OAuth verifier is a required string that is provided with the corresponding request token in exchange for an access token. An access token is a token that the consumer uses to request Identity API tokens on behalf of the authorizing user instead of using the credentials for the user." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:32(para) +msgid "Request and access tokens use token keys to identify themselves. For OpenStack purposes, the token key is the token ID. The consumer uses a token secret to establish ownership of a specified token. Both request and access tokens have token secrets." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:37(para) +msgid "Delegated authentication through OAuth occurs as follows:" +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:41(para) +msgid "A user creates a consumer." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:44(para) +msgid "The consumer gets an unauthorized request token. Then, the consumer uses the request token to initiate user authorization." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:49(para) +msgid "The user authorizes the request token." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:52(para) +msgid "The consumer exchanges the authorized request token and the OAuth verifier for an access token." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:55(para) +msgid "The authorizing user receives the request token key from the consumer out-of-band." +msgstr "" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:59(para) +msgid "The consumer uses the access token to request an Identity API token." +msgstr "" + +#. Put one translator per line, in the form of NAME , YEAR1, YEAR2 +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml:0(None) +msgid "translator-credits" +msgstr "" + diff --git a/restapi-doc/restapi-doc/api-ref/locale/fr.po b/restapi-doc/restapi-doc/api-ref/locale/fr.po new file mode 100644 index 000000000..a2d031314 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/locale/fr.po @@ -0,0 +1,2282 @@ +# +# Translators: +# François Bureau, 2014 +# Frédéric , 2014 +# cloudwatt_l10n , 2014 +# Léo Carré , 2014 +# Nicolas HAHN , 2014 +msgid "" +msgstr "" +"Project-Id-Version: OpenStack Manuals\n" +"POT-Creation-Date: 2014-08-25 07:06+0000\n" +"PO-Revision-Date: 2014-08-25 14:41+0000\n" +"Last-Translator: Frédéric \n" +"Language-Team: French (http://www.transifex.com/projects/p/openstack-manuals-i18n/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ./api-ref/src/docbkx/api-ref-compute-v2-ext.xml11(title) +msgid "OpenStack Compute API v2 extensions" +msgstr "Extensions de l'API de Calcul v2 OpenStack" + +#: ./api-ref/src/docbkx/api-ref-compute-v2-ext.xml13(year) +#: ./api-ref/src/docbkx/api-ref-identity-v3.xml13(year) +#: ./api-ref/src/docbkx/api-ref-blockstorage-v1.xml13(year) +#: ./api-ref/src/docbkx/api-ref-objectstorage-v1.xml13(year) +#: ./api-ref/src/docbkx/api-ref.xml13(year) +#: ./api-ref/src/docbkx/api-ref-image-v2.xml13(year) +#: ./api-ref/src/docbkx/api-ref-orchestration-v1.xml13(year) +#: ./api-ref/src/docbkx/api-ref-networking-v2.xml13(year) +#: ./api-ref/src/docbkx/api-ref-compute-v2.xml13(year) +#: ./api-ref/src/docbkx/api-ref-image-v1.xml13(year) +#: ./api-ref/src/docbkx/api-ref-telemetry-v2.xml13(year) +#: ./api-ref/src/docbkx/api-ref-blockstorage-v2.xml13(year) +#: ./api-ref/src/docbkx/api-ref-identity-v2.xml13(year) +#: ./api-ref/src/docbkx/api-ref-databases-v1.xml13(year) +#: ./api-ref/src/docbkx/api-ref-compute-v3.xml13(year) +msgid "2010-2014" +msgstr "2010-2014" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml7(title) +msgid "Identity admin API v2.0 (STABLE)" +msgstr "API d'administration des Identités v2.0 (STABLE)" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml8(para) +msgid "Get an authentication token that permits access to the Compute API." +msgstr "Obtenir un jeton d'authentification permettant l'accès à l'API de Calcul." + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml10(title) +msgid "Versions" +msgstr "Versions" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml18(title) +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml8(title) +#: ./api-ref/src/docbkx/ch_compute-v2.xml38(title) +#: ./api-ref/src/docbkx/ch_identity-v2.xml27(title) +msgid "Extensions" +msgstr "Extensions" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml29(title) +#: ./api-ref/src/docbkx/ch_identity-v2.xml40(title) +#: ./api-ref/src/docbkx/ch_identity-v3.xml24(title) +msgid "Tokens" +msgstr "Jetons" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml41(title) +#: ./api-ref/src/docbkx/ch_identity-v3.xml167(title) +msgid "Users" +msgstr "Utilisateurs" + +#: ./api-ref/src/docbkx/ch_identity-admin-v2.xml62(title) +msgid "Tenants" +msgstr "Clients" + +#: ./api-ref/src/docbkx/preface.xml9(title) +msgid "OpenStack API Complete Reference" +msgstr "Référence Complète de l'API OpenStack" + +#: ./api-ref/src/docbkx/preface.xml10(para) +msgid "" +"Use the OpenStack APIs and extensions to launch server instances, create " +"images, assign metadata to instances and images, create containers and " +"objects, and complete other actions in your OpenStack cloud." +msgstr "Utilisez les autres APIs et extensions pour démarrer des instances de serveur, créer des images, assigner des métadonnées aux instances et images, créer des conteneurs et des objets, et mener à bien d'autres actions dans votre cloud OpenStack." + +#: ./api-ref/src/docbkx/preface.xml14(para) +msgid "" +"The API status reflects the state of the " +"endpoint on the service. CURRENT is a " +"stable version that is up-to-date, recent, and might receive future " +"versions. This endpoint should be prioritized over all others. SUPPORTED is a stable version that is available on " +"the server. However, it is not likely the most recent available and might " +"not be updated or might be deprecated at some time in the future. DEPRECATED is a stable version that is still " +"available but is being deprecated and might be removed in the future. " +"EXPERIMENTAL is not a stable version. " +"This version is under development or contains features that are otherwise " +"subject to change. For more information about API status values and version information, see Version " +"Discovery." +msgstr "L'API status reflète l'état d'aboutissement du service. ACTUEL est une version stable qui est à jour, récente, et qui pourrait bénéficier de futures versions. Cette version aboutie devrait être prioritaire par rapport à toutes les autres. SUPPORTÉ est une version stable qui est disponible sur le serveur. Cependant, ce n'est pas forcément la versions la plus récente disponible et elle pourrait ne pas être mise à jour ou elle pourrait être abandonnée relativement rapidement. ABANDONNÉ est une version stable qui est toujours disponible mais qui est abandonnée et qui pourrait être supprimée dans le futur. EXPÉRIMENTAL n'est pas une version stable. Cette version est en cours de développement ou contient des fonctionnalités qui peuvent être sujettes à modification. Pour obtenir plus d'informations sur les paramètres de l'API status et les informations de version, reportez-vous à la documentation Découverte des Versions." + +#: ./api-ref/src/docbkx/preface.xml32(para) +msgid "" +"You must install the packages for each API separately. You can use the APIs " +"and extensions after you authenticate through the Identity API:" +msgstr "Vous devez installer les packages de chaque API séparément. Vous pouvez utiliser les APIs et extensions après vous être authentifié par l'intermédiaire de l'API de Gestion des Identités:" + +#: ./api-ref/src/docbkx/preface.xml41(para) +msgid "" +"To get started with the APIs, see the OpenStack API " +"Quick Start." +msgstr "Pour débuter avec les APIs, reportez-vous à la documentation API d'OpenStack: démarrage rapide." + +#: ./api-ref/src/docbkx/ch_images-v1.xml10(title) +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml48(link) +msgid "Image Service API v1 (SUPPORTED)" +msgstr "API du Service d'Image v1 (SUPPORTÉ)" + +#: ./api-ref/src/docbkx/ch_images-v1.xml11(para) +msgid "" +"Load images for use at launch time by the Compute API. Also, assign metadata" +" to images." +msgstr "Charge les images à utiliser lors du démarrage par l'intermédiaire de l'API de Calcul. De plus, assigne les métadonnées aux images." + +#: ./api-ref/src/docbkx/ch_images-v1.xml13(para) +msgid "" +"Some cloud implementations do not expose this API and offer pretested images" +" only." +msgstr "Quelques implémentations de cloud n'exposent pas cette API et offrent des images pré-testées seulement." + +#: ./api-ref/src/docbkx/ch_images-v1.xml15(para) +#: ./api-ref/src/docbkx/ch_images-v2.xml11(para) +msgid "" +"Cloud providers can configure property protections that prevent non-" +"administrative users from updating and deleting protected properties. For " +"more information, see Image property " +"protection in the OpenStack Cloud Administrator " +"Guide." +msgstr "Les fournisseurs du cloud peuvent configurer des propriétés de protection qui éviteront que des utilisateurs non administrateurs ne modifient ou n'effacent des propriétés protégées. Pour plus d'informations, reportez-vous à la section Protection d'une propriété d'image dans le Guide de l'Administrateur du Cloud OpenStack." + +#: ./api-ref/src/docbkx/ch_images-v1.xml23(title) +#: ./api-ref/src/docbkx/ch_compute-v2.xml17(title) +#: ./api-ref/src/docbkx/ch_netconn-v2.xml20(title) +#: ./api-ref/src/docbkx/ch_identity-v2.xml14(title) +#: ./api-ref/src/docbkx/ch_databases-v1.xml11(title) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml14(title) +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml13(title) +#: ./api-ref/src/docbkx/ch_images-v2.xml19(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml21(title) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml45(title) +#: ./api-ref/src/docbkx/ch_identity-v3.xml11(title) +msgid "API versions" +msgstr "Versions de l'API" + +#: ./api-ref/src/docbkx/ch_images-v1.xml37(title) +#: ./api-ref/src/docbkx/ch_compute-v2.xml230(title) +#: ./api-ref/src/docbkx/ch_images-v2.xml28(title) +msgid "Images" +msgstr "Images" + +#: ./api-ref/src/docbkx/ch_images-v1.xml57(title) +#: ./api-ref/src/docbkx/ch_images-v2.xml69(title) +msgid "Members" +msgstr "Membres" + +#: ./api-ref/src/docbkx/ch_images-v1.xml71(title) +msgid "Shared images" +msgstr "Images partagées" + +#: ./api-ref/src/docbkx/api-ref-identity-v3.xml11(title) +msgid "OpenStack Identity API v3 and extensions" +msgstr "API de Gestion des Identités v3 OpenStack et extensions" + +#: ./api-ref/src/docbkx/api-ref-blockstorage-v1.xml11(title) +msgid "OpenStack Block Storage API v1" +msgstr "API de Stockage de Bloc v1 OpenStack" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml6(title) +msgid "Networking API v2.0 extensions" +msgstr "Extensions de l'API de gestion Réseau v2.0" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml9(para) +msgid "" +"List available Networking API v2.0 extensions and show details for a " +"specified extension." +msgstr "Liste les extensions de l'API de gestion de Réseau v2.0 et indique les informations détaillées d'une extension spécifique." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml21(title) +msgid "Quotas extension (quotas)" +msgstr "Extension de gestion des Quotas (quotas)" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml22(para) +msgid "List, show information for, update, and reset quotas." +msgstr "Liste, affiche des informations, met à jour, et réinitialise les quotas." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml33(title) +msgid "Networks provider extended attributes (networks)" +msgstr "Attibuts étendus de fournisseur de réseaux (réseaux)" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml34(para) +msgid "List, create, show information for, update, and delete networks." +msgstr "Liste, crée, affiche les informations, met à jour, et supprime les réseaux." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml48(title) +msgid "Networks multiple provider extension (networks)" +msgstr "Extension de fournisseur de réseaux multiple (réseaux)" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml49(para) +msgid "" +"Enables administrative users to define multiple physical bindings for an " +"OpenStack Networking network and list or show details for networks with " +"multiple physical bindings." +msgstr "Permet aux utilisateurs administrateurs de définir des liaisons physiques pour un réseau OpenStack Networking et liste ou montre les détails des réseaux avec de multiples liaisons physiques." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml52(para) +msgid "" +"You cannot update any provider attributes. If you try to " +"do so, an error occurs." +msgstr "Vous ne pouvez modifier aucun des attributs de fournisseur. Si vous essayez de le faire, une erreur sera provoquée." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml54(para) +msgid "" +"To delete a network with multiple physical bindings, issue a normal delete " +"network request." +msgstr "Pour supprimer un réseau avec des liaisons physiques multiples, utilisez une demande de suppression de réseau normale." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml56(para) +msgid "" +"To define multiple physical bindings for a network, include a " +"segments list in the request body of a POST " +"/v2.0/networks request. Each element in the " +"segments list has the same structure as the provider " +"network attributes. These attributes are " +"provider:network_type, " +"provider:physical_network, and " +"provider:segmentation_id. The validation rules for these " +"attributes are the same as for the Networks provider extended attributes. You " +"cannot use both extensions at the same time." +msgstr "Pour définir des liaisons physiques multiples pour un réseau, incluez une liste de segments dans le corps d'une requête POST /v2.0/networks. Chaque élément dans la liste de segments possède la même structure que les attributs de fournisseur de réseau. Ces attributs sont provider:network_type, provider:physical_network, et provider:segmentation_id. Les règles de validation pour ces attributs sont équivalentes aux attributs étendus de fournisseur de réseaux. Vous ne pouvez pas utiliser les deux extensions en même temps." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml67(para) +msgid "" +"The NSX and ML2 plug-ins support this extension. With the ML2 plug-in, you " +"can specify multiple VLANs for a specified network, a VXLAN tunnel ID, and a" +" VLAN." +msgstr "Les plugins NSX et ML2 supportent cette extension. Avec le plugin ML2, vous pouvez spécifier de multiples VLANs pour un réseau donné, un ID de tunnel VXLAN, et un VLAN." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml73(title) +msgid "Ports binding extended attributes (ports)" +msgstr "Attributs étendus de liaison de ports (ports)" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml74(para) +msgid "List, create, show information for, and update ports." +msgstr "Liste, crée, affiche les informations, et met à jour les ports." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml87(title) +msgid "Security groups and rules (security-groups)" +msgstr "Groupes et règles de sécurité (security-groups)" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml88(para) +msgid "" +"List, create, show information for, and delete security groups and security " +"group rules." +msgstr "Liste, crée, affiche les informations, et supprime les groupes de sécurité et les les règles des groupes de sécurité." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml112(title) +msgid "Layer-3 networking" +msgstr "Gestion de réseau: couche 3 du modèle OSI" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml113(para) +msgid "" +"Route packets between subnets, forward packets from internal networks to " +"external ones, and access instances from external networks through floating " +"IPs." +msgstr "Effectue le routage des paquets entre les sous-réseaux, transfère les paquets des réseaux internes aux réseaux externes, et accède aux instances à partir des réseaux externes au moyen d'addresses IP flottantes." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml115(para) +msgid "This extension introduces these resources:" +msgstr "Cette extension introduit ces ressources:" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml118(para) +msgid "" +"router. A logical entity for forwarding " +"packets across internal subnets and NATting them on external networks " +"through an appropriate external gateway." +msgstr "router. Une entité logique permettant de transférer les paquets entre les sous-réseaux internes, et de les NATter sur les réseaux externes au moyen d'une passerelle externe appropriée." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml123(para) +msgid "" +"floatingip. An external IP address that " +"is mapped to a port that is attached to an internal network." +msgstr "floatingip. Une addresse IP externe qui est mappée sur un port, lui-même attaché à un réseau interne." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml131(title) +msgid "Metering labels and rules" +msgstr "Libellés et règles de comptage" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml132(para) +msgid "Create, modify, and delete OpenStack Layer3 Metering labels and rules." +msgstr "Créer, modifier, et supprimer des libellés et des règles de comptage OpenStack Layer3" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml137(title) +msgid "Load-Balancer-as-a-Service (LBaaS)" +msgstr "Répartition-de-charge-en-tant-que-service (LBaaS)" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml138(para) +msgid "" +"The LBaaS extension enables OpenStack tenants to load-balance their VM " +"traffic. The extension enables you to load-balance client traffic from one " +"network to application services, such as VMs, on the same or a different " +"network. You can load-balance several protocols, such as TCP and HTTP and " +"monitor the health of application services. The LBaaS extension supports " +"session persistence." +msgstr "L'extension LBaaS permet aux clients OpenStack de répartir la charge du traffic de leur VM. L'extension vous permet de répartir la charge du traffic du client d'un réseau aux services d'application, comme les VMs, sur le même réseau ou un réseau différent. Vous pouvez répartir la charge de plusieurs protocoles, comme TCP et HTTP, et vous pouvez surveiller la bonne exécution des services d'application. L'extension LBaaS supporte la persistence de session." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml144(caption) +msgid "Load balancer statuses" +msgstr "Etats des load-balancers" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml150(th) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml45(th) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml147(th) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml266(th) +msgid "Status" +msgstr "Statut" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml151(th) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml46(th) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml148(th) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml267(th) +msgid "Description" +msgstr "Description" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml152(th) +msgid "Operational" +msgstr "Opérationnel" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml157(td) +msgid "DEFERRED" +msgstr "DEFERRED" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml158(td) +msgid "An entity was created but is not yet linked to a load balancer." +msgstr "Une entité a été créée mais n'est pas encore liée à un load-balancer." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml159(td) +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml164(td) +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml174(td) +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml184(td) +msgid "No" +msgstr "Non" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml162(td) +msgid "PENDING_CREATE" +msgstr "PENDING_CREATE" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml163(td) +msgid "An entity is being created." +msgstr "Une entité est en cours de création." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml167(td) +msgid "PENDING_UPDATE" +msgstr "PENDING_UPDATE" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml168(td) +msgid "An entity was updated. It remains in an operational state." +msgstr "Une entité a été mise à jour. Elle demeure dans l'état opérationnel." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml169(td) +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml179(td) +msgid "Yes" +msgstr "Oui" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml172(td) +msgid "PENDING_DELETE" +msgstr "PENDING_DELETE" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml173(td) +msgid "An entity is in the process of being deleted." +msgstr "La suppression d'une unité a été initiée." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml177(td) +msgid "ACTIVE" +msgstr "ACTIVE" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml178(td) +msgid "An entity is in a normal operational state." +msgstr "Une entité est dans un état opérationnel normal." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml182(td) +msgid "INACTIVE" +msgstr "INACTIVE" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml183(td) +msgid "Applies to members that fail health checks." +msgstr "S'applique aux membres ayant échoué aux tests de bon fonctionnement." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml187(td) +msgid "ERROR" +msgstr "ERROR" + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml188(td) +msgid "Something has gone wrong." +msgstr "Quelque chose ne s'est pas passé correctement." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml189(td) +msgid "This might be in either an operational or non-operational state." +msgstr "Cela peut être soit dans un état opérationnel, soit dans un état non opérationnel." + +#: ./api-ref/src/docbkx/ch_netconn-ext-v2.xml193(para) +msgid "" +"Use this extension to create and manage load balancers, listeners, pools, " +"members, and health monitors." +msgstr "Utilisez cette extension pour créer et gérer des load balancers, des listeners, des pools, des membres, et des sondes de monitoring." + +#: ./api-ref/src/docbkx/api-ref-objectstorage-v1.xml11(title) +msgid "OpenStack Object Storage API v1" +msgstr "API de Stockage d'Objet v1 OpenStack" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml12(link) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml10(title) +msgid "Block Storage API v2 (CURRENT)" +msgstr "API de Stockage par Bloc v2 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml16(link) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml10(title) +msgid "Block Storage API v1 (CURRENT)" +msgstr "API de Stockage par Bloc v1 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml20(link) +#: ./api-ref/src/docbkx/ch_compute-v2.xml9(title) +msgid "Compute API v2 (CURRENT)" +msgstr "API de Calcul v2 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml24(link) +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml13(title) +msgid "Compute API v2 extensions (CURRENT)" +msgstr "Extensions de l'API de Calcul v2 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml28(link) +#: ./api-ref/src/docbkx/ch_compute-v3.xml14(title) +msgid "Compute API v3 (EXPERIMENTAL)" +msgstr "API de Calcul v3 (EXPÉRIMENTAL)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml32(link) +msgid "Database Service API v1.0 (CURRENT)" +msgstr "API de Service de Base de données v1.0 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml36(link) +#: ./api-ref/src/docbkx/ch_identity-v3.xml7(title) +msgid "Identity API v3 (STABLE)" +msgstr "API de Gestion des Identités v3 (STABLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml40(link) +#: ./api-ref/src/docbkx/ch_identity-v2.xml10(title) +msgid "Identity API v2.0 (STABLE)" +msgstr "API de Gestion des Identités v2.0 (STABLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml44(link) +#: ./api-ref/src/docbkx/ch_images-v2.xml9(title) +msgid "Image Service API v2 (SUPPORTED)" +msgstr "API de Service d'Image v2 (SUPPORTÉ)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml52(link) +#: ./api-ref/src/docbkx/ch_netconn-v2.xml9(title) +msgid "Networking API v2.0 (CURRENT)" +msgstr "API de Gestion Réseau v2.0 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml56(link) +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml9(title) +msgid "Object Storage API v1 (SUPPORTED)" +msgstr "API de Stockage d'Objet v1 (SUPPORTÉ)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml61(link) +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml9(title) +msgid "Orchestration API v1 (CURRENT)" +msgstr "API d'Orchestration v1 (ACTUELLE)" + +#: ./api-ref/src/docbkx/itemizedlist-service-list.xml64(link) +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml9(title) +msgid "Telemetry API v2 (CURRENT)" +msgstr "API de Télémétrie v2 (ACTUELLE)" + +#: ./api-ref/src/docbkx/api-ref.xml11(title) +msgid "OpenStack API Reference" +msgstr "Références des APIs Openstack" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml14(para) +msgid "" +"Extensions add features, MIME types, actions, states, headers, parameters, " +"and resources to the core Compute API without requiring a version change." +msgstr "Les extensions ajoutent des fonctionnalités, types MIME, actions, états, en-têtes, paramètres et ressources au coeur de l'API de Calcul sans requérir un changement de version." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml17(para) +#: ./api-ref/src/docbkx/ch_compute-v2.xml13(para) +msgid "" +"XML support in requests and responses has been deprecated for the Compute " +"API v2." +msgstr "Le support d'XML dans les requêtes et les réponses a été abandonné pour l'API de Calcul v2." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml20(title) +msgid "Server admin actions (action)" +msgstr "Actions de l'administrateur du serveur (action)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml21(para) +msgid "" +"Administrator only. Perform actions on a server. Specify the action in the " +"request body." +msgstr "Pour Administrateur seulement. Effectue des actions sur un serveur. Spécifiez l'action dans le corps de la requête." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml28(title) +msgid "Server diagnostics (diagnostics)" +msgstr "Diagnostics de serveur (diagnostics)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml29(para) +msgid "Get the usage data for a server." +msgstr "Obtenir les statistiques d'utilisation d'un serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml35(title) +msgid "Flavor access (flavors)" +msgstr "Accès aux instances (flavors)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml36(para) +msgid "" +"Create and get details for private flavors. Also, list, add, and remove " +"tenants' access to private flavors." +msgstr "Créez et obtenez les détails des types d'instances privés. En plus, listez, ajoutez, et enlevez l'accès des clients aux types d'instances privés. " + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml43(title) +msgid "Flavors with FlavorDisabled attribute (flavors)" +msgstr "Instances avec l'attribut FlavorDisabled (flavors)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml44(para) +msgid "" +"Get details for a flavor, and list details for available flavors. Includes " +"the OS-FLV-DISABLED:disabled extended attribute." +msgstr "Obtenir les informations concernant une instance, et lister les détails des instances disponibles. Inclut l'attribut étendu OS-FLV-DISABLED:disabled." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml53(title) +msgid "Flavor extra-specs (os-extra-specs)" +msgstr "Spécifications supplémentaires d'instance (os-extra-specs)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml54(para) +msgid "List, create, and update the extra-specs or keys for a flavor." +msgstr "Liste, crée, et modifie les spécifications supplémentaires ou clés d'une instance." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml61(title) +msgid "Flavors with rxtx_factor extended attribute (flavors)" +msgstr "Instances avec l'attribut étendu rxtx_factor (flavors)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml63(para) +msgid "" +"Create, get details for, and list details for flavors. Includes the " +"rxtx_factor extended attribute, related to configured " +"bandwidth cap values." +msgstr "Crée, obtient et liste les informations des instances. Inclut l'attribut étendu rxtx_factor, qui est en relation avec les valeurs butoires de bande passante configurées." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml72(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml158(title) +msgid "Flavors with extended attributes (flavors)" +msgstr "Instances avec des attributs étendus (flavors)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml73(para) +msgid "" +"Create, get details for, and list details for flavors. Includes the " +"rxtx_factor, OS-FLV-EXT-" +"DATA:ephemeral, and swap extended attributes." +msgstr "Crée, obtient et liste les informations des instances. Inclut les attributs étendus rxtx_factor, OS-FLV-EXT-DATA:ephemeral, et swap." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml82(title) +msgid "Flavors create or delete (flavors)" +msgstr "Création et suppression d'instances (flavors)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml83(para) +msgid "Create or delete flavors." +msgstr "Créer ou supprimer des types d'instances." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml89(title) +msgid "Images with size attribute (images)" +msgstr "Images avec l'attribut de taille (images)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml90(para) +msgid "" +"List details for available images or get details for a specified image. " +"Includes the OS-EXT-IMG-SIZE:size extended attribute, which " +"shows the image size." +msgstr "Liste les informations sur les images disponibles ou obtient les informations pour une image spécifique. Inclut l'attribut étendu OS-EXT-IMG-SIZE:size, qui montre la taille de l'image." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml99(title) +msgid "Limits with project usage (limits)" +msgstr "Limites avec l'utilisation du projet (limits)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml100(para) +msgid "" +"Extend limits to show the project usage. Show information such as RAM or " +"instance quotas usage." +msgstr "Etend les limites pour montrer l'utilisation du projet. Affiche des informations comme la RAM ou l'utilisation des quotas de l'instance." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml107(title) +msgid "Limits with project usage for administrators (limits)" +msgstr "Limites avec l'utilisation du projet pour les administrateurs (limits)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml109(para) +msgid "" +"Extend limits to enable administrators to show the project usage for a " +"specified customer project ID. Show information such as RAM or instance " +"quotas usage." +msgstr "Etend les limites de façon à permettre aux administrateurs d'afficher l'utilisation du projet pour un ID de projet client spécifié. Affiche des informations comme la RAM ou l'utilisation des quotas de l'instance." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml117(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml43(title) +msgid "Guest agents (os-agents)" +msgstr "Agents invités (os-agents)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml118(para) +msgid "" +"Create, update, and delete guest agents. Use guest agents to access files on" +" the disk, configure networking, or run other applications or scripts in the" +" guest while it runs. This hypervisor-specific extension is not currently " +"enabled for KVM. Use of guest agents is possible only if the underlying " +"service provider uses the Xen driver." +msgstr "Crée, modifie, et supprime des agents invités. Utilisez les agents invités pour accéder aux fichiers du disque, configurer le réseau, ou exécuter d'autres applications ou scripts dans l'invité pendant qu'il est exécuté. Cette extension hyperviseur spécifique n'est pas actuellement active pour KVM. L'utilisation des agents invités est possible seulement si le fournisseur de service sous-jacent utilise le driver Xen." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml130(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml55(title) +msgid "Host aggregates (os-aggregates)" +msgstr "Agrégats hôtes (os-aggregates)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml131(para) +msgid "" +"Create and manage host aggregates. An aggregate assigns metadata to groups " +"of compute nodes. Aggregates are only visible to the cloud provider." +msgstr "Crée et gère les agrégats hôtes. Un agrégat assigne des métadonnées à des groupes de noeuds de calcul. Les agrégats sont visibles seulement au fournisseur du cloud." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml139(title) +msgid "Attach interfaces (os-interface)" +msgstr "Attacher des interfaces (os-interface)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml140(para) +msgid "Create, list, get details for, and delete port interfaces." +msgstr "Crée, liste, obtient des informations, et supprime les interfaces de port." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml147(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml73(title) +msgid "Root certificates (os-certificates)" +msgstr "Certificats racines (os-certificates)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml148(para) +msgid "Create and show details for a root certificate." +msgstr "Crée et montre les informations d'un certificat racine." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml154(title) +msgid "Cloudpipe (os-cloudpipe)" +msgstr "Cloudpipe (os-cloudpipe)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml155(para) +msgid "Manage virtual VPNs for projects." +msgstr "Gère les VPNs virtuels des projets." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml161(title) +msgid "Server console output (os-console-output)" +msgstr "Résultat de la console du serveur (os-console-output)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml162(para) +msgid "Get console output for a server instance." +msgstr "Obtenir la sortie de la console pour une instance de serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml168(title) +msgid "Server console (os-consoles)" +msgstr "Console du serveur (os-consoles)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml169(para) +msgid "Get a console for a server instance." +msgstr "Obtenir une console pour une instance de serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml175(title) +msgid "Coverage reports (os-coverage)" +msgstr "Rapports de couverture (os-coverage)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml181(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml88(title) +msgid "Server deferred delete (os-deferred-delete)" +msgstr "Suppression différée de serveur (os-deferred-delete)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml182(para) +msgid "Force-delete a server or restore a deleted server." +msgstr "Forcer la suppression d'un serveur ou restaurer un serveur supprimé." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml189(title) +msgid "Fixed IPs (os-fixed-ips)" +msgstr "IPs fixes (os-fixed-ips)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml190(para) +msgid "" +"Show data for a specified fixed IP, such as host name, CIDR, and address. " +"Also, reserve or free a fixed IP." +msgstr "Affiche les informations d'une adresse IP fixe, comme le nom d'hôte, le CIDR, et l'adresse. De plus, réserve ou libère une adresse IP fixe." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml198(title) +msgid "Floating IP DNS records (os-floating-ip-dns)" +msgstr "Enregistrements DNS d'adresse IP flottante (os-floating-ip-dns)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml199(para) +msgid "" +"Manage DNS records associated with IP addresses allocated by the floating " +"IPs extension. Requests are dispatched to a DNS driver selected at startup." +msgstr "Gère les enregistrements DNS associés avec les adresses IP allouées par l'extension d'adresses IP flottantes. Les requêtes sont distribuées à un driver DNS sélectionné lors du démarrage." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml207(title) +msgid "Floating IP pools (os-floating-ip-pools)" +msgstr "Espaces d'adresses IP flottantes (os-floating-ip-pools)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml208(para) +msgid "Manage groups of floating IPs." +msgstr "Gérer les groupes d'adresses IP flottantes." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml214(title) +msgid "Floating IPs (os-floating-ips)" +msgstr "Adresses IP flottantes (os-floating-ips)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml215(para) +msgid "" +"Assign and allocate floating IP addresses to instances that run in an " +"OpenStack cloud." +msgstr "Assigner et allouer des adresses IP flottantes aux instances qui fonctionnent dans un cloud OpenStack." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml222(title) +msgid "Floating IPs bulk (os-floating-ips-bulk)" +msgstr "Adresses IP flottantes en masse (os-floating-ips-bulk)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml223(para) +msgid "" +"Bulk-create, delete, and list floating IPs. By default, the pool is named " +"nova. Use the os-floating-ip-pools extension to view " +"available pools." +msgstr "Crée, supprime, et liste des adresses IP flottantes en masse. Par défaut, l'espace est nommé nova. Utilisez l'extension os-floating-ip-pools pour voir les jeux disponibles." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml232(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml165(title) +msgid "Hosts (os-hosts)" +msgstr "Hôtes (os-hosts)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml233(para) +msgid "Manage physical hosts." +msgstr "Gérez les hôtes physiques." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml239(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml172(title) +msgid "Hypervisors (os-hypervisors)" +msgstr "Hyperviseurs (os-hypervisors)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml240(para) +msgid "" +"Display extra statistical information from the machine that hosts the " +"hypervisor through the API for the hypervisor (XenAPI or KVM/libvirt)." +msgstr "Affiche des informations statistiques additionnelles à partir de la machine qui héberge l'hyperviseur, au moyen de l'API pour l'hyperviseur (XenAPI ou KVM/libvirt)." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml267(title) +msgid "Server actions (os-instance-actions)" +msgstr "Actions du serveur (os-instance-actions)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml268(para) +msgid "" +"List available actions for a specified server. Administrators can get " +"details for a specified action for a specified server." +msgstr "Liste les actions disponibles pour un serveur spécifié. Les administrateurs peuvent obtenir des informations pour une action spécifiée, pour un serveur spécifié." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml276(title) +msgid "Keypairs (os-keypairs)" +msgstr "Paires de clés (os-keypairs)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml277(para) +msgid "Generate, import, and delete SSH keys." +msgstr "Génère, importe, et supprime des clés SSH." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml283(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml205(title) +msgid "Migrations (os-migrations)" +msgstr "Migrations (os-migrations)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml284(para) +msgid "" +"Administrators only. Fetch in-progress migrations for a region or a " +"specified cell in a region." +msgstr "Pour Administrateurs seulement. Va chercher les migrations en cours pour une région ou une cellule d'une région spécifiée." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml291(title) +msgid "Networks (os-networks)" +msgstr "Réseaux (os-networks)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml292(para) +msgid "" +"Show network information for or delete networks. Also, disassociate a " +"network from a project if you use vlan mode." +msgstr "Affiche les informations de réseau pour les réseaux ou supprime des réseaux. De plus, casse le lien d'un réseau avec un projet si le mode vlan est utilisé." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml300(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml226(title) +msgid "Quota sets (os-quota-sets)" +msgstr "Jeux de quotas (os-quota-sets)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml301(para) +msgid "" +"Administrators only, depending on policy settings. View quotas for a tenant " +"and view and update default quotas." +msgstr "Pour Administrateurs seulement, en fonction des réglages de la police. Permet de voir les quotas pour un client et permet de voir ou de modifier les quotas par défaut." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml309(title) +msgid "Rules for default security group (os-security-group-default-rules)" +msgstr "Règles pour le groupe de sécurité par défaut (os-security-group-default-rules)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml311(para) +msgid "List, show information for, and create default security group rules." +msgstr "Liste, montre les informations, et crée les règles du groupe de sécurité par défaut." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml318(title) +msgid "Security groups (os-security-groups)" +msgstr "Groupes de sécutiré (os-security-groups)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml319(para) +msgid "List, show information for, create, and delete security groups." +msgstr "Liste, montre les informations, crée, et supprime les groupes de sécurité." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml326(title) +msgid "Server groups (os-server-groups)" +msgstr "Groupes de serveur (os-server-groups)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml327(para) +msgid "List, show information for, create, and delete server groups." +msgstr "Liste, montre les informations, crée, et supprime les groupes de serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml343(title) +msgid "Server password (os-server-password)" +msgstr "Mot de passe du serveur (os-server-password)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml344(para) +msgid "" +"Get and reset the encrypted administrative password set through the metadata" +" service." +msgstr "Obtient et réinitialise le mot de passe crypté administratif configuré au moyen du service de métadonnées." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml351(title) +msgid "Server shelve (servers)" +msgstr "Mise en sommeil du serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml352(para) +msgid "" +"Shelve running servers, restore shelved servers, and remove shelved servers." +msgstr "Mettre en sommeil des serveurs en fonctionnement, réveiller des serveurs en veille, et enlever des serveurs en veille." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml354(para) +msgid "" +"Shelving is useful when you have an instance that you are not using but " +"would like retain in your list of servers. For example, you can stop an " +"instance at the end of a work week and resume work at the start of the next " +"week. Use the shelve action to shelve a server. All associated " +"data and resources are kept; however, anything still in memory is not " +"retained. You can restore a shelved instance by using the " +"unshelve action. If a shelved instance is no longer needed, you" +" can remove it by using the shelveOffload action." +msgstr "Mettre en sommeil est utile lorsque vous avez une instance que vou sn'utilisez pas, mais que vous souhaitez la conserver dans votre liste de serveurs. Par exemple, vous pouvez arrêter une instanceà la fin d'une semaine de travail, et la réveiller lorsque la semaine suivante commence. Utilisez l'action suspendre pour mettre un serveur en sommeil. Toutes les données et ressources associées sont conservées; cependant, tout ce qui est toujours en mémoire ne l'est pas. Vous pouvez réveiller une instance suspendue en utilisant l'action réveiller. Si une instance suspendue n'est plus nécessaire, vous pouvez l'enlever en utilisant l'action suspendre et décharger." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml370(title) +msgid "Server start and stop (servers)" +msgstr "Démarrage et arrêt du serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml371(para) +msgid "Start a stopped server or stop a running server." +msgstr "Démarrer un serveur arrêté ou stopper un serveur en fonctionnement." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml377(title) +msgid "Manage services (os-services)" +msgstr "Gérer les services (os-services)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml378(para) +msgid "List, enable, and disable Compute services in all hosts." +msgstr "Liste, active, et désactive les services Calcul dans tous les hôtes." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml385(title) +#: ./api-ref/src/docbkx/ch_compute-v3.xml249(title) +msgid "Usage reports (os-simple-tenant-usage)" +msgstr "Rapports d'utilisation (os-simple-tenant-usage)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml386(para) +msgid "Report usage statistics on compute and storage resources." +msgstr "Rapporter les statistiques d'utilisation des ressources de stockage et de calcul." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml393(title) +msgid "Virtual interfaces (os-virtual-interfaces)" +msgstr "Interfaces virtuelles (os-virtual-interfaces)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml394(para) +msgid "List the virtual interfaces for a specified server instance." +msgstr "Liste les interfaces virtuelles pour une instance de serveur spécifiée." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml401(title) +msgid "Volume extension (os-volumes, os-snapshots)" +msgstr "Extension Volume (os-volumes, os-snapshots)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml402(para) +msgid "Manage volumes and snapshots for use with the Compute API." +msgstr "Gestion des volumes et des snapshots à utiliser avec l'API de Calcul." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml409(title) +msgid "Volume attachments (os-volume_attachments)" +msgstr "Distribution des volumes (os-volume_attachments)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml410(para) +msgid "" +"Attach volumes created through the volume API to server instances. Also, " +"list volume attachments for a server instance, get volume details for a " +"volume attachment, and delete a volume attachment." +msgstr "Attache les volumes créés au moyen de l'API Volume aux instances de serveur. De plus, liste les volumes attachés pour une instance de serveur, obtient les informations pour un volume attaché, et détache un volume." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml419(title) +msgid "Servers with block device mapping format (servers)" +msgstr "Serveurs avec un format périphérique en mode bloc mappé (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml421(para) +msgid "Create a server with a block device mapping." +msgstr "Créer un serveur avec un périphérique de bloc mappé." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml427(title) +msgid "Server OS-EXT-IPS-MAC:mac_addr extended attribute (servers)" +msgstr "Attribut étendu de serveur OS-EXT-IPS-MAC:mac_addr (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml429(para) +msgid "" +"Add OS-EXT-IPS-MAC:mac_addr extended attribute when you create, show " +"information for, or list servers." +msgstr "Ajoute l'attribut étendu OS-EXT-IPS-MAC:mac_addr lorsque vous créez, affichez les informations, ou listez les serveurs." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml436(title) +msgid "Configuration drive (servers)" +msgstr "Lecteur de configuration (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml437(para) +msgid "Extend servers and images with a configuration drive." +msgstr "Etendre les serveurs et images avec un lecteur de configuration." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml444(title) +msgid "Servers with extended availability zones (servers)" +msgstr "Serveurs avec zones de disponibilité étendues (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml446(para) +msgid "" +"Show the instance availability zone for compute nodes (nova-compute). " +"Internal services appear in their own internal availability zone." +msgstr "Affiche la zone de disponibilité d'instance pour les noeuds de calcul (nova-compute). Les services internes apparaissent dans leur propre zone de disponiblité interne." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml455(title) +msgid "Servers and images with disk config (servers, images)" +msgstr "Serveurs et images avec configuration disque (servers, images)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml457(para) +msgid "Extend servers with the diskConfig attribute." +msgstr "Etendre les serveurs avec l'attribut diskConfig." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml463(title) +msgid "Server IP type (servers)" +msgstr "Type d'adresse IP de serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml464(para) +msgid "" +"Show the type of the IP addresses assigned to an instance. Type is either " +"fixed or floating." +msgstr "Affiche le type des adresses IP assignées à une instance. Le type est soit fixe soit flottant." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml471(title) +msgid "Server extended attributes (servers)" +msgstr "Attributs étendus de serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml472(para) +msgid "Show metadata for servers." +msgstr "Affiche les métadonnées des serveurs." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml478(title) +msgid "Server extended status (servers)" +msgstr "Status étendu de serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml479(para) +msgid "" +"Show extended status information, vm_state, task_state, and power_state, in " +"detailed server responses." +msgstr "Affiche les informations de status étendues, vm_state, task_state, et power_state, dans les réponses détaillées du serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml486(title) +msgid "Servers multiple create (servers)" +msgstr "Création multiple de serveurs (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml487(para) +msgid "" +"Create one or more servers with an optional reservation ID. The request and " +"response examples show how to create multiple servers with or without a " +"reservation ID." +msgstr "Crée un ou plusieurs serveurs avec un ID de réservation optionnel. Les exemples de requêtes et de réponses montrent comment créer des serveurs multiples avec ou sans ID de réservation." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml495(title) +msgid "Server rescue and unrescue (servers)" +msgstr "Faire entrer et sortir un serveur du mode rescue (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml496(para) +msgid "Put a server into rescue mode or unrescue a server in rescue mode." +msgstr "Mettre un serveur en mode rescue ou sortir un serveur du mode rescue." + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml503(title) +msgid "Servers with scheduler hints (servers)" +msgstr "Serveurs avec conseils d'ordonnancement (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v2-ext.xml504(para) +msgid "Create a server with scheduler hints." +msgstr "Créer un serveur avec suggestions d'ordonnancement." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml10(para) +msgid "" +"Launch virtual machines from images or images stored on persistent volumes. " +"API v1.1 is identical to API v2." +msgstr "Démarrer des machines virtuelles à partir d'images ou d'images stockées sur des volumes persistents. l'API v1.1 est identique à l'API v2." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml18(para) +msgid "List information for all API versions and show details about API v2." +msgstr "Liste les informations pour toutes les versions de l'API et affiche les détails à propos de l'API v2." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml29(title) +msgid "Limits" +msgstr "Limites" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml30(para) +msgid "Get rate and absolute limits." +msgstr "Obtenir les limites de débit et absolue." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml39(para) +msgid "" +"List available Compute API v2 extensions and show details for a specified " +"extension." +msgstr "Liste les extensions de l'API de Calcul v2 disponibles et affiche les informations d'une extension spécifiée." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml51(title) +msgid "Servers" +msgstr "Serveurs" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml52(para) +msgid "List, create, get details for, update, and delete servers." +msgstr "Liste, crée, obtient les informations, modifie, et supprime les serveurs." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml55(emphasis) +msgid "Passwords" +msgstr "Mots de passe" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml56(para) +msgid "" +"When you create a server, you can specify a password through the optional " +"adminPass attribute. The specified password must meet " +"the complexity requirements set by your OpenStack Compute provider. The " +"server might enter an ERROR state if the complexity " +"requirements are not met. In this case, a client might issue a change " +"password action to reset the server password." +msgstr "Lorsque vous créez un serveur, vous pouvez indiquer un mot de passe au moyen de l'attribut optionnel adminPass. Le mot de passe indiqué doit correspondre aux réglages de complexité donnés par votre fournisseur de Calcul OpenStack. Le serveur pourrait provoquer un état d'ERREUR si les critères de complexité ne sont pas remplis. Dans ce cas, un client peut éventuellement déclencher une action de changement de mot de passe pour réinitialiser le mot de passe du serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml62(para) +msgid "" +"If you do not specify a password, a randomly generated password is assigned " +"and returned in the response object. This password is guaranteed to meet the" +" security requirements set by the compute provider. For security reasons, " +"the password is not returned in subsequent calls." +msgstr "Si vous n'indiquez pas de mot de passe, un mot de passe généré de façon aléatoire est configuré et retourné dans l'objet réponse. Ce mot de passe obéira aux règles de complexité réglés par le fournisseur de calcul. Pour des raisons de sécurité, le mot de passe n'est pas retourné dans les appels ultérieurs." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml70(emphasis) +#: ./api-ref/src/docbkx/ch_compute-v2.xml172(title) +msgid "Server metadata" +msgstr "Métadonnées de serveur" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml71(para) +msgid "" +"You can specify custom server metadata at server launch time. The maximum " +"size for each metadata key-value pair is 255 bytes. The maximum number of " +"key-value pairs that can be supplied per server is determined by the compute" +" provider. You can query this value through the maxServerMeta " +"absolute limit." +msgstr "Vous pouvez indiquer des métadonnées de serveur customisées au lancement de celui-ci. La taille maximale pour chaque clé-valeur de métadonnée est de 255 octets. Le nombre maximal de paires clé-valeur qui peuvent être fournies par serveur est déterminé par le fournisseur de calcul. Vous pouvez obtenir cette valeur au moyen de la limite absolue maxServerMeta." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml80(emphasis) +msgid "Server networks" +msgstr "Réseaux du serveur" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml81(para) +msgid "" +"You can specify networks to which the server connects at launch time. You " +"can specify one or more networks. Users can also specify a specific port on " +"the network or the fixed IP address to assign to the server interface." +msgstr "Vous pouvez spécifier les réseaux auxquels le serveur se connecte lors du lancement. Vous pouvez spécifier un ou plusieurs réseaux. Les utilisateurs peuvent aussi indiquer un port spécifique sur le réseau ou une adresse IP fixe à assigner à l'interface du serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml85(para) +msgid "" +"You can use both IPv4 and IPv6 addresses as access addresses and you can " +"assign both addresses simultaneously. You can update access addresses after " +"you create a server." +msgstr "Vous pouvez utiliser à la fois des adresses IPv4 et IPv6 en tant qu'adresses d'accès et vous pouvez configurer ces deux adresses simultanément. Vous pouvez mettre à jour les adresses d'accès après avoir créé un serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml93(emphasis) +msgid "Server personality" +msgstr "Personnalité du serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml94(para) +msgid "" +"You can customize the personality of a server instance by injecting data " +"into its file system. For example, you might want to insert ssh keys, set " +"configuration files, or store data that you want to retrieve from inside the" +" instance. This feature provides a minimal amount of launch-time " +"personalization. If you require significant customization, create a custom " +"image." +msgstr "Vous pouvez personnaliser la personnalité d'une instance de serveur en injectant des données dans son système de fichiers. Par exemple, vous pourriez insérer des clés ssh, écrire des fichiers de configuration, ou stocker des données que vous souhaiteriez retrouver depuis l'intérieur de l'instance. Cette fonctionnalité donne une personnalisation du démarrage minimale. Si vous avez besoin de plus de personnalisation, créez une image personnalisée." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml99(para) +msgid "Follow these guidelines when you inject files:" +msgstr "Suivez ces recommandations lorsque vous injectez des fichiers:" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml102(para) +msgid "The maximum size of the file path data is 255 bytes." +msgstr "La taille maximum des données de chemin de fichier est de 255 octets." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml105(para) +msgid "" +"Encode the file contents as a Base64 string. The compute providers " +"determines the maximum size of the file contents. This value can vary based " +"on the image that is used to create the server." +msgstr "Encodez le contenu des fichiers en tant que chaine de caractères en Base64. Les fournisseurs de calcul déterminent la taille maximum du contenu des fichiers. Cette valeur peut varier en fonction de l'image qui est utilisée pour créer le serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml109(para) +msgid "" +"The maximum limit refers to the number of bytes in the decoded data and not " +"to the number of characters in the encoded data." +msgstr "La limite maximum fait référence au nombre d'octets dans les données décodées et pas au nombre de caractères dans les données encodées." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml114(para) +msgid "" +"You can inject text files only. You cannot inject binary or ZIP files into a" +" new build." +msgstr "Vous pouvez injecter des fichiers texte seulement. Vous ne pouvez pas injecter de fichiers binaires ou au format ZIP dans une nouvelle version." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml118(para) +msgid "" +"The maximum number of file path/content pairs that you can supply is also " +"determined by the compute provider and is defined by the maxPersonality " +"absolute limit." +msgstr "Le nombre maximum de paires chemin de fichier/contenu que vous pouvez fournir est aussi déterminé par le fournisseur de calcul et est défini parla limite absolue maxPersonality." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml123(para) +msgid "" +"The absolute limit, maxPersonalitySize, is a byte limit that is" +" guaranteed to apply to all images in the deployment. Providers can set " +"additional per-image personality limits." +msgstr "La limite absolue, maxPersonalitySize, est une limite en octets qui est garantie s'appliquer à toutes les images dans le déploiement. Les fournisseurs peuvent configurer des limites de personnalité par image." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml128(para) +msgid "" +"The file injection might not occur until after the server is built and " +"booted." +msgstr "L'injection de fichier ne devrait pas pouvoir survenir avant que le serveur n'est été construit et n'ait booté." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml130(para) +msgid "" +"During file injection, any existing files that match specified files are " +"renamed to include the BAK extension appended with a time stamp. For " +"example, if the /etc/passwd file exists, it is backed " +"up as /etc/passwd.bak.1246036261.5785." +msgstr "Durant l'injection de fichier, tout fichier existant correspondant aux fichiers spécifiés est renommé afin d'inclure l'extension BAK avec la date et l'heure. Par exemple, si le fichier /etc/passwd existe, il est dupliqué en tant que /etc/passwd.bak.1246036261.5785." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml134(para) +msgid "" +"After file injection, personality files are accessible by only system " +"administrators. For example, on Linux, all files have root and the root " +"group as the owner and group owner, respectively, and allow user and group " +"read access only ( )." +msgstr "Après l'injection du fichier, les fichiers de personnalité sont accessibles uniquement par les administrateurs système. Par exemple, sous Linux, tous les fichiers ont l'utilisateur propriétaire root et le groupe root, respectivement, et permettent seulement des accès en lecture seule au propriétaire et au groupe ( )." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml142(emphasis) +msgid "Server access addresses" +msgstr "Adresses d'accès au serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml143(para) +msgid "" +"In a hybrid environment, the IP address of a server might not be controlled " +"by the underlying implementation. Instead, the access IP address might be " +"part of the dedicated hardware; for example, a router/NAT device. In this " +"case, the addresses provided by the implementation cannot actually be used " +"to access the server (from outside the local LAN). Here, a separate " +"access address might be assigned at creation time to " +"provide access to the server. This address might not be directly bound to a " +"network interface on the server and might not necessarily appear when you " +"query the server addresses. See . Nonetheless, clients that must access the server directly are" +" encouraged to do so through an access address." +msgstr "Dans un environnement hybride, l'adresse IP d'un serveur pourrait ne pas être contrôlée par l'implémentation inférieure. Au lieu de cela, l'adresse IP d'accès pourrait être une partie d'un composant matériel dédié; par exemple, un périphérique de routage/NAT. Dans ce cas, les adresses fournies par l'implémentation ne peuvent pas être utilisées pour accéder au serveur (depuis l'extérieur du réseau local). Ici, une adresse d'accès séparée pourrait être assignée au moment de la création pour donner l'accès au serveur. Cette adresse pourrait ne pas être directement liée à une interface réseau sur le serveur et pourrait ne pas nécessairement apparaître lorsque vous interrogez les adresses du serveur. Voyez . Néanmoins, les clients qui doivent accéder au serveur directement sont encouragés à le faire au moyen d'une adresse d'accès." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml173(para) +msgid "" +"Show details for, set, update, and delete server metadata or metadata items." +msgstr "Affiche les informations, configure, modifie, et supprime les métadonnées du serveur ou des objets." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml189(title) +msgid "Server addresses" +msgstr "Adresses du serveur" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml190(para) +msgid "" +"List addresses for a specified server or a specified server and network." +msgstr "Liste les adresses d'un serveur spécifié ou d'un serveur et d'un réseau spécifiés." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml197(title) +msgid "Server actions" +msgstr "Actions de serveur" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml198(para) +msgid "" +"Perform actions for a specified server, including change administrator " +"password, reboot, rebuild, resize, and create image from server." +msgstr "Met en oeuvre les actions pour un serveur spécifié, incluant le changement du mot de passe administrateur, le reboot, la reconstruction, le re-dimensionnement, et crée une image à partir d'un serveur." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml213(title) +msgid "Flavors" +msgstr "Types d'instance" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml214(para) +msgid "" +"List available flavors and get details for a specified flavor. A flavor is a" +" hardware configuration for a server. Each flavor is a unique combination of" +" disk space and memory capacity." +msgstr "Liste les types d'instances disponibles et obtient les informations d'un type d'instance spécifié. Un type d'instance est une configuration typique de matériel pour un serveur. Chaque type d'instance est une combinaison unique d'espace disque et de capacité mémoire." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml231(para) +msgid "" +"List available images, get details for a specified image, and delete an " +"image." +msgstr "Liste les images disponibles, obtient les informations pour une image spécifiée, et supprime une image." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml232(para) +msgid "Also, set, list, get details for, and delete image metadata." +msgstr "De plus, configure, liste, obtient les informations, et supprime les métadonnées d'une image." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml233(para) +msgid "" +"An image is a collection of files that you use to create or rebuild a " +"server. By default, operators provide pre-built operating system images. You" +" can also create custom images: See ." +msgstr "Une image est une collection de fichiers que vous utilisez pour créer ou reconstruire un serveur. Par défaut, les opérateurs fournissent des images de système d'exploitation pré-construites. Vous pouvez aussi créer des images customisées: voyez ." + +#: ./api-ref/src/docbkx/ch_compute-v2.xml250(title) +msgid "Image metadata" +msgstr "Métadonnées d'image" + +#: ./api-ref/src/docbkx/ch_compute-v2.xml251(para) +msgid "" +"Show details for, set, update, and delete image metadata or metadata items." +msgstr "Affiche les informations, configure, modifie, et supprime les métadonnées d'image ou objets de métadonnées." + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml10(para) +msgid "" +"Use virtual networking services among devices that are managed by the " +"OpenStack Compute service. The Networking (neutron) API v2.0 combines the " +"API v1.1 functionality with some essential Internet Protocol Address " +"Management (IPAM) functionality. Enables users to associate IP address " +"blocks and other network configuration settings with an OpenStack Networking" +" network. You can choose a specific IP address from the block or let " +"OpenStack Networking choose the first available IP address." +msgstr "Utilisez les services de réseau virtuels parmi les périphériques qui sont gérés par le service de Calcul OpenStack. L'API de Gestion Réseau (neutron) v2.0 combine la fonctionnalité de l'API v1.1 avec quelques-unes des fonctionnalités de Gestion d'Adresse de Protocole Internet (IPAM) essentielles. Permet aux utilisateurs d'associer des blocs d'adresses IP et d'autres réglages de configuration réseau avec un réseau OpenStack Networking. Vous pouvez choisir une adresse IP spécifique à partir du bloc ou laisser la couche Réseau d'OpenStack choisir la première adresse IP disponible." + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml21(para) +msgid "" +"List information for all Networking API versions and show details about API " +"v2." +msgstr "Liste les informations pour toutes les versions de l'API de Gestion Réseau et affiche les détails de l'API v2." + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml34(title) +msgid "Networks" +msgstr "Réseaux" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml35(para) +msgid "List, show information for, create, update, and delete networks." +msgstr "Liste, affiche les informations, crée, modifie, et supprime les réseaux." + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml42(title) +msgid "Subnets" +msgstr "Sous-réseaux" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml43(para) +msgid "" +"List, show information for, create, update, and delete subnet resources." +msgstr "Liste, affiche les informations, crée, modifie, et supprime les ressources de sous-réseau." + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml50(title) +msgid "Ports" +msgstr "Ports" + +#: ./api-ref/src/docbkx/ch_netconn-v2.xml51(para) +msgid "List, show information for, create, update, and delete ports." +msgstr "Liste, affiche les informations, crée, modifie, et supprime les ports." + +#: ./api-ref/src/docbkx/api-ref-image-v2.xml11(title) +msgid "OpenStack Image Service API v2" +msgstr "API du Service d'Image OpenStack v2" + +#: ./api-ref/src/docbkx/ch_identity-v2.xml11(para) +#: ./api-ref/src/docbkx/ch_identity-v3.xml8(para) +msgid "" +"Get an authentication token that permits access to the OpenStack services " +"REST API." +msgstr "Obtenir un jeton d'authentification permettant l'accès aux services de l'API REST d'OpenStack." + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml13(title) +msgid "Identity API v2.0 extensions (STABLE)" +msgstr "Extensions de l'API de Gestion des Indentités v2.0 (STABLE)" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml14(para) +msgid "" +"Query the Identity API to list available extensions with a GET request to " +"v2.0/extensions." +msgstr "Demande à l'API de Gestion des Identités de lister les extensions disponibles au moyen d'une requête GET sur les extensions/v2.0." + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml17(title) +msgid "HP-IDM-serviceId extended parameter" +msgstr "Paramètre étendu HP-IDM-serviceId" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml23(title) +msgid "OS-KSADM admin extension" +msgstr "Extension d'administration OS-KSADM" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml96(title) +msgid "OS-KSCATALOG admin extension" +msgstr "Extension d'administration OS-KSCATALOG" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml102(title) +msgid "OS-KSEC2 admin extension" +msgstr "Extension d'administration OS-KSEC2" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml108(title) +msgid "OS-KSS3 admin extension" +msgstr "Extension d'administration OS-KSS3" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml114(title) +msgid "OS-KSVALIDATE admin extension" +msgstr "Extension d'administration OS-KSVALIDATE" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml120(title) +msgid "RAX-GRPADM admin extension" +msgstr "Extension d'administration RAX-GRPADM" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml126(title) +msgid "RAX-KSGRP admin extension" +msgstr "Extension d'administration RAX-KSGRP" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml132(title) +msgid "RAX-KSKEY admin extension" +msgstr "Extension d'administration RAX-KSKEY" + +#: ./api-ref/src/docbkx/ch_identity-v2-ext.xml138(title) +msgid "RAX-KSQA admin extension" +msgstr "Extension d'administration RAX-KSQA" + +#: ./api-ref/src/docbkx/api-ref-orchestration-v1.xml11(title) +msgid "OpenStack Orchestration API v1" +msgstr "API d'Orchestration v1 OpenStack" + +#: ./api-ref/src/docbkx/api-ref-networking-v2.xml11(title) +msgid "OpenStack Networking API v2.0" +msgstr "API de Gestion Réseau v2.0 OpenStack" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml9(title) +msgid "Databases Service API v1.0 (CURRENT)" +msgstr "API de Service de Base de données v1.0 (ACTUELLE)" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml25(title) +msgid "Database instances (instances)" +msgstr "Instances de base de données (instances)" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml45(title) +msgid "Database instance actions (action)" +msgstr "Actions d'instance de base de données (action)" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml56(title) +msgid "Databases (databases)" +msgstr "Bases de données (databases)" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml70(title) +msgid "Users (users)" +msgstr "Utilisateurs (users)" + +#: ./api-ref/src/docbkx/ch_databases-v1.xml84(title) +msgid "Flavors (flavors)" +msgstr "Types d'instance (flavors)" + +#: ./api-ref/src/docbkx/api-ref-compute-v2.xml11(title) +msgid "OpenStack Compute API v2 (CURRENT)" +msgstr "API de Calcul v2 OpenStack (ACTUELLE)" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml11(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml11(para) +msgid "" +"Manage volumes and snapshots for use with the Block Storage API, also known " +"as cinder services." +msgstr "Gère les volumes et les instantanés à utiliser avec l'API de Stockage par Bloc, aussi connu en tant que services cinder." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml27(title) +msgid "API extensions" +msgstr "Extensions de l'API" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml36(title) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml58(title) +msgid "Volumes" +msgstr "Volumes" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml37(para) +msgid "" +"A volume is a detachable block storage device. You can think of it as a USB " +"hard drive. You can attach a volume to one instance at a time." +msgstr "Un volume est un périphérique de stockage par bloc amovible. Vous pouvez le voir comme un disque dur USB. Vous pouvez attacher un volume à une instance à un moment." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml40(para) +msgid "" +"When you create, list, or delete volumes, these status values are possible:" +msgstr "Quand vous créez, listez ou détruisez des volumes, ces valeurs de statuts sont possibles :" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml51(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml154(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml273(para) +msgid "creating" +msgstr "création" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml52(para) +msgid "The volume is being created." +msgstr "Le volume est en train d'être créer." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml55(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml159(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml278(para) +msgid "available" +msgstr "disponible" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml56(para) +msgid "The volume is ready to be attached to an instance." +msgstr "Le volume est prêt à être attaché à une instance." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml60(para) +msgid "attaching" +msgstr "attachement" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml61(para) +msgid "The volume is attaching to an instance." +msgstr "Le volume est attaché à une instance." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml65(para) +msgid "in-use" +msgstr "en cours d'utilisation" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml66(para) +msgid "The volume is attached to an instance." +msgstr "Le volume est attaché à une instance." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml70(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml164(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml284(para) +msgid "deleting" +msgstr "suppression" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml71(para) +msgid "The volume is being deleted." +msgstr "Le volume est en train d'être supprimer." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml74(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml169(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml289(para) +msgid "error" +msgstr "erreur" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml75(para) +msgid "An error occurred during volume creation." +msgstr "Une erreur est survenue durant la création du volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml79(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml175(para) +msgid "error_deleting" +msgstr "erreur_suppression" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml80(para) +msgid "An error occurred during volume deletion." +msgstr "Une erreur est survenue durant la suppression du volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml84(para) +msgid "backing-up" +msgstr "sauvegarde en cours" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml85(para) +msgid "The volume is being backed up." +msgstr "Le volume est en train d'être sauvegardé." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml88(para) +msgid "restoring-backup" +msgstr "restauration de sauvegarde" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml89(para) +msgid "A backup is being restored to the volume." +msgstr "Une sauvegarde est en train de restaurer un volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml93(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml301(para) +msgid "error_restoring" +msgstr "erreur_restauration" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml94(para) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml302(para) +msgid "An error occurred during backup restoration to a volume." +msgstr "Une erreur est survenue durant la sauvegarde de restauration d'un volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml118(title) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml77(title) +msgid "Volume types" +msgstr "Types de volume" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml139(title) +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml98(title) +msgid "Snapshots" +msgstr "Instantanés " + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml140(para) +msgid "A snapshot is a point in time copy of the data that a volume contains." +msgstr "Un instantané est à un moment précis une copie des données qu'un volume contient. " + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml142(para) +msgid "" +"When you create, list, or delete snapshots, these status values are " +"possible:" +msgstr "Quand vous créez, listez ou supprimez des instantanés, ces valeurs de statuts sont possibles :" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml155(para) +msgid "The snapshot is being created." +msgstr "L'instantané est en train d'être créé." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml160(para) +msgid "The snapshot is ready to be used." +msgstr "L'instantané est prêt à être utilisé." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml165(para) +msgid "The snapshot is being deleted." +msgstr "L'instantané est en train d'être supprimer." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml170(para) +msgid "An error occurred during snapshot creation." +msgstr "Une erreur est survenue durant la création d'un instantané." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml176(para) +msgid "An error occurred during snapshot deletion." +msgstr "Une erreur est survenue durant la suppression d'un instantané." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml205(title) +msgid "Quality of service (QoS) specifications (qos-specs)" +msgstr "Spécifications de qualité de service (QoS) (qos-specs)" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml207(para) +msgid "" +"Administrators only, depending on policy settings. Create, list, show " +"details for, associate, disassociate, and delete quality of service (QoS) " +"specifications." +msgstr "Pour administrateurs seulement, en fonction des réglages de la police. Crée, liste, affiche les informations, associe, désassocie, et supprime les spécifications de qualité de service (QoS)." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml237(title) +msgid "Quota sets extension (os-quota-sets)" +msgstr "Extension de jeux de quotas (os-quota-sets)" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml238(para) +msgid "" +"Administrators only, depending on policy settings. View, update, and delete " +"quotas for a tenant." +msgstr "Pour administrateurs seulement, en fonction des réglages de police. Affiche, modifie, et supprime les quotas pour un client." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml245(title) +msgid "Limits extension (limits)" +msgstr "Extension de Limites (limits)" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml246(para) +msgid "Show absolute limits for a tenant." +msgstr "Affiche les limites absolues pour un client." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml252(title) +msgid "Backups" +msgstr "Sauvegardes" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml253(para) +msgid "" +"A backup is a full copy of a volume stored in an external service. The " +"service can be configured. The only supported service for now is Object " +"Storage. A backup can subsequently be restored from the external service to " +"either the same volume that the backup was originally taken from, or to a " +"new volume. backup and restore operations can only be carried out on volumes" +" which are in an unattached and available state." +msgstr "Une sauvegarde est une copie complète d'un volume stocké dans un service externe. Ce service peut être configuré. Le seul service supporté aujourd'hui est Object Storage. Une sauvegarde peut ensuite être restaurée depuis un service externe dans au choix le même volume où la sauvegarde a été prise ou dans un nouveau volume. Les opérations de sauvegarde et de restauration ne peuvent être uniquement effectuées sur des volumes qui sont dans des états libres et disponibles." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml261(para) +msgid "" +"When you create, list, or delete backups, these status values are possible:" +msgstr "Quand vous créez, listez ou supprimez des sauvegardes, ces valeurs de statuts sont possibles :" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml274(para) +msgid "The backup is being created." +msgstr "La sauvegarde est en train d'être créée." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml279(para) +msgid "The backup is ready to be restored to a volume." +msgstr "La sauvegarde est prête à être restaurer dans un volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml285(para) +msgid "The backup is being deleted." +msgstr "La sauvegarde est en train d'être supprimer." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml290(para) +msgid "An error has occurred with the backup." +msgstr "Une erreur est survenue avec la sauvegarde." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml295(para) +msgid "restoring" +msgstr "restauration en cours" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml296(para) +msgid "The backup is being restored to a volume." +msgstr "La sauvegarde va être restaurée dans un volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v2.xml307(para) +msgid "" +"In the event of an error, more information about the error can be found in " +"the fail_reason field for the backup." +msgstr "Dans l'éventualité d'une erreur, plus d'information sur celle-ci peut être trouvé dans le champ fail_reason pour la sauvegarde. " + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml10(para) +msgid "Use a template language to orchestrate OpenStack services." +msgstr "Utilise un modèle de language pour orchestrer les services OpenStack." + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml22(title) +msgid "Stacks" +msgstr "Piles" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml51(title) +msgid "Stack actions" +msgstr "Actions de pile." + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml52(para) +msgid "" +"Performs non-lifecycle operations on the stack. Specify the action in the " +"request body." +msgstr "Exécute les opérations hors cycle de vie sur la pile. Spécifie l'action dans le corps de la requête." + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml63(title) +msgid "Stack resources" +msgstr "Ressources de pile" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml96(title) +msgid "Stack events" +msgstr "Evénements de pile" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml117(title) +msgid "Templates" +msgstr "Modèles" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml130(title) +msgid "Build info" +msgstr "Information de version" + +#: ./api-ref/src/docbkx/ch_orchestration-v1.xml139(title) +msgid "Software configuration" +msgstr "Configuration du logiciel" + +#: ./api-ref/src/docbkx/api-ref-image-v1.xml11(title) +msgid "OpenStack Image Service API v1" +msgstr "API de Service d'Image v1 OpenStack" + +#: ./api-ref/src/docbkx/ch_images-v2.xml10(para) +msgid "Image Service API v2.0, API v2.1, and API v2.2." +msgstr "API du Service d'Images v2.0, API v2.1, et API v2.2" + +#: ./api-ref/src/docbkx/ch_images-v2.xml29(para) +msgid "" +"Create, update, and delete image metadata records. Enable users to share " +"images with each other. Also, upload and download raw image data." +msgstr "Crée, modifie, et supprime les enregistrements des métadonnées d'image. Permet aux utilisateurs de partager des images entre eux. De plus, envoi ou télécharge les données brutes d'image." + +#: ./api-ref/src/docbkx/ch_images-v2.xml47(title) +msgid "Image data" +msgstr "Données d'image" + +#: ./api-ref/src/docbkx/ch_images-v2.xml48(para) +msgid "Upload and download raw image data." +msgstr "Envoyer et télécharger des données brutes d'image." + +#: ./api-ref/src/docbkx/ch_images-v2.xml58(title) +msgid "Image tags" +msgstr "Etiquettes d'image" + +#: ./api-ref/src/docbkx/ch_images-v2.xml59(para) +msgid "Add and delete image tags." +msgstr "Ajoute et supprime des étiquettes d'image." + +#: ./api-ref/src/docbkx/ch_images-v2.xml85(title) +msgid "Image schemas" +msgstr "Schémas d'images" + +#: ./api-ref/src/docbkx/ch_images-v2.xml86(para) +msgid "Get a JSON-schema document that represents an images or image entity." +msgstr "Obtient un document schéma-JSON qui représente une image ou une entité d'image." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml15(para) +msgid "" +"XML support in requests and responses has been deprecated for the Compute " +"API v3." +msgstr "Le support d'XML dans les requêtes et les réponses a été abandonné pour l'API de Calcul v3." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml22(para) +msgid "List information for all API versions." +msgstr "Liste les informations pour toutes les versions de l'API." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml35(title) +msgid "Server admin actions (servers)" +msgstr "Actions de l'administration de serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml36(para) +msgid "" +"Administrators only. Perform actions on a server. Specify the action in the " +"request body." +msgstr "Pour administrateurs seulement. Exécute des actions sur un serveur. Spécifie l'action dans le corps de la requête." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml44(para) +msgid "" +"Creates, updates, and deletes guest agents. Use guest agents to access files" +" on the disk, configure networking, or run other applications or scripts in " +"the guest while it runs. This hypervisor-specific extension is not currently" +" enabled for KVM. Use of guest agents is possible only if the underlying " +"service provider uses the Xen driver." +msgstr "Crée, modifie, et supprime des agents invités. Utilisez les agents invités pour accéder aux fichiers sur le disque, configurer le réseau, ou lancer d'autres applications ou scripts dans l'invité en fonctionnement. Cette extension hyperviseur spécifique n'est pas actuellement active pour KVM. L'utilisation des agents invités est possible seulement si le fournisseur de servce sous-jacent utilise le driver Xen." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml56(para) +msgid "" +"Creates and manages host aggregates. An aggregate assigns metadata to groups" +" of compute nodes. Aggregates are only visible to the cloud provider." +msgstr "Crée et gère les agrégats d'hôtes. Un agrégat assigne des métadonnées à des groupes de noeuds de calcul. Les agrégats sont seulement visibles au fournisseur du cloud." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml64(title) +msgid "Cells (os-cells)" +msgstr "Cellules (os-cells)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml65(para) +msgid "" +"Enables cells-related functionality such as adding neighbor cells, listing " +"neighbor cells, and getting the capabilities of the local cell." +msgstr "Autorise les fonctionnalités relatives aux cellules comme l'ajout de cellules voisines, le listage des cellules voisines, et l'obtention des capacités de la cellule locale." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml74(para) +msgid "Creates and shows details for a root certificate." +msgstr "Crée et affiche les détails d'un certificat racine." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml80(title) +msgid "Configuration drive (os-config-drive)" +msgstr "Lecteur de configuration (os-config-drive)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml81(para) +msgid "Returns server details for a specific service ID or user." +msgstr "Retourne les informations de serveur pour un ID de service spécifique ou un utilisateur." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml89(para) +msgid "Force-deletes a server or restores a deleted server." +msgstr "Force la suppression d'un serveur ou restaure un serveur supprimé." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml95(title) +msgid "Evacuate (os-evacuate)" +msgstr "Evacuer (os-evacuate)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml96(para) +msgid "Enables server evacuation." +msgstr "Active l'évacuation du serveur." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml102(title) +msgid "" +"Servers with extended availability zones (os-extended-availability-zone)" +msgstr "Serveurs avec zones de disponibilité étendues (os-extended-availability-zone)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml104(para) +msgid "" +"Shows the instance availability zone for compute nodes (nova-compute). " +"Internal services appear in their own internal availability zone." +msgstr "Affiche la zone de disponibilité de l'instance pour les noeuds de calcul (nova-compute). Les services internes apparaissent dans leur propre zone de disponibilité." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml112(title) +msgid "Server extended attributes (os-extended-server-attributes)" +msgstr "Attributs de serveur étendus (os-extended-server-attributes)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml114(para) +msgid "Shows metadata for servers." +msgstr "Affiche les métadonnées des serveurs." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml120(title) +msgid "Server extended status (os-extended-status)" +msgstr "Status étendu de serveur (os-extended-status)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml121(para) +msgid "" +"Shows extended status information, vm_state, task_state, and power_state, in" +" detailed server responses." +msgstr "Affiche les information de status étendues, vm_state, task_state, et power_state, dans les réponses détaillées de serveur." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml128(title) +msgid "Flavor access (os-flavor-access)" +msgstr "Accès aux types d'instance (os-flavor-access)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml129(para) +msgid "Flavor access support." +msgstr "Support de l'accès aux types d'instance." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml135(title) +msgid "Flavor extra-specs (flavor-extra-specs)" +msgstr "Spécifications additionnelles de type d'instance (flavor-extra-specs)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml136(para) +msgid "" +"Lists, creates, deletes, and updates the extra-specs or keys for a flavor." +msgstr "Liste, crée, supprime, et modifie les spécifications additionnelles ou clés pour un type d'instance." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml143(title) +msgid "Flavors manage (flavor-manage)" +msgstr "Gestion des types d'instance (flavor-manage)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml144(para) +msgid "Support for creating and deleting flavor." +msgstr "Support pour la création et suppression du type d'instance." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml150(title) +msgid "Flavors with rxtx_factor extended attribute (os-flavor-rxtx)" +msgstr "Types d'instance avec l'attribut étendu rxtx_factor (os-flavor-rxtx)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml152(para) +msgid "Support to show the rxtx status of a flavor." +msgstr "Support pour afficher le status rxtx d'un type d'instance." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml159(para) +msgid "Returns information about Flavors." +msgstr "Retourne des informations sur les types d'instances. " + +#: ./api-ref/src/docbkx/ch_compute-v3.xml166(para) +msgid "Manages physical hosts." +msgstr "Gère les hôtes physiques." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml173(para) +msgid "" +"Displays extra statistical information from the machine that hosts the " +"hypervisor through the API for the hypervisor (XenAPI or KVM/libvirt)." +msgstr "Affiche des informations statistiques additionnelles à partir de la machine qui héberge l'hyperviseur au moyen de l'API pour l'hyperviseur (XenAPI ou KVM/libvirt)." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml181(title) +msgid "Server actions (servers)" +msgstr "Actions de serveur (servers)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml182(para) +msgid "" +"Permits all users to list available actions for a specified server. Permits " +"administrators to get details for a specified action for a specified server." +msgstr "Autorise les utilisateurs à lister les actions disponibles pour un serveur spécifié. Permet aux administrateurs d'obtenir les détails d'une action spécifiée pour un serveur spécifié." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml190(title) +msgid "Instance usage audit log (os-instance-usage-audit-log)" +msgstr "Journal d'audit de l'utilisation de l'instance (os-instance-usage-audit-log)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml192(para) +msgid "Admin-only task log monitoring." +msgstr "Surveillance du journal de tâche de l'administrateur seulement." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml198(title) +msgid "Limits (limits)" +msgstr "Limites (limits)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml199(para) +msgid "Provide all global and rate limit information." +msgstr "Donne toutes les informations de limite de débit et limite globale." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml206(para) +msgid "Provide data on migrations." +msgstr "Fournit des données sur les migrations." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml212(title) +msgid "Multinic (os-multinic)" +msgstr "Multinic (os-multinic)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml213(para) +msgid "Multiple network support." +msgstr "Support de réseau multiple." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml219(title) +msgid "Quota class (os-quota-class-sets)" +msgstr "Classe de quota (os-quota-class-sets)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml220(para) +msgid "Quota classes management support." +msgstr "Support de la gestion des classes de quota." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml227(para) +msgid "" +"Permits administrators, depending on policy settings, to view quotas for a " +"tenant and view and update default quotas." +msgstr "Permet aux administrateurs, en fonction des réglages de la police, de voir les quotas pour un client et de voir et modifier les quotas par défaut." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml235(title) +msgid "Server remote console (os-remote-consoles)" +msgstr "Console du serveur distant (os-remote-consoles)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml236(para) +msgid "Interactive console support." +msgstr "Support de la console interactive." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml242(title) +msgid "Server usage (os-server-usage)" +msgstr "Utilisation du serveur (os-server-usage)" + +#: ./api-ref/src/docbkx/ch_compute-v3.xml243(para) +msgid "Adds launched_at and terminated_at to servers." +msgstr "Ajoute launched_at et terminated_at aux serveurs." + +#: ./api-ref/src/docbkx/ch_compute-v3.xml250(para) +msgid "Provide simple tenant usage for tenant." +msgstr "Donne l'utilisation du client simple pour le client." + +#: ./api-ref/src/docbkx/api-ref-telemetry-v2.xml11(title) +msgid "OpenStack Telemetry API v2" +msgstr "API de Télémétrie v2 OpenStack" + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml13(para) +msgid "" +"When making an API call to create, list, or delete volume(s), the following " +"status values are possible:" +msgstr "Quand vous faîtes un appel à l'API pour créer, lister ou supprimer un ou des volume(s), les valeurs de statuts suivantes sont possibles : " + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml18(para) +msgid "CREATING: The volume is being created." +msgstr "CRÉATION : Le volume va être créé." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml21(para) +msgid "AVAILABLE: The volume is read to be attached to an instance." +msgstr "DISPONIBLE : Le volume est prêt à être attaché à une instance." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml25(para) +msgid "ATTACHING: The volume is attaching to an instance." +msgstr "ATTACHEMENT : Le volume est attaché à une instance." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml29(para) +msgid "IN-USE: The volume is attached to an instance." +msgstr "UTILISATION EN COURS : Le volume est attaché à une instance." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml33(para) +msgid "DELETING: The volume is being deleted." +msgstr "SUPPRESSION : Le volume est en train d'être supprimer." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml36(para) +msgid "ERROR: An error has occurred with the volume." +msgstr "ERREUR : Une erreur est survenue avec le volume." + +#: ./api-ref/src/docbkx/ch_blockstorage-api-v1.xml40(para) +msgid "ERROR_DELETING: There was an error deleting the volume." +msgstr "ERREUR_SUPPRESSION : Il y a eu une erreur supprimant le volume." + +#: ./api-ref/src/docbkx/api-ref-blockstorage-v2.xml11(title) +msgid "OpenStack Block Storage API v2" +msgstr "API de Stockage par Bloc v2 OpenStack" + +#: ./api-ref/src/docbkx/api-ref-identity-v2.xml11(title) +msgid "OpenStack Identity API v2 and extensions" +msgstr "API de Gestion des Identités v2 OpenStack et extensions" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml25(para) +msgid "Manage tokens." +msgstr "Gestion des jetons." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml38(title) +msgid "Service catalog" +msgstr "Catalogue de services" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml39(para) +msgid "Manage the catalog of services." +msgstr "Gestion du catalogue de services." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml56(title) +msgid "Endpoints" +msgstr "Points de terminaison" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml57(para) +msgid "Manage endpoints." +msgstr "Gestion des points de terminaison." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml67(title) +msgid "Domains" +msgstr "Domaines" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml68(para) +msgid "Manage domains." +msgstr "Gestion des domaines." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml69(para) +msgid "" +"Domains represent collections of users, groups, and projects. Each is owned " +"by exactly one domain. Users, however, can be associated with multiple " +"projects by granting roles to the user on a project, including projects " +"owned by other domains." +msgstr "Les domaines représentent des collections d'utilisateurs, de groupes, et de projets. Chacun d'entre eux est possédé par exactement un domaine. Les utilisateurs, cependant, peuvent être associés avec des projets multiples en accordant des rôles à un utilisateur sur un projet, incluant les projets possédés par d'autres domaines." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml72(para) +msgid "" +"Each domain defines a namespace where certain API-visible name attributes " +"exist, which affects whether those names must be globally unique or unique " +"within that domain. In the Identity API, the uniqueness of the following " +"attributes is as follows:" +msgstr "Chaque domaine défini un espace de nommage où certains attributs de nom visibles de l'API existent, ce qui affecte le fait que ces noms doivent être globallement uniques ou uniques à l'intérieur de ce domaine. Dans l'API de Gestion des Identités, la caractère unique des attributs suivants est représenté comme suit:" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml77(para) +msgid "" +"Domain Name. Globally unique across all" +" domains." +msgstr "Nom de Domain. Globallement unique à travers tous les domaines." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml81(para) +msgid "" +"Role Name. Globally unique across all " +"domains." +msgstr "Nom de Rôle. Globallement unique à travers tous les domaines." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml85(para) +msgid "" +"User Name. Unique within the owning " +"domain." +msgstr "Nom d'Utilisateur. Unique à l'intérieur du domaine dont il est issu." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml89(para) +msgid "" +"Project Name. Unique within the owning " +"domain." +msgstr "Nom de Projet. Unique à l'intérieur du domaine dont il est issu." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml93(para) +msgid "" +"Group Name. Unique within the owning " +"domain." +msgstr "Nom de Groupe. Unique à l'intérieur du domaine dont il est issu." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml132(title) +msgid "Projects" +msgstr "Projets" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml133(para) +msgid "Manage projects." +msgstr "Gestion des projets." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml168(para) +msgid "Manage users." +msgstr "Gestion des utilisateurs." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml196(title) +msgid "Groups" +msgstr "Groupes" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml197(para) +msgid "Manage groups." +msgstr "Gestion des groupes." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml225(title) +msgid "Credentials" +msgstr "Information d'Authentification " + +#: ./api-ref/src/docbkx/ch_identity-v3.xml226(para) +msgid "Manage credentials." +msgstr "Gestion des informations d'authentification." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml244(title) +msgid "Roles" +msgstr "Rôles" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml245(para) +msgid "Manage roles." +msgstr "Gestion des rôles." + +#: ./api-ref/src/docbkx/ch_identity-v3.xml267(title) +msgid "Policies" +msgstr "Politiques" + +#: ./api-ref/src/docbkx/ch_identity-v3.xml268(para) +msgid "Manage policies." +msgstr "Gestion des polices." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml10(para) +msgid "" +"Manage the accounts, containers, and objects in the Object Storage system." +msgstr "Gestion des comptes, conteneurs, et objets dans le système de Stockage des Objets." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml12(para) +msgid "" +"To run the cURL command examples for these requests, set these environment " +"variables:" +msgstr "Pour exécuter les exemples de commande cURL pour ces requêtes, configurer ces variables d'environnement:" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml16(para) +msgid "" +"publicURL. The public URL that is the HTTP endpoint from where " +"you can access Object Storage. It includes the Object Storage API version " +"number and your account name. For example, " +"https://23.253.72.207/v1/my_account." +msgstr "publicURL. l'URL publique est le point de terminaison HTTP à partir duquel vous pouvez acéder le Stockage d'Objets. Il inclut le numéro de version de l'API de Stockage d'Objets et votre nom de compte. Par exemple, https://23.253.72.207/v1/my_account." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml23(para) +msgid "token. The authentication token for Object Storage." +msgstr "token. Le jeton d'authentification pour le Stockage d'Objet." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml27(para) +msgid "To obtain these values, run the command." +msgstr "Pour obtenir ces valeurs, exécutez la commande ." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml29(para) +msgid "" +"As shown in this example, the public URL appears in the " +"StorageURL field, and the token appears in the Auth " +"Token field:" +msgstr "Comme montré dans cet exemple, l'URL publique apparaît dans le champ StorageURL, et le jeton apparaît dans le champ Auth Token:" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml43(para) +msgid "" +"For a complete description of HTTP 1.1 header definitions, see Header" +" Field Definitions." +msgstr "Pour une description complète des définitions des headers HTTP 1.1, reportez-vous à la documentation Définitions des Champs de Header." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml48(title) +msgid "Accounts" +msgstr "Comptes" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml49(para) +msgid "" +"List containers for a specified account. Create, update, show, and delete " +"account metadata." +msgstr "Liste les conteneurs pour un compte spécifié. Crée, modifie, affiche, et supprime les métadonnées de compte." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml61(title) +msgid "Containers" +msgstr "Conteneurs" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml62(para) +msgid "" +"List objects in a specified container. Create, show details for, and delete " +"containers. Create, update, show, and delete container metadata." +msgstr "Liste les objets dans un conteneur spécifié. Crée, affiche les ifnormations, et supprime les conteneurs. Crée, modifie, montre, et supprime les métadonnées de conteneur." + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml77(title) +msgid "Objects" +msgstr "Objets" + +#: ./api-ref/src/docbkx/ch_objectstorage-v1.xml78(para) +msgid "" +"Create, replace, show details for, and delete objects. Copy objects from " +"another object with a new or different name. Update object metadata." +msgstr "Crée, remplace, montre les informations, et supprime les objets. Copie les objets à partir d'un autre objet avec un nouveau nom ou un nom différent. Met à jour les métadonnées d'objet." + +#: ./api-ref/src/docbkx/api-ref-databases-v1.xml11(title) +msgid "OpenStack Database Service API v1.0" +msgstr "API du Service de Base de données v1.0 OpenStack" + +#: ./api-ref/src/docbkx/api-ref-compute-v3.xml11(title) +msgid "OpenStack Compute API v3" +msgstr "API de Calcul v3 OpenStack" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml10(para) +msgid "Manage telemetry operations." +msgstr "Gérer les opérations de télémétrie." + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml12(title) +msgid "Alarms" +msgstr "Alarmes" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml13(para) +msgid "List, create, gets details for, update, and delete alarms." +msgstr "Liste, crée, obtient les informations, modifie, et supprime les alarmes." + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml39(title) +msgid "Meters" +msgstr "Mètres" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml40(para) +msgid "Get information for meters." +msgstr " Obtient les informations des métriques." + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml58(title) +msgid "Resources" +msgstr "Ressources" + +#: ./api-ref/src/docbkx/ch_telemetry-v2.xml59(para) +msgid "Get information for resources." +msgstr "Obtenir les informations pour les resources." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml13(title) +msgid "Identity API v3 extensions (STABLE)" +msgstr "Extensions de l'API de Gestion des Identités v3 (STABLE)" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml15(title) +msgid "OS-OAUTH1 extension" +msgstr "Extension OS-OAUTH1" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml16(para) +msgid "" +"Enable users to delegate roles to third-party consumers through the OAuth 1.0a specification." +msgstr "Permet aux utilisateurs de déléguer les rôles à des consommateurs tierce-partie au moyen de la spécification OAuth 1.0a." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml19(para) +msgid "" +"A user is an Identity API user who delegates its roles and who authorizes " +"request tokens. A consumer is a third-party application that uses OAuth to " +"access a protected resource. An OAuth-derived token enables admin users to " +"act on behalf of the authorizing user. A request token is a token that the " +"consumer uses to get authorization from the user and exchanges with an OAuth" +" verifier for an access token. The OAuth verifier is a required string that " +"is provided with the corresponding request token in exchange for an access " +"token. An access token is a token that the consumer uses to request Identity" +" API tokens on behalf of the authorizing user instead of using the " +"credentials for the user." +msgstr "Un utilisateur est un utilisateur de l'API de Gestion des Identités qui délègue ses rôles et qui authorise les jetons de requête. un consommateur est une application tierce-partie qui utilise OAuth pour accéder à une ressource protégée. Un jeton dérivé OAuth permet aux utilisateurs administrateurs de se faire passer pour un utilisateur l'ayant autorisé. Un jeton de requête est un jeton que le consommateur utilise pour obtenir une autorisation de l'utilisateur et les échanges avec un vérificateur OAuth pour un jeton d'accès. Le vérificateur OAuth est une chaine de caractères requise qui est fournie avec le jeton de requête correspondant en échange d'un jeton d'accès. un jeton d'accès est un jeton que le consommateur utilise pour demander des jetons de l'API de Gestion des Identités de la part d'un utilisateur l'ayant autorisé au lieu d'utiliser les informations d'authentification pour l'utilisateur." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml32(para) +msgid "" +"Request and access tokens use token keys to identify themselves. For " +"OpenStack purposes, the token key is the token ID. The consumer uses a token" +" secret to establish ownership of a specified token. Both request and access" +" tokens have token secrets." +msgstr "Les jetons de requête et d'accès utilisent des jetons de clés pour s'identifier eux-même. Dans le but d'OpenStack, le jeton de clé est le jeton d'ID. Le consommateur utilise un secret de jeton afin d'établir la propriété d'un jeton spécifié. A la fois les jetons de requête et d'accès ont des secrets de jeton." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml37(para) +msgid "Delegated authentication through OAuth occurs as follows:" +msgstr "La délégation de l'authentification à travers OAuth est réalisée comme suit:" + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml41(para) +msgid "A user creates a consumer." +msgstr "Un utilisateur crée un consommateur. " + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml44(para) +msgid "" +"The consumer gets an unauthorized request token. Then, the consumer uses the" +" request token to initiate user authorization." +msgstr "Le consommateur obtient un jeton de requête non autorisé. Ensuite, le consommateur utilise le jeton de requête pour initier l'autorisation de l'utilisateur." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml49(para) +msgid "The user authorizes the request token." +msgstr "L'utilisateur autorise le jeton de requête. " + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml52(para) +msgid "" +"The consumer exchanges the authorized request token and the OAuth verifier " +"for an access token." +msgstr "Le consommateur échange le jeton de requête autorisé et le vérificateur OAuth pour un jeton d'accès." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml55(para) +msgid "" +"The authorizing user receives the request token key from the consumer out-" +"of-band." +msgstr "L'utilisateur l'ayant autorisé reçoit la clé du jeton de requête du consommateur hors bande." + +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml59(para) +msgid "The consumer uses the access token to request an Identity API token." +msgstr "Le consommateur utilise le jeton d'accès pour demander un jeton de l'API de Gestion des Identités." + +#. Put one translator per line, in the form of NAME , YEAR1, YEAR2 +#: ./api-ref/src/docbkx/ch_identity-v3-ext.xml0(None) +msgid "translator-credits" +msgstr "Olivier Buisson , 2012" diff --git a/restapi-doc/restapi-doc/api-ref/pom.xml b/restapi-doc/restapi-doc/api-ref/pom.xml new file mode 100644 index 000000000..8adb50b68 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/pom.xml @@ -0,0 +1,174 @@ + + + + + + + + org.openstack.docs + parent-pom + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + titanium-api-ref + jar + Titanium Cloud API Complete Reference + + UTF-8 + + + + src + + + locale + + + + + + com.rackspace.cloud.api + clouddocs-maven-plugin + + + + os-api-ref + + generate-html + + generate-sources + + api-ref.xml + bk-api-ref + + + + sysinv-api-v1 + + generate-html + + generate-sources + + api-ref-sysinv-v1.xml + bk-sysinv-api-v1 + + + + os-api-ref-compute-v2-cgcs-ext + + generate-html + + generate-sources + + api-ref-compute-v2-cgcs-ext.xml + bk-api-ref-compute-v2-cgcs-ext + + + + os-api-ref-networking-v2-cgcs-ext + + generate-html + + generate-sources + + api-ref-networking-v2-cgcs-ext.xml + bk-api-ref-networking-v2-cgcs-ext + + + + os-api-ref-telemetry-v2-cgcs-ext + + generate-html + + generate-sources + + api-ref-telemetry-v2-cgcs-ext.xml + bk-api-ref-telemetry-v2-cgcs-ext + + + + os-api-ref-image-v2-cgcs-ext + + generate-html + + generate-sources + + api-ref-image-v2-cgcs-ext.xml + bk-api-ref-image-v2-cgcs-ext + + + + os-api-ref-patching-v1-cgcs-ext + + generate-html + + generate-sources + + api-ref-patching-v1.xml + bk-api-ref-patching-v1 + + + + os-api-ref-blockstorage-v2-cgcs-ext + + generate-html + + generate-sources + + api-ref-blockstorage-v2-cgcs-ext.xml + bk-api-ref-blockstorage-v2 + + + + os-api-ref-nfv-vim-v1-cgcs-ext + + generate-html + + generate-sources + + api-ref-nfv-vim-v1.xml + bk-api-ref-nfv-vim-v1 + + + + + + + + appendix toc,title + article/appendix nop + article toc,title + book toc,title + chapter toc,title + section toc,title + part toc,title + qandadiv toc + qandaset toc + reference toc,title + set toc,title + true + src/docbkx + openstack + 1 + true + reviewer + false + 1 + UA-17511903-1 + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-blockstorage-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-blockstorage-v2-cgcs-ext.xml new file mode 100644 index 000000000..6dbe06755 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-blockstorage-v2-cgcs-ext.xml @@ -0,0 +1,30 @@ + + + + + Block Storage V2-TITANIUM-Extensions API + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-compute-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-compute-v2-cgcs-ext.xml new file mode 100644 index 000000000..8360a9b9d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-compute-v2-cgcs-ext.xml @@ -0,0 +1,30 @@ + + + + + Compute V2-TITANIUM-Extensions API + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-image-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-image-v2-cgcs-ext.xml new file mode 100644 index 000000000..d75241648 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-image-v2-cgcs-ext.xml @@ -0,0 +1,30 @@ + + + + + Image V2-TITANIUM-Extensions API + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-networking-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-networking-v2-cgcs-ext.xml new file mode 100644 index 000000000..25b05b543 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-networking-v2-cgcs-ext.xml @@ -0,0 +1,30 @@ + + + + + Networking V2-TITANIUM-Extensions API + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-nfv-vim-v1.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-nfv-vim-v1.xml new file mode 100644 index 000000000..dcf03c085 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-nfv-vim-v1.xml @@ -0,0 +1,30 @@ + + + + + Titanium NFV VIM API v1 + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-patching-v1.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-patching-v1.xml new file mode 100755 index 000000000..b80a32ad7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-patching-v1.xml @@ -0,0 +1,30 @@ + + + + + Titanium Patching API v1 + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-sysinv-v1.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-sysinv-v1.xml new file mode 100644 index 000000000..e28a7202c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-sysinv-v1.xml @@ -0,0 +1,30 @@ + + + + + Titanium System Inventory API v1 + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-telemetry-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-telemetry-v2-cgcs-ext.xml new file mode 100644 index 000000000..4acc4d21b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref-telemetry-v2-cgcs-ext.xml @@ -0,0 +1,30 @@ + + + + + Telemetry V2-TITANIUM-Extensions API + + 2014 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref.xml new file mode 100644 index 000000000..fb9696a73 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/api-ref.xml @@ -0,0 +1,29 @@ + + + + + Titanium API Reference + + 2017 + Wind River + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_blockstorage-api-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_blockstorage-api-v2-cgcs-ext.xml new file mode 100644 index 000000000..f1dbe1ab4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_blockstorage-api-v2-cgcs-ext.xml @@ -0,0 +1,75 @@ + + + + Block Storage API v2 + Titanium extensions + Titanium extensions to the OpenStack Block Storage API such as backup + status and export/import actions for volumes and snapshots. + The typical port used for the Block Storage REST API is 8776. + However, proper technique would be to look up the cinderv2 service endpoint in keystone. + +
+ Extensions + The Extensions entity lists all available extensions + + + + + + + + + +
+ +
+ Volumes + Titanium extensions include export and import actions for + performing backup and restores of volumes, and a backup status + attribute to indicate the status of the new actions. + + + + + + + + + + + + +
+
+ Snapshots + Titanium extensions include export actions for + performing backup volumes already attached to a VM, and a backup status + attribute to indicate the status of the new actions. + + + + + + + + + + + + +
+
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_cgcs-rest-api-intro.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_cgcs-rest-api-intro.xml new file mode 100644 index 000000000..070a0a6d2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_cgcs-rest-api-intro.xml @@ -0,0 +1,61 @@ + + + + Titanium Cloud REST API Overview + The Wind River Systems Titanium Cloud is a high-performance, high-availability, NFV-enabled cloud operating platform that enables telecommunication and industrial operators to deploy and maintain next generation communication services. It brings together the flexibility and scalability of the IT cloud, and the high-availability and performance demanded by these industry verticals, into a unique industry-leading solution. The CG Comms Server leverages the power of Commercial Off-The-Shelf (COTS) server hardware to deliver a price-performance ratio well above alternative solutions. + The Titanium Cloud Platform leverages core Wind River virtualization and carrier-grade technologies, Intel DPDK high-performance packet processing, open architectures, cutting edge security features, and the OpenStack software suite. It extends the OpenStack software suite to implement a unique carrier-grade, high-availability architecture, on which high-performance production systems can be deployed. +
+ OpenStack REST API Documentation + The OpenStack REST API Documentation is open-source; both the published formats (PDF and HTML pages) as well as the docbook/wadl source documents. The published formats can be found at http://developer.openstack.org/api-ref.html . + Although some of the general open-source OpenStack Documentation (e.g. Admin Guide) is versioned based on OpenStack Releases (e.g. Havana), the open-source OpenStack REST API Documentation is currently NOT versioned. There is only a master/current version of the OpenStack REST API Documentation containing updates from 'all' versions of OpenStack. +
+
+ Strategy for Titanium Cloud REST API Documentation + Due to the lack of versioning on the open-source OpenStack REST API Documentation, Titanium Cloud REST API Documentation will not build on top of open-source documents. Instead, Titanium Cloud REST API Documenation will provide a description of the delta between the Titanium Cloud REST API and the open-source OpenStack REST API. For existing OpenStack Components (e.g. Nova, Neutron, ...), any modified APIs will be re-documented with any modified or additional request parameters, response attributes and/or behaviour. For any new Titanium Components (e.g. SysInv), all APIs will be fully documented. + Additionally, only high-level description of the semantics around objects and parameters are described in this REST API Documentation. For full description of objects and parameters, please refer to the Wind River Titanium Cloud Administration Guide. +
+
+ Titanium-specific Extensions and Titanium REST API Header + By default, Titanium Cloud does not send 'Titanium Cloud'-specific extensions (attributes) as a part of any REST API responses. In order to have 'Titanium Cloud'-specific extended attributes appear in the REST API responses, the Titanium Cloud header 'wrs-header' must be present in the REST API request. As a result, vanilla Openstack clients will not get any 'Titanium Cloud'-specific extended attributes as a part of the REST API response. Titanium Cloud clients will automatically send the Titanium Cloud header, and thus contain 'Titanium Cloud'-specific extensions as a part of the REST API response. The components affected by the Titanium Cloud header are Compute, Networking, and Block Storage. +
+
+ Overview of Document + The sections of this document consist of: + + + TITANIUM-Extensions to Compute REST API + + + TITANIUM-Extensions to Networking REST API + + + TITANIUM-Extensions to Block Storage REST API + + + TITANIUM-Extensions to Telemetry REST API + + + TITANIUM-Extensions to Image REST API + + + TITANIUM System Inventory (SysInv) REST API + + + TITANIUM Patching REST API + + + There are no TITANIUM-Extensions to Identity REST API (Keystone) and Orchestration REST API (Heat). +
+
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_compute-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_compute-v2-cgcs-ext.xml new file mode 100644 index 000000000..1fcc32684 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_compute-v2-cgcs-ext.xml @@ -0,0 +1,258 @@ + + +GET'> +]> + + Compute API v2 Titanium extensions + Titanium extensions to the OpenStack Compute API include: + + + Adding capability to specify VIF-Model on a per-NIC basis when + creating/launching/booting a VM Server. + + + Adding capability to specify VIF-PCI Address on a per-NIC basis when + creating/launching/booting a VM Server. + + + Adding an attribute to allow sorting of a VM Server's IP Addresses + in order of network attachment(NIC). + + + Adding the ability to scale the resources (currently only + vCPUs) of a VM Server up and down without requiring a restart + of the VM Server. + + + Adding a number of new attributes and behavior to VM Server Groups; + a project_id attribute for ownership, an affinity-hyperthread policy and + best_effort and max group_size metadata attribute values. + + + Support for various new Flavor Extra Specs to enable + Titanium-specific optimizations and capabilities for compute servers. + + + Adding the capability of displaying details about Provider + Network with regards to Nova usage. + + + The typical port used for the Compute REST API is 8774. + However, proper technique would be to look up the nova service endpoint in keystone. + + + + + +
+ Extensions + The Extensions entity lists all available extensions + + + + + + + + + +
+ + + + + + +
+ Server + The Titanium extensions to the server entity are: + + + Adding capability to specify VIF-Model on a per-NIC basis when + creating/launching/booting a VM Server. + + + Adding capability to specify VIF-PCI Address on a per-NIC basis when + creating/launching/booting a VM Server. + + + Adding the ability to scale the resources (currently only + vCPUs) of a server up and down without requiring a restart of + the VM Server. + + + Adding an attribute to allow sorting of a VM Server's IP Addresses + in order of network attachment(NIC). + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ Server Groups (os-server-groups) + The Titanium extensions to the Server Groups entity are: + + + Added a 'wrs-sg:project_id' attribute to assign tenant ownership to a + Server Group. + + + Added a 'wrs-sg:affinity-hyperthread' policy to indicate that members + of the Server Group are allowed to share hyperthread siblings. + + + Added a boolean 'wrs-sg:best_effort' metadata key/value in order to + specify whether the policy should be strictly enforced or not. + + + Added an integer 'wrs-sg:group_size' metadata key/value in order to + specify the maximum number of members in the group. + + + + + + + + + + + + + +
+ + + + + +
+ Flavor Extra Specs + Titanium Cloud has added several flavor extra specs, e.g. + sw:wrs:guest:heartbeat, hw:wrs:shared_vcpu, + hw:wrs:min_vcpus, sw:wrs:vtpm and many more. + For the complete list of additional flavor extra specs added by Titanium + Cloud, and an explanation of how to use them, please refer to the Wind River + Titanium Cloud Administration guide set. + + + + + + + + + + + + + +
+ + + + + +
+ Provider Network + The Titanium extensions to the Provider Network entity are: + + + + + + + + + +
+ + + + + +
+ PCI + The Titanium extensions to the PCI device entity are: + + + + + + + + + +
+ + + + + +
+ Hypervisors + The Titanium extensions to the Hypervisor entity are: + + + + + + + + +
+ +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_image-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_image-v2-cgcs-ext.xml new file mode 100644 index 000000000..d2214a0f0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_image-v2-cgcs-ext.xml @@ -0,0 +1,63 @@ + + +GET'> +]> + + Image API v2 Titanium extensions + Titanium extensions to the OpenStack Image API to support + additional properties on images for customizing migration behaviour, supporting + raw cached images in ceph cluster, disabling VM auto-recovery and indicating + the backend where the image is stored. + + The typical port used for the Image REST API is 9292. + However, proper technique would be to look up the image/glance service endpoint in Keystone. + + + + + + +
+ Images + The Image entity is extended by Titanium Cloud to + have additional properties on images for customizing migration behaviour, supporting + raw cached images in ceph cluster, disabling VM auto-recovery and indicating + the backend where the image is stored. + + + + + + + + + + + + + + + + + + +
+ +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_networking-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_networking-v2-cgcs-ext.xml new file mode 100644 index 000000000..87fbb7963 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_networking-v2-cgcs-ext.xml @@ -0,0 +1,409 @@ + + +GET'> +]> + + Networking API v2 Titanium extensions + This section describes changes made to the standard OpenStack Networking API for the Titanium Cloud. Some existing OpenStack API instances have been enhanced to add new attributes, or update the semantics of existing attributes. In other cases, entirely new API instances have been created to expose Titanium Cloud networking functionality via the standard RESTful API. + The typical port used for the Networking REST API is 9696. + However, proper technique would be to look up the neutron service endpoint in Keystone. + + + + + +
+ Extensions + The Extensions entity lists all available extensions; both open-source extensions and Wind River (wrs-) extensions. + + + + + + + + + +
+ + + + + + +
+ Provider Network + The Provider Network entity is a new entity which was added to the OpenStack API. It enables management of provider networks via the RESTful API. The standard OpenStack API included no such entity; instead, the end user was required to edit static configuration files through the system to add, or update provider network information. + + This entity and all of its operations are only available to administrator level users. + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Provider Network Range + The Provider Network Range entity is a new entity which was added to the OpenStack API. It enables management of provider network segmentation ranges via the RESTful API. The standard OpenStack API included no such entity; instead, the end user was required to edit static configuration files through the system to add, or update provider network segmentation ranges. + + This entity and all of its operations are only available to administrator level users. + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Provider Network Type + The Provider Network Type entity is a new entity which was added to the OpenStack API. It exists simply to allow the end user to query which provider network types are supported by the system. + + This entity and all of its operations are only available to administrator level users. + + + + + + +
+ + + + + +
+ Provider Network Connectivity Test + The Provider Network Connectivity Test entity is a new entity which was added to the OpenStack API. It enables the verification of provider network connectivity between compute nodes. + + This entity and all of its operations are only available to administrator level users. + + + + + + + + + +
+ + + + + + + + + + + + + +
+ Tenant Settings + The Tenant Settings entity is a new entity which was added to the OpenStack API. It enables management of features or system behaviours on a per-tenant basis by the administrator. + + This entity and all of its operations are only available to administrator level users. + + + + + + + + + + + + + + + +
+ + + + + + +
+ QOS Policies + The QOS entity is a new entity which was added to the OpenStack API. It enables management of Quality of Service policies and profiles via the RESTful API. QOS policies can be created and maintained by the administrator. + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Network + The Network entity is an existing OpenStack API. It has been extended to add the following Titanium Cloud functionality. + + + A QOS policy can optionally be associated to a tenant network + + + The maximum transmit unit (MTU) of each tenant network is inherited from its associated provider network + + + The status of each tenant network is derived from the state of the DHCP server which services its subnets + + + + + + + + + + + + +
+ + + + + + +
+ Subnet + The Subnet entity is an existing OpenStack API. It has been extended to add the following Titanium Cloud functionality. + + + A subnet can be configured to allow VLAN tagging by the VM instance. + + + + + + + + + + + + + + + +
+ + + + + + +
+ Port + The Port entity is an existing OpenStack API. It has been extended to add the following Titanium Cloud functionality. + + + The network interface type (vif_model) is recorded when attached to a VM instance. + + + Source MAC address filtering is enabled when created for a tenant which has this feature enabled by the administrator. + + + The MAC address automatically updates to reflect changes to PCI passthrough devices for VM instances. + + + The maximum transmit unit (MTU) attribute is a reflection of the MTU value of the attached tenant network. + + + + + + + + + + + + +
+ + + + + + +
+ Router + The Router entity is an existing OpenStack API. It has been extended to add the following Titanium Cloud functionality. + + + The host attribute has been added to reflect which compute host implements the virtual router. + + + + + + + + + + + + +
+ + + + + +
+ Port Forwarding + The portfowarding entity is an upstream subproject that is not yet part of the existing OpenStack API. It provides virtual router port forwarding functionality. It has been included to add the functionality to the Titanium Cloud. + + + + + + + + + + + + + + + + + + + +
+ +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_nfv-vim-api-v1.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_nfv-vim-api-v1.xml new file mode 100644 index 000000000..6cfa2d47b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_nfv-vim-api-v1.xml @@ -0,0 +1,116 @@ + + + + NFV VIM API v1 + Manage patch orchestration with the Titanium Cloud NFV VIM API. This includes + creation, application and querying of patch strategies. + Manage upgrade orchestration with the Titanium Cloud NFV VIM API. This includes + creation, application and querying of upgrade strategies. + The typical port used for the NFV VIM REST API is 4545. + However, proper technique would be to look up the nfv vim service endpoint in Keystone. + + + + + + +
+ API versions + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Patch Strategy + Patch orchestration is done with a patch orchestration strategy, + or plan, for the automated patching procedure which contains a + number of parameters for customizing the particular behavior of the + patching orchestration. + + + + + + + + + + + + + + +
+ + + + + +
+ Upgrade Strategy + Upgrade orchestration is done with an upgrade orchestration strategy, + or plan, for the automated upgrade procedure which contains a + number of parameters for customizing the particular behavior of the + upgrade orchestration. + + + + + + + + + + + + + + +
+ +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_patching-api-v1.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_patching-api-v1.xml new file mode 100755 index 000000000..d95c8bc8f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_patching-api-v1.xml @@ -0,0 +1,97 @@ + + + + Patching API v1 + Manage the patching of hosts with the Titanium Cloud Patching API. + This includes upload, application, installation, removal, deletion, + and querying. + The typical port used for the Patching REST API is 15491. + However, proper technique would be to look up the patching service endpoint in Keystone. + + + + + + +
+ API versions + + + + + +
+ + + + + + +
+ Patches + The patches used by the patching service to update individual + hosts in the cloud. + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Hosts + Hosts are the physical hosts or servers for the system + as viewed by the patching service. + + + + + + + + +
+ + +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_sysinv-api-v1.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_sysinv-api-v1.xml new file mode 100644 index 000000000..43457a524 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_sysinv-api-v1.xml @@ -0,0 +1,1441 @@ + + + + SysInv API v1 + Manage physical servers with the Titanium System Inventory API. This includes + inventory collection and configuration of nodes, ports, interfaces, CPUs, disks, + partitions, memory, and sensors. The API also supports alarm collection for fault + events of the cloud itself as well as configuration of the cloud's SNMP interface. + The typical port used for the SysInv REST API is 6385. + However, proper technique would be to look up the sysinv service endpoint in Keystone. + + + + + + +
+ API versions + + + + + + + + +
+ + + + + + +
+ System + The cloud server cluster is represented internally by a unique object referred to as the + system. + + + + + + + + +
+ + + + + + +
+ Clusters + A cluster within the cloud server is represented internally by a unique object referred to as the + cluster. + + + + + + + + +
+ + + + + + +
+ Hosts + Hosts are the physical hosts or servers for the system. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Ports + These APIs allow the display of the physical ports of + a host and their attributes. + + + + + + + + +
+ + + + + + +
+ Interfaces + These APIs allow the create, display, modify and delete + of the L2 interfaces of a host. + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ CPUs + These APIs allow the display of the logical core(s) of the + processor(s) on a host, and the display and modification + of the cores assigned function. + + + + + + + + + + + +
+ + + + + + +
+ Memory + These APIs allow the display of the size and usage + of various memory areas of the NUMA nodes of a host. + The modification of the size of these memory areas is + also supported through these APIs. + The different memory areas of a NUMA node of a host are: + + + Memory reserved for the Platform; where the Platform consists + of the kernel and the cloud services, + + + Memory reserved for the virtual switch (Note: only on 'compute' hosts), + + + Memory reserved for the hosted VMs (Note: only on 'compute' hosts). + + + + + + + + + + + +
+ + + + + + +
+ SensorGroup + These APIs allow the display of the operational state + and configuration attributes of the sensorgroups of a host. + The modification of certain sensorgroup attributes is + supported through these APIs; and propagates the + configuration change to the corresponding attributes of + all sensors defined in the group. + Examples of sensorgroup sensortype monitoring for + the host are: + + + + temperature, + + + voltage, + + + current, + + + fan, + + + cpu, + + + memory, + + + disk, + + + partition, + + + firmware baseline, + + + hardware baseline. + + + + + + + + + + + +
+ + + + + + +
+ Sensor + These APIs allow the display of the status and + operational state of various sensor areas of a host. + The modification of the certain sensor attributes is + also supported through these APIs. + Examples of different sensortypes are as defined for + the sensorgroup. + + + + + + + + + + +
+ + + + + + +
+ Disks + + + + + + + + + + + +
+ + + + + + +
+ Partitions + + + + + + + + + + + + + + + + + +
+ + + + + +
+ Ceph Storage Functions + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Volume Groups + These APIs allow the creation, deletion, and displaying + of LVM volume groups. + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Physical Volumes + These APIs allow the creation, deletion, and displaying + of LVM physical volumes. + + + + + + + + + + + + + + +
+ + + + + + +
+ Profiles + These APIs allow the create, display and delete + of host profiles. This includes interface profiles, + cpu profiles, and volume profiles. NOTE that the + same record is used in the database for both hosts and + host profiles. + + + + + + + + + + + + + + +
+ + + + + + +
+ DNS + The DNS is the Domain Name Server entity for the system. + + + + + + + + + +
+ + + + + + +
+ NTP + The NTP is the Network Time Protocol entity for the system. + + + + + + + + + +
+ + + + + + +
+ External OAM + The extoam is the External OAM entity for the system. + + + + + + + + + +
+ + + + + + +
+ Infrastructure Subnet + The infra is the Infrastructure subnet entity for the system. + + + + + + + + + + + + + + + +
+ + + + + + +
+ DRBD Configuration + The drbdconfig is the Distributed Replicated Block Device (DRBD) +configuration entity for the system. + + + + + + + + + +
+ + + + + + +
+ Alarms + These APIs allow the display of the Active Alarms + in the system. + + + + + + + + + + + + + + +
+ + + + + + +
+ Event Log + These APIs allow the display of the Event Log + in the system. The Event log contains both historical alarms and customer logs. + + + + + + + + +
+ + + + + + +
+ Event Suppression + These APIs allow the display of the Event Suppression state + in the system. + + + + + + + + +
+ + + + + + +
+ SNMP Communities + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ SNMP Trap Destinations + + + + + + + + + + + + + + + + + +
+ + + + + +
+ Devices + These APIs allow the display of the pci devices of + a host and their attributes. + + + + + + + + + + + +
+ + + + + +
+ Service Parameter + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ LLDP Agents + These APIs allow the display of the lldp agents of + a host and their attributes. + + + + + + + + +
+ + + + + +
+ LLDP Neighbors + These APIs allow the display of the lldp neighbors of + a host and their attributes. + + + + + + + + +
+ + + + + +
+ Services + These APIs allow the display of the services running + and their attributes + + + + + + + + + + + +
+ + + + + +
+ Service Nodes + These APIs allow the display of the service nodes + and their attributes + + + + + + + + +
+ + + + + +
+ Service Groups + These APIs allow the display of the service groups + and their attributes + + + + + + + + +
+ + + + + +
+ SDN Controllers + These APIs allow for the display and configuration of + the SDN controllers that each of the compute nodes will connect + to for the purpose of SDN manager interface (i.e. OVSDB connection). + The SDN controllers configured are for active connections to + the SDN controller for each of the virtual switch instances running + on the compute nodes, and is shared across all compute nodes. + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ Remote Logging + These APIs allow the display and configuration of the + remote logging settings + + + + + + + + +
+ + + + + +
+ Networks + These APIs allow the display of system managed networks. They are intended for internal system use only. + + + + + + + + +
+ + + + + +
+ Address Pools + These APIs allow the display and configuration of IP address pools. + + + + + + + + + + + + + + + + + +
+ + + + + +
+ Addresses + These APIs allow the display and configuration of IP addresses for a specific host resource. + + + + + + + + + + + + + + +
+ + + + + +
+ Routes + These APIs allow the display and configuration of IP route for a specific host resource. + + + + + + + + + + + + + + +
+ + + + + +
+ Storage Backends + These APIs allow the display and configuration of different storage backends. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ Storage Tiers + These APIs allow the create, display, modify and delete + of the storage tiers. + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Controller Filesystem + These APIs allow the display and configuration of the controller filesystem. + + + + + + + + + + + + + + +
+ + + + + +
+ Ceph Monitors + These APIs allow the display and configuration of the Ceph monitors. + + + + + + + + + + + +
+ + + + + +
+ System Health + These APIs allow the display of the system health. + + + + + + + + +
+ + + + + +
+ Software Loads + These APIs allow the display and configuration of the software loads. + + + + + + + + + + + + + + +
+ + + + + +
+ Software Upgrade + These APIs allow the display and configuration of the software upgrade. + + + + + + + + + + + + + + +
+ + + + + +
+ System Certificate Configuration + These APIs allow for the display and configuration of + Host certificates which include SSL, Murano and Trusted Platform Module(TPM) certificates. + + + + + + + + + + + + +
+ + + + + +
+ Trusted Platform Module (TPM) Configuration + These APIs allow for the display and configuration of + Trusted Platform Module (TPM). + + + + + + + + + + + + + + + +
+ + + + + +
+ Custom Firewall Rules + These APIs allow for the installation of custom firewall rules. + + + + + + + + + +
+ + + + + +
+ License + These APIs allow for the installation of license file and display of + the license information. + + + + + + + + + +
+ +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_telemetry-v2-cgcs-ext.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_telemetry-v2-cgcs-ext.xml new file mode 100644 index 000000000..0b17cbd02 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/ch_telemetry-v2-cgcs-ext.xml @@ -0,0 +1,97 @@ + + +GET'> +]> + + Telemetry API v2 Titanium extensions + Titanium extensions to the OpenStack Telemetry API such as + Pipelines for outputting samples to CSV files. + + The typical port used for the Telemetry REST API is 8777. + However, proper technique would be to look up the ceilometer service endpoint in Keystone. + + + + + +
+ Extensions + The Extensions entity lists all available extensions + + + + + + + + + + + + +
+ + + + + +
+ Meter Types + The Meter Types entity is modeled by Titanium extensions to + show unique meter types + + + + + + + + + +
+ + + + + +
+ Pipeline + The Pipeline entity is modeled by Titanium extensions to + manipulate how samples are stored to CSV files + + + + + + + + + + + + + + + +
+ +
diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/itemizedlist-service-list.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/itemizedlist-service-list.xml new file mode 100644 index 000000000..8a6fb0092 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/itemizedlist-service-list.xml @@ -0,0 +1,49 @@ + + + + + + Compute + API v2 Titanium extensions + + + Networking + API v2.0 Titanium extensions + + + Block Storage + API v2 Titanium extensions + + + Telemetry + API v2 Titanium extensions + + + Image + API v2 Titanium extensions + + + Titanium System Inventory + API v1 + + + Titanium Patching Service + API v1 + + + Titanium NFV VIM Service + API v1 + + diff --git a/restapi-doc/restapi-doc/api-ref/src/docbkx/preface.xml b/restapi-doc/restapi-doc/api-ref/src/docbkx/preface.xml new file mode 100644 index 000000000..deea4243a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/docbkx/preface.xml @@ -0,0 +1,26 @@ + + + + Titanium API Complete Reference + Use the Titanium APIs and extensions to launch server + instances, create images, assign metadata to instances and + images, create containers and objects, and complete other + actions in your OpenStack cloud. + You must install the packages for each API separately. You + can use the APIs and extensions after you authenticate through + the Identity API. + To get started with the APIs, see the OpenStack API Quick Start. + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_get-response.json new file mode 100644 index 000000000..a6a665219 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_get-response.json @@ -0,0 +1,49 @@ +{ + "extension" : { + "namespace" : "http://docs.windriver.com/tis/ext/wrs-if/api/v1.0", + "name" : "wrs-server-if", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Interface Related Extensions", + "alias" : "wrs-if", + "links" : [] + } +} + +OR + +{ + "extension" : { + "namespace" : "http://docs.windriver.com/tis/ext/wrs-res/api/v1.0", + "name" : "wrs-server-resource", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Server Resource Extensions", + "alias" : "wrs-res", + "links" : [] + } +} + +OR + +{ + "extension" : { + "namespace" : "http://docs.windriver.com/tis/ext/wrs-sg/api/v1.0", + "name" : "wrs-server-group", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Server Group Extensions", + "alias" : "wrs-sg", + "links" : [] + } +} + +OR + +{ + "extension" : { + "namespace" : "http://docs.windriver.com/tis/ext/wrs/api/v1.0", + "name" : "wrs-flavor-extra-spec", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Extended Flavor Extra Spec Keys" + "alias" : "wrs", + "links" : [] + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_list-response.json new file mode 100644 index 000000000..c53454064 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/extension_list-response.json @@ -0,0 +1,39 @@ +{ + "extensions" : [ + ... + { + "namespace" : "http://docs.windriver.com/tis/ext/wrs-if/api/v1.0", + "name" : "wrs-server-if", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Interface Related Extensions", + "alias" : "wrs-if", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.com/tis/ext/wrs-res/api/v1.0", + "name" : "wrs-server-resource", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Server Resource Extensions", + "alias" : "wrs-res", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.com/tis/ext/wrs-sg/api/v1.0", + "name" : "wrs-server-group", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Server Grouip Extensions", + "alias" : "wrs-sg", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.com/tis/ext/wrs/api/v1.0", + "name" : "wrs-flavor-extra-spec", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "WRS Extended Flavor Extra Spec Keys" + "alias" : "wrs", + "links" : [] + }, + ... + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-request.json new file mode 100644 index 000000000..3e25789e0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-request.json @@ -0,0 +1,5 @@ +{ + "extra_specs": { + "sw:wrs:guest:heartbeat": "True", + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-response.json new file mode 100644 index 000000000..3e25789e0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-create-response.json @@ -0,0 +1,5 @@ +{ + "extra_specs": { + "sw:wrs:guest:heartbeat": "True", + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-get-response.json new file mode 100644 index 000000000..4df5171a6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-get-response.json @@ -0,0 +1,3 @@ +{ + "sw:wrs:guest:heartbeat": "True", +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-list-response.json new file mode 100644 index 000000000..f6a9513fd --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/flavor-extra-specs-list-response.json @@ -0,0 +1,13 @@ +{ + "extra_specs": { + "sw:wrs:guest:heartbeat": "True", + "sw:wrs:srv_grp_messaging": "True", + "sw:wrs:vtpm": "False", + "hw:numa_node.0": "1", + "hw:wrs:vcpu:scheduler": "fifo:50:0" + "hw:wrs:min_vcpus": "2" + "hw:wrs:shared_vcpu": "1" + "hw:cpu_model": "Nehalem" + "aggregate_instance_extra_specs:localstorage": "False" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/hypervisor-get-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/hypervisor-get-resp.json new file mode 100644 index 000000000..f2dbd4892 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/hypervisor-get-resp.json @@ -0,0 +1,110 @@ +{ + "hypervisor":{ + "memory_mb_used_by_node":"{\"0\": {\"2M\": 5120, \"4K\": 0, \"1G\": 0}, \"1\": {\"2M\": 0, \"4K\": 0, \"1G\": 0}}", + "cpu_info":{ + "arch":"x86_64", + "model":"IvyBridge", + "vendor":"Intel", + "features":[ + "pge", + "avx", + "vmx", + "clflush", + "sep", + "syscall", + "vme", + "dtes64", + "tsc", + "sse", + "xsave", + "xsaveopt", + "erms", + "xtpr", + "cmov", + "smep", + "ssse3", + "est", + "pat", + "monitor", + "smx", + "pcid", + "lm", + "msr", + "nx", + "fxsr", + "tm", + "sse4.1", + "pae", + "sse4.2", + "pclmuldq", + "acpi", + "tsc-deadline", + "popcnt", + "mmx", + "osxsave", + "cx8", + "mce", + "de", + "tm2", + "ht", + "dca", + "pni", + "pdcm", + "mca", + "pdpe1gb", + "apic", + "fsgsbase", + "f16c", + "pse", + "ds", + "invtsc", + "lahf_lm", + "aes", + "sse2", + "ss", + "ds_cpl", + "arat", + "pbe", + "fpu", + "cx16", + "pse36", + "mtrr", + "rdrand", + "rdtscp", + "x2apic" + ], + "topology":{ + "cores":10, + "cells":2, + "threads":2, + "sockets":1 + } + }, + "free_disk_gb":208, + "memory_mb_used":5120, + "vcpus_by_node":"{\"0\": 14, \"1\": 20}", + "memory_mb_by_node":"{\"0\": {\"2M\": 21440, \"4K\": 0, \"1G\": 0}, \"1\": {\"2M\": 29088, \"4K\": 0, \"1G\": 0}}", + "service":{ + "host":"compute-1", + "disabled_reason":null, + "id":8 + }, + "local_gb_used":9, + "id":2, + "current_workload":0, + "state":"up", + "vcpus_used_by_node":"{\"0\": {\"shared\": 0.125, \"dedicated\": 6}, \"1\": {\"shared\": 0.0, \"dedicated\": 0}}", + "status":"enabled", + "host_ip":"192.168.205.205", + "hypervisor_hostname":"compute-1", + "hypervisor_version":2006000, + "disk_available_least":208, + "local_gb":219, + "free_ram_mb":45408, + "vcpus_used":6.125, + "hypervisor_type":"QEMU", + "memory_mb":50528, + "vcpus":34, + "running_vms":7 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-get-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-get-resp.json new file mode 100644 index 000000000..49f01ff53 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-get-resp.json @@ -0,0 +1,15 @@ +{ + "server_group": { + "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", + "wrs-sg:project_id": "28d41dbebab24bdf8854a6632271a3f6" + "name": "callservergroup", + "policies": [ + "wrs-sg:affinity-hyperthread" + ], + "members": [], + "metadata": { + "wrs-sg:best_effort": "1", + "wrs-sg:group_size": "2" + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-list-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-list-resp.json new file mode 100644 index 000000000..0fc048eda --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-list-resp.json @@ -0,0 +1,27 @@ +{ + "server_groups": [ + { + "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", + "wrs-sg:project_id": "28d41dbebab24bdf8854a6632271a3f6" + "name": "callservergroup", + "policies": [ + "wrs-sg:affinity-hyperthread" + ], + "members": [], + "metadata": { + "wrs-sg:best_effort": "1", + "wrs-sg:group_size": "2" + } + }, + { + "id": "2fb919a2-4666-11e4-9255-080027367628", + "wrs-sg:project_id": "28d41dbebab24bdf8854a6632271a3f6" + "name": "antiaffinitygroup", + "policies": [ + "anti-affinity" + ], + "members": [], + "metadata": {} + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-req.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-req.json new file mode 100644 index 000000000..609d18a9c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-req.json @@ -0,0 +1,13 @@ +{ + "server_group": { + "name": "antiaffinitygroup", + "wrs-sg:project_id": "28d41dbebab24bdf8854a6632271a3f6" + "policies": [ + "anti-affinity" + ], + "metadata": { + "wrs-sg:best_effort": "1", + "wrs-sg:group_size": "2" + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-resp.json new file mode 100644 index 000000000..afd6ae642 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/os-server-groups/server-groups-post-resp.json @@ -0,0 +1,15 @@ +{ + "server_group": { + "id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9", + "wrs-sg:project_id": "28d41dbebab24bdf8854a6632271a3f6" + "name": "antiaffinitygroup", + "policies": [ + "anti-affinity" + ], + "members": [], + "metadata": { + "wrs-sg:best_effort": "1", + "wrs-sg:group_size": "2" + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-get-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-get-resp.json new file mode 100644 index 000000000..f9586ae6d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-get-resp.json @@ -0,0 +1,48 @@ +{ + "pci_device_usage": [ + { + "pci_vfs_used": 0, + "host": "compute-3", + "pci_pfs_used": 0, + "pci_pfs_configured": 0, + "pci_vfs_configured": 0, + "device_name": "Coleto Creek PCIe Co-processor", + "vendor_id": "8086", + "device_id": "0443", + "class_id": "0b4000" + }, + { + "pci_vfs_used": 1, + "host": "compute-1", + "pci_pfs_used": 0, + "pci_pfs_configured": 0, + "pci_vfs_configured": 32, + "device_name": "Coleto Creek PCIe Co-processor", + "vendor_id": "8086", + "device_id": "0443", + "class_id": "0b4000" + }, + { + "pci_vfs_used": 0, + "host": "compute-2", + "pci_pfs_used": 0, + "pci_pfs_configured": 0, + "pci_vfs_configured": 0, + "device_name": "Coleto Creek PCIe Co-processor", + "vendor_id": "8086", + "device_id": "0443", + "class_id": "0b4000" + }, + { + "pci_vfs_used": 0, + "host": "compute-0", + "pci_pfs_used": 0, + "pci_pfs_configured": 0, + "pci_vfs_configured": 32, + "device_name": "Coleto Creek PCIe Co-processor", + "vendor_id": "8086", + "device_id": "0443", + "class_id": "0b4000" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-list-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-list-resp.json new file mode 100644 index 000000000..72124bf46 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/pci-list-resp.json @@ -0,0 +1,14 @@ +{ + "pci_device_usage": [ + { + "pci_pfs_used": 0, + "pci_pfs_configured": 0, + "pci_vfs_used": 1, + "vendor_id": "8086", + "pci_vfs_configured": 64, + "device_name": "Coleto Creek PCIe Co-processor", + "device_id": "0443", + "class_id": "0b4000" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/providernet-get-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/providernet-get-resp.json new file mode 100644 index 000000000..69f542658 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/providernet-get-resp.json @@ -0,0 +1,10 @@ +{ + "providernet": { + "pci_pfs_used": 0, + "pci_pfs_configured": 0, + "pci_vfs_used": 1, + "pci_vfs_configured": 16, + "id": "21c41131-07fb-43ac-a6f3-8a8020152530", + "name": "group0-data0" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-get-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-get-resp.json new file mode 100644 index 000000000..02952b1ca --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-get-resp.json @@ -0,0 +1,86 @@ +{ + "server" : { + "accessIPv4" : "", + "wrs-if:nics" : [ + { + "nic1" : { + "network" : "tenant1-mgmt-net", + "port_id" : "dc627524-64a9-4fec-957a-b271f353fb22", + "vif_model" : "virtio", + "vif_pci_address": "0000:04:12.0", + "mtu" : 1500 + } + } + ], + "OS-EXT-SRV-ATTR:instance_name" : "instance-0000003d", + "OS-SRV-USG:terminated_at" : null, + "accessIPv6" : "", + "config_drive" : "", + "OS-DCF:diskConfig" : "MANUAL", + "wrs-sg:server_group" : "", + "updated" : "2015-04-01T20:32:57Z", + "metadata" : {}, + "id" : "770a214c-5d22-42ce-9273-f6baab0ad7fd", + "flavor" : { + "id" : "00bbded9-318a-461a-aef8-3904356ca8d9", + "links" : [ + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:8774/101d1cffc5ec4accbdb075c89a4c5cd7/flavors/00bbded9-318a-461a-aef8-3904356ca8d9" + } + ] + }, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.243:8774/v2/101d1cffc5ec4accbdb075c89a4c5cd7/servers/770a214c-5d22-42ce-9273-f6baab0ad7fd" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:8774/101d1cffc5ec4accbdb075c89a4c5cd7/servers/770a214c-5d22-42ce-9273-f6baab0ad7fd" + } + ], + "OS-EXT-SRV-ATTR:host" : "compute-0", + "OS-EXT-AZ:availability_zone" : "nova", + "name" : "vm07-shared-vcpu-id", + "hostId" : "938254ae1b04aabc901dd4ad2cf2a561a4eab858efa0b0a48eb048ff", + "user_id" : "13dbcb9d22474c39a4a612cd44bf58ad", + "status" : "ACTIVE", + "wrs-res:topology" : "node:1, 1024MB, pgsize:4K, vcpus:3", + "wrs-res:pci_devices": "node:1, addr:0000:83:04.6, type:VF, vendor:8086, product:0443", + "OS-EXT-STS:power_state" : 1, + "OS-EXT-SRV-ATTR:hypervisor_hostname" : "compute-0", + "tenant_id" : "101d1cffc5ec4accbdb075c89a4c5cd7", + "OS-SRV-USG:launched_at" : "2015-04-01T20:32:57.000000", + "OS-EXT-STS:vm_state" : "active", + "OS-EXT-STS:task_state" : null, + "progress" : 0, + "key_name" : null, + "image" : { + "id" : "a99dfaa7-c850-4a63-ad99-d4a5f8da3069", + "links" : [ + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:8774/101d1cffc5ec4accbdb075c89a4c5cd7/images/a99dfaa7-c850-4a63-ad99-d4a5f8da3069" + } + ] + }, + "wrs-res:vcpus (min/cur/max)" : [ + 3, + 3, + 3 + ], + "created" : "2015-04-01T20:32:49Z", + "addresses" : { + "tenant1-mgmt-net" : [ + { + "OS-EXT-IPS:type" : "fixed", + "version" : 4, + "OS-EXT-IPS-MAC:mac_addr" : "fa:16:3e:fc:65:81", + "addr" : "192.168.102.6" + } + ] + }, + "os-extended-volumes:volumes_attached" : [] + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-interface-attach-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-interface-attach-request.json new file mode 100644 index 000000000..bf5e41cfc --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-interface-attach-request.json @@ -0,0 +1,6 @@ +{ + "interfaceAttachment": { + "net_id": "e8b9af5e-1f47-429e-9ee0-fef202d4ea14", + "wrs-if:vif_model": "virtio" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-list-resp.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-list-resp.json new file mode 100644 index 000000000..cada460db --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-list-resp.json @@ -0,0 +1,88 @@ +{ + "servers" : [ + { + "accessIPv4" : "", + "wrs-if:nics" : [ + { + "nic1" : { + "network" : "tenant1-mgmt-net", + "port_id" : "dc627524-64a9-4fec-957a-b271f353fb22", + "vif_model" : "virtio", + "vif_pci_address": "0000:04:12.0", + "mtu" : 1500 + } + } + ], + "OS-EXT-SRV-ATTR:instance_name" : "instance-0000003d", + "OS-SRV-USG:terminated_at" : null, + "accessIPv6" : "", + "config_drive" : "", + "OS-DCF:diskConfig" : "MANUAL", + "wrs-sg:server_group" : "", + "updated" : "2015-04-01T20:32:57Z", + "metadata" : {}, + "id" : "770a214c-5d22-42ce-9273-f6baab0ad7fd", + "flavor" : { + "id" : "00bbded9-318a-461a-aef8-3904356ca8d9", + "links" : [ + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:8774/101d1cffc5ec4accbdb075c89a4c5cd7/flavors/00bbded9-318a-461a-aef8-3904356ca8d9" + } + ] + }, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.243:8774/v2/101d1cffc5ec4accbdb075c89a4c5cd7/servers/770a214c-5d22-42ce-9273-f6baab0ad7fd" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:8774/101d1cffc5ec4accbdb075c89a4c5cd7/servers/770a214c-5d22-42ce-9273-f6baab0ad7fd" + } + ], + "OS-EXT-SRV-ATTR:host" : "compute-0", + "OS-EXT-AZ:availability_zone" : "nova", + "name" : "vm07-shared-vcpu-id", + "hostId" : "938254ae1b04aabc901dd4ad2cf2a561a4eab858efa0b0a48eb048ff", + "user_id" : "13dbcb9d22474c39a4a612cd44bf58ad", + "status" : "ACTIVE", + "wrs-res:topology" : "node:1, 1024MB, pgsize:4K, vcpus:3", + "wrs-res:pci_devices": "node:1, addr:0000:83:04.6, type:VF, vendor:8086, product:0443", + "OS-EXT-STS:power_state" : 1, + "OS-EXT-SRV-ATTR:hypervisor_hostname" : "compute-0", + "tenant_id" : "101d1cffc5ec4accbdb075c89a4c5cd7", + "OS-SRV-USG:launched_at" : "2015-04-01T20:32:57.000000", + "OS-EXT-STS:vm_state" : "active", + "OS-EXT-STS:task_state" : null, + "progress" : 0, + "key_name" : null, + "image" : { + "id" : "a99dfaa7-c850-4a63-ad99-d4a5f8da3069", + "links" : [ + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:8774/101d1cffc5ec4accbdb075c89a4c5cd7/images/a99dfaa7-c850-4a63-ad99-d4a5f8da3069" + } + ] + }, + "wrs-res:vcpus (min/cur/max)" : [ + 3, + 3, + 3 + ], + "created" : "2015-04-01T20:32:49Z", + "addresses" : { + "tenant1-mgmt-net" : [ + { + "OS-EXT-IPS:type" : "fixed", + "version" : 4, + "OS-EXT-IPS-MAC:mac_addr" : "fa:16:3e:fc:65:81", + "addr" : "192.168.102.6" + } + ] + }, + "os-extended-volumes:volumes_attached" : [] + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-scale-up-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-scale-up-request.json new file mode 100644 index 000000000..f77e3c0dd --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server-scale-up-request.json @@ -0,0 +1,6 @@ +{ + "wrs-res:scale": { + "direction": "up", + "resource": cpu + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-request.json new file mode 100644 index 000000000..8512cab5c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-request.json @@ -0,0 +1,20 @@ +{ + "server": { + "name": "testvm", + "imageRef": "ec42f67b-1dcd-4f09-aa02-7a426737c20a", + "flavorRef": "2", + "networks": [ + { + "wrs-if:vif_model": "e1000", + "uuid": "06937e9e-0acd-4ad5-a6bb-f82d8896d5e8" + }, + { + "wrs-if:vif_pci_address": "0000:04:12.0", + "uuid": "cdc149b5-9122-4a16-975c-6acb973f49c3" + }, + { + "uuid": "b7adf5a0-3c5a-47f3-b733-8d56d12d2f45" + } + ] + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-response.json new file mode 100644 index 000000000..721fa7bd2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/api_samples/compute-v2-cgcs-ext/server_add-response.json @@ -0,0 +1,16 @@ +{ + "server": { + "adminPass": "yjzytFHb7XHc", + "id": "f8f4f3ce-f6e0-4e05-8f79-bf984fdfce45", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/servers/f8f4f3ce-f6e0-4e05-8f79-bf984fdfce45", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/servers/f8f4f3ce-f6e0-4e05-8f79-bf984fdfce45", + "rel": "bookmark" + } + ] + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/cgcs-ext/compute-v2-cgcs-ext.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/cgcs-ext/compute-v2-cgcs-ext.wadl new file mode 100644 index 000000000..fce2ef5be --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/cgcs-ext/compute-v2-cgcs-ext.wadl @@ -0,0 +1,1039 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + The ID for the tenant or + account in a multi-tenancy + cloud. + + + + + + + + + The alias for the extension + to list. + + + + + + + + + + + + + + + + + + + The ID for the server of + interest to you. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The server group + ID. + + + + + + + + + + + + The ID of the + flavor of interest to you. + + + + + + + + + + + + The key of the + extra-spec of interest to you. + + + + + + + + + + + + + + + + + The ID of the + provider network of interest to you. + + + + + + + + + + + + + + The device id of the + pci device of interest to you. + + + + + + + + + + + + + + The ID for the hypervisor of + interest to you. + + + + + + + + + + + + + + + + + + + + Lists all extensions. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Gets information about a specified extension. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + Creates a server. + + + + + + + + A networks object. By default, + the server instance is provisioned with all + isolated networks for the tenant. + Optionally, you can create one or more NICs + on the server. + To provision the server instance with a NIC + for a nova-network network, + specify the UUID in the uuid + attribute in a network + object. + To provision the server instance with a NIC + for a neutron network, specify + the UUID in the port attribute in + a network object. + In Titanium Cloud, to optionally provision the vif model + of the NIC, specify the appropriate value in the + wrs-if:vif_model attribute in the network + object. Valid vif model values are: e1000, + virtio, ne2k_pci, pcnet, + rtl8139, pci-passthrough, + pci-sriov. If not specified, + a vif model of virtio will be used. + To provision the PCI address of the NIC, specify the appropriate + value in the wrs-if:vif_pci_address attribute in + the network object. Valid PCI address values are in + the domain:bus:slot.function format. If not specified, a PCI + address will be chosen by the hypervisor. + You can specify multiple NICs on the + server. + + + + + + + + + + + + + + + + + + + + + Lists details of servers. + + + + + + + + The list of server objects. + + + &serverParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows details for a specified server. + + + + + + + + The requested server object. + + + &serverParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Allows the resources associated with the server + (currently only the number of CPUs) to be scaled up and down without requiring + a restart of the VM. + + + + + + + + Specify the wrs-res:scale action in the request body. + + + + + Direction to scale, "up" or "down". This will result in scaling the + specified resource by one unit in the specified direction. + + + + + + Resource to scale. Currently only "cpu" is supported. + + + + + + + + + + + + + + + + Create Interface + + + + + + + + Requested VIF model. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Creates a server group. + + + + + + + + + + + + + The project or tenant ID which owns this server group. + + + + + The scheduler policy to associate with the server + group. Modified by Titanium Cloud to include the following additional policy: + + + wrs-sg:affinity-hyperthread which will try to put servers + on the same compute node and have servers sharing sibling hyperthread + cores with each other, and only each other. Server Groups using + this policy are restriceted to a maximum of 2 members. + + + + + + + This parameter specifies a dictionary of optional + metadata to be associated with the group. + Additional keys added by Titanium Cloud are: + + + wrs-sg:best_effort (where a value of 0 means + that the scheduler policy will be strictly applied and a value of 1 + means that the server will still be scheduled even if the + policy can't be met). + + + wrs-sg:group_size (where the value is an integer + specifying the max number of servers in the group). + + + + + + + + + + + + + The requested server_group object. + + + &serverGroupsParameters; + + + + + + + + + + + + + Lists server groups. + + + + + + + + The list of server_group objects. + + + &serverGroupsParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows details for a specified server group. + + + + + + + + The requested server_group object. + + + &serverGroupsParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + + Lists the extra-specs or keys for + the specified flavor. + + + + + + + + The list of flavor extra specs. + + + &flavorextraspecListShowParameters; + + + + + + + + + + + + Creates extra-specs or keys for the + specified flavor. + + + + + + + + The list of flavor extra specs. + + + &flavorextraspecListShowParameters; + + + + + + + + + + + + &flavorextraspecListShowParameters; + + + + + + + + + + + + Gets the value of the specified + key. + + + + + + &flavorextraspecListShowParameters; + + + + + + + + + + + + + + + + List the provider networks (not supported). + + + + + + Show the details of a particular provider network. + + + + + + + + The requested provider network object. + + + + + The ID of the provider network. + + + + + The name of the provider network. + + + + + The number of configured PCI devices (PFs). + + + + + The number of used PCI devices (PFs). + + + + + The number of configured SR-IOV PCI devices (VFs). + + + + + The number of used SR-IOV PCI devices (VFs). + + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List PCI device usage statistics. This excludes network interface cards (NICs) + + + + + + + + The name of device. + + + + + The device id of device. + + + + + The vendor id of device. + + + + + The class id of device. + + + + + The number of configured PCI devices (PFs). + + + + + The number of used PCI devices (PFs). + + + + + The number of configured SR-IOV PCI devices (VFs). + + + + + The number of used SR-IOV PCI devices (VFs). + + + + + + + + + + &commonFaults; &getFaults; + + + + + Show the usage details of a particular PCI device. + + + + + + + + The name of device. + + + + + The device id of device. + + + + + The vendor id of device. + + + + + The class id of device. + + + + + The name of the compute host. + + + + + The number of configured PCI devices (PFs). + + + + + The number of used PCI devices (PFs). + + + + + The number of configured SR-IOV PCI devices (VFs). + + + + + The number of used SR-IOV PCI devices (VFs). + + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + Shows details for a specified hypervisor. + + + + + + + + lists available memory, in Megabytes, based on page size (4K, 2M, 1G) + on each NUMA node. The sum total must match the number reported in + memory_mb. + + + + + + lists memory currently in use, in Megabytes, based on page size + (4K, 2M, 1G) on each NUMA node. The sum total must match the + number reported in memory_mb_used. + + + + + + lists available vcpus, on each NUMA node. The sum total must + match the quantity reported by vcpus. + + + + + + lists vcpus currently in use, on each NUMA node. The sum total must + match the quantity reported by vcpus_used. + + + + + + + + + + &commonFaults; &getFaults; + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/common.ent new file mode 100644 index 000000000..7212c98e2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/compute-api/v2/common.ent @@ -0,0 +1,321 @@ + + + + + + Indicates namespace of the extension. + + + + + Indicates name of the extension. + + + + + Indicates updated time of the extension. + + + + + Indicates description of the extension. + + + + + Indicates alias of the extension. + + + + + A list of links for the extension. + + + '> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + '> + + + + + + + + + '> + + + + + '> + + + + + + '> + + + + + + '> + + + + + + The tenant or project owning the server group. + + + + + A list of policies associated with the server group. + Titanium Cloud added wrs-sg:affinity-hyperthread policy to indicate that only the + members of this server group can share sibling threads with each other. + + + + + Associated metadata key-and-value pairs. + Titanium Cloud added a boolean valued wrs-sg:best_effort metadata key-and-value + pair to indicate whether the server groups policy should be strictly enforced + or not. + Titanium Cloud added an integer valued wrs-sg:group_size metadata key-and-value + pair to indicate the maximum number of members of the server group. + + + '> + + + + + A nics object. Contains the list of NICs provisioned on the server + instance. + Optionally, in Titanium Cloud, each NIC can contain: + + + A wrs-if:vif_model attribute specifying the NICs vif model; + where valid vif model values are: e1000, + virtio, ne2k_pci, pcnet, + rtl8139, pci-passthrough, + pci-sriov. If not specified, + a vif model of virtio is being used. + + + A wrs-if:vif_pci_address attibute specifying the NICs PCI + address. If not specified, the PCI address in the guest is chosen by the + hypervisor and this value is empty. + + + + + + + + An addresses object. Contains + the list of addresses associated with the server instance. + + + + + An wrs-if:nics object. Contains + the list of NIC devices allocated for a VM instance. These + are a VM representation of the neutron port objects associated + to the VM. They are listed in the same order which the network + attachments were specified when the VM was launched. + + + + + This attribute specifies a number of resource details of the VM Server; + the number of numa nodes, the amount of memory and the memory page size, + and the current number of VCPUs. + + + + + List of pci devices associated with the server instance; + indicates the numa node, pci address, type of device, vendor id, + product id. + + + + + This attribute specifies the minimum number of vcpus, current number of + vcpus and maximum number of vcpus of a VM Server. + + + + + This attribute specifies the server group which the + VM Server is in; a null-string if the VM Server is not in a + server group. + + + '> + + + + + + + Indicates whether or not the guest applications running in the virtual + machine make use of the Titanium Cloud Heartbeat client API. + + + + + Indicates whether or not to expose a TPM device to the Guest. + + + + + Indicates the vCPU of the guest virtual machine that will be scheduled + to run on a shared CPU of the host. Note, this can be specified even if + hw:cpu_policy is set to dedicated; allowing the guest application to use + dedicated cores exclusively for its high-load tasks, but use a shared core + for its low-load (e.g. management type) tasks. + + + + + Indicates the minimum number of vCPUs for the virtual machine. The value + must be between one and the number of VCPUs in the flavor of the virtual + machine. If this extra_spec is specified then the server is assumed to support + vCPU scaling. + + + + + See Wind River Titanium Cloud Administration Guide for complete list of + additional flavor extra specs. + + + '> + + + + + GET'> + PUT'> + POST'> + DELETE'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-request.json new file mode 100644 index 000000000..2583a77e5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-request.json @@ -0,0 +1,10 @@ +{ + "hw_wrs_live_migration_timeout":"400", + "name":"cirros", + "container_format":"bare", + "cache_raw":"True", + "visibility":"public", + "disk_format":"qcow2", + "sw_wrs_auto_recovery":"False", + "hw_wrs_live_migration_max_downtime":"350" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-response.json new file mode 100644 index 000000000..ac743d291 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_add-response.json @@ -0,0 +1,27 @@ +{ + "hw_wrs_live_migration_timeout":"400", + "disk_format":"qcow2", + "min_ram":0, + "updated_at":"2016-10-25T12:02:09Z", + "file":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67/file", + "owner":"b27359bcdb3e424db43a3e2255777f37", + "id":"9d34ff07-6f66-4107-9363-e38b0b559a67", + "size":null, + "self":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67", + "cache_raw":"True", + "container_format":"bare", + "schema":"/v2/schemas/image", + "status":"queued", + "tags":[ + + ], + "visibility":"public", + "min_disk":0, + "sw_wrs_auto_recovery":"False", + "virtual_size":null, + "hw_wrs_live_migration_max_downtime":"350", + "name":"cirros", + "checksum":null, + "created_at":"2016-10-25T12:02:09Z", + "protected":false +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_list-response.json new file mode 100644 index 000000000..abd6c7f22 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_list-response.json @@ -0,0 +1,63 @@ +{ + "images":[ + { + "status":"active", + "virtual_size":null, + "name":"sample-guest", + "tags":[ + + ], + "container_format":"bare", + "created_at":"2016-10-24T22:50:17Z", + "size":688914432, + "disk_format":"raw", + "updated_at":"2016-10-24T22:50:26Z", + "visibility":"public", + "self":"/v2/images/ac22a842-27c6-40a5-8475-f15f12e94202", + "min_disk":0, + "protected":false, + "id":"ac22a842-27c6-40a5-8475-f15f12e94202", + "file":"/v2/images/ac22a842-27c6-40a5-8475-f15f12e94202/file", + "checksum":"29514837240a4bb80df0e2362644ae17", + "owner":"b27359bcdb3e424db43a3e2255777f37", + "direct_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/ac22a842-27c6-40a5-8475-f15f12e94202/snap", + "min_ram":0, + "store":"rbd", + "schema":"/v2/schemas/image" + }, + { + "hw_wrs_live_migration_timeout":"400", + "cache_raw":"True", + "min_ram":0, + "updated_at":"2016-10-25T12:06:19Z", + "file":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67/file", + "owner":"b27359bcdb3e424db43a3e2255777f37", + "id":"9d34ff07-6f66-4107-9363-e38b0b559a67", + "size":13287936, + "self":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67", + "disk_format":"qcow2", + "cache_raw_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/9d34ff07-6f66-4107-9363-e38b0b559a67_raw/snap", + "container_format":"bare", + "direct_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/9d34ff07-6f66-4107-9363-e38b0b559a67/snap", + "store":"rbd", + "schema":"/v2/schemas/image", + "status":"active", + "cache_raw_size":"41126400", + "cache_raw_status":"Cached", + "tags":[ + + ], + "visibility":"public", + "min_disk":0, + "sw_wrs_auto_recovery":"False", + "virtual_size":null, + "hw_wrs_live_migration_max_downtime":"350", + "name":"cirros", + "checksum":"ee1eca47dc88f4879d8a229cc70a07c6", + "created_at":"2016-10-25T12:02:09Z", + "protected":false + } + ], + "schema":"/v2/schemas/images", + "first":"/v2/images?sort_key=name&sort_dir=asc&limit=20" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-request.json new file mode 100644 index 000000000..6cc778150 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-request.json @@ -0,0 +1,17 @@ +[ + { + "path":"/hw_wrs_live_migration_timeout", + "value":"500", + "op":"replace" + }, + { + "path":"/sw_wrs_auto_recovery", + "value":"True", + "op":"replace" + }, + { + "path":"/hw_wrs_live_migration_max_downtime", + "value":"300", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-response.json new file mode 100644 index 000000000..e91f7392a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_modify-response.json @@ -0,0 +1,32 @@ +{ + "hw_wrs_live_migration_timeout":"500", + "cache_raw":"True", + "min_ram":0, + "updated_at":"2016-10-25T12:15:41Z", + "file":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67/file", + "owner":"b27359bcdb3e424db43a3e2255777f37", + "id":"9d34ff07-6f66-4107-9363-e38b0b559a67", + "size":13287936, + "self":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67", + "disk_format":"qcow2", + "cache_raw_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/9d34ff07-6f66-4107-9363-e38b0b559a67_raw/snap", + "container_format":"bare", + "direct_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/9d34ff07-6f66-4107-9363-e38b0b559a67/snap", + "store":"rbd", + "schema":"/v2/schemas/image", + "status":"active", + "cache_raw_size":"41126400", + "cache_raw_status":"Cached", + "tags":[ + + ], + "visibility":"public", + "min_disk":0, + "sw_wrs_auto_recovery":"True", + "virtual_size":null, + "hw_wrs_live_migration_max_downtime":"300", + "name":"cirros", + "checksum":"ee1eca47dc88f4879d8a229cc70a07c6", + "created_at":"2016-10-25T12:02:09Z", + "protected":false +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_show-response.json new file mode 100644 index 000000000..ad6f6cbbd --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/api_samples/image-v2-cgcs-ext/image_show-response.json @@ -0,0 +1,32 @@ +{ + "hw_wrs_live_migration_timeout":"400", + "cache_raw":"True", + "min_ram":0, + "updated_at":"2016-10-25T12:06:19Z", + "file":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67/file", + "owner":"b27359bcdb3e424db43a3e2255777f37", + "id":"9d34ff07-6f66-4107-9363-e38b0b559a67", + "size":13287936, + "self":"/v2/images/9d34ff07-6f66-4107-9363-e38b0b559a67", + "disk_format":"qcow2", + "cache_raw_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/9d34ff07-6f66-4107-9363-e38b0b559a67_raw/snap", + "container_format":"bare", + "direct_url":"rbd://840f16bc-3238-4adb-8700-6b9876c23462/images/9d34ff07-6f66-4107-9363-e38b0b559a67/snap", + "store":"rbd", + "schema":"/v2/schemas/image", + "status":"active", + "cache_raw_size":"41126400", + "cache_raw_status":"Cached", + "tags":[ + + ], + "visibility":"public", + "min_disk":0, + "sw_wrs_auto_recovery":"False", + "virtual_size":null, + "hw_wrs_live_migration_max_downtime":"350", + "name":"cirros", + "checksum":"ee1eca47dc88f4879d8a229cc70a07c6", + "created_at":"2016-10-25T12:02:09Z", + "protected":false +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/cgcs-ext/image-v2-cgcs-ext.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/cgcs-ext/image-v2-cgcs-ext.wadl new file mode 100644 index 000000000..bee5e2b03 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/cgcs-ext/image-v2-cgcs-ext.wadl @@ -0,0 +1,204 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + + + + + + The name for the image. + + + + + + + + + + + + + + + + + Lists all images. + &standardApiDescription; + + + + + + &imageListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows detailed information about a specific image. + &standardApiDescription; + + + + + + &imageListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Creates an image. + &standardApiDescription; + + + + + + + + On systems using Ceph storage, boot image files must be + converted to RAW format before they can be used to create + volumes. You can accelerate volume creation in Titanium Cloud + (and therefore instance launch time) by caching the RAW images + as they are created. The cached images are maintained in the + Glance image storage space and used for volume creation, eliminating + conversion time. The default behaviour is to NOT cache the raw format. + + + + + Indicates whether auto recovery of failed virutal machine instances is enabled or not. + The default is True. + + + + + Indicates the number of seconds to wait for a live migration to complete for + a VM created with this image. Note that this can be specified as an extraspec + of the flavor as well. If the timeout value is provisioned in both the flavor + and the image, the smaller value is used. The default is 800 seconds. The + minimum timeout is 120 seconds and the maximum timeout value is 800 seconds. + To disable the live migration timeout feature, set this value to 0. + + + + + Indicates the maximum amoutn of downtime to tolerate during a live migration of + a VM created with this image. Note that this can be specified as an extraspec + of the flavor as well. If the max downtime value is provisioned in both the flavor + and the image, the value from the flavor overrides the value from the image. The default + is 500 milliseconds. The minimum timer value is 100 milliseconds. + + + + + + + + + + + + + + &imageListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies a specific image. + &standardApiDescription; + + + + + + &imageListUpdateParameters; + + + + + + + + + + + + &imageListShowParameters; + + + + + + + + &postPutFaults; + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/common.ent new file mode 100644 index 000000000..5e1c27898 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/image-api/v2/common.ent @@ -0,0 +1,240 @@ + + + This is an existing OpenStack API. The documentation that follows lists only the fields that are new or modified. For a detailed description of existing and unmodified fields please refer to the standard OpenStack API documentation. NOTE that the extensions listed here are additional properties which are supported in the Image API and implemented in a Stack-specific manner. + '> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + '> + + + + + + + + + '> + + + + + '> + + + + + + '> + + + + + + '> + + + + + + Indicates namespace of the extension. + + + + + Indicates name of the extension. + + + + + Indicates updated time of the extension. + + + + + Indicates description of the extension. + + + + + Indicates alias of the extension. + + + + + A list of links for the extension. + + + '> + + + + + + On systems using Ceph storage, boot image files must be + converted to RAW format before they can be used to create + volumes. You can accelerate volume creation in Titanium Cloud + (and therefore instance launch time) by caching the RAW images + as they are created. The cached images are maintained in the + Glance image storage space and used for volume creation, eliminating + conversion time. The default behaviour is to NOT cache the raw format. + + + + + Indicates which Glance backend the image is stored in; either file for + the Controller Filesystem or rbd for the ceph backend. + + + + + Indicates whether auto recovery of failed virutal machine instances is enabled or not. + The default is True. + + + + + Indicates the number of seconds to wait for a live migration to complete for + a VM created with this image. Note that this can be specified as an extraspec + of the flavor as well. If the timeout value is provisioned in both the flavor + and the image, the smaller value is used. The default is 800 seconds. The + minimum timeout is 120 seconds and the maximum timeout value is 800 seconds. + To disable the live migration timeout feature, set this value to 0. + + + + + Indicates the maximum amoutn of downtime to tolerate during a live migration of + a VM created with this image. Note that this can be specified as an extraspec + of the flavor as well. If the max downtime value is provisioned in both the flavor + and the image, the value from the flavor overrides the value from the image. The default + is 500 milliseconds. The minimum timer value is 100 milliseconds. + + + '> + + + Indicates whether auto recovery of failed virutal machine instances is enabled or not. + The default is True. + + + + + Indicates the number of seconds to wait for a live migration to complete for + a VM created with this image. Note that this can be specified as an extraspec + of the flavor as well. If the timeout value is provisioned in both the flavor + and the image, the smaller value is used. The default is 800 seconds. The + minimum timeout is 120 seconds and the maximum timeout value is 800 seconds. + To disable the live migration timeout feature, set this value to 0. + + + + + Indicates the maximum amoutn of downtime to tolerate during a live migration of + a VM created with this image. Note that this can be specified as an extraspec + of the flavor as well. If the max downtime value is provisioned in both the flavor + and the image, the value from the flavor overrides the value from the image. The default + is 500 milliseconds. The minimum timer value is 100 milliseconds. + + + '> + + + + + + + GET'> + PUT'> + POST'> + DELETE'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_get-response.json new file mode 100644 index 000000000..00585b447 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_get-response.json @@ -0,0 +1,62 @@ +{ + "extensions" : { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-provider/v1", + "name" : "wrs-provider-network", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Provider Network Extensions.", + "alias" : "wrs-provider", + "links" : [] + } +} + +OR + +{ + "extensions" : { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-tenant/v1", + "name" : "wrs-tenant-settings", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Tenant Network Settings Extensions.", + "alias" : "wrs-tenant", + "links" : [] + } +} + +OR + +{ + "extensions" : { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-tm/v1", + "name" : "wrs-traffic-management", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Traffic Management Extensions.", + "alias" : "wrs-tm", + "links" : [] + } +} + +OR + +{ + "extensions" : { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-net/v1", + "name" : "wrs-tenant-network", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Tenant Network Extensions.", + "alias" : "wrs-net", + "links" : [] + } +} + +OR + +{ + "extensions" : { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-binding/v1", + "name" : "wrs-port-binding", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Port Binding Extensions.", + "alias" : "wrs-binding", + "links" : [] + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_list-response.json new file mode 100644 index 000000000..754cd04cc --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/extension_list-response.json @@ -0,0 +1,47 @@ +{ + "extensions" : [ + ... + { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-provider/v1", + "name" : "wrs-provider-network", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Provider Network Extensions.", + "alias" : "wrs-provider", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-tenant/v1", + "name" : "wrs-tenant-settings", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Tenant Network Settings Extensions.", + "alias" : "wrs-tenant", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-tm/v1", + "name" : "wrs-traffic-management", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Traffic Management Extensions.", + "alias" : "wrs-tm", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-net/v1", + "name" : "wrs-tenant-network", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Tenant Network Extensions.", + "alias" : "wrs-net", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-binding/v1", + "name" : "wrs-port-binding", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "WRS Port Binding Extensions.", + "alias" : "wrs-binding", + "links" : [] + }, + ... + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_request.json new file mode 100644 index 000000000..6a67f7535 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_request.json @@ -0,0 +1,7 @@ +{ + "host": { + "availability": "down", + "id": "b1165275-b0dd-4f01-bbb7-988cdede05ab", + "name": "compute-99" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_response.json new file mode 100644 index 000000000..9897a9f48 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-create_admin_response.json @@ -0,0 +1,13 @@ +{ + "host": { + "agents": [], + "availability": "down", + "created_at": "2014-10-01 17:02:03.974462", + "id": "b1165275-b0dd-4f01-bbb7-988cdede05ab", + "name": "compute-99", + "ports": 0, + "routers": 0, + "subnets": 0, + "updated_at": null + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-delete_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-delete_admin_response.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-delete_admin_response.json @@ -0,0 +1 @@ +{} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-list_admin_response.json new file mode 100644 index 000000000..13118cd87 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-list_admin_response.json @@ -0,0 +1,52 @@ +{ + "hosts": [ + { + "agents": [ + { + "id": "894d7327-ef14-468d-9037-82f7209a4165", + "type": "AVS agent" + }, + { + "id": "b3aa7556-0f13-4822-9707-d42b5bca114d", + "type": "L3 agent" + }, + { + "id": "7305ce69-c576-4e16-b880-57dec9fa2bb4", + "type": "DHCP agent" + } + ], + "availability": "up", + "created_at": "2014-10-01 13:11:22.590178", + "id": "6c7153a8-fdbb-4707-b8ab-5243ef9b0072", + "name": "compute-0", + "ports": 6, + "routers": 2, + "subnets": 2, + "updated_at": "2014-10-01 15:30:28.038701" + }, + { + "agents": [ + { + "id": "91eccf13-ae92-4dcd-b36d-4a52c2b8348f", + "type": "DHCP agent" + }, + { + "id": "53b84157-5761-4480-8b14-10abc22e3c65", + "type": "AVS agent" + }, + { + "id": "3c28bc57-ae08-428f-8387-1e4b74376220", + "type": "L3 agent" + } + ], + "availability": "up", + "created_at": "2014-10-01 13:11:51.881858", + "id": "4f31a85c-3066-4a94-b1b7-cd736897fb6a", + "name": "compute-1", + "ports": 3, + "routers": 0, + "subnets": 0, + "updated_at": "2014-10-01 15:47:11.208369" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-show_admin_response.json new file mode 100644 index 000000000..204ea7032 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-show_admin_response.json @@ -0,0 +1,26 @@ +{ + "host": { + "agents": [ + { + "id": "b3aa7556-0f13-4822-9707-d42b5bca114d", + "type": "L3 agent" + }, + { + "id": "7305ce69-c576-4e16-b880-57dec9fa2bb4", + "type": "DHCP agent" + }, + { + "id": "894d7327-ef14-468d-9037-82f7209a4165", + "type": "AVS agent" + } + ], + "availability": "up", + "created_at": "2014-10-01 13:11:22.590178", + "id": "6c7153a8-fdbb-4707-b8ab-5243ef9b0072", + "name": "compute-0", + "ports": 6, + "routers": 2, + "subnets": 2, + "updated_at": "2014-10-01 15:30:28.038701" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_request.json new file mode 100644 index 000000000..a504c7608 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_request.json @@ -0,0 +1,5 @@ +{ + "host": { + "availability": "up" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_response.json new file mode 100644 index 000000000..cd50c4b7f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/host-update_admin_response.json @@ -0,0 +1,26 @@ +{ + "host": { + "agents": [ + { + "id": "894d7327-ef14-468d-9037-82f7209a4165", + "type": "AVS agent" + }, + { + "id": "b3aa7556-0f13-4822-9707-d42b5bca114d", + "type": "L3 agent" + }, + { + "id": "7305ce69-c576-4e16-b880-57dec9fa2bb4", + "type": "DHCP agent" + } + ], + "availability": "up", + "created_at": "2014-10-01 13:11:22.590178", + "id": "6c7153a8-fdbb-4707-b8ab-5243ef9b0072", + "name": "compute-0", + "ports": 6, + "routers": 2, + "subnets": 2, + "updated_at": "2014-10-01 16:47:56.529831" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_request.json new file mode 100644 index 000000000..cafb65093 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_request.json @@ -0,0 +1,8 @@ +{ + "network": { + "admin_state_up": true, + "name": "test-net-0", + "wrs-tm:qos": "102c64e4-ad26-4610-ae39-f59e15fcb80c", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10", + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_response.json new file mode 100644 index 000000000..497a0e883 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-create_admin_response.json @@ -0,0 +1,17 @@ +{ + "network": { + "admin_state_up": true, + "id": "e815237e-9255-497f-a9b6-8c000d6e3224", + "name": "test-net-0", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data0", + "provider:segmentation_id": 602, + "wrs-tm:qos": "102c64e4-ad26-4610-ae39-f59e15fcb80c", + "shared": false, + "status": "ACTIVE", + "subnets": [], + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10", + "vlan_transparent": false, + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list-on-providernet_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list-on-providernet_admin_response.json new file mode 100644 index 000000000..e1f3aa064 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list-on-providernet_admin_response.json @@ -0,0 +1,32 @@ +{ + "networks": [ + { + "id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "name": "tenant1-net0", + "providernet_type": "vlan", + "segmentation_id": 601, + "vlan_id": 0 + }, + { + "id": "7e5ed852-a990-4fc5-89a2-b17093ca1982", + "name": "internal0-net0", + "providernet_type": "vlan", + "segmentation_id": 700, + "vlan_id": 0 + }, + { + "id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "name": "external-net0", + "providernet_type": "vlan", + "segmentation_id": 10, + "vlan_id": 0 + }, + { + "id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "name": "tenant1-mgmt-net", + "providernet_type": "vlan", + "segmentation_id": 600, + "vlan_id": 0 + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list_admin_response.json new file mode 100644 index 000000000..3f42c8819 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-list_admin_response.json @@ -0,0 +1,107 @@ +{ + "networks": [ + { + "admin_state_up": true, + "id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "name": "external-net0", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data0", + "provider:segmentation_id": 10, + "wrs-tm:qos": "d28e697c-c290-4895-b57c-ac7d38db9003", + "router:external": true, + "shared": true, + "status": "ACTIVE", + "subnets": [ + "b282ef86-2584-4a02-9b58-69d6233952a2" + ], + "tenant_id": "206f147dcf72421fa6829e33bfb34637" + }, + { + "admin_state_up": true, + "id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "name": "tenant1-mgmt-net", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data0", + "provider:segmentation_id": 600, + "wrs-tm:qos": "102c64e4-ad26-4610-ae39-f59e15fcb80c", + "router:external": false, + "shared": false, + "status": "ACTIVE", + "subnets": [ + "34efd537-7a72-4fcd-b837-9874caf34117" + ], + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "id": "9472a8ab-9205-43ef-a460-5f01f031791a", + "name": "tenant2-mgmt-net", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data1", + "provider:segmentation_id": 616, + "wrs-tm:qos": "62970a9a-b093-4747-92dd-9de25616036a", + "router:external": false, + "shared": false, + "status": "ACTIVE", + "subnets": [ + "9aa900f4-522b-4b83-ba93-57f7d92da5d5" + ], + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + }, + { + "admin_state_up": true, + "id": "7e5ed852-a990-4fc5-89a2-b17093ca1982", + "name": "internal0-net0", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data0", + "provider:segmentation_id": 700, + "router:external": false, + "shared": true, + "status": "ACTIVE", + "subnets": [ + "ad791a3e-33cf-4d8d-b80f-91c87f97745e" + ], + "tenant_id": "206f147dcf72421fa6829e33bfb34637", + "vlan_transparent": false, + }, + { + "admin_state_up": true, + "id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "name": "tenant1-net0", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data0", + "provider:segmentation_id": 601, + "router:external": false, + "shared": false, + "status": "ACTIVE", + "subnets": [ + "bc269028-1862-4dde-ba2e-62a67d1af4e4", + "837aebc9-6c78-43e9-8124-168ba16adbc7" + ], + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + "vlan_transparent": false, + }, + { + "admin_state_up": true, + "id": "7a77e654-794a-4e19-9679-ac2733e19876", + "name": "tenant2-net0", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data1", + "provider:segmentation_id": 617, + "router:external": false, + "shared": false, + "status": "ACTIVE", + "subnets": [ + "985806f5-9fd7-4d47-9da6-cb0c1316e63d" + ], + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + "vlan_transparent": false, + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-show_admin_response.json new file mode 100644 index 000000000..97c7433fc --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/net-show_admin_response.json @@ -0,0 +1,18 @@ +{ + "network": { + "admin_state_up": true, + "id": "e87e7438-8a07-4e82-a472-862bb7fa93ac", + "name": "test-net-0", + "mtu": 1500, + "provider:network_type": "vlan", + "provider:physical_network": "group0-data0", + "provider:segmentation_id": 602, + "wrs-tm:qos": "102c64e4-ad26-4610-ae39-f59e15fcb80c", + "router:external": false, + "shared": false, + "status": "ACTIVE", + "subnets": [], + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10", + "vlan_transparent": false, + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-list_admin_response.json new file mode 100644 index 000000000..1a3877001 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-list_admin_response.json @@ -0,0 +1,268 @@ +{ + "ports": [ + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-0", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "ce58c529-ba73-47f7-a409-a438ceced112", + "device_owner": "network:router_interface", + "fixed_ips": [ + { + "ip_address": "192.168.201.1", + "subnet_id": "9aa900f4-522b-4b83-ba93-57f7d92da5d5" + } + ], + "id": "e44d4c03-0add-4b1a-bd36-8f6e7ccd48d9", + "mac_address": "fa:16:3e:a6:27:3f", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "9472a8ab-9205-43ef-a460-5f01f031791a", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-0", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "ea2baef7-d84b-44c4-82e7-f274ab5e8b6f", + "device_owner": "network:router_gateway", + "fixed_ips": [ + { + "ip_address": "192.168.1.2", + "subnet_id": "b282ef86-2584-4a02-9b58-69d6233952a2" + } + ], + "id": "0ebefe26-de93-4d9e-b31a-b4620a6743e8", + "mac_address": "fa:16:3e:29:11:9b", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-0", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "ea2baef7-d84b-44c4-82e7-f274ab5e8b6f", + "device_owner": "network:router_interface", + "fixed_ips": [ + { + "ip_address": "192.168.101.1", + "subnet_id": "34efd537-7a72-4fcd-b837-9874caf34117" + } + ], + "id": "cf8c4f0a-f615-4437-a87a-39f2b87b7662", + "mac_address": "fa:16:3e:fb:4b:89", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-0", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "dhcp596d6b96-7696-5200-a782-fa1c60fe4171-f652780a-7a9d-4667-8df4-5c8632728be9", + "device_owner": "network:dhcp", + "fixed_ips": [ + { + "ip_address": "192.168.101.9", + "subnet_id": "34efd537-7a72-4fcd-b837-9874caf34117" + } + ], + "id": "30a92b3d-3353-4c24-9963-d0177b38ad59", + "mac_address": "fa:16:3e:f5:db:a6", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-1", + "wrs-binding:mtu": 1500, + "wrs-binding:vif_model": "virtio", + "binding:vif_type": "bridge", + "device_id": "2e934b37-772e-451a-b64a-cd68d9f8ae42", + "device_owner": "compute:nova", + "fixed_ips": [ + { + "ip_address": "192.168.101.11", + "subnet_id": "34efd537-7a72-4fcd-b837-9874caf34117" + } + ], + "id": "3ec39233-315c-474b-9f08-482e70c264c7", + "mac_address": "fa:16:3e:23:0c:bc", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "2c5c2553-36f2-4db4-8769-6ab71b6e2b1e", + "device_owner": "network:floatingip", + "fixed_ips": [ + { + "ip_address": "192.168.1.4", + "subnet_id": "b282ef86-2584-4a02-9b58-69d6233952a2" + } + ], + "id": "5e5a6728-81af-4b2d-b068-8a8e56847a1e", + "mac_address": "fa:16:3e:67:22:12", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "security_groups": [], + "status": "UNKNOWN", + "tenant_id": "" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-1", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "2e934b37-772e-451a-b64a-cd68d9f8ae42", + "device_owner": "compute:nova", + "fixed_ips": [], + "id": "8c99a79f-212c-45e5-89e6-8aa9ed3b5fcb", + "mac_address": "fa:16:3e:46:47:46", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-0", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "ce58c529-ba73-47f7-a409-a438ceced112", + "device_owner": "network:router_gateway", + "fixed_ips": [ + { + "ip_address": "192.168.1.3", + "subnet_id": "b282ef86-2584-4a02-9b58-69d6233952a2" + } + ], + "id": "10ce8655-96de-45f4-952c-a830ddf1f0d9", + "mac_address": "fa:16:3e:a4:1d:67", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "f2ade26f-5a16-4fef-b6f7-9bd9769ea1f4", + "device_owner": "network:floatingip", + "fixed_ips": [ + { + "ip_address": "192.168.1.5", + "subnet_id": "b282ef86-2584-4a02-9b58-69d6233952a2" + } + ], + "id": "573e154f-ec13-4e39-afcc-8e79d2089589", + "mac_address": "fa:16:3e:23:37:59", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "security_groups": [], + "status": "UNKNOWN", + "tenant_id": "" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-1", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "2e934b37-772e-451a-b64a-cd68d9f8ae42", + "device_owner": "compute:nova", + "fixed_ips": [], + "id": "9c9b1182-9f7d-4e21-910c-c4441a23d397", + "mac_address": "fa:16:3e:75:5f:61", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "7e5ed852-a990-4fc5-89a2-b17093ca1982", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-0", + "wrs-binding:mtu": 1500, + "binding:vif_type": "bridge", + "device_id": "dhcp596d6b96-7696-5200-a782-fa1c60fe4171-9472a8ab-9205-43ef-a460-5f01f031791a", + "device_owner": "network:dhcp", + "fixed_ips": [ + { + "ip_address": "192.168.201.6", + "subnet_id": "9aa900f4-522b-4b83-ba93-57f7d92da5d5" + } + ], + "id": "62872b6d-3e74-4838-9cf3-99736d0f3919", + "mac_address": "fa:16:3e:92:0b:14", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "9472a8ab-9205-43ef-a460-5f01f031791a", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-show_admin_response.json new file mode 100644 index 000000000..9d6f43b5a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/port-show_admin_response.json @@ -0,0 +1,28 @@ +{ + "port": { + "admin_state_up": true, + "binding:capabilities": { + "port_filter": true + }, + "binding:host_id": "compute-1", + "wrs-binding:mtu": 1500, + "wrs-binding:vif_model": "virtio", + "binding:vif_type": "bridge", + "device_id": "2e934b37-772e-451a-b64a-cd68d9f8ae42", + "device_owner": "compute:nova", + "fixed_ips": [ + { + "ip_address": "192.168.101.11", + "subnet_id": "34efd537-7a72-4fcd-b837-9874caf34117" + } + ], + "id": "3ec39233-315c-474b-9f08-482e70c264c7", + "mac_address": "fa:16:3e:23:0c:bc", + "wrs-binding:mac_filtering": false + "name": "", + "network_id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "security_groups": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_request.json new file mode 100644 index 000000000..800b415d8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_request.json @@ -0,0 +1,10 @@ +{ + "portforwarding": { + "router_id": "3303b254-404c-47eb-b02c-81bf0d602682", + "inside_addr": "192.168.101.63", + "protocol": "tcp", + "outside_port": "1234", + "inside_port": "80", + "description": "sample port forwarding rule" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_response.json new file mode 100644 index 000000000..4ba742cea --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-create_admin_response.json @@ -0,0 +1,12 @@ +{ + "portforwarding": { + "router_id": "3303b254-404c-47eb-b02c-81bf0d602682", + "inside_addr": "192.168.101.63", + "protocol": "tcp", + "outside_port": "1234", + "tenant_id": "6d8ff9303a45465492566fb936fe3b1d", + "description": "sample port forwarding rule", + "id": "66ebb891-f883-4fbd-9daf-15b367429d39", + "inside_port": "80" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-list_admin_response.json new file mode 100644 index 000000000..053bb388e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-list_admin_response.json @@ -0,0 +1,22 @@ +{ + "portforwardings": [{ + "router_id": "3303b254-404c-47eb-b02c-81bf0d602682", + "inside_addr": "192.168.101.63", + "protocol": "tcp", + "outside_port": 1234, + "tenant_id": "6d8ff9303a45465492566fb936fe3b1d", + "description": "sample port forwarding rule", + "id": "66ebb891-f883-4fbd-9daf-15b367429d39", + "inside_port": 80 + }, + { + "router_id": "3303b254-404c-47eb-b02c-81bf0d602682", + "inside_addr": "192.168.101.62", + "protocol": "tcp", + "outside_port": 1235, + "tenant_id": "6d8ff9303a45465492566fb936fe3b1d", + "description": "another sample port forwarding rule", + "id": "f8e22185-07f2-43e7-9213-abf84ef0eb58", + "inside_port": 80 + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-show_admin_response.json new file mode 100644 index 000000000..d762c75c9 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-show_admin_response.json @@ -0,0 +1,12 @@ +{ + "portforwarding": { + "router_id": "3303b254-404c-47eb-b02c-81bf0d602682", + "inside_addr": "192.168.101.63", + "protocol": "tcp", + "outside_port": 1234, + "tenant_id": "6d8ff9303a45465492566fb936fe3b1d", + "description": "sample port forwarding rule", + "id": "66ebb891-f883-4fbd-9daf-15b367429d39", + "inside_port": 80 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_request.json new file mode 100644 index 000000000..832012476 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_request.json @@ -0,0 +1,5 @@ +{ + "portforwarding": { + "description": "updated sample port forwarding rule" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_response.json new file mode 100644 index 000000000..fc846ffa3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/portforwarding-update_admin_response.json @@ -0,0 +1,12 @@ +{ + "portforwarding": { + "router_id": "3303b254-404c-47eb-b02c-81bf0d602682", + "inside_addr": "192.168.101.63", + "protocol": "tcp", + "outside_port": 1234, + "tenant_id": "6d8ff9303a45465492566fb936fe3b1d", + "description": "updated sample port forwarding rule", + "id": "66ebb891-f883-4fbd-9daf-15b367429d39", + "inside_port": 80 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-list_admin_response.json new file mode 100644 index 000000000..dd6817f47 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-list_admin_response.json @@ -0,0 +1,28 @@ +{ + "providernet_connectivity_tests":[ + { + "status":"PASS", + "segmentation_id":"10", + "updated_at":"2016-04-12 17:11:34.515416", + "host_name":"compute-1", + "providernet_id":"fc210630-7bb5-4ad2-a7e3-a4b752a8377b", + "host_id":"da6e8822-49ed-43f7-a5e4-90db837ffb2e", + "providernet_name":"physnet0", + "audit_uuid":"c3278c0b-660b-4152-a756-4eab241c1627", + "type":"vlan", + "message":"" + }, + { + "status":"PASS", + "segmentation_id":"10", + "updated_at":"2016-04-12 17:11:34.511279", + "host_name":"compute-0", + "providernet_id":"fc210630-7bb5-4ad2-a7e3-a4b752a8377b", + "host_id":"3c349ef5-d5f1-4bb1-9742-3538b6e9a352", + "providernet_name":"physnet0", + "audit_uuid":"c3278c0b-660b-4152-a756-4eab241c1627", + "type":"vlan", + "message":"" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_request.json new file mode 100644 index 000000000..e5dc6481f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_request.json @@ -0,0 +1,7 @@ +{ + "providernet_connectivity_test":{ + "segmentation_id":null, + "host_name":null, + "providernet_id":null + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_response.json new file mode 100644 index 000000000..f8879d4ed --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-connectivity-test-schedule_admin_response.json @@ -0,0 +1,5 @@ +{ + "providernet_connectivity_test":{ + "audit_uuid":"12a9f9c2-ca3b-4b56-b463-5755022c8d16" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_request.json new file mode 100644 index 000000000..aac43f98e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_request.json @@ -0,0 +1,8 @@ +{ + "providernet": { + "description": "A sample provider network", + "name": "test", + "type": "vlan", + "vlan_transparent": false, + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_response.json new file mode 100644 index 000000000..512f2fe9b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-create_admin_response.json @@ -0,0 +1,12 @@ +{ + "providernet": { + "description": "A sample provider network", + "id": "4da9e42c-e556-470c-8e92-cbd19bcc6a10", + "mtu": 1500, + "name": "test", + "ranges": [], + "status": "DOWN", + "type": "vlan", + "vlan_transparent": false, + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-delete_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-delete_admin_response.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-delete_admin_response.json @@ -0,0 +1 @@ +{} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-list_admin_response.json new file mode 100644 index 000000000..81f899e58 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-list_admin_response.json @@ -0,0 +1,62 @@ +{ + "providernets": [ + { + "description": "Group0 provider networks for data1 interfaces", + "id": "b67d40aa-3651-4dd6-886f-4bff5caa266e", + "mtu": 1500, + "name": "group0-data1", + "ranges": [ + { + "description": "tenant2 reserved networks", + "id": "a8184bf7-b683-4bc1-a70c-dae34391344c", + "maximum": 631, + "minimum": 616, + "name": "group0-tenant2", + "shared": false, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + } + ], + "status": "ACTIVE", + "type": "vlan", + "vlan_transparent": false, + }, + { + "description": "Group0 provider networks for data0 interfaces", + "id": "c496c429-cb52-4d4b-9171-b4b31fa91a80", + "mtu": 1500, + "name": "group0-data0", + "ranges": [ + { + "description": "Shared internal networks", + "id": "f3e1bc29-29f7-4ee0-a78d-9c3d7a0f53e5", + "maximum": 731, + "minimum": 700, + "name": "group0-shared", + "shared": true, + "tenant_id": null + }, + { + "description": "External network access", + "id": "35ef3460-700a-48a3-8df9-145eb68fcd31", + "maximum": 10, + "minimum": 10, + "name": "group0-external", + "shared": true, + "tenant_id": null + }, + { + "description": "tenant1 reserved networks", + "id": "736b0c0d-945b-4a17-9fe4-cf02a5327132", + "maximum": 615, + "minimum": 600, + "name": "group0-tenant1", + "shared": false, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } + ], + "status": "ACTIVE", + "type": "vlan", + "vlan_transparent": false, + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_request.json new file mode 100644 index 000000000..2c9894a87 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_request.json @@ -0,0 +1,10 @@ +{ + "providernet_range": { + "description": "A sample provider network segmentation range", + "maximum": "100", + "minimum": "1", + "name": "test-range-0", + "providernet_id": "239ffb19-bad8-4b05-9194-aa8399816a36", + "shared": true + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_response.json new file mode 100644 index 000000000..1f619850c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-create_admin_response.json @@ -0,0 +1,13 @@ +{ + "providernet_range": { + "description": "A sample provider network segmentation range", + "id": "bdf07406-a867-42e5-9533-5100c4a3f2ba", + "maximum": "100", + "minimum": "1", + "name": "test-range-0", + "providernet_id": "239ffb19-bad8-4b05-9194-aa8399816a36", + "providernet_name": "test", + "shared": true, + "tenant_id": null + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-delete_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-delete_admin_response.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-delete_admin_response.json @@ -0,0 +1 @@ +{} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-list_admin_response.json new file mode 100644 index 000000000..824a17c59 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-list_admin_response.json @@ -0,0 +1,59 @@ +{ + "providernet_ranges": [ + { + "description": "Shared internal networks", + "id": "f3e1bc29-29f7-4ee0-a78d-9c3d7a0f53e5", + "maximum": 731, + "minimum": 700, + "name": "group0-shared", + "providernet_id": "c496c429-cb52-4d4b-9171-b4b31fa91a80", + "providernet_name": "group0-data0", + "shared": true, + "tenant_id": null + }, + { + "description": "External network access", + "id": "35ef3460-700a-48a3-8df9-145eb68fcd31", + "maximum": 10, + "minimum": 10, + "name": "group0-external", + "providernet_id": "c496c429-cb52-4d4b-9171-b4b31fa91a80", + "providernet_name": "group0-data0", + "shared": true, + "tenant_id": null + }, + { + "description": "tenant1 reserved networks", + "id": "736b0c0d-945b-4a17-9fe4-cf02a5327132", + "maximum": 615, + "minimum": 600, + "name": "group0-tenant1", + "providernet_id": "c496c429-cb52-4d4b-9171-b4b31fa91a80", + "providernet_name": "group0-data0", + "shared": false, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "description": "tenant2 reserved networks", + "id": "a8184bf7-b683-4bc1-a70c-dae34391344c", + "maximum": 631, + "minimum": 616, + "name": "group0-tenant2", + "providernet_id": "b67d40aa-3651-4dd6-886f-4bff5caa266e", + "providernet_name": "group0-data1", + "shared": false, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + }, + { + "description": "A sample provider network segmentation range", + "id": "bdf07406-a867-42e5-9533-5100c4a3f2ba", + "maximum": 100, + "minimum": 1, + "name": "test-range-0", + "providernet_id": "239ffb19-bad8-4b05-9194-aa8399816a36", + "providernet_name": "test", + "shared": true, + "tenant_id": null + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-show_admin_response.json new file mode 100644 index 000000000..a732ccd64 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-show_admin_response.json @@ -0,0 +1,13 @@ +{ + "providernet_range": { + "description": "A sample provider network segmentation range", + "id": "bdf07406-a867-42e5-9533-5100c4a3f2ba", + "maximum": 100, + "minimum": 1, + "name": "test-range-0", + "providernet_id": "239ffb19-bad8-4b05-9194-aa8399816a36", + "providernet_name": "test", + "shared": true, + "tenant_id": null + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_request.json new file mode 100644 index 000000000..36174157f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_request.json @@ -0,0 +1,7 @@ +{ + "providernet_range": { + "maximum": "1099", + "minimum": "1000", + "description": "VLAN identifiers reserved for tenant1" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_response.json new file mode 100644 index 000000000..214c61c3a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-range-update_admin_response.json @@ -0,0 +1,13 @@ +{ + "providernet_range": { + "description": null, + "id": "fe24481a-303f-4cd9-a0ac-76c2e4a9bcc8", + "maximum": "1099", + "minimum": "1000", + "name": "test-range-0", + "providernet_id": "c496c429-cb52-4d4b-9171-b4b31fa91a80", + "providernet_name": "group0-data0", + "shared": false, + "tenant_id": "206f147dcf72421fa6829e33bfb34637" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-show_admin_response.json new file mode 100644 index 000000000..c39830042 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-show_admin_response.json @@ -0,0 +1,22 @@ +{ + "providernet": { + "description": "Group0 provider networks for data1 interfaces", + "id": "b67d40aa-3651-4dd6-886f-4bff5caa266e", + "mtu": 1500, + "name": "group0-data1", + "ranges": [ + { + "description": "tenant2 reserved networks", + "id": "a8184bf7-b683-4bc1-a70c-dae34391344c", + "maximum": 631, + "minimum": 616, + "name": "group0-tenant2", + "shared": false, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + } + ], + "status": "ACTIVE", + "type": "vlan", + "vlan_transparent": false, + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-type-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-type-list_admin_response.json new file mode 100644 index 000000000..8ede3117c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-type-list_admin_response.json @@ -0,0 +1,12 @@ +{ + "providernet_types": [ + { + "description": "Ethernet network without additional encapsulation", + "type": "flat" + }, + { + "description": "802.1q encapsulated Ethernet network", + "type": "vlan" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_request.json new file mode 100644 index 000000000..73afba1cb --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_request.json @@ -0,0 +1,5 @@ +{ + "providernet": { + "description": "Another sample provider network" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_response.json new file mode 100644 index 000000000..31e0b5e39 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/providernet-update_admin_response.json @@ -0,0 +1,12 @@ +{ + "providernet": { + "description": "Another sample provider network", + "id": "4da9e42c-e556-470c-8e92-cbd19bcc6a10", + "mtu": 1500, + "name": "test", + "ranges": [], + "status": "DOWN", + "type": "vlan", + "vlan_transparent": false, + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_request.json new file mode 100644 index 000000000..26e9e492b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_request.json @@ -0,0 +1,12 @@ +{ + "qos": { + "description": "A sample QoS profile", + "name": "test-qos-0", + "policies": { + "scheduler": { + "weight": "8" + } + }, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_response.json new file mode 100644 index 000000000..51061e1ab --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-create_admin_response.json @@ -0,0 +1,13 @@ +{ + "qos": { + "description": "A sample QoS profile", + "id": "5e1841fa-c106-47ee-a736-e527478f1239", + "name": "test-qos-0", + "policies": { + "scheduler": { + "weight": "8" + } + }, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-delete_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-delete_admin_response.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-delete_admin_response.json @@ -0,0 +1 @@ +{} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-list_admin_response.json new file mode 100644 index 000000000..a2d63511d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-list_admin_response.json @@ -0,0 +1,37 @@ +{ + "qoses": [ + { + "description": "tenant1 Management Network Policy", + "id": "102c64e4-ad26-4610-ae39-f59e15fcb80c", + "name": "tenant1-mgmt-qos", + "policies": { + "scheduler": { + "weight": "8" + } + }, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "description": "tenant2 Management Network Policy", + "id": "62970a9a-b093-4747-92dd-9de25616036a", + "name": "tenant2-mgmt-qos", + "policies": { + "scheduler": { + "weight": "8" + } + }, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + }, + { + "description": "External Network Policy", + "id": "d28e697c-c290-4895-b57c-ac7d38db9003", + "name": "external-qos", + "policies": { + "scheduler": { + "weight": "16" + } + }, + "tenant_id": "206f147dcf72421fa6829e33bfb34637" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-show_admin_response.json new file mode 100644 index 000000000..2d447bdce --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-show_admin_response.json @@ -0,0 +1,13 @@ +{ + "qos": { + "description": "tenant1 Management Network Policy", + "id": "102c64e4-ad26-4610-ae39-f59e15fcb80c", + "name": "tenant1-mgmt-qos", + "policies": { + "scheduler": { + "weight": "8" + } + }, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_request.json new file mode 100644 index 000000000..915c5257b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_request.json @@ -0,0 +1,10 @@ +{ + "qos": { + "description": "Another sample QoS profile", + "policies": { + "scheduler": { + "weight": "16" + } + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_response.json new file mode 100644 index 000000000..f30e97cdf --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/qos-update_admin_response.json @@ -0,0 +1,13 @@ +{ + "qos": { + "description": "Another sample QoS profile", + "id": "5e1841fa-c106-47ee-a736-e527478f1239", + "name": "test-qos-0", + "policies": { + "scheduler": { + "weight": "16" + } + }, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-list_admin_response.json new file mode 100644 index 000000000..841277b95 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-list_admin_response.json @@ -0,0 +1,30 @@ +{ + "routers": [ + { + "admin_state_up": true, + "external_gateway_info": { + "enable_snat": true, + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876" + }, + "wrs-net:host": "compute-0", + "id": "ea2baef7-d84b-44c4-82e7-f274ab5e8b6f", + "name": "tenant1-router", + "routes": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "admin_state_up": true, + "external_gateway_info": { + "enable_snat": true, + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876" + }, + "wrs-net:host": "compute-0", + "id": "ce58c529-ba73-47f7-a409-a438ceced112", + "name": "tenant2-router", + "routes": [], + "status": "ACTIVE", + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-show_admin_response.json new file mode 100644 index 000000000..fe50ad41d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/router-show_admin_response.json @@ -0,0 +1,15 @@ +{ + "router": { + "admin_state_up": true, + "external_gateway_info": { + "enable_snat": true, + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876" + }, + "wrs-net:host": "compute-0", + "id": "ea2baef7-d84b-44c4-82e7-f274ab5e8b6f", + "name": "tenant1-router", + "routes": [], + "status": "ACTIVE", + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-delete_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-delete_admin_response.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-delete_admin_response.json @@ -0,0 +1 @@ +{} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-list_admin_response.json new file mode 100644 index 000000000..ba19c2204 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-list_admin_response.json @@ -0,0 +1,12 @@ +{ + "settings": [ + { + "mac_filtering": false, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10" + }, + { + "mac_filtering": false, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-show_admin_response.json new file mode 100644 index 000000000..711e0cc83 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-show_admin_response.json @@ -0,0 +1,5 @@ +{ + "setting": { + "mac_filtering": false + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_request.json new file mode 100644 index 000000000..8b07d45b4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_request.json @@ -0,0 +1,5 @@ +{ + "setting": { + "mac_filtering": true + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_response.json new file mode 100644 index 000000000..8b07d45b4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/setting-update_admin_response.json @@ -0,0 +1,5 @@ +{ + "setting": { + "mac_filtering": true + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_request.json new file mode 100644 index 000000000..2a669b1b6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_request.json @@ -0,0 +1,14 @@ +{ + "subnet": { + "cidr": "1.2.3.0/24", + "enable_dhcp": false, + "ip_version": 4, + "wrs-net:managed": false, + "name": "test-subnet-0", + "network_id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": "615", + "wrs-net:vlan_id": 99 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_response.json new file mode 100644 index 000000000..fe694b0b0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-create_admin_response.json @@ -0,0 +1,20 @@ +{ + "subnet": { + "allocation_pools": [], + "cidr": "1.2.3.0/24", + "dns_nameservers": [], + "enable_dhcp": false, + "gateway_ip": null, + "host_routes": [], + "id": "837aebc9-6c78-43e9-8124-168ba16adbc7", + "ip_version": 4, + "wrs-net:managed": false, + "name": "test-subnet-0", + "network_id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": 615, + "tenant_id": "206f147dcf72421fa6829e33bfb34637", + "wrs-net:vlan_id": 99 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-list_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-list_admin_response.json new file mode 100644 index 000000000..ef632343d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-list_admin_response.json @@ -0,0 +1,127 @@ +{ + "subnets": [ + { + "allocation_pools": [ + { + "end": "192.168.1.254", + "start": "192.168.1.2" + } + ], + "cidr": "192.168.1.0/24", + "dns_nameservers": [], + "enable_dhcp": false, + "gateway_ip": "192.168.1.1", + "host_routes": [], + "id": "b282ef86-2584-4a02-9b58-69d6233952a2", + "ip_version": 4, + "wrs-net:managed": true, + "name": "external-subnet0", + "network_id": "b9475152-11d3-4bda-95c7-fb26a3ad3876", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": 10, + "tenant_id": "206f147dcf72421fa6829e33bfb34637", + "wrs-net:vlan_id": 0 + }, + { + "allocation_pools": [ + { + "end": "192.168.201.50", + "start": "192.168.201.2" + } + ], + "cidr": "192.168.201.0/24", + "dns_nameservers": [], + "enable_dhcp": true, + "gateway_ip": "192.168.201.1", + "host_routes": [], + "id": "9aa900f4-522b-4b83-ba93-57f7d92da5d5", + "ip_version": 4, + "wrs-net:managed": true, + "name": "tenant2-mgmt-subnet", + "network_id": "9472a8ab-9205-43ef-a460-5f01f031791a", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data1", + "wrs-provider:segmentation_id": 616, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3", + "wrs-net:vlan_id": 0 + }, + { + "allocation_pools": [ + { + "end": "192.168.101.50", + "start": "192.168.101.2" + } + ], + "cidr": "192.168.101.0/24", + "dns_nameservers": [], + "enable_dhcp": true, + "gateway_ip": "192.168.101.1", + "host_routes": [], + "id": "34efd537-7a72-4fcd-b837-9874caf34117", + "ip_version": 4, + "wrs-net:managed": true, + "name": "tenant1-mgmt-subnet", + "network_id": "f652780a-7a9d-4667-8df4-5c8632728be9", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": 600, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10", + "wrs-net:vlan_id": 0 + }, + { + "allocation_pools": [], + "cidr": "10.0.0.0/24", + "dns_nameservers": [], + "enable_dhcp": false, + "gateway_ip": null, + "host_routes": [], + "id": "ad791a3e-33cf-4d8d-b80f-91c87f97745e", + "ip_version": 4, + "wrs-net:managed": false, + "name": "internal0-subnet0-0", + "network_id": "7e5ed852-a990-4fc5-89a2-b17093ca1982", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": 700, + "tenant_id": "206f147dcf72421fa6829e33bfb34637", + "wrs-net:vlan_id": 0 + }, + { + "allocation_pools": [], + "cidr": "172.16.0.0/24", + "dns_nameservers": [], + "enable_dhcp": false, + "gateway_ip": null, + "host_routes": [], + "id": "bc269028-1862-4dde-ba2e-62a67d1af4e4", + "ip_version": 4, + "wrs-net:managed": false, + "name": "tenant1-subnet0", + "network_id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": 601, + "tenant_id": "0590d9fa3dd74bfe9bdf7ed4e5331a10", + "wrs-net:vlan_id": 0 + }, + { + "allocation_pools": [], + "cidr": "172.18.0.0/24", + "dns_nameservers": [], + "enable_dhcp": false, + "gateway_ip": null, + "host_routes": [], + "id": "985806f5-9fd7-4d47-9da6-cb0c1316e63d", + "ip_version": 4, + "wrs-net:managed": false, + "name": "tenant2-subnet0", + "network_id": "7a77e654-794a-4e19-9679-ac2733e19876", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data1", + "wrs-provider:segmentation_id": 617, + "tenant_id": "d8753af85cef49a4bf5f95208c4957f3", + "wrs-net:vlan_id": 0 + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-show_admin_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-show_admin_response.json new file mode 100644 index 000000000..fe694b0b0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/api_samples/networking-v2-cgcs-ext/subnet-show_admin_response.json @@ -0,0 +1,20 @@ +{ + "subnet": { + "allocation_pools": [], + "cidr": "1.2.3.0/24", + "dns_nameservers": [], + "enable_dhcp": false, + "gateway_ip": null, + "host_routes": [], + "id": "837aebc9-6c78-43e9-8124-168ba16adbc7", + "ip_version": 4, + "wrs-net:managed": false, + "name": "test-subnet-0", + "network_id": "2c0896cf-d118-4dca-9760-b4d97e3c7ec3", + "wrs-provider:network_type": "vlan", + "wrs-provider:physical_network": "group0-data0", + "wrs-provider:segmentation_id": 615, + "tenant_id": "206f147dcf72421fa6829e33bfb34637", + "wrs-net:vlan_id": 99 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/cgcs-ext/networking-v2-cgcs-ext.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/cgcs-ext/networking-v2-cgcs-ext.wadl new file mode 100644 index 000000000..da3fbfb73 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/cgcs-ext/networking-v2-cgcs-ext.wadl @@ -0,0 +1,1864 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + + + + The alias for the extension + to list. + + + + + + + + + + + + + + + + + + + The ID for a provider network. + + + + + + + + + + + + + + + + + + + + + + + + The ID for a provider network segmentation range. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The ID for a host running neutron services. + + + + + + + + + + + + + + + + + + + + The ID for a tenant. + + + + + + + + + + + + + + + + + + + + + + + + + The ID for a QOS Policy. + + + + + + + + + + + + + + + + + + + + + + The UUID for a network. + + + + + + + + + + + + + + + + + + The UUID for a subnet. + + + + + + + + + + + + + + + + + The UUID for a port. + + + + + + + + + + + + + + + + + The UUID for a router. + + + + + + + + + + + + + + + + + The ID for a virtual router port forwarding rule. + + + + + + + + + + + + + + + + + + + + + + + + Lists all extensions. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Gets information about a specified extension. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + Lists all provider networks. + + + + + + + + The list of provider networks. + + + &providernetListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific provider network. + + + + + + &providernetListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific provider network. + + + + + + + + User defined description of the provider network. + + + + + Specifies whether VLAN transparent network are supported on this provider network. + + + + + + + + + + + + + + &providernetListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a provider network. + + + + + + + + User defined description of the provider network. + + + + + The user defined name of the provider network. + + + + + The encapsulation type of the provider network. Valid values are: vlan, flat + + + + + Specifies whether VLAN transparent network are supported on this provider network. + + + + + + + + + + + + + + &providernetListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific provider network. + + + + + + + + + + + + + + + + + + Lists all provider network ranges. + + + + + + + + The list of provider network ranges. + + + &providernetrangeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific provider network range. + + + + + + &providernetrangeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific provider network range. + + + + + + + + User defined description of the provider network segmentation range. + + + + + The upper bound of the segmentation range (inclusive). + + + + + The lower bound of the segmentation range (inclusive). + + + + + + + + + + + + + + &providernetrangeListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a provider network range. + + + + + + + + User defined description of the provider network segmentation range. + + + + + The upper bound of the segmentation range (inclusive). + + + + + The lower bound of the segmentation range (inclusive). + + + + + The user defined name of the provider network segmentation range. + + + + + + + + + + + + + + &providernetrangeListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific provider network range. + + + + + + + + + + + + + + + + + Lists all supported providernet types. + Insert extra description here, if required. + + + + + + + + The list of supported providernet types. + + + + + System description of the provider network type. + + + + + The encapsulation type of the provider network. Valid values are: vlan, flat + + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + Lists results of providernet connectivity tests. + + + + + + + + List of providernet connectivity test results. + + + + + + + + + + &commonFaults; &getFaults; + + + + + Schedule providernet connectivity test to be run, and return scheduled UUID. + + + + + + + + Run audit for a given providernet identified by name. + + + + + Run audit for a given providernet identified by ID. + + + + + Run audit for all providernets on a given host identified by name. + + + + + Run audit for all providernets on a given host identified by ID. + + + + + Restrict audit to these segmentation IDs. + + + + + + + + + + + + + + + + Unique ID assigned to the audit. + + + + + + + + + + &postPutFaults; + + + + + + + + + + + Lists all hosts providing neutron services. + + + + + + + + The list of host entities with neutron services. + + + &hostListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific host providing neutron services. + + + + + + &hostListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Creates a record for a host providing neutron services. + + + + + + + + The current availability state of the host. Valid values are: UP or DOWN + + + + + The user defined name assigned to the host. This should normally match the system hostname of the host node. + + + + + + + + + + + + + + &providernetrangeListShowParameters; + + + + + + + + &postPutFaults; + + + + + Updates a host record. + + + + + + + + The current availability state of the host. Valid values are: up or down + + + + + + + + + + + + + + &providernetrangeListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a specific host record. + + + + + + + + + + + + + + + + Lists all tenant network settings. + + + + + + + + The list of tenant network settings. + + + &settingListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific tenant network setting. + + + + + + &settingListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific tenant network setting. + + + + + + + + The state of the source MAC filtering feature for the + specified tenant. The current state of the feature only affects + newly launched VM instances. + + + + + + + + + + + + + + &settingListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific tenant network setting. + + + + + + + + + + + + + + + + + Lists all QOS policies. + + + + + + + + The list of QOS policies. + + + &qosListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific QOS policy. + + + + + + &qosListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific QOS policy. + + + + + + + + The user defined description of the QoS policy. + + + + + The set of scheduler policies and weights for the QoS policy. + + + + + + + + + + + + + + &qosListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a QOS policy. + + + + + + + + The user defined description of the QoS policy. + + + + + The user defined name of the QoS policy. + + + + + The set of scheduler policies and weights for the QoS policy. + + + + + The unique UUID of the tenant to which this policy is assigned. + + + + + + + + + + + + + + &qosListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific QOS policy. + + + + + + + + + + + + + + + + + + Lists networks that are accessible + to the tenant who submits the reequest. + &standardApiDescription; + + + + + + + + The list of tenant networks. + + + &netListShowParameters; + + + + + + + &fault401; + + + + + Lists networks that are implemented by a given provider network. Each network is listed with its assigned provider network segmentation identifier. If the network has any tagged subnets then they will be listed as separate entities with their corresponding provider network segmentation identifier. + + + + + + + + The list of tenant networks. + + + + + The unique UUID value of the tenant network. + + + + + The user defined name of the tenant network. + + + + + The encapsulation type of the provider network. + + + + + The provider network segmentation identifier that is assigned to this tenant network. If the vlan_id attribute is non-zero then the segmentation_id represents that identifier which has been associated to a tagged subnet on the listed tenant network. + + + + + The VLAN identifier which has been configured on the tenant subnet. + + + + + + + + + &fault401; + + + + + Shows information for a specified + network. + &standardApiDescription; + + + + + + &netListShowParameters; + + + + + + + &fault401; &fault404; + + + + + Creates a tenant network. + &standardApiDescription; + + + + + + + + The unique UUID of the assigned QoS policy. + + + + + + + + + + + + + + &providernetrangeListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + Lists subnets that are accessible + to the tenant who submits the request. + &standardApiDescription; + + + + + + + + The list of subnets. + + + &subnetListShowParameters; + + + + + + + &fault401; + + + + + Creates a subnet on a specified + network. + &standardApiDescription; + + + + + + + + Indicates whether IP address allocation is managed by the system or by the customer. + If true then the system allocates IP addresses when ports are created and attached to VM instances. + If false then the system will not assign any IP addresses automatically. This implies that if the system cannot allocate any IP addresses that it also cannot allocate a DHCP server, manage allocation pools, or server DNS nameservers or static routers. + + + + + The VLAN ID to be used in the VM instance. If the VLAN ID is 0 then all packets originated from the VM instance are expected to be untagged. If the VLAN ID value is non zero than it is expected that all packets originated by the VM must be tagged with the corresponding VLAN ID value. Any other value will be discarded by the host vswitch. + + + + + The type of physical network that maps to this subnet resource. For example, flat, vlan, or vxlan. The value specified must match the equivalent attribute value on the parent network resource. + Only available to admin users. + + + + + The physical network where this subnet object is implemented. The value specified must match the equivalent attribute value on the parent network resource. + Only available to admin users. + + + + + An isolated segment on the physical network reserved for this subnet resource. The network_type attribute defines the segmentation model. For example, if the network_type is vlan, this ID is a vlan identifier. If the network_type value is vxlan, this ID is a vxlan VNI value. All subnets on a specific network that share the same wrs-net:vlan_id attribute value must have the same segmentation_id attribute value. + Only available to admin users. + + + + + + + + + + + + + + &subnetListShowParameters; + + + + + + + &fault400; &fault401; &fault403; &fault404; + &fault409conflict; + + + + + Shows information for a specified + subnet. + &standardApiDescription; + + + + + + &subnetListShowParameters; + + + + + + + &fault401; &fault404; + + + + + + + + + + Lists ports to which the tenant has + access. + &standardApiDescription; + + + + + + + + The list of ports. + + + &portListShowParameters; + + + + + + + &fault401; + + + + + Shows information for a specified + port. + &standardApiDescription; + + + + + + &portListShowParameters; + + + + + + + &fault401; &fault404; + + + + + + + + + + + Lists logical routers that are + accessible to the tenant who submits the + request. + &standardApiDescription; + + + + + + + + The list of virtual routers. + + + &routerListShowParameters; + + + + + + + &fault401; + + + + + Shows details for a specified + router. + &standardApiDescription; + + + + + + &routerListShowParameters; + + + + + + + &fault401; &fault403; &fault404; + + + + + + + + + Lists all virtual router port forwarding rules. + + + + + + + + The list of virtual router port forwarding rules. + + + &portForwardingListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific virtual router port forwarding rule. + + + + + + &portForwardingListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Creates a record for a virtual router port forwarding rule. + + + + + + + + The virtual router on which to create the port forwarding rule + + + + + The internal (private) address which is the final destination of the forwarding rule. + + + + + The internal (private) layer4 protocol port number. + + + + + The external (public) address which is the initial destination of the forwarding rule. + + + + + The layer4 protocol name; valid values are: udp, tcp, udp-lite, sctp, dccp. + + + + + A user defined description string. + + + + + + + + + + + + + + &portForwardingListShowParameters; + + + + + + + + &postPutFaults; + + + + + Updates a virtual router port forwarding rule. + + + + + + + + The internal (private) address which is the final destination of the forwarding rule. + + + + + The internal (private) layer4 protocol port number. + + + + + The external (public) address which is the initial destination of the forwarding rule. + + + + + The layer4 protocol name; valid values are: udp, tcp, udp-lite, sctp, dccp. + + + + + A user defined description string. + + + + + + + + + + + + + + &portForwardingListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a specific virtual router port forwarding rule. + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/common.ent new file mode 100644 index 000000000..2655d2dc9 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/networking-api/v2/common.ent @@ -0,0 +1,590 @@ + + + + + + Indicates namespace of the extension. + + + + + Indicates name of the extension. + + + + + Indicates updated time of the extension. + + + + + Indicates description of the extension. + + + + + Indicates alias of the extension. + + + + + A list of links for the extension. + + + '> + + + This is an existing OpenStack API. The documentation that follows lists only the fields that are new or modified. For a detailed description of existing and unmodified fields please refer to the standard OpenStack API documentation. + '> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + + '> + + + + + + '> + + + + + + '> + + + + + + '> + + + + + + '> + + + + + + '> + + + + + + + + + + '> + + + + + '> + + + + + + + '> + + + + + + '> + + + + + + + User defined description of the provider network. + + + + + The unique UUID value of the provider network. + + + + + The maximum transmit unit (MTU) assigned to the provider network. + Must be between 576 and 9216 bytes inclusively. The default value is 1500. + + + + + + The user defined name of the provider network. + + + + + The list of segmentation ranges defined for this provider network. + See the provider network range description for a description of range fields. + + + + + The current status of the provider network. Returns ACTIVE if at least + one compute node has a data interface associated to this provider network and + is available. + + + '> + + + + + + + User defined description of the provider network segmentation range. + + + + + The unique UUID value of the provider network segmentation range. + + + + + The upper bound of the segmentation range (inclusive). + + + + + The lower bound of the segmentation range (inclusive). + + + + + The user defined name of the provider network segmentation range. + + + + + The unique UUID of the parent provider network. + + + + + The user defined name of the parent provider network. + + + + + The shared attribute indicates that the range is available to any tenant. + + + + + The unique UUID of the tenant which owns the range. + Only valid if the shared attribute is False. + + + '> + + + + + + The list of neutron agents that are running on the host. + + + + + The current availability state of the host. Valid values are: UP or DOWN + + + + + The unique UUID of the host. + + + + + The user defined name assigned to the host. This should normally match the system hostname of the host node. + + + + + The number of virtual ports currently allocated on the host vswitch. + + + + + The number of virtual routers currently assigned to the host. + + + + + The number of DHCP enabled tenant networks currently assigned + to the DHCP server running on the host. + + + '> + + + + + + The state of the source MAC filtering feature for the + specified tenant. The current state of the feature only affects + newly launched VM instances. + + + + + The unique UUID of the tenant. + + + '> + + + + + + + The unique UUID of the assigned QoS policy. + + + + + Indicates whether the tenant network is ACTIVE or DOWN. If the network is DHCP enabled then it can only be active if at least 1 DHCP agent is servicing the network. + Titanium Cloud corrected the reporting of this status. + + + '> + + + + + + + Indicates whether IP address allocation is managed by the system or by the customer. + If true then the system allocates IP addresses when ports are created and attached to VM instances. + If false then the system will not assign any IP addresses automatically. This implies that if the system cannot allocate any IP addresses that it also cannot allocate a DHCP server, manage allocation pools, or server DNS nameservers or static routers. + + + + + The type of the provider network to which this subnet is assigned. + Only visible to admin users. + + + + + The name of the provider network to which this subnet is assigned. + Only visible to admin users. + + + + + The provider network segmentation id to which this subnet is assigned. + Only visible to admin users. + + + + + The VLAN ID to be used in the VM instance. If the VLAN ID is 0 then all packets originated from the VM instance are expected to be untagged. If the VLAN ID value is non zero than it is expected that all packets originated by the VM must be tagged with the corresponding VLAN ID value. Any other value will be discarded by the host vswitch. + + + '> + + + + + + The state of source MAC address filtering on the port. If this is true then the attached vswitch enforces that all ingress packets have a source MAC address that matches the port MAC address. + + + + + The maximum transmit unit (MTU). This value is inherited from the tenant network that attaches to this port. + + + + + The type of virtual networking device that is presented to the VM instance. This value is only visible if the device_owner is a VM instance port (i.e., device_owner="compute:nova"). + + + '> + + + + + + The host node where this virtual router is implemented. + Only visible to admin users. + + + '> + + + + + + + The user defined description of the QoS policy. + + + + + The unique UUID value of the QoS policy. + + + + + The user defined name of the QoS policy. + + + + + The set of scheduler policies and weights for the QoS policy. + + + + + The unique UUID of the tenant to which this policy is assigned. + + + + '> + + + + + + + The unique UUID of the router to which the rule is associated. + + + + + The unique UUID of the tenant which owns the rule. + + + + + The internal (private) address which is the final destination of the forwarding rule. + + + + + The internal (private) layer4 protocol port number. + + + + + The external (public) address which is the initial destination of the forwarding rule. + + + + + The layer4 protocol name; valid values are: udp, tcp, udp-lite, sctp, dccp. + + + + + A user defined description string. + + + '> + + + + GET'> + PUT'> + POST'> + DELETE'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-request.json new file mode 100755 index 000000000..9105460c1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-request.json @@ -0,0 +1,8 @@ +{ + "controller-apply-type": "serial", + "default-instance-action": "stop-start", + "compute-apply-type": "serial", + "storage-apply-type": "serial", + "swift-apply-type": "ignore", + "alarm-restrictions": "strict" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-response.json new file mode 100755 index 000000000..5b38fb3ff --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-patch-strategy-response.json @@ -0,0 +1,108 @@ +{ + "strategy": { + "controller-apply-type": "serial", + "current-phase-completion-percentage": 0, + "uuid": "15dc4b63-ae5f-48ca-b76e-ec367ef817f5", + "compute-apply-type": "serial", + "max-parallel-compute-hosts": 2, + "alarm-restrictions": "strict", + "current-phase": "build", + "apply-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "apply", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "storage-apply-type": "serial", + "state": "building", + "default-instance-action": "stop-start", + "abort-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "abort", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "build-phase": { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "", + "phase-name": "build", + "completion-percentage": 0, + "total-stages": 1, + "stop-at-stage": 1, + "result": "inprogress", + "timeout": 182, + "reason": "", + "inprogress": true, + "stages": [ + { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "", + "stage-id": 0, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "wait", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 1, + "entity-uuids": [], + "step-name": "query-sw-patches", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "query-sw-patch-hosts", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "inprogress", + "timeout": 181, + "total-steps": 3, + "inprogress": true, + "stage-name": "sw-patch-query" + } + ], + "current-stage": 0 + }, + "swift-apply-type": "ignore" + } +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-request.json new file mode 100755 index 000000000..8ea910e79 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-request.json @@ -0,0 +1,5 @@ +{ + "compute-apply-type": "serial", + "storage-apply-type": "serial", + "alarm-restrictions": "relaxed" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-response.json new file mode 100755 index 000000000..f6e6bd788 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/create-upgrade-strategy-response.json @@ -0,0 +1,97 @@ +{ + "strategy": { + "controller-apply-type": "serial", + "current-phase-completion-percentage": 0, + "uuid": "ac9b953a-caf1-4abe-8d53-498b598e6731", + "name": "sw-upgrade", + "compute-apply-type": "serial", + "max-parallel-compute-hosts": 2, + "current-phase": "build", + "apply-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "apply", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "storage-apply-type": "serial", + "state": "building", + "default-instance-action": "migrate", + "alarm-restrictions": "relaxed", + "abort-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "abort", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "build-phase": { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "", + "phase-name": "build", + "completion-percentage": 0, + "total-stages": 1, + "stop-at-stage": 1, + "result": "inprogress", + "timeout": 122, + "reason": "", + "inprogress": true, + "stages": [ + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "", + "stage-id": 0, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "wait", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 1, + "entity-uuids": [], + "step-name": "query-upgrade", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "inprogress", + "timeout": 121, + "total-steps": 2, + "inprogress": true, + "stage-name": "sw-upgrade-query" + } + ], + "current-stage": 0 + }, + "swift-apply-type": "ignore" + } +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-patch-strategy-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-patch-strategy-request.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-patch-strategy-request.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-upgrade-strategy-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-upgrade-strategy-request.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/delete-upgrade-strategy-request.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-patch-strategy-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-patch-strategy-response.json new file mode 100755 index 000000000..647c2a49a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-patch-strategy-response.json @@ -0,0 +1,725 @@ +{ + "strategy": { + "controller-apply-type": "serial", + "current-phase-completion-percentage": 100, + "uuid": "c1971c42-b494-4ff0-8abf-dbde17929972", + "compute-apply-type": "serial", + "max-parallel-compute-hosts": 2, + "alarm-restrictions": "strict", + "current-phase": "build", + "apply-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "apply", + "completion-percentage": 100, + "total-stages": 6, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [ + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 0, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "523cbd2d-f7f8-4707-8617-d085386f8711" + ], + "step-name": "swact-hosts", + "result": "initial", + "entity-names": [ + "controller-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "523cbd2d-f7f8-4707-8617-d085386f8711" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "controller-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "523cbd2d-f7f8-4707-8617-d085386f8711" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "controller-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 4, + "entity-uuids": [ + "523cbd2d-f7f8-4707-8617-d085386f8711" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "controller-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 5, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 4621, + "total-steps": 6, + "inprogress": false, + "stage-name": "sw-patch-controllers" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 1, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "0f3715c0-fecd-46e0-9cd0-4fbb31810393" + ], + "step-name": "swact-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "0f3715c0-fecd-46e0-9cd0-4fbb31810393" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "0f3715c0-fecd-46e0-9cd0-4fbb31810393" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 4, + "entity-uuids": [ + "0f3715c0-fecd-46e0-9cd0-4fbb31810393" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 5, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 4621, + "total-steps": 6, + "inprogress": false, + "stage-name": "sw-patch-controllers" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 2, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "instances", + "step-id": 1, + "entity-uuids": [ + "e5236dac-288f-4a1d-b1de-1c630aaa0df0" + ], + "step-name": "migrate-instances", + "result": "initial", + "entity-names": [ + "cirros-image-with-volumes-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "9a0dd555-a73b-4e49-b8e0-9cefeb2fb636" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-3" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "9a0dd555-a73b-4e49-b8e0-9cefeb2fb636" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-3" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 4, + "entity-uuids": [ + "9a0dd555-a73b-4e49-b8e0-9cefeb2fb636" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-3" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 5, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 4621, + "total-steps": 6, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 3, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "instances", + "step-id": 1, + "entity-uuids": [ + "ab977908-b5a4-44f1-832b-d7ebcfa476f0", + "7da7e6c6-fe9a-400e-99e5-4940b9b372ad", + "936fe92e-e48c-46ad-a052-9cdaea6fe840" + ], + "step-name": "migrate-instances", + "result": "initial", + "entity-names": [ + "cirros-ephemeral-swap-1", + "cirros-1", + "cirros-ephemeral-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "8fb371f2-fe1c-4325-a6f5-3487e33c9059" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "8fb371f2-fe1c-4325-a6f5-3487e33c9059" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 4, + "entity-uuids": [ + "8fb371f2-fe1c-4325-a6f5-3487e33c9059" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 5, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 4621, + "total-steps": 6, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 4, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "instances", + "step-id": 1, + "entity-uuids": [ + "f8c263c7-06c6-46f9-8c34-e2451e5ac8d5" + ], + "step-name": "migrate-instances", + "result": "initial", + "entity-names": [ + "cirros-swap-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "14cfa022-a29f-488b-a1e3-0c2a8231b33a" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "14cfa022-a29f-488b-a1e3-0c2a8231b33a" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 4, + "entity-uuids": [ + "14cfa022-a29f-488b-a1e3-0c2a8231b33a" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 5, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 4621, + "total-steps": 6, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 5, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "instances", + "step-id": 1, + "entity-uuids": [ + "25ad74e3-e4fe-4d1d-920a-7e1ecb38625b" + ], + "step-name": "migrate-instances", + "result": "initial", + "entity-names": [ + "cirros-image-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "c4f93e44-241b-4230-b4b3-098c0a9949fb" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-2" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "c4f93e44-241b-4230-b4b3-098c0a9949fb" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-2" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 4, + "entity-uuids": [ + "c4f93e44-241b-4230-b4b3-098c0a9949fb" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-2" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 5, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 4621, + "total-steps": 6, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + } + ], + "current-stage": 0 + }, + "storage-apply-type": "serial", + "state": "ready-to-apply", + "default-instance-action": "migrate", + "abort-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "abort", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "build-phase": { + "start-date-time": "2016-11-16 13:36:27", + "end-date-time": "2016-11-16 13:36:28", + "phase-name": "build", + "completion-percentage": 100, + "total-stages": 1, + "stop-at-stage": 1, + "result": "success", + "timeout": 182, + "reason": "", + "inprogress": false, + "stages": [ + { + "start-date-time": "2016-11-16 13:36:27", + "end-date-time": "2016-11-16 13:36:28", + "stage-id": 0, + "reason": "", + "current-step": 3, + "steps": [ + { + "start-date-time": "2016-11-16 13:36:27", + "end-date-time": "2016-11-16 13:36:27", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "success", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "2016-11-16 13:36:27", + "end-date-time": "2016-11-16 13:36:28", + "timeout": 60, + "entity-type": "", + "step-id": 1, + "entity-uuids": [], + "step-name": "query-sw-patches", + "result": "success", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "2016-11-16 13:36:28", + "end-date-time": "2016-11-16 13:36:28", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "query-sw-patch-hosts", + "result": "success", + "entity-names": [], + "reason": "" + } + ], + "result": "success", + "timeout": 181, + "total-steps": 3, + "inprogress": false, + "stage-name": "sw-patch-query" + } + ], + "current-stage": 1 + }, + "swift-apply-type": "ignore" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-upgrade-strategy-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-upgrade-strategy-response.json new file mode 100755 index 000000000..a974490ce --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/get-upgrade-strategy-response.json @@ -0,0 +1,356 @@ +{ + "strategy": { + "controller-apply-type": "serial", + "current-phase-completion-percentage": 100, + "uuid": "ac9b953a-caf1-4abe-8d53-498b598e6731", + "name": "sw-upgrade", + "compute-apply-type": "serial", + "max-parallel-compute-hosts": 2, + "current-phase": "build", + "apply-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "apply", + "completion-percentage": 100, + "total-stages": 3, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [ + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 0, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "77f00eea-a346-46f1-bf81-837088616b13" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "77f00eea-a346-46f1-bf81-837088616b13" + ], + "step-name": "upgrade-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "77f00eea-a346-46f1-bf81-837088616b13" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 7200, + "entity-type": "", + "step-id": 4, + "entity-uuids": [], + "step-name": "wait-data-sync", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 10861, + "total-steps": 5, + "inprogress": false, + "stage-name": "sw-upgrade-controllers" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 1, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "2acdfcdc-c29c-46f1-846d-23838ff608cb" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "2acdfcdc-c29c-46f1-846d-23838ff608cb" + ], + "step-name": "upgrade-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "2acdfcdc-c29c-46f1-846d-23838ff608cb" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 4, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 3721, + "total-steps": 5, + "inprogress": false, + "stage-name": "sw-upgrade-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 2, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "fe3ba4e3-e84d-467f-b633-e23df2f86e90" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "fe3ba4e3-e84d-467f-b633-e23df2f86e90" + ], + "step-name": "upgrade-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "fe3ba4e3-e84d-467f-b633-e23df2f86e90" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 4, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 3721, + "total-steps": 5, + "inprogress": false, + "stage-name": "sw-upgrade-compute-hosts" + } + ], + "current-stage": 0 + }, + "storage-apply-type": "serial", + "state": "ready-to-apply", + "default-instance-action": "migrate", + "alarm-restrictions": "relaxed", + "abort-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "abort", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "build-phase": { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "phase-name": "build", + "completion-percentage": 100, + "total-stages": 1, + "stop-at-stage": 1, + "result": "success", + "timeout": 122, + "reason": "", + "inprogress": false, + "stages": [ + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "stage-id": 0, + "reason": "", + "current-step": 2, + "steps": [ + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "success", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "timeout": 60, + "entity-type": "", + "step-id": 1, + "entity-uuids": [], + "step-name": "query-upgrade", + "result": "success", + "entity-names": [], + "reason": "" + } + ], + "result": "success", + "timeout": 121, + "total-steps": 2, + "inprogress": false, + "stage-name": "sw-upgrade-query" + } + ], + "current-stage": 1 + }, + "swift-apply-type": "ignore" + } +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-api-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-api-response.json new file mode 100644 index 000000000..0a8ab05d5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-api-response.json @@ -0,0 +1,18 @@ +{ + "versions": [ + { + "status": "stable", + "id": "v1", + "links": [ + { + "href": "http://192.168.204.2:4545/api/", + "rel": "self" + }, + { + "href": "http://192.168.204.2:4545/api/orchestration/", + "rel": "orchestration" + } + ] + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-response.json new file mode 100644 index 000000000..46d04b0a3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/nfv-vim-response.json @@ -0,0 +1,10 @@ +{ + "name": "nfv-vim", + "links": [ + { + "href": "http://192.168.204.2:4545/api/", + "rel": "api" + } + ], + "description": "NFV - Virtual Infrastructure Manager" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/orchestration-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/orchestration-response.json new file mode 100644 index 000000000..8e45b1b4d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/orchestration-response.json @@ -0,0 +1,17 @@ +{ + "id": "orchestration", + "links": [ + { + "href": "http://192.168.204.2:4545/orchestration/", + "rel": "self" + }, + { + "href": "http://192.168.204.2:4545/orchestration/sw-patch/", + "rel": "sw-patch" + }, + { + "href": "http://192.168.204.2:4545/orchestration/sw-upgrade/", + "rel": "sw-upgrade" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-request.json new file mode 100644 index 000000000..6ca8b11c7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-request.json @@ -0,0 +1,3 @@ +{ + "action": "apply-all" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-response.json new file mode 100755 index 000000000..8f2a63afb --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/patch-strategy-action-response.json @@ -0,0 +1,379 @@ +{ + "strategy": { + "controller-apply-type": "serial", + "current-phase-completion-percentage": 0, + "uuid": "15dc4b63-ae5f-48ca-b76e-ec367ef817f5", + "compute-apply-type": "serial", + "max-parallel-compute-hosts": 2, + "alarm-restrictions": "strict", + "current-phase": "apply", + "apply-phase": { + "start-date-time": "2016-11-16 19:28:28", + "end-date-time": "", + "phase-name": "apply", + "completion-percentage": 0, + "total-stages": 5, + "stop-at-stage": 5, + "result": "inprogress", + "timeout": 9606, + "reason": "", + "inprogress": true, + "stages": [ + { + "start-date-time": "2016-11-16 19:28:28", + "end-date-time": "", + "stage-id": 0, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "2016-11-16 19:28:28", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "wait", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "0f3715c0-fecd-46e0-9cd0-4fbb31810393" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "inprogress", + "timeout": 1921, + "total-steps": 3, + "inprogress": true, + "stage-name": "sw-patch-controllers" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 1, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "9a0dd555-a73b-4e49-b8e0-9cefeb2fb636" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-3" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 1921, + "total-steps": 3, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 2, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "8fb371f2-fe1c-4325-a6f5-3487e33c9059" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 1921, + "total-steps": 3, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 3, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "14cfa022-a29f-488b-a1e3-0c2a8231b33a" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 1921, + "total-steps": 3, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 4, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "c4f93e44-241b-4230-b4b3-098c0a9949fb" + ], + "step-name": "sw-patch-hosts", + "result": "initial", + "entity-names": [ + "compute-2" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 1921, + "total-steps": 3, + "inprogress": false, + "stage-name": "sw-patch-compute-hosts" + } + ], + "current-stage": 0 + }, + "storage-apply-type": "serial", + "state": "applying", + "default-instance-action": "stop-start", + "abort-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "abort", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "build-phase": { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "2016-11-16 19:14:05", + "phase-name": "build", + "completion-percentage": 100, + "total-stages": 1, + "stop-at-stage": 1, + "result": "success", + "timeout": 182, + "reason": "", + "inprogress": false, + "stages": [ + { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "2016-11-16 19:14:05", + "stage-id": 0, + "reason": "", + "current-step": 3, + "steps": [ + { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "2016-11-16 19:14:05", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "success", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "2016-11-16 19:14:05", + "timeout": 60, + "entity-type": "", + "step-id": 1, + "entity-uuids": [], + "step-name": "query-sw-patches", + "result": "success", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "2016-11-16 19:14:05", + "end-date-time": "2016-11-16 19:14:05", + "timeout": 60, + "entity-type": "", + "step-id": 2, + "entity-uuids": [], + "step-name": "query-sw-patch-hosts", + "result": "success", + "entity-names": [], + "reason": "" + } + ], + "result": "success", + "timeout": 181, + "total-steps": 3, + "inprogress": false, + "stage-name": "sw-patch-query" + } + ], + "current-stage": 1 + }, + "swift-apply-type": "ignore" + } +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-patch-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-patch-response.json new file mode 100644 index 000000000..22929af43 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-patch-response.json @@ -0,0 +1,13 @@ +{ + "id": "sw-patch", + "links": [ + { + "href": "http://192.168.204.2:4545/orchestration/sw-patch/", + "rel": "self" + }, + { + "href": "http://192.168.204.2:4545/orchestration/sw-patch/strategy/", + "rel": "strategy" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-upgrade-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-upgrade-response.json new file mode 100644 index 000000000..4de96cd1e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/sw-upgrade-response.json @@ -0,0 +1,13 @@ +{ + "id": "sw-upgrade", + "links": [ + { + "href": "http://192.168.204.2:4545/orchestration/sw-upgrade/", + "rel": "self" + }, + { + "href": "http://192.168.204.2:4545/orchestration/sw-upgrade/strategy/", + "rel": "strategy" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-request.json new file mode 100644 index 000000000..6ca8b11c7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-request.json @@ -0,0 +1,3 @@ +{ + "action": "apply-all" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-response.json new file mode 100755 index 000000000..4e0e50cb5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/api_samples/upgrade-strategy-action-response.json @@ -0,0 +1,356 @@ +{ + "strategy": { + "controller-apply-type": "serial", + "current-phase-completion-percentage": 0, + "uuid": "ac9b953a-caf1-4abe-8d53-498b598e6731", + "name": "sw-upgrade", + "compute-apply-type": "serial", + "max-parallel-compute-hosts": 2, + "current-phase": "apply", + "apply-phase": { + "start-date-time": "2017-01-10 16:19:12", + "end-date-time": "", + "phase-name": "apply", + "completion-percentage": 0, + "total-stages": 3, + "stop-at-stage": 3, + "result": "inprogress", + "timeout": 18304, + "reason": "", + "inprogress": true, + "stages": [ + { + "start-date-time": "2017-01-10 16:19:12", + "end-date-time": "", + "stage-id": 0, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "2017-01-10 16:19:12", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "wait", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "77f00eea-a346-46f1-bf81-837088616b13" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "77f00eea-a346-46f1-bf81-837088616b13" + ], + "step-name": "upgrade-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "77f00eea-a346-46f1-bf81-837088616b13" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "controller-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 7200, + "entity-type": "", + "step-id": 4, + "entity-uuids": [], + "step-name": "wait-data-sync", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "inprogress", + "timeout": 10861, + "total-steps": 5, + "inprogress": true, + "stage-name": "sw-upgrade-controllers" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 1, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "2acdfcdc-c29c-46f1-846d-23838ff608cb" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "2acdfcdc-c29c-46f1-846d-23838ff608cb" + ], + "step-name": "upgrade-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "2acdfcdc-c29c-46f1-846d-23838ff608cb" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-1" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 4, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 3721, + "total-steps": 5, + "inprogress": false, + "stage-name": "sw-upgrade-compute-hosts" + }, + { + "start-date-time": "", + "end-date-time": "", + "stage-id": 2, + "reason": "", + "current-step": 0, + "steps": [ + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "initial", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 1, + "entity-uuids": [ + "fe3ba4e3-e84d-467f-b633-e23df2f86e90" + ], + "step-name": "lock-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 1800, + "entity-type": "hosts", + "step-id": 2, + "entity-uuids": [ + "fe3ba4e3-e84d-467f-b633-e23df2f86e90" + ], + "step-name": "upgrade-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 900, + "entity-type": "hosts", + "step-id": 3, + "entity-uuids": [ + "fe3ba4e3-e84d-467f-b633-e23df2f86e90" + ], + "step-name": "unlock-hosts", + "result": "initial", + "entity-names": [ + "compute-0" + ], + "reason": "" + }, + { + "start-date-time": "", + "end-date-time": "", + "timeout": 60, + "entity-type": "", + "step-id": 4, + "entity-uuids": [], + "step-name": "system-stabilize", + "result": "initial", + "entity-names": [], + "reason": "" + } + ], + "result": "initial", + "timeout": 3721, + "total-steps": 5, + "inprogress": false, + "stage-name": "sw-upgrade-compute-hosts" + } + ], + "current-stage": 0 + }, + "storage-apply-type": "serial", + "state": "applying", + "default-instance-action": "migrate", + "alarm-restrictions": "relaxed", + "abort-phase": { + "start-date-time": "", + "end-date-time": "", + "phase-name": "abort", + "completion-percentage": 100, + "total-stages": 0, + "stop-at-stage": 0, + "result": "initial", + "timeout": 0, + "reason": "", + "inprogress": false, + "stages": [], + "current-stage": 0 + }, + "build-phase": { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "phase-name": "build", + "completion-percentage": 100, + "total-stages": 1, + "stop-at-stage": 1, + "result": "success", + "timeout": 122, + "reason": "", + "inprogress": false, + "stages": [ + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "stage-id": 0, + "reason": "", + "current-step": 2, + "steps": [ + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "timeout": 60, + "entity-type": "", + "step-id": 0, + "entity-uuids": [], + "step-name": "query-alarms", + "result": "success", + "entity-names": [], + "reason": "" + }, + { + "start-date-time": "2017-01-10 15:23:12", + "end-date-time": "2017-01-10 15:23:12", + "timeout": 60, + "entity-type": "", + "step-id": 1, + "entity-uuids": [], + "step-name": "query-upgrade", + "result": "success", + "entity-names": [], + "reason": "" + } + ], + "result": "success", + "timeout": 121, + "total-steps": 2, + "inprogress": false, + "stage-name": "sw-upgrade-query" + } + ], + "current-stage": 1 + }, + "swift-apply-type": "ignore" + } +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/common.ent new file mode 100755 index 000000000..da0a5ea00 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/common.ent @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + + '> + + + + + '> + + + + + '> + + + GET'> + POST'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/nfv-vim-api-v1.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/nfv-vim-api-v1.wadl new file mode 100755 index 000000000..3b8e87e76 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/nfv-vim-api/v1/nfv-vim-api-v1.wadl @@ -0,0 +1,479 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lists information about all NFV VIM links. + + + + + + + + + &commonFaults; &getFaults; + + + + + Lists information about all NFV VIM API versions. + + + + + + + + + &commonFaults; &getFaults; + + + + + Lists information about all NFV VIM API orchestration links. + + + + + + + + + &commonFaults; &getFaults; + + + + + Lists information about all NFV VIM API orchestration sw-patch links. + + + + + + + + + &commonFaults; &getFaults; + + + + + Lists information about all NFV VIM API orchestration sw-upgrade links. + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + Shows detailed information about the current sw-patch strategy. + + + + + + + + + + + + + &commonFaults; &getFaults; + + + + + Creates a sw-patch strategy. + + + + + + + + The apply type for controller hosts: serial or ignore. + + + + + The apply type for storage hosts: serial, parallel or ignore. + + + + + The apply type for compute hosts: serial, parallel or ignore. + + + + + The maximum number of compute hosts to patch in parallel; only applicable if compute-apply-type = parallel. Default value is 2. + + + + + The apply type for swift hosts: serial, parallel or ignore. + + + + + The default instance action: stop-start or migrate. + + + + + The strictness of alarm checks: strict or relaxed. + + + + + + + + + + + + + + + + + + + + + &commonFaults; + + + + + Applies or aborts a sw-patch strategy. + + + + + + + + The action to take: apply-all, apply-stage, abort or abort-stage. + + + + + The stage-id to apply or abort. Only used with apply-stage or abort-stage actions. + + + + + + + + + + + + + + + + + + + + + &commonFaults; + + + + + Deletes the current sw-patch strategy. + + + + + + + + + + + + + + + + + + + + + + + + + + + Shows detailed information about the current sw-upgrade strategy. + + + + + + + + + + + + + &commonFaults; &getFaults; + + + + + Creates a sw-upgrade strategy. + + + + + + + + The apply type for storage hosts: serial, parallel or ignore. + + + + + The apply type for compute hosts: serial, parallel or ignore. + + + + + The maximum number of compute hosts to upgrade in parallel; only applicable if compute-apply-type = parallel. Default value is 2. + + + + + The strictness of alarm checks: strict or relaxed. + + + + + + + + + + + + + + + + + + + + + &commonFaults; + + + + + Applies or aborts a sw-upgrade strategy. + + + + + + + + The action to take: apply-all, apply-stage, abort or abort-stage. + + + + + The stage-id to apply or abort. Only used with apply-stage or abort-stage actions. + + + + + + + + + + + + + + + + + + + + + &commonFaults; + + + + + Deletes the current sw-upgrade strategy. + + + + + + + + + + + + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_install_async-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_install_async-response.json new file mode 100755 index 000000000..4144fa683 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_install_async-response.json @@ -0,0 +1,5 @@ +{ + "info": "Patch installation request sent to compute-0.\n", + "warning": "", + "error": "" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_list-response.json new file mode 100755 index 000000000..c92532ec6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/host_list-response.json @@ -0,0 +1,39 @@ +{ + 'data': [ + { + 'hostname': 'controller-0', + 'nodetype': 'controller', + 'patch_failed': False, + 'ip': u'192.168.204.3', + 'requires_reboot': False, + 'installed': {}, + 'secs_since_ack': 18, + 'missing_pkgs': [], + 'patch_current': True, + 'stale_details': False, + 'to_remove': [], + 'state': 'idle', + 'subfunctions': [ + 'controller' + ], + 'sw_version': '15.12' + }, + { 'hostname': 'compute-0', + 'nodetype': 'compute', + 'patch_failed': False, + 'ip': u'192.168.204.27', + 'requires_reboot': False, + 'installed': {}, + 'secs_since_ack': 18, + 'missing_pkgs': [], + 'patch_current': True, + 'stale_details': False, + 'to_remove': [], + 'state': 'idle', + 'subfunctions': [ + 'compute' + ], + 'sw_version': '15.12' + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_apply-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_apply-response.json new file mode 100755 index 000000000..486c43b63 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_apply-response.json @@ -0,0 +1,5 @@ +{ + "info": "TS_15.12_PATCH_0001 has been applied\n", + "warning": "", + "error": "" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_delete-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_delete-response.json new file mode 100755 index 000000000..3e5b06c0f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_delete-response.json @@ -0,0 +1,5 @@ +{ + "info": "TS_15.12_PATCH_0001 has been deleted\n", + "warning": "", + "error": "" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_list-response.json new file mode 100755 index 000000000..05895b81f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_list-response.json @@ -0,0 +1,26 @@ +{ + 'pd':{ + 'TS_15.12_PATCH_0002':{ + 'status': 'REL', + 'sw_version': '15.12', + 'patchstate': 'Partial-Remove', + 'description': 'Fixes the following Issues:\n compute-4 and storage-0 multiple resets after DOR\n Alarms bogged down for 1 hour after DOR\n Guest Heartbeat cannot be enabled from horizon', + 'warnings': '', + 'summary': 'TS_15.12 Patch 0002', + 'repostate': 'Available', + 'install_instructions': '', + 'requires': [] + }, + 'TS_15.12_PATCH_0001':{ + 'status': 'REL', + 'sw_version': '15.12', + 'patchstate': 'Applied', + 'description': 'Fixes the following Issues:\n hbsClient instrumentation can cause server reset or hang after long soaks', + 'warnings': '', + 'summary': 'TS_15.12 Patch 0001', + 'repostate': 'Applied', + 'install_instructions': 'No special install instructions.', + 'requires': [] + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_remove-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_remove-response.json new file mode 100755 index 000000000..262372e46 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_remove-response.json @@ -0,0 +1,5 @@ +{ + "info": "TS_15.12_PATCH_0001 has been removed from the repo\n", + "warning": "", + "error": "" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_show-response.json new file mode 100755 index 000000000..1c12809b6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_show-response.json @@ -0,0 +1,22 @@ +{ + "contents": { + "TS_15.12_PATCH_0002": [ + "python-horizon-2013.2.3-r118.x86_64.rpm", + "sysinv-1.0-r81.x86_64.rpm" + ] + }, + "error": "", + "metadata": { + "TS_15.12_PATCH_0002": { + "description": "Fixes the following Issues:\n compute-4 and storage-0 multiple resets after DOR", + "install_instructions": "", + "patchstate": "Partial-Remove", + "repostate": "Available", + "requires": [], + "status": "DEV", + "summary": "TS_15.12 Patch 0002", + "sw_version": "15.12", + "warnings": "" + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_upload-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_upload-response.json new file mode 100755 index 000000000..c0e248dc8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patch_upload-response.json @@ -0,0 +1,5 @@ +{ + "info": "TS_15.12_PATCH_0001 is now available\n", + "warning": "", + "error": "" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patching-versions-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patching-versions-response.json new file mode 100755 index 000000000..8a843f3c6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/patching-versions-response.json @@ -0,0 +1 @@ +"Titanium Cloud Patching API, Available versions: /v1" \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/versionv1-get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/versionv1-get-response.json new file mode 100755 index 000000000..d73972061 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/api_samples/versionv1-get-response.json @@ -0,0 +1,26 @@ +{ + 'pd':{ + 'TS_15.12_PATCH_0002':{ + 'status': 'REL', + 'sw_version': '15.12', + 'patchstate': 'Partial-Remove', + 'description': 'Fixes the following Issues:\n compute-4 and storage-0 multiple resets after DOR\n CGTS-883 Alarms bogged down for 1 hour after DOR\n CGTS-894 Guest Heartbeat cannot be enabled from horizon', + 'warnings': '', + 'summary': 'TS_15.12 Patch 0002', + 'repostate': 'Available', + 'install_instructions': '', + 'requires': [] + }, + 'TS_15.12_PATCH_0001':{ + 'status': 'REL', + 'sw_version': '15.12', + 'patchstate': 'Applied', + 'description': 'Fixes the following Issues:\n hbsClient instrumentation can cause server reset or hang after long soaks', + 'warnings': '', + 'summary': 'TS_15.12 Patch 0001', + 'repostate': 'Applied', + 'install_instructions': 'No special install instructions.', + 'requires': [] + } + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/common.ent new file mode 100755 index 000000000..1cd98a3b1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/common.ent @@ -0,0 +1,406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + + '> + + + + + '> + + + + + '> + + + + + + + Any information regarding the request processing. + + + + + Any warnings generated during the request processing. + + + + + Any errors generated during the request processing. + + + '> + + + + + + + The list of patches present in the patching system. + + + + + A patch present in the patching system. + + + + + The status of the patch. + + + + + The software version for which the patch is intended. + + + + + Instructions on how to install the patch. + + + + + The description of any updates present in this patch. + + + + + Any warnings associated with the usage of the patch. + + + + + A brief summary of the patch. + + + + + Whether this patch`s content`s have been added to the patching repository; Applied or Available. + + + + + The state of this patch`s application to hosts; Available, Partial-Apply, Applied, or Partial-Removed. + + + + + A list of patch ids required for this patch to be installed. + + + '> + + + + + + + The RPMs contained within the patch. + + + + + A patch present in the patching system. + + + + + A package included in a patch. + + + + + Any errors associated with the patch. + + + + + Metadata associated with the patch. + + + + + The status of the patch. + + + + + The software version for which the patch is intended. + + + + + Instructions on how to install the patch. + + + + + The description of any updates present in this patch. + + + + + Any warnings associated with the usage of the patch. + + + + + A brief summary of the patch. + + + + + Whether the patch content has been added to the patching repository; Applied or Available. + + + + + The state of the patch regarding application to hosts; Available, Partial-Apply, Applied, or Partial-Removed. + + + + + A list of patch ids required for this patch to be installed. + + + '> + + + + + + + Indicates whether the host requires a reboot. + + + + + The type of the host; controller, compute or storage. + + + + + The list of packages missing from this host. + + + + + The ip address of the host. + + + + + The name of the host. + + + + + The packages installed on this host by the patching system. + + + + + The number of seconds since the host last reported its status. + + + + + Indicates whether a patch installation has failed on the host. + + + + + Indicates whether the details of this host are out of date. + + + + + Indicates whether the host is up to date regarding patches. + + + + + The list of packages that are to be removed from the host. + + + + + The software version running on the host. + + + + + The state of the patch agent: + + + + + idle: The patch agent is in an idle state, ready for installation requests. + + + + + installing: The patch agent is installing or removing patches as needed. + + + + + install-failed: The installation failed on the host. + + + + + install-rejected: The host is unlocked. Lock the node, and run the command again. + + + + + + + + The list of host subfunctions. + + + '> + + + + GET'> + POST'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/patching-api-v1.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/patching-api-v1.wadl new file mode 100755 index 000000000..d7568652f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/patching-api/v1/patching-api-v1.wadl @@ -0,0 +1,325 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + API version details. + + + + + + + + + + + + + + + + + Lists all patches in the patching system. + Supported query values are all, available, or applied. + + + + + + &listPatchParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific patch. + + + + + + &showPatchParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Uplaods a patch to the patching system. + Note that only one patch may be added per request + + + + + + + + + + + + &responseParameters; + + + + + + + + &postPutFaults; + + + + + + Applies a patch which is in the Available state. + + + + + + &responseParameters; + + + + + + + + &postPutFaults; + + + + + Removes a patch which is in the Applied state. + + + + + + &responseParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a patch which is in the Available state. + + + + + + &responseParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + + Lists information about all Titanium Cloud Patching API versions. + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + + Lists all host entities and their patching information. + + + + + + + + The list of host entities. + + + &queryHostsParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Trigger an asynchronous host install on the specified host. + The host must be in the Locked-Disabled-Online state. + + + + + + &responseParameters; + + + + + + + + &commonFaults; &postPutFaults; + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-request.json new file mode 100644 index 000000000..58ff70926 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-request.json @@ -0,0 +1,7 @@ +{ + "ranges": [["1.2.3.1", "1.2.3.10"], ["1.2.3.20", "1.2.3.29"]], + "network": "1.2.3.0", + "prefix": "24", + "order": "random", + "name": "test1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-response.json new file mode 100644 index 000000000..7deed09f9 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_add-response.json @@ -0,0 +1,11 @@ +{ + "network": "1.2.3.0", + "updated_at": null, + "created_at": "2016-11-16T15:50:00.628246+00:00", + "uuid": "dbac9f9d-2d1f-4c48-99d0-77eb9acac856", + "id": 8, + "ranges": [["1.2.3.1", "1.2.3.10"], ["1.2.3.20", "1.2.3.29"]], + "prefix": 24, + "order": "random", + "name": "test1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_list-response.json new file mode 100644 index 000000000..cfed70dc9 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_list-response.json @@ -0,0 +1,65 @@ +{ + "addrpools": [{ + "network": "192.168.204.0", + "name": "management", + "ranges": [["192.168.204.2", + "192.168.204.254"]], + "prefix": 24, + "order": "random", + "uuid": "d7187d17-8715-4934-8754-4827e604a468" + }, + { + "network": "192.168.205.0", + "name": "infrastructure", + "ranges": [["192.168.205.2", + "192.168.205.254"]], + "prefix": 24, + "order": "random", + "uuid": "7b299949-614c-4f1a-85cb-c46a09827f0c" + }, + { + "network": "10.10.10.0", + "name": "oam", + "ranges": [["10.10.10.1", + "10.10.10.254"]], + "prefix": 24, + "order": "random", + "uuid": "c5fced12-40ad-47fa-ad01-6800d1e418b7" + }, + { + "network": "192.168.58.0", + "name": "group0-data1v4", + "ranges": [["192.168.58.2", + "192.168.58.10"]], + "prefix": 24, + "order": "sequential", + "uuid": "15a1fa4e-d1c0-49f8-80d9-484640fb95a0" + }, + { + "network": "fd00:0:0:2::", + "name": "group0-data1v6", + "ranges": [["fd00:0:0:2::2", + "fd00:0:0:2::a"]], + "prefix": 64, + "order": "random", + "uuid": "04ff8781-9042-4602-a19e-7ed90f0979ad" + }, + { + "network": "192.168.57.0", + "name": "group0-data0v4", + "ranges": [["192.168.57.2", + "192.168.57.10"]], + "prefix": 24, + "order": "random", + "uuid": "366e08ac-a5c8-4554-b019-0a0d2d011e6e" + }, + { + "network": "fd00:0:0:1::", + "name": "group0-data0v6", + "ranges": [["fd00:0:0:1::2", + "fd00:0:0:1::a"]], + "prefix": 64, + "order": "sequential", + "uuid": "950a4587-2baf-4075-994a-98189de51acc" + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-request.json new file mode 100644 index 000000000..6d2bd8599 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-request.json @@ -0,0 +1,10 @@ +[{ + "path": "/ranges", + "value": [["192.168.57.2", "192.168.57.11"]], + "op": "replace" +}, +{ + "path": "/name", + "value": "group0-data0v4-modified", + "op": "replace" +}] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-response.json new file mode 100644 index 000000000..e3a3d2098 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_modify-response.json @@ -0,0 +1,11 @@ +{ + "network": "192.168.57.0", + "updated_at": "2016-11-16T15:40:54.855820+00:00", + "created_at": "2016-11-09T15:13:59.652107+00:00", + "uuid": "366e08ac-a5c8-4554-b019-0a0d2d011e6e", + "id": 6, + "ranges": [["192.168.57.2", "192.168.57.10"]], + "prefix": 24, + "order": "random", + "name": "group0-data0v4-modified" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_show-response.json new file mode 100644 index 000000000..fccb60b3a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/addrpool_show-response.json @@ -0,0 +1,12 @@ +{ + "network": "192.168.57.0", + "updated_at": null, + "created_at": "2016-11-09T15:13:59.652107+00:00", + "uuid": "366e08ac-a5c8-4554-b019-0a0d2d011e6e", + "id": 6, + "ranges": [["192.168.57.2", + "192.168.57.10"]], + "prefix": 24, + "order": "random", + "name": "group0-data0v4" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm-response.json new file mode 100755 index 000000000..7749a14b0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm-response.json @@ -0,0 +1,18 @@ +{ + "alarm_state": "set", + "service_affecting": "True", + "proposed_repair_action": "contact next level of support", + "alarm_type": "processing-error", + "severity": "minor", + "created_at": "2014-09-23T00:38:16.797155+00:00", + "entity_type_id": "host", + "probable_cause": "key-expired", + "updated_at": "2014-09-24T00:38:17.403135+00:00", + "alarm_id": "400.003", + "entity_instance_id": "system=big_lab.host=controller-0", + "suppression": "False", + "timestamp": "2014-09-24T00:38:17.400169+00:00", + "uuid": "2a88acd3-e9eb-432e-bc0a-4276e3537a40", + "reason_text": "evaluation license key will exprire on 31-dec-2014", + "mgmt_affecting": "critical" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-request.json new file mode 100644 index 000000000..4aa914e46 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-request.json @@ -0,0 +1 @@ +http://192.168.204.2:6385/v1/ialarms?q.field=severity&q.op=eq&q.type=&q.value=major&include_suppress=True diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-response.json new file mode 100755 index 000000000..b2d425b51 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_list-response.json @@ -0,0 +1,24 @@ +{ + "ialarms":[ + { + "severity":"major", + "timestamp":"2016-05-12T12:11:10.405609", + "uuid":"25d28c97-70e4-45c7-a896-ba8e71a81f26", + "alarm_id":"400.002", + "entity_instance_id":"service_domain=controller.service_group=oam-services", + "suppression_status":"suppressed", + "reason_text":"Service group oam-services loss of redundancy; expected 1 standby member but no standby members available", + "mgmt_affecting": "warning" + }, + { + "severity":"major", + "timestamp":"2016-05-12T12:08:12.850730", + "uuid":"63c94239-2d16-4a30-a910-60198de1c0a8", + "alarm_id":"200.001", + "entity_instance_id":"host=controller-1", + "suppression_status":"unsuppressed", + "reason_text":"controller-1 was administratively locked to take it out-of-service.", + "mgmt_affecting": "warning" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_summary-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_summary-response.json new file mode 100644 index 000000000..5ff4ba7f8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/alarm_summary-response.json @@ -0,0 +1,8 @@ +{ + "status": "OK", + "major": 0, + "warnings": 0, + "system_uuid": "6a314f63-4969-46f8-9221-b69b6b50424c", + "critical": 0, + "minor": 0 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_list-response.json new file mode 100644 index 000000000..a50467806 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_list-response.json @@ -0,0 +1,46 @@ +{ + "ceph_mon": [ + { + "ceph_mon_dev_ctrl0": null, + "ceph_mon_dev_ctrl1": null, + "ceph_mon_gib": 20, + "created_at": "2016-12-08T17:48:06.623435+00:00", + "device_node": null, + "device_path": null, + "hostname": "controller-0", + "links": [ + { + "href": "http://10.10.20.2:6385/v1/ceph_mon/9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "rel": "self" + }, + { + "href": "http://10.10.20.2:6385/ceph_mon/9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "rel": "bookmark" + } + ], + "updated_at": null, + "uuid": "9608cc7f-ace6-4fc7-8eb8-01cfebf6906e" + }, + { + "ceph_mon_dev_ctrl0": null, + "ceph_mon_dev_ctrl1": null, + "ceph_mon_gib": 20, + "created_at": "2016-12-08T19:02:02.359114+00:00", + "device_node": null, + "device_path": null, + "hostname": "controller-1", + "links": [ + { + "href": "http://10.10.20.2:6385/v1/ceph_mon/9c1d1dce-40aa-4c58-bdf2-9715ec870944", + "rel": "self" + }, + { + "href": "http://10.10.20.2:6385/ceph_mon/9c1d1dce-40aa-4c58-bdf2-9715ec870944", + "rel": "bookmark" + } + ], + "updated_at": null, + "uuid": "9c1d1dce-40aa-4c58-bdf2-9715ec870944" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-request.json new file mode 100644 index 000000000..4d1e0d71d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-request.json @@ -0,0 +1,13 @@ +[ + { + "path": "/ceph_mon_gib", + "value": "35", + "op": "replace" + }, + { + "path": "/controller", + "value": "controller-0", + "op": "replace" + } +] + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-response.json new file mode 100644 index 000000000..96da2be1f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_modify-response.json @@ -0,0 +1,21 @@ +{ + "ceph_mon_dev_ctrl1": null, + "uuid": "9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "links": [ + { + "href": "http://10.10.20.2:6385/v1/ceph_mon/9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "rel": "self" + }, + { + "href": "http://10.10.20.2:6385/ceph_mon/9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "rel": "bookmark" + } + ], + "ceph_mon_gib": 35, + "created_at": "2016-12-08T17:48:06.623435+00:00", + "hostname": "controller-0", + "updated_at": null, + "device_node": null, + "device_path": null, + "ceph_mon_dev_ctrl0": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_show-response.json new file mode 100644 index 000000000..b5b2f5f47 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ceph_mon_show-response.json @@ -0,0 +1,21 @@ +{ + "ceph_mon_dev_ctrl0": null, + "ceph_mon_dev_ctrl1": null, + "ceph_mon_gib": 20, + "created_at": "2016-12-08T17:48:06.623435+00:00", + "device_node": null, + "device_path": null, + "hostname": "controller-0", + "links": [ + { + "href": "http://10.10.20.2:6385/v1/ceph_mon/9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "rel": "self" + }, + { + "href": "http://10.10.20.2:6385/ceph_mon/9608cc7f-ace6-4fc7-8eb8-01cfebf6906e", + "rel": "bookmark" + } + ], + "updated_at": null, + "uuid": "9608cc7f-ace6-4fc7-8eb8-01cfebf6906e" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certconfig_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certconfig_show-response.json new file mode 100644 index 000000000..d0f0e2f38 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certconfig_show-response.json @@ -0,0 +1,8 @@ +{ + "uuid": "ada8f12c-0ab2-49b7-bad9-946e34cedd69", + "certtype": "ssl", + "expiry_date": "2018-03-27T18:15:23+00:00", + "signature": "ssl_14615813356245445293", + "start_date": "2017-03-27T18:15:23+00:00", + "issuer": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certificate_install-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certificate_install-request.json new file mode 100644 index 000000000..53223c36e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/certificate_install-request.json @@ -0,0 +1 @@ +file=@/home/wrsroot/server-with-key.pem diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_list-response.json new file mode 100644 index 000000000..74ce63447 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_list-response.json @@ -0,0 +1,20 @@ +{ + "clusters": [ + { + "cluster_uuid": null, + "type": "ceph", + "uuid": "ba42aa45-7094-4bcd-b094-2848816441a3", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/clusters/ba42aa45-7094-4bcd-b094-2848816441a3", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/clusters/ba42aa45-7094-4bcd-b094-2848816441a3", + "rel": "bookmark" + } + ], + "name": "ceph_cluster" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_show-response.json new file mode 100644 index 000000000..f5aeb2558 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cluster_show-response.json @@ -0,0 +1,46 @@ +{ + "peers": [ + { + "status": "provisioned", + "hosts": [ + "storage-0" + ], + "name": "group-0", + "uuid": "779145f1-f0ba-42a9-b371-c2ddbd2c3617" + } + ], + "name": "ceph_cluster", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/clusters/ba42aa45-7094-4bcd-b094-2848816441a3", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/clusters/ba42aa45-7094-4bcd-b094-2848816441a3", + "rel": "bookmark" + } + ], + "storage_tiers": [ + { + "href": "http://10.10.10.2:6385/v1/clusters/ba42aa45-7094-4bcd-b094-2848816441a3/storage_tiers", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/clusters/ba42aa45-7094-4bcd-b094-2848816441a3/storage_tiers", + "rel": "bookmark" + } + ], + "created_at": "2018-02-07T04:34:26.738705+00:00", + "tiers": [ + { + "status": "in-use", + "name": "storage", + "uuid": "70184946-7b3e-4833-a4f8-e46edf006e37" + } + ], + "updated_at": null, + "cluster_uuid": null, + "type": "ceph", + "id": 1, + "uuid": "ba42aa45-7094-4bcd-b094-2848816441a3" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-request.json new file mode 100644 index 000000000..cec5dec33 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-request.json @@ -0,0 +1,3 @@ +{ + "community": "guest" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-response.json new file mode 100644 index 000000000..4328e7449 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_add-response.json @@ -0,0 +1,9 @@ +{ + "uuid": "73706882-9d7c-4a8f-9409-185ffee0066c", + "created_at": "2014-09-24T20:06:54.386982+00:00", + "updated_at": null, + "community": "guest", + "access": "ro", + "view": ".1" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_list-response.json new file mode 100644 index 000000000..2cb8f9161 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_list-response.json @@ -0,0 +1,16 @@ +{ + "icommunity": [ + { + "access": "ro", + "uuid": "744cddaa-8a24-4573-aa0e-4f8b535d95b7", + "community": "new", + "view": ".1" + }, + { + "access": "ro", + "uuid": "73706882-9d7c-4a8f-9409-185ffee0066c", + "community": "guest", + "view": ".1" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-request.json new file mode 100644 index 000000000..9fdb6f423 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/community", + "value": "wrs", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-response.json new file mode 100644 index 000000000..3169baa4d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_modify-response.json @@ -0,0 +1,8 @@ +{ + "uuid": "744cddaa-8a24-4573-aa0e-4f8b535d95b7", + "created_at": "2014-09-23T15:01:53.187164+00:00", + "updated_at": "2014-09-24T19:46:40.138145+00:00", + "community": "wrs", + "access": "ro", + "view": ".1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_show-response.json new file mode 100644 index 000000000..ee5abeb62 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/community_show-response.json @@ -0,0 +1,8 @@ +{ + "uuid": "73706882-9d7c-4a8f-9409-185ffee0066c", + "created_at": "2014-09-24T20:06:54.386982+00:00", + "updated_at": null, + "community": "guest", + "access": "ro", + "view": ".1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_list-response.json new file mode 100755 index 000000000..669fab961 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_list-response.json @@ -0,0 +1,71 @@ +{"controller_fs": +[ + { + "logical_volume": "backup-lv", + "uuid": "3ce46550-4703-4161-b654-5573045546b3", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/3ce46550-4703-4161-b654-5573045546b3", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/3ce46550-4703-4161-b654-5573045546b3", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.853307+00:00", + "updated_at": "2017-09-15T15:18:38.006260+00:00", + "name": "backup", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, "size": 92 + }, + { + "logical_volume": "cgcs-lv", + "uuid": "d30cc018-9218-403e-a1c2-9a5691a8bffb", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/d30cc018-9218-403e-a1c2-9a5691a8bffb", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/d30cc018-9218-403e-a1c2-9a5691a8bffb", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.896408+00:00", + "updated_at": "2017-09-14T20:59:53.114344+00:00", + "name": "cgcs", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": true, + "size": 36}, + { + "logical_volume": "pgsql-lv", + "uuid": "d5fd96f5-05c2-4d4c-b2b7-a46d7b0eb6e7", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/d5fd96f5-05c2-4d4c-b2b7-a46d7b0eb6e7", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/d5fd96f5-05c2-4d4c-b2b7-a46d7b0eb6e7", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.955574+00:00", + "updated_at": "2017-09-14T20:50:53.032463+00:00", + "name": "database", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": true, + "size": 30}, + { + "logical_volume": "scratch-lv", + "uuid": "a12de715-0037-4083-b652-121d3908bc6c", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/a12de715-0037-4083-b652-121d3908bc6c", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/a12de715-0037-4083-b652-121d3908bc6c", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:16.012491+00:00", + "updated_at": "2017-09-14T18:35:51.859954+00:00", + "name": "scratch", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, + "size": 8}, + { + "logical_volume": "img-conversions-lv", + "uuid": "f7bae4fe-3cd1-4335-8664-a149579b2b47", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/f7bae4fe-3cd1-4335-8664-a149579b2b47", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/f7bae4fe-3cd1-4335-8664-a149579b2b47", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:16.050789+00:00", + "updated_at": "2017-09-14T18:35:51.876670+00:00", + "name": "img-conversions", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, "size": 20 + }, + { + "logical_volume": "extension-lv", + "uuid": "320dc274-1e35-4700-bfaa-cee2f2d448c5", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/320dc274-1e35-4700-bfaa-cee2f2d448c5", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/320dc274-1e35-4700-bfaa-cee2f2d448c5", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:16.090570+00:00", + "updated_at": "2017-09-14T18:35:51.893766+00:00", + "name": "extension", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": true, + "size": 1 + } +] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-request.json new file mode 100644 index 000000000..ef07b6fa3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-request.json @@ -0,0 +1,11 @@ +[ + { + "path": "/name", + "value": "backup", + "op": "replace"}, + { + "path": "/size", + "value": "94", + "op": "replace" + } +] \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-response.json new file mode 100644 index 000000000..b01f204b8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify-response.json @@ -0,0 +1,14 @@ +{ + "logical_volume": "backup-lv", + "uuid": "3ce46550-4703-4161-b654-5573045546b3", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/3ce46550-4703-4161-b654-5573045546b3", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/3ce46550-4703-4161-b654-5573045546b3", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.853307+00:00", + "updated_at": "2017-09-15T15:18:38.006260+00:00", + "name": "backup", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, + "forisystemid": 1, + "size": 94 +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify_multi-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify_multi-request.json new file mode 100644 index 000000000..8ad66c370 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_modify_multi-request.json @@ -0,0 +1,18 @@ +[ + [{ + "path": "/name", + "value": "extension", + "op": "replace"}, + { + "path": "/size", + "value": "2", + "op": "replace"}], + [{ + "path": "/name", + "value": "backup", + "op": "replace"}, + { + "path": "/size", + "value": "6", + "op": "replace"}] +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_show-response.json new file mode 100644 index 000000000..c927c21d9 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/controller_fs_show-response.json @@ -0,0 +1,72 @@ +{ + "controller_fs": + [ + { + "logical_volume": "backup-lv", + "uuid": "3ce46550-4703-4161-b654-5573045546b3", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/3ce46550-4703-4161-b654-5573045546b3", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/3ce46550-4703-4161-b654-5573045546b3", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.853307+00:00", + "updated_at": "2017-09-15T15:36:32.304443+00:00", + "name": "backup", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, + "size": 94}, + { + "logical_volume": "cgcs-lv", + "uuid": "d30cc018-9218-403e-a1c2-9a5691a8bffb", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/d30cc018-9218-403e-a1c2-9a5691a8bffb", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/d30cc018-9218-403e-a1c2-9a5691a8bffb", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.896408+00:00", + "updated_at": "2017-09-14T20:59:53.114344+00:00", + "name": "cgcs", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": true, + "size": 36 + }, + { + "logical_volume": "pgsql-lv", + "uuid": "d5fd96f5-05c2-4d4c-b2b7-a46d7b0eb6e7", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/d5fd96f5-05c2-4d4c-b2b7-a46d7b0eb6e7", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/d5fd96f5-05c2-4d4c-b2b7-a46d7b0eb6e7", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:15.955574+00:00", + "updated_at": "2017-09-14T20:50:53.032463+00:00", + "name": "database", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": true, + "size": 30 + }, + { + "logical_volume": "scratch-lv", + "uuid": "a12de715-0037-4083-b652-121d3908bc6c", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/a12de715-0037-4083-b652-121d3908bc6c", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/a12de715-0037-4083-b652-121d3908bc6c", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:16.012491+00:00", + "updated_at": "2017-09-14T18:35:51.859954+00:00", + "name": "scratch", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, + "size": 8}, + { + "logical_volume": "img-conversions-lv", + "uuid": "f7bae4fe-3cd1-4335-8664-a149579b2b47", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/f7bae4fe-3cd1-4335-8664-a149579b2b47", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/f7bae4fe-3cd1-4335-8664-a149579b2b47", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:16.050789+00:00", + "updated_at": "2017-09-14T18:35:51.876670+00:00", + "name": "img-conversions", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": false, "size": 20}, + { + "logical_volume": "extension-lv", + "uuid": "320dc274-1e35-4700-bfaa-cee2f2d448c5", + "links": [{"href": "http://127.168.204.2:6385/v1/controller_fs/320dc274-1e35-4700-bfaa-cee2f2d448c5", "rel": "self"}, {"href": "http://127.168.204.2:6385/controller_fs/320dc274-1e35-4700-bfaa-cee2f2d448c5", "rel": "bookmark"}], + "created_at": "2017-09-14T17:54:16.090570+00:00", + "updated_at": "2017-09-14T18:35:51.893766+00:00", + "name": "extension", + "state": "available", + "isystem_uuid": "a5b7f26c-423f-41ed-a660-cd8cff4627eb", + "replicated": true, + "size": 1} + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_list-response.json new file mode 100644 index 000000000..f352e6cc8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_list-response.json @@ -0,0 +1,57 @@ +{ + "icpus" : [ + { + "core" : 0, + "allocated_function" : "Platform", + "cpu" : 0, + "numa_node" : 0, + "uuid" : "d269a009-de03-463e-a553-10944361d38b", + "cpu_family" : "6", + "ihost_uuid" : "0aca08f9-882f-4491-8ffd-7368d20ead48", + "thread" : 0, + "created_at" : "2014-09-18T03:12:15.429976+00:00", + "cpu_model" : "Intel(R) Xeon(R) CPU E5-2690 0 @ 2.90GHz", + "updated_at" : null, + "capabilities" : {}, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.243:6385/v1/icpus/d269a009-de03-463e-a553-10944361d38b" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:6385/icpus/d269a009-de03-463e-a553-10944361d38b" + } + ], + "inode_uuid" : "e5d68519-eb07-4b28-8ca2-32bb476eeec1" + }, + { + "core" : 1, + "allocated_function" : "Vswitch", + "cpu" : 1, + "numa_node" : 0, + "uuid" : "f236a371-48e9-4618-8f02-3a7ea0c2d16e", + "cpu_family" : "6", + "ihost_uuid" : "0aca08f9-882f-4491-8ffd-7368d20ead48", + "thread" : 0, + "created_at" : "2014-09-18T03:12:15.432471+00:00", + "cpu_model" : "Intel(R) Xeon(R) CPU E5-2690 0 @ 2.90GHz", + "updated_at" : null, + "capabilities" : {}, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.243:6385/v1/icpus/f236a371-48e9-4618-8f02-3a7ea0c2d16e" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:6385/icpus/f236a371-48e9-4618-8f02-3a7ea0c2d16e" + } + ], + "inode_uuid" : "e5d68519-eb07-4b28-8ca2-32bb476eeec1" + }, + +... + + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request-platform.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request-platform.json new file mode 100644 index 000000000..a098a35d5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request-platform.json @@ -0,0 +1,6 @@ +[ + { + "function": "platform", + "sockets": [{"0": 1}, {"1": 1}], + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request.json new file mode 100644 index 000000000..72cef6d8a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-request.json @@ -0,0 +1,6 @@ +[ + { + "function": "vswitch", + "sockets": [{"0": 1}] + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-response.json new file mode 100644 index 000000000..3951e8dc7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_modify-response.json @@ -0,0 +1,32 @@ +{ + "allocated_function": "VMs", + "core": 7, + "thread": 0, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/icpus/8a960696-c242-436f-a79c-d904fa6dcbd2", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/icpus/8a960696-c242-436f-a79c-d904fa6dcbd2", + "rel": "bookmark" + } + ], + "inode_uuid": "4ed560e2-c3a1-4d41-8b00-6af257e6ac75", + "function": null, + "numa_node": 1, + "created_at": "2014-09-26T02:01:36.514217+00:00", + "cpu_model": "Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz", + "capabilities": { + + }, + "updated_at": "2014-09-26T11:58:20.586235+00:00", + "num_cores_on_processor1": null, + "ihost_uuid": "22d5827c-7a04-4a3c-9509-e8849b9a595d", + "num_cores_on_processor3": null, + "num_cores_on_processor2": null, + "num_cores_on_processor0": null, + "cpu_family": "6", + "cpu": 15, + "uuid": "8a960696-c242-436f-a79c-d904fa6dcbd2" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_show-response.json new file mode 100644 index 000000000..493a2e644 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/cpu_show-response.json @@ -0,0 +1,30 @@ +{ + "core" : 0, + "allocated_function" : "Platform", + "function" : null, + "uuid" : "d269a009-de03-463e-a553-10944361d38b", + "cpu_family" : "6", + "ihost_uuid" : "0aca08f9-882f-4491-8ffd-7368d20ead48", + "created_at" : "2014-09-18T03:12:15.429976+00:00", + "num_cores_on_processor1" : null, + "capabilities" : {}, + "num_cores_on_processor3" : null, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.243:6385/v1/icpus/d269a009-de03-463e-a553-10944361d38b" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:6385/icpus/d269a009-de03-463e-a553-10944361d38b" + } + ], + "num_cores_on_processor2" : null, + "cpu" : 0, + "numa_node" : 0, + "num_cores_on_processor0" : null, + "thread" : 0, + "cpu_model" : "Intel(R) Xeon(R) CPU E5-2690 0 @ 2.90GHz", + "updated_at" : null, + "inode_uuid" : "e5d68519-eb07-4b28-8ca2-32bb476eeec1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_list-response.json new file mode 100644 index 000000000..836966e21 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_list-response.json @@ -0,0 +1,388 @@ +{ + "pci_devices": [ + { + "uuid": "b2b411a8-1522-4d22-9679-e9fb8b24813b", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "440FX - 82441FX PMC [Natoma]", + "created_at": "2015-11-02T02:15:23.608001+00:00", + "sriov_totalvfs": null, + "pdevice_id": "1237", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/b2b411a8-1522-4d22-9679-e9fb8b24813b", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/b2b411a8-1522-4d22-9679-e9fb8b24813b", + "rel": "bookmark" + } + ], + "pclass": "Host bridge", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:00.0", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "60000", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_00_0" + }, + { + "uuid": "49139dd2-3e46-4056-b91d-c7d5cb453524", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "82371SB PIIX3 ISA [Natoma\/Triton II]", + "created_at": "2015-11-02T02:15:23.615088+00:00", + "sriov_totalvfs": null, + "pdevice_id": "7000", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/49139dd2-3e46-4056-b91d-c7d5cb453524", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/49139dd2-3e46-4056-b91d-c7d5cb453524", + "rel": "bookmark" + } + ], + "pclass": "ISA bridge", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:01.0", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "60100", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_01_0" + }, + { + "uuid": "4a11043c-c1fe-463f-ab13-01e0b6c12376", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "82371AB\/EB\/MB PIIX4 IDE", + "created_at": "2015-11-02T02:15:23.620579+00:00", + "sriov_totalvfs": null, + "pdevice_id": "7111", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/4a11043c-c1fe-463f-ab13-01e0b6c12376", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/4a11043c-c1fe-463f-ab13-01e0b6c12376", + "rel": "bookmark" + } + ], + "pclass": "IDE interface", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:01.1", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "1018a", + "driver": null, + "psvendor": "-p8a", + "enabled": "False", + "name": "pci_0000_00_01_1" + }, + { + "uuid": "09746d46-9ca9-4ef4-a7a4-0fa46c2a9165", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "VirtualBox Graphics Adapter", + "created_at": "2015-11-02T02:15:23.627342+00:00", + "sriov_totalvfs": null, + "pdevice_id": "beef", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/09746d46-9ca9-4ef4-a7a4-0fa46c2a9165", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/09746d46-9ca9-4ef4-a7a4-0fa46c2a9165", + "rel": "bookmark" + } + ], + "pclass": "VGA compatible controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "InnoTek Systemberatung GmbH", + "pciaddr": "0000:00:02.0", + "numa_node": -1, + "pvendor_id": "80ee", + "pclass_id": "30000", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_02_0" + }, + { + "uuid": "56686ced-6dd7-445a-aed9-6ff7399b322e", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "82540EM Gigabit Ethernet Controller", + "created_at": "2015-11-02T02:15:23.632929+00:00", + "sriov_totalvfs": null, + "pdevice_id": "100e", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/56686ced-6dd7-445a-aed9-6ff7399b322e", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/56686ced-6dd7-445a-aed9-6ff7399b322e", + "rel": "bookmark" + } + ], + "pclass": "Ethernet controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "PRO\/1000 MT Desktop Adapter", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:03.0", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "20000", + "driver": null, + "psvendor": "Intel Corporation", + "enabled": "False", + "name": "pci_0000_00_03_0" + }, + { + "uuid": "93c27653-7858-4025-babf-e72e4b1ba45e", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "VirtualBox Guest Service", + "created_at": "2015-11-02T02:15:23.639261+00:00", + "sriov_totalvfs": null, + "pdevice_id": "cafe", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/93c27653-7858-4025-babf-e72e4b1ba45e", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/93c27653-7858-4025-babf-e72e4b1ba45e", + "rel": "bookmark" + } + ], + "pclass": "System peripheral", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "InnoTek Systemberatung GmbH", + "pciaddr": "0000:00:04.0", + "numa_node": -1, + "pvendor_id": "80ee", + "pclass_id": "88000", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_04_0" + }, + { + "uuid": "c67c2c89-fc01-4bc7-97a8-d913f5623b7e", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "KeyLargo\/Intrepid USB", + "created_at": "2015-11-02T02:15:23.644716+00:00", + "sriov_totalvfs": null, + "pdevice_id": "3f", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/c67c2c89-fc01-4bc7-97a8-d913f5623b7e", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/c67c2c89-fc01-4bc7-97a8-d913f5623b7e", + "rel": "bookmark" + } + ], + "pclass": "USB controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "Apple Inc.", + "pciaddr": "0000:00:06.0", + "numa_node": -1, + "pvendor_id": "106b", + "pclass_id": "c0310", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_06_0" + }, + { + "uuid": "a769a7d0-c32f-4072-ba2e-73b754361ac6", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "82371AB\/EB\/MB PIIX4 ACPI", + "created_at": "2015-11-02T02:15:23.651222+00:00", + "sriov_totalvfs": null, + "pdevice_id": "7113", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/a769a7d0-c32f-4072-ba2e-73b754361ac6", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/a769a7d0-c32f-4072-ba2e-73b754361ac6", + "rel": "bookmark" + } + ], + "pclass": "Bridge", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:07.0", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "68000", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_07_0" + }, + { + "uuid": "40fc39e7-d6bb-4ae5-9c98-0e7a0c71dc6f", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "82540EM Gigabit Ethernet Controller", + "created_at": "2015-11-02T02:15:23.657036+00:00", + "sriov_totalvfs": null, + "pdevice_id": "100e", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/40fc39e7-d6bb-4ae5-9c98-0e7a0c71dc6f", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/40fc39e7-d6bb-4ae5-9c98-0e7a0c71dc6f", + "rel": "bookmark" + } + ], + "pclass": "Ethernet controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "PRO\/1000 MT Desktop Adapter", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:08.0", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "20000", + "driver": null, + "psvendor": "Intel Corporation", + "enabled": "False", + "name": "pci_0000_00_08_0" + }, + { + "uuid": "a674ae59-aa08-4bef-85a5-ad209809725d", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "Virtio network device", + "created_at": "2015-11-02T02:15:23.662643+00:00", + "sriov_totalvfs": null, + "pdevice_id": "1000", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/a674ae59-aa08-4bef-85a5-ad209809725d", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/a674ae59-aa08-4bef-85a5-ad209809725d", + "rel": "bookmark" + } + ], + "pclass": "Ethernet controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "Device 0001", + "sriov_vfs_pci_address": "", + "pvendor": "Red Hat, Inc", + "pciaddr": "0000:00:09.0", + "numa_node": -1, + "pvendor_id": "1af4", + "pclass_id": "20000", + "driver": null, + "psvendor": "Red Hat, Inc", + "enabled": "False", + "name": "pci_0000_00_09_0" + }, + { + "uuid": "67d75625-12a6-48ca-8e93-40a704eb7bf7", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "Virtio network device", + "created_at": "2015-11-02T02:15:23.668183+00:00", + "sriov_totalvfs": null, + "pdevice_id": "1000", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/67d75625-12a6-48ca-8e93-40a704eb7bf7", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/67d75625-12a6-48ca-8e93-40a704eb7bf7", + "rel": "bookmark" + } + ], + "pclass": "Ethernet controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "Device 0001", + "sriov_vfs_pci_address": "", + "pvendor": "Red Hat, Inc", + "pciaddr": "0000:00:0a.0", + "numa_node": -1, + "pvendor_id": "1af4", + "pclass_id": "20000", + "driver": null, + "psvendor": "Red Hat, Inc", + "enabled": "False", + "name": "pci_0000_00_0a_0" + }, + { + "uuid": "4b1d9cf8-81bd-40cb-b873-594faa9d23ef", + "sriov_numvfs": 0, + "updated_at": null, + "pdevice": "82801FB\/FBM\/FR\/FW\/FRW (ICH6 Family) USB2 EHCI Controller", + "created_at": "2015-11-02T02:15:23.673775+00:00", + "sriov_totalvfs": null, + "pdevice_id": "265c", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/4b1d9cf8-81bd-40cb-b873-594faa9d23ef", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/4b1d9cf8-81bd-40cb-b873-594faa9d23ef", + "rel": "bookmark" + } + ], + "pclass": "USB controller", + "host_uuid": "ae8d3ec5-b2e1-425d-a73f-d7c7b00551fd", + "psdevice": "", + "sriov_vfs_pci_address": "", + "pvendor": "Intel Corporation", + "pciaddr": "0000:00:0b.0", + "numa_node": -1, + "pvendor_id": "8086", + "pclass_id": "c0320", + "driver": null, + "psvendor": "", + "enabled": "False", + "name": "pci_0000_00_0b_0" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-request.json new file mode 100644 index 000000000..89676fdff --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-request.json @@ -0,0 +1,12 @@ +[ + { + "path": "/enabled", + "value": "True", + "op": "replace" + }, + { + "path": "/name", + "value": "pci_0000_09_00_0", + "op": "replace" + } +] \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-response.json new file mode 100644 index 000000000..66753970a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_modify-response.json @@ -0,0 +1,33 @@ +{ + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/8fdab3b1-c90a-421b-ba5f-5dc2d677dac6", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/8fdab3b1-c90a-421b-ba5f-5dc2d677dac6", + "rel": "bookmark" + } + ], + "enabled": "True", + "updated_at": "2015-11-04T18:48:09.051858+00:00", + "extra_info": null, + "uuid": "8fdab3b1-c90a-421b-ba5f-5dc2d677dac6", + "pdevice": "Coleto Creek PCIe Endpoint", + "psvendor": "Intel Corporation", + "psdevice": "Device 35c5", + "pclass_id": "b4000", + "pvendor": "Intel Corporation", + "sriov_numvfs": 32, + "driver": null, + "host_uuid": "aa3fabca-e007-485b-bea9-4f1a0ad9049a", + "name": "pci_0000_09_00_0", + "numa_node": 0, + "created_at": "2015-11-04T04:22:59.406921+00:00", + "pdevice_id": "435", + "pclass": "Co-processor", + "sriov_vfs_pci_address": "0000:09:01.0,0000:09:01.1,0000:09:01.2,0000:09:01.3,0000:09:01.4,0000:09:01.5,0000:09:01.6,0000:09:01.7,0000:09:02.0,0000:09:02.1,0000:09:02.2,0000:09:02.3,0000:09:02.4,0000:09:02.5,0000:09:02.6,0000:09:02.7,0000:09:03.0,0000:09:03.1,0000:09:03.2,0000:09:03.3,0000:09:03.4,0000:09:03.5,0000:09:03.6,0000:09:03.7,0000:09:04.0,0000:09:04.1,0000:09:04.2,0000:09:04.3,0000:09:04.4,0000:09:04.5,0000:09:04.6,0000:09:04.7", + "sriov_totalvfs": 32, + "pciaddr": "0000:09:00.0", + "pvendor_id": "8086" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_show-response.json new file mode 100644 index 000000000..c07639e1f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/device_show-response.json @@ -0,0 +1,32 @@ +{ + "uuid": "8fdab3b1-c90a-421b-ba5f-5dc2d677dac6", + "sriov_numvfs": 32, + "updated_at": "2015-11-04T18:48:09.051858+00:00", + "pdevice": "Coleto Creek PCIe Endpoint", + "created_at": "2015-11-04T04:22:59.406921+00:00", + "sriov_totalvfs": 32, + "pdevice_id": "435", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/pci_devices\/8fdab3b1-c90a-421b-ba5f-5dc2d677dac6", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/pci_devices\/8fdab3b1-c90a-421b-ba5f-5dc2d677dac6", + "rel": "bookmark" + } + ], + "pclass": "Co-processor", + "host_uuid": "aa3fabca-e007-485b-bea9-4f1a0ad9049a", + "psdevice": "Device 35c5", + "sriov_vfs_pci_address": "0000:09:01.0,0000:09:01.1,0000:09:01.2,0000:09:01.3,0000:09:01.4,0000:09:01.5,0000:09:01.6,0000:09:01.7,0000:09:02.0,0000:09:02.1,0000:09:02.2,0000:09:02.3,0000:09:02.4,0000:09:02.5,0000:09:02.6,0000:09:02.7,0000:09:03.0,0000:09:03.1,0000:09:03.2,0000:09:03.3,0000:09:03.4,0000:09:03.5,0000:09:03.6,0000:09:03.7,0000:09:04.0,0000:09:04.1,0000:09:04.2,0000:09:04.3,0000:09:04.4,0000:09:04.5,0000:09:04.6,0000:09:04.7", + "pvendor": "Intel Corporation", + "pciaddr": "0000:09:00.0", + "numa_node": 0, + "pvendor_id": "8086", + "pclass_id": "b4000", + "driver": null, + "psvendor": "Intel Corporation", + "enabled": "True", + "name": "pci_0000_09_00_0" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_list-response.json new file mode 100644 index 000000000..e22354d7d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_list-response.json @@ -0,0 +1,67 @@ +{ + "idisks": [ + { + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-1.0", + "uuid": "8352385e-b13b-488c-abca-f38db6a5e234", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/idisks/8352385e-b13b-488c-abca-f38db6a5e234", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/idisks/8352385e-b13b-488c-abca-f38db6a5e234", + "rel": "bookmark" + } + ], + "ihost_uuid": "422f7a16-90b7-49b9-856e-e7a2527e3da1", + "created_at": "2018-02-06T07:04:49.098057+00:00", + "updated_at": "2018-02-06T08:44:03.928696+00:00", + "device_node": "/dev/sda", + "available_mib": 0, + "ipv_uuid": null, + "serial_id": "VB7f149a22-bb415a22", + "device_type": "HDD", + "device_wwn": null, + "istor_uuid": null, + "device_num": 2048, + "capabilities": { + "model_num": "VBOX HARDDISK", + "stor_function": "rootfs" + }, + "rpm": "Undetermined", + "size_mib": 61440, + "device_id": "ata-VBOX_HARDDISK_VB7f149a22-bb415a22" + }, + { + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0", + "uuid": "0612ae5a-4b16-47a4-bb2b-d2776e6c0959", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/idisks/0612ae5a-4b16-47a4-bb2b-d2776e6c0959", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/idisks/0612ae5a-4b16-47a4-bb2b-d2776e6c0959", + "rel": "bookmark" + } + ], + "ihost_uuid": "422f7a16-90b7-49b9-856e-e7a2527e3da1", + "created_at": "2018-02-06T07:04:49.127350+00:00", + "updated_at": "2018-02-06T08:44:03.987878+00:00", + "device_node": "/dev/sdb", + "available_mib": 51197, + "ipv_uuid": null, + "serial_id": "VBa3c3ba49-6d2fb877", + "device_type": "HDD", + "device_wwn": null, + "istor_uuid": null, + "device_num": 2064, + "capabilities": { + "model_num": "VBOX HARDDISK" + }, + "rpm": "Undetermined", + "size_mib": 61440, + "device_id": "ata-VBOX_HARDDISK_VBa3c3ba49-6d2fb877" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_modify-request.json new file mode 100644 index 000000000..a232ebab3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/partition_table", + "value": "gpt", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_show-response.json new file mode 100644 index 000000000..11c9ddafa --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/disk_show-response.json @@ -0,0 +1,42 @@ +{ + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-1.0", + "uuid": "8352385e-b13b-488c-abca-f38db6a5e234", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/idisks/8352385e-b13b-488c-abca-f38db6a5e234", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/idisks/8352385e-b13b-488c-abca-f38db6a5e234", + "rel": "bookmark" + } + ], + "ihost_uuid": "422f7a16-90b7-49b9-856e-e7a2527e3da1", + "partitions": [ + { + "href": "http://10.10.10.2:6385/v1/idisks/8352385e-b13b-488c-abca-f38db6a5e234/partitions", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/idisks/8352385e-b13b-488c-abca-f38db6a5e234/partitions", + "rel": "bookmark" + } + ], + "updated_at": "2018-02-06T08:45:03.851208+00:00", + "device_node": "/dev/sda", + "available_mib": 0, + "ipv_uuid": null, + "serial_id": "VB7f149a22-bb415a22", + "device_type": "HDD", + "device_wwn": null, + "istor_uuid": null, + "device_num": 2048, + "capabilities": { + "model_num": "VBOX HARDDISK", + "stor_function": "rootfs" + }, + "rpm": "Undetermined", + "created_at": "2018-02-06T07:04:49.098057+00:00", + "size_mib": 61440, + "device_id": "ata-VBOX_HARDDISK_VB7f149a22-bb415a22" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-request.json new file mode 100644 index 000000000..080dac5e1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-request.json @@ -0,0 +1,12 @@ +[ + { + "path": "/nameservers", + "value": "8.8.8.99,8.8.4.99", + "op": "replace" + }, + { + "path": "/action", + "value": "apply", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-response.json new file mode 100644 index 000000000..96e23d162 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_modify-response.json @@ -0,0 +1,19 @@ +{ + "links": [ + { + "href": "http://192.168.204.2:6385/v1/idnss/fab4ff99-ed44-41d0-9e04-2efb3138cf03", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/idnss/fab4ff99-ed44-41d0-9e04-2efb3138cf03", + "rel": "bookmark" + } + ], + "nameservers": "8.8.8.99,8.8.4.99", + "created_at": "2014-09-30T14:42:16.676726+00:00", + "updated_at": "2014-10-01T15:13:42.356658+00:00", + "isystem_uuid": "ce178041-2b2c-405d-bf87-f19334a35582", + "action": null, + "forisystemid": 1, + "uuid": "fab4ff99-ed44-41d0-9e04-2efb3138cf03" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_show-response.json new file mode 100644 index 000000000..0ba8807ba --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/dns_show-response.json @@ -0,0 +1,21 @@ +{ + "idnss": [ + { + "links": [ + { + "href": "http://192.168.204.2:6385/v1/idnss/fab4ff99-ed44-41d0-9e04-2efb3138cf03", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/idnss/fab4ff99-ed44-41d0-9e04-2efb3138cf03", + "rel": "bookmark" + } + ], + "nameservers": "8.8.8.4,8.8.4.5", + "created_at": "2014-09-30T14:42:16.676726+00:00", + "updated_at": "2014-10-01T15:10:42.328364+00:00", + "isystem_uuid": "ce178041-2b2c-405d-bf87-f19334a35582", + "uuid": "fab4ff99-ed44-41d0-9e04-2efb3138cf03" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-request.json new file mode 100644 index 000000000..684d2234c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-request.json @@ -0,0 +1,17 @@ +[ + { + "op": "replace", + "path": "/link_util", + "value": "40" + }, + { + "op": "replace", + "path": "/rtt_ms", + "value": "0.2" + }, + { + "op": "replace", + "path": "/action", + "value": "apply" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-response.json new file mode 100644 index 000000000..4ac867d5c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_modify-response.json @@ -0,0 +1,21 @@ +{ + "action": null, + "created_at": "2015-12-14T21:20:23.329867+00:00", + "forisystemid": 1, + "isystem_uuid": "88770f18-1ade-4222-b08f-dadd8aa78b32", + "link_util": 40, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/drbdconfigs/e23b99b4-62b3-4bcc-a78b-ece63bc0edc5", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/drbdconfigs/e23b99b4-62b3-4bcc-a78b-ece63bc0edc5", + "rel": "bookmark" + } + ], + "num_parallel": 1, + "rtt_ms": 0.2, + "updated_at": "2015-12-14T21:20:26.792494+00:00", + "uuid": "e23b99b4-62b3-4bcc-a78b-ece63bc0edc5" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_show-response.json new file mode 100644 index 000000000..ea1e52290 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/drbdsync_show-response.json @@ -0,0 +1,23 @@ +{ + "drbdconfigs": [ + { + "created_at": "2015-12-14T21:20:23.329867+00:00", + "isystem_uuid": "88770f18-1ade-4222-b08f-dadd8aa78b32", + "link_util": 40, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/drbdconfigs/e23b99b4-62b3-4bcc-a78b-ece63bc0edc5", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/drbdconfigs/e23b99b4-62b3-4bcc-a78b-ece63bc0edc5", + "rel": "bookmark" + } + ], + "num_parallel": 1, + "rtt_ms": 0.2, + "updated_at": "2015-12-14T22:15:03.909772+00:00", + "uuid": "e23b99b4-62b3-4bcc-a78b-ece63bc0edc5" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-request.json new file mode 100644 index 000000000..f779ac846 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-request.json @@ -0,0 +1 @@ +http://192.168.204.2:6385/v1/event_log?q.field=start&q.field=end&q.op=eq&q.op=eq&q.type=&q.type=&q.value=2014-11-28T16%3A56%3A44&q.value=2014-11-28T16%3A56%3A45&limit=2 diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-response.json new file mode 100644 index 000000000..6c6458ca5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_list-response.json @@ -0,0 +1,23 @@ +{ + "event_log": [ + { + "severity": "critical", + "timestamp": "2014-11-28T16:56:44.814747", + "uuid": "67f88971-d769-450e-9e8a-126dd8585187", + "event_log_id": "400.005", + "entity_instance_id": "host=controller-0.network=mgmt", + "reason_text": "Communication failure detected with peer over port eth1 on host controller-0", + "state": "log" + }, + { + "severity": "major", + "timestamp": "2014-11-28T16:56:44.808965", + "uuid": "1a259ab9-8ea2-4177-8053-ad7596509c66", + "log_id": "400.002", + "entity_instance_id": "service_domain=controller.service_group=cloud-services", + "reason_text": "Service group cloud-services loss of redundancy; expected 1 standby member but no standby members available", + "state": "set" + }], + "next": "http://192.168.204.2:6385/v1/event_log?sort_key=timestamp&sort_dir=desc&limit=2&marker=1a259ab9-8ea2-4177-8053-ad7596509c66" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_show-response.json new file mode 100644 index 000000000..9a53573f6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_log_show-response.json @@ -0,0 +1,18 @@ +{ + "state": "set", + "service_affecting": "True", + "proposed_repair_action": + "Contact next level of support.", + "event_log_type": "processing-error", + "severity": "critical", + "created_at": "2014-11-28T20:00:56.116251+00:00", + "entity_type_id": "service_domain.service_group.host", + "probable_cause": "underlying-resource-unavailable", + "updated_at": null, + "event_log_id": "400.001", + "entity_instance_id":"system=1bcd6f11-8152-45f7-9d93-0960e1887afe.service_domain=controller.service_group=patching-services.host=controller-0", + "suppression": "True", + "timestamp": "2014-11-28T20:00:56.114060+00:00", + "uuid": "8701d806-cae7-4f34-be8d-17fd11a0d25d", + "reason_text": "Service group failure; patch-alarm-manager(disabled, failed)." +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-request.json new file mode 100644 index 000000000..0de69f46a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-request.json @@ -0,0 +1 @@ +http://192.168.204.2:6385/v1/event_suppression diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-response.json new file mode 100644 index 000000000..e36358047 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_list-response.json @@ -0,0 +1,57 @@ +{ + "event_suppression":[ + { + "alarm_id":"100.101", + "suppression_status":"unsuppressed", + "description":"Platform CPU threshold exceeded; threshold x%, actual y% .", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/event_suppression/494af09d-6810-4cf2-a57b-528f570f0511", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/event_suppression/494af09d-6810-4cf2-a57b-528f570f0511", + "rel":"bookmark" + } + ], + "uuid":"494af09d-6810-4cf2-a57b-528f570f0511" + }, + { + "alarm_id":"100.102", + "suppression_status":"unsuppressed", + "description":"VSwitch CPU threshold exceeded; threshold x%, actual y% .", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/event_suppression/b140b479-10a3-430f-9aba-a9a46b3fc03f", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/event_suppression/b140b479-10a3-430f-9aba-a9a46b3fc03f", + "rel":"bookmark" + } + ], + "uuid":"b140b479-10a3-430f-9aba-a9a46b3fc03f" + }, + + + ... + + + { + "alarm_id":"900.003", + "suppression_status":"suppressed", + "description":"Patch host install failure.", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/event_suppression/72285cc6-07ad-47ef-8b39-2e4482895533", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/event_suppression/72285cc6-07ad-47ef-8b39-2e4482895533", + "rel":"bookmark" + } + ], + "uuid":"72285cc6-07ad-47ef-8b39-2e4482895533" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-request.json new file mode 100644 index 000000000..89c694507 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/suppression_status", + "value":"unsuppressed", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-response.json new file mode 100644 index 000000000..4346262d4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/event_suppression_modify-response.json @@ -0,0 +1,19 @@ +{ + "description":"Service group loss of redundancy; expected standby member but only standby member available.ORService group loss of redundancy; expected standby member but only standby member available.ORService group loss of redu ...", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/event_suppression/eb54eb1a-6314-4818-8fe7-83bdb6fe5b80", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/event_suppression/eb54eb1a-6314-4818-8fe7-83bdb6fe5b80", + "rel":"bookmark" + } + ], + "created_at":"2016-05-09T11:25:22.436412+00:00", + "updated_at":"2016-05-12T12:38:51.524402+00:00", + "alarm_id":"400.002", + "suppression_status":"unsuppressed", + "id":37, + "uuid":"eb54eb1a-6314-4818-8fe7-83bdb6fe5b80" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-request.json new file mode 100644 index 000000000..89a129b1f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-request.json @@ -0,0 +1,12 @@ +[ + { + "path":"/oam_c1_ip", + "value":"10.10.10.4", + "op":"replace" + }, + { + "path":"/action", + "value":"apply", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-response.json new file mode 100644 index 000000000..d48b487e1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_modify-response.json @@ -0,0 +1,25 @@ +{ + "iextoams":[ + { + "links":[ + { + "href":"http://192.168.204.2:6385/v1/iextoams/2056b372-10a5-47d3-b1da-8957c370b630", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/iextoams/2056b372-10a5-47d3-b1da-8957c370b630", + "rel":"bookmark" + } + ], + "created_at":"2014-09-30T14:42:16.656226+00:00", + "updated_at":"2014-10-01T17:35:43.131331+00:00", + "oam_subnet":"10.10.10.0/24", + "oam_gateway_ip":"10.10.10.1", + "oam_floating_ip":"10.10.10.2", + "oam_c0_ip":"10.10.10.3", + "oam_c1_ip":"10.10.10.4", + "isystem_uuid":"ce178041-2b2c-405d-bf87-f19334a35582", + "uuid":"2056b372-10a5-47d3-b1da-8957c370b630" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_show-response.json new file mode 100644 index 000000000..c56609927 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/extoam_show-response.json @@ -0,0 +1,26 @@ +{ + "iextoams":[ + { + "links":[ + { + "href":"http://192.168.204.2:6385/v1/iextoams/2056b372-10a5-47d3-b1da-8957c370b630", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/iextoams/2056b372-10a5-47d3-b1da-8957c370b630", + "rel":"bookmark" + } + ], + "created_at":"2014-09-30T14:42:16.656226+00:00", + "updated_at":"2014-10-01T17:35:43.131331+00:00", + "oam_subnet":"10.10.10.0/24", + "oam_ifcs":"eth0", + "oam_gateway_ip":"10.10.10.1", + "oam_floating_ip":"10.10.10.2", + "oam_c0_ip":"10.10.10.3", + "oam_c1_ip":"10.10.10.4", + "isystem_uuid":"ce178041-2b2c-405d-bf87-f19334a35582", + "uuid":"2056b372-10a5-47d3-b1da-8957c370b630" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/firewall_rules_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/firewall_rules_show-response.json new file mode 100644 index 000000000..133a85925 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/firewall_rules_show-response.json @@ -0,0 +1,9 @@ +{ + "firewallrules": [ + { + "firewall_sig": "ab9695c4ef143d72317a860c6db7f699", + "uuid": "bc276605-7ae2-476a-a8c0-01f097f5177e", + "updated_at": "2018-03-02T15:59:14.114812+00:00" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-request.json new file mode 100644 index 000000000..0495d6db5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/action", + "value":"unlock", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-response.json new file mode 100644 index 000000000..c347cd451 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_action-response.json @@ -0,0 +1,119 @@ +{ + "ports":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/ports", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/ports", + "rel":"bookmark" + } + ], + "reserved":"False", + "idisks":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/idisks", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/idisks", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T15:31:31.565491+00:00", + "bm_username":"", + "iprofile_uuid":null, + "id":5, + "forisystemid":1, + "icpus":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/icpus", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/icpus", + "rel":"bookmark" + } + ], + "uptime":107, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923", + "rel":"bookmark" + } + ], + "mgmt_ip":"192.168.204.5", + "hostname":"storage-0", + "istors":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/istors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/istors", + "rel":"bookmark" + } + ], + "capabilities":{ + "stor_function":"monitor" + }, + "availability":"online", + "location":{ + "locn":"" + }, + "config_applied":"a47cfb0d-3892-4608-8012-371ce45faf55", + "invprovision":"provisioned", + "administrative":"locked", + "personality":"storage", + "iinterfaces":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/iinterfaces", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/iinterfaces", + "rel":"bookmark" + } + ], + "config_status":"", + "config_target":null, + "isystem_uuid":"e79e74a5-e08e-41ab-9277-5e01457a0e5e", + "mgmt_mac":"08:00:27:fa:e2:1c", + "task":"Unlocking", + "recordtype":"standard", + "operational":"disabled", + "created_at":"2014-10-01T21:12:09.899675+00:00", + "uuid":"0dad0322-f289-40ca-9059-67cd673a0923", + "action":"none", + "bm_type":null, + "serialId":null, + "boot_device": "sda", + "rootfs_device": "sda", + "install_output": "text", + "console": "ttyS0,115200", + "inodes":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/inodes", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/inodes", + "rel":"bookmark" + } + ], + "imemorys":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/imemorys", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923/imemorys", + "rel":"bookmark" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-request.json new file mode 100644 index 000000000..58237c536 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-request.json @@ -0,0 +1,17 @@ +{ + "hostname":"compute-0", + "personality":"compute", + "subfunctions":"compute_lowlatency", + "mgmt_mac":"11:22:33:44:55:66", + "mgmt_ip":"192.168.204.200", + "bm_type":"bmc", + "bm_ip":"10.10.10.240", + "bm_username":"bm_user", + "bm_password":"bm_user_pwd", + "boot_device": "sda", + "rootfs_device": "sda", + "install_output": "text", + "console": "ttyS0,115200", + "ttys_dcd":"True", + "location":{"locn":"West tower, Room B"} +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-response.json new file mode 100644 index 000000000..2a473f2c8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_add-response.json @@ -0,0 +1,162 @@ +{ + "ports":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ports", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ports", + "rel":"bookmark" + } + ], + "reserved":"False", + "idisks":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/idisks", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/idisks", + "rel":"bookmark" + } + ], + "subfunctions":"compute_lowlatency", + "bm_ip":"10.10.10.240", + "updated_at":null, + "ihost_action":null, + "bm_username":"bm_user", + "id":3, + "serialid":null, + "availability":"offline", + "forisystemid":1, + "vim_progress_status":null, + "icpus":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/icpus", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/icpus", + "rel":"bookmark" + } + ], + "uptime":0, + "links":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755", + "rel":"bookmark" + } + ], + "mgmt_ip":"192.168.204.200", + "hostname":"compute-0", + "istors":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/istors", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/istors", + "rel":"bookmark" + } + ], + "capabilities":{ + + }, + "iprofile_uuid":null, + "location":{ + + }, + "config_applied":null, + "invprovision":null, + "mgmt_mac": "11:22:33:44:55:66", "administrative":"locked", + "personality":"compute", + "iinterfaces":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/iinterfaces", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/iinterfaces", + "rel":"bookmark" + } + ], + "isystem_uuid":"b3bbc885-2389-43e8-8b00-54a3ad6614af", + "config_target":null, + "ethernet_ports":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ethernet_ports", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ethernet_ports", + "rel":"bookmark" + } + ], + "uuid":"88d437b5-aa2c-4f1b-8f27-d13330dca755", + "subfunction_oper":"disabled", + "task":null, + "ttys_dcd":null, + "recordtype":"standard", + "operational":"disabled", + "created_at": "2015-05-06T17:06:13.506319+00:00", "subfunction_avail":"offline", + "ipvs":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ipvs", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ipvs", + "rel":"bookmark" + } + ], + "ilvgs":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ilvgs", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ilvgs", + "rel":"bookmark" + } + ], + "action":"none", + "bm_type":"bmc", + "boot_device": "sda", + "rootfs_device": "sda", + "install_output": "text", + "console": "ttyS0,115200", + "ports":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ports", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/ports", + "rel":"bookmark" + } + ], + "inodes":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/inodes", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/inodes", + "rel":"bookmark" + } + ], + "imemorys":[ + { + "href": "http://192.168.204.2:6385/v1/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/imemorys", + "rel":"self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/88d437b5-aa2c-4f1b-8f27-d13330dca755/imemorys", + "rel":"bookmark" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-request.json new file mode 100644 index 000000000..6b15e1cef --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-request.json @@ -0,0 +1,5 @@ +{ + "prefix": "24", + "interface_uuid": "4e49a054-3c72-43b8-8e48-1f63dcc5ff7d", + "address": "192.168.59.3" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-response.json new file mode 100644 index 000000000..39940958f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_add-response.json @@ -0,0 +1,14 @@ +{ + "forihostid": 3, + "uuid": "5dc26260-d825-424d-88d2-b1906022c374", + "created_at": "2016-11-16T16:03:14.614922+00:00", + "updated_at": null, + "pool_uuid": null, + "prefix": 24, + "address": "192.168.59.3", + "enable_dad": false, + "ifname": "vlan11", + "interface_uuid": "4e49a054-3c72-43b8-8e48-1f63dcc5ff7d", + "id": 25, + "name": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_list-response.json new file mode 100644 index 000000000..394bd952c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_list-response.json @@ -0,0 +1,82 @@ +{ + "addresses": [{ + "forihostid": 1, + "uuid": "268241c3-99b8-4d0a-9172-49d2ff9681bc", + "prefix": 24, + "address": "192.168.204.3", + "enable_dad": false, + "ifname": "enp0s8", + "interface_uuid": "49e994d5-2733-4fab-8e1b-54523afdd2d9", + "pool_uuid": "d7187d17-8715-4934-8754-4827e604a468" + }, + { + "forihostid": 1, + "uuid": "1a3fb522-be74-4563-a418-6063f9fcf8a1", + "prefix": 24, + "address": "192.168.205.3", + "enable_dad": false, + "ifname": "eth0.99", + "interface_uuid": "434df886-4709-4187-8639-ec10d0784a36", + "pool_uuid": "7b299949-614c-4f1a-85cb-c46a09827f0c" + }, + { + "forihostid": 1, + "uuid": "7040521a-6a59-49ad-a703-0fc35573d4db", + "prefix": 24, + "address": "192.168.59.2", + "enable_dad": false, + "ifname": "vlan11", + "interface_uuid": "280baad6-7791-41a5-97f9-f8f8e0f879c5", + "pool_uuid": null + }, + { + "forihostid": 1, + "uuid": "e7169f61-9b8e-455f-bac3-936b774d4b69", + "prefix": 64, + "address": "fd00:0:0:b::2", + "enable_dad": true, + "ifname": "vlan11", + "interface_uuid": "280baad6-7791-41a5-97f9-f8f8e0f879c5", + "pool_uuid": null + }, + { + "forihostid": 1, + "uuid": "08608f9c-d5f7-4f29-bd71-2d6feee22a6e", + "prefix": 24, + "address": "192.168.58.2", + "enable_dad": false, + "ifname": "data1", + "interface_uuid": "6db88b94-fbaa-47a9-95f5-0633036a1a27", + "pool_uuid": "15a1fa4e-d1c0-49f8-80d9-484640fb95a0" + }, + { + "forihostid": 1, + "uuid": "53bb0f7e-1547-4635-9faf-4d9b8dad2698", + "prefix": 64, + "address": "fd00:0:0:2::7", + "enable_dad": true, + "ifname": "data1", + "interface_uuid": "6db88b94-fbaa-47a9-95f5-0633036a1a27", + "pool_uuid": "04ff8781-9042-4602-a19e-7ed90f0979ad" + }, + { + "forihostid": 1, + "uuid": "369c552a-1da6-4181-afdb-778d3b90d4c9", + "prefix": 24, + "address": "192.168.57.2", + "enable_dad": false, + "ifname": "data0", + "interface_uuid": "7a3331e2-88c4-4c30-a49e-67bf924661b4", + "pool_uuid": "366e08ac-a5c8-4554-b019-0a0d2d011e6e" + }, + { + "forihostid": 1, + "uuid": "af3c8e3c-57ad-4eda-ad5a-f1dbab93875b", + "prefix": 64, + "address": "fd00:0:0:1::2", + "enable_dad": true, + "ifname": "data0", + "interface_uuid": "7a3331e2-88c4-4c30-a49e-67bf924661b4", + "pool_uuid": "950a4587-2baf-4075-994a-98189de51acc" + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_show-response.json new file mode 100644 index 000000000..fe2e8fc86 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_addr_show-response.json @@ -0,0 +1,14 @@ +{ + "forihostid": 1, + "uuid": "369c552a-1da6-4181-afdb-778d3b90d4c9", + "created_at": "2016-11-09T15:14:09.409615+00:00", + "updated_at": null, + "pool_uuid": "366e08ac-a5c8-4554-b019-0a0d2d011e6e", + "prefix": 24, + "address": "192.168.57.2", + "enable_dad": false, + "ifname": "data0", + "interface_uuid": "7a3331e2-88c4-4c30-a49e-67bf924661b4", + "id": 17, + "name": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_add-response.json new file mode 100755 index 000000000..7e33f9127 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_add-response.json @@ -0,0 +1,4 @@ +{ + "success":"compute-0, compute-1" + "error":"compute-2: Host-add Rejected: Host with mgmt_mac 08:00:28:A9:54:19 already exists" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_export-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_export-response.json new file mode 100644 index 000000000..1ff9a8199 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_bulk_export-response.json @@ -0,0 +1 @@ +{"content": "\n\n\t\n\t\tcontroller\n\t\t08:00:27:d0:e0:2b\n\t\t192.168.204.3\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\tsda\n\t\tsda\n\t\ttext\n\t\tttyS0,115200\n\t\n\t\n\t\tcompute\n\t\t08:00:27:bf:29:39\n\t\t192.168.204.20\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\tsda\n\t\tsda\n\t\ttext\n\t\tttyS0,115200\n\t\n\n"} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-request.json new file mode 100644 index 000000000..e16d0c2c8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-request.json @@ -0,0 +1 @@ +{"force": false} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-response.json new file mode 100644 index 000000000..0a6a13b19 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_downgrade-response.json @@ -0,0 +1,226 @@ +{ + "iports": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/iports", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/iports", + "rel": "bookmark" + } + ], + "reserved": "False", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade", + "rel": "bookmark" + } + ], + "idisks": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/idisks", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/idisks", + "rel": "bookmark" + } + ], + "subfunctions": "compute", + "config_applied": "install", + "bm_ip": "", + "updated_at": "2017-03-06T16:16:10.126508+00:00", + "isensors": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/isensors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/isensors", + "rel": "bookmark" + } + ], + "ceph_mon": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ceph_mon", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ceph_mon", + "rel": "bookmark" + } + ], + "ihost_action": "lock", + "bm_username": "", + "id": 4, + "iprofile_uuid": null, + "serialid": null, + "availability": "offline", + "forisystemid": 1, + "vim_progress_status": "services-disabled", + "icpus": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/icpus", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/icpus", + "rel": "bookmark" + } + ], + "uptime": 0, + "console": "", + "uuid": "e6c1a877-a332-46dd-821d-e5fa9e2c4ade", + "mgmt_ip": "192.168.204.80", + "software_load": "15.12", + "config_status": null, + "hostname": "compute-1", + "istors": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/istors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/istors", + "rel": "bookmark" + } + ], + "capabilities": {}, + "operational": "disabled", + "location": { + "locn": "" + }, + "invprovision": "provisioned", + "administrative": "locked", + "personality": "compute", + "iinterfaces": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/iinterfaces", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/iinterfaces", + "rel": "bookmark" + } + ], + "pci_devices": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/pci_devices", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/pci_devices", + "rel": "bookmark" + } + ], + "ethernet_ports": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ethernet_ports", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ethernet_ports", + "rel": "bookmark" + } + ], + "mtce_info": null, + "isensorgroups": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/isensorgroups", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/isensorgroups", + "rel": "bookmark" + } + ], + "isystem_uuid": "4d31d98d-4992-445a-b749-485ce6077fd2", + "boot_device": "sda", + "rootfs_device": "sda", + "mgmt_mac": "08:00:27:a1:02:ff", + "subfunction_oper": "disabled", + "peers": null, + "task": "", + "ttys_dcd": "False", + "target_load": "15.12", + "lldp_neighbours": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/lldp_neighbors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/lldp_neighbors", + "rel": "bookmark" + } + ], + "created_at": "2016-11-28T17:58:07.778282+00:00", + "subfunction_avail": "online", + "install_output": "graphical", + "ipvs": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ipvs", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ipvs", + "rel": "bookmark" + } + ], + "ilvgs": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ilvgs", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ilvgs", + "rel": "bookmark" + } + ], + "action": "none", + "bm_type": "", + "lldp_agents": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/lldp_agents", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/lldp_agents", + "rel": "bookmark" + } + ], + "imemorys": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/imemorys", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/imemorys", + "rel": "bookmark" + } + ], + "ports": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ports", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/ports", + "rel": "bookmark" + } + ], + "inodes": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/inodes", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/e6c1a877-a332-46dd-821d-e5fa9e2c4ade/inodes", + "rel": "bookmark" + } + ], + "config_target": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_list-response.json new file mode 100644 index 000000000..6daabbd82 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_list-response.json @@ -0,0 +1,206 @@ +{ + "ihosts":[ + { + "reserved":"False", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T14:56:23.230316+00:00", + "bm_username":null, + "iprofile_uuid":null, + "id":1, + "uptime":68379, + "mgmt_ip":"192.168.204.3", + "hostname":"controller-0", + "capabilities":{ + "stor_function":"monitor", + "Personality":"Controller-Active" + }, + "operational":"enabled", + "availability":"available", + "location":{ + + }, + "config_applied":"18c9e850-be49-4b84-9eba-6aaeab12ec72", + "administrative":"unlocked", + "personality":"controller", + "config_status":"Config out-of-date", + "config_target":"a47cfb0d-3892-4608-8012-371ce45faf55", + "mgmt_mac":"08:00:27:3d:c2:fe", + "task":"", + "created_at":"2014-10-01T20:06:44.302456+00:00", + "uuid":"298d0050-7758-4bb8-aefc-dfddad2c4984", + "action":"none", + "bm_type":null + }, + { + "reserved":"False", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/5f7d15c6-77aa-49cd-a6a1-678aef89edea", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/5f7d15c6-77aa-49cd-a6a1-678aef89edea", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T14:56:23.252439+00:00", + "bm_username":"", + "iprofile_uuid":null, + "id":2, + "uptime":65518, + "mgmt_ip":"192.168.204.4", + "hostname":"controller-1", + "capabilities":{ + "stor_function":"monitor", + "Personality":"Controller-Standby" + }, + "operational":"enabled", + "availability":"available", + "location":{ + "locn":"" + }, + "config_applied":"18c9e850-be49-4b84-9eba-6aaeab12ec72", + "administrative":"unlocked", + "personality":"controller", + "config_status":"Config out-of-date", + "config_target":"a47cfb0d-3892-4608-8012-371ce45faf55", + "mgmt_mac":"08:00:27:90:be:dc", + "task":"", + "created_at":"2014-10-01T20:07:11.401964+00:00", + "uuid":"5f7d15c6-77aa-49cd-a6a1-678aef89edea", + "action":"none", + "bm_type":null + }, + { + "reserved":"False", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/0dad0322-f289-40ca-9059-67cd673a0923", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/0dad0322-f289-40ca-9059-67cd673a0923", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T15:00:23.445512+00:00", + "bm_username":"", + "iprofile_uuid":null, + "id":5, + "uptime":63720, + "mgmt_ip":"192.168.204.5", + "hostname":"storage-0", + "capabilities":{ + "stor_function":"monitor" + }, + "operational":"disabled", + "availability":"online", + "location":{ + "locn":"" + }, + "config_applied":null, + "administrative":"locked", + "personality":"storage", + "config_status":null, + "config_target":null, + "mgmt_mac":"08:00:27:fa:e2:1c", + "task":"", + "created_at":"2014-10-01T21:12:09.899675+00:00", + "uuid":"0dad0322-f289-40ca-9059-67cd673a0923", + "action":"none", + "bm_type":null + }, + { + "reserved":"False", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T14:56:23.268242+00:00", + "bm_username":"", + "iprofile_uuid":null, + "id":6, + "uptime":62651, + "mgmt_ip":"192.168.204.6", + "hostname":"storage-1", + "capabilities":{ + + }, + "operational":"disabled", + "availability":"online", + "location":{ + "locn":"" + }, + "config_applied":null, + "administrative":"locked", + "personality":"storage", + "config_status":null, + "config_target":null, + "mgmt_mac":"08:00:27:22:48:f2", + "task":"", + "created_at":"2014-10-01T21:26:17.404218+00:00", + "uuid":"42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "action":"none", + "bm_type":null + }, + { + "reserved":"False", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/cd5ef327-618b-4aac-9b10-9bbbe2baa8e0", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/cd5ef327-618b-4aac-9b10-9bbbe2baa8e0", + "rel":"bookmark" + } + ], + "bm_ip":null, + "updated_at":null, + "bm_username":null, + "iprofile_uuid":null, + "id":7, + "uptime":0, + "mgmt_ip":"192.168.204.129", + "hostname":null, + "capabilities":{ + + }, + "operational":"disabled", + "availability":"offline", + "location":{ + + }, + "config_applied":null, + "administrative":"locked", + "personality":null, + "config_status":null, + "config_target":null, + "mgmt_mac":"08:00:27:be:6e:25", + "task":null, + "created_at":"2014-10-02T13:57:04.900900+00:00", + "uuid":"cd5ef327-618b-4aac-9b10-9bbbe2baa8e0", + "action":"none", + "bm_type":null + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-request.json new file mode 100644 index 000000000..70c19ab9c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/location", + "value":"{'locn':'350 Terry Fox Dr, Kanata, Ontario, Canada'}", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-response.json new file mode 100644 index 000000000..73e2188b8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_modify-response.json @@ -0,0 +1,120 @@ +{ + "ports":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/ports", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/ports", + "rel":"bookmark" + } + ], + "reserved":"False", + "idisks":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/idisks", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/idisks", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T15:19:42.572251+00:00", + "bm_username":null, + "iprofile_uuid":null, + "id":1, + "forisystemid":1, + "icpus":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/icpus", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/icpus", + "rel":"bookmark" + } + ], + "uptime":69459, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984", + "rel":"bookmark" + } + ], + "mgmt_ip":"192.168.204.3", + "hostname":"controller-0", + "istors":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/istors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/istors", + "rel":"bookmark" + } + ], + "capabilities":{ + "stor_function":"monitor" + }, + "availability":"available", + "location":{ + "locn":"350 Terry Fox Dr, Kanata, Ontario, Canada" + }, + "config_applied":"18c9e850-be49-4b84-9eba-6aaeab12ec72", + "invprovision":"provisioned", + "administrative":"unlocked", + "personality":"controller", + "iinterfaces":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/iinterfaces", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/iinterfaces", + "rel":"bookmark" + } + ], + "config_status":"Config out-of-date", + "config_target":"a47cfb0d-3892-4608-8012-371ce45faf55", + "isystem_uuid":"e79e74a5-e08e-41ab-9277-5e01457a0e5e", + "mgmt_mac":"08:00:27:3d:c2:fe", + "task":null, + "ttys_dcd":null, + "recordtype":"standard", + "operational":"enabled", + "created_at":"2014-10-01T20:06:44.302456+00:00", + "uuid":"298d0050-7758-4bb8-aefc-dfddad2c4984", + "action":"none", + "bm_type":null, + "serialId":null, + "boot_device": "sda", + "rootfs_device": "sda", + "install_output": "text", + "console": "ttyS0,115200", + "inodes":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/inodes", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/inodes", + "rel":"bookmark" + } + ], + "imemorys":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/imemorys", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/imemorys", + "rel":"bookmark" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-request.json new file mode 100644 index 000000000..435e71b0d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-request.json @@ -0,0 +1,7 @@ +{ + "prefix": "0", + "interface_uuid": "4e49a054-3c72-43b8-8e48-1f63dcc5ff7d", + "gateway": "192.168.59.1", + "metric": "1", + "network": "0.0.0.0" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-response.json new file mode 100644 index 000000000..3b37b3f66 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_add-response.json @@ -0,0 +1,13 @@ +{ + "forihostid": 3, + "network": "0.0.0.0", + "metric": 1, + "updated_at": null, + "gateway": "192.168.59.1", + "created_at": "2016-11-16T16:49:58.044211+00:00", + "prefix": 0, + "ifname": "vlan11", + "interface_uuid": "4e49a054-3c72-43b8-8e48-1f63dcc5ff7d", + "id": 14, + "uuid": "83c1d4e1-9dd4-414b-93e9-61875bc5a180" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_list-response.json new file mode 100644 index 000000000..7e2351454 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_list-response.json @@ -0,0 +1,56 @@ +{ + "routes": [{ + "forihostid": 3, + "uuid": "dbacbb57-b3cd-4b9c-b365-0ecf5dec4d60", + "metric": 1, + "prefix": 0, + "ifname": "vlan11", + "gateway": "192.168.59.1", + "network": "0.0.0.0" + }, + { + "forihostid": 3, + "uuid": "354968fc-6f18-46dc-93a1-6118280e3cee", + "metric": 1, + "prefix": 0, + "ifname": "vlan11", + "gateway": "fd00:0:0:b::1", + "network": "::" + }, + { + "forihostid": 3, + "uuid": "014b66b2-3d57-4c3c-a305-5d417ee75125", + "metric": 1, + "prefix": 0, + "ifname": "data1", + "gateway": "192.168.58.1", + "network": "0.0.0.0" + }, + { + "forihostid": 3, + "uuid": "1ef1bc3f-813d-4947-a1a6-1ee9945010d4", + "metric": 1, + "prefix": 0, + "ifname": "data1", + "gateway": "fd00:0:0:2::1", + "network": "::" + }, + { + "forihostid": 3, + "uuid": "67255752-ad7f-496d-8d72-b42775fca330", + "metric": 1, + "prefix": 0, + "ifname": "data0", + "gateway": "192.168.57.1", + "network": "0.0.0.0" + }, + { + "forihostid": 3, + "uuid": "77c9ac25-49c4-4327-aa3c-f9e868b6a56d", + "metric": 1, + "prefix": 0, + "ifname": "data0", + "gateway": "fd00:0:0:1::1", + "network": "::" + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_show-response.json new file mode 100644 index 000000000..be70c0bf9 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_route_show-response.json @@ -0,0 +1,13 @@ +{ + "forihostid": 3, + "network": "0.0.0.0", + "metric": 1, + "updated_at": null, + "gateway": "192.168.57.1", + "created_at": "2016-11-09T15:58:31.830131+00:00", + "prefix": 0, + "ifname": "data0", + "interface_uuid": "da107d6c-3844-482b-aa5d-2c355f5434d3", + "id": 11, + "uuid": "67255752-ad7f-496d-8d72-b42775fca330" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_show-response.json new file mode 100644 index 000000000..91e63c5c2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_show-response.json @@ -0,0 +1,122 @@ +{ + "ports":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/ports", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/ports", + "rel":"bookmark" + } + ], + "reserved":"False", + "idisks":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/idisks", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/idisks", + "rel":"bookmark" + } + ], + "bm_ip":"", + "updated_at":"2014-10-02T15:14:23.744473+00:00", + "bm_username":null, + "iprofile_uuid":null, + "id":1, + "forisystemid":1, + "icpus":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/icpus", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/icpus", + "rel":"bookmark" + } + ], + "uptime":69459, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984", + "rel":"bookmark" + } + ], + "mgmt_ip":"192.168.204.3", + "hostname":"controller-0", + "istors":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/istors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/istors", + "rel":"bookmark" + } + ], + "capabilities":{ + "stor_function":"monitor", + "Personality":"Controller-Active" + }, + "availability":"available", + "location":{ + + }, + "config_applied":"18c9e850-be49-4b84-9eba-6aaeab12ec72", + "invprovision":"provisioned", + "administrative":"unlocked", + "personality":"controller", + "iinterfaces":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/iinterfaces", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/iinterfaces", + "rel":"bookmark" + } + ], + "config_status":"Config out-of-date", + "config_target":"a47cfb0d-3892-4608-8012-371ce45faf55", + "isystem_uuid":"e79e74a5-e08e-41ab-9277-5e01457a0e5e", + "mgmt_mac":"08:00:27:3d:c2:fe", + "task":"", + "recordtype":"standard", + "operational":"enabled", + "created_at":"2014-10-01T20:06:44.302456+00:00", + "uuid":"298d0050-7758-4bb8-aefc-dfddad2c4984", + "action":"none", + "install_state": "installed", + "install_state_info": "", + "bm_type":null, + "serialId":null, + "boot_device": "sda", + "rootfs_device": "sda", + "install_output": "text", + "console": "ttyS0,115200", + "inodes":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/inodes", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/inodes", + "rel":"bookmark" + } + ], + "imemorys":[ + { + "href":"http://192.168.204.2:6385/v1/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/imemorys", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/ihosts/298d0050-7758-4bb8-aefc-dfddad2c4984/imemorys", + "rel":"bookmark" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-request.json new file mode 100644 index 000000000..e16d0c2c8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-request.json @@ -0,0 +1 @@ +{"force": false} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-response.json new file mode 100644 index 000000000..a7739c63d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/host_upgrade-response.json @@ -0,0 +1,226 @@ +{ + "iports": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/iports", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/iports", + "rel": "bookmark" + } + ], + "reserved": "False", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95", + "rel": "bookmark" + } + ], + "idisks": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/idisks", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/idisks", + "rel": "bookmark" + } + ], + "subfunctions": "compute", + "config_applied": "install", + "bm_ip": "", + "updated_at": "2017-03-06T16:02:47.042128+00:00", + "isensors": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/isensors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/isensors", + "rel": "bookmark" + } + ], + "ceph_mon": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ceph_mon", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ceph_mon", + "rel": "bookmark" + } + ], + "ihost_action": "lock", + "bm_username": "", + "id": 3, + "iprofile_uuid": null, + "serialid": null, + "availability": "online", + "forisystemid": 1, + "vim_progress_status": "services-disabled", + "icpus": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/icpus", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/icpus", + "rel": "bookmark" + } + ], + "uptime": 1112, + "console": "", + "uuid": "bed0aee2-d637-488e-ada1-c837ee503f95", + "mgmt_ip": "192.168.204.247", + "software_load": "15.12", + "config_status": null, + "hostname": "compute-0", + "istors": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/istors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/istors", + "rel": "bookmark" + } + ], + "capabilities": {}, + "operational": "disabled", + "location": { + "locn": "" + }, + "invprovision": "provisioned", + "administrative": "locked", + "personality": "compute", + "iinterfaces": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/iinterfaces", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/iinterfaces", + "rel": "bookmark" + } + ], + "pci_devices": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/pci_devices", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/pci_devices", + "rel": "bookmark" + } + ], + "ethernet_ports": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ethernet_ports", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ethernet_ports", + "rel": "bookmark" + } + ], + "mtce_info": null, + "isensorgroups": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/isensorgroups", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/isensorgroups", + "rel": "bookmark" + } + ], + "isystem_uuid": "4d31d98d-4992-445a-b749-485ce6077fd2", + "boot_device": "sda", + "rootfs_device": "sda", + "mgmt_mac": "08:00:27:f2:60:5a", + "subfunction_oper": "disabled", + "peers": null, + "task": "", + "ttys_dcd": "False", + "target_load": "16.10", + "lldp_neighbours": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/lldp_neighbors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/lldp_neighbors", + "rel": "bookmark" + } + ], + "created_at": "2016-11-28T17:40:21.476162+00:00", + "subfunction_avail": "online", + "install_output": "graphical", + "ipvs": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ipvs", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ipvs", + "rel": "bookmark" + } + ], + "ilvgs": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ilvgs", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ilvgs", + "rel": "bookmark" + } + ], + "action": "none", + "bm_type": "", + "lldp_agents": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/lldp_agents", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/lldp_agents", + "rel": "bookmark" + } + ], + "imemorys": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/imemorys", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/imemorys", + "rel": "bookmark" + } + ], + "ports": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ports", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/ports", + "rel": "bookmark" + } + ], + "inodes": [ + { + "href": "http://10.10.10.2:6385/v1/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/inodes", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ihosts/bed0aee2-d637-488e-ada1-c837ee503f95/inodes", + "rel": "bookmark" + } + ], + "config_target": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-request.json new file mode 100644 index 000000000..b708f5958 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-request.json @@ -0,0 +1,7 @@ +{ + "infra_subnet": "192.168.205.0/24" + "infra_start": "192.168.205.2", + "infra_end": "192.168.205.254", + "infra_mtu": "9216", + "infra_vlan_id": "137", +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-response.json new file mode 100644 index 000000000..ae906a237 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_add-response.json @@ -0,0 +1,25 @@ +{ + "iinfras":[ + { + "infra_subnet":"192.168.205.0/24", + "infra_start":"192.168.205.2", + "infra_end":"192.168.205.254", + "infra_mtu": "9216", + "infra_vlan_id": "137", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel":"bookmark" + } + ], + "created_at": "2014-12-01T19:35:36.965657+00:00", + "updated_at": "2014-12-02T20:38:51.646902+00:00", + "isystem_uuid": "b7fdc4dd-333d-471b-b21d-ba664ea87714", + "uuid": "15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-request.json new file mode 100644 index 000000000..4c8d35002 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/action", + "value":"apply", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-response.json new file mode 100644 index 000000000..ae906a237 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_apply-response.json @@ -0,0 +1,25 @@ +{ + "iinfras":[ + { + "infra_subnet":"192.168.205.0/24", + "infra_start":"192.168.205.2", + "infra_end":"192.168.205.254", + "infra_mtu": "9216", + "infra_vlan_id": "137", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel":"bookmark" + } + ], + "created_at": "2014-12-01T19:35:36.965657+00:00", + "updated_at": "2014-12-02T20:38:51.646902+00:00", + "isystem_uuid": "b7fdc4dd-333d-471b-b21d-ba664ea87714", + "uuid": "15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-request.json new file mode 100644 index 000000000..463f37b30 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/infra_subnet", + "value":"192.168.205.0/24", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-response.json new file mode 100644 index 000000000..ae906a237 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_modify-response.json @@ -0,0 +1,25 @@ +{ + "iinfras":[ + { + "infra_subnet":"192.168.205.0/24", + "infra_start":"192.168.205.2", + "infra_end":"192.168.205.254", + "infra_mtu": "9216", + "infra_vlan_id": "137", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel":"bookmark" + } + ], + "created_at": "2014-12-01T19:35:36.965657+00:00", + "updated_at": "2014-12-02T20:38:51.646902+00:00", + "isystem_uuid": "b7fdc4dd-333d-471b-b21d-ba664ea87714", + "uuid": "15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_show-response.json new file mode 100644 index 000000000..a7808c5f1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/infra_show-response.json @@ -0,0 +1,25 @@ +{ + "iinfras":[ + { + "infra_subnet": "192.168.205.0/24", + "infra_start": "192.168.205.2", + "infra_end": "192.168.205.254", + "infra_mtu": "9216", + "infra_vlan_id": "137", + "links":[ + { + "href": "http://10.10.10.2:6385/v1/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/iinfras/15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c", + "rel": "bookmark" + } + ], + "created_at": "2014-12-01T19:35:36.965657+00:00", + "updated_at": "2014-12-02T20:38:51.646902+00:00", + "isystem_uuid": "b7fdc4dd-333d-471b-b21d-ba664ea87714", + "uuid": "15ba72aa-442f-4b57-a8a1-e3f3cdd5b04c" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-request.json new file mode 100644 index 000000000..865d2c7d5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-request.json @@ -0,0 +1,12 @@ +{ + "iftype": "ae", + "txhashpolicy": "layer2", + "ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85", + "imtu": "1500", + "providernetworks": "physnet-0,physnet1", + "networktype": "data", + "ifname": "data1", + "uses": ['eth2','eth3'], + "aemode": "balanced", + "sriov_numvfs": 0 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-response.json new file mode 100644 index 000000000..a5bcdbf1d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_add-response.json @@ -0,0 +1,52 @@ +{ + "ports": [ + { + "href": "http://192.168.204.2:6385/v1/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856/ports", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856/ports", + "rel": "bookmark" + } + ], + "forihostid": 2, + "iftype": "ae", + "uuid": "92dec2e1-a793-4c63-a408-affc492b7856", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856", + "rel": "bookmark" + } + ], + "ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85", + "vlan_id": null, + "txhashpolicy": "layer2", + "created_at": "2014-09-29T10:55:20.515705+00:00", + "schedpolicy": null, + "providernetworksdict": { + + }, + "imac": null, + "updated_at": null, + "ifcapabilities": { + + }, + "imtu": 1500, + "uses": [ + "eth2", + "eth3" + ], + "used_by": [ + + ], + "aemode": "balanced", + "sriov_numvfs": 0, + "providernetworks": "physnet-0,physnet-1", + "networktype": "data", + "ifname": "data1", + "ports": null, +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_list-response.json new file mode 100644 index 000000000..db5b3e37d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_list-response.json @@ -0,0 +1,62 @@ +{ + "iinterfaces": [ + { + "forihostid": 2, + "iftype": "ethernet", + "uuid": "1425e76f-eb40-41bd-825f-f692a3064043", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iinterfaces/1425e76f-eb40-41bd-825f-f692a3064043", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iinterfaces/1425e76f-eb40-41bd-825f-f692a3064043", + "rel": "bookmark" + } + ], + "txhashpolicy": null, + "schedpolicy": null, + "imac": "08:00:27:80:aa:6e", + "sriov_numvfs": 0, + "ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85", + "vlan_id": null, + "imtu": 1500, + "aemode": null, + "providernetworks": null, + "networktype": "mgmt", + "ifname": "eth1" + }, + { + "forihostid": 2, + "iftype": "ae", + "uuid": "92dec2e1-a793-4c63-a408-affc492b7856", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856", + "rel": "bookmark" + } + ], + "txhashpolicy": "layer2", + "schedpolicy": null, + "imac": null, + "sriov_numvfs": 0, + "ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85", + "imtu": 1500, + "uses": [ + "eth2", + "eth3" + ], + "used_by": [ + + ], + "aemode": "balanced", + "providernetworks": "physnet-0,physnet-1", + "networktype": "data", + "ifname": "data1" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-request.json new file mode 100644 index 000000000..304b76bd7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-request.json @@ -0,0 +1,27 @@ +[ + { + "path": "/imtu", + "value": "1500", + "op": "replace" + }, + { + "path": "/txhashpolicy", + "value": "layer2", + "op": "replace" + }, + { + "path": "/providernetworks", + "value": "physnet-0,physnet-1", + "op": "replace" + }, + { + "path": "/aemode", + "value": "active_standby", + "op": "replace" + }, + { + "path": "/uses", + "value": ['eth2','eth3'], + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-response.json new file mode 100644 index 000000000..3ce7d4de3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_modify-response.json @@ -0,0 +1,52 @@ +{ + "ports": [ + { + "href": "http://192.168.204.2:6385/v1/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856/ports", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856/ports", + "rel": "bookmark" + } + ], + "forihostid": 2, + "iftype": "ae", + "uuid": "92dec2e1-a793-4c63-a408-affc492b7856", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iinterfaces/92dec2e1-a793-4c63-a408-affc492b7856", + "rel": "bookmark" + } + ], + "ihost_uuid": "ff453a51-1d3b-437f-a65e-b2d163f79f85", + "vlan_id": null, + "txhashpolicy": "layer2", + "created_at": "2014-09-29T10:55:20.515705+00:00", + "schedpolicy": null, + "providernetworksdict": { + + }, + "imac": null, + "sriov_numvfs": 0, + "updated_at": "2014-09-29T11:08:21.016145+00:00", + "ifcapabilities": { + + }, + "imtu": 1500, + "uses": [ + "eth2", + "eth3" + ], + "used_by": [ + + ], + "aemode": "active_standby", + "providernetworks": "physnet-0,physnet-1", + "networktype": "data", + "ifname": "data1", + "ports": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_show-response.json new file mode 100644 index 000000000..b3f4bb3d2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/interface_show-response.json @@ -0,0 +1,47 @@ +{ + "ports" : [ + { + "rel" : "self", + "href" : "http://10.10.10.2:6385/v1/iinterfaces/740a5bec-b7a8-4645-93ed-aea0d4cfbf86/ports" + }, + { + "rel" : "bookmark", + "href" : "http://10.10.10.2:6385/iinterfaces/740a5bec-b7a8-4645-93ed-aea0d4cfbf86/ports" + } + ], + "providernetworks" : "physnet-0,physnet-1", + "txhashpolicy" : "layer2", + "schedpolicy" : null, + "networktype" : "data", + "uuid" : "740a5bec-b7a8-4645-93ed-aea0d4cfbf86", + "ihost_uuid" : "ff453a51-1d3b-437f-a65e-b2d163f79f85", + "vlan_id": null, + "created_at" : "2014-09-29T11:12:42.556372+00:00", + "ifcapabilities" : {}, + "iftype" : "ae", + "links" : [ + { + "rel" : "self", + "href" : "http://10.10.10.2:6385/v1/iinterfaces/740a5bec-b7a8-4645-93ed-aea0d4cfbf86" + }, + { + "rel" : "bookmark", + "href" : "http://10.10.10.2:6385/iinterfaces/740a5bec-b7a8-4645-93ed-aea0d4cfbf86" + } + ], + "providernetworksdict" : {}, + "imac" : null, + "sriov_numvfs": 0, + "aemode" : "balanced", + "ifname" : "data1", + "ports" : null, + "uses": [ + + ], + "used_by": [ + + ], + "forihostid" : 2, + "updated_at" : null, + "imtu" : 1500 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/istorconfig_summary-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/istorconfig_summary-response.json new file mode 100644 index 000000000..0855a181b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/istorconfig_summary-response.json @@ -0,0 +1 @@ +{"database_gib": "20", "cinder_pool_gib": 180, "image_gib": "20", "glance_backend": "[LVM, CEPH]", "ceph_mon_gib": 20, "created_at": "2016-06-08T22:12:05.633108+00:00", "updated_at": "2016-06-09T22:12:05.633108+00:00", "ceph_total_space_gib": 208, "cinder_backend": "[LVM, CEPH]", "glance_pool_gib": 20, "cinder_device": "{u'controller-1': u'/dev/disk/by-path/pci-0000:00:0d.0-ata-4.0', u'controller-0': u'/dev/disk/by-path/pci-0000:00:0d.0-ata-3.0'}", "cinder_gib": 20, "backup_gib": 20, "isystem_uuid": "e29e3087-444b-461d-a850-6f84364ae4ba", "ceph_mon_dev_ctrl1": null, "img_conversions_gib": 10, "ceph_mon_dev_ctrl0": null, "ephemeral_pool_gib": 0} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_install-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_install-request.json new file mode 100644 index 000000000..16f0bdf7d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_install-request.json @@ -0,0 +1 @@ +file=@/home/wrsroot/license.lic diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_list-response.json new file mode 100644 index 000000000..9b96aea49 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/license_list-response.json @@ -0,0 +1,17 @@ +{ + "licenses": [{ + "status": "Installed", + "expiry_date": "31-jan-2018", + "name": "Standard_Product_Configuration", + }, + { + "status": "Installed", + "expiry_date": "31-jan-2018", + "name": "All-In-One_Product_Configuration", + }, + { + "status": "Installed", + "expiry_date": "31-jan-2018", + "name": "All-In-One_Simplex_Product_Configuration", + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_list-response.json new file mode 100644 index 000000000..5e4c92094 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_list-response.json @@ -0,0 +1,100 @@ +{ + "lldp_agents": [ + { + "status": "rx=enabled,tx=enabled", + "system_name": "controller-0:vbox", + "port_description": "eth0", + "dot3_max_frame": null, + "port_uuid": "6d222be7-221d-4556-be69-145a21afeb69", + "uuid": "a4a734d1-b749-412e-ad32-ea511d8e7499", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_agents\/a4a734d1-b749-412e-ad32-ea511d8e7499", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_agents\/a4a734d1-b749-412e-ad32-ea511d8e7499", + "rel": "bookmark" + } + ], + "dot3_mac_status": null, + "port_identifier": "08:00:27:19:ad:0d", + "system_description": "Titanium Cloud version 18.03", + "updated_at": null, + "chassis_id": "08:00:27:19:ad:0d", + "dot1_lag": "capable=y,enabled=n", + "port_name": "eth0", + "port_namedisplay": null, + "management_address": "10.10.10.3, fe80::a00:27ff:fe19:ad0d", + "ttl": "120", + "dot1_vlan_names": null, + "created_at": "2016-04-11T15:40:18.366046+00:00", + "host_uuid": "9285be64-83a9-4067-905f-ab50b5f48823", + "system_capabilities": "station" + }, + { + "status": "rx=enabled,tx=enabled", + "system_name": "controller-0:vbox", + "port_description": "eth1", + "dot3_max_frame": null, + "port_uuid": "c1e44562-fe58-4255-ab2f-d58aa5be1ced", + "uuid": "0ec02f88-623f-4148-801c-08d2c4c015f4", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_agents\/0ec02f88-623f-4148-801c-08d2c4c015f4", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_agents\/0ec02f88-623f-4148-801c-08d2c4c015f4", + "rel": "bookmark" + } + ], + "dot3_mac_status": null, + "port_identifier": "08:00:27:b9:af:30", + "system_description": "Titanium Cloud version 18.03", + "updated_at": null, + "chassis_id": "08:00:27:19:ad:0d", + "dot1_lag": "capable=y,enabled=n", + "port_name": "eth1", + "port_namedisplay": null, + "management_address": "10.10.10.3, fe80::a00:27ff:fe19:ad0d", + "ttl": "120", + "dot1_vlan_names": null, + "created_at": "2016-04-11T15:40:18.396903+00:00", + "host_uuid": "9285be64-83a9-4067-905f-ab50b5f48823", + "system_capabilities": "station" + }, + { + "status": "rx=enabled,tx=enabled", + "system_name": "controller-0:vbox", + "port_description": "eth2", + "dot3_max_frame": null, + "port_uuid": "3b525a1d-9aad-4e74-9d51-8be28db9c4d6", + "uuid": "0c3e3cca-de7d-4b6a-9766-61f16ed34e78", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_agents\/0c3e3cca-de7d-4b6a-9766-61f16ed34e78", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_agents\/0c3e3cca-de7d-4b6a-9766-61f16ed34e78", + "rel": "bookmark" + } + ], + "dot3_mac_status": null, + "port_identifier": "08:00:27:b7:c9:78", + "system_description": "Titanium Cloud version 18.03", + "updated_at": null, + "chassis_id": "08:00:27:19:ad:0d", + "dot1_lag": "capable=y,enabled=n", + "port_name": "eth2", + "port_namedisplay": null, + "management_address": "10.10.10.3, fe80::a00:27ff:fe19:ad0d", + "ttl": "120", + "dot1_vlan_names": null, + "created_at": "2016-04-11T15:40:18.424135+00:00", + "host_uuid": "9285be64-83a9-4067-905f-ab50b5f48823", + "system_capabilities": "station" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_show-response.json new file mode 100644 index 000000000..69601469f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_agent_show-response.json @@ -0,0 +1,42 @@ +{ + "port_description": "eth0", + "port_uuid": "6d222be7-221d-4556-be69-145a21afeb69", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_agents\/a4a734d1-b749-412e-ad32-ea511d8e7499", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_agents\/a4a734d1-b749-412e-ad32-ea511d8e7499", + "rel": "bookmark" + } + ], + "port_identifier": "08:00:27:19:ad:0d", + "updated_at": null, + "port_name": "eth0", + "port_namedisplay": null, + "ttl": "120", + "dot1_vlan_names": null, + "uuid": "a4a734d1-b749-412e-ad32-ea511d8e7499", + "system_description": "Titanium Cloud version 18.03", + "chassis_id": "08:00:27:19:ad:0d", + "dot1_lag": "capable=y,enabled=n", + "system_capabilities": "station", + "status": "rx=enabled,tx=enabled", + "tlvs": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_agents\/a4a734d1-b749-412e-ad32-ea511d8e7499\/tlvs", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_agents\/a4a734d1-b749-412e-ad32-ea511d8e7499\/tlvs", + "rel": "bookmark" + } + ], + "host_uuid": "9285be64-83a9-4067-905f-ab50b5f48823", + "system_name": "controller-0:vbox", + "dot3_max_frame": null, + "dot3_mac_status": null, + "created_at": "2016-04-11T15:40:18.366046+00:00", + "management_address": "10.10.10.3, fe80::a00:27ff:fe19:ad0d" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_list-response.json new file mode 100644 index 000000000..fa9eb11e0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_list-response.json @@ -0,0 +1,42 @@ +{ + "lldp_neighbours": [ + { + "port_description": null, + "msap": "08:00:27:ae:0a:60,Management1", + "port_uuid": "6d222be7-221d-4556-be69-145a21afeb69", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_neighbours\/5742ce56-0420-42df-9096-d13b0a118521", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_neighbours\/5742ce56-0420-42df-9096-d13b0a118521", + "rel": "bookmark" + } + ], + "port_identifier": "Management1", + "updated_at": null, + "dot1_vid_digest": null, + "port_name": "eth0", + "port_namedisplay": null, + "ttl": "104", + "dot1_port_vid": null, + "dot1_vlan_names": null, + "uuid": "5742ce56-0420-42df-9096-d13b0a118521", + "system_description": "Arista Networks EOS version 4.15.0F running on an Arista Networks vEOS", + "dot1_management_vid": null, + "chassis_id": "08:00:27:ae:0a:60", + "dot1_lag": "capable=y,enabled=n", + "dot1_proto_vids": null, + "system_capabilities": "bridge", + "dot1_proto_ids": null, + "host_uuid": "9285be64-83a9-4067-905f-ab50b5f48823", + "system_name": "arista-swtich", + "dot3_power_mdi": null, + "dot3_max_frame": "1518", + "dot3_mac_status": null, + "created_at": "2016-04-11T15:40:17.982210+00:00", + "management_address": "10.10.10.253" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_show-response.json new file mode 100644 index 000000000..558e292ac --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/lldp_neighbor_show-response.json @@ -0,0 +1,48 @@ +{ + "port_description": null, + "msap": "08:00:27:ae:0a:60,Management1", + "port_uuid": "6d222be7-221d-4556-be69-145a21afeb69", + "links": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_neighbours\/5742ce56-0420-42df-9096-d13b0a118521", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_neighbours\/5742ce56-0420-42df-9096-d13b0a118521", + "rel": "bookmark" + } + ], + "port_identifier": "Management1", + "updated_at": null, + "dot1_vid_digest": null, + "port_name": "eth0", + "port_namedisplay": null, + "ttl": "104", + "dot1_port_vid": null, + "dot1_vlan_names": null, + "uuid": "5742ce56-0420-42df-9096-d13b0a118521", + "system_description": "Arista Networks EOS version 4.15.0F running on an Arista Networks vEOS", + "dot1_management_vid": null, + "chassis_id": "08:00:27:ae:0a:60", + "dot1_lag": "capable=y,enabled=n", + "dot1_proto_vids": null, + "system_capabilities": "bridge", + "tlvs": [ + { + "href": "http:\/\/192.168.204.2:6385\/v1\/lldp_neighbours\/5742ce56-0420-42df-9096-d13b0a118521\/tlvs", + "rel": "self" + }, + { + "href": "http:\/\/192.168.204.2:6385\/lldp_neighbours\/5742ce56-0420-42df-9096-d13b0a118521\/tlvs", + "rel": "bookmark" + } + ], + "dot1_proto_ids": null, + "host_uuid": "9285be64-83a9-4067-905f-ab50b5f48823", + "system_name": "arista-swtich", + "dot3_power_mdi": null, + "dot3_max_frame": "1518", + "dot3_mac_status": null, + "created_at": "2016-04-11T15:40:17.982210+00:00", + "management_address": "10.10.10.253" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-request.json new file mode 100644 index 000000000..6e8d85807 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-request.json @@ -0,0 +1,4 @@ +{ + "path_to_iso": "/home/wrsroot/bootimage.iso", + "path_to_signature": "/home/wrsroot/bootimage.sig" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-response.json new file mode 100644 index 000000000..82dbaffe7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/load_import-response.json @@ -0,0 +1,10 @@ +{ + "required_patches": "", + "uuid": "f57e2b86-9047-443f-be39-d3c8aa47222b", + "software_version": "18.03", + "created_at": "2017-03-07T16:29:27+00:00", + "updated_at": null, + "id": 2, + "state": "importing", + "compatible_version": "16.10" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_list-response.json new file mode 100644 index 000000000..3269d3301 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_list-response.json @@ -0,0 +1,20 @@ +{ + "loads": [ + { + "required_patches": "N/A", + "uuid": "924a83a1-3d86-4b67-80fe-decf4c60ac78", + "software_version": "16.10", + "id": 1, + "state": "active", + "compatible_version": "N/A" + }, + { + "required_patches": "", + "uuid": "f57e2b86-9047-443f-be39-d3c8aa47222b", + "software_version": "18.03", + "id": 2, + "state": "imported", + "compatible_version": "16.10" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_show-response.json new file mode 100644 index 000000000..05ebd4b67 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/loads_show-response.json @@ -0,0 +1,10 @@ +{ + "required_patches": "N/A", + "uuid": "924a83a1-3d86-4b67-80fe-decf4c60ac78", + "software_version": "16.10", + "created_at": "2016-11-03T17:16:15.212760+00:00", + "updated_at": null, + "id": 1, + "state": "active", + "compatible_version": "N/A" +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_list-response.json new file mode 100644 index 000000000..44d10d81b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_list-response.json @@ -0,0 +1,62 @@ +{ + "imemorys" : [ + { + "hugepages_configured" : "True", + "vm_hugepages_nr_1G_pending" : null, + "memavail_mib" : 22448, + "uuid" : "34098f3a-6b95-4cad-aecb-986dc6312f4f", + "ihost_uuid" : "afecdcfb-2954-498d-88bf-d1385b00f34d", + "created_at" : "2015-04-06T20:27:50.171841+00:00", + "vm_hugepages_avail_1G" : 0, + "capabilities" : {}, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.150.54:6385/v1/imemorys/34098f3a-6b95-4cad-aecb-986dc6312f4f" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.150.54:6385/imemorys/34098f3a-6b95-4cad-aecb-986dc6312f4f" + } + ], + "vm_hugepages_nr_2M_pending" : null, + "vm_hugepages_avail_2M" : 11224, + "numa_node" : 0, + "vm_hugepages_nr_1G" : 0, + "updated_at" : "2015-04-08T11:32:25.205552+00:00", + "platform_reserved_mib" : 4000, + "memtotal_mib" : 27056, + "vm_hugepages_nr_2M" : 13016, + "inode_uuid" : "c65c852c-1707-40e1-abfc-334270ec0427" + }, + { + "hugepages_configured" : "True", + "vm_hugepages_nr_1G_pending" : null, + "memavail_mib" : 24082, + "uuid" : "85df5109-77d9-4335-9181-0efa82c98dcc", + "ihost_uuid" : "afecdcfb-2954-498d-88bf-d1385b00f34d", + "created_at" : "2015-04-06T20:27:50.182764+00:00", + "vm_hugepages_avail_1G" : 0, + "capabilities" : {}, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.150.54:6385/v1/imemorys/85df5109-77d9-4335-9181-0efa82c98dcc" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.150.54:6385/imemorys/85df5109-77d9-4335-9181-0efa82c98dcc" + } + ], + "vm_hugepages_nr_2M_pending" : null, + "vm_hugepages_avail_2M" : 12041, + "numa_node" : 1, + "vm_hugepages_nr_1G" : 0, + "updated_at" : "2015-04-08T11:32:25.220242+00:00", + "platform_reserved_mib" : 2000, + "memtotal_mib" : 29202, + "vm_hugepages_nr_2M" : 14089, + "inode_uuid" : "67d3c9a0-57b2-4532-b7ea-f1cd16a3b349" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-request.json new file mode 100644 index 000000000..82b59939a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-request.json @@ -0,0 +1,17 @@ +[ + { + "path": "/platform_reserved_mib", + "value": "2000", + "op": "replace" + }, + { + "path": "/vm_hugepages_nr_1G_pending", + "value": "100", + "op": "replace" + }, + { + "path": "/vm_hugepages_nr_2M_pending", + "value": "50", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-response.json new file mode 100644 index 000000000..98b7a345b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_modify-response.json @@ -0,0 +1,29 @@ +{ + "hugepages_configured" : "True", + "vm_hugepages_nr_1G_pending" : null, + "memavail_mib" : 24082, + "uuid" : "85df5109-77d9-4335-9181-0efa82c98dcc", + "ihost_uuid" : "afecdcfb-2954-498d-88bf-d1385b00f34d", + "created_at" : "2015-04-06T20:27:50.182764+00:00", + "vm_hugepages_avail_1G" : 0, + "capabilities" : {}, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.150.54:6385/v1/imemorys/85df5109-77d9-4335-9181-0efa82c98dcc" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.150.54:6385/imemorys/85df5109-77d9-4335-9181-0efa82c98dcc" + } + ], + "vm_hugepages_nr_2M_pending" : null, + "vm_hugepages_avail_2M" : 12041, + "numa_node" : 1, + "vm_hugepages_nr_1G" : 0, + "updated_at" : "2015-04-08T11:33:25.280674+00:00", + "platform_reserved_mib" : 2000, + "memtotal_mib" : 29202, + "vm_hugepages_nr_2M" : 14089, + "inode_uuid" : "67d3c9a0-57b2-4532-b7ea-f1cd16a3b349" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_show-response.json new file mode 100644 index 000000000..98b7a345b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/memory_show-response.json @@ -0,0 +1,29 @@ +{ + "hugepages_configured" : "True", + "vm_hugepages_nr_1G_pending" : null, + "memavail_mib" : 24082, + "uuid" : "85df5109-77d9-4335-9181-0efa82c98dcc", + "ihost_uuid" : "afecdcfb-2954-498d-88bf-d1385b00f34d", + "created_at" : "2015-04-06T20:27:50.182764+00:00", + "vm_hugepages_avail_1G" : 0, + "capabilities" : {}, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.150.54:6385/v1/imemorys/85df5109-77d9-4335-9181-0efa82c98dcc" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.150.54:6385/imemorys/85df5109-77d9-4335-9181-0efa82c98dcc" + } + ], + "vm_hugepages_nr_2M_pending" : null, + "vm_hugepages_avail_2M" : 12041, + "numa_node" : 1, + "vm_hugepages_nr_1G" : 0, + "updated_at" : "2015-04-08T11:33:25.280674+00:00", + "platform_reserved_mib" : 2000, + "memtotal_mib" : 29202, + "vm_hugepages_nr_2M" : 14089, + "inode_uuid" : "67d3c9a0-57b2-4532-b7ea-f1cd16a3b349" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_list-response.json new file mode 100644 index 000000000..90e0c16d0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_list-response.json @@ -0,0 +1,29 @@ +{ + "networks": [{ + "uuid": "7b322329-8097-4233-a7df-83eafaba8447", + "dynamic": true, + "mtu": 1500, + "link_capacity": 1000, + "pool_uuid": "d7187d17-8715-4934-8754-4827e604a468", + "type": "mgmt", + "vlan_id": null + }, + { + "uuid": "bf226d1f-39a3-4c3f-abde-8077077835a4", + "dynamic": true, + "mtu": 1500, + "link_capacity": 1000, + "pool_uuid": "7b299949-614c-4f1a-85cb-c46a09827f0c", + "type": "infra", + "vlan_id": 99 + }, + { + "uuid": "d735fe97-6e10-4534-8720-1ee2d24ec8ae", + "dynamic": false, + "mtu": 1500, + "link_capacity": null, + "pool_uuid": "c5fced12-40ad-47fa-ad01-6800d1e418b7", + "type": "oam", + "vlan_id": null + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_show-response.json new file mode 100644 index 000000000..dd38515df --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/network_show-response.json @@ -0,0 +1,12 @@ +{ + "uuid": "bf226d1f-39a3-4c3f-abde-8077077835a4", + "created_at": "2016-11-09T14:53:20.185156+00:00", + "dynamic": true, + "updated_at": null, + "mtu": 1500, + "link_capacity": 1000, + "pool_uuid": "7b299949-614c-4f1a-85cb-c46a09827f0c", + "type": "infra", + "id": 2, + "vlan_id": 99 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-request.json new file mode 100644 index 000000000..b6aacdf57 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-request.json @@ -0,0 +1,12 @@ +[ + { + "path":"/ntpservers", + "value":"0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org", + "op":"replace" + }, + { + "path":"/action", + "value":"apply", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-response.json new file mode 100644 index 000000000..c6124ef00 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_modify-response.json @@ -0,0 +1,18 @@ +{ + "links":[ + { + "href":"http://192.168.204.2:6385/v1/intps/81321749-5092-4faf-94ba-6a6853440725", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/intps/81321749-5092-4faf-94ba-6a6853440725", + "rel":"bookmark" + } + ], + "created_at":"2014-09-30T14:42:16.693209+00:00", + "updated_at":"2014-10-01T17:35:43.162472+00:00", + "ntpservers":"0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org", + "isystem_uuid":"ce178041-2b2c-405d-bf87-f19334a35582", + "forisystemid":1, + "uuid":"81321749-5092-4faf-94ba-6a6853440725" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_show-response.json new file mode 100644 index 000000000..f253ce585 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/ntp_show-response.json @@ -0,0 +1,21 @@ +{ + "intps":[ + { + "links":[ + { + "href":"http://192.168.204.2:6385/v1/intps/81321749-5092-4faf-94ba-6a6853440725", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/intps/81321749-5092-4faf-94ba-6a6853440725", + "rel":"bookmark" + } + ], + "created_at":"2014-09-30T14:42:16.693209+00:00", + "updated_at":"2014-10-01T17:33:43.169595+00:00", + "ntpservers":"0.pool.ntp.org,2.pool.ntp.org,1.pool.ntp.org", + "isystem_uuid":"ce178041-2b2c-405d-bf87-f19334a35582", + "uuid":"81321749-5092-4faf-94ba-6a6853440725" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-request.json new file mode 100644 index 000000000..09f88ee94 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-request.json @@ -0,0 +1,6 @@ +{ + "ihost_uuid": "33178c5b-8b2b-45b4-b438-236a6eb4d0fd", + "size_mib": 256, + "type_guid": "ba5eba11-0000-1111-2222-000000000001", + "idisk_uuid": "9483349f-7612-4176-8ab7-957d840abf08"}, +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-response.json new file mode 100644 index 000000000..003b15b13 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_add-response.json @@ -0,0 +1,27 @@ +{ + "status": 2, + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part3", + "start_mib": null, + "uuid": "eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/partitions/eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/partitions/eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "rel": "bookmark" + } + ], + "capabilities": {}, + "created_at": "2017-08-30T22:10:39.796884+00:00", + "type_name": null, + "updated_at": null, + "device_node": "/dev/sdb3", + "ihost_uuid": "33178c5b-8b2b-45b4-b438-236a6eb4d0fd", + "ipv_uuid": null, + "end_mib": null, + "idisk_uuid": "9483349f-7612-4176-8ab7-957d840abf08", + "type_guid": "ba5eba11-0000-1111-2222-000000000001", + "size_mib": 256 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-request.json new file mode 100644 index 000000000..88f44c5b5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-request.json @@ -0,0 +1,3 @@ +{ + "size_mib": "512" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-response.json new file mode 100644 index 000000000..4ff2b6a28 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_edit-response.json @@ -0,0 +1,27 @@ +{ + "status": 2, + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part3", + "start_mib": null, + "uuid": "eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/partitions/eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/partitions/eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "rel": "bookmark" + } + ], + "capabilities": {}, + "created_at": "2017-08-30T22:10:39.796884+00:00", + "type_name": null, + "updated_at": null, + "device_node": "/dev/sdb3", + "ihost_uuid": "33178c5b-8b2b-45b4-b438-236a6eb4d0fd", + "ipv_uuid": null, + "end_mib": null, + "idisk_uuid": "9483349f-7612-4176-8ab7-957d840abf08", + "type_guid": "ba5eba11-0000-1111-2222-000000000001", + "size_mib": 512 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_list-response.json new file mode 100644 index 000000000..56bd691d3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_list-response.json @@ -0,0 +1,59 @@ +{ + "partitions": [ + { + "capabilities": {}, + "created_at": "2017-08-30T21:10:53.160862+00:00", + "device_node": "/dev/sdb2", + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part2", + "end_mib": 19968, + "idisk_uuid": "9483349f-7612-4176-8ab7-957d840abf08", + "ihost_uuid": "33178c5b-8b2b-45b4-b438-236a6eb4d0fd", + "ipv_uuid": null, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/partitions/209da106-ca41-4910-bb6a-8b498d5ac953", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/partitions/209da106-ca41-4910-bb6a-8b498d5ac953", + "rel": "bookmark" + } + ], + "size_mib": 512, + "start_mib": 512, + "status": 0, + "type_guid": "ba5eba11-0000-1111-2222-000000000001", + "type_name": "LVM Physical Volume", + "updated_at": "2017-08-30T21:11:24.107207+00:00", + "uuid": "209da106-ca41-4910-bb6a-8b498d5ac953" + }, + { + "capabilities": {}, + "created_at": "2017-08-30T22:10:39.796884+00:00", + "device_node": "/dev/sdb3", + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part3", + "end_mib": 20225, + "idisk_uuid": "9483349f-7612-4176-8ab7-957d840abf08", + "ihost_uuid": "33178c5b-8b2b-45b4-b438-236a6eb4d0fd", + "ipv_uuid": null, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/partitions/eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/partitions/eed80f15-0a31-43c3-a46c-a62cf4cecb7d", + "rel": "bookmark" + } + ], + "size_mib": 258, + "start_mib": 258, + "status": 0, + "type_guid": "ba5eba11-0000-1111-2222-000000000001", + "type_name": "LVM Physical Volume", + "updated_at": "2017-08-30T22:26:25.464595+00:00", + "uuid": "eed80f15-0a31-43c3-a46c-a62cf4cecb7d" + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_show-response.json new file mode 100644 index 000000000..206575cb5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/partition_show-response.json @@ -0,0 +1,27 @@ +{ + "capabilities": {}, + "created_at": "2017-08-30T21:10:53.160862+00:00", + "device_node": "/dev/sdb2", + "device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part2", + "end_mib": 19968, + "idisk_uuid": "9483349f-7612-4176-8ab7-957d840abf08", + "ihost_uuid": "33178c5b-8b2b-45b4-b438-236a6eb4d0fd", + "ipv_uuid": null, + "links": [ + { + "href": "http://10.10.2.2:6385/v1/partitions/209da106-ca41-4910-bb6a-8b498d5ac953", + "rel": "self" + }, + { + "href": "http://10.10.2.2:6385/partitions/209da106-ca41-4910-bb6a-8b498d5ac953", + "rel": "bookmark" + } + ], + "size_mib": 512, + "start_mib": 512, + "status": 0, + "type_guid": "ba5eba11-0000-1111-2222-000000000001", + "type_name": "LVM Physical Volume", + "updated_at": "2017-08-30T21:11:24.107207+00:00", + "uuid": "209da106-ca41-4910-bb6a-8b498d5ac953" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-request.json new file mode 100644 index 000000000..beaa0667b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-request.json @@ -0,0 +1,5 @@ +{ + "ilvg_uuid":"11ac6dfc-a5ea-4cc9-a0c9-50afb13f7b24", + "ihost_uuid":"a0f0a6d5-75ad-4769-8e0e-3a7c7c0ce783", + "idisk_uuid":"0e2e3ca6-841e-4315-ba1c-ad624415da2f" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-response.json new file mode 100644 index 000000000..542b17265 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_add-response.json @@ -0,0 +1,40 @@ +{ + "lvm_pe_alloced": 0, + "lvm_pe_total": 0, + "ilvg_uuid": "a0f0a6d5-75ad-4769-8e0e-3a7c7c0ce783", + "uuid": "4f504017-b0e8-4563-bb74-fc4d521c59f6", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/ipvs/4f504017-b0e8-4563-bb74-fc4d521c59f6", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ipvs/4f504017-b0e8-4563-bb74-fc4d521c59f6", + "rel": "bookmark" + } + ], + "idisks": [ + { + "href": "http://10.10.10.2:6385/v1/ipvs/4f504017-b0e8-4563-bb74-fc4d521c59f6/idisks", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ipvs/4f504017-b0e8-4563-bb74-fc4d521c59f6/idisks", + "rel": "bookmark" + } + ], + "lvm_pv_name": "/dev/sda7", + "created_at": "2015-03-11T05:03:31.649520+00:00", + "forilvgid": 2, + "idisk_uuid": "0e2e3ca6-841e-4315-ba1c-ad624415da2f", + "updated_at": null, + "pv_state": "adding", + "ihost_uuid": "a0f0a6d5-75ad-4769-8e0e-3a7c7c0ce783", + "pv_type": "partition", + "capabilities": {}, + "idisk_device_node": "/dev/sda", + "idisk_device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0", + "lvm_vg_name": "nova-local", + "lvm_pv_uuid": null, + "lvm_pv_size": 0 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_list-response.json new file mode 100644 index 000000000..70db4b93b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_list-response.json @@ -0,0 +1,34 @@ +{ + "ipvs": [ + { + "capabilities": {}, + "created_at": "2018-01-03T13:06:36.888057+00:00", + "disk_or_part_device_node": "/dev/sda4", + "disk_or_part_device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-1.0-part4", + "disk_or_part_uuid": "38c24bde-0488-4b50-9576-cfb555179698", + "forilvgid": 1, + "ihost_uuid": "28d70ad2-d722-458c-b361-8cf956e096ed", + "ilvg_uuid": "55786da6-0534-4f4c-b9d1-36a53b0ac510", + "links": [ + { + "href": "http://10.10.12.2:6385/v1/ipvs/a8f13d11-0d55-45ff-a964-98d6e75717ba", + "rel": "self" + }, + { + "href": "http://10.10.12.2:6385/ipvs/a8f13d11-0d55-45ff-a964-98d6e75717ba", + "rel": "bookmark" + } + ], + "lvm_pe_alloced": 1658, + "lvm_pe_total": 3199, + "lvm_pv_name": "/dev/sda4", + "lvm_pv_size": 107340627968, + "lvm_pv_uuid": "M1k6bc-sP7j-kpe2-YWWV-ckZy-zLRh-F6hzff", + "lvm_vg_name": "cgts-vg", + "pv_state": "provisioned", + "pv_type": "partition", + "updated_at": "2018-01-04T09:24:56.071039+00:00", + "uuid": "a8f13d11-0d55-45ff-a964-98d6e75717ba" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-request.json new file mode 100644 index 000000000..a84d2107e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-request.json @@ -0,0 +1,5 @@ +{ + TBD + TBD + TBD +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-response.json new file mode 100644 index 000000000..a84d2107e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_modify-response.json @@ -0,0 +1,5 @@ +{ + TBD + TBD + TBD +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_show-response.json new file mode 100644 index 000000000..0425ed57d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/physvolume_show-response.json @@ -0,0 +1,50 @@ +{ + "capabilities": {}, + "created_at": "2018-01-03T13:32:50.025647+00:00", + "disk_or_part_device_node": "/dev/sdb1", + "disk_or_part_device_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part1", + "disk_or_part_uuid": "ab8852dd-6c2e-421e-b6b6-abebeee6b790", + "forilvgid": 2, + "idisks": [ + { + "href": "http://10.10.12.2:6385/v1/ipvs/2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd/idisks", + "rel": "self" + }, + { + "href": "http://10.10.12.2:6385/ipvs/2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd/idisks", + "rel": "bookmark" + } + ], + "ihost_uuid": "28d70ad2-d722-458c-b361-8cf956e096ed", + "ilvg_uuid": "cf6094c9-380f-407e-91d2-4b3583702a96", + "links": [ + { + "href": "http://10.10.12.2:6385/v1/ipvs/2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd", + "rel": "self" + }, + { + "href": "http://10.10.12.2:6385/ipvs/2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd", + "rel": "bookmark" + } + ], + "lvm_pe_alloced": 1236, + "lvm_pe_total": 1249, + "lvm_pv_name": "/dev/drbd4", + "lvm_pv_size": 5238685696, + "lvm_pv_uuid": "8i5nt3-gyS0-QTwy-aPIr-YRwL-i4vc-rBTLtK", + "lvm_vg_name": "cinder-volumes", + "partitions": [ + { + "href": "http://10.10.12.2:6385/v1/ipvs/2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd/partitions", + "rel": "self" + }, + { + "href": "http://10.10.12.2:6385/ipvs/2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd/partitions", + "rel": "bookmark" + } + ], + "pv_state": "provisioned", + "pv_type": "partition", + "updated_at": "2018-01-04T12:59:48.788114+00:00", + "uuid": "2182ecc6-aab0-40f8-8e0e-d1ad9a9ccbdd" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_list-response.json new file mode 100644 index 000000000..4ee22da84 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_list-response.json @@ -0,0 +1,84 @@ +{ + "ports": [ + { + "links": [ + { + "href": "http://192.168.204.2:6385/v1/ports/972dd648-bec0-4204-a469-75c745a5994e", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ports/972dd648-bec0-4204-a469-75c745a5994e", + "rel": "bookmark" + } + ], + "inode_uuid": "e5d68519-eb07-4b28-8ca2-32bb476eeec1", + "updated_at": "2014-09-18T03:12:15.389263+00:00", + "ihost_uuid": "0aca08f9-882f-4491-8ffd-7368d20ead48", + "autoneg": null, + "speed": null, + "iinterface_uuid": null, + "uuid": "972dd648-bec0-4204-a469-75c745a5994e", + "pdevice": "I350 Gigabit Network Connection", + "capabilities": { + + }, + "psdevice": "Device 3592", + "link_mode": 0, + "bootp": null, + "mac": "00:1e:67:51:50:01", + "sriov_totalvfs": 63, + "sriov_numvfs": 0, + "sriov_vfs_pci_address": "", + "driver": "ixgbe", + "name": "eth0", + "psvendor": "Intel Corporation", + "numa_node": 0, + "created_at": "2014-09-18T03:12:15.334214+00:00", + "pclass": "Ethernet controller", + "mtu": 1500, + "pvendor": "Intel Corporation", + "pciaddr": "0000:0a:00.0", + "namedisplay": null + }, + { + "links": [ + { + "href": "http://192.168.204.2:6385/v1/ports/c822edfe-af87-4a15-ac9b-6a8123caede1", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ports/c822edfe-af87-4a15-ac9b-6a8123caede1", + "rel": "bookmark" + } + ], + "inode_uuid": "e5d68519-eb07-4b28-8ca2-32bb476eeec1", + "updated_at": "2014-09-22T02:00:43.938843+00:00", + "ihost_uuid": "0aca08f9-882f-4491-8ffd-7368d20ead48", + "autoneg": null, + "speed": null, + "iinterface_uuid": "b24caa6c-71b1-42be-8968-89abd269ea82", + "uuid": "c822edfe-af87-4a15-ac9b-6a8123caede1", + "pdevice": "82599EB 10-Gigabit SFI/SFP+ Network Connection", + "capabilities": { + + }, + "psdevice": "Ethernet Server Adapter X520-2", + "link_mode": 0, + "bootp": null, + "mac": "90:e2:ba:39:bb:8c", + "sriov_totalvfs": 63, + "sriov_numvfs": 0, + "sriov_vfs_pci_address": "", + "driver": "ixgbe", + "name": "eth4", + "psvendor": "Intel Corporation", + "numa_node": 0, + "created_at": "2014-09-18T03:12:15.325296+00:00", + "pclass": "Ethernet controller", + "mtu": 1500, + "pvendor": "Intel Corporation", + "pciaddr": "0000:05:00.0", + "namedisplay": null + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_show-response.json new file mode 100644 index 000000000..c569b39b4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/port_show-response.json @@ -0,0 +1,38 @@ +{ + "pdevice" : "82599EB 10-Gigabit SFI/SFP+ Network Connection", + "bootp" : null, + "uuid" : "c822edfe-af87-4a15-ac9b-6a8123caede1", + "ihost_uuid" : "0aca08f9-882f-4491-8ffd-7368d20ead48", + "pvendor" : "Intel Corporation", + "created_at" : "2014-09-18T03:12:15.325296+00:00", + "speed" : null, + "capabilities" : {}, + "mac" : "90:e2:ba:39:bb:8c", + "sriov_totalvfs": 63, + "sriov_numvfs": 0, + "sriov_vfs_pci_address": "", + "driver": "ixgbe", + "mtu" : 1500, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.243:6385/v1/ports/c822edfe-af87-4a15-ac9b-6a8123caede1" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.243:6385/ports/c822edfe-af87-4a15-ac9b-6a8123caede1" + } + ], + "psvendor" : "Intel Corporation", + "iinterface_uuid" : "b24caa6c-71b1-42be-8968-89abd269ea82", + "numa_node" : 0, + "pciaddr" : "0000:05:00.0", + "pclass" : "Ethernet controller", + "psdevice" : "Ethernet Server Adapter X520-2", + "updated_at" : "2014-09-22T02:00:43.938843+00:00", + "link_mode" : 0, + "autoneg" : null, + "pname" : "eth4", + "pnamedisplay" : null, + "inode_uuid" : "e5d68519-eb07-4b28-8ca2-32bb476eeec1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-request.json new file mode 100644 index 000000000..474d136a5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-request.json @@ -0,0 +1,5 @@ +{ + "profilename": "ifprofile-type-1", + "profiletype": "if", + "ihost_uuid": "959f785b-6387-4b98-aa30-bc861061d7a1" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-response.json new file mode 100644 index 000000000..1145c23f8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_add-response.json @@ -0,0 +1,106 @@ +{ + "ports": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/ports", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/ports", + "rel": "bookmark" + } + ], + "reserved": "False", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b", + "rel": "bookmark" + } + ], + "idisks": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/idisks", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/idisks", + "rel": "bookmark" + } + ], + "availability": "offline", + "updated_at": null, + "ihost_uuid": null, + "id": 23, + "icpus": [ + { + "href": "http://192.168.204.2:6385/v1/ihosts/b6bde724-4fda-4941-ae3f-15abd3d4107b/icpus", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/b6bde724-4fda-4941-ae3f-15abd3d4107b/icpus", + "rel": "bookmark" + } + ], + "uptime": 0, + "uuid": "b6bde724-4fda-4941-ae3f-15abd3d4107b", + "mgmt_ip": null, + "hostname": "ifprofile-type-1", + "istors": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/istors", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/istors", + "rel": "bookmark" + } + ], + "operational": "disabled", + "location": { + + }, + "invprovision": null, + "administrative": "locked", + "personality": null, + "iinterfaces": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/iinterfaces", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b/iinterfaces", + "rel": "bookmark" + } + ], + "profiletype": null, + "mgmt_mac": null, + "task": null, + "recordtype": "profile", + "created_at": "2014-09-29T13:36:36.760707+00:00", + "action": "none", + "profilename": null, + "serialId": null, + "inodes": [ + { + "href": "http://192.168.204.2:6385/v1/ihosts/b6bde724-4fda-4941-ae3f-15abd3d4107b/inodes", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/b6bde724-4fda-4941-ae3f-15abd3d4107b/inodes", + "rel": "bookmark" + } + ], + "imemorys": [ + { + "href": "http://192.168.204.2:6385/v1/ihosts/b6bde724-4fda-4941-ae3f-15abd3d4107b/imemorys", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ihosts/b6bde724-4fda-4941-ae3f-15abd3d4107b/imemorys", + "rel": "bookmark" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_list-response.json new file mode 100644 index 000000000..839a986cb --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_list-response.json @@ -0,0 +1,72 @@ +{ + "iprofiles": [ + { + "uuid": "b6bde724-4fda-4941-ae3f-15abd3d4107b", + "recordtype": "profile", + "task": null, + "reserved": "False", + "mgmt_ip": null, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/b6bde724-4fda-4941-ae3f-15abd3d4107b", + "rel": "bookmark" + } + ], + "personality": null, + "created_at": "2014-09-29T13:36:36.760707+00:00", + "hostname": "ifprofile-type-1", + "updated_at": null, + "id": 23, + "ihost_uuid": null, + "profiletype": null, + "location": { + + }, + "action": "none", + "profilename": null, + "operational": "disabled", + "administrative": "locked", + "availability": "offline", + "uptime": 0, + "mgmt_mac": null + }, + { + "uuid": "85b8d979-a1d5-4b06-8666-22646d45dcdf", + "recordtype": "profile", + "task": null, + "reserved": "False", + "mgmt_ip": null, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf", + "rel": "bookmark" + } + ], + "personality": null, + "created_at": "2014-09-29T13:42:40.592612+00:00", + "hostname": "ifprofile-type-2", + "updated_at": null, + "id": 24, + "ihost_uuid": null, + "profiletype": null, + "location": { + + }, + "action": "none", + "profilename": null, + "operational": "disabled", + "administrative": "locked", + "availability": "offline", + "uptime": 0, + "mgmt_mac": null + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_show-response.json new file mode 100644 index 000000000..9de73837e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/profile_show-response.json @@ -0,0 +1,104 @@ +{ + "ports" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/ports" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/ports" + } + ], + "operational" : "disabled", + "imemorys" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/ihosts/85b8d979-a1d5-4b06-8666-22646d45dcdf/imemorys" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/ihosts/85b8d979-a1d5-4b06-8666-22646d45dcdf/imemorys" + } + ], + "iinterfaces" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/iinterfaces" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/iinterfaces" + } + ], + "personality" : null, + "serialId" : null, + "hostname" : "ifprofile-type-2", + "profilename" : null, + "uuid" : "85b8d979-a1d5-4b06-8666-22646d45dcdf", + "profiletype" : null, + "ihost_uuid" : null, + "created_at" : "2014-09-29T13:42:40.592612+00:00", + "availability" : "offline", + "recordtype" : "profile", + "istors" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/istors" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/istors" + } + ], + "idisks" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/idisks" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf/idisks" + } + ], + "uptime" : 0, + "icpus" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/ihosts/85b8d979-a1d5-4b06-8666-22646d45dcdf/icpus" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/ihosts/85b8d979-a1d5-4b06-8666-22646d45dcdf/icpus" + } + ], + "id" : 24, + "mgmt_ip" : null, + "links" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/iprofile/85b8d979-a1d5-4b06-8666-22646d45dcdf" + } + ], + "location" : {}, + "inodes" : [ + { + "rel" : "self", + "href" : "http://128.224.151.244:6385/v1/ihosts/85b8d979-a1d5-4b06-8666-22646d45dcdf/inodes" + }, + { + "rel" : "bookmark", + "href" : "http://128.224.151.244:6385/ihosts/85b8d979-a1d5-4b06-8666-22646d45dcdf/inodes" + } + ], + "task" : null, + "mgmt_mac" : null, + "invprovision" : null, + "administrative" : "locked", + "updated_at" : null, + "action" : "none", + "reserved" : "False" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-request.json new file mode 100644 index 000000000..027ea112c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-request.json @@ -0,0 +1,27 @@ +[ + { + "path":"/ip_address", + "value":"10.10.10.45", + "op":"replace" + }, + { + "path":"/enabled", + "value":"True", + "op":"replace" + }, + { + "path":"/transport", + "value":"tcp", + "op":"replace" + }, + { + "path":"/port", + "value":"514", + "op":"replace" + }, + { + "path":"/action", + "value":"apply", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-response.json new file mode 100644 index 000000000..0f92708ce --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_modify-response.json @@ -0,0 +1,22 @@ +{ + "uuid":"319a1a4c-a1b1-4dc0-a29f-b257497619ef", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/remoteloggings/319a1a4c-a1b1-4dc0-a29f-b257497619ef", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/remoteloggings/319a1a4c-a1b1-4dc0-a29f-b257497619ef", + "rel":"bookmark" + } + ], + "created_at":"2016-11-10T19:57:37.969067+00:00", + "enabled":"True", + "updated_at":null, + "isystem_uuid":"036b338e-8217-4378-97b2-6a3c097882b4", + "action":null, + "key_file":null, + "ip_address":"10.10.10.45", + "port":514, + "transport":"tcp" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_show-response.json new file mode 100644 index 000000000..e598116cf --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/remotelogging_show-response.json @@ -0,0 +1,24 @@ +{ + "remoteloggings":[ + { + "uuid":"319a1a4c-a1b1-4dc0-a29f-b257497619ef", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/remoteloggings/319a1a4c-a1b1-4dc0-a29f-b257497619ef", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/remoteloggings/319a1a4c-a1b1-4dc0-a29f-b257497619ef", + "rel":"bookmark" + } + ], + "created_at":"2016-11-10T19:57:37.969067+00:00", + "enabled":"False", + "updated_at":null, + "key_file":null, + "ip_address":null, + "port":514, + "transport":"udp" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-request.json new file mode 100644 index 000000000..faee51287 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-request.json @@ -0,0 +1,6 @@ +{ + "state" : "enabled", + "ip_address" : "192.168.0.1", + "port" : "6640", + "transport" : "TCP" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-response.json new file mode 100644 index 000000000..acb12e786 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_add-response.json @@ -0,0 +1,17 @@ +{ + "uuid" : "55390e8e-1262-4945-8792-40a26206c8a0", + "links" : [{ + "href" : "http://192.168.204.2:6385/v1/sdn_controllers/55390e8e-1262-4945-8792-40a26206c8a0", + "rel" : "self" + }, { + "href" : "http://192.168.204.2:6385/sdn_controllers/55390e8e-1262-4945-8792-40a26206c8a0", + "rel" : "bookmark" + } + ], + "created_at" : "2016-08-16T17:06:25.368111+00:00", + "updated_at" : null, + "state" : "enabled", + "ip_address" : "192.168.0.1", + "port" : 6640, + "transport" : "TCP" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_list-response.json new file mode 100644 index 000000000..6281fc63f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_list-response.json @@ -0,0 +1,18 @@ +{ + "sdn_controllers" : [{ + "uuid" : "cdae53f1-d842-4a51-a64a-30a682611a24", + "links" : [{ + "href" : "http://192.168.204.2:6385/v1/sdn_controllers/cdae53f1-d842-4a51-a64a-30a682611a24", + "rel" : "self" + }, { + "href" : "http://192.168.204.2:6385/sdn_controllers/cdae53f1-d842-4a51-a64a-30a682611a24", + "rel" : "bookmark" + } + ], + "state" : "enabled", + "ip_address" : "192.168.0.1", + "port" : 6640, + "transport" : "TCP" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-request.json new file mode 100644 index 000000000..d76c4b3ae --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-request.json @@ -0,0 +1,10 @@ +[{ + "path" : "/state", + "value" : "disabled", + "op" : "replace" + }, { + "path" : "/transport", + "value" : "TCP", + "op" : "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-response.json new file mode 100644 index 000000000..f834bee35 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_modify-response.json @@ -0,0 +1,17 @@ +{ + "uuid" : "55390e8e-1262-4945-8792-40a26206c8a0", + "links" : [{ + "href" : "http://192.168.204.2:6385/v1/sdn_controllers/55390e8e-1262-4945-8792-40a26206c8a0", + "rel" : "self" + }, { + "href" : "http://192.168.204.2:6385/sdn_controllers/55390e8e-1262-4945-8792-40a26206c8a0", + "rel" : "bookmark" + } + ], + "created_at" : "2016-08-16T17:06:25.368111+00:00", + "updated_at" : "2016-08-16T17:13:31.035249+00:00", + "state" : "disabled", + "ip_address" : "192.168.0.1", + "port" : 6640, + "transport" : "TCP" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_show-response.json new file mode 100644 index 000000000..460f2a807 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sdn_controller_show-response.json @@ -0,0 +1,17 @@ +{ + "uuid" : "cdae53f1-d842-4a51-a64a-30a682611a24", + "links" : [{ + "href" : "http://192.168.204.2:6385/v1/sdn_controllers/cdae53f1-d842-4a51-a64a-30a682611a24", + "rel" : "self" + }, { + "href" : "http://192.168.204.2:6385/sdn_controllers/cdae53f1-d842-4a51-a64a-30a682611a24", + "rel" : "bookmark" + } + ], + "created_at" : "2016-08-16T13:04:30.997350+00:00", + "updated_at" : null, + "state" : "enabled", + "ip_address" : "192.168.0.1", + "port" : 6640, + "transport" : "TCP" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_list-response.json new file mode 100644 index 000000000..f1d7d453c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_list-response.json @@ -0,0 +1,154 @@ +{ + "isensors":[ + { + "t_critical_upper":"120", + "actions_minor":"ignore", + "sensorname":"cpu0temp", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensors/18daed11-4c89-46ae-9197-a741e9c0bd2c", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensors/18daed11-4c89-46ae-9197-a741e9c0bd2c", + "rel":"bookmark" + } + ], + "updated_at":"2015-09-08T13:37:36.366979+00:00", + "path":null, + "state_requested":null, + "t_major_lower":"-20", + "uuid":"18daed11-4c89-46ae-9197-a741e9c0bd2c", + "t_minor_upper":"85", + "capabilities":{ + + }, + "actions_critical":"alarm", + "state":"enabled", + "sensorgroup_uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "t_major_upper":"105", + "actions_major":"alarm", + "status":"ok", + "suppress":"False", + "sensortype":"temperature", + "t_critical_lower":"-40", + "t_minor_lower":"-10", + "unit_rate":null, + "unit_modifier":"1", + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "unit_base":"Celcius", + "algorithm":null, + "datatype":"analog", + "created_at":"2015-09-08T12:45:49.337205+00:00", + "audit_interval":null + }, + { + "t_critical_upper":"120", + "actions_minor":"ignore", + "sensorname":"cpu1temp", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensors/b6567aa3-f52f-44ef-8231-1df901f8c977", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensors/b6567aa3-f52f-44ef-8231-1df901f8c977", + "rel":"bookmark" + } + ], + "updated_at":"2015-09-08T13:43:08.497704+00:00", + "path":null, + "state_requested":null, + "t_major_lower":"-20", + "uuid":"b6567aa3-f52f-44ef-8231-1df901f8c977", + "t_minor_upper":"85", + "capabilities":{ + + }, + "actions_critical":"alarm", + "state":"enabled", + "sensorgroup_uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "t_major_upper":"105", + "actions_major":"alarm", + "status":"ok", + "suppress":"False", + "sensortype":"temperature", + "t_critical_lower":"-40", + "t_minor_lower":"-10", + "unit_rate":null, + "unit_modifier":"1", + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "unit_base":"Celcius", + "algorithm":null, + "datatype":"analog", + "created_at":"2015-09-08T12:45:55.638149+00:00", + "audit_interval":null + }, + { + "status":null, + "actions_minor":null, + "uuid":"d6258b09-5e2e-44d4-bec7-930d378e237c", + "algorithm":null, + "updated_at":null, + "datatype":"discrete", + "suppress":"False", + "created_at":"2015-09-08T13:46:17.790654+00:00", + "sensorgroup_uuid":null, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensors/d6258b09-5e2e-44d4-bec7-930d378e237c", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensors/d6258b09-5e2e-44d4-bec7-930d378e237c", + "rel":"bookmark" + } + ], + "capabilities":{ + + }, + "actions_critical":null, + "sensortype":"watchdog", + "state":null, + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "state_requested":null, + "path":null, + "audit_interval":null, + "actions_major":null, + "sensorname":"cpuwdt" + }, + { + "status":"ok", + "actions_minor":null, + "uuid":"27f49183-cf73-434c-bff5-5e02ba6076fc", + "algorithm":null, + "updated_at":"2015-09-08T13:47:17.738427+00:00", + "datatype":"discrete", + "suppress":"False", + "created_at":"2015-09-08T13:46:42.624861+00:00", + "sensorgroup_uuid":null, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensors/27f49183-cf73-434c-bff5-5e02ba6076fc", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensors/27f49183-cf73-434c-bff5-5e02ba6076fc", + "rel":"bookmark" + } + ], + "capabilities":{ + + }, + "actions_critical":null, + "sensortype":"watchdog", + "state":"enabled", + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "state_requested":null, + "path":null, + "audit_interval":null, + "actions_major":null, + "sensorname":"fwwdt" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-request.json new file mode 100644 index 000000000..d8e467b08 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/suppress", + "value":"False", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-response.json new file mode 100644 index 000000000..c594129fb --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_modify-response.json @@ -0,0 +1,42 @@ +{ + "t_critical_upper":"120", + "actions_minor":"ignore", + "sensorname":"cpu1temp", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensors/b6567aa3-f52f-44ef-8231-1df901f8c977", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensors/b6567aa3-f52f-44ef-8231-1df901f8c977", + "rel":"bookmark" + } + ], + "updated_at":"2015-09-08T13:42:55.448781+00:00", + "path":null, + "state_requested":null, + "t_major_lower":"-20", + "uuid":"b6567aa3-f52f-44ef-8231-1df901f8c977", + "t_minor_upper":"85", + "capabilities":{ + + }, + "actions_critical":"alarm", + "state":"enabled", + "sensorgroup_uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "t_major_upper":"105", + "actions_major":"alarm", + "status":"ok", + "suppress":"False", + "sensortype":"temperature", + "t_critical_lower":"-40", + "t_minor_lower":"-10", + "unit_rate":null, + "unit_modifier":"1", + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "unit_base":"Celcius", + "algorithm":null, + "datatype":"analog", + "created_at":"2015-09-08T12:45:55.638149+00:00", + "audit_interval":60 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_show-response.json new file mode 100644 index 000000000..c9aab101d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensor_show-response.json @@ -0,0 +1,43 @@ +{ + "t_critical_upper":"120", + "actions_minor":"ignore", + "sensorname":"cpu1temp", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensors/b6567aa3-f52f-44ef-8231-1df901f8c977", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensors/b6567aa3-f52f-44ef-8231-1df901f8c977", + "rel":"bookmark" + } + ], + "updated_at":"2015-09-08T13:37:36.396138+00:00", + "path":null, + "state_requested":null, + "t_major_lower":"-20", + "uuid":"b6567aa3-f52f-44ef-8231-1df901f8c977", + "t_minor_upper":"85", + "capabilities":{ + + }, + "actions_critical":"alarm", + "state":"enabled", + "sensorgroup_uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "t_major_upper":"105", + "actions_major":"alarm", + "status":"ok", + "suppress":"False", + "sensortype":"temperature", + "t_critical_lower":"-40", + "t_minor_lower":"-10", + "unit_rate":null, + "unit_modifier":"1", + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "unit_base":"Celcius", + "algorithm":null, + "datatype":"analog", + "created_at":"2015-09-08T12:45:55.638149+00:00", + "audit_interval":60 +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_list-response.json new file mode 100644 index 000000000..a6d1edbca --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_list-response.json @@ -0,0 +1,97 @@ +{ + "isensorgroups":[ + { + "audit_interval_group":null, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b", + "rel":"bookmark" + } + ], + "t_critical_upper_group":"120", + "updated_at":"2015-09-08T13:37:36.426408+00:00", + "isensors":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b/isensors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b/isensors", + "rel":"bookmark" + } + ], + "t_critical_lower_group":"-40", + "t_minor_upper_group":"85", + "t_minor_lower_group":"-10", + "uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "unit_modifier_group":"1", + "capabilities":{ + + }, + "state":null, + "unit_rate_group":null, + "actions_major_group":"alarm", + "suppress":"False", + "actions_minor_group":"ignore", + "sensorgroupname":"cpuTemp", + "sensors":null, + "actions_configurable":null, + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "t_major_lower_group":"-20", + "unit_base_group":"Celcius", + "sensortype":"temperature", + "algorithm":null, + "datatype":"analog", + "possible_states":null, + "created_at":"2015-09-08T12:46:36.808611+00:00", + "actions_critical_group":"alarm", + "t_major_upper_group":"10" + }, + { + "actions_minor_group":"ignore", + "audit_interval_group":60, + "actions_major_group":"alarm", + "uuid":"3d05da03-d973-465f-bba1-ddbc14a4f36e", + "algorithm":null, + "datatype":"discrete", + "possible_states":null, + "created_at":"2015-09-08T13:48:27.615374+00:00", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/3d05da03-d973-465f-bba1-ddbc14a4f36e", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/3d05da03-d973-465f-bba1-ddbc14a4f36e", + "rel":"bookmark" + } + ], + "capabilities":{ + + }, + "updated_at":"2015-09-08T13:49:47.098184+00:00", + "sensortype":"watchdog", + "sensorgroupname":"watchdogSystem", + "state":null, + "isensors":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/3d05da03-d973-465f-bba1-ddbc14a4f36e/isensors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/3d05da03-d973-465f-bba1-ddbc14a4f36e/isensors", + "rel":"bookmark" + } + ], + "suppress":"False", + "sensors":null, + "actions_configurable":"alarm", + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "actions_critical_group":"alarm" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-request.json new file mode 100644 index 000000000..fe9a618bf --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-request.json @@ -0,0 +1,17 @@ +[ + { + "path":"/actions_critical_group", + "value":"alarm", + "op":"replace" + }, + { + "path":"/actions_major_group", + "value":"alarm", + "op":"replace" + }, + { + "path":"/actions_minor_group", + "value":"ignore", + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-response.json new file mode 100644 index 000000000..6c5a6a2af --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_modify-response.json @@ -0,0 +1,51 @@ +{ + "audit_interval_group":null, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b", + "rel":"bookmark" + } + ], + "t_critical_upper_group":"120", + "updated_at":"2015-09-08T13:37:15.547558+00:00", + "isensors":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b/isensors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b/isensors", + "rel":"bookmark" + } + ], + "t_critical_lower_group":"-40", + "t_minor_upper_group":"85", + "t_minor_lower_group":"-10", + "uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "unit_modifier_group":"1", + "capabilities":{ + + }, + "state":'enabled', + "unit_rate_group":null, + "actions_major_group":"alarm", + "suppress":"False", + "actions_minor_group":"ignore", + "sensorgroupname":"cpuTemp", + "sensors":null, + "actions_configurable":null, + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "t_major_lower_group":"-20", + "unit_base_group":"Celcius", + "sensortype":"temperature", + "algorithm":null, + "datatype":"analog", + "possible_states":null, + "created_at":"2015-09-08T12:46:36.808611+00:00", + "actions_critical_group":"alarm", + "t_major_upper_group":"10" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_show-response.json new file mode 100644 index 000000000..4fe9a7a22 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sensorgroup_show-response.json @@ -0,0 +1,51 @@ +{ + "audit_interval_group":null, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b", + "rel":"bookmark" + } + ], + "t_critical_upper_group":"120", + "updated_at":"2015-09-08T13:37:36.426408+00:00", + "isensors":[ + { + "href":"http://192.168.204.2:6385/v1/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b/isensors", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/isensorgroups/58f297b6-7d32-409a-979b-e141ca50c39b/isensors", + "rel":"bookmark" + } + ], + "t_critical_lower_group":"-40", + "t_minor_upper_group":"85", + "t_minor_lower_group":"-10", + "uuid":"58f297b6-7d32-409a-979b-e141ca50c39b", + "unit_modifier_group":"1", + "capabilities":{ + + }, + "state":null, + "unit_rate_group":null, + "actions_major_group":"alarm", + "suppress":"False", + "actions_minor_group":"ignore", + "sensorgroupname":"cpuTemp", + "sensors":null, + "actions_configurable":null, + "host_uuid":"0a66f89c-412c-4480-a38d-fdad248467a3", + "t_major_lower_group":"-20", + "unit_base_group":"Celcius", + "sensortype":"temperature", + "algorithm":null, + "datatype":"analog", + "possible_states":null, + "created_at":"2015-09-08T12:46:36.808611+00:00", + "actions_critical_group":"alarm", + "t_major_upper_group":"10" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_list-response.json new file mode 100644 index 000000000..737ce14a7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_list-response.json @@ -0,0 +1,81 @@ +{ + "sm_servicegroup":[ + { + "status":"", + "name":"controller", + "service_group_name":"web-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":1, + "condition":"", + "uuid":"e3aa5e50-030b-4ab6-a339-929f0be50e5d" + }, + { + "status":"", + "name":"controller", + "service_group_name":"directory-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":2, + "condition":"", + "uuid":"f7b01783-ea3d-44b8-8dd3-9a0c4a1cae9d" + }, + { + "status":"", + "name":"controller", + "service_group_name":"patching-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":3, + "condition":"", + "uuid":"f64bc693-62fa-4f31-b96e-9851c42669ec" + }, + { + "status":"", + "name":"controller", + "service_group_name":"vim-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":4, + "condition":"", + "uuid":"e7dab99d-7bdc-4756-b8b3-b069e7b26e0d" + }, + { + "status":"", + "name":"controller", + "service_group_name":"cloud-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":5, + "condition":"", + "uuid":"149e9f4e-13ba-4d91-9e0e-09905073fda6" + }, + { + "status":"", + "name":"controller", + "service_group_name":"controller-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":6, + "condition":"", + "uuid":"54d46994-9c0e-43bd-8d83-be7396f04f70" + }, + { + "status":"", + "name":"controller", + "service_group_name":"oam-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":7, + "condition":"", + "uuid":"f7b532bf-0dc0-41bd-b38a-75b7747da754" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_show-response.json new file mode 100644 index 000000000..538d18436 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_group_show-response.json @@ -0,0 +1,11 @@ +{ + "status":"", + "name":"controller", + "service_group_name":"oam-services", + "node_name":"controller-1", + "state":"active", + "desired_state":"active", + "id":7, + "condition":"", + "uuid":"f7b532bf-0dc0-41bd-b38a-75b7747da754" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_list-response.json new file mode 100644 index 000000000..a9f2199ee --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_list-response.json @@ -0,0 +1,39 @@ +{ + "services":[ + { + "status":"", + "state":"enabled-active", + "id":5, + "desired_state":"enabled-active", + "name":"drbd-cgcs" + }, + { + "status":"", + "state":"enabled-active", + "id":3, + "desired_state":"enabled-active", + "name":"drbd-pg" + }, + { + "status":"", + "state":"enabled-active", + "id":4, + "desired_state":"enabled-active", + "name":"drbd-rabbit" + }, + { + "status":"", + "state":"enabled-active", + "id":2, + "desired_state":"enabled-active", + "name":"management-ip" + }, + { + "status":"", + "state":"enabled-active", + "id":1, + "desired_state":"enabled-active", + "name":"oam-ip" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-request.json new file mode 100644 index 000000000..9474b90bc --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path":"/enabled", + "value":true, + "op":"replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-response.json new file mode 100644 index 000000000..f6cb33ebd --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_modify-response.json @@ -0,0 +1,6 @@ +{ + "created_at":"2017-03-08T15:45:08.984813+00:00", + "enabled":true, + "name":"murano", + "updated_at":null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_list-response.json new file mode 100644 index 000000000..e8da62855 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_list-response.json @@ -0,0 +1,20 @@ +{ + "nodes":[ + { + "administrative_state":"unlocked", + "ready_state":"disabled", + "name":"controller-0", + "operational_state":"disabled", + "availability_status":"unknown", + "id":2 + }, + { + "administrative_state":"unlocked", + "ready_state":"enabled", + "name":"controller-1", + "operational_state":"enabled", + "availability_status":"available", + "id":1 + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_show-response.json new file mode 100644 index 000000000..fbff27b50 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_node_show-response.json @@ -0,0 +1,8 @@ +{ + "administrative_state":"unlocked", + "ready_state":"enabled", + "name":"controller-1", + "operational_state":"enabled", + "availability_status":"available", + "id":1 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-request.json new file mode 100644 index 000000000..547a9b2b4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-request.json @@ -0,0 +1,9 @@ +{ + "section":"ldap", + "parameters":{ + "url":"ldap://localhost", + "allow_subtree_delete":"False" + }, + "service":"identity" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-response.json new file mode 100644 index 000000000..f71445216 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_add-response.json @@ -0,0 +1,39 @@ +{ + "uuid":"399ec29b-5cf4-45e2-a9d0-a640a5a1760c", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/parameters/399ec29b-5cf4-45e2-a9d0-a640a5a1760c", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/parameters/399ec29b-5cf4-45e2-a9d0-a640a5a1760c", + "rel":"bookmark" + } + ], + "section":"ldap", + "updated_at":null, + "value":"ldap://localhost", + "service":"identity", + "created_at":"2015-12-24T15:29:54.954563+00:00", + "name":"url" +} +{ + "uuid":"cff25627-0f2e-42b3-a8b0-34d491c15728", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/parameters/cff25627-0f2e-42b3-a8b0-34d491c15728", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/parameters/cff25627-0f2e-42b3-a8b0-34d491c15728", + "rel":"bookmark" + } + ], + "section":"ldap", + "updated_at":null, + "value":"False", + "service":"identity", + "created_at":"2015-12-24T15:29:54.957636+00:00", + "name":"allow_subtree_delete" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_apply-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_apply-request.json new file mode 100644 index 000000000..2b6acc6dc --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_apply-request.json @@ -0,0 +1,4 @@ +{ + "service":"identity" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_list-response.json new file mode 100644 index 000000000..dfe3af2f5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_list-response.json @@ -0,0 +1,73 @@ +{ + "parameters":[ + { + "uuid":"7694eca1-21e0-4998-bf2c-15f71b3bddc5", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/parameters/7694eca1-21e0-4998-bf2c-15f71b3bddc5", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/parameters/7694eca1-21e0-4998-bf2c-15f71b3bddc5", + "rel":"bookmark" + } + ], + "section":"assignment", + "value":"keystone.assignment.backends.sql.Assignment", + "service":"identity", + "name":"driver" + }, + { + "uuid":"5eeebd50-4809-4d2e-b4ce-1acd9cfeadab", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/parameters/5eeebd50-4809-4d2e-b4ce-1acd9cfeadab", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/parameters/5eeebd50-4809-4d2e-b4ce-1acd9cfeadab", + "rel":"bookmark" + } + ], + "section":"identity", + "value":"keystone.identity.backends.sql.Identity", + "service":"identity", + "name":"driver" + }, + { + "uuid":"b84378ae-6e0a-48f0-b394-f8a519fc14f4", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/parameters/b84378ae-6e0a-48f0-b394-f8a519fc14f4", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/parameters/b84378ae-6e0a-48f0-b394-f8a519fc14f4", + "rel":"bookmark" + } + ], + "section":"resource", + "value":"keystone.resource.backends.sql.Resource", + "service":"identity", + "name":"driver" + }, + { + "uuid":"6634285f-428e-4ebe-becd-cbb0ab7f30ad", + "links":[ + { + "href":"http://10.10.10.2:6385/v1/parameters/6634285f-428e-4ebe-becd-cbb0ab7f30ad", + "rel":"self" + }, + { + "href":"http://10.10.10.2:6385/parameters/6634285f-428e-4ebe-becd-cbb0ab7f30ad", + "rel":"bookmark" + } + ], + "section":"role", + "value":"keystone.assignment.role_backends.sql.Role", + "service":"identity", + "name":"driver" + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-request.json new file mode 100644 index 000000000..e161e1b50 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-request.json @@ -0,0 +1,13 @@ +[ + { + "path":"/name", + "value":"suffix", + "op":"replace" + }, + { + "path":"/value", + "value":"dc=openstack,dc=org", + "op":"replace" + } +] + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-response.json new file mode 100644 index 000000000..6de0b1e58 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_modify-response.json @@ -0,0 +1,20 @@ +{ + "uuid":"b1d07555-ac16-4d5a-ba00-8191f4047bd6", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/parameters/b1d07555-ac16-4d5a-ba00-8191f4047bd6", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/parameters/b1d07555-ac16-4d5a-ba00-8191f4047bd6", + "rel":"bookmark" + } + ], + "section":"ldap", + "updated_at":"2015-12-24T15:37:06.091315+00:00", + "value":"dc=openstack,dc=org", + "service":"identity", + "created_at":"2015-12-23T18:58:03.166244+00:00", + "name":"suffix" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_show-response.json new file mode 100644 index 000000000..ad1b80bd6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_parameter_show-response.json @@ -0,0 +1,20 @@ +{ + "uuid":"fd5e5e4c-2723-430a-b162-b06b49d94313", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/parameters/fd5e5e4c-2723-430a-b162-b06b49d94313", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/parameters/fd5e5e4c-2723-430a-b162-b06b49d94313", + "rel":"bookmark" + } + ], + "section":"identity", + "updated_at":"2015-12-23T19:07:41.257052+00:00", + "value":"keystone.identity.backends.sql.Identity", + "service":"identity", + "created_at":"2015-12-23T18:54:53.676200+00:00", + "name":"driver" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_show-response.json new file mode 100644 index 000000000..d37f86a3c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/service_show-response.json @@ -0,0 +1,7 @@ +{ + "status":"", + "state":"enabled-active", + "id":1, + "desired_state":"enabled-active", + "name":"oam-ip" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_backend_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_backend_list-response.json new file mode 100644 index 000000000..c189d25b4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_backend_list-response.json @@ -0,0 +1,26 @@ +{ + "storage_backends": [ + { + "task": null, + "uuid": "9172f885-4a84-41e0-89cd-e350d7fcfeb7", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_backends/9172f885-4a84-41e0-89cd-e350d7fcfeb7", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_backends/9172f885-4a84-41e0-89cd-e350d7fcfeb7", + "rel": "bookmark" + } + ], + "created_at": "2018-02-06T07:03:55.373879+00:00", + "updated_at": "2018-02-06T07:04:04.760902+00:00", + "capabilities": {}, + "services": "glance", + "state": "configured", + "isystem_uuid": "d0f2c2ff-9fc2-4ad3-869f-ef9ea6367c0e", + "backend": "file", + "name": "file-store" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-request.json new file mode 100644 index 000000000..1e25cfb19 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-request.json @@ -0,0 +1,4 @@ +{ + "services": "cinder,glance", + "confirmed": true +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-response.json new file mode 100644 index 000000000..78c4cf2f7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_add-response.json @@ -0,0 +1,33 @@ +{ + "confirmed": false, + "tier_uuid": null, + "cinder_pool_gib": null, + "uuid": "253f5801-e8bc-468d-a040-1bfa918541ac", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_ceph/253f5801-e8bc-468d-a040-1bfa918541ac", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_ceph/253f5801-e8bc-468d-a040-1bfa918541ac", + "rel": "bookmark" + } + ], + "name": "ceph-store", + "object_pool_gib": null, + "updated_at": null, + "capabilities": { + "min_replication": "1", + "replication": "2" + }, + "ceph_total_space_gib": 0, + "backend": "ceph", + "glance_pool_gib": null, + "state": "configuring", + "task": "applying-manifests", + "tier_name": null, + "services": "cinder,glance", + "object_gateway": false, + "created_at": "2018-02-07T08:39:00.880044+00:00", + "ephemeral_pool_gib": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_list-response.json new file mode 100644 index 000000000..994c6548a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_list-response.json @@ -0,0 +1,69 @@ +{ + "storage_ceph": [ + { + "backend": "ceph", + "capabilities": { + "min_replication": "1", + "replication": "2" + }, + "ceph_total_space_gib": 0, + "cinder_pool_gib": 27, + "created_at": "2018-03-04T07:19:51.699172+00:00", + "ephemeral_pool_gib": 0, + "glance_pool_gib": 21, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/storage_ceph/bb6a60f6-7fe2-407d-afd0-21d8b6e2f128", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/storage_ceph/bb6a60f6-7fe2-407d-afd0-21d8b6e2f128", + "rel": "bookmark" + } + ], + "name": "ceph-store", + "object_gateway": true, + "object_pool_gib": 0, + "services": "cinder,glance,swift", + "state": "configured", + "task": "restore", + "tier_name": "storage", + "tier_uuid": "dcb41fcc-307a-4d0b-b5dd-af8c6a48a3c5", + "updated_at": "2018-03-08T06:13:02.485985+00:00", + "uuid": "bb6a60f6-7fe2-407d-afd0-21d8b6e2f128" + }, + { + "backend": "ceph", + "capabilities": { + "min_replication": "1", + "replication": "2" + }, + "ceph_total_space_gib": 0, + "cinder_pool_gib": 0, + "created_at": "2018-03-07T18:56:22.525053+00:00", + "ephemeral_pool_gib": null, + "glance_pool_gib": null, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/storage_ceph/6320a6d5-e3d7-4e63-a02c-964b9a4460f8", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/storage_ceph/6320a6d5-e3d7-4e63-a02c-964b9a4460f8", + "rel": "bookmark" + } + ], + "name": "gold-store", + "object_gateway": false, + "object_pool_gib": null, + "services": "cinder", + "state": "configured", + "task": null, + "tier_name": "gold", + "tier_uuid": "270e8fa4-8f38-4410-a54a-8e44d8f24f6f", + "updated_at": "2018-03-07T18:56:56.221489+00:00", + "uuid": "6320a6d5-e3d7-4e63-a02c-964b9a4460f8" + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-request.json new file mode 100644 index 000000000..1dd919629 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-request.json @@ -0,0 +1,5 @@ +{ + "path": "/capabilities", + "value": "{\\"min_replication\\": \\"2\\"}", + "op": "replace" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-response.json new file mode 100644 index 000000000..2861d03ac --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_modify-response.json @@ -0,0 +1,30 @@ +{ + "backend": "ceph", + "capabilities": { + "min_replication": "2", + "replication": "2" + }, + "ceph_total_space_gib": 0, + "cinder_pool_gib": 0, + "confirmed": false, + "created_at": "2018-01-04T11:15:41.957698+00:00", + "ephemeral_pool_gib": 0, + "glance_pool_gib": 20, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/storage_ceph/3f14980c-018f-4f6c-8bfb-82d7c665df06", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/storage_ceph/3f14980c-018f-4f6c-8bfb-82d7c665df06", + "rel": "bookmark" + } + ], + "object_gateway": false, + "object_pool_gib": 0, + "services": "cinder,glance", + "state": "configured", + "task": null, + "updated_at": "2018-01-08T01:53:44.446623+00:00", + "uuid": "3f14980c-018f-4f6c-8bfb-82d7c665df06" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_show-response.json new file mode 100644 index 000000000..9a7dd89ab --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_ceph_show-response.json @@ -0,0 +1,33 @@ +{ + "backend": "ceph", + "capabilities": { + "min_replication": "1", + "replication": "2" + }, + "ceph_total_space_gib": 0, + "cinder_pool_gib": 27, + "created_at": "2018-03-04T07:19:51.699172+00:00", + "ephemeral_pool_gib": 0, + "glance_pool_gib": 21, + "links": [ + { + "href": "http://192.168.204.2:6385/v1/storage_ceph/bb6a60f6-7fe2-407d-afd0-21d8b6e2f128", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/storage_ceph/bb6a60f6-7fe2-407d-afd0-21d8b6e2f128", + "rel": "bookmark" + } + ], + "name": "ceph-store", + "object_gateway": true, + "object_pool_gib": 0, + "services": "cinder,glance,swift", + "state": "configured", + "task": "restore", + "tier_name": "storage", + "tier_uuid": "dcb41fcc-307a-4d0b-b5dd-af8c6a48a3c5", + "updated_at": "2018-03-08T06:13:02.485985+00:00", + "uuid": "bb6a60f6-7fe2-407d-afd0-21d8b6e2f128" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-request.json new file mode 100644 index 000000000..6c9703f1f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-request.json @@ -0,0 +1,5 @@ +{ + "name": "new-shared-services", + "services": "cinder", + "confirmed": true +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-response.json new file mode 100644 index 000000000..289f96591 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_add-response.json @@ -0,0 +1,23 @@ +{ + "backend": "external", + "capabilities": {}, + "confirmed": false, + "created_at": "2018-03-08T19:12:34.419453+00:00", + "links": [ + { + "href": "http://192.168.144.103:6385/v1/storage_file/a9c3d775-8913-4b92-a091-3bd1b905a6a5", + "rel": "self" + }, + { + "href": "http://192.168.144.103:6385/storage_file/a9c3d775-8913-4b92-a091-3bd1b905a6a5", + "rel": "bookmark" + } + ], + "name": "new-shared-services", + "services": "glance", + "state": "configuring", + "task": null, + "updated_at": null, + "uuid": "a9c3d775-8913-4b92-a091-3bd1b905a6a5" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_list-response.json new file mode 100644 index 000000000..a405401ea --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_list-response.json @@ -0,0 +1,26 @@ +{ + "storage_external": [ + { + "backend": "external", + "capabilities": {}, + "created_at": "2018-03-08T07:28:59.840381+00:00", + "links": [ + { + "href": "http://192.168.144.103:6385/v1/storage_external/38803ac0-aa33-431f-ae43-e09d86eb4fa5", + "rel": "self" + }, + { + "href": "http://192.168.144.103:6385/storage_external/38803ac0-aa33-431f-ae43-e09d86eb4fa5", + "rel": "bookmark" + } + ], + "name": "shared_services", + "services": "glance", + "state": "configured", + "task": null, + "updated_at": null, + "uuid": "38803ac0-aa33-431f-ae43-e09d86eb4fa5" + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-request.json new file mode 100644 index 000000000..65ab44d76 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/services", + "value": "glance,cinder", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_modify-response.json new file mode 100644 index 000000000..e69de29bb diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_show-response.json new file mode 100644 index 000000000..445d87dad --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_external_show-response.json @@ -0,0 +1,23 @@ +{ + "backend": "external", + "capabilities": {}, + "confirmed": false, + "created_at": "2018-03-08T07:28:59.840381+00:00", + "links": [ + { + "href": "http://192.168.144.103:6385/v1/storage_external/38803ac0-aa33-431f-ae43-e09d86eb4fa5", + "rel": "self" + }, + { + "href": "http://192.168.144.103:6385/storage_external/38803ac0-aa33-431f-ae43-e09d86eb4fa5", + "rel": "bookmark" + } + ], + "name": "shared_services", + "services": "glance", + "state": "configured", + "task": null, + "updated_at": null, + "uuid": "38803ac0-aa33-431f-ae43-e09d86eb4fa5" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-request.json new file mode 100644 index 000000000..92cfd393e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-request.json @@ -0,0 +1,5 @@ +{ + "name": "new-file-store", + "services": "glance", + "confirmed": true +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-response.json new file mode 100644 index 000000000..2ef390a89 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_add-response.json @@ -0,0 +1,22 @@ +{ + "confirmed": false, + "task": null, + "uuid": "c70ab134-20f3-419f-8048-66ba9fae960d", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_file/c70ab134-20f3-419f-8048-66ba9fae960d", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_file/c70ab134-20f3-419f-8048-66ba9fae960d", + "rel": "bookmark" + } + ], + "created_at": "2018-02-07T09:19:35.077198+00:00", + "updated_at": null, + "capabilities": {}, + "name": "new-file-store", + "state": "configuring", + "services": "glance", + "backend": "file" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_list-response.json new file mode 100644 index 000000000..9ed989825 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_list-response.json @@ -0,0 +1,26 @@ +{ + "storage_file": [ + { + "backend": "file", + "capabilities": {}, + "created_at": "2018-03-08T05:29:55.246907+00:00", + "links": [ + { + "href": "http://192.168.144.2:6385/v1/storage_file/e9e734b0-8143-4835-b70a-21267f5d8ca9", + "rel": "self" + }, + { + "href": "http://192.168.144.2:6385/storage_file/e9e734b0-8143-4835-b70a-21267f5d8ca9", + "rel": "bookmark" + } + ], + "name": "file-store", + "services": "glance", + "state": "configured", + "task": null, + "updated_at": "2018-03-08T05:29:59.518621+00:00", + "uuid": "e9e734b0-8143-4835-b70a-21267f5d8ca9" + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-request.json new file mode 100644 index 000000000..65ab44d76 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/services", + "value": "glance,cinder", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-response.json new file mode 100644 index 000000000..b5c66e7b2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_modify-response.json @@ -0,0 +1,3 @@ +{ + "error_message": "{\"debuginfo\": null, \"faultcode\": \"Client\", \"faultstring\": \"Service cinder is not supported for the file backend\"}" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_show-response.json new file mode 100644 index 000000000..1684d75a6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_file_show-response.json @@ -0,0 +1,23 @@ +{ + "backend": "file", + "capabilities": {}, + "confirmed": false, + "created_at": "2018-03-08T19:12:34.419453+00:00", + "links": [ + { + "href": "http://192.168.144.103:6385/v1/storage_file/a9c3d775-8913-4b92-a091-3bd1b905a6a5", + "rel": "self" + }, + { + "href": "http://192.168.144.103:6385/storage_file/a9c3d775-8913-4b92-a091-3bd1b905a6a5", + "rel": "bookmark" + } + ], + "name": "file-store", + "services": "glance", + "state": "configured", + "task": null, + "updated_at": "2018-03-08T19:12:34.463159+00:00", + "uuid": "a9c3d775-8913-4b92-a091-3bd1b905a6a5" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-request.json new file mode 100644 index 000000000..69a682b9a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-request.json @@ -0,0 +1,4 @@ +{ + "services": "cinder", + "confirmed": true +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-response.json new file mode 100644 index 000000000..e1c3d3289 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_add-response.json @@ -0,0 +1,22 @@ +{ + "confirmed": false, + "task": null, + "name": "lvm-store", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_lvm/5798d210-bbfc-436a-84f3-66dfd1d18aef", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_lvm/5798d210-bbfc-436a-84f3-66dfd1d18aef", + "rel": "bookmark" + } + ], + "created_at": "2018-02-07T07:47:42.841988+00:00", + "uuid": "5798d210-bbfc-436a-84f3-66dfd1d18aef", + "capabilities": {}, + "updated_at": null, + "state": "configuring", + "services": "cinder", + "backend": "lvm" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_list-response.json new file mode 100644 index 000000000..b3d707212 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_list-response.json @@ -0,0 +1,26 @@ +{ + "storage_lvm": [ + { + "backend": "lvm", + "capabilities": {}, + "created_at": "2018-03-08T07:52:40.795489+00:00", + "links": [ + { + "href": "http://192.168.144.103:6385/v1/storage_lvm/4d966cf9-c721-4d44-b9f8-7b7f98e4dc89", + "rel": "self" + }, + { + "href": "http://192.168.144.103:6385/storage_lvm/4d966cf9-c721-4d44-b9f8-7b7f98e4dc89", + "rel": "bookmark" + } + ], + "name": "lvm-store", + "services": "cinder", + "state": "configured", + "task": null, + "updated_at": "2018-03-08T07:55:07.253739+00:00", + "uuid": "4d966cf9-c721-4d44-b9f8-7b7f98e4dc89" + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-request.json new file mode 100644 index 000000000..66e21b0c6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/services", + "value": "cinder,glance", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-response.json new file mode 100644 index 000000000..909ce17c8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_modify-response.json @@ -0,0 +1,3 @@ +{ + "error_message": "{\"debuginfo\": null, \"faultcode\": \"Client\", \"faultstring\": \"Service glance is not supported for the lvm backend\"}" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_show-response.json new file mode 100644 index 000000000..93f10d315 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_lvm_show-response.json @@ -0,0 +1,23 @@ +{ + "backend": "lvm", + "capabilities": {}, + "confirmed": false, + "created_at": "2018-03-08T07:52:40.795489+00:00", + "links": [ + { + "href": "http://192.168.144.103:6385/v1/storage_lvm/4d966cf9-c721-4d44-b9f8-7b7f98e4dc89", + "rel": "self" + }, + { + "href": "http://192.168.144.103:6385/storage_lvm/4d966cf9-c721-4d44-b9f8-7b7f98e4dc89", + "rel": "bookmark" + } + ], + "name": "lvm-store", + "services": "cinder", + "state": "configured", + "task": null, + "updated_at": "2018-03-08T07:55:07.253739+00:00", + "uuid": "4d966cf9-c721-4d44-b9f8-7b7f98e4dc89" +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-request.json new file mode 100644 index 000000000..5cb8abd7f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-request.json @@ -0,0 +1,5 @@ +{ + "name": "new-tier", + "type": "ceph", + "cluster_uuid": "ba42aa45-7094-4bcd-b094-2848816441a3" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-response.json new file mode 100644 index 000000000..90db103a2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_add-response.json @@ -0,0 +1,33 @@ +{ + "status": "defined", + "uuid": "5ff4a489-dcbc-4fd2-a04a-1a95f4a45780", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780", + "rel": "bookmark" + } + ], + "stors": [], + "created_at": "2018-02-07T09:27:24.482961+00:00", + "istors": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780/istors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780/istors", + "rel": "bookmark" + } + ], + "updated_at": null, + "capabilities": {}, + "cluster_uuid": "ba42aa45-7094-4bcd-b094-2848816441a3", + "backend_uuid": null, + "type": "ceph", + "forclusterid": 1, + "name": "new-tier" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_list-response.json new file mode 100644 index 000000000..b7e36bb1c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_list-response.json @@ -0,0 +1,26 @@ +{ + "storage_tiers": [ + { + "status": "in-use", + "uuid": "70184946-7b3e-4833-a4f8-e46edf006e37", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/70184946-7b3e-4833-a4f8-e46edf006e37", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/70184946-7b3e-4833-a4f8-e46edf006e37", + "rel": "bookmark" + } + ], + "stors": [], + "created_at": "2018-02-07T04:34:27.078558+00:00", + "updated_at": "2018-02-07T08:39:00.950066+00:00", + "capabilities": {}, + "cluster_uuid": "ba42aa45-7094-4bcd-b094-2848816441a3", + "backend_uuid": "253f5801-e8bc-468d-a040-1bfa918541ac", + "type": "ceph", + "name": "storage" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-request.json new file mode 100644 index 000000000..a9833be5d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/name", + "value": "really-new-tier", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-response.json new file mode 100644 index 000000000..9295d9594 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_modify-response.json @@ -0,0 +1,33 @@ +{ + "status": "defined", + "uuid": "5ff4a489-dcbc-4fd2-a04a-1a95f4a45780", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780", + "rel": "bookmark" + } + ], + "stors": [], + "created_at": "2018-02-07T09:27:24.482961+00:00", + "istors": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780/istors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/5ff4a489-dcbc-4fd2-a04a-1a95f4a45780/istors", + "rel": "bookmark" + } + ], + "updated_at": null, + "capabilities": {}, + "cluster_uuid": "ba42aa45-7094-4bcd-b094-2848816441a3", + "backend_uuid": null, + "type": "ceph", + "forclusterid": 1, + "name": "really-new-tier" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_show-response.json new file mode 100644 index 000000000..65a61eba8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_tier_show-response.json @@ -0,0 +1,32 @@ +{ + "status": "in-use", + "uuid": "70184946-7b3e-4833-a4f8-e46edf006e37", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/70184946-7b3e-4833-a4f8-e46edf006e37", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/70184946-7b3e-4833-a4f8-e46edf006e37", + "rel": "bookmark" + } + ], + "stors": [], + "created_at": "2018-02-07T04:34:27.078558+00:00", + "istors": [ + { + "href": "http://10.10.10.2:6385/v1/storage_tiers/70184946-7b3e-4833-a4f8-e46edf006e37/istors", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/storage_tiers/70184946-7b3e-4833-a4f8-e46edf006e37/istors", + "rel": "bookmark" + } + ], + "updated_at": "2018-02-07T08:39:00.950066+00:00", + "capabilities": {}, + "cluster_uuid": "ba42aa45-7094-4bcd-b094-2848816441a3", + "backend_uuid": "253f5801-e8bc-468d-a040-1bfa918541ac", + "type": "ceph", + "name": "storage" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_usage_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_usage_list-response.json new file mode 100644 index 000000000..a7968c2e0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/storage_usage_list-response.json @@ -0,0 +1,16 @@ +[ + { + "free_capacity": 7.48, + "service_name": "glance", + "total_capacity": 7.84, + "name": "file-store", + "backend": "file" + }, + { + "free_capacity": 6.9, + "service_name": "cinder", + "total_capacity": 6.9, + "name": "lvm-store", + "backend": "lvm" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sysinv-versions-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sysinv-versions-response.json new file mode 100644 index 000000000..31a632c5b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/sysinv-versions-response.json @@ -0,0 +1,24 @@ +{ + "default_version":{ + "id":"v1", + "links":[ + { + "href":"http://128.224.150.54:6385/v1/", + "rel":"self" + } + ] + }, + "versions":[ + { + "id":"v1", + "links":[ + { + "href":"http://128.224.150.54:6385/v1/", + "rel":"self" + } + ] + } + ], + "description":"Titanium Cloud System API allows for the management of physical servers. This includes inventory collection and configuration of hosts, ports, interfaces, CPUs, disk, memory, and system configuration. The API also supports alarms and fault collection for the cloud itself as well as the configuration of the cloud's SNMP interface. ", + "name":"Titanium SysInv API" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health-response.json new file mode 100644 index 000000000..c92bfd4e2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health-response.json @@ -0,0 +1 @@ +"System Health:\nAll hosts are provisioned: [OK]\nAll hosts are unlocked/enabled: [OK]\nAll hosts have current configurations: [OK]\nAll hosts are patch current: [OK]\nNo alarms: [OK]\n" \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health_upgrade-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health_upgrade-response.json new file mode 100644 index 000000000..acccb8273 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_health_upgrade-response.json @@ -0,0 +1 @@ +"System Health:\nAll hosts are provisioned: [OK]\nAll hosts are unlocked/enabled: [OK]\nAll hosts have current configurations: [OK]\nAll hosts are patch current: [OK]\nNo alarms: [OK]\nRequired patches are applied: [OK]\nLicense valid for upgrade: [OK]\n" \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-request.json new file mode 100644 index 000000000..c5fd7a679 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-request.json @@ -0,0 +1,37 @@ +[ + { + "path": "/name", + "value": "OTTAWA_LAB_WEST", + "op": "replace" + } + { + "path": "/description", + "value": "The Ottawa Cloud Test Lab - West Wing.", + "op": "replace" + } + { + "path": "/location", + "value": "350 Terry Fox Dr, Kanata, Ontario, Canada", + "op": "replace" + } + { + "path": "/contact", + "value": "support@windriver.com", + "op": "replace" + } + { + "path": "/system_mode", + "value": "duplex-direct", + "op": "replace" + } + { + "path": "/timezone", + "value": "UTC", + "op": "replace" + } + { + "path": "/sdn_enabled", + "value": "true", + "op": "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-response.json new file mode 100644 index 000000000..dec269b4a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_modify-response.json @@ -0,0 +1,35 @@ +{ + "isystems": [ + { + "links": [ + { + "href": "http://192.168.204.2:6385/v1/isystems/5ce48a37-f6f5-4f14-8fbd-ac6393464b19", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/isystems/5ce48a37-f6f5-4f14-8fbd-ac6393464b19", + "rel": "bookmark" + } + ], + "description": "The Ottawa Cloud Test Lab - West Wing.", + "software_version": "18.03", + "updated_at": "2017-07-31T17:44:06.051441+00:00", + "created_at": "2017-07-31T17:35:46.836024+00:00", + "location": "350 Terry Fox Dr, Kanata, Ontario, Canada", + "capabilities": { + "sdn_enabled": true, + "shared_services": "[]", + "bm_region": "External", + "cinder_backend": "lvm", + "https_enabled": true, + "region_config": false + }, + "name": "OTTAWA_LAB_WEST", + "contact": "support@windriver.com", + "system_type": "Standard", + "system_mode": "duplex", + "timezone": "UTC", + "uuid": "5ce48a37-f6f5-4f14-8fbd-ac6393464b19" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_show-response.json new file mode 100644 index 000000000..b70e11126 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/system_show-response.json @@ -0,0 +1,35 @@ +{ + "isystems": [ + { + "uuid": "67e5fca6-3580-4b06-acc8-3200dce794a4", + "software_version": "Golden Gate 14.08 3.4.103-ovp-ga2-rt120-WR5.0.1.17_standard ", + "name": "OTTAWA_LAB", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/isystems/67e5fca6-3580-4b06-acc8-3200dce794a4", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/isystems/67e5fca6-3580-4b06-acc8-3200dce794a4", + "rel": "bookmark" + } + ], + "created_at": "2014-09-17T19:08:11.325946+00:00", + "updated_at": "2014-09-24T14:35:38.091392+00:00", + "contact": null, + "location": null, + "description": "The Ottawa Cloud Test Lab.", + "system_type": "Standard", + "system_mode": "duplex", + "timezone": "UTC", + "capabilities": { + "sdn_enabled": false, + "shared_services": "[]", + "bm_region": "External", + "cinder_backend": "lvm", + "https_enabled": false, + "region_config": false + }, + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-request.json new file mode 100644 index 000000000..10367842b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-request.json @@ -0,0 +1,5 @@ +{ + "cert_path" : "/etc/ssl/private/key.pem", + "public_path" : "/etc/ssl/private/cert.pem", + "tpm_path" : "/etc/ssl/private/object.tpm" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-response.json new file mode 100644 index 000000000..5e9c13db5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_add-response.json @@ -0,0 +1,19 @@ +{ + "tpm_path": "/etc/ssl/private/object.tpm", + "uuid": "6e06345a-9d02-41bf-9af7-4593ad7db14c", + "links": [{ + "href": "http://192.168.204.2:6385/v1/tpmconfigs/6e06345a-9d02-41bf-9af7-4593ad7db14c", + "rel": "self" + }, { + "href": "http://192.168.204.2:6385/tpmconfigs/6e06345a-9d02-41bf-9af7-4593ad7db14c", + "rel": "bookmark" + }], + "public_path": null, + "created_at": "2017-05-30T16:52:36.788395+00:00", + "updated_at": null, + "state": { + "controller-0": "tpm-config-applying", + "controller-1": "tpm-config-applying" + }, + "cert_path": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-request.json new file mode 100644 index 000000000..8996a8824 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-request.json @@ -0,0 +1,14 @@ +[{ + "path" : "/cert_path", + "value" : "/etc/ssl/private/key2.pem", + "op" : "replace" + }, { + "path" : "/public_path", + "value" : "/etc/ssl/private/cert2.pem", + "op" : "replace" + }, { + "path" : "/tpm_path", + "value" : "/etc/ssl/private/object2.tpm", + "op" : "replace" + } +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-response.json new file mode 100644 index 000000000..1b849e41e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_modify-response.json @@ -0,0 +1,19 @@ +{ + "tpm_path": "/etc/ssl/private/object2.tpm", + "uuid": "6e06345a-9d02-41bf-9af7-4593ad7db14c", + "links": [{ + "href": "http://192.168.204.2:6385/v1/tpmconfigs/6e06345a-9d02-41bf-9af7-4593ad7db14c", + "rel": "self" + }, { + "href": "http://192.168.204.2:6385/tpmconfigs/6e06345a-9d02-41bf-9af7-4593ad7db14c", + "rel": "bookmark" + }], + "public_path": null, + "created_at": "2017-05-30T16:52:36.788395+00:00", + "updated_at": "2017-06-21T15:12:16.666333+00:00", + "state": { + "controller-0": "tpm-config-applying", + "controller-1": "tpm-config-applying" + }, + "cert_path": null +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_show-response.json new file mode 100644 index 000000000..de69aa047 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/tpmconfig_show-response.json @@ -0,0 +1,20 @@ +{ + "tpmconfigs": [{ + "tpm_path": "/etc/ssl/private/object.tpm", + "uuid": "556159b8-f39b-47ec-a410-e2d5499b6661", + "links": [{ + "href": "http://192.168.204.2:6385/v1/tpmconfigs/556159b8-f39b-47ec-a410-e2d5499b6661", + "rel": "self" + }, { + "href": "http://192.168.204.2:6385/tpmconfigs/556159b8-f39b-47ec-a410-e2d5499b6661", + "rel": "bookmark" + }], + "public_path": null, + "created_at": "2017-05-30T14:49:16.445438+00:00", + "updated_at": null, + "state": { + "controller-0": "tpm-config-applied" + }, + "cert_path": null + }] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-request.json new file mode 100644 index 000000000..51fa1b8c6 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-request.json @@ -0,0 +1,4 @@ +{ + "ip_address": "27.134.0.8", + "community": "sprint" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-response.json new file mode 100644 index 000000000..7379eadd7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_add-response.json @@ -0,0 +1,20 @@ +{ + "uuid": "22f0497c-0a09-41c4-8514-cb5afcbf930d", "links": + [ + { + "href": "http://192.168.204.2:6385/v1/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "bookmark" + } + ], + "type": "snmpv2c_trap", + "created_at": "2014-09-24T21:09:02.842231+00:00", + "updated_at": null, + "community": "sprint", + "ip_address": "27.134.0.8", + "port": 162, + "transport": "udp" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_list-response.json new file mode 100644 index 000000000..19fddb2a5 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_list-response.json @@ -0,0 +1,37 @@ +{ + "itrapdest": [ + { + "uuid": "fc33945c-7aba-4d83-9216-a60db7097a23", "links": [ + { + "href": "http://192.168.204.2:6385/v1/itrapdest/fc33945c-7aba-4d83-9216-a60db7097a23", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/itrapdest/fc33945c-7aba-4d83-9216-a60db7097a23", + "rel": "bookmark" + } + ], + "ip_address": "10.10.10.1", + "community": "cgts", + "type": "snmpv2c_trap", + "port": 162, "transport": "udp" + }, + { + "uuid": "22f0497c-0a09-41c4-8514-cb5afcbf930d", "links": [ + { + "href": "http://192.168.204.2:6385/v1/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "bookmark" + } + ], + "ip_address": "27.134.0.8", + "community": "sprint", + "type": "snmpv2c_trap", + "port": 162, + "transport": "udp" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-request.json new file mode 100644 index 000000000..69b246f70 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-request.json @@ -0,0 +1,13 @@ +[ + { + "path": "/ip_address", + "value": "47.10.1.128", + "op": "replace" + }, + { + "path": "/community", + "value": "sprint", + "op": "replace" + } +] + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-response.json new file mode 100644 index 000000000..5efd610f3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_modify-response.json @@ -0,0 +1,19 @@ +{ + "uuid": "22f0497c-0a09-41c4-8514-cb5afcbf930d", "links": [ + { + "href": "http://192.168.204.2:6385/v1/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "bookmark" + } + ], + "type": "snmpv2c_trap", + "created_at": "2014-09-24T21:09:02.842231+00:00", + "updated_at": "2014-09-24T21:13:51.061300+00:00", + "community": "sprint", + "ip_address": "47.10.1.128", + "port": 162, + "transport": "udp" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_show-response.json new file mode 100644 index 000000000..3e8d60fa2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/trapdest_show-response.json @@ -0,0 +1,19 @@ +{ + "uuid": "22f0497c-0a09-41c4-8514-cb5afcbf930d", "links": [ + { + "href": "http://192.168.204.2:6385/v1/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/itrapdest/22f0497c-0a09-41c4-8514-cb5afcbf930d", + "rel": "bookmark" + } + ], + "type": "snmpv2c_trap", + "created_at": "2014-09-24T21:09:02.842231+00:00", + "updated_at": null, + "community": "sprint", + "ip_address": "27.134.0.8", + "port": 162, + "transport": "udp" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_delete-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_delete-response.json new file mode 100644 index 000000000..d5405af8d --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_delete-response.json @@ -0,0 +1,21 @@ +{ + "uuid": "d0a6a564-0539-4f76-ab5f-2213e20193fe", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/upgrades/d0a6a564-0539-4f76-ab5f-2213e20193fe", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/upgrades/d0a6a564-0539-4f76-ab5f-2213e20193fe", + "rel": "bookmark" + } + ], + "created_at": "2017-02-27T17:10:40.033745+00:00", + "from_load": 1, + "from_release": "15.12", + "updated_at": "2017-03-06T17:51:43.906711+00:00", + "state": "completing", + "to_load": 2, + "to_release": "16.10", + "id": 1 +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-request.json new file mode 100644 index 000000000..9ae8a6126 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-request.json @@ -0,0 +1 @@ +[{"path": "/state", "value": "activation-requested", "op": "replace"}] \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-response.json new file mode 100644 index 000000000..de8306144 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_patch-response.json @@ -0,0 +1,21 @@ +{ + "uuid": "d0a6a564-0539-4f76-ab5f-2213e20193fe", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/upgrades/d0a6a564-0539-4f76-ab5f-2213e20193fe", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/upgrades/d0a6a564-0539-4f76-ab5f-2213e20193fe", + "rel": "bookmark" + } + ], + "created_at": "2017-02-27T17:10:40.033745+00:00", + "from_load": 1, + "from_release": "15.12", + "updated_at": "2017-03-06T16:36:23.294777+00:00", + "state": "activation-requested", + "to_load": 2, + "to_release": "16.10", + "id": 1 +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_show-response.json new file mode 100644 index 000000000..bca94f9d7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_show-response.json @@ -0,0 +1,20 @@ +{ + "upgrades": [ + { + "state": "activating", + "to_release": "16.10", + "uuid": "d0a6a564-0539-4f76-ab5f-2213e20193fe", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/upgrades/d0a6a564-0539-4f76-ab5f-2213e20193fe", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/upgrades/d0a6a564-0539-4f76-ab5f-2213e20193fe", + "rel": "bookmark" + } + ], + "from_release": "15.12" + } + ] +} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-request.json new file mode 100644 index 000000000..e16d0c2c8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-request.json @@ -0,0 +1 @@ +{"force": false} \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-response.json new file mode 100644 index 000000000..73f4526d4 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/upgrade_start-response.json @@ -0,0 +1,21 @@ +{ + "uuid": "452298f3-dfd2-495f-9a4e-f611a03b93e6", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/upgrades/452298f3-dfd2-495f-9a4e-f611a03b93e6", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/upgrades/452298f3-dfd2-495f-9a4e-f611a03b93e6", + "rel": "bookmark" + } + ], + "created_at": "2017-03-07T16:35:36.662098+00:00", + "from_load": 1, + "from_release": "16.10", + "updated_at": null, + "state": "starting", + "to_load": 2, + "to_release": "18.03", + "id": 1 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/version-get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/version-get-response.json new file mode 100644 index 000000000..31a632c5b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/version-get-response.json @@ -0,0 +1,24 @@ +{ + "default_version":{ + "id":"v1", + "links":[ + { + "href":"http://128.224.150.54:6385/v1/", + "rel":"self" + } + ] + }, + "versions":[ + { + "id":"v1", + "links":[ + { + "href":"http://128.224.150.54:6385/v1/", + "rel":"self" + } + ] + } + ], + "description":"Titanium Cloud System API allows for the management of physical servers. This includes inventory collection and configuration of hosts, ports, interfaces, CPUs, disk, memory, and system configuration. The API also supports alarms and fault collection for the cloud itself as well as the configuration of the cloud's SNMP interface. ", + "name":"Titanium SysInv API" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/versionv1-get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/versionv1-get-response.json new file mode 100644 index 000000000..dbb2ae95a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/versionv1-get-response.json @@ -0,0 +1,190 @@ +{ + "ihosts":[ + { + "href":"http://128.224.150.54:6385/v1/ihosts/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/ihosts/", + "rel":"bookmark" + } + ], + "media_types":[ + { + "base":"application/json", + "type":"application/vnd.openstack.sysinv.v1+json" + } + ], + "links":[ + { + "href":"http://128.224.150.54:6385/v1/", + "rel":"self" + }, + { + "href":"http://www.windriver.com/developer/sysinv/dev/api-spec-v1.html", + "type":"text/html", + "rel":"describedby" + } + ], + "inode":[ + { + "href":"http://128.224.150.54:6385/v1/inode/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/inode/", + "rel":"bookmark" + } + ], + "imemory":[ + { + "href":"http://128.224.150.54:6385/v1/imemory/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/imemory/", + "rel":"bookmark" + } + ], + "idns":[ + { + "href":"http://128.224.150.54:6385/v1/idns/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/idns/", + "rel":"bookmark" + } + ], + "iuser":[ + { + "href":"http://128.224.150.54:6385/v1/iuser/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/iuser/", + "rel":"bookmark" + } + ], + "itrapdest":[ + { + "href":"http://128.224.150.54:6385/v1/itrapdest/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/itrapdest/", + "rel":"bookmark" + } + ], + "istorconfig":[ + { + "href":"http://128.224.150.54:6385/v1/istorconfig/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/istorconfig/", + "rel":"bookmark" + } + ], + "iextoam":[ + { + "href":"http://128.224.150.54:6385/v1/iextoam/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/iextoam/", + "rel":"bookmark" + } + ], + "intp":[ + { + "href":"http://128.224.150.54:6385/v1/intp/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/intp/", + "rel":"bookmark" + } + ], + "isystems":[ + { + "href":"http://128.224.150.54:6385/v1/isystems/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/isystems/", + "rel":"bookmark" + } + ], + "iprofile":[ + { + "href":"http://128.224.150.54:6385/v1/iprofile/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/iprofile/", + "rel":"bookmark" + } + ], + "icpu":[ + { + "href":"http://128.224.150.54:6385/v1/icpu/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/icpu/", + "rel":"bookmark" + } + ], + "ialarms":[ + { + "href":"http://128.224.150.54:6385/v1/ialarms/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/ialarms/", + "rel":"bookmark" + } + ], + "event_log":[ + { + "href":"http://128.224.150.54:6385/v1/event_log/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/event_log/", + "rel":"bookmark" + } + ], + "event_suppression":[ + { + "href":"http://128.224.150.54:6385/v1/event_suppression/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/event_suppression/", + "rel":"bookmark" + } + ], + "icommunity":[ + { + "href":"http://128.224.150.54:6385/v1/icommunity/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/icommunity/", + "rel":"bookmark" + } + ], + "iinfra":[ + { + "href":"http://128.224.150.54:6385/v1/iinfra/", + "rel":"self" + }, + { + "href":"http://128.224.150.54:6385/iinfra/", + "rel":"bookmark" + } + ], + "id":"v1", +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-request.json new file mode 100644 index 000000000..55b1a15ef --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-request.json @@ -0,0 +1,7 @@ +{ + "function":"osd", + "ihost_uuid":"42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "idisk_uuid":"4da10410-2959-46df-b571-04e954c0e115", + "journal_location":"0929aa31-ee1a-406d-82b1-308be72b300a", + "journal_size":1024, +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-response.json new file mode 100644 index 000000000..332704c8f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_add-response.json @@ -0,0 +1,39 @@ +{ + "function":"osd", + "uuid":"31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "journal_location":"0929aa31-ee1a-406d-82b1-308be72b300a", + "journal_size_mib":1024, + "journal_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0-part2", + "journal_node": "/dev/sdb2", + "tier_name": "storage", + "tier_uuid": "dcb41fcc-307a-4d0b-b5dd-af8c6a48a3c5", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"bookmark" + } + ], + "idisks":[ + { + "href":"http://192.168.204.2:6385/v1/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0/idisks", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0/idisks", + "rel":"bookmark" + } + ], + "created_at":"2014-10-01T21:41:23+00:00", + "updated_at":null, + "idisk_uuid":"4da10410-2959-46df-b571-04e954c0e115", + "ihost_uuid":"42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "state":null, + "capabilities":{ + + }, + "osdid":2 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-request.json new file mode 100644 index 000000000..fc771aa4b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-request.json @@ -0,0 +1,4 @@ +{ + "journal_location":"e0f12323-f9b9-4ca0-a79b-bc9e7a6d7084", + "journal_size_mib":2500, +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-response.json new file mode 100644 index 000000000..6b4221c52 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_edit-response.json @@ -0,0 +1,39 @@ +{ + "function":"osd", + "uuid":"31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "journal_location":"e0f12323-f9b9-4ca0-a79b-bc9e7a6d7084", + "journal_size_mib":2500, + "journal_path": "/dev/disk/by-path/pci-0000:00:0d.0-ata-3.0-part1", + "journal_node": "/dev/sdc1", + "tier_name": "storage", + "tier_uuid": "dcb41fcc-307a-4d0b-b5dd-af8c6a48a3c5", + "links":[ + { + "href":"http://192.168.204.2:6385/v1/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"bookmark" + } + ], + "idisks":[ + { + "href":"http://192.168.204.2:6385/v1/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0/idisks", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0/idisks", + "rel":"bookmark" + } + ], + "created_at":"2014-10-01T21:41:23+00:00", + "updated_at":null, + "idisk_uuid":"4da10410-2959-46df-b571-04e954c0e115", + "ihost_uuid":"42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "state":null, + "capabilities":{ + + }, + "osdid":2 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_list-response.json new file mode 100644 index 000000000..7cfd0500c --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_list-response.json @@ -0,0 +1,28 @@ +{ + "istors":[ + { + "function":"osd", + "uuid":"31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "journal_location":"0929aa31-ee1a-406d-82b1-308be72b300a", + "journal_size_mib":2500, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"bookmark" + } + ], + "created_at":"2014-10-01T21:41:23.973344+00:00", + "updated_at":"2014-10-01T21:41:24.129134+00:00", + "capabilities":{ + + }, + "ihost_uuid":"42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "state":null, + "osdid":2 + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-request.json new file mode 100644 index 000000000..fc771aa4b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-request.json @@ -0,0 +1,4 @@ +{ + "journal_location":"e0f12323-f9b9-4ca0-a79b-bc9e7a6d7084", + "journal_size_mib":2500, +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-response.json new file mode 100644 index 000000000..a84d2107e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_modify-response.json @@ -0,0 +1,5 @@ +{ + TBD + TBD + TBD +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_show-response.json new file mode 100644 index 000000000..5f321ea3a --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volume_show-response.json @@ -0,0 +1,28 @@ +{ + "istors":[ + { + "function":"osd", + "uuid":"31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "journal_location":"0929aa31-ee1a-406d-82b1-308be72b300a", + "journal_size":1024, + "links":[ + { + "href":"http://192.168.204.2:6385/v1/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"self" + }, + { + "href":"http://192.168.204.2:6385/istors/31c7a5a3-9154-462a-9ea3-ab5c5e0d06e0", + "rel":"bookmark" + } + ], + "created_at":"2014-10-01T21:41:23.973344+00:00", + "updated_at":"2014-10-01T21:41:24.129134+00:00", + "capabilities":{ + + }, + "ihost_uuid":"42d72247-e0e3-4a5a-8cb1-40bbee52c8db", + "state":null, + "osdid":2 + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-request.json new file mode 100644 index 000000000..bfb84f8ed --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-request.json @@ -0,0 +1,4 @@ +{ + "lvm_vg_name":"nova-local", + "ihost_uuid":"a0f0a6d5-75ad-4769-8e0e-3a7c7c0ce783" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-response.json new file mode 100644 index 000000000..69517ce69 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_add-response.json @@ -0,0 +1,38 @@ +{ + "lvm_vg_access": null, + "lvm_vg_size": 0, + "lvm_max_lv": 0, + "lvm_vg_free_pe": 0, + "uuid": "11ac6dfc-a5ea-4cc9-a0c9-50afb13f7b24", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/ilvgs/11ac6dfc-a5ea-4cc9-a0c9-50afb13f7b24", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ilvgs/11ac6dfc-a5ea-4cc9-a0c9-50afb13f7b24", + "rel": "bookmark" + } + ], + "lvm_cur_lv": 0, + "created_at": "2015-03-11T04:52:32.007904+00:00", + "lvm_max_pv": 0, + "updated_at": null, + "capabilities": {}, + "vg_state": "adding", + "ihost_uuid": "a0f0a6d5-75ad-4769-8e0e-3a7c7c0ce783", + "ipvs": [ + { + "href": "http://10.10.10.2:6385/v1/ilvgs/11ac6dfc-a5ea-4cc9-a0c9-50afb13f7b24/ipvs", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ilvgs/11ac6dfc-a5ea-4cc9-a0c9-50afb13f7b24/ipvs", + "rel": "bookmark" + } + ], + "lvm_cur_pv": 0, + "lvm_vg_uuid": null, + "lvm_vg_total_pe": 0, + "lvm_vg_name": "nova-local" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_list-response.json new file mode 100644 index 000000000..a81cfe136 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_list-response.json @@ -0,0 +1,32 @@ +{ + "ilvgs": [ + { + "lvm_vg_access": "wz--n-", + "lvm_vg_size": 7310671872, + "lvm_max_lv": 0, + "lvm_vg_free_pe": 1743, + "uuid": "039de9ef-b1db-4c31-9072-add0f888b8b9", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/ilvgs/039de9ef-b1db-4c31-9072-add0f888b8b9", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ilvgs/039de9ef-b1db-4c31-9072-add0f888b8b9", + "rel": "bookmark" + } + ], + "lvm_cur_lv": 0, + "created_at": "2015-03-11T02:46:55.730611+00:00", + "lvm_max_pv": 0, + "updated_at": "2015-03-11T02:50:57.361006+00:00", + "capabilities": {}, + "vg_state": "provisioned", + "ihost_uuid": "1ef159f8-0192-4879-a08e-f60328486e34", + "lvm_cur_pv": 1, + "lvm_vg_uuid": "u7NzxA-1LeR-G88h-3lMk-eFvo-YnL8-HT9SEP", + "lvm_vg_total_pe": 1743, + "lvm_vg_name": "nova-local" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-request.json new file mode 100644 index 000000000..e7e9f12ea --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-request.json @@ -0,0 +1,7 @@ +[ + { + "path": "/capabilities", + "value": "{\\"instances_lv_size_mib\\": 10240}", + "op": "replace" + } +] \ No newline at end of file diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-response.json new file mode 100644 index 000000000..9408e25a8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_modify-response.json @@ -0,0 +1,40 @@ +{ + "lvm_vg_access": null, + "lvm_vg_size": 0, + "lvm_max_lv": 0, + "lvm_vg_free_pe": 0, + "uuid": "79926a38-f60c-4ede-8201-da8b009a07ee", + "links": [ + { + "href": "http://192.168.204.2:6385/v1/ilvgs/79926a38-f60c-4ede-8201-da8b009a07ee", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ilvgs/79926a38-f60c-4ede-8201-da8b009a07ee", + "rel": "bookmark" + } + ], + "lvm_cur_lv": 0, + "created_at": "2015-09-29T07:36:24.251731+00:00", + "lvm_max_pv": 0, + "updated_at": null, + "capabilities": { + "instances_lv_size_mib": 10240 + }, + "vg_state": "adding", + "ihost_uuid": "6b55a4c8-4194-4e3b-8d32-ca658473314e", + "ipvs": [ + { + "href": "http://192.168.204.2:6385/v1/ilvgs/79926a38-f60c-4ede-8201-da8b009a07ee/ipvs", + "rel": "self" + }, + { + "href": "http://192.168.204.2:6385/ilvgs/79926a38-f60c-4ede-8201-da8b009a07ee/ipvs", + "rel": "bookmark" + } + ], + "lvm_cur_pv": 0, + "lvm_vg_uuid": null, + "lvm_vg_total_pe": 0, + "lvm_vg_name": "nova-local" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_show-response.json new file mode 100644 index 000000000..27dd48ad0 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/api_samples/volumegroup_show-response.json @@ -0,0 +1,38 @@ +{ + "lvm_vg_access": "wz--n-", + "lvm_vg_size": 7310671872, + "lvm_max_lv": 0, + "lvm_vg_free_pe": 1743, + "uuid": "039de9ef-b1db-4c31-9072-add0f888b8b9", + "links": [ + { + "href": "http://10.10.10.2:6385/v1/ilvgs/039de9ef-b1db-4c31-9072-add0f888b8b9", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ilvgs/039de9ef-b1db-4c31-9072-add0f888b8b9", + "rel": "bookmark" + } + ], + "lvm_cur_lv": 0, + "created_at": "2015-03-11T02:46:55.730611+00:00", + "lvm_max_pv": 0, + "updated_at": "2015-03-11T02:50:57.361006+00:00", + "capabilities": {}, + "vg_state": "provisioned", + "ihost_uuid": "1ef159f8-0192-4879-a08e-f60328486e34", + "ipvs": [ + { + "href": "http://10.10.10.2:6385/v1/ilvgs/039de9ef-b1db-4c31-9072-add0f888b8b9/ipvs", + "rel": "self" + }, + { + "href": "http://10.10.10.2:6385/ilvgs/039de9ef-b1db-4c31-9072-add0f888b8b9/ipvs", + "rel": "bookmark" + } + ], + "lvm_cur_pv": 1, + "lvm_vg_uuid": "u7NzxA-1LeR-G88h-3lMk-eFvo-YnL8-HT9SEP", + "lvm_vg_total_pe": 1743, + "lvm_vg_name": "nova-local" +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/common.ent new file mode 100644 index 000000000..119436dd3 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/common.ent @@ -0,0 +1,4214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + + '> + + + + + + '> + + + + + '> + + + + + + '> + + + + + + '> + + + + + + + The universally unique identifier for this object. + + + + + For convenience, resources contain links to themselves. + This allows a client to easily obtain rather than construct + resource URIs. The following types of link relations are + associated with resources: a self link containing a versioned + link to the resource, and a bookmark link containing a permanent + link to a resource that is appropriate for long term storage. + + + + + The time when the object was created. + + + + + The time when the object was last updated. + + + '> + + + + + + + A user-specified name of the cloud system. The default value + is the system UUID. + + + + + A installed system type of the cloud system. + + + + + The system mode of the cloud system. + + + + + The timezone of the cloud system. + + + + + A user-specified description of the cloud system. + + + + + The user-specified location of the cloud system. + + + + + The user-specified contact for the cloud system. + + + + + Contains the Cloud Server Software Version and the + Software Version of the underlying Linux Kernel. + + + '> + + + + + + A name of the cloud cluster. + + + + + An installed cluster type of the cloud system. + + + + + A system generated unique identifier for this cluster in the cloud system. + + + + + The unique identifier of the underlying cluster instance represented by this cluster. + + + '> + + + + + A list of dictionaries for each replication group of storage host peers. + + + + + A list of dictionaries for each storage tier in the cluster + + + '> + + + + + + The name provisioned for the host. + + + + + The role of the host: controller, compute or storage. + + + + + The administrative state of the host; unlocked or locked. + + + + + The operational state of the host; enabled or disabled. + + + + + The availability state of the host; offline, online, + intest, available, degraded or + failed. + + + + + The management MAC of the host management interface. + + + + + + The management IP Address of the host. + + + + + + The current maintenance task in progress on the host. + + + + + + The serial id configured for the host. + + + + + + The board management type of the host. + + + + + + The board management username of the host. + + + + + + The board management IP Address of the host. + + + + + + Device used for boot partition, relative to /dev. Default: sda + + + + + Device used for rootfs and platform partitions, relative to /dev. Default: sda + + + + + Installation output format. Values are text or graphical. Default: text + + + + + Serial console configuration, specifying port and baud rate. Default: ttyS0,115200. + + + + + The configuration UUID applied to the host. + + + + + + The configuration target UUID of the host. + + + + + + The configuration status of the host. + + + + + + The uptime in seconds of the host. + + + + + + The location information of the host. + + + + + + + The list of roles supported by the host. Comma separated string. + For a host with compute role, the compute subfunction is configurable on + initial installation, and may be either: + compute or compute_lowlatency. + + + + + + The subfunction operational state, excluding + the primary role personality. + + + + + + The subfunction availability state, excluding + the primary role personality. + + + + + + The recordtype of the host: standard or + profile. + + + + + + Id value of the host. + + + + + + Action on the host in progress. + + + + + + The installation state of the host; preinstall, installing, postinstall, installed or failed. + + + + + + Progress information of the installation of the host. For example, installing 2/1040, indicating the number of packages installed out of the total packages to be installed. + + + + + + virtual infrastructure manager progress status. + + + + + + Serial port data carrier detect status. + + + + + + The version of the software currently running on the host. + + + + + + The version of the software requested to run on the host. + + + + + '> + + + + + + + Link to the ports resources on the host. + + + + + + Link to the network interfaces resources on the host. + + + + + + Link to the ethernet ports resources on the host. + + + + + + Link to the numa node resources on the host. + + + + + + Link to the memory resources on the host. + + + + + + Link to the disks resources on the host. + + + + + + Link to the storage resources on the host. + + + + + + Link to the physical volume storage resources on the host. + + + + + + Link to the logical volume group storage resources on the host. + + + + + + Serial port data carrier detect status. + + + + '> + + + + + + + The discovered name of the port, typically the Linux assigned device name, if available. + + + + + The user-specified name for the port. + + + + + The MAC Address of the port. + + + + + The PCI Address of the port. + + + + + Currently not supported. + + + + + Currently not supported. + + + + + The Maximum Transmission Unit (MTU) of the port, in bytes. + + + + + Currently not supported. + + + + + Indicates whether the port can be used for network booting. + + + + + Indicates the maximum number of VFs that this port can support. + + + + + Indicates the actual number of VFs configured for the interface using this port. + + + + + A comma-separated list of the PCI addresses of the configured VFs. + + + + + The driver being used for the port. Valid values are + ixgbe and igb. + + + + + + The class or type of the physical IO controller device of the port. + + + + + The primary vendor information of the port hardware. + + + + + The secondary vendor information of the port hardware. + + + + + The primary type and model information of the port hardware. + + + + + The secondary type and model information of the port hardware . + + + + + The UUID of the L2 interface of the port. + + + + + The NUMA Node of the port. + + + + + The UUID of the NUMA node of the port. + + + + + The UUID of the host containing the port. + + + '> + + + + + + + The user-specified name of the interface. + + + + + Indicates the type of network that this interface is + attached to; mgmt, oam, infra, none, + data, pci-passthrough or pci-sriov. + + + + + Indicates the type of L2 interface; ethernet or + ae (aggregated ethernet or link aggregation (LAG)) or vlan (virtual lan). + + + + + Only applicable if iftype : ae, + this attribute indicates the basic mode of operation for + the AE/LAG interface. Supported modes are: balanced round + robin, active-backup, balanced xor, broadcast, 802.3ad, + balance-tlb, balance-alb. NOTE only balanced xor and + active-standby modes are supported by interfaces of + networktype=data. + + + + + + Only applicable if iftype : ae and aemode : balanced, + this attribute indicates what packet headers the AE/LAG is using to distribute + packets across the different links/ports of the AE/LAG group; + layer2, layer2+3 or layer3+4. + + + + + Only applicable if iftype : vlan, + this attribute indicates that the vlan interface id. + A vlan id between 1 and 4094 (inclusive) must be selected. + NOTE The vlan id must be unique for the host interface. + + + + + + Only applicable if networktype : data, + this attribute provides a comma-separated list of + provider networks that this data interface + is attached to. + + + + + The MAC Address being used by the interface. In the case + of AE/LAG, the MAC address of one of the physical ports of + the AE/LAG group is used. + + + + + The Maximum Transmission Unit (MTU) of the interface, in bytes. + + + + + The number of VFs configured on the interfaces port; only applicable + if networktype = pci-sriov where only a + single port is associated with the interface. + + + + + Currently not supported. + + + + + The ID of the host of this interface. + + + + + The UUID of the host of this interface. + + + '> + + + + + + + The logical core number. + + + + + The NUMA Node or physical processor device of the logical core. + + + + + The physical core of the logical core. + + + + + The thread within the physical core of the logical core. + + + + + The function assigned to this logical core; valid values are + Platform, Vswitch, Shared or VMs . + Platform indicates the core is used for the host + kernel, Titanium Cloud and OpenStack Services, + Vswitch indicates the core is used by AVS, the + virtual switch, + Shared indicates that the core is reserved for + sharing by VMs using the hw:wrs:shared_vcpu flavor extra spec, + VMs indicates that the core is available for + use by VMs. + + + + + The CPU Family for the processor of the logical core. + + + + + The vendor, model, part number and other info related to the + processor device of the logical core. + + + + + The UUID of the host of the logical core. + + + + + The UUID of the NUMA Node of the logical core. + + + '> + + + + + + + The UUID of the host. + + + + + The NUMA node number. + + + + + The UUID of the NUMA node. + + + + + Memory reserved for the Kernel and Cloud Platform Services, + in MiBs. + + + + + Total memory reserved for the hosted Virtual Machines, + in MiBs. + + + + + Free / available memory from the total memory reserved for + the hosted Virtual Machines, in MiBs. + + + + + Boolean indicating whether huge page memory is configured + or not. + + + + + The total number of Virtual Machine 1G huge pages. + + + + + The free / available Virtual Machine 1G huge pages. + + + + + If not null, the pending configured number of Virtual Machine + 1G huge pages. + + + + + The total number of Virtual Machine 2M huge pages. + + + + + The free / available Virtual Machine 2M huge pages. + + + + + If not null, the pending configured number of Virtual Machine + 2M huge pages. + + + '> + + + + + + + The name of the sensorgroup. + + + + + The entity path of the sensorgroup. + + + + + The sensortype of the sensors in the sensorgroup. + e.g. temperature, voltage, current, fan, + power, disk, watchdog, memory, + interrupt, firmware, hardware. + + + + + + The sensor datatype of the sensors in the sensorgroup. + e.g. discrete or analog + + + + + + The UUID of the host. + + + + + Specifies whether sensorgroup actions are suppressed. True specifies suppressed. + This attribute is user configurable and affects all sensors within the sensorgroup. + + + + + Specifies the audit interval time in seconds for the system sensor monitoring algorithm. + This attribute is user configurable and affects all sensors within the sensorgroup. + + + + + + For datatype analog sensors: the Critical Lower Threshold of the SensorGroup. + + + + + + For datatype analog sensors: the Critical Upper Threshold of the SensorGroup. + + + + + + For datatype analog sensors: the Major Lower Threshold of the SensorGroup. + + + + + + For datatype analog sensors: the Major Upper Threshold of the SensorGroup. + + + + + + For datatype analog sensors: the Minor Lower Threshold of the SensorGroup. + + + + + + For datatype analog sensors: the Minor Upper Threshold of the SensorGroup. + + + + + + + The unit base of the sensor. e.g. revolutions, C (Celcius), etc. + + + + + + The unit modifier of the sensor. e.g. 10^2 (*100). + + + + + The unit rate of the sensor. e.g. /h (per hour). + + + + + The system sensor algorithm version information. + + + + + + The actions to take upon critical threshold sensor event. e.g. alarm, ignore. + This attribute is user configurable and affects all sensors within the sensorgroup. + + + + + + The actions to take upon major threshold sensor event. e.g. alarm, ignore. + This attribute is user configurable and affects all sensors within the sensorgroup. + + + + + + The actions to take upon minor threshold sensor event. e.g. alarm, ignore. + This attribute is user configurable and affects all sensors within the sensorgroup. + + + + + '> + + + + + + The UUID of the sensorgroup. + + + + + Specifies whether sensor actions are suppressed. True specifies suppressed. + This attribute is user configurable. + + + + + The name of the sensor. + + + + + The entity path of the sensor. + + + + + The sensortype of the sensor. + e.g. temperature, voltage, fan, power + + + + + + The sensor datatype. e.g. discrete or analog + + + + + The sensor status: One of ok, minor, major, critical. + + + + + + The operational state of the sensor. + + + + + + The sensor action requested for the sensor. Only applicable to action sensors. + + + + + For datatype analog sensors: the Critical Lower Threshold of the Sensor. + + + + + + For datatype analog sensors: the Critical Upper Threshold of the Sensor. + + + + + + For datatype analog sensors: the Major Lower Threshold of the Sensor. + + + + + + For datatype analog sensors: the Major Upper Threshold of the Sensor. + + + + + + For datatype analog sensors: the Minor Lower Threshold of the Sensor. + + + + + + For datatype analog sensors: the Minor Upper Threshold of the Sensor. + + + + + + + The unit base of the sensor. e.g. revolutions, C (Celcius), etc. + + + + + + The unit modifier of the sensor. e.g. 10^2 (*100). + + + + + The unit rate of the sensor. e.g. /h (per hour). + + + + + The sensor algorithm version information. + + + + + + The actions to take upon critical threshold sensor event. e.g. alarm, ignore + + + + + + The actions to take upon major threshold sensor event. e.g. alarm, ignore + + + + + + The actions to take upon minor threshold sensor event. e.g. alarm, ignore + + + + + '> + + + + + + + + + Indicates that the record is being used for host profile + rather than a host. + + + + + The name of the profile. + + + '> + + + + Indicates that the record is being used for host profile + rather than a host. + + + + + The name of the profile. + + + + + Links to the ports of the profile. + + + + + Links to the interfaces of the profile. + + + + + Links to the disks of the profile. + + + + + Links to the partitions of the profile. + + + + + Links to the physical volume storage resources of + the profile. + + + + + + Links to the physical volumes of the profile. + + + + + + Links to the logical volume group storage resources of + the profile. + + + + + + Links to the NUMA Nodes of the profile. + + + + + Links to the logical cores (CPUs) of the profile. + + + '> + + + + + + + The alarm ID; each type of alarm has a unique ID. Note + the alarm_id and the entity_instance_id uniquely identify + an alarm instance. + + + + + The instance of the object raising alarm. A . separated list + of sub-entity-type=instance-value pairs, representing the containment + structure of the overall entity instance. Note + the alarm_id and the entity_instance_id uniquely identify + an alarm instance. + + + + + The text description of the alarm. + + + + + The severity of the alarm; critical, + major, minor, or warning. + + + + + The time in UTC at which the alarm has last been updated. + + + + + The unique identifier of the alarm. + + + '> + + + + The state of the alarm; set or clear + + + + + Indicates whether the alarm affects the service. + + + + + The proposed action to clear the alarm. + + + + + The type of the alarm. + + + + + The type of the object raising the alarm. A . separated list + of sub-entity-type, representing the containment structure of the + overall entity type. + + + + + The probable cause of the alarm. + + + + + Indicates whether suppression of the specific alarm is allowed. + + + '> + + + + UUID of the system. + + + + + Overall system status based on alarms present; critical, + degraded, or OK. + + + + + Count of critical alarms on the system + + + + + Count of major alarms on the system + + + + + Count of minor alarms on the system + + + + + Count of warnings on the system + + + + + '> + + + + + + + The SNMP GET/SET access control for a specific community. + + + + + The community string of which the SNMP client is a member. + + + + + The SNMP MIB view of which the community has access to. + + + + '> + + + + + + + The IP address of a specific trap destination. + + + + + The community of which the trap destination is a member. + + + + + The SNMP version of the trap message for a specific destination. + + + + + The port number of which SNMP manager is listening for traps. + + + + + The transport protocol used by the trap messages. + + + '> + + + + + + + The comma-separated list of DNS nameservers. + + + + + The System UUID which the DNS belongs to. + + + + '> + + + + + + The comma-separated list of NTP ntpservers. + + + + + The System UUID which the NTP belongs to. + + + + '> + + + + + + The External OAM IP Subnet. + + + + + The External OAM Gateway IP Address. + + + + + The External OAM Floating IP Address. + + + + + The External OAM Controller-0 IP Address. + + + + + The External OAM Controller-1 IP Address. + + + + + The System UUID which the External OAM IP belongs to. + + + + '> + + + + + + + The infrastructure network IP subnet. + + + + + The infrastructure network start IP address. + + + + + The infrastructure network end IP address. + + + + + The MTU of the infrastructure interface. + + + + + The VLAN id of the infrastructure interface. + + + + + The System UUID which the infrastructure network IP subnet belongs to. + + + + '> + + + + + + + The DRBD engineered link utilization percent during resync. + + + + + The DRBD number of parallel devices to resync. + + + + + The DRBD replication nodes round-trip-time milliseconds. + + + + + The System UUID which the DRBD link belongs to. + + + + '> + + + + + + + Additional capabilities info about the disk. + + + + + The device node of the disk. + + + + + The device path of the disk. + + + + + The device ID of the disk. + + + + + The device WWN of the disk. + + + + + The device number of the disk. + + + + + The disk device type. + + + + + The host UUID that the disk belongs to. + + + + + The node UUID that the disk belongs to. + + + + + The logical storage function that this disk belongs to. + + + + + The LVM physical volume that this disk belongs to. + + + + + The serial id or number of the disk. + + + + + The RPM of the disk. "Undetermined" if not specified. + "N/A", not applicable for SSDs or NVME disks. + + + + + + The size of the disk in MiBytes. + + + + + The unpartitioned size of the disk in MiBytes. + + + + '> + + + + + + + Set the partition table type to wipe and format the + disk. Supported values are gpt. + + + + + '> + + + + + + Additional capabilities info about the partition. + + + + + The device node of the partition. + + + + + The device path of the partition. + + + + + The host UUID that the partition belongs to. + + + + + The disk UUID that this partition belongs to. + + + + + The LVM physical volume that this partition belongs to. + + + + + The status of the partition. + + + + + The GUID for the partition type. + + + + + The name for the partition type. + + + + + The size of the partition in MiBytes. + + + + + The start of the partition MiBytes. + + + + + The end of the partition in MiBytes. + + + + '> + + + + + + + The name of the storage service. + + + + + A dictionary of storage backend capabilities. + + + + + + When "false" it will run in test mode without applying any + modification. This allow checking a request for validity before + performing non-reversible changes. When set to "true" the modifications + are immediately applied. + + + + + '> + + + + + + + Additional capabilities info about the storage function. + + + + + The storage function e.g. "osd" (object storage daemon) or + "journal" (backing stor for journals) for ceph. + + + + + The host UUID that the storage belongs to. + + + + + The System UUID which the storage belongs to. + + + + + The object storage daemon identifier of the storage function. + + + + + The journal stor on which the journal is kept. + + + + + The size of the journal. + + + + + The device path of the journal. + + + + + The device node of the journal. + + + + + The state info of the storage function. + + + + + The name of the storage tier that is using this storage function. + + + + + The UUID of the storage tier that is using this storage function. + + + + '> + + + + + + Additional capabilities info about the volume group. + + + + + + This is the state of the volume group which is one of the following: + unprovisioned, adding, provisioned, or removing. + + + + + + + This is the LVM volume group name as retrieved from the vgdisplay + command on the host. + + + + + + + This is the LVM generated volume group UUID as retrieved from the + vgdisplay command on the host. + + + + + + + This is the LVM generated volume group access status as retrieved + from the vgdisplay command on the host. + + + + + + + This is the LVM generated max number of logical volumes allowed as + retrieved from the vgdisplay command on the host. + + + + + + + This is the LVM generated current number of logical volumes as + retrieved from the vgdisplay command on the host. + + + + + + + This is the LVM generated max number of physical volumes allowed + as retrieved from the vgdisplay command on the host. + + + + + + + This is the LVM generated current number of physical volumes + as retrieved from the vgdisplay command on the host. + + + + + + + This is the LVM generated volume group size in bytes as retrieved + from the vgdisplay command on the host. + + + + + + + This is the LVM generated total number of physical extents within the + volume group as retrieved from the vgdisplay command on the host. + + + + + + + This is the LVM generated number of physical extents not allocated + within the volume group as retrieved from the vgdisplay command on + the host. + + + + + + The UUID of the host containing the port. + + + + '> + + + + + + Links to associated physical volumes. + + + + '> + + + + + + Additional capabilities info about the volume group. + + + + + + This is the state of the physical volume. It has one of the following + values: unprovisioned, adding, provisioned, or removing. + + + + + + + This is the type of physical volume that is allocated. This will have + the value of disk or partition. + + + + + + + This is the UUID of the device that is associated with this physical volume. + + + + + + + This is the device node name associated with the physical volume. + + + + + + + This is the device path associated with the physical partition. + + + + + + + This is the physical volume name as retrieved from the pvdisplay command + on the host. + + + + + + + This is the name of the volume group that this physical volume belongs as + retrieved from the pvdisplay command on the host. + + + + + + + This is the LVM generated UUID for the physical volume as retrieved from + the pvdisplay command on the host. + + + + + + + This is the LVM generated size in bytes of the physical volume as retrieved + from the pvdisplay command on the host. + + + + + + + This is the LVM generated total number of physical extents associated + with the physical volume as retrieved from the pvdisplay command on + the host. + + + + + + + This is the LVM generated number of allocated physical extents associated + with the physical volume as retrieved from the pvdisplay command on + the host. + + + + + + The UUID of the host containing the port. + + + + + The UUID of the volume group containing the physical volume. + + + + + The ID of the volume group containing the physical volume. + + + + '> + + + + + + Links to associated disks. + + + + + Links to associated partitions. + + + + '> + + + + + + + The event log ID; each type of event log has a unique ID. Note + the event_log_id and the entity_instance_id uniquely identify + an event log instance. + + + + + The state of the event; set, clear or log + + + + + The instance of the object generating the event log. A . separated list + of sub-entity-type=instance-value pairs, representing the containment + structure of the overall entity instance. Note + the event_log_id and the entity_instance_id uniquely identify + an event log instance. + + + + + The text description of the event log. + + + + + The severity of the event log; critical, + major, minor or warning. + + + + + The time in UTC at which the event log has last been updated. + + + + + The unique identifier of the event log. + + + + + The next attribute is the request to use to get the next n + items. It is used to paginate the event log list. + + + '> + + + + The state of the event; set, clear or log + + + + + Indicates whether the event affects the service. + + + + + The proposed action to clear the event. + + + + + The type of the event. + + + + + The type of the object raising the alarm. A . separated list + of sub-entity-type, representing the containment structure of the + overall entity type. + + + + + The probable cause of the event. + + + + + Indicates whether suppression of the specific event is allowed. + + + '> + + + + + + The alarm ID type (event ID type) that can be suppressed or unsuppressed. + + + + + + The text description of the event type. + + + + + The suppression status for the event ID type; suppressed or unsuppressed + + + '> + + + + + + + The user-specified name for the PCI device + + + + + The PCI Address of the device. + + + + + The class or type identifier of the physical IO controller device of the device. + + + + + The primary vendor identifier of the device hardware. + + + + + The primary type and model identifier of the devicehardware. + + + + + The class or type name of the physical IO controller device of the device. + + + + + The primary vendor name of the port hardware. + + + + + The primary type and model information of the device hardware. + + + + + The secondary vendor information of the device hardware. + + + + + The secondary type and model information of the device hardware. + + + + + Indicates the maximum number of VFs that this device can support. + + + + + Indicates the actual number of VFs configured for the interface using this device. + + + + + A comma-separated list of the PCI addresses of the configured VFs. + + + + + The driver being used for the device. + + + + + The availability status of the device. + + + + + Extra information about the device. + + + + + The NUMA Node of the device. + + + + + The UUID of the host containing the device. + + + '> + + + + + + The name of the service. + + + + + The section name within the configuration file + for the specified service. + + + + + The name of the service parameter. + + + + + The value of the service parameter. + + + '> + + + + + + The UUID of the host containing the lldp agent. + + + + + The name of the local port to which this lldp agent belongs. + + + + + The 802.1AB chassis identifier advertised by the lldp agent. + + + + + The 802.1AB port identifier advertised by the lldp agent. + + + + + The 802.1AB port descrioption advertised by the lldp agent. + + + + + The 802.1AB time to live advertised by the lldp agent. + + + + + The 802.1AB system description advertised by the lldp agent. + + + + + The 802.1AB system name advertised by the lldp agent. + + + + + The 802.1AB system capabilities advertised by the lldp agent. + + + + + The 802.1AB management address advertised by the lldp agent. + + + + + The 802.1AB link aggregation status advertised by the lldp agent. + + + + + The 802.1AB vlan names advertised by the lldp agent. + + + + + The 802.1AB MAC status advertised by the lldp agent. + + + + + The 802.1AB maximum frame size advertised by the lldp agent. + + + '> + + + + + + The UUID of the host containing the lldp neighbor. + + + + + The MAC service access point identifier of the lldp neighbor. + + + + + The name of the local port to which this lldp neighbor is connected. + + + + + The 802.1AB chassis identifier advertised by the lldp neighbor. + + + + + The 802.1AB port identifier advertised by the lldp neighbor. + + + + + The 802.1AB port descrioption advertised by the lldp neighbor. + + + + + The 802.1AB time to live advertised by the lldp neighbor. + + + + + The 802.1AB system description advertised by the lldp neighbor. + + + + + The 802.1AB system name advertised by the lldp neighbor. + + + + + The 802.1AB system capabilities advertised by the lldp neighbor. + + + + + The 802.1AB management address advertised by the lldp neighbor. + + + + + The 802.1AB link aggregation status advertised by the lldp neighbor. + + + + + The 802.1AB vlan names advertised by the lldp neighbor. + + + + + The 802.1AB port vlan id advertised by the lldp neighbor. + + + + + The 802.1AB protocol vlan ids advertised by the lldp neighbor. + + + + + The 802.1AB protocol ids advertised by the lldp neighbor. + + + + + The 802.1AB MAC status advertised by the lldp neighbor. + + + + + The 802.1AB maximum frame size advertised by the lldp neighbor. + + + '> + + + + + + The operational state of the service. + + + + + The id of the service. + + + + + The desired state of the service + + + + + The name of the service. + + + + + The name of the host which the service is running on. + + + '> + + + + + + Administrative state of the node. + + + + + The operational state of the node. + + + + + The name of the node. + + + + + The operational state of the node + + + + + The availability status of the node. + + + + + The id of the node. + + + '> + + + + + + The type of host that the service is running on. + + + + + The name of the service group. + + + + + The name of the node that the service is running on. + + + + + The state of the service. + + + + + The uuid of the service group. + + + '> + + + + + + This parameter specifies the IP address or FQDN of the + SDN controller. + + + + + + This parameter specifies the listening port number of the OVSDB + southbound API of the SDN controller. + + + + + + This parameter specifies the transport protocol to use for the + connection of the OVSDB protocol. Expected value is TCP. + Valid values are: UDP or TCP. + + + + + + This parameter specifies the administrative state of the + SDN controller. + Valid values are: enabled or disabled. + + + + '> + + + + + + IP Address of remote log server. + + + + + Remote log server enabled. + + + + + Remote log server transport protocol. + + + + + Remote log server port. + + + + + Remote log server TLS key file. + + + '> + + + + + + The uuid of the network resource. + + + + + The type of network resource. + + + + + The maximum IP packet length that is support on this network. + + + + + The transmission speed in megabits per second. + + + + + A boolean describing whether IP addresses are assigned by the user (False) or by the system (True). + + + + + The VLAN instance number (1-4094) if applicable. + + + + + The uuid of the address pool from which IP addresses are allocated or registered. + + + '> + + + + + + The name (or network type) of the address pool resource. + + + + + The IP address of the network. + + + + + The network address prefix length in bits. + + + + + A string representing the IP address allocation scheme; random to allocate in random order, or sequential to allocate in sequential order. + + + + + A python list, formatted as a JSON string, representing a series of start-end pairs which define the allocatable ranges of IP addresses in the pool. + + + '> + + + + + + + The uuid of the address pool resource. + + + '> + + + + + + + The interface uuid to which the address is assigned. + + + + + The IP address. + + + + + The IP address prefix length in bits. + + + '> + + + + + + + The uuid of the address resource. + + + + + The interface name to which the address is assigned. + + + + + Whether duplicate address detection is enabled on allocated addresses. + + + '> + + + + + + + The interface uuid to which the address is assigned. + + + + + The IP address of the network. + + + + + The network address prefix length in bits. + + + + + The IP address of the nexthop gateway device. + + + + + The IP route metric/weight. + + + '> + + + + + + The uuid of the route resource. + + + + + The interface name to which the address is assigned. + + + '> + + + + + + Name of this backend. + + + + + The type of the storage backend. + + + + + The admin state of the storage backend. + + + + + The current task of the storage backend when in "configuring" state. + + + + + The System UUID which the storage backend belongs to. + + + + + A dictionary of storage backend capabilities. + + + + + A comma separated list of backend services. + + + + '> + + + + + The name of the storage service. + + + + + A dictionary of storage backend capabilities. + + + + + + When "false" it will run in test mode without applying any + modification. This allow checking a request for validity before + performing non-reversible changes. When set to "true" the modifications + are immediately applied. + + + + + '> + + + + + + + + The name of the storage service. + + + + + The name of the storage backend. + + + + + The type of the storage backend. + + + + + The free storage capacity in GiB. + + + + + The total capacity in GiB. + + + '> + + + + + + + + + + + The cinder volumes pool quota in GiB. + + + + + The glance image pool quota in GiB. + + + + + The ephemeral pool quota in GiB. + + + + + The object gateway pool quota in GiB. + + + + + The total ceph pool space in GiB. + + + + + This specifies if object gateway is configured. + + + + + This specifies storage tier name this backend is using . + + + + + This specifies storage tier uuid this backend is using . + + + '> + + + + + + + + + + + + + + Name of this storage tier. + + + + + The type of storage tier. This maps to a backend type.. + + + + + The status of the storage tier: defined or in-use. + + + + + The list of osd ids assigned to this tier. + + + + + A dictionary of storage backend capabilities. + + + + + The backend UUID which is using this tier. + + + + + The cluster UUID which this tier is associated. + + + + + '> + + + + + + + The type of storage tier. This corresponds to the + backend type that will be attached to the tier. + Currently only a tier type of ceph is + supported. + + + + + + + The UUID of the backend that is attached to this tier. + The backend is attached to enable service(s) to use the + storage tier resources. + + + + + + + For tier type of ceph, this provides the + cluster_uuid that this tier is associated. + + + + + '> + + + + + + The name of the filesystem. + + + + + The size of the filesystem in GiB. + + + + + The logical volume of the filesystem. + + + + + Specifies if the filesystem is drbd replicated. + + + + + The state of the filesystem; None, availabe or drbd_fs_resizing_in_progress + + + '> + + + + The name of the filesystem. + + + + + The size of the filesystem in GiB. + + + '> + + + + The System UUID which the storage backend belongs to. + + + '> + + + + + + [Deprecated] The disk device node on the host that cgts-vg will be extended to create ceph-mon-lv. + + + + + [Deprecated] The disk device path on the host that cgts-vg will be extended to create ceph-mon-lv. + + + + + The name of host this ceph mon belongs to. + + + + + The ceph-mon-lv size in GiB, for Ceph backend only. + + + + + [Deprecated] The disk device on both controllers that cgts-vg will be extended to create ceph-mon-lv. + + + + + [Deprecated] The disk device on controller-0 that cgts-vg will be extended to create ceph-mon-lv. + + + + + [Deprecated] The disk device on controller-1 that cgts-vg will be extended to create ceph-mon-lv. + + + '> + + + + The UUID of this ceph monitor. + + + + + The System UUID which the storage backend belongs to. + + + '> + + + + + + The UUID of this load. + + + + + The state of the software load. + + + + + The id of the load. + + + + + A list of patches required before the system can upgrade to this load. + + + + + The software version of this load. + + + + + The software version this load can be upgraded from. + + + '> + + + + + + The state of the software upgrade. + + + + + The id of the load the system is upgrading from. + + + + + The software version the system is upgrading from. + + + + + The id of the load the system is upgrading to. + + + + + The software version the system is upgrading to. + + + '> + + + + The state of the software upgrade. + + + + + The software version the system is upgrading from. + + + + + The software version the system is upgrading to. + + + + + The universally unique identifier for this object. + + + + + For convenience, resources contain links to themselves. + This allows a client to easily obtain rather than construct + resource URIs. The following types of link relations are + associated with resources: a self link containing a versioned + link to the resource, and a bookmark link containing a permanent + link to a resource that is appropriate for long term storage. + + + '> + + + + + + The passphrase for the PEM file. + + + + + + This parameter specifies the type of System certificate. + Possible values are: ssl, tpm_mode, murano, murano_ca. + Default: ssl + + + + '> + + + + + + This parameter specifies the path to the certificate (private) + to upload to TPM. + + + + + + This parameter specifies the path to store the TPM + object context. + + + + + + This parameter specifies the path to store the public certificate + + + + '> + + + + + + This name of a packaged license. + + + + + This status of a packaged license.(installed/uninstalled) + + + + + The expiry date of a packaged license. + + + '> + + + + + + The signature of the custom firewall rules. + + + '> + + + GET'> + PUT'> + POST'> + DELETE'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/sysinv-api-v1.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/sysinv-api-v1.wadl new file mode 100644 index 000000000..d448ddea7 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/sysinv-api/v1/sysinv-api-v1.wadl @@ -0,0 +1,7602 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of the system. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of an existing host. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of an address resource. + + + + + + + + + + + + + + + + + The unique identifier of a route resource. + + + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of an existing port. + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of an existing interface. + + + + + + + + + + + + + + + + + The unique identifier of a cpu (logical processor core). + + + + + + + + + + + + + + + The unique identifier of a memory area. + + + + + + + + + + + + + + + + The unique identifier of a physical disk. + + + + + + + + + + + + + + + + The unique identifier of a physical partition. + + + + + + + + + + + + + + + + + The unique identifier of an existing Ceph storage function. + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of an existing LVM volume group. + + + + + + + + + + + + + + + + + + The unique identifier of an existing LVM physical volume. + + + + + + + + + + + + + + + + The unique identifier of a sensorgroup. + + + + + + + + + + + + + + + + The unique identifier of a sensor. + + + + + + + + + + + + + + + + + + The unique identifier of an existing profile. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of the DNS for this system. + + + + + + + + + + + + + + + + The unique identifier of the NTP for this system. + + + + + + + + + + + + + + + + + The unique identifier of the External OAM for this system. + + + + + + + + + + + + + + + + + + The unique identifier of the infrastructure network subnet configuration for this system. + + + + + + + + + + + + + + + + + The unique identifier of the DRBD config for this system. + + + + + + + + + + + + + + + + + The unique identifier of an existing active alarm. + + + + + + + + + + + + + + + + + + + + + + + + The unique community string of an existing SNMP Community. + + + + + + + + + + + + + + + + + + + The unique identifier of an existing SNMP Trap Destination. + + + + + + + + + + + + + + + + + + The unique identifier of an event log. + + + + + + + + + + + + + + + + + The unique identifier of an event suppression. + + + + + + + + + + + + + + + The unique identifier of an existing pci device. PCI address or name. + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of a service parameter. + + + + + + + + + + + + + + + + + + The system generated unique identifier of a cluster. + + + + + + + + + + + + + + + + The unique identifier of an existing lldp agent. + + + + + + + + + + + + + + + + The unique identifier of an existing lldp neighbor. + + + + + + + + + + + + + + + + The unique identifier of an existing service. + + + + + + + + + The name of an existing service. + + + + + + + + + + + + + + The unique identifier of an existing service node. + + + + + + + + + + + + + + + The unique identifier of an existing service group. + + + + + + + + + + + + + + + + + The unique identifier of the SDN controller. + + + + + + + + + + + + + + + + + + The unique identifier of a remotelogging settings entry. + + + + + + + + + + + + + + + + + The unique identifier of the address pool resource. + + + + + + + + + + + + + + + + + + The unique identifier of the network resource. + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of the storage backend. + + + + + + + + + + + + + + + + + + The unique identifier of the storage backend. + + + + + + + + + + + + + + + + + + The unique identifier of the storage backend. + + + + + + + + + + + + + + + + + + The unique identifier of the storage backend. + + + + + + + + + + + + + + + + + + The unique identifier of the storage tier resource. + + + + + + + + + + + + + + + + + The unique identifier of the controller filesystem. + + + + + + + + + + + + + + + + The unique identifier of Ceph monitor. + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of the load. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The unique identifier of the Certificate configuration. + + + + + + + + + + + + + + + + The unique identifier of the TPM configuration. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + API version details. + + + + + + + + + + + + + + + + + Lists information about all Titanium Cloud System Inventory API versions. + + + + + + + + + &commonFaults; &getFaults; + + + + + Shows details for System Inventory API v1. + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + Lists all host entities. + + + + + + + + The list of host entities. + + + &hostListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific host. + + + + + + + + Indicates whether the host has the minimum level of provisioning or not. + Only a provisioned host can be unlocked. + + + &hostListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Creates a host. + Note that a host should only be added through the REST API if the system is + not already configured to be automatically added by the system. + This is determined by configuration option during config_controller at + system installation. + + + + + + + + The hostname for the host. Must be a unique name. + + + + + The role of of this host: + i.e. controller, storage, compute + . + + + + + The MAC address of the host's management interface. Must be unique. + + + + + The IP address of the host's management interface. Must be unique. + + + + + This attribute specifies whether board management controller type is + bmc. + + bmc enables Board Management Controller. + Default is None to indicate no board management controller. + If bm_type is specified, then bm_ip, bm_username, + and bm_password are also required. + + + + + + Only applicable if bm_type is not None. + This attribute specifies the host's board management controller interface IP + address. bm_ip is not allowed to be added if the system is configured + with board management (e.g. board management subnet and vlan) at installation + (config_controller). + + + + + + Only applicable if bm_type is not None. + This attribute specifies the host's board management controller username. + + + + + + Only applicable if bm_type is not None. + This attribute specifies the host's board management controller password. + + + + + + Device used for boot partition, relative to /dev. Default: sda + + + + + Device used for rootfs and platform partitions, relative to /dev. Default: sda + + + + + Installation output format. Values are 'text' or 'graphical'. Default: text + + + + + Serial console configuration, specifying port and baud rate. Default: 'ttyS0,115200'. + + + + + This attribute specifies whether serial port data carrier detect is enabled. + + + + + The location of the host. + Must be a dictinoary with a single parameter 'locn'. + + + + + + + + + + + + + + &hostListShowParameters; + &hostAddParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; + + + + + + Creates multiple hosts from a template. + Accepts an XML file containing the specifications of hosts + to be added to the system and performs a host-add for each. + Refer to the Administration Guide for XML specifications. + + + + + + + + + + + + + + + + &commonFaults; + + + + + + Export hosts definition file from an existing system. + Output XML string is well formatted (with line breaks and indent) + + + + + + + + + &commonFaults; + + + + + + Modifies a specific host. + The atrributes of a Host which are modifiable: + + personality, + hostname, + bm_type, + bm_ip, + bm_username, + bm_password, + serialid, + location, + boot_device, + rootfs_device, + install_output, + console, + ttys_dcd. + + + + + + + + + The name provisioned for the host. + + + + + The role of the host: controller, compute or storage. + + + + + The board management type of the host. + + + + + + The board management username of the host. + + + + + + The board management IP Address of the host. + + + + + + The serial id configured for the host. + + + + + + The location information of the host. + + + + + + Device used for boot partition, relative to /dev. Default: sda + + + + + Device used for rootfs and platform partitions, relative to /dev. Default: sda + + + + + Installation output format. Values are 'text' or 'graphical'. Default: text + + + + + Serial console configuration, specifying port and baud rate. Default: 'ttyS0,115200'. + + + + + This attribute specifies whether serial port data carrier detect is enabled. + + + + + + + + + + + + + + &hostListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Executes an action on a specific host. + + + + + + + + Perform one of the following actions to the host: + Valid values are: unlock, + lock, + swact, + apply-profile, + reboot, + reset, + power-on, + power-off, + or reinstall. + + + + + + + + + + + + + + + &hostListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific host. + + + + + + + + + + + + + + + + List the physical ports of a host. + + + + + + + + The list of physical ports of a host. + + + &portListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific physical port. + + + + + + &portListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + List the L2 interfaces of a specific host. + + + + + + + + The list of L2 interfaces for a specific host. + + + &interfaceListShowParameters; + &commonListShowParameters; + + + Interfaces which the current interface uses. + + + + + + Interfaces which use the current interface. + + + + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows information about a specific L2 interface. + + + + + + &interfaceListShowParameters; + + + Currently not supported. + + + + + + Currently not supported. + + + + + + URIs to the physical ports of this interface. + + + + + + Interfaces which the current interface uses. + + + + + + Interfaces which use the current interface. + + + + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Creates an L2 interface on a specific host. + Note that mgmt and oam + can only be added through the REST API if their networktype is unassigned to none. + mgmt and oam are automatically added by the + system by default. + + + + + + + + The name for the interface. + + + + + The type of network that this interface will be attached to; + i.e. mgmt, infra, oam, + data, pci-passthrough, pci-sriov, + infra. + + + + + The type of interface; i.e. ae or + vlan. + + + + + Only applicable if iftype : ae, + this attribute specifies whether the AE/LAG should operate as balanced + or active_standby or 802.3ad across its links. + The balanced and active_standby are the only modes + supported by data type interface. For mgmt + type interface the 802.3ad option must be selected. + + + + + + Only applicable if iftype : ae and aemode : balanced, + this attribute specifies what packet headers the AE/LAG should use to distribute + packets across the different links/ports of the AE/LAG group; + layer2, layer2+3 or layer3+4. + + + + + Only applicable if iftype : vlan, + this attribute specifies a virtual lan id for a vlan interface type. + + + + + + Only applicable if networktype : data, + this attribute specifies a comma-separated list of + provider networks that this data interface + is attached to. + + + + + This attribute specifies a comma-separated list of + ports that this interface contains. If iftype : ethernet + then only one port is allowed. + + + + + Only applicable if iftype : ae or iftype: vlan, + this attribute specifies a comma-separated list of + interfaces that this interface uses. + + + + + This attribute specifies a comma-separated list of + interfaces that use this interface. + + + + + This attribute specifies the interface's Maximum Transmit Unit. + + + + + The number of VFs to configure on the interface's port; only applicable + if networktype = pci-sriov where only a + single port is associated with the interface. + + + + + The UUID of the host to create the interface on. + + + + + + + + + + + + + + &interfaceListShowParameters; + + + Currently not supported. + + + + + + Currently not supported. + + + + + + URIs to the physical ports of this interface. + + + + + + Interfaces which the current interface uses. + + + + + + Interfaces which use the current interface. + + + + + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Modifies a specific L2 interface. + + + + + + + + The name for the interface. + + + + + The type of network that this interface will be attached to; + i.e. mgmt, infra, oam, + data, pci-passthrough, pci-sriov, + infra or none. + + + + + The type of interface; i.e. ethernet or ae or + vlan. + + + + + Only applicable if iftype : ae, + this attribute specifies whether the AE/LAG should operate as balanced + or active_standby across its links. These are + the only modes supported by data type interface. + + + + + Only applicable if iftype : ae and aemode : balanced, + this attribute specifies what packet headers the AE/LAG should use to distribute + packets across the different links/ports of the AE/LAG group; + layer2, layer2+3 or layer3+4. + + + + + Only applicable if iftype : vlan, + this attribute specifies a virtual lan id for a vlan interface type. + + + + + + Only applicable if networktype : data, + this attribute specifies a comma-separated list of + provider networks that this data interface + is attached to. + + + + + This attribute specifies a comma-separated list of + ports that this interface contains. If iftype : ethernet + then only one port is allowed. + + + + + Only applicable if iftype : ae or iftype: vlan, + this attribute specifies a comma-separated list of + interfaces that this interface uses. + + + + + This attribute specifies a comma-separated list of + interfaces that use this interface. + + + + + This attribute specifies the interface's Maximum Transmit Unit. + + + + + The number of VFs to configure on the interface's port; only applicable + if networktype = pci-sriov where only a single + port is associated with the interface. + + + + + + + + + + + + + + &interfaceListShowParameters; + + + Currently not supported. + + + + + + Currently not supported. + + + + + + URIs to the physical ports of this interface. + + + + + + Interfaces which the current interface uses. + + + + + + Interfaces which use the current interface. + + + + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific L2 interface. + + + + + + + + + + + + + + + + + Shows attributes of the System object. + + + + + + &systemListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies attributes of the System object. + The attributes of the System object that are modifiable are: + + name, + system_mode, + timezone, + description, + location, + sdn_enabled, + contact. + + + + + + + + + + + + + + + + + + + + Links for retreiving the list of hosts for this system. + + + + &systemListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + Lists all cluster entities. + + + + + + + + The list of cluster entities. + + + &clusterListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific cluster. + + + + + + &clusterListShowParameters; + &clusterShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + Lists all cpus (logical processor cores) of a host. + + + + + + + + The list of cpus (logical processor cores) of a host. + + + &cpuListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows information about a specific cpu (logical processor core). + + + + + + &cpuListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies the number of cores assigned to different functions + on a host. + + + + + + + + This parameter specifies the function that is being assigned + a different number of cores. The only functions currently allowed to be + assigned a different number of cores platform, vswitch and + shared. + platform function is for managing the cores + dedicated to the platform. + vswitch function is for managing the cores + dedicated to the vswitch. + shared function is for managing the cores + reserved for sharing by VMs using the hw:wrs:shared_vcpu flavor extra spec. + + + + + The number of cores on a socket assigned to this function. + + + + + + + + + + + + + + + + + + + &cpuListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + Lists the memory information of all NUMA nodes of a host. + + + + + + + + The list of NUMA nodes (and their associated memory information) for this host. + + + &memoryListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the memory information about a specific NUMA node of a specific host. + + + + + + &memoryListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies the memory information about a specific NUMA node of a specific host.. + + + + + + + + If not null, the amount of reserved memory for platform in MiB + + + + + + If not null, the pending configured number of Virtual Machine + 1G huge pages. + + + + + If not null, the pending configured number of Virtual Machine + 2M huge pages. + + + + + + + + + + + + + + &memoryListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + Lists the sensorgroup information of a host. + + + + + + + + The list of associated sensorgroup information for this host. + + + &sensorgroupListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows the sensorgroup information of a specific sensorgroup. + + + + + + &sensorgroupListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies the sensorgroup information of a specific sensorgroup. + + + + + + + + + If True, suppresses any actions configured for the sensorgroup. + The sensorgroup remains monitored, but the actions configured will be suppressed. + + + + + + + Specifies the actions to take upon critical threshold event. Action selectable from actions_critical_choices. e.g. alarm, ignore, log, reset, powercycle. + + + + + + Specifies the actions to take upon major threshold event. Action selectable from actions_major_choices. e.g. alarm, ignore, log. + + + + + + Specifies the actions to take upon minor threshold event. Action selectable from actions_minor_choices. e.g. ignore, log, alarm. + + + + + + Specifies the audit interval, in time-units of seconds, for the sensors in the sensorgroup. + + + + + + + + + + + + + + + &sensorgroupListShowParameters; + + + + + + + + &postPutFaults; + + + + + Lists the sensor information of a host. + + + + + + + + The list of their associated sensor information for this host. + + + &sensorListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows the sensor information of a specific sensor. + + + + + + &sensorListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies the sensor information of a specific sensor. + + + + + + + + If True, suppresses any actions configured for the sensor. + When suppressed, the sensor remains monitored, but the actions configured will be suppressed. + + + + + + + + + + + + + + + &sensorListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + Lists all physical disks of a host. + + + + + + + + The list of physical disk entities. + + + &diskListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific physical disk. + + + + + + &diskListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies the disk. + + + + + + &diskModifyParameters; + + + + + + + + + + + + + + + + + + &postPutFaults; + + + + + + + + + + Lists all disk partitions of a host. + + + + + + + + The list of disk partition entities. + + + &partitionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific disk partition. + + + + + + &partitionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific disk partition. + + + + + + + + This parameter specifies a new size for the disk + partition. + + + + + + + + + + + + + + + &partitionListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a partition on a specific disk of a host. + + + + + + + + This parameter specifies the partition host uuid. + + + + + + This parameter specifies the partition type guid. + + + + + + This parameter specifies the partition disk uuid. + + + + + + This parameter specifies the size of the partition. + + + + + + + + + + + + + + + &partitionListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific disk partition. + This is supported just for user created, LVM Physical Volume, partition. + In order to delete a partition, it must be the last partition on the disk. + + + + + + + + + + + + + + + + + + Lists all Ceph storage functions of a host. + + + + + + + + The list of Ceph storage function entities. + + + &volumeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific Ceph storage function. + + + + + + &volumeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific Ceph storage function. + + + + + + + + This parameter specifies a new location for the stor's journal. + Needed only for "osd" functions. + + + + + + This parameter specifies a new size for the stor's journal. + Needed only for "osd" functions. + + + + + + + + + + + + + + + &volumeListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a Ceph storage function on a specific host. + + PREREQUISITES: A 'ceph' storage backend must be configured in the + system. If multiple storage tiers are defined then a tier_uuid must be + specified. + + + + + + + + + This parameter specifies the Ceph storage function. + Valid values are (is): osd or journal. + + + + + + This parameter specifies the storage host uuid. + + + + + + This parameter specifies the storage disk uuid. + + + + + + This parameter specifies the uuid of the journal stor + on which the stor's journal will reside. Needed only + for "osd" functions. + + + + + + This parameter specifies the size of the journal. Needed + only for "osd" functions. + + + + + + + + + + + + + + + &volumeListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific Ceph storage function. + This is supported just for journal type stors. The host must be locked. + In order to delete an osd stor, the host must be locked and deleted. + + + + + + + + + + + + + + + + + get storage backend summary. + + + + + + &profileShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + Lists all LVM volume groups of a host. + + This will list all the LVM volume groups for a given host. + + + + + + + + + The list of volume group entities. + + + &volumegroupListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific LVM volume group. + + This will show detailed information about a specific LVM volume group. + + + + + + + &volumegroupListShowParameters; + &volumegroupListShowParametersExtra; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific volume group capability. + + + + + + + + A dictionary of key-value pairs prepresenting volume group parameters and values. + Valid nova-local parameters are: instances_lv_size_mib, + instance_backing, and concurrent_disk_operations. Valid + cinder-volumes parameters are: lvm_type + + + + + + + + + + + + + + &volumegroupListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates an LVM volume group on a specific host. + + This will create an LVM volume group on the specified host. This + functionality is not available on storage hosts. In addition, the + volume group name is limited to "nova-local" or "cinder-volumes". + + + + + + + + + This parameter specifies the volume group name. + Valid values are (is): nova-local + + + + + + This parameter specifies the compute host uuid. + + + + + + + + + + + + + + + &volumegroupListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific LVM volume group. + + In order to delete an LVM volume group, the host must be locked. All + physical volumes assigned to the volume group will also be deleted. + + + + + + + + + + + + + + + + + + Lists all LVM physical volumes of a host. + + This will list all the LVM physical volumes defined on the given host. + A physical volume can be a pre-defined disk partition or an entire + extra disk as supported by the Volume Group. + + + + + + + + + The list of physical volume entities. + + + &physicalvolumeListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows detailed information about a specific LVM physical volume. + + This will show detailed information about a specific LVM physical volume. + + + + + + + &physicalvolumeListShowParameters; + &physicalvolumeListShowParametersExtra; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Creates an LVM physical volume on a specific host. + + This will create an LVM physical volume on the specified host. This + functionality is disabled on storage nodes. A physical volume can + be a pre-defined disk partition or an entire extra disk as supported by + the Volume Group. In addition, the volume group name is limited to + "nova-local" or "cinder-volumes". + + + + + + + + + This parameter specifies the volume group uuid. + + + + + This parameter specifies the compute host uuid. + + + + + + This parameter specifies the storage disk uuid. + + + + + + + + + + + + + + + &physicalvolumeListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific LVM physical volume. + + In order to delete an LVM physical volume, the host must be locked. + + + + + + + + + + + + + + + + + + Lists all profiles. + + + + + + + + The list of profile entities. + + + &profileListParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows information about a specific profile. + + + + + + &profileShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Creates a profile. + + + + + + + + The name for the new profile. + + + + + The type of profile to be created. + Valid values are: if, cpu or + stor. + + + + + The UUID of the Host to create the profile based on. + + + + + + + + + + + + + + &profileShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific profile. + + + + + + + + + + + + + + + + + + + + + + + Lists all active alarms based on specified query. + The supported query options are alarm_id, entity_type_id, entity_instance_id, + severity and alarm_type. + + + + + + + + This optional parameter when set to true (include_suppress=true) specifies + to include suppressed alarms in output. + + + + + + + + + + + + + + + + The list of active alarms based on the specified query. + + + &alarmListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows information about a specific alarm. + + + + + + + &alarmListShowParameters; + &alarmDetailShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Deletes a specific alarm. + NOTE Typically this command should NOT be used. I.e typically + alarms will be and should be cleared by the system + when the alarm condition clears. This command is only provided + in the event that the alarm has cleared but for some reason the + system has not removed the alarm. + + + + + + + + + + + + + Summarize all active alarms by severity. + + + + + + + + This optional parameter when set to true (include_suppress=true) specifies + to include suppressed alarms in the summations (default false). + + + + + + + + + &alarmSummaryShowParameters; + + + + + + + + &commonFaults; + + + + + + + + + + Lists all SNMP Communities. + + + + + + + + + The list of SNMP Communities. + + + &communityListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows information about a specific SNMP Community. + + + + + + + &communityListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific SNMP Community. + + + + + + + + + This parameter specifies the new community string. + + + + + + + + + + + + + + &communityListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a SNMP Community. + + + + + + + + + This parameter specifies the community string to create. + + + + + + + + + + + + + + &communityListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific SNMP Community. + + + + + + + + + + + + + + + + + + Lists all SNMP Trap Destinations. + + + + + + + + + The list of SNMP Trap Destinations. + + + &trapdestListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows information about a specific SNMP Trap Destination. + + + + + + + &trapdestListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific SNMP Trap Destination. + + + + + + + + + This parameter specifies the IP address of a specific trap destination. + + + + + This parameter specifies the the community of which the trap destination is a member. + + + + + + + + + + + + + + &trapdestListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Creates a SNMP Trap Destination. + + + + + + + + + This parameter specifies the IP address of a new trap destination. + + + + + This parameter specifies the community of which the trap destination is a member. + + + + + + + + + + + + + + &trapdestListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Deletes a specific SNMP Trap Destination. + + + + + + + + + + + + + + + + + + Shows attributes of the DNS object. + + + + + + &dnsListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies attributes of the DNS object. + The attributes of the DNS object that are configurable are: + + nameservers + + + + + + + + + This parameter specifies the list of Domain Name Servers (DNS). Comma separated list. + + + + + + + + + + + + + + &dnsListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + Shows attributes of the NTP object. + + + + + + &ntpListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies attributes of the NTP object. + The attributes of the NTP object that are configurable are: + + ntpservers + + + + + + + + + This parameter specifies the list of Network Time Protocol (NTP) Servers. Comma separated list. + + + + + + + + + + + + + + &ntpListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + Shows attributes of the External OAM object. + + + + + + &extoamListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies attributes of the External OAM object. + The attributes of the External OAM objects that are configurable are: + + oam_subnet + oam_gateway_ip + oam_floating_ip + oam_c0_ip + oam_c1_ip + + + + + + + + + This parameter specifies External +OAM IP Subnet. + + + + + This parameter specifies External +OAM Gateway IP Address. + + + + + This parameter specifies External +OAM Floating IP. + + + + + This parameter specifies External +OAM Controller-0 IP Address. + + + + + This parameter specifies External +OAM Controller-1 IP Address. + + + + + + + + + + + + + + &extoamListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + Shows attributes of the infrastructure network IP subnet object. + + + + + + &infraListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Add attributes of the infrastructure network IP subnet object. + The attributes of the infrastructure network IP subnet object that are configurable are: + + infra_subnet + infra_start + infra_end + infra_mtu + infra_vlan_id + + + + + + + + + This parameter specifies the infrastructure network IP subnet. + + + + + This parameter specifies the infrastructure network start IP address. + + + + + This parameter specifies the infrastructure network end IP address. + + + + + This parameter specifies the MTU of the infrastructure interface. + + + + + This parameter specifies the VLAN ID of the infrastructure interface. + + + + + + + + + + + + + + &infraListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies attributes of the infrastructure network IP subnet object. + The attributes of the infrastructure network IP subnet object that are configurable are: + + infra_start + infra_end + infra_mtu + infra_vlan_id + + + + + + + + + This parameter specifies the infrastructure network IP subnet. + + + + + + + + + + + + + + &infraListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Applies attributes of the infrastructure network IP subnet object. + + + + + + + + + + + + + + + + + + + + + + + + + Shows attributes of the DRBD configuration object. + + + + + + &drbdsyncListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies attributes of the DRBD configuration object. + The attributes of the DRBD configuration object that are configurable are: + + link_util + num_parallel + rtt_ms + + + + + + + + + This parameter specifies the DRBD engineered link utilization percent during resync. + + + + + This parameter specifies the DRBD number of parallel devices to resync. + + + + + This parameter specifies the DRBD replication nodes round-trip-time milliseconds. + + + + + + + + + + + + + + + &drbdsyncListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + + + + Lists all event logs (historical alarms and customer logs) based on specified query. The logs + are returned in reverse chronological order. + The supported query options are event_log_id, entity_type_id, entity_instance_id, + severity, event_log_type, start and end. + + + + + + + + This parameter specifies filter rules for the logs to + be returned. + + + + + This parameter specifies the maximum number of event logs to + be returned. + + + + + This optional parameter when set to true (alarms=true) specifies + that only alarm event log records should be returned. + + + + + This optional parameter when set to true (logs=true) specifies + that only customer log records should be returned. + + + + + This optional parameter when set to true (include_suppress=true) specifies + to include suppressed alarms in output. + + + + + + + + + + + + + + + + The list of events log based on the specified query. + + + &eventLogListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows information about a specific event log. + + + + + + + &eventLogListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + + + Lists suppressed event id's. + + + + + + + + + The list of suppressed event types. + + + &EventSuppressionListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies the value of an event suppression. + + + + + + + + The suppression status of an event suppression; suppressed or unsuppressed + + + + + + + + + + + + + + + + URIs to the modified event suppression. + + + + &EventSuppressionListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + List the PCI devices of a host. + + + + + + + + The list of PCI devices of a host. + + + &deviceListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific PCI device. + + + + + + &deviceListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies a specific PCI device. + + + + + + + + The name for the device. + + + + + The status of this device; + i.e. True, False. + + + + + + + + + + + + + + + + URIs to the PCI devices of this host. + + + + &deviceListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + List the service parameters. + + + + + + + + The list of service parameters. + + + &serviceParameterListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of the Service parameter + object. + + + + + + &serviceParameterListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Creates parameters for a service. + + + + + + + + + This parameter specifies the name of the service. + Valid values are (is): identity + + + + + + This parameter specifies the section of the + configuration file for the service. + + + + + + + + + + + + + + + &serviceParameterListShowParameters; + + + + + + + + &postPutFaults; + + + + + Applies the service parameters. + + + + + + + + + This parameter specifies the name of the service. + Valid values are (is): identity + + + + + + + + + + + + + + + + + + + + + + Modifies the value of the Service + parameter object. + + + + + + + + The name for the service parameter. + + + + + The value of the service parameter. + + + + + + + + + + + + + + + + URIs to the service parameters. + + + &serviceParameterListShowParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a service parameter. + + + + + + + + + + + + + + + + + List the LLDP agents of a host. + + + + + + + + The list of LLDP agents of a host. + + + &lldpAgentListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific LLDP agent. + + + + + + &lldpAgentListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List the LLDP neighbors of a host. + + + + + + + + The list of LLDP neighbors of a host. + + + &lldpNeighborListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific LLDP neighbor. + + + + + + &lldpNeighborListShowParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List all services running. + + + + + + + + The list of services. + + + &serviceListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific service. + + + + + + &serviceListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Modifies the configuration of a service. + + + + + + + + Service enabled. + + + + + + + + + + + + + + + + Service enabled. + + + + + Service name. + + + + + + + + + + &postPutFaults; + + + + + + + + + List all service nodes in the system. + + + + + + + + The list of service nodes. + + + &serviceNodeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific service node. + + + + + + &serviceNodeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List all service groups in the system. + + + + + + + + The list of service groups. + + + &serviceGroupListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Shows the attributes of a specific service group. + + + + + + &serviceGroupListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List the SDN controllers. + + + + + + + + The list of SDN controllers. + + + &sdnControllerCommonParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of the SDN controller. + + + + + + &sdnControllerCommonParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Adds an SDN controller. + + + + + + + &sdnControllerCommonParameters; + + + + + + + + + + + + &sdnControllerCommonParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies the attributes of the SDN controller. + + + + + + &sdnControllerCommonParameters; + + + + + + + + + + + + &sdnControllerCommonParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes an SDN controller. + + + + + + + + + + + + + + + + + Show configuration for remote logging. + + + + + + + + The list of remotelogging configuration. + + + &remoteLoggingParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies the configuration of the remote logging of this system. + + + + + + + + IP Address of remote log server. + + + + + Remote log server enabled. + + + + + Remote log server transport protocol. + + + + + Remote log server port. + + + + + + + + + + + + + + &remoteLoggingParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Shows detailed information about a specific address pool. + + + + + + &addrPoolCommonParameters; + &addrPoolListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows detailed information about all address pools. + + + + + + &addrPoolCommonParameters; + &addrPoolListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Deletes an address pool. + + + + + + + + + + + + + Adds an address pool. + + + + + + + &addrPoolCommonParameters; + + + + + + + + + + + + &addrPoolCommonParameters; &addrPoolListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies an address pool. + + + + + + + + The name (or network type) of the address pool resource. + + + + + A string representing the IP address allocation scheme; random to allocate in random order, or sequential to allocate in sequential order. + + + + + A python list, formatted as a JSON string, representing a series of start-end pairs which define the allocatable ranges of IP addresses in the pool. + + + + + + + + + + + + + + &addrPoolCommonParameters; + &addrPoolListShowParameters; + + + + + + + + &postPutFaults; + + + + + Shows detailed information about a specific address. + + + + + + &addressCommonParameters; + &addressListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows detailed information about all addresses. + + + + + + &addressCommonParameters; + &addressListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Deletes an address. + + + + + + + + + + + + + Adds an address. + + + + + + + &addressCommonParameters; + + + + + + + + + + + + &addressCommonParameters; &addressListShowParameters; + + + + + + + + &postPutFaults; + + + + + Shows detailed information about a specific route. + + + + + + &routeCommonParameters; + &routeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows detailed information about all routes. + + + + + + &routeCommonParameters; + &routeListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Deletes a route. + + + + + + + + + + + + + Adds a route. + + + + + + + &routeCommonParameters; + + + + + + + + + + + + &routeCommonParameters; &routeListShowParameters; + + + + + + + + &postPutFaults; + + + + + + Shows detailed information about a specific network. + + + + + + &networkListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows detailed information about all networks. + + + + + + &networkListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List the storage backends. + + + + + + &storageBackendListParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + List the storage backends usage. + + + + + + &storageBackendUsageParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List LVM storage backends. + + + + + + &storageBackendListParameters; + &storageLvmParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of the Lvm storage backend. + + + + + + &storageBackendListParameters; + &storageLvmParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Add a Lvm storage backend. + + + + + + + + This parameter specifies the type of the backend. + Valid values are (is): lvm + + + + + + This parameter specifies the name of the backend. + + + + &storageBackendModifyParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageLvmParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies the Lvm storage backend. + + LVM backend only supports cinder service and is mandatory. Also, there is + currently no modifiable parameter in the capabilities field. Any custom + defined parameter will remain unused. + + + + + + + &storageBackendModifyParameters; + + + + + + + + + + + + + + Returns back parameter in request. + + + &storageBackendListParameters; + &storageLvmParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes an LVM storage backend. + + + + + + + + + + + + + + + + List Ceph storage backends. + + + + + + &storageBackendListParameters; + &storageCephParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of the Ceph storage backend. + + + + + + &storageBackendListParameters; + &storageCephParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Add a Ceph storage backend. + + + + + + + + + This parameter specifies the type of the backend. + Valid values are (is): ceph + + + + + + This parameter specifies the name of the backend. + + + + &storageBackendModifyParameters; + &storageCephParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageCephParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies the Ceph storage backend. + + + + + + &storageBackendModifyParameters; + &storageCephParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageCephParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a ceph storage backend. + + + + + + + + + + + + + + + + List file storage backends. + + + + + + &storageBackendListParameters; + &storageFileParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of the file storage backend. + + + + + + &storageBackendListParameters; + &storageFileParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Add a File storage backend. + + + + + + + + + This parameter specifies the type of the backend. + Valid values are (is): file + + + + + + This parameter specifies the name of the backend. + + + + &storageBackendModifyParameters; + &storageFileParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageFileParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies the File storage backend. + + + + + + &storageBackendModifyParameters; + &storageFileParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageFileParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a file storage backend. + + + + + + + + + + + + + + + + List external storage backends. + + + + + + &storageBackendListParameters; + &storageExternalParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of the external storage backend. + + + + + + &storageBackendListParameters; + &storageExternalParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Add an External storage backend. + + + + + + + + + This parameter specifies the type of the backend. + Valid values are (is): external + + + + + + This parameter specifies the name of the backend. + + + + &storageBackendModifyParameters; + &storageExternalParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageExternalParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies the External storage backend. + + + + + + &storageBackendModifyParameters; + &storageExternalParameters; + + + + + + + + + + + + &storageBackendListParameters; + &storageExternalParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes an external storage backend. + + + + + + + + + + + + + + + + List the storage tiers. + + + + + + &storageTierListParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of a storage tier. + + + + + + &storageTierListParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Add a storage tier. + + + + + + + + + This parameter specifies the unique name of the storage tier. + + + &storageTierModifyParameters; + + + + + + + + + + + + &storageTierListParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies the storage tier. + + + + + + &storageTierModifyParameters; + + + + + + + + + + + + &storageTierListParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a storage tier. + + + + + + + + + + + + + + + + Shows attributes of a Controller filesystem. + + + + + + &controllerFsParametersFilesystems; + &controllerFsParametersExtra; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + List the Controller filesystems. + + + + + + &controllerFsParametersFilesystems; + &controllerFsParametersExtra; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies a Controller filesystem. + + + + + + &controllerFsModifyParametersFilesystems; + + + + + + + + + + + + &controllerFsParametersFilesystems; + &controllerFsParametersExtra; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies Controller Filesystem(s). + + + + + + &controllerFsModifyParametersFilesystems; + + + + + + + + + + + + + + + + + + &postPutFaults; + + + + + + + + + List Ceph monitors. + + + + + + &cephMonParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows attributes of a Ceph monitor. + + + + + + &cephMonParameters; + &cephMonParametersExtra; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies a Ceph monitor. + + + + + + &cephMonParameters; + + + + + + + + + + + + &cephMonParameters; + &cephMonParametersExtra; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + + + + + Shows the health status of the system. + + + + + + + + + &commonFaults; &getFaults; + + + + + Shows the health status of the system with requirements for an upgrade. + + + + + + + + + &commonFaults; &getFaults; + + + + + + + + + List of loads installed on the system. + + + + + + &loadParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows the attributes of a load. + + + + + + &loadParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Deletes a load. + + + + + + + + + + + + + Import a load. + + + + + + + + The full system path of the iso. + + + + + The full system path of the detached signature for the iso. + + + + + + + + + + + + + + &loadParameters; + + + + + + + + &commonFaults; &postPutFaults; + + + + + + + + + Shows the status of the upgrade + + + + + + &upgradeListParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Completes the upgrade. This can be done after the upgrade is activated or aborted. + + + + + + + &upgradeParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; + + + + + Activate or abort the upgrade. + + + + + + + + Change the state of the upgrade: + Valid values are: aborting, + or activation-requested. + + + + + + + + + + + + + + + &upgradeParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Starts the upgrade. + + + + + + + + Set to true to ignore minor and warning alarms. + + + + + + + + + + + + + + &upgradeParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &postPutFaults; + + + + + Upgrades a host. + + + + + + + + Set to true to perform the action even if the host is offline. + + + + + + + + + + + + + + &hostListShowParameters; + + + + + + + + &commonFaults; &postPutFaults; + + + + + Downgrades a host. + + + + + + + + Set to true to perform the action even if the host is offline. + + + + + + + + + + + + + + &hostListShowParameters; + + + + + + + + &commonFaults; &postPutFaults; + + + + + + + + + Install System Certificate. + Accepts a PEM file containing the X509 certificate. + + + + For security reasons, the original certificate, + containing the private key, will be removed, + once the private key is processed. + + + + + + + + + + + The content of a file. + e.g. if using curl, this would be specified as: + curl -F name=@full_path_of_filename + + + + + &certconfigCommonParameters; + + + + + + + + + &commonFaults; &postPutFaults; + + + + + Shows attributes of the Certificate configuration. + + + + + + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + List installed System Certificates. + + + + + + &commonListShowParameters; + + + + + + + &commonFaults; &getFaults; + + + + + + + + + + Shows attributes of the TPM configuration. + + + + + + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Adds a TPM configuration. + + + + + + + &tpmconfigCommonParameters; + + + + + + + + + + + + &tpmconfigCommonParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Modifies a TPM configuration. + + + + + + &tpmconfigCommonParameters; + + + + + + + + + + + + &tpmconfigCommonParameters; + &commonListShowParameters; + + + + + + + + &postPutFaults; + + + + + Deletes a TPM configuration. + + + + + + + + + + + + + + + + + Shows custom firewall rules. + + + + + + &customFirewallRulesParameters; + &commonListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Install custom firewall rules. + Accepts a file containing the custom OAM firewall rules + compatible with the Linux Netfilter framework. + + + + + + + + + The content of a file. + e.g. if using curl, this would be specified as: + curl -F name=@full_path_of_filename + + + + + + + + + + + + &commonFaults; &postPutFaults; + + + + + + + + + Install license file. + + + + + + + + The content of a file. + e.g. if using curl, this would be specified as: + curl -F name=@full_path_of_filename + + + + + + + + + + + + + &commonFaults; &postPutFaults; + + + + + List license information. + + + + + + &licenseListParameters; + + + + + + + + &commonFaults; &getFaults; + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_get-response.json new file mode 100644 index 000000000..0355b5490 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_get-response.json @@ -0,0 +1,11 @@ +{ + "extensions" : { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-pipelines/v1", + "name" : "wrs-pipelines", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "Windriver Telemetry Pipelines for managing the writing of Ceilometer PMs to a Comma-Separated-Value file.", + "alias" : "wrs-pipelines", + "links" : [] + } +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_list-response.json new file mode 100644 index 000000000..ac4d5ea9e --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/extension_list-response.json @@ -0,0 +1,13 @@ +{ + "extensions" : [ + { + "namespace" : "http://docs.windriver.org/tis/ext/wrs-pipelines/v1", + "name" : "wrs-pipelines", + "updated" : "2014-10-01T12:00:00-00:00", + "description" : "Windriver Telemetry Pipelines for managing the writing of Ceilometer PMs to a Comma-Separated-Value file.", + "alias" : "wrs-pipelines", + "links" : [] + } + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/metertype_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/metertype_list-response.json new file mode 100644 index 000000000..b6050f026 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/metertype_list-response.json @@ -0,0 +1,7 @@ +[ +{ + "name": "memory.usage", + "type": "gauge", + "unit": "MB" +} +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_list-response.json new file mode 100644 index 000000000..d69233922 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_list-response.json @@ -0,0 +1,11 @@ +[ +{ + "name": "csv", + "compress": true, + "enabled": true, + "meters": ["!vswitch.*"], + "location": "/opt/cgcs/ceilometer/csv/pm.csv", + "backup_count": 5, + "max_bytes": 10000000 +} +] diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-request.json new file mode 100644 index 000000000..9df0e7973 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-request.json @@ -0,0 +1,8 @@ +{"name": "csv", + "compress": false, + "enabled": false, + "meters": ["!vswitch.*", "!cpu_util"], + "location": "/opt/cgcs/ceilometer/csv/pm2.csv", + "backup_count": 4, + "max_bytes": 9999999 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-response.json new file mode 100644 index 000000000..755e81da2 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_modify-response.json @@ -0,0 +1,10 @@ +{ + "name": "csv", + "compress": false, + "enabled": false, + "meters": ["!vswitch.*", "!cpu_util"], + "location": "/opt/cgcs/ceilometer/csv/pm2.csv", + "backup_count": 4, + "max_bytes": 9999999 +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_show-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_show-response.json new file mode 100644 index 000000000..3214dfa90 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/api_samples/telemetry-v2-cgcs-ext/pipeline_show-response.json @@ -0,0 +1,9 @@ +{ + "name": "csv", + "compress": true, + "enabled": true, + "meters": ["!vswitch.*"], + "location": "/opt/cgcs/ceilometer/csv/pm.csv", + "backup_count": 5, + "max_bytes": 10000000 +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/cgcs-ext/telemetry-v2-cgcs-ext.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/cgcs-ext/telemetry-v2-cgcs-ext.wadl new file mode 100644 index 000000000..e0ed209b1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/cgcs-ext/telemetry-v2-cgcs-ext.wadl @@ -0,0 +1,229 @@ + + + +%common;]> + + + + + + + + + + + + + + + + + + + + The alias for the extension + to list. + + + + + + + + + + + + + + + + + + + The name for the pipeline. + + + + + + + + + + + + + + + + + Lists all extensions. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Gets information about a specified extension. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Lists meter types. + + + + + + + + + Indicates name of the Meter Type + + + + + Indicates type of the Meter Type + + + + + Indicates unit of the Meter Type + + + + + + + + + + + &commonFaults; &getFaults; + + + + + + Lists all pipelines. + + + + + + + &pipelineListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Shows detailed information about a specific pipeline that outputs to CSV. + + + + + + + &pipelineListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + Modifies a specific pipeline. + Performance of the entire system can be impacted by storing too much data to CSV + + + + + + &pipelineListUpdateParameters; + + + + + + + + + + + + &pipelineListShowParameters; + + + + + + + + &postPutFaults; + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/common.ent new file mode 100644 index 000000000..9c5b3d76b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/telemetry-api/v2/common.ent @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + '> + + + + + + + + + '> + + + + + '> + + + + + + '> + + + + + + '> + + + + + + Indicates namespace of the extension. + + + + + Indicates name of the extension. + + + + + Indicates updated time of the extension. + + + + + Indicates description of the extension. + + + + + Indicates alias of the extension. + + + + + A list of links for the extension. + + + '> + + + + + + Indicates name of the CSV pipeline. + + + + + Indicates whether or not to compress the CSV file when rotating. + + + + + Indicates whether or not to enable this CSV pipeline. + + + + + A regular expression of the meters piped to CSV. + + + + + The full path to the CSV output file. The folder is restricted. + + + + + The number of backed up CSV files to preserve. + + + + + The size in bytes to allow the CSV file to grow before triggering rotating and compressing. + + + '> + + + Indicates whether or not to compress the CSV file when rotating. + + + + + Indicates whether or not to enable this CSV pipeline. + + + + + A regular expression of the meters piped to CSV + + + + + The full path to the CSV output file. The folder is restricted + + + + + The number of backed up CSV files to preserve. It can be any number from 0. No backup file will be generated when backup_count is set to 0 + + + + + The size in bytes to allow the CSV file to grow before triggering rotating and compressing. It can be any number from 0. No rotating and compressing will be triggered when max_bytes is set to 0 + + + '> + + + + + + + GET'> + PUT'> + POST'> + DELETE'> diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-snapshot-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-snapshot-request.json new file mode 100644 index 000000000..c2747462f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-snapshot-request.json @@ -0,0 +1,10 @@ +{ + "wrs-snapshot:os-export_snapshot" : { + "volume_type" : null, + "updated_at" : "2015-03-03T15:32:31.386661", + "status" : "exporting", + "volume_size" : 1, + "id" : "9ad36199-c5b3-44bf-9273-c298ab7a0a2b", + "display_description" : null + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-volume-request.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-volume-request.json new file mode 100644 index 000000000..2e700b17f --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/action-volume-request.json @@ -0,0 +1,21 @@ +{ + 'wrs-volume:os-volume_export' : { + 'volume_type' : null, + 'updated_at' : '2015-02-27T14:04:35.201969', + 'status' : 'exporting', + 'id' : '27080551-9d88-4cf0-aa85-c1392dbf38f4', + 'display_description' : null, + 'size' : 1 + } +} +or +{ + 'wrs-volume:os-volume_import' : { + 'volume_type' : null, + 'updated_at' : '2015-02-27T15:03:54.045796', + 'status' : 'importing', + 'id' : '27080551-9d88-4cf0-aa85-c1392dbf38f4', + 'display_description' : null, + 'size' : 1 + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_get-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_get-response.json new file mode 100644 index 000000000..c76e8d894 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_get-response.json @@ -0,0 +1,24 @@ +{ + "extension" : { + "namespace" : "http://docs.windriver.com/volume/ext/wrs-volume/api/v1.0", + "name" : "WrsVolumeExport", + "updated" : "2014-08-11T00:00:00+00:00", + "description" : "Enable volume export/import", + "alias" : "wrs-volume", + "links" : [] + } +} + +OR + +{ + "extension" : { + "namespace" : "http://docs.windriver.com/volume/ext/wrs-snapshot/api/v1.0", + "name" : "WrsSnapshotExportAction", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "Enable snapshot export to file", + "alias" : "wrs-snapshot", + "links" : [] + } +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_list-response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_list-response.json new file mode 100644 index 000000000..6a0ecf9ad --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/extension_list-response.json @@ -0,0 +1,23 @@ +{ + "extensions" : [ + ... + { + "namespace" : "http://docs.windriver.com/volume/ext/wrs-snapshot/api/v1.0", + "name" : "WrsSnapshotExportAction", + "updated" : "2014-08-16T00:00:00+00:00", + "description" : "Enable snapshot export to file", + "alias" : "wrs-snapshot", + "links" : [] + }, + { + "namespace" : "http://docs.windriver.com/volume/ext/wrs-volume/api/v1.0", + "name" : "WrsVolumeExport", + "updated" : "2014-08-11T00:00:00+00:00", + "description" : "Enable volume export/import", + "alias" : "wrs-volume", + "links" : [] + }, + ... + ] +} + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_list_detail_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_list_detail_response.json new file mode 100644 index 000000000..00f88a45b --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_list_detail_response.json @@ -0,0 +1,30 @@ +{ + "snapshots" : [ + { + "volume_id" : "f15dcbfb-8b41-4fff-adb8-77a4162a318b", + "status" : "available", + "display_description" : null, + "display_name" : null, + "size" : 1, + "created_at" : "2015-02-27T13:19:02.380453", + "os-extended-snapshot-attributes:project_id" : "e0741109067649a8899936e9fefda95b", + "wrs-snapshot:backup_status" : "Export completed at 2015-02-27 13:19:48.914344", + "id" : "7b220cb7-212f-411e-a8cd-41e6bdbac724", + "metadata" : {}, + "os-extended-snapshot-attributes:progress" : "100%" + }, + { + "volume_id" : "2c4f094b-f6d8-4ff6-800e-e5998cb4d6fa", + "status" : "available", + "display_description" : null, + "display_name" : null, + "size" : 1, + "created_at" : "2015-02-27T20:56:32.033427", + "os-extended-snapshot-attributes:project_id" : "e0741109067649a8899936e9fefda95b", + "wrs-snapshot:backup_status" : "Export completed at 2015-02-27 20:57:29.279574", + "id" : "0aa45e0c-74ea-433e-b8f3-0dc778d3972b", + "metadata" : {}, + "os-extended-snapshot-attributes:progress" : "100%" + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_show_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_show_response.json new file mode 100644 index 000000000..3b3e53aea --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/snapshot_show_response.json @@ -0,0 +1,15 @@ +{ + "snapshot" : { + "volume_id" : "2c4f094b-f6d8-4ff6-800e-e5998cb4d6fa", + "status" : "available", + "display_description" : null, + "display_name" : null, + "size" : 1, + "created_at" : "2015-02-27T20:56:32.033427", + "os-extended-snapshot-attributes:project_id" : "e0741109067649a8899936e9fefda95b", + "wrs-snapshot:backup_status" : "Export completed at 2015-02-27 20:57:29.279574", + "id" : "0aa45e0c-74ea-433e-b8f3-0dc778d3972b", + "metadata" : {}, + "os-extended-snapshot-attributes:progress" : "100%" + } +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_list_detail_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_list_detail_response.json new file mode 100644 index 000000000..990b3a6e1 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_list_detail_response.json @@ -0,0 +1,73 @@ +{ + "volumes" : [ + { + "wrs-volume:backup_status" : "Export completed at 2015-02-27 16:35:53.545339", + "volume_type" : "None", + "status" : "available", + "size" : 1, + "created_at" : "2015-02-27T16:26:08.164607", + "id" : "b7db512f-463e-4720-8fbd-154c0f2bc2ae", + "metadata" : {}, + "attachments" : [], + "os-volume-replication:driver_data" : null, + "os-vol-mig-status-attr:migstat" : null, + "display_name" : null, + "availability_zone" : "nova", + "display_description" : null, + "encrypted" : false, + "os-vol-mig-status-attr:name_id" : null, + "os-vol-host-attr:host" : "controller@lvm#lvm", + "os-volume-replication:extended_status" : null, + "snapshot_id" : null, + "os-vol-tenant-attr:tenant_id" : "e0741109067649a8899936e9fefda95b", + "bootable" : "false", + "source_volid" : null + }, + { + "wrs-volume:backup_status" : "Import completed at 2015-02-27 15:04:29.135579", + "volume_type" : "None", + "status" : "available", + "size" : 1, + "created_at" : "2015-02-27T14:04:34.763953", + "id" : "27080551-9d88-4cf0-aa85-c1392dbf38f4", + "metadata" : {}, + "attachments" : [], + "os-volume-replication:driver_data" : null, + "os-vol-mig-status-attr:migstat" : null, + "display_name" : null, + "availability_zone" : "nova", + "display_description" : null, + "encrypted" : false, + "os-vol-mig-status-attr:name_id" : null, + "os-vol-host-attr:host" : "controller@lvm#lvm", + "os-volume-replication:extended_status" : null, + "snapshot_id" : null, + "os-vol-tenant-attr:tenant_id" : "e0741109067649a8899936e9fefda95b", + "bootable" : "false", + "source_volid" : null + }, + { + "wrs-volume:backup_status" : "Snapshot export completed at 2015-02-27 20:57:29.323714", + "volume_type" : "None", + "status" : "available", + "size" : 1, + "created_at" : "2015-02-27T13:44:55.317995", + "id" : "2c4f094b-f6d8-4ff6-800e-e5998cb4d6fa", + "metadata" : {}, + "attachments" : [], + "os-volume-replication:driver_data" : null, + "os-vol-mig-status-attr:migstat" : null, + "display_name" : null, + "availability_zone" : "nova", + "display_description" : null, + "encrypted" : false, + "os-vol-mig-status-attr:name_id" : null, + "os-vol-host-attr:host" : "controller@lvm#lvm", + "os-volume-replication:extended_status" : null, + "snapshot_id" : null, + "os-vol-tenant-attr:tenant_id" : "e0741109067649a8899936e9fefda95b", + "bootable" : "false", + "source_volid" : null + } + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_show_response.json b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_show_response.json new file mode 100644 index 000000000..fd0869be8 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/api_samples/volume-v2-cgcs-ext/volume_show_response.json @@ -0,0 +1,27 @@ +{ + "volumes" : [ + { + "wrs-volume:backup_status" : "Import completed at 2015-02-27 15:04:29.135579", + "volume_type" : "None", + "status" : "available", + "size" : 1, + "created_at" : "2015-02-27T14:04:34.763953", + "id" : "27080551-9d88-4cf0-aa85-c1392dbf38f4", + "metadata" : {}, + "attachments" : [], + "os-volume-replication:driver_data" : null, + "os-vol-mig-status-attr:migstat" : null, + "display_name" : null, + "availability_zone" : "nova", + "display_description" : null, + "encrypted" : false, + "os-vol-mig-status-attr:name_id" : null, + "os-vol-host-attr:host" : "controller@lvm#lvm", + "os-volume-replication:extended_status" : null, + "snapshot_id" : null, + "os-vol-tenant-attr:tenant_id" : "e0741109067649a8899936e9fefda95b", + "bootable" : "false", + "source_volid" : null + }, + ] +} diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/cgcs-ext/volume-v2-cgcs-ext.wadl b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/cgcs-ext/volume-v2-cgcs-ext.wadl new file mode 100644 index 000000000..469e33fff --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/cgcs-ext/volume-v2-cgcs-ext.wadl @@ -0,0 +1,507 @@ + + + +%common;]> + + + + + + + + + + + + + + + + The ID for the tenant or + account in a multi-tenancy + cloud. + + + + + + + + + The alias for the extension + to list. + + + + + + + + + + + + + + + + + The ID for the volume + to list. + + + + + + + + + + + + + + + + + + + The ID for the snapshot + to list. + + + + + + + + + + + + + + + + Details for a version. + + + + + + + + + + + Lists all extensions. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Gets information about a specified extension. + + + + + + + &extensionListShowParameters; + + + + + + + + &commonFaults; &getFaults; + + + + + + Get information about system volumes. + Preconditions + + The specified volume must exist in all case. + + + + + + + + + + + + + + + + Indicates backup status. + + + + + + + + + + + + + + Get information about a specified volume. + Preconditions + + The specified volume must exist in all case. + + + + + + + + + + + + + + + + Indicates backup status. + + + + + + + + + + + + + + + Executes the specified action or command + on the specified volume. + Preconditions + + The specified volume must exist in all case. + + + + + + + + + Export volume to a file + + + + + + Import a volume from a file + + + file_name: "VolumeExportName.tgz". + + + + + + + + + + + + Indicates the volume type. + + + + + Indicates when the action was performed. + + + + + Indicates the state of the export or import action. + + + + + Indicates the volume UUID. + + + + + Volume descrition if any. + + + + + Indicates the volume size in Gbyte. + + + + + + + + + + + + + + Get information about system volume snapshots. + Preconditions + + The specified volume snapshot must exist in all case. + + + + + + + + + + + + + + + + Indicates backup status. + + + + + + + + + + + + + + Get information of a specific volume snapshot. + Preconditions + + The specified volume snapshot must exist in all case. + + + + + + + + + + + + + + + + Indicates backup status. + + + + + + + + + + + + + + + Executes the specified action or command + on the specified volume snapshot. + Preconditions + + The specified volume snapshot must exist in all case. + + + + sn + + + + + Export volume snapshot to a file + + + + + + + + + + + + Indicates the volume type. + + + + + Indicates when the action was performed. + + + + + Indicates the state of the volume snapshot export action. + + + + + Indicates the volume UUID. + + + + + Volume descrition if any. + + + + + Indicates the volume size in Gbyte. + + + + + + + + + + + diff --git a/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/common.ent b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/common.ent new file mode 100644 index 000000000..5641d5a67 --- /dev/null +++ b/restapi-doc/restapi-doc/api-ref/src/wadls/volume-api/v2/common.ent @@ -0,0 +1,183 @@ + + + + + + Indicates namespace of the extension. + + + + + Indicates name of the extension. + + + + + Indicates updated time of the extension. + + + + + Indicates description of the extension. + + + + + Indicates alias of the extension. + + + + + A list of links for the extension. + + + '> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '> + + + + + '> + + + + + + + + + '> + + + + + '> + + + + + + '> + + + + + + '> + + + + + + + + + + Indicates name of the volume. + + + + + Indicates whether or not the volume is compressed. + + + '> + + + + + + + Indicates name of the snapshot. + + + + + Indicates whether or not the snapshot is compressed. + + + '> + + + + GET'> + PUT'> + POST'> + DELETE'> diff --git a/restapi-doc/restapi-doc/pom.xml b/restapi-doc/restapi-doc/pom.xml new file mode 100644 index 000000000..cb914836d --- /dev/null +++ b/restapi-doc/restapi-doc/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + org.openstack.docs + parent-pom + 1.0.0-SNAPSHOT + pom + + api-ref + api-ref-guides + + + + Rackspace Research Repositories + + true + + + + rackspace-research + Rackspace Research Repository + http://maven.research.rackspacecloud.com/content/groups/public/ + + + + + rackspace-research + Rackspace Research Repository + http://maven.research.rackspacecloud.com/content/groups/public/ + + + + + + + + com.rackspace.cloud.api + clouddocs-maven-plugin + 2.1.2 + + + + diff --git a/restapi-doc/restapi-doc/rest-api-usage-example.pdf b/restapi-doc/restapi-doc/rest-api-usage-example.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4cce1aa1e1fa87f31b5bd70cfb5a3e44af44fa42 GIT binary patch literal 293312 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

(~{ux92 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 +Date: Fri, 6 Oct 2017 14:26:03 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/audit.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/audit.spec b/SPECS/audit.spec +index 74b6e7a..f1b28fb 100644 +--- a/SPECS/audit.spec ++++ b/SPECS/audit.spec +@@ -3,7 +3,7 @@ + Summary: User space tools for 2.6 kernel auditing + Name: audit + Version: 2.7.6 +-Release: 3%{?dist} ++Release: 3.el7%{?_tis_dist}.%{tis_patch_ver} + License: GPLv2+ + Group: System Environment/Daemons + URL: http://people.redhat.com/sgrubb/audit/ +-- +1.8.3.1 + diff --git a/security/audit/centos/meta_patches/PATCH_ORDER b/security/audit/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..56ab8f664 --- /dev/null +++ b/security/audit/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +0001-Update-package-versioning-for-TIS-format.patch +meta-enable-audispd.patch diff --git a/security/audit/centos/meta_patches/meta-enable-audispd.patch b/security/audit/centos/meta_patches/meta-enable-audispd.patch new file mode 100644 index 000000000..84e0a4168 --- /dev/null +++ b/security/audit/centos/meta_patches/meta-enable-audispd.patch @@ -0,0 +1,37 @@ +From f0d91192bc8778899d01e7723ababcf7a3808c91 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 6 Oct 2017 14:10:25 -0400 +Subject: [PATCH] meta patch for enabling audispd and LOG_AUTH facility + +--- + SPECS/audit.spec | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/SPECS/audit.spec b/SPECS/audit.spec +index e144332..a188b89 100644 +--- a/SPECS/audit.spec ++++ b/SPECS/audit.spec +@@ -16,6 +16,10 @@ Patch2: audit-2.7.5-no-backlog-wait-time.patch + Patch3: audit-2.7.7-queue_error_action.patch + # BZ 1460110 - aureport does not report all anomalies + Patch4: audit-2.7.7-aureport.patch ++ ++# WRS Patches ++Patch1000: 0001-enable-audispd-and-auth-facility.patch ++ + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + BuildRequires: openldap-devel + BuildRequires: swig +@@ -95,6 +99,9 @@ behavior. + %patch3 -p1 + %patch4 -p1 + ++# WRS patches ++%patch1000 -p1 ++ + %build + %configure --sbindir=/sbin --libdir=/%{_lib} --with-python=yes --with-libwrap --enable-gssapi-krb5=yes --with-libcap-ng=yes --with-arm --with-aarch64 \ + --without-golang --enable-zos-remote --enable-systemd +-- +1.9.1 + diff --git a/security/audit/centos/patches/0001-enable-audispd-and-auth-facility.patch b/security/audit/centos/patches/0001-enable-audispd-and-auth-facility.patch new file mode 100644 index 000000000..7f5ed346c --- /dev/null +++ b/security/audit/centos/patches/0001-enable-audispd-and-auth-facility.patch @@ -0,0 +1,31 @@ +From de26fc2d64a7afe600d528f34a5bd4f59e250883 Mon Sep 17 00:00:00 2001 +From: Kam Nasim +Date: Fri, 6 Oct 2017 12:57:24 -0400 +Subject: [PATCH] US103091: IMA: System Configuration + +enable audispd to send audit events to the LOG_AUTH facility where +it will be used by syslog-ng to filter them into a seperate ima log as +well as send them to an FM Event log stream +--- + audisp/plugins/builtins/syslog.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/audisp/plugins/builtins/syslog.conf b/audisp/plugins/builtins/syslog.conf +index 7d7dbd7..0a80d72 100644 +--- a/audisp/plugins/builtins/syslog.conf ++++ b/audisp/plugins/builtins/syslog.conf +@@ -6,9 +6,9 @@ + # logged to. Valid options are LOG_LOCAL0 through 7, LOG_AUTH, + # LOG_AUTHPRIV, LOG_DAEMON, LOG_SYSLOG, and LOG_USER. + +-active = no ++active = yes + direction = out + path = builtin_syslog + type = builtin +-args = LOG_INFO ++args = LOG_INFO LOG_AUTH + format = string +-- +1.8.3.1 + diff --git a/security/audit/centos/srpm_path b/security/audit/centos/srpm_path new file mode 100644 index 000000000..f2c35df82 --- /dev/null +++ b/security/audit/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/audit-2.7.6-3.el7.src.rpm diff --git a/security/libtpms/centos/build_srpm.data b/security/libtpms/centos/build_srpm.data new file mode 100644 index 000000000..3803d4c06 --- /dev/null +++ b/security/libtpms/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$CGCS_BASE/downloads/libtpms-0.6.0-4f0d59d.tar.gz" +TIS_PATCH_VER=0 diff --git a/security/libtpms/centos/libtpms.spec b/security/libtpms/centos/libtpms.spec new file mode 100644 index 000000000..48b4fa363 --- /dev/null +++ b/security/libtpms/centos/libtpms.spec @@ -0,0 +1,218 @@ +# --- libtpm rpm-spec --- + +%define name libtpms +%define version 0.6.0 +#WRS +#%define release 1_dev1 +%define release 2%{?_tis_dist}.%{tis_patch_ver} + +# Valid crypto subsystems are 'freebl' and 'openssl' +#WRS +#%if "%{?crypto_subsystem}" == "" +%define crypto_subsystem openssl +#%endif + +# Valid build types are 'production' or 'debug' +%define build_type production + +Summary: Library providing Trusted Platform Module (TPM) functionality +Name: %{name} +Version: %{version} +#WRS +#Release: %{release}%{?dist} +Release: %{release} +License: BSD +Group: Development/Libraries +#WRS +#Url: http://sourceforge.net/projects/ibmswtpm +#Source: http://bergerstefan.users.sourceforge.net/libtpms/%{name}-%{version}.tar.gz +Url: https://github.com/stefanberger/libtpms +Source: %{name}-%{version}-4f0d59d.tar.gz +Provides: libtpms-%{crypto_subsystem} + +%if "%{crypto_subsystem}" == "openssl" +BuildRequires: openssl-devel +%else +BuildRequires: nss-devel >= 3.12.9-2 +BuildRequires: nss-softokn-freebl-devel >= 3.12.9-2 +%if 0%{?rhel} > 6 || 0%{?fedora} >= 13 +BuildRequires: nss-softokn-freebl-static >= 3.12.9-2 +%endif +BuildRequires: nss-softokn-devel >= 3.12.9-2, gmp-devel +%endif +BuildRequires: pkgconfig gawk sed +BuildRequires: automake autoconf libtool bash coreutils + +%if "%{crypto_subsystem}" == "openssl" +Requires: openssl +%else +Requires: nss-softokn-freebl >= 3.12.9-2, nss-softokn >= 3.12.9-2 +%endif +Requires: gmp + +%description +A library providing TPM functionality for VMs. Targeted for integration +into Qemu. + +%package devel +Summary: Include files for libtpms +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Libtpms header files and documentation. + +%files +%defattr(-, root, root, -) +%{_libdir}/%{name}.so.%{version} +%{_libdir}/%{name}.so.0 +%doc LICENSE README CHANGES + +%files devel +%defattr(-, root, root, -) + +%{_libdir}/%{name}.so +%dir %{_includedir}/%{name} +%attr(644, root, root) %{_libdir}/pkgconfig/*.pc +%attr(644, root, root) %{_includedir}/%{name}/*.h +%attr(644, root, root) %{_mandir}/man3/* + +%prep +%setup -q + +%build + +%if "%{crypto_subsystem}" == "openssl" +%define _with_openssl --with-openssl +%endif + +%if %{build_type} == debug +%define _enable_debug --enable-debug +%endif + +./bootstrap.sh +%if %{build_type} == debug +CFLAGS=-O0 +%endif +%configure \ + --with-tpm2 \ + --disable-static \ + --prefix=/usr \ + --libdir=%{_libdir} \ + %{?_with_openssl} \ + %{?_enable_debug} + +make %{?_smp_mflags} + +%check +make check + +%install +install -d -m 0755 $RPM_BUILD_ROOT%{_libdir} +install -d -m 0755 $RPM_BUILD_ROOT%{_includedir}/libtpms +install -d -m 0755 $RPM_BUILD_ROOT%{_mandir}/man3 + +make %{?_smp_mflags} install DESTDIR=${RPM_BUILD_ROOT} + +rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%changelog +* Mon Jun 30 2014 Stefan Berger - 0.5.2-1 +- Updated to version 0.5.2 +- coverity fixes +- fixes for ARM64 using __aarch64__ + +* Sat Jun 07 2014 Fedora Release Engineering - 0.5.1-20.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sat Aug 03 2013 Fedora Release Engineering - 0.5.1-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Mar 25 2013 Stefan Berger - 0.5.1-18 +- Ran autoreconf for support of aarch64 +- Checking for __arm64__ in code + +* Thu Feb 14 2013 Fedora Release Engineering - 0.5.1-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Jul 19 2012 Fedora Release Engineering - 0.5.1-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Feb 17 2012 Peter Robinson - 0.5.1-15 +- Add dist tag as required by package guidelines + +* Fri Jan 27 2012 Stefan Berger - 0.5.1-14 +- fix gcc-4.7 compilation problem + +* Fri Jan 13 2012 Fedora Release Engineering - 0.5.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Dec 20 2011 Dan Horák - 0.5.1-12 +- fix build on secondary arches + +* Wed Nov 2 2011 Stefan Berger - 0.5.1-11 +- added (lib)gmp as runtime dependency + +* Sat Oct 8 2011 Stefan Berger - 0.5.1-10 +- internal fixes; callback fixes + +* Tue Aug 30 2011 Stefan Berger - 0.5.1-9 +- new directory structure and build process + +* Tue Jul 12 2011 Stefan Berger - 0.5.1-8 +- added pkgconfig as build dependency +- enabling __powerpc__ build following Bz 728220 + +* Wed May 25 2011 Stefan Berger - 0.5.1-7 +- increasing NVRAM area space to have enough room for certificates + +* Wed May 25 2011 Stefan Berger - 0.5.1-6 +- adding libtpms.pc pkg-config file + +* Wed Apr 13 2011 Stefan Berger - 0.5.1-5 +- adding BuildRequires for nss-softokn-freebl-static +- several libtpms-internal changes around state serialization and + deserialization +- fixes to libtpms makefile (makefile-libtpms) +- adding build_type to generate a debug or production build +- need nss-devel to have nss-config + +* Tue Mar 08 2011 Stefan Berger - 0.5.1-4 +- small fixes to libtpms makefile + +* Fri Feb 25 2011 Stefan Berger - 0.5.1-3 +- removing release from tar ball name +- Use {?_smp_mflags} for make rather than hardcoding it +- Fixing post and postun scripts; removing the scripts for devel package +- Fixing usage of defattr +- Adding version information into the changelog headers and spaces between the changelog entries +- Adding LICENSE, README and CHANGELOG file into tar ball and main rpm +- Removing clean section +- removed command to clean the build root +- adding library version to the libries required for building and during + runtime +- Extended Requires in devel package with {?_isa} + +* Fri Feb 18 2011 Stefan Berger - 0.5.1-2 +- make rpmlint happy by replacing tabs with spaces +- providing a valid URL for the tgz file +- release is now 2 -> 0.5.1-2 + +* Mon Jan 17 2011 Stefan Berger - 0.5.1-1 +- Update version to 0.5.1 + +* Fri Jan 14 2011 Stefan Berger - 0.5.0-1 +- Changes following Fedora review comments + +* Thu Dec 2 2010 Stefan Berger +- Small tweaks after reading the FedoreCore packaging requirements + +* Tue Nov 16 2010 Stefan Berger +- Created initial version of rpm spec files +- Version of library is now 0.5.0 +- Debuginfo rpm is built but empty -- seems to be a known problem + Check https://bugzilla.redhat.com/show_bug.cgi?id=209316 diff --git a/security/swtpm/centos/build_srpm.data b/security/swtpm/centos/build_srpm.data new file mode 100644 index 000000000..ca0fb04bd --- /dev/null +++ b/security/swtpm/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$PKG_BASE/files/* $CGCS_BASE/downloads/swtpm-0.1.0-253eac5.tar.gz" +TIS_PATCH_VER=0 diff --git a/security/swtpm/centos/swtpm.spec b/security/swtpm/centos/swtpm.spec new file mode 100644 index 000000000..9c44d0962 --- /dev/null +++ b/security/swtpm/centos/swtpm.spec @@ -0,0 +1,215 @@ +# --- swtpm rpm-spec --- + +%define name swtpm +%define version 0.1.0 +#WRS +#%define release 1 +%define release 2%{?_tis_dist}.%{tis_patch_ver} + +# Valid crypto subsystems are 'freebl' and 'openssl' +#WRS +#%if "%{crypto_subsystem}" == "" +%define crypto_subsystem openssl +#%endif + +Summary: TPM Emulator +Name: %{name} +Version: %{version} +#WRS +#Release: %{release}.dev2%{?dist} +Release: %{release} +License: BSD +Group: Applications/Emulators +Source: %{name}-%{version}-253eac5.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +#WRS +Source1: qemu +Source2: setup_vtpm + + +# due to gnutls backlevel API: +%if 0%{?rhel} >= 7 || 0%{?fedora} >= 19 + %define with_gnutls 1 +%else + %define with_gnutls 0 +%endif + +BuildRequires: automake autoconf bash coreutils libtool sed +BuildRequires: libtpms-devel >= 0.6.0 fuse-devel glib2-devel gmp-devel +BuildRequires: expect bash net-tools nss-devel socat python-twisted +%if %{with_gnutls} +BuildRequires: gnutls >= 3.1.0 gnutls-devel gnutls-utils +BuildRequires: libtasn1-devel libtasn1 +%if 0%{?fedora} +BuildRequires: libtasn1-tools +%endif +%endif +%if 0%{?fedora} > 16 +BuildRequires: kernel-modules-extra +%endif + +#WRS +BuildRequires: openssl-devel +Requires: openssl + +#WRS +Requires: seabios-bin >= 1.10.2-3 + +Requires: fuse expect libtpms >= 0.6.0 +%if 0%{?fedora} > 16 +Requires: kernel-modules-extra +%endif + +%description +TPM emulator built on libtpms providing TPM functionality for QEMU VMs + +%package libs +Summary: Common libraries for TPM emulators +Group: System Environment/Libraries +License: BSD + +%description libs +A library with callback functions for libtpms based TPM emulator + +%package cuse +Summary: TPM emulator with CUSE interface +Group: Applications/Emulators +License: BSD +BuildRequires: selinux-policy-devel + +%description cuse +TPM Emulator with CUSE interface + +%package devel +Summary: Include files for the TPM emulator's CUSE interface for usage by clients +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Include files for the TPM emulator's CUSE interface. + +%package tools +Summary: Tools for the TPM emulator +License: BSD +Group: Applications/Emulators +Requires: swtpm fuse +#WRS +#Requires: trousers >= 0.3.9 tpm-tools >= 1.3.8-6 expect bash net-tools gnutls-utils +Requires: trousers >= 0.3.9 expect bash net-tools gnutls-utils + +%description tools +Tools for the TPM emulator from the swtpm package + +%files +%defattr(-,root,root,-) +%attr( 755, root, root) %{_bindir}/swtpm +%{_mandir}/man8/swtpm.8* + +#WRS +/etc/libvirt/setup_vtpm +/etc/libvirt/hooks/qemu + + +%files cuse +%defattr(-,root,root,-) +%attr( 755, root, root) %{_bindir}/swtpm_cuse +%{_mandir}/man8/swtpm_cuse.8* +%attr( 755, root, root) %{_datadir}/swtpm/*.pp + +%files libs +%{_libdir}/libswtpm_libtpms.so.* + +%files devel +%defattr(-, root, root, -) +%{_libdir}/libswtpm_libtpms.so + +%dir %{_includedir}/%{name} +%attr(644, root, root) %{_includedir}/%{name}/*.h +%{_mandir}/man3/swtpm_ioctls.3* + +%files tools +%defattr(-,root,root,-) +%attr( 755, root, root) %{_bindir}/swtpm_bios +%if %{with_gnutls} +%attr( 755, root, root) %{_bindir}/swtpm_cert +%endif +%attr( 755, root, root) %{_bindir}/swtpm_setup +%attr( 755, tss , tss) %{_bindir}/swtpm_setup.sh +%attr( 755, root, root) %{_bindir}/swtpm_ioctl +%{_mandir}/man8/swtpm_bios.8* +%{_mandir}/man8/swtpm_cert.8* +%{_mandir}/man8/swtpm_ioctl.8* +%{_mandir}/man8/swtpm-localca.conf.8* +%{_mandir}/man8/swtpm-localca.options.8* +%{_mandir}/man8/swtpm-localca.8* +%{_mandir}/man8/swtpm_setup.8* +%{_mandir}/man8/swtpm_setup.conf.8* +%{_mandir}/man8/swtpm_setup.sh.8* +%config(noreplace) %{_sysconfdir}/swtpm_setup.conf +%config(noreplace) %{_sysconfdir}/swtpm-localca.options +%config(noreplace) %{_sysconfdir}/swtpm-localca.conf +%attr( 755, root, root) %{_datadir}/swtpm/swtpm-localca +%attr( 755, tss, tss) %{_localstatedir}/lib/swtpm-localca + + +%prep +%setup -q + +%build + +#WRS +./bootstrap.sh +%configure \ + --prefix=/usr \ +%if %{with_gnutls} + --with-gnutls \ +%endif +%if "%{crypto_subsystem}" == "openssl" + --with-openssl \ +%endif + TPM_NVDEFINE=/bin/true + +make %{?_smp_mflags} + +%check +make %{?_smp_mflags} check + +%install + +make %{?_smp_mflags} install DESTDIR=${RPM_BUILD_ROOT} +rm -f ${RPM_BUILD_ROOT}%{_libdir}/*.a ${RPM_BUILD_ROOT}%{_libdir}/*.la + +#WRS +mkdir -p $RPM_BUILD_ROOT/etc/libvirt/hooks + +install -m 0500 %{SOURCE1} $RPM_BUILD_ROOT/etc/libvirt/hooks/qemu +install -m 0500 %{SOURCE2} $RPM_BUILD_ROOT/etc/libvirt/setup_vtpm + +# WRS: Don't set (or remove on uninstall): SELINUX Policy and contexts +#%post cuse +#if [ -n "$(type -p semodule)" ]; then +# for pp in /usr/share/swtpm/*.pp ; do +# echo "Activating SELinux policy $pp" +# semodule -i $pp +# done +#fi + +#if [ -n "$(type -p restorecon)" ]; then +# restorecon /usr/bin/swtpm_cuse +#fi + +#%postun cuse +#if [ $1 -eq 0 ]; then +# if [ -n "$(type -p semodule)" ]; then +# for p in swtpmcuse_svirt swtpmcuse ; do +# echo "Removing SELinux policy $p" +# semodule -r $p +# done +# fi +#fi + +%post libs -p /sbin/ldconfig +%postun libs -p /sbin/ldconfig + +%changelog diff --git a/security/swtpm/files/qemu b/security/swtpm/files/qemu new file mode 100755 index 000000000..654485453 --- /dev/null +++ b/security/swtpm/files/qemu @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# This script logs to user.log +# +# An instance with vTPM enable will have a QEMU config section in its XML file. +# e.g. +# +# +# +# +# +# +# +# +# +# For more information see the vTPM HLD in /folk/cgts/docs/security/ +# +# The script is called with the following parameters +# e.g. /etc/libvirt/hooks/qemu +# + +# Save the instance's XML. The guest qemu hook scrips are given the full XML description +# on their stdin. +XML_DATA=$(/bin/cat) + +GUEST_NAME=$1 + +shift +OPERATION=$* + +logger -p info -t $0 "hook qemu file guest $GUEST_NAME with operation $OPERATION" + +VTPM_OPER="" + +if [ "$OPERATION" == "prepare begin -" ]; then + + # Get the instance's uuid + UUID=$(echo $XML_DATA | grep -oP '(?<=).*?(?=)') + if [ -z "$UUID" ]; then + # This should not happen + logger -p err -t $0 "Failed to retrieve uuid for guest $GUEST_NAME" + exit 1 + fi + + # Grab the qemu line "&1 > /dev/null + rc=$? + if [[ $rc != 0 ]]; then + logger -p err -t $0 "setup_vtpm failed with return value $rc for device $VTPM and guest $UUID" + # Do not return error if we were just doing a clear + if [ "$VTPM_OPER" != "clear" ]; then + exit 1; + fi + fi + +fi + +exit 0 + diff --git a/security/swtpm/files/setup_vtpm b/security/swtpm/files/setup_vtpm new file mode 100755 index 000000000..6d9434d50 --- /dev/null +++ b/security/swtpm/files/setup_vtpm @@ -0,0 +1,93 @@ +#!/bin/bash +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# This script logs to user.log +# +# This script will either set up a vTPM or clear a vTPM's data folder if it exists. For +# more information see the vTPM HLD in /folk/cgts/docs/security/ +# +# The vTPM data path will be in the following format +# /etc/nova/instances// +# e.g /etc/nova/instances/137d8de2-1079-46f8-9d96-8b6fd1599238/vtpm-instance-00000036 +# +# This script parameters are +# OPERATION: "clear" or "setup" +# TPM_DEVICE: The vTPM full device name e.g /dev/vtpm-instance-00000036 +# INSTANCE_UUID: The UUID of the Guest e.g. 137d8de2-1079-46f8-9d96-8b6fd1599238 +# +# e.g. setup_vtpm clear /dev/vtpm-instance-00000036 137d8de2-1079-46f8-9d96-8b6fd1599238 +# + +OPERATION=$1 +TPM_DEVICE=$2 +INSTANCE_UUID=$3 + +TPM_DEVICENAME=`basename $TPM_DEVICE` +DATA_PATH=/etc/nova/instances/$INSTANCE_UUID/$TPM_DEVICENAME + +logger -p info -t $0 "$OPERATION the vTPM device $TPM_DEVICE with data path $DATA_PATH for guest $INSTANCE_UUID" + +modprobe cuse +lsmod | grep cuse +rc=$? +if [[ $rc != 0 ]]; then + logger -p err -t $0 "Failed modprobe cuse" + exit $rc; +fi + +if [ "$OPERATION" == "clear" ]; then + # This will clear the vTPM NVData if there was any + rm -rf $DATA_PATH + exit 0 +fi + +if [ "$OPERATION" != "setup" ]; then + logger -p err -t $0 "Invalid operation $OPERATION for vTPM device $TPM_DEVICE" + exit 1 +fi + +if [ -n "$DATA_PATH" ]; then + logger -p info -t $0 "Creating the data path $DATA_PATH" + mkdir -p $DATA_PATH + chown -R tss:root $DATA_PATH + mkdir -p $DATA_PATH/state + chown -R tss:root $DATA_PATH/state +fi + +if [ -e $TPM_DEVICE ]; then + logger -p info -t $0 "The vTPM device $TPM_DEVICE already exists, exiting" + exit 0 +fi + +if [ "$(ls -A $DATA_PATH/state)" ]; then + logger -p info -t $0 "The state file exists under $DATA_PATH/state. Skip swtpm_setup" +else + logger -p info -t $0 "Calling swtpm_setup TPM device $TPM_DEVICE" + swtpm_setup --tpm-state $DATA_PATH/state --tpm2 --logfile $DATA_PATH/swtpm_setup.log + rc=$? + if [[ $rc != 0 ]]; then + logger -p err -t $0 "Failed to set vTPM device $TPM_DEVICE. swtpm_setup returned $rc" + exit $rc; + fi +fi + +# Need to wait for the setup completion +sleep 1 + +logger -p info -t $0 "Calling swtpm cuse on TPM device $TPM_DEVICE" +swtpm cuse --tpm2 -n $TPM_DEVICENAME --tpmstate dir=$DATA_PATH/state --log file=$DATA_PATH/swtpm.log,level=5 +rc=$? +if [[ $rc != 0 ]]; then + logger -p err -t $0 "Failed swtpm cuse for vTPM device $TPM_DEVICE. swtpm returned $rc" + exit $rc; +fi + +# Need to wait for the device creation completion +sleep 1 + +logger -p info -t $0 "The vTPM device $TPM_DEVICE was successfully setup" + +exit 0 diff --git a/security/tpm2-openssl-engine/PKG_INFO b/security/tpm2-openssl-engine/PKG_INFO new file mode 100644 index 000000000..9f29aad37 --- /dev/null +++ b/security/tpm2-openssl-engine/PKG_INFO @@ -0,0 +1,14 @@ +Metadata-Version: 1.1 +Name: tpm2-openssl-engine +Version: 1.0 +Summary: TPM 2.0 Openssl Engine +Home-page: +Author: Windriver +Author-email: info@windriver.com +License: openssl + +Description: Titanium Control's TPM 2.0 OpenSSL Engine. Leveraged by + Titanium applications to provide secure TLS Decryption and Signing + capabilities to Titanium host applications. + +Platform: UNKNOWN diff --git a/security/tpm2-openssl-engine/centos/build_srpm.data b/security/tpm2-openssl-engine/centos/build_srpm.data new file mode 100644 index 000000000..9c445bbb7 --- /dev/null +++ b/security/tpm2-openssl-engine/centos/build_srpm.data @@ -0,0 +1,2 @@ +SRC_DIR="tpm2-openssl-engine" +TIS_PATCH_VER=2 diff --git a/security/tpm2-openssl-engine/centos/tpm2-openssl-engine.spec b/security/tpm2-openssl-engine/centos/tpm2-openssl-engine.spec new file mode 100644 index 000000000..b2719a1e4 --- /dev/null +++ b/security/tpm2-openssl-engine/centos/tpm2-openssl-engine.spec @@ -0,0 +1,39 @@ +Name: tpm2-openssl-engine +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +Summary: TPM 2.0 Openssl Engine +License: openssl +Group: base +Packager: Wind River +URL: unknown + +Source0: %{name}-%{version}.tar.gz + +BuildRequires: openssl-devel +BuildRequires: openssl +BuildRequires: tss2-devel +Requires: tss2 + +%description +TPM 2.0 OpenSSL engine. Leveraged by applications +to provide secure TLS Decryption and Signing capabilities + +%prep +%setup -q + +%build +make %{?_smp_mflags} + +%install +make install ENGINEDIR=%{buildroot}/%{_libdir}/openssl/engines UTILDIR=%{buildroot}/usr/sbin + + +%files +%license LICENSE + +%defattr(-,root,root,-) + +%{_libdir}/openssl/engines/libtpm2.so +/usr/sbin/create_tpm2_key + + diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/LICENSE b/security/tpm2-openssl-engine/tpm2-openssl-engine/LICENSE new file mode 100644 index 000000000..0adcabd4d --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/LICENSE @@ -0,0 +1,57 @@ +OpenSSL License +==================================================================== +Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + +4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + endorse or promote products derived from this software without + prior written permission. For written permission, please contact + openssl-core@openssl.org. + +5. Products derived from this software may not be called "OpenSSL" + nor may "OpenSSL" appear in their names without prior written + permission of the OpenSSL Project. + +6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/)" + +THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +==================================================================== + +This product includes cryptographic software written by Eric Young +(eay@cryptsoft.com). This product includes software written by Tim +Hudson (tjh@cryptsoft.com). +This product is inspired by the original TPM 1.2 openssl engine written +by Kent Yoder for the Trousers Project. This product +includes TPM key blob ASN-1 encoding scheme from James Bottomley + + diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/Makefile b/security/tpm2-openssl-engine/tpm2-openssl-engine/Makefile new file mode 100644 index 000000000..b6d1f8f3c --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/Makefile @@ -0,0 +1,54 @@ +# +# Copyright (c) 2013-2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +#### Installation options +ENGINEDIR= +UTILDIR= + +#### Toolchain options +CC = gcc +LD = $(CC) + +#### Debug flags (typically "-g"). +# Those flags only feed CFLAGS so it is not mandatory to use this form. +DEBUG_CFLAGS = -g -O2 -Werror -Wno-unused-parameter -Wno-missing-braces + +#### Compiler-specific flags that may be used to disable some negative over- +# optimization or to silence some warnings. -fno-strict-aliasing is needed with +# gcc >= 4.4. +SPEC_CFLAGS = -fno-strict-aliasing + +#### Common CFLAGS +CFLAGS = $(DEBUG_CFLAGS) $(SPEC_CFLAGS) + +#### Common LDFLAGS +LDFLAGS = -g + +DYNAMIC_ENGINE=libtpm2.so +UTIL=create_tpm2_key + +INCLUDES+=-I${SYSTEM_DIR}/usr/include/ +LDFLAGS +=-lcrypto -lc -ltss +SRCS += e_tpm2.c e_tpm2_err.c +HEADERS += e_tpm2.h + +OBJS = $(SRCS:.c=.o) + +all: $(DYNAMIC_ENGINE) ${UTIL} + +${UTIL}: $(OBJS) + $(CC) -Wall ${CFLAGS} ${INCLUDES} create_tpm2_key.c ${LDFLAGS} -o ${UTIL} + +$(DYNAMIC_ENGINE): $(OBJS) + $(CC) -Wall ${CFLAGS} ${INCLUDES} ${LDFLAGS} -fPIC -c ${SRCS} + $(CC) -shared -Wl,-soname,${DYNAMIC_ENGINE} ${LDFLAGS} -o ${DYNAMIC_ENGINE} $(OBJS) + +install: all + install -D -m 755 ${DYNAMIC_ENGINE} ${ENGINEDIR}/${DYNAMIC_ENGINE} + install -D -m 755 ${UTIL} ${UTILDIR}/${UTIL} + +clean: + $(RM) *.o *.so *.so.0 diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/create_tpm2_key.c b/security/tpm2-openssl-engine/tpm2-openssl-engine/create_tpm2_key.c new file mode 100644 index 000000000..06c854b7d --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/create_tpm2_key.c @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2017 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ +/* ==================================================================== + * + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * This product is inspired by the original TPM 1.2 openssl engine written + * by Kent Yoder for the Trousers Project. This product + * includes TPM key blob ASN-1 encoding scheme from James Bottomley + * + * + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tpm2-asn.h" + +static struct option long_options[] = { + {"auth", 0, 0, 'a'}, + {"help", 0, 0, 'h'}, + {"name-scheme", 1, 0, 'n'}, + {"parent-handle", 1, 0, 'p'}, + {"wrap", 1, 0, 'w'}, + {0, 0, 0, 0} +}; + +static TPM_ALG_ID name_alg = TPM_ALG_SHA256; +static int name_alg_size = SHA256_DIGEST_SIZE; + +void +usage(char *argv0) +{ + fprintf(stderr, "\t%s: create a TPM key and write it to disk\n" + "\tusage: %s [options] \n\n" + "\tOptions:\n" + "\t\t-a|--auth require a password for the key [NO]\n" + "\t\t-h|--help print this help message\n" + "\t\t-n|--name-scheme name algorithm to use sha1 [sha256] sha384 sha512\n" + "\t\t-p|--parent-handle persistent handle of parent key\n" + "\t\t-w|--wrap [file] wrap an existing openssl PEM key\n", + argv0, argv0); + exit(-1); +} + +void tpm2_error(TPM_RC rc, const char *reason) +{ + const char *msg, *submsg, *num; + + fprintf(stderr, "%s failed with %d\n", reason, rc); + TSS_ResponseCode_toString(&msg, &submsg, &num, rc); + fprintf(stderr, "%s%s%s\n", msg, submsg, num); +} + +void +openssl_print_errors() +{ + ERR_load_ERR_strings(); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); +} + +int +openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len, + BYTE *privkey, int privkey_len, int empty_auth, + TPM_HANDLE parent) +{ + TSSLOADABLE tssl; + BIO *outb; + + /* clear structure so as not to have to set optional parameters */ + memset(&tssl, 0, sizeof(tssl)); + if ((outb = BIO_new_file(file, "w")) == NULL) { + fprintf(stderr, "Error opening file for write: %s\n", file); + return 1; + } + tssl.type = OBJ_txt2obj(OID_loadableKey, 1); + tssl.emptyAuth = empty_auth; + if ((parent & 0xff000000) == 0x81000000) { + tssl.parent = ASN1_INTEGER_new(); + ASN1_INTEGER_set(tssl.parent, parent); + } + tssl.pubkey = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(tssl.pubkey, pubkey, pubkey_len); + tssl.privkey = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(tssl.privkey, privkey, privkey_len); + + PEM_write_bio_TSSLOADABLE(outb, &tssl); + BIO_free(outb); + return 0; +} + +EVP_PKEY * +openssl_read_key(char *filename) +{ + BIO *b = NULL; + EVP_PKEY *pkey; + + b = BIO_new_file(filename, "r"); + if (b == NULL) { + fprintf(stderr, "Error opening file for read: %s\n", filename); + return NULL; + } + + if ((pkey = PEM_read_bio_PrivateKey(b, NULL, PEM_def_callback, NULL)) == NULL) { + fprintf(stderr, "Reading key %s from disk failed.\n", filename); + openssl_print_errors(); + } + BIO_free(b); + + return pkey; +} + +void tpm2_public_template_rsa(TPMT_PUBLIC *pub) +{ + pub->type = TPM_ALG_RSA; + pub->nameAlg = name_alg; + /* note: all our keys are decrypt only. This is because + * we use the TPM2_RSA_Decrypt operation for both signing + * and decryption (see e_tpm2.c for details) */ + pub->objectAttributes.val = TPMA_OBJECT_NODA | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_SIGN | + TPMA_OBJECT_USERWITHAUTH; + pub->authPolicy.t.size = 0; + pub->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL; + pub->parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; +} + +TPM_RC openssl_to_tpm_public_rsa(TPMT_PUBLIC *pub, EVP_PKEY *pkey) +{ + RSA *rsa = EVP_PKEY_get1_RSA(pkey); + BIGNUM *n, *e; + int size = RSA_size(rsa); + unsigned long exp; + + if (size > MAX_RSA_KEY_BYTES) + return TPM_RC_KEY_SIZE; + +#if OPENSSL_VERSION_NUMBER < 0x10100000 + n = rsa->n; + e = rsa->e; +#else + RSA_get0_key(&n, &e, NULL); +#endif + exp = BN_get_word(e); + /* TPM limitations means exponents must be under a word in size */ + if (exp == 0xffffffffL) + return TPM_RC_KEY_SIZE; + tpm2_public_template_rsa(pub); + pub->parameters.rsaDetail.keyBits = size*8; + if (exp == 0x10001) + pub->parameters.rsaDetail.exponent = 0; + else + pub->parameters.rsaDetail.exponent = exp; + + pub->unique.rsa.t.size = BN_bn2bin(n, pub->unique.rsa.t.buffer); + + return 0; +} + +TPM_RC openssl_to_tpm_public(TPM2B_PUBLIC *pub, EVP_PKEY *pkey) +{ + TPMT_PUBLIC *tpub = &pub->publicArea; + pub->size = sizeof(*pub); + + switch (EVP_PKEY_type(pkey->type)) { + case EVP_PKEY_RSA: + return openssl_to_tpm_public_rsa(tpub, pkey); + default: + break; + } + return TPM_RC_ASYMMETRIC; +} + +TPM_RC openssl_to_tpm_private_rsa(TPMT_SENSITIVE *s, EVP_PKEY *pkey) +{ + BIGNUM *q; + TPM2B_PRIVATE_KEY_RSA *t2brsa = &s->sensitive.rsa; + RSA *rsa = EVP_PKEY_get1_RSA(pkey); + +#if OPENSSL_VERSION_NUMBER < 0x10100000 + q = rsa->q; +#else + BIGNUM *p; + + RSA_get0_factors(rsa, &p, &q); +#endif + + if (!q) + return TPM_RC_ASYMMETRIC; + + s->sensitiveType = TPM_ALG_RSA; + s->seedValue.b.size = 0; + + t2brsa->t.size = BN_bn2bin(q, t2brsa->t.buffer); + return 0; +} + +TPM_RC openssl_to_tpm_private(TPMT_SENSITIVE *priv, EVP_PKEY *pkey) +{ + switch (EVP_PKEY_type(pkey->type)) { + case EVP_PKEY_RSA: + return openssl_to_tpm_private_rsa(priv, pkey); + default: + break; + } + return TPM_RC_ASYMMETRIC; +} + +TPM_RC wrap_key(TPM2B_PRIVATE *priv, const char *password, EVP_PKEY *pkey) +{ + TPMT_SENSITIVE s; + TPM2B_SENSITIVE b; + BYTE *buf; + int32_t size; + TPM_RC rc; + + memset(&b, 0, sizeof(b)); + memset(&s, 0, sizeof(s)); + + openssl_to_tpm_private(&s, pkey); + + if (password) { + int len = strlen(password); + + memcpy(s.authValue.b.buffer, password, len); + s.authValue.b.size = len; + } else { + s.authValue.b.size = 0; + } + size = sizeof(s); + buf = b.b.buffer; + rc = TSS_TPMT_SENSITIVE_Marshal(&s, &b.b.size, &buf, &size); + if (rc) + tpm2_error(rc, "TSS_TPMT_SENSITIVE_Marshal"); + + size = sizeof(*priv); + buf = priv->b.buffer; + priv->b.size = 0; + /* no encryption means innerIntegrity and outerIntegrity are + * absent, so the TPM2B_PRIVATE is a TPMT_SENSITIVE*/ + rc = TSS_TPM2B_PRIVATE_Marshal((TPM2B_PRIVATE *)&b, &priv->b.size, &buf, &size); + if (rc) + tpm2_error(rc, "TSS_TPM2B_PRIVATE_Marshal"); + + return TPM_RC_ASYMMETRIC; +} + +int main(int argc, char **argv) +{ + char *filename, c, *wrap = NULL, *auth = NULL; + int option_index; + const char *reason; + TSS_CONTEXT *tssContext = NULL; + TPM_HANDLE parent = 0; + TPM_RC rc = 0; + BYTE pubkey[sizeof(TPM2B_PUBLIC)],privkey[sizeof(TPM2B_PRIVATE)], *buffer; + uint16_t pubkey_len, privkey_len; + int32_t size = 0; + TPM2B_PUBLIC *pub; + TPM2B_PRIVATE *priv; + + + while (1) { + option_index = 0; + c = getopt_long(argc, argv, "n:ap:hw:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'a': + auth = malloc(128); + break; + case 'h': + usage(argv[0]); + break; + case 'n': + if (!strcasecmp("sha1", optarg)) { + name_alg = TPM_ALG_SHA1; + name_alg_size = SHA1_DIGEST_SIZE; + } else if (strcasecmp("sha256", optarg)) { + /* default, do nothing */ + } else if (strcasecmp("sha384", optarg)) { + name_alg = TPM_ALG_SHA384; + name_alg_size = SHA384_DIGEST_SIZE; +#ifdef TPM_ALG_SHA512 + } else if (strcasecmp("sha512", optarg)) { + name_alg = TPM_ALG_SHA512; + name_alg_size = SHA512_DIGEST_SIZE; +#endif + } else { + usage(argv[0]); + } + break; + case 'p': + parent = strtol(optarg, NULL, 16); + break; + case 'w': + wrap = optarg; + break; + default: + usage(argv[0]); + break; + } + } + + filename = argv[argc - 1]; + + if (argc < 2) + usage(argv[0]); + + if (!wrap) { + fprintf(stderr, "wrap is a compulsory option\n"); + usage(argv[0]); + } + + if (!parent) { + fprintf(stderr, "parent handle is a compulsory option\n"); + usage(argv[0]); + } + + if (parent && (parent & 0xff000000) != 0x81000000) { + fprintf(stderr, "you must specify a persistent parent handle\n"); + usage(argv[0]); + } + + if (auth) { + if (EVP_read_pw_string(auth, 128, "Enter TPM key authority: ", 1)) { + fprintf(stderr, "Passwords do not match\n"); + exit(1); + } + } + + rc = TSS_Create(&tssContext); + if (rc) { + reason = "TSS_Create"; + goto out_err; + } + + /* + * avoid using the device TCTI as that will bind + * exclusively to the TPM device. Instead + * use the Kernel TPM Resource Manager as that + * allows concurrent access + * + * N.B: This assumes that the kernel-modules-tpm + * pkg is installed with the modified tpm_crb KLM + */ + rc = TSS_SetProperty(tssContext, TPM_DEVICE, "/dev/tpmrm0"); + if (rc) { + reason = "TSS_SetProperty: TPM_USE_RESOURCE_MANAGER"; + goto out_err; + } + + if (wrap) { + Import_In iin; + Import_Out iout; + EVP_PKEY *pkey; + + /* may be needed to decrypt the key */ + OpenSSL_add_all_ciphers(); + pkey = openssl_read_key(wrap); + if (!pkey) { + reason = "unable to read key"; + goto out_delete; + } + + iin.parentHandle = parent; + iin.encryptionKey.t.size = 0; + openssl_to_tpm_public(&iin.objectPublic, pkey); + /* set random iin.symSeed */ + iin.inSymSeed.t.size = 0; + iin.symmetricAlg.algorithm = TPM_ALG_NULL; + wrap_key(&iin.duplicate, auth, pkey); + openssl_to_tpm_public(&iin.objectPublic, pkey); + rc = TSS_Execute(tssContext, + (RESPONSE_PARAMETERS *)&iout, + (COMMAND_PARAMETERS *)&iin, + NULL, + TPM_CC_Import, + TPM_RS_PW, NULL, 0, + TPM_RH_NULL, NULL, 0, + TPM_RH_NULL, NULL, 0, + TPM_RH_NULL, NULL, 0); + if (rc) { + reason = "TPM2_Import"; + goto out_flush; + } + pub = &iin.objectPublic; + priv = &iout.outPrivate; + } + + buffer = pubkey; + pubkey_len = 0; + size = sizeof(pubkey); + TSS_TPM2B_PUBLIC_Marshal(pub, &pubkey_len, &buffer, &size); + buffer = privkey; + privkey_len = 0; + size = sizeof(privkey); + TSS_TPM2B_PRIVATE_Marshal(priv, &privkey_len, &buffer, &size); + openssl_write_tpmfile(filename, pubkey, pubkey_len, privkey, privkey_len, auth == NULL, parent); + TSS_Delete(tssContext); + exit(0); + + out_flush: + out_delete: + TSS_Delete(tssContext); + out_err: + tpm2_error(rc, reason); + + exit(1); +} diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.c b/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.c new file mode 100644 index 000000000..5b5ca2e44 --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.c @@ -0,0 +1,852 @@ +/* + * Copyright (c) 2017 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * This product is inspired by the original TPM 1.2 openssl engine written + * by Kent Yoder for the Trousers Project. This product + * includes TPM key blob ASN-1 encoding scheme from James Bottomley + * + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "e_tpm2.h" + +#include "tpm2-asn.h" + +//IMPLEMENT_ASN1_FUNCTIONS(TSSLOADABLE) + +/* IBM TSS2 library functions */ +static const char *TPM_F_File_ReadStructure = "TSS_File_ReadStructure"; +static const char *TPM_F_Context_Create = "TSS_Create"; +static const char *TPM_F_Context_Close = "TSS_Delete"; +static const char *TPM_F_TPM_Execute = "TSS_Execute"; +static const char *TPM_F_Hash_Generate = "TSS_Hash_Generate"; +static const char *TPM_F_Structure_Marshal = "TSS_Structure_Marshal"; +static const char *TPM_F_PrivateKey_Unmarshal = "TPM2B_PRIVATE_Unmarshal"; +static const char *TPM_F_PublicKey_Unmarshal = "TPM2B_PUBLIC_Unmarshal"; +static const char *TPM_F_Set_Property = "TSS_SetProperty"; + +/* engine specific functions */ +static int tpm_engine_destroy(ENGINE *); +static int tpm_engine_init(ENGINE *); +static int tpm_engine_finish(ENGINE *); +static int tpm_engine_ctrl(ENGINE *, int, long, void *, void (*)()); +static EVP_PKEY *tpm_engine_load_key(ENGINE *, const char *, UI_METHOD *, void *); +static int tpm_engine_flush_key_context(TPMI_DH_OBJECT hKey); + +#ifndef OPENSSL_NO_RSA +/* rsa functions */ +static int tpm_rsa_init(RSA *rsa); +static int tpm_rsa_finish(RSA *rsa); +static int tpm_rsa_priv_dec(int, const unsigned char *, unsigned char *, RSA *, int); +static int tpm_rsa_priv_enc(int, const unsigned char *, unsigned char *, RSA *, int); +#endif + + +/* The definitions for control commands specific to this engine */ +#define TPM_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN tpm_cmd_defns[] = { + {TPM_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the libtpm2.so shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +// for now we will only overwrite the RSA decryption +// operation to go over TPM 2.0. +// Add additional hooks as new use cases pop up +#ifndef OPENSSL_NO_RSA +static RSA_METHOD tpm_rsa = { + "TPM 2.0 RSA method", // name + NULL, // rsa_pub_enc (encrypt) + NULL, // rsa_pub_dec (verify arbitrary data) + tpm_rsa_priv_enc, // rsa_priv_enc (sign) + tpm_rsa_priv_dec, // rsa_priv_dec (decrypt) + NULL, // rsa_mod_exp + BN_mod_exp_mont, // bn_mod_exp + tpm_rsa_init, // init + tpm_rsa_finish, // free + (RSA_FLAG_SIGN_VER | RSA_FLAG_NO_BLINDING | RSA_FLAG_EXT_PKEY), + NULL, // app_data + NULL, /* sign */ // rsa_sign + NULL, /* verify */ // rsa_verify + NULL // rsa_keygen +}; +#endif + +/* Constants used when creating the ENGINE */ +static const char *engine_tpm_id = "tpm2"; +static const char *engine_tpm_name = "TPM 2.0 hardware engine support for"; +static const char *TPM_LIBNAME = "tpm2"; + +static TSS_CONTEXT *hContext = NULL_HCONTEXT; +static TPMI_DH_OBJECT hKey = NULL_HKEY; +/* varibles used to get/set CRYPTO_EX_DATA values */ +int ex_app_data = TPM_ENGINE_EX_DATA_UNINIT; + +/* This is a process-global DSO handle used for loading and unloading + * the TSS library. NB: This is only set (or unset) during an + * init() or finish() call (reference counts permitting) and they're + * operating with global locks, so this should be thread-safe + * implicitly. */ + +static DSO *tpm_dso = NULL; + +/* These are the function pointers that are (un)set when the library has + * successfully (un)loaded. */ +static unsigned int (*p_tpm2_File_ReadStructure)(); +static unsigned int (*p_tpm2_Context_Create)(); +static unsigned int (*p_tpm2_Context_Close)(); +static unsigned int (*p_tpm2_TPM_Execute)(); +static unsigned int (*p_tpm2_Hash_Generate)(); +static unsigned int (*p_tpm2_Structure_Marshal)(); +static unsigned int (*p_tpm2_TPM_PrivateKey_Unmarshal)(); +static unsigned int (*p_tpm2_TPM_PublicKey_Unmarshal)(); +static unsigned int (*p_tpm2_Set_Property)(); + + +/* This internal function is used by ENGINE_tpm() and possibly by the + * "dynamic" ENGINE support too */ +static int bind_helper(ENGINE * e) +{ +#ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +#endif + if (!ENGINE_set_id(e, engine_tpm_id) || + !ENGINE_set_name(e, engine_tpm_name) || +#ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &tpm_rsa) || +#endif + !ENGINE_set_destroy_function(e, tpm_engine_destroy) || + !ENGINE_set_init_function(e, tpm_engine_init) || + !ENGINE_set_finish_function(e, tpm_engine_finish) || + !ENGINE_set_ctrl_function(e, tpm_engine_ctrl) || + !ENGINE_set_load_privkey_function(e, tpm_engine_load_key) || + !ENGINE_set_cmd_defns(e, tpm_cmd_defns)) + return 0; + +#ifndef OPENSSL_NO_RSA + /* We know that the "PKCS1_SSLeay()" functions hook properly + * to the tpm-specific mod_exp and mod_exp_crt so we use + * those functions. NB: We don't use ENGINE_openssl() or + * anything "more generic" because something like the RSAref + * code may not hook properly, and if you own one of these + * cards then you have the right to do RSA operations on it + * anyway! */ + meth1 = RSA_PKCS1_SSLeay(); + if (meth1) + { + tpm_rsa.rsa_mod_exp = meth1->rsa_mod_exp; + tpm_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + tpm_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + } +#endif + + /* Ensure the tpm error handling is set up */ + ERR_load_TPM_strings(); + return 1; +} + +static ENGINE *engine_tpm(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_tpm(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_tpm(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} + +/* Destructor (complements the "ENGINE_tpm()" constructor) */ +static int tpm_engine_destroy(ENGINE * e) +{ + /* Unload the tpm error strings so any error state including our + * functs or reasons won't lead to a segfault (they simply get displayed + * without corresponding string data because none will be found). */ + ERR_unload_TPM_strings(); + return 1; +} + +/* initialisation function */ +static int tpm_engine_init(ENGINE * e) +{ + void (*p1) (); + void (*p2) (); + void (*p3) (); + void (*p4) (); + void (*p5) (); + void (*p6) (); + void (*p7) (); + void (*p8) (); + void (*p9) (); + TPM_RC result; + + if (tpm_dso != NULL) { + TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_ALREADY_LOADED); + return 1; + } + + if ((tpm_dso = DSO_load(NULL, TPM_LIBNAME, NULL, 0)) == NULL) { + TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_DSO_FAILURE); + goto err; + } + + if (!(p1 = DSO_bind_func(tpm_dso, TPM_F_File_ReadStructure)) || + !(p2 = DSO_bind_func(tpm_dso, TPM_F_Context_Create)) || + !(p3 = DSO_bind_func(tpm_dso, TPM_F_Context_Close)) || + !(p4 = DSO_bind_func(tpm_dso, TPM_F_TPM_Execute)) || + !(p5 = DSO_bind_func(tpm_dso, TPM_F_Hash_Generate)) || + !(p6 = DSO_bind_func(tpm_dso, TPM_F_Structure_Marshal)) || + !(p7 = DSO_bind_func(tpm_dso, TPM_F_PrivateKey_Unmarshal)) || + !(p8 = DSO_bind_func(tpm_dso, TPM_F_PublicKey_Unmarshal)) || + !(p9 = DSO_bind_func(tpm_dso, TPM_F_Set_Property)) + ) { + TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_DSO_FAILURE); + goto err; + } + + /* Copy the pointers */ + p_tpm2_File_ReadStructure = (unsigned int (*) ()) p1; + p_tpm2_Context_Create = (unsigned int (*) ()) p2; + p_tpm2_Context_Close = (unsigned int (*) ()) p3; + p_tpm2_TPM_Execute = (unsigned int (*) ()) p4; + p_tpm2_Hash_Generate = (unsigned int (*) ()) p5; + p_tpm2_Structure_Marshal = (unsigned int (*) ()) p6; + p_tpm2_TPM_PrivateKey_Unmarshal = (unsigned int (*) ()) p7; + p_tpm2_TPM_PublicKey_Unmarshal = (unsigned int (*) ()) p8; + p_tpm2_Set_Property = (unsigned int (*) ()) p9; + + if ((result = p_tpm2_Context_Create(&hContext))) { + TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_UNIT_FAILURE); + goto err; + } + + /* + * avoid using the tpm0 device TCTI as that will bind + * exclusively to the TPM device. Instead + * use the Kernel TPM Resource Manager as that + * allows concurrent access + * + * N.B: This assumes that the kernel-modules-tpm + * pkg is installed with the modified tpm_crb KLM + */ + if ((result = p_tpm2_Set_Property(hContext, + TPM_DEVICE, "/dev/tpmrm0"))) { + DBG("Failed to set Resource Manager in context (%p): rc %d", + hContext, (int)result); + TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_UNIT_FAILURE); + goto err; + } + + return 1; +err: + if (hContext != NULL_HCONTEXT) { + p_tpm2_Context_Close(hContext); + hContext = NULL_HCONTEXT; + } + + if (tpm_dso) { + DSO_free(tpm_dso); + tpm_dso = NULL; + } + + p_tpm2_File_ReadStructure = NULL; + p_tpm2_Context_Create = NULL; + p_tpm2_Context_Close = NULL; + p_tpm2_TPM_Execute = NULL; + p_tpm2_Hash_Generate = NULL; + p_tpm2_Structure_Marshal = NULL; + p_tpm2_TPM_PrivateKey_Unmarshal = NULL; + p_tpm2_TPM_PublicKey_Unmarshal = NULL; + p_tpm2_Set_Property = NULL; + + return 0; +} + +static int tpm_engine_finish(ENGINE * e) +{ + if (tpm_dso == NULL) { + TSSerr(TPM_F_TPM_ENGINE_FINISH, TPM_R_NOT_LOADED); + return 0; + } + + if (hKey != NULL_HKEY) { + tpm_engine_flush_key_context(hKey); + hKey = NULL_HKEY; + } + + if (hContext != NULL_HCONTEXT) { + p_tpm2_Context_Close(hContext); + hContext = NULL_HCONTEXT; + } + + if (!DSO_free(tpm_dso)) { + TSSerr(TPM_F_TPM_ENGINE_FINISH, TPM_R_DSO_FAILURE); + return 0; + } + tpm_dso = NULL; + + return 1; +} + +int fill_out_rsa_object(RSA *rsa, TPMT_PUBLIC *pub, TPMI_DH_OBJECT hKey) +{ + struct rsa_app_data *app_data; + unsigned long exp; + + if ((app_data = OPENSSL_malloc(sizeof(struct rsa_app_data))) == NULL) { + TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* set e in the RSA object */ + if (!rsa->e && ((rsa->e = BN_new()) == NULL)) { + TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (pub->parameters.rsaDetail.exponent == 0) + exp = 65537; + else + exp = pub->parameters.rsaDetail.exponent; + + if (!BN_set_word(rsa->e, exp)) { + TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, TPM_R_REQUEST_FAILED); + BN_free(rsa->e); + return 0; + } + + /* set n in the RSA object */ + if (!rsa->n && ((rsa->n = BN_new()) == NULL)) { + TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE); + BN_free(rsa->e); + return 0; + } + + if (!BN_bin2bn(pub->unique.rsa.t.buffer, pub->unique.rsa.t.size, + rsa->n)) { + TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE); + BN_free(rsa->e); + BN_free(rsa->n); + return 0; + } + +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + RSA_set0_key(rsa, rsa->n, rsa->e, NULL); +#endif + + DBG("Setting hKey(0x%x) in RSA object", hKey); + + memset(app_data, 0, sizeof(struct rsa_app_data)); + app_data->hKey = hKey; + RSA_set_ex_data(rsa, ex_app_data, app_data); + + return 1; +} + +static int tpm_engine_flush_key_context(TPMI_DH_OBJECT hKey) +{ + TPM_RC rc; + FlushContext_In input; + + if (hKey == NULL_HKEY) { + TSSerr(TPM_F_TPM_FLUSH_OBJECT_CONTEXT, TPM_R_INVALID_KEY); + return -1; + } + input.flushHandle = hKey; + + if ((rc = p_tpm2_TPM_Execute(hContext, + NULL, + (COMMAND_PARAMETERS *)&input, + NULL, + TPM_CC_FlushContext, + TPM_RH_NULL, NULL, 0))) { + DBG("Context Flush Failed: Ret code %d", rc); + TSSerr(TPM_F_TPM_FLUSH_OBJECT_CONTEXT, + TPM_R_REQUEST_FAILED); + return -1; + } + + return 0; +} + +static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, + UI_METHOD *ui, void *cb_data) +{ + RSA *rsa; + EVP_PKEY *pkey; + BIO *bf; + char oid[128]; + TPM_RC rc; + TSSLOADABLE *tssl; // the TPM key + Load_In input; + Load_Out output; + + const char *parentPassword = NULL; + TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW; + unsigned int sessionAttributes0 = 0; + TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL; + unsigned int sessionAttributes1 = 0; + TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL; + unsigned int sessionAttributes2 = 0; + + + if (!key_id) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + // check if the file exists + if ((bf = BIO_new_file(key_id, "r")) == NULL) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + TPM_R_FILE_NOT_FOUND); + return NULL; + } + + tssl = PEM_read_bio_TSSLOADABLE(bf, NULL, NULL, NULL); + BIO_free(bf); + + + if (!tssl) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + TPM_R_FILE_READ_FAILED); + goto load_err; + } + + if (OBJ_obj2txt(oid, sizeof(oid), tssl->type, 1) == 0) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_FILE_READ_FAILED); + goto load_err; + } + + if (strcmp(OID_loadableKey, oid) == 0) { + DBG ("TSSL key type is of format that can be loaded in TPM 2.0"); + } else if (strcmp(OID_12Key, oid) == 0) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + TPM_R_TPM_1_2_KEY); + goto load_err; + } else if (strcmp(OID_importableKey, oid) == 0) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + TPM_R_KEY_UNSUPPORTED); + goto load_err; + } else { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_KEY_UNRECOGNIZED); + goto err; + } + + // since this TPM key was wrapped in the Endorsement + // Key hierarchy and its handle was persisted, we will + // specify that as the Parent Handle for the Load operation + if (!tssl->parent) { + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_KEY_NO_PARENT_HANDLE); + goto load_err; + } + + input.parentHandle = ASN1_INTEGER_get(tssl->parent); + DBG ("Got parent handle 0x%x", input.parentHandle); + // unmarshal the public and private key portions from + // within the TPM ASN1 key blob + p_tpm2_TPM_PrivateKey_Unmarshal(&input.inPrivate, + &(tssl->privkey->data), + &(tssl->privkey->length)); + p_tpm2_TPM_PublicKey_Unmarshal(&input.inPublic, + &(tssl->pubkey->data), + &(tssl->pubkey->length), + FALSE); + if ((rc = p_tpm2_TPM_Execute(hContext, + (RESPONSE_PARAMETERS *)&output, + (COMMAND_PARAMETERS *)&input, + NULL, + TPM_CC_Load, + sessionHandle0, + parentPassword, + sessionAttributes0, + sessionHandle1, + NULL, + sessionAttributes1, + sessionHandle2, + NULL, + sessionAttributes2, + TPM_RH_NULL, NULL, 0))) { + DBG("Context Load Failed: Ret code %08x", rc); + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, + TPM_R_REQUEST_FAILED); + goto load_err; + } + hKey = output.objectHandle; + + /* create the new objects to return */ + if ((pkey = EVP_PKEY_new()) == NULL) { + goto err; + } + pkey->type = EVP_PKEY_RSA; + + if ((rsa = RSA_new()) == NULL) { + EVP_PKEY_free(pkey); + goto err; + } + rsa->meth = &tpm_rsa; + /* call our local init function here */ + rsa->meth->init(rsa); + pkey->pkey.rsa = rsa; + + if (!fill_out_rsa_object(rsa, + &input.inPublic.publicArea, + hKey)) { + EVP_PKEY_free(pkey); + RSA_free(rsa); + goto err; + } + + EVP_PKEY_assign_RSA(pkey, rsa); + return pkey; + +err: + tpm_engine_flush_key_context(hKey); + hKey = NULL_HKEY; + TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); + +load_err: + //TSSLOADABLE_free(tssl); + return NULL; +} + +static int tpm_engine_ctrl(ENGINE * e, int cmd, long i, void *p, void (*f) ()) +{ + int initialised = ((tpm_dso == NULL) ? 0 : 1); + switch (cmd) { + case TPM_CMD_SO_PATH: + if (p == NULL) { + TSSerr(TPM_F_TPM_ENGINE_CTRL, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + TSSerr(TPM_F_TPM_ENGINE_CTRL, + TPM_R_ALREADY_LOADED); + return 0; + } + TPM_LIBNAME = (const char *) p; + return 1; + default: + break; + } + TSSerr(TPM_F_TPM_ENGINE_CTRL, TPM_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int tpm_rsa_init(RSA *rsa) +{ + if (ex_app_data == TPM_ENGINE_EX_DATA_UNINIT) + ex_app_data = RSA_get_ex_new_index(0, NULL, NULL, NULL, NULL); + + if (ex_app_data == TPM_ENGINE_EX_DATA_UNINIT) { + TSSerr(TPM_F_TPM_RSA_INIT, TPM_R_REQUEST_FAILED); + return 0; + } + + return 1; +} + +static int tpm_rsa_finish(RSA *rsa) +{ + struct rsa_app_data *app_data = RSA_get_ex_data(rsa, ex_app_data); + + OPENSSL_free(app_data); + + return 1; +} + +static int tpm_rsa_priv_dec(int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) +{ + struct rsa_app_data *app_data = RSA_get_ex_data(rsa, ex_app_data); + TPM_RC result; + UINT32 out_len; + int rv; + RSA_Decrypt_In input; + RSA_Decrypt_Out output; + // the parent object is not passwod protected + // but it may be in the future. + const char *parentPassword = NULL; + TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW; + unsigned int sessionAttributes0 = 0; + TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL; + unsigned int sessionAttributes1 = 0; + TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL; + unsigned int sessionAttributes2 = 0; + + + if (!app_data) { + TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_NO_APP_DATA); + if ((rv = RSA_PKCS1_SSLeay()->rsa_priv_dec(flen, from, to, rsa, + padding)) < 0) { + TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_REQUEST_FAILED); + } + + return rv; + } + + // hKey is the handle of the private key that is used for decrypt + if (app_data->hKey == NULL_HKEY) { + TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_INVALID_KEY); + return 0; + } + /* handler of the private key that will perform rsa decrypt */ + input.keyHandle = app_data->hKey; + + // fill in the TPM2RB_PUBLIC_KEY_RSA structure with the + // cipher text and cipher lenght + { + input.label.t.size = 0; + input.cipherText.t.size = flen; + memcpy(input.cipherText.t.buffer, from, flen); + } + + /* + * Table 157 - Definition of {RSA} TPMT_RSA_DECRYPT Structure: + * we MAY set the input scheme to TPM_ALG_NULL to allow + * for the encryption algorithm prescribed in the digital + * certificate to be used for encryption + */ + input.inScheme.scheme = TPM_ALG_RSAES; /* TPM_ALG_NULL; */ + + // decrypt this cipher text using the private key stored inside + // tpm and referenced by hKey + if ((result = p_tpm2_TPM_Execute(hContext, + (RESPONSE_PARAMETERS *)&output, + (COMMAND_PARAMETERS *)&input, + NULL, + TPM_CC_RSA_Decrypt, + sessionHandle0, + parentPassword, + sessionAttributes0, + sessionHandle1, + NULL, + sessionAttributes1, + sessionHandle2, + NULL, + sessionAttributes2, + TPM_RH_NULL, NULL, 0))) { + DBG("RSA Decrypt Failed: Ret code %d", result); + TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_REQUEST_FAILED); + return 0; + } + DBG ("Doing RSA Decryption"); + + // Unmarshal the output data and return decrypted cipher text + // and output length + rv = p_tpm2_Structure_Marshal(&to, &out_len, + &output.message, + (MarshalFunction_t) + TSS_TPM2B_PUBLIC_KEY_RSA_Marshal); + if (rv == 0) { + DBG("writing out %d bytes as a signature", out_len); + return out_len; + } + return 0; +} + +static int tpm_rsa_priv_enc(int flen, + const unsigned char *from, + unsigned char *to, + RSA *rsa, + int padding) +{ + struct rsa_app_data *app_data = RSA_get_ex_data(rsa, ex_app_data); + TPM_RC result = 0; + UINT32 sig_len; + int rv; + RSA_Decrypt_In input; + RSA_Decrypt_Out output; + // the parent object is not passwod protected + // but it may be in the future. + const char *parentPassword = NULL; + TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW; + unsigned int sessionAttributes0 = 0; + TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL; + unsigned int sessionAttributes1 = 0; + TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL; + unsigned int sessionAttributes2 = 0; + + if (!app_data) { + TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_NO_APP_DATA); + if ((rv = RSA_PKCS1_SSLeay()->rsa_priv_enc(flen, from, to, rsa, + padding)) < 0) { + TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_REQUEST_FAILED); + } + return rv; + } + + if (padding != RSA_PKCS1_PADDING) { + TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_INVALID_PADDING_TYPE); + return 0; + } + + // hKey is the handle to the private key that is used for hashing + if (app_data->hKey == NULL_HKEY) { + TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_INVALID_KEY); + return 0; + } + /* handler of the private key that will perform signing */ + input.keyHandle = app_data->hKey; + + /* + * Table 145 - Definition of TPMT_SIG_SCHEME inscheme: + * we will set the input scheme to TPM_ALG_NULL to allow + * for the hash algorithm prescribed in the digital certificate + * to be used for signing. + * + * Note that we are using a Decryption operation instead of ] + * a TPM 2.0 Sign operation because of a serious limitation in the + * IBM TSS that it will only sign digests which it has hashed itself, + * i.e. the hash has a corresponding TPM_ST_HASHCHECK validation + * ticket in TPM memory. Long story short, TPM will only sign + * stuff it knows the OID to. + * + * We will therefore specify a Decyrption operation with our + * own padding applied upto the RSA block size and specify + * a TPM_ALG_NULL hashing scheme so that a decrypt operation + * essentially becomes an encrypt op + */ + input.inScheme.scheme = TPM_ALG_NULL; + + /* digest to be signed */ + int size = RSA_size(rsa); + input.cipherText.t.size = size; + RSA_padding_add_PKCS1_type_1(input.cipherText.t.buffer, + size, from, flen); + input.label.t.size = 0; + + // sign this digest using the private key stored inside + // tpm and referenced by hKey + if ((result = p_tpm2_TPM_Execute(hContext, + (RESPONSE_PARAMETERS *)&output, + (COMMAND_PARAMETERS *)&input, + NULL, + TPM_CC_RSA_Decrypt, + sessionHandle0, + parentPassword, + sessionAttributes0, + sessionHandle1, + NULL, + sessionAttributes1, + sessionHandle2, + NULL, + sessionAttributes2, + TPM_RH_NULL, NULL, 0))) { + DBG("RSA Sign Failed: Ret code %d", result); + TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_REQUEST_FAILED); + return 0; + } + + // thats right son!!! finally signed + sig_len = output.message.t.size; + memcpy(to, output.message.t.buffer, sig_len); + + DBG("writing out %d bytes as a signature", sig_len); + return sig_len; +} + +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. */ +static int bind_fn(ENGINE * e, const char *id) +{ + if (id && (strcmp(id, engine_tpm_id) != 0)) { + TSSerr(TPM_F_TPM_BIND_FN, TPM_R_ID_INVALID); + return 0; + } + if (!bind_helper(e)) { + TSSerr(TPM_F_TPM_BIND_FN, TPM_R_REQUEST_FAILED); + return 0; + } + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.h b/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.h new file mode 100644 index 000000000..9b8f7a500 --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2017 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * This product is inspired by the original TPM 1.2 openssl engine written + * by Kent Yoder for the Trousers Project. This product + * includes TPM key blob ASN-1 encoding scheme from James Bottomley + * + * + */ + +#ifndef _E_TPM_H +#define _E_TPM_H + +#include +#include +#include +#include +#include +#include + +#define TPM_LIB_NAME "tpm2 engine" + +#define NULL_HCONTEXT NULL +#define NULL_HKEY 0 + +void ERR_load_TPM_strings(void); +void ERR_unload_TPM_strings(void); +void ERR_TSS_error(int function, int reason, char *file, int line); + +#define TSSerr(f,r) ERR_TSS_error((f),(r),__FILE__,__LINE__) +#define DBG(x, ...) fprintf(stderr, "DEBUG %s:%d %s " x "\n", __FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__) + +/* Error codes for the TPM functions. */ + +/* Function codes. */ +#define TPM_F_TPM_ENGINE_CTRL 100 +#define TPM_F_TPM_ENGINE_FINISH 101 +#define TPM_F_TPM_ENGINE_INIT 102 +#define TPM_F_TPM_RSA_PRIV_ENC 103 +#define TPM_F_TPM_RSA_PRIV_DEC 104 +#define TPM_F_TPM_RSA_FINISH 105 +#define TPM_F_TPM_RSA_INIT 106 +#define TPM_F_TPM_ENGINE_LOAD_KEY 107 +#define TPM_F_TPM_BIND_FN 108 +#define TPM_F_TPM_FILL_RSA_OBJECT 109 +#define TPM_F_TPM_FLUSH_OBJECT_CONTEXT 110 + +/* Reason codes. */ +#define TPM_R_ALREADY_LOADED 100 +#define TPM_R_CTRL_COMMAND_NOT_IMPLEMENTED 101 +#define TPM_R_DSO_FAILURE 102 +#define TPM_R_MEXP_LENGTH_TO_LARGE 103 +#define TPM_R_MISSING_KEY_COMPONENTS 104 +#define TPM_R_NOT_INITIALISED 105 +#define TPM_R_NOT_LOADED 106 +#define TPM_R_OPERANDS_TOO_LARGE 107 +#define TPM_R_OUTLEN_TO_LARGE 108 +#define TPM_R_REQUEST_FAILED 109 +#define TPM_R_UNDERFLOW_CONDITION 110 +#define TPM_R_UNDERFLOW_KEYRECORD 111 +#define TPM_R_UNIT_FAILURE 112 +#define TPM_R_INVALID_KEY_SIZE 113 +#define TPM_R_BN_CONVERSION_FAILED 114 +#define TPM_R_INVALID_EXPONENT 115 +#define TPM_R_REQUEST_TOO_BIG 116 +#define TPM_R_NO_APP_DATA 117 +#define TPM_R_INVALID_ENC_SCHEME 118 +#define TPM_R_INVALID_MSG_SIZE 119 +#define TPM_R_INVALID_PADDING_TYPE 120 +#define TPM_R_INVALID_KEY 121 +#define TPM_R_FILE_NOT_FOUND 122 +#define TPM_R_FILE_READ_FAILED 123 +#define TPM_R_ID_INVALID 124 +#define TPM_R_TPM_1_2_KEY 125 +#define TPM_R_KEY_UNSUPPORTED 126 +#define TPM_R_KEY_UNRECOGNIZED 127 +#define TPM_R_KEY_NO_PARENT_HANDLE 128 + +/* structure pointed to by the RSA object's app_data pointer. + * this is used to tag TPM meta data in the RSA object and + * use that to distinguish between a vanilla Openssl RSA object + * and a TPM RSA object + */ +struct rsa_app_data +{ + TPMI_DH_OBJECT hKey; + // add additional meta data as need be +}; + +#define TPM_ENGINE_EX_DATA_UNINIT -1 +#define RSA_PKCS1_OAEP_PADDING_SIZE (2 * SHA_DIGEST_LENGTH + 2) + +#endif diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2_err.c b/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2_err.c new file mode 100644 index 000000000..6a584a965 --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/e_tpm2_err.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2017 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * This product is inspired by the original TPM 1.2 openssl engine written + * by Kent Yoder for the Trousers Project. This product + * includes TPM key blob ASN-1 encoding scheme from James Bottomley + * + * + */ +#include + +#include +#include +#include + +#include "e_tpm2.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA TPM_str_functs[] = { + {ERR_PACK(0, TPM_F_TPM_ENGINE_CTRL, 0), "TPM_ENGINE_CTRL"}, + {ERR_PACK(0, TPM_F_TPM_ENGINE_FINISH, 0), "TPM_ENGINE_FINISH"}, + {ERR_PACK(0, TPM_F_TPM_ENGINE_INIT, 0), "TPM_ENGINE_INIT"}, + {ERR_PACK(0, TPM_F_TPM_RSA_PRIV_ENC, 0), "TPM_RSA_PRIV_ENC"}, + {ERR_PACK(0, TPM_F_TPM_RSA_PRIV_DEC, 0), "TPM_RSA_PRIV_DEC"}, + {ERR_PACK(0, TPM_F_TPM_RSA_FINISH, 0), "TPM_RSA_FINISH"}, + {ERR_PACK(0, TPM_F_TPM_RSA_INIT, 0), "TPM_RSA_INIT"}, + {ERR_PACK(0, TPM_F_TPM_ENGINE_LOAD_KEY, 0), "TPM_ENGINE_LOAD_KEY"}, + {ERR_PACK(0, TPM_F_TPM_BIND_FN, 0), "TPM_BIND_FN"}, + {ERR_PACK(0, TPM_F_TPM_FILL_RSA_OBJECT, 0), "TPM_FILL_RSA_OBJECT"}, + {ERR_PACK(0, TPM_F_TPM_FLUSH_OBJECT_CONTEXT, 0), "TPM_FLUSH_OBJECT_CONTEXT"}, + {0, NULL} +}; + +static ERR_STRING_DATA TPM_str_reasons[] = { + {TPM_R_ALREADY_LOADED, "already loaded"}, + {TPM_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctrl command not implemented"}, + {TPM_R_DSO_FAILURE, "dso failure"}, + {TPM_R_MISSING_KEY_COMPONENTS, "missing key components"}, + {TPM_R_NOT_INITIALISED, "not initialised"}, + {TPM_R_NOT_LOADED, "not loaded"}, + {TPM_R_OPERANDS_TOO_LARGE, "operands too large"}, + {TPM_R_OUTLEN_TO_LARGE, "outlen to large"}, + {TPM_R_REQUEST_FAILED, "request failed"}, + {TPM_R_REQUEST_TOO_BIG, "requested number of random bytes > 4096"}, + {TPM_R_UNDERFLOW_CONDITION, "underflow condition"}, + {TPM_R_UNDERFLOW_KEYRECORD, "underflow keyrecord"}, + {TPM_R_UNIT_FAILURE, "unit failure"}, + {TPM_R_INVALID_KEY_SIZE, "invalid key size"}, + {TPM_R_BN_CONVERSION_FAILED, "bn conversion failed"}, + {TPM_R_INVALID_EXPONENT, "invalid exponent"}, + {TPM_R_NO_APP_DATA, "no app data in RSA object"}, + {TPM_R_INVALID_ENC_SCHEME, "invalid encryption scheme"}, + {TPM_R_INVALID_MSG_SIZE, "invalid message size to sign"}, + {TPM_R_INVALID_PADDING_TYPE, "invalid padding type"}, + {TPM_R_INVALID_KEY, "invalid key"}, + {TPM_R_FILE_NOT_FOUND, "file to load not found"}, + {TPM_R_FILE_READ_FAILED, "failed reading the key file"}, + {TPM_R_ID_INVALID, "engine id doesn't match"}, + {TPM_R_TPM_1_2_KEY, "tpm 1.2 key format not supported"}, + {TPM_R_KEY_UNSUPPORTED, "unsupported TPM key format"}, + {TPM_R_KEY_UNRECOGNIZED, "unrecognized TPM key format"}, + {TPM_R_KEY_NO_PARENT_HANDLE, "TPM key has no parent handle"}, + {0, NULL} +}; + +#endif + +static ERR_STRING_DATA TPM_lib_name[] = { + {0, TPM_LIB_NAME}, + {0, NULL} +}; + + +static int TPM_lib_error_code = 0; +static int TPM_error_init = 1; + +void ERR_load_TPM_strings(void) +{ + if (TPM_lib_error_code == 0) { + TPM_lib_error_code = ERR_get_next_error_library(); + DBG("TPM_lib_error_code is %d", TPM_lib_error_code); + } + + if (TPM_error_init) { + TPM_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(TPM_lib_error_code, TPM_str_functs); + ERR_load_strings(TPM_lib_error_code, TPM_str_reasons); +#endif + TPM_lib_name[0].error = ERR_PACK(TPM_lib_error_code, 0, 0); + ERR_load_strings(0, TPM_lib_name); + } +} + +void ERR_unload_TPM_strings(void) +{ + if (TPM_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(TPM_lib_error_code, TPM_str_functs); + ERR_unload_strings(TPM_lib_error_code, TPM_str_reasons); +#endif + + ERR_load_strings(0, TPM_lib_name); + TPM_error_init = 1; + } +} + +void ERR_TSS_error(int function, int reason, char *file, int line) +{ + if (TPM_lib_error_code == 0) + TPM_lib_error_code = ERR_get_next_error_library(); + + ERR_PUT_error(TPM_lib_error_code, function, reason, file, line); +} + diff --git a/security/tpm2-openssl-engine/tpm2-openssl-engine/tpm2-asn.h b/security/tpm2-openssl-engine/tpm2-openssl-engine/tpm2-asn.h new file mode 100644 index 000000000..20c8c074c --- /dev/null +++ b/security/tpm2-openssl-engine/tpm2-openssl-engine/tpm2-asn.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017 Wind River Systems, Inc. +* +* SPDX-License-Identifier: Apache-2.0 +* + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * This product is inspired by the original TPM 1.2 openssl engine written + * by Kent Yoder for the Trousers Project. This product + * includes TPM key blob ASN-1 encoding scheme from James Bottomley + * + * + */ + +#ifndef _TPM2_ASN_H +#define _TPM2_ASN_H + +#include +#include + +/* + * Define the format of a TPM key file. The current format covers + * both TPM1.2 keys as well as symmetrically encrypted private keys + * produced by TSS2_Import and the TPM2 format public key which + * contains things like the policy but which is cryptographically tied + * to the private key. + * + * TPMKey ::= SEQUENCE { + * type OBJECT IDENTIFIER + * emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL + * parent [1] EXPLICIT INTEGER OPTIONAL + * pubkey [2] EXPLICIT OCTET STRING OPTIONAL + * privkey OCTET STRING + * } + */ + +typedef struct { + ASN1_OBJECT *type; + ASN1_BOOLEAN emptyAuth; + ASN1_INTEGER *parent; + ASN1_OCTET_STRING *pubkey; + ASN1_OCTET_STRING *privkey; +} TSSLOADABLE; + +/* the two type oids are in the TCG namespace 2.23.133; we choose an + * unoccupied child (10) for keytype file and two values: + * 1 : Key that is directly loadable + * 2 : Key that must first be imported then loaded + */ +#define OID_12Key "2.23.133.10.1" +#define OID_loadableKey "2.23.133.10.2" +#define OID_importableKey "2.23.133.10.3" + +ASN1_SEQUENCE(TSSLOADABLE) = { + ASN1_SIMPLE(TSSLOADABLE, type, ASN1_OBJECT), + ASN1_EXP_OPT(TSSLOADABLE, emptyAuth, ASN1_BOOLEAN, 0), + ASN1_EXP_OPT(TSSLOADABLE, parent, ASN1_INTEGER, 1), + ASN1_EXP_OPT(TSSLOADABLE, pubkey, ASN1_OCTET_STRING, 2), + ASN1_SIMPLE(TSSLOADABLE, privkey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(TSSLOADABLE) + +IMPLEMENT_ASN1_FUNCTIONS(TSSLOADABLE) +//DECLARE_ASN1_FUNCTIONS(TSSLOADABLE) + +/* This is the PEM guard tag */ +#define TSSLOADABLE_PEM_STRING "TSS2 KEY BLOB" + +static IMPLEMENT_PEM_write_bio(TSSLOADABLE, TSSLOADABLE, TSSLOADABLE_PEM_STRING, TSSLOADABLE) +static IMPLEMENT_PEM_read_bio(TSSLOADABLE, TSSLOADABLE, TSSLOADABLE_PEM_STRING, TSSLOADABLE) + +#endif diff --git a/security/tpm2-tools/PKG-INFO b/security/tpm2-tools/PKG-INFO new file mode 100644 index 000000000..1b7d2f8a2 --- /dev/null +++ b/security/tpm2-tools/PKG-INFO @@ -0,0 +1,14 @@ +Metadata-Version: 1.1 +Name: tpm2-tools +Version: 1.1.0 +Summary: A TPM2.0 testing tool build upon TPM2.0-TSS +Home-page: +Author: +Author-email: +License: BSD + +Description: +tpm2-tools is a batch of testing tools for tpm2.0. +It is based on tpm2-tss. + +Platform: UNKNOWN diff --git a/security/tpm2-tools/centos/build_srpm.data b/security/tpm2-tools/centos/build_srpm.data new file mode 100644 index 000000000..ece53b3fc --- /dev/null +++ b/security/tpm2-tools/centos/build_srpm.data @@ -0,0 +1,2 @@ +#COPY_LIST="tpm2-tools/*" +TIS_PATCH_VER=2 diff --git a/security/tpm2-tools/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/security/tpm2-tools/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..64aaa13ca --- /dev/null +++ b/security/tpm2-tools/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,35 @@ +From cf30b93accbda4284677507a88ca3727a97fb83c Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:30:57 -0400 +Subject: [PATCH 2/2] WRS: 0001-Update-package-versioning-for-TIS-format.patch + +Conflicts: + SPECS/tpm2-tools.spec +--- + SPECS/tpm2-tools.spec | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/SPECS/tpm2-tools.spec b/SPECS/tpm2-tools.spec +index c858d6f..464c814 100644 +--- a/SPECS/tpm2-tools.spec ++++ b/SPECS/tpm2-tools.spec +@@ -1,6 +1,6 @@ + Name: tpm2-tools + Version: 1.1.0 +-Release: 7%{?dist} ++Release: 7.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: A TPM2.0 testing tool build upon TPM2.0-TSS + + %global pkg_prefix tpm2.0-tools +@@ -44,7 +44,7 @@ BuildRequires: pkgconfig(tcti-socket) + ExclusiveArch: %{ix86} x86_64 + + # tpm2-tools is heavily depending on TPM2.0-TSS project, matched tss is required +-Requires: tpm2-tss%{?_isa} >= 1.0-2%{?dist} ++Requires: tpm2-tss%{?_isa} = 1.0-2.el7 + + %description + tpm2-tools is a batch of testing tools for tpm2.0. It is based on tpm2-tss. +-- +1.9.1 + diff --git a/security/tpm2-tools/centos/meta_patches/PATCH_ORDER b/security/tpm2-tools/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..2bcda5ed9 --- /dev/null +++ b/security/tpm2-tools/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +disable-socket-mode-TCTI.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/security/tpm2-tools/centos/meta_patches/disable-socket-mode-TCTI.patch b/security/tpm2-tools/centos/meta_patches/disable-socket-mode-TCTI.patch new file mode 100644 index 000000000..3b5be5a34 --- /dev/null +++ b/security/tpm2-tools/centos/meta_patches/disable-socket-mode-TCTI.patch @@ -0,0 +1,25 @@ +From e54d19f53dcd78d0aaceb30d1fb89eebefc1c066 Mon Sep 17 00:00:00 2001 +From: Scott Little +Date: Mon, 2 Oct 2017 17:30:56 -0400 +Subject: [PATCH 1/2] WRS: disable-socket-mode-TCTI.patch + +--- + SPECS/tpm2-tools.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/tpm2-tools.spec b/SPECS/tpm2-tools.spec +index 715d2a9..c858d6f 100644 +--- a/SPECS/tpm2-tools.spec ++++ b/SPECS/tpm2-tools.spec +@@ -54,7 +54,7 @@ tpm2-tools is a batch of testing tools for tpm2.0. It is based on tpm2-tss. + ./bootstrap + + %build +-%configure --prefix=/usr --disable-static --disable-silent-rules ++%configure --prefix=/usr --disable-static --disable-silent-rules --without-tcti-socket + %make_build + + %install +-- +1.9.1 + diff --git a/security/tpm2-tools/centos/srpm_path b/security/tpm2-tools/centos/srpm_path new file mode 100644 index 000000000..4e0786eff --- /dev/null +++ b/security/tpm2-tools/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/tpm2-tools-1.1.0-7.el7.src.rpm diff --git a/security/tss2/PKG-INFO b/security/tss2/PKG-INFO new file mode 100644 index 000000000..b62e80a9c --- /dev/null +++ b/security/tss2/PKG-INFO @@ -0,0 +1,19 @@ +Metadata-Version: 1.1 +Name: tss2 +Version: 930 +Summary: IBM's TCG Software Stack (TSS) for TPM 2.0 and related utilities +Home-page: +Author: +Author-email: +License: BSD + +Description: +TSS2 is a user space Trusted Computing Group's Software Stack (TSS) for +TPM 2.0. It implements the functionality equivalent to the TCG TSS +working group's ESAPI, SAPI, and TCTI layers (and perhaps more) but with +a hopefully far simpler interface. + +It comes with about 80 "TPM tools" that can be used for rapid prototyping, +education and debugging. + +Platform: UNKNOWN diff --git a/security/tss2/centos/build_srpm.data b/security/tss2/centos/build_srpm.data new file mode 100644 index 000000000..c844c0518 --- /dev/null +++ b/security/tss2/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$CGCS_BASE/downloads/tss2-930.tar.gz" +TIS_PATCH_VER=1 diff --git a/security/tss2/centos/tss2.spec b/security/tss2/centos/tss2.spec new file mode 100644 index 000000000..de16dde30 --- /dev/null +++ b/security/tss2/centos/tss2.spec @@ -0,0 +1,81 @@ +# +# Spec file for IBM's TSS for the TPM 2.0 +# +%{!?__global_ldflags: %global __global_ldflags -Wl,-z,relro} + +Name: tss2 +Version: 930 +Release: 1%{?_tis_dist}.%{tis_patch_ver} +Summary: IBM's TCG Software Stack (TSS) for TPM 2.0 and related utilities + +Group: Applications/System +License: BSD +Source0: %{name}-%{version}.tar.gz + +# tss2 does not work on Big Endian arch yet +ExcludeArch: ppc64 s390x +BuildRequires: openssl-devel +Requires: openssl + +%description +TSS2 is a user space Trusted Computing Group's Software Stack (TSS) for +TPM 2.0. It implements the functionality equivalent to the TCG TSS +working group's ESAPI, SAPI, and TCTI layers (and perhaps more) but with +a hopefully far simpler interface. + +It comes with about 80 "TPM tools" that can be used for rapid prototyping, +education and debugging. + +%package devel +Summary: Development libraries and headers for IBM's TSS 2.0 +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Development libraries and headers for IBM's TSS 2.0. You will need this in +order to build TSS 2.0 applications. + +%prep +%setup -q -c %{name}-%{version} + +%build +# nonstandard variable names are used in place of CFLAGS and LDFLAGS +pushd %{name}-%{version}/utils +CCFLAGS="%{optflags}" \ +LNFLAGS="%{__global_ldflags}" \ +make %{?_smp_mflags} +popd + +%install +# Prefix for namespacing +BIN_PREFIX=tss2_ +mkdir -p %{buildroot}/%{_bindir} +mkdir -p %{buildroot}/%{_libdir} +mkdir -p %{buildroot}/%{_includedir}/%{name}/ +pushd %{name}-%{version}/utils +# Pick out executables and copy with namespacing +for f in *; do + if [[ -x $f && -f $f && ! $f =~ .*\..* ]]; then + cp -p $f %{buildroot}/%{_bindir}/${BIN_PREFIX}$f + fi; +done +cp -p *.so %{buildroot}/%{_libdir} +cp -p %{name}/*.h %{buildroot}/%{_includedir}/%{name}/ +popd + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%license %{name}-%{version}/LICENSE +%{_bindir}/tss2* +%{_libdir}/libtss.so* + +%files devel +%{_includedir}/%{name} +%{_libdir}/libtss.so +#%doc ibmtss.doc + +%changelog +* Thu Feb 16 2017 Kam Nasim - 930-1 +- initial RPM for tss v930 tarball (released: 2017-01-27) diff --git a/security/wrs-ssl/LICENSE b/security/wrs-ssl/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/security/wrs-ssl/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/security/wrs-ssl/centos/build_srpm.data b/security/wrs-ssl/centos/build_srpm.data new file mode 100644 index 000000000..b2285b4cb --- /dev/null +++ b/security/wrs-ssl/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$PKG_BASE/files/* $PKG_BASE/LICENSE $PKG_BASE/server-csr.conf" +TIS_PATCH_VER=13 diff --git a/security/wrs-ssl/centos/wrs-ssl.spec b/security/wrs-ssl/centos/wrs-ssl.spec new file mode 100644 index 000000000..57cb0718c --- /dev/null +++ b/security/wrs-ssl/centos/wrs-ssl.spec @@ -0,0 +1,41 @@ +Summary: wrs-ssl version 1.0.0-r2 +Name: wrs-ssl +Version: 1.0.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: Wind River +URL: unknown +BuildRequires: openssl + +Source0: LICENSE +Source1: server-csr.conf +Source2: tpmdevice-setup + +%description +Wind River Security + +%install +rm -rf $RPM_BUILD_ROOT + +RPM_BUILD_DIR_PKG="%{name}-%{version}" +mkdir -p $RPM_BUILD_DIR_PKG +CSRCONF="$RPM_BUILD_DIR_PKG/server-csr.conf" +PEMFILE="$RPM_BUILD_DIR_PKG/server-cert.pem" +cp %{SOURCE1} $CSRCONF +# generate a self signed default certificate +/usr/bin/openssl req -new -x509 -sha256 -keyout $PEMFILE -out $PEMFILE -days 365 -nodes -config $CSRCONF +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/ssl/private +install -m 400 $PEMFILE $RPM_BUILD_ROOT/%{_sysconfdir}/ssl/private/server-cert.pem + +mkdir -p $RPM_BUILD_ROOT/%{_sbindir} +install -m 700 %{SOURCE2} $RPM_BUILD_ROOT/%{_sbindir}/tpmdevice-setup + +mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}-%{version} +install -m 644 %{SOURCE0} $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}-%{version} + +%files +%defattr(-,root,root,-) +%{_sysconfdir}/* +%{_sbindir}/* +%{_defaultdocdir}/%{name}-%{version} diff --git a/security/wrs-ssl/files/tpmdevice-setup b/security/wrs-ssl/files/tpmdevice-setup new file mode 100644 index 000000000..5fa10772c --- /dev/null +++ b/security/wrs-ssl/files/tpmdevice-setup @@ -0,0 +1,160 @@ +#!/bin/bash +# +# Copyright (c) 2013-2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# TPM setup (both active controller and remote) + +CERTIFICATE_FILE="server-cert.pem" +LOGFILE="/etc/ssl/private/.install.log" +ORIGINAL_KEY=$1 +TPM_OBJECT_CONTEXT=$2 +PUBLIC_KEY=$3 +TPM_KEY_HIERARCHY_HANDLE=0x81010002 + +if [ -z "$ORIGINAL_KEY" ] || [ -z "$TPM_OBJECT_CONTEXT" ] || [ -z "$PUBLIC_KEY" ]; then + echo "ERROR: Missing required parameters" + echo "USAGE: $0 " + exit 1 +fi + +CERTIFICATE_DIR=$(dirname "${ORIGINAL_KEY}") +export TPM_DATA_DIR=$CERTIFICATE_DIR + +# TPM specific environment +TPM_OBJECT_NAME="$CERTIFICATE_DIR/key.blob.name" +RESOURCEMGR_DEFAULT_PORT="2323" + +### Helper functions ### + +# Echo's an error and exits with provided error code +# Input : error message ($1), ret code ($2) +# Output : None +# Note : If no retcode is provided, exits with 1 +error_exit () { + echo "$1" + # remove previous object context + rm -f $TPM_OBJECT_CONTEXT &> /dev/null + exit "${2:-1}" +} + +# func: checkTPMTools +# check if the appropriate TPM2.0-tools are installed +# +# Input : None +# Output : None +checkTPMTools () { +declare -a helper_scripts=("tss2_createprimary" + "tss2_importpem" + "tss2_getcapability" + "tss2_load" + "tss2_contextsave" + "tss2_evictcontrol" + "tss2_flushcontext" + "create_tpm2_key" + "resourcemgr") +for src in "${helper_scripts[@]}"; do + if ! type "$src" &>/dev/null; then + error_exit "ERROR: Cannot find $src. Needed for TPM configuration" + fi +done +} + +startResourceMgr () { +resourcemgr &>> $LOGFILE 2>&1 & + +# ensure the resourcemgr is started +for i in {1..5} +do + sleep 0.5 + MGR_RUNNING=`pidof resourcemgr` + if [ ! -z $MGR_RUNNING ]; then + break + fi +done +[ ! -z $MGR_RUNNING ] || error_exit "Unable to start TPM resourcemgr" + +# check to see if the resourcemgr port is open +IS_OPEN=0 +for i in {1..5} +do + sleep 0.5 + _test=`netstat -an | grep $RESOURCEMGR_DEFAULT_PORT | grep -i listen` + if [ ! -z "$_test" ]; then + IS_OPEN=1 + break + fi +done +[ $IS_OPEN -ne 0 ] || error_exit "Unable to initialize resourcemgr" +} + +stopResourceMgr () { +# Kill any previous instances of resourcemgr +pkill -c -TERM resourcemgr &> /dev/null 2>&1 +} + + + +### Main ### +# remove previous object context +rm -f $TPM_OBJECT_CONTEXT &> /dev/null +rm -f $CERTIFICATE_DIR/*.bin &> /dev/null + +tpmCheck=`lsmod | grep "tpm" -c` +[ "$tpmCheck" -ne 0 ] || error_exit "TPM Kernel Module not found. Check BIOS/Kernel configuration" + +# Ensure that the appropriate TPM tool utilities are +# installed on the system +checkTPMTools + +# Confirm that this is a TPM 2.0 device +TPM_VERSION=`tss2_getcapability -cap 6 | grep TPM_PT_FAMILY_INDICATOR | awk '{print $4}' | xxd -r -p` +if [ "$TPM_VERSION" != "2.0" ]; then + error_exit "ERROR: TPM Device is not version 2.0 compatible" +fi + +# Start the Intel ResourceMgr to clear the NV +# as well as all stale transient handles in +# the endorsement hierarchy. +# Since ResourceMgr has a number of stability, +# and security issues, we will stop it after it +# initializes the NV and Handle space +startResourceMgr +stopResourceMgr + +# Create the Endorsement Primary Key hierarchy which will be used +# for wrapping the private key. Use RSA as the primary key encryption +# and SHA 256 for hashing. Allow TPM to output the object +# handle as a file context +PRIMARY_HANDLE=`tss2_createprimary -hi e -rsa -halg sha256 | grep "Handle" | awk '{print $2}'` +[ ! -z "$PRIMARY_HANDLE" ] || error_exit "Unable to create TPM Key Hierarchy" +PRIMARY_HANDLE="0x$PRIMARY_HANDLE" + +# The object context will be lost over node reboots, and needs to +# be persistently stored in TPM NV. +# evict the persistent handle if it exists previously +tss2_evictcontrol -hi o -ho $TPM_KEY_HIERARCHY_HANDLE -hp $TPM_KEY_HIERARCHY_HANDLE +tss2_evictcontrol -hi o -ho $PRIMARY_HANDLE -hp $TPM_KEY_HIERARCHY_HANDLE &>> $LOGFILE +[ $? -eq 0 ] || error_exit "Unable to persist Key Hierarchy in TPM memory" + +tss2_flushcontext -ha $PRIMARY_HANDLE + +# wrap the original private key in TPM's Endorsement key hierarchy +# this will generate a TSS key blob in ASN 1 encoding +create_tpm2_key -p $TPM_KEY_HIERARCHY_HANDLE -w $ORIGINAL_KEY $TPM_OBJECT_CONTEXT &>> $LOGFILE +[ $? -eq 0 ] || error_exit "Unable to wrap provided private key into TPM Key Hierarchy" + +# the apps will also need to the public key, place it in +# the certificate dirpath +mv $PUBLIC_KEY $CERTIFICATE_DIR/$CERTIFICATE_FILE + +# ensure that the TPM object and the public cert are only readable by root +chown root $CERTIFICATE_DIR/$CERTIFICATE_FILE $TPM_OBJECT_CONTEXT +chmod 0600 $CERTIFICATE_DIR/$CERTIFICATE_FILE $TPM_OBJECT_CONTEXT + +# remove all sysinv key copy artifacts +rm -f $ORIGINAL_KEY "${ORIGINAL_KEY}.sysinv" "${PUBLIC_KEY}.sysinv" &> /dev/null + +exit 0 diff --git a/security/wrs-ssl/server-csr.conf b/security/wrs-ssl/server-csr.conf new file mode 100644 index 000000000..d754cfa11 --- /dev/null +++ b/security/wrs-ssl/server-csr.conf @@ -0,0 +1,13 @@ +[ req ] +default_bits = 1024 +distinguished_name = req_distinguished_name +prompt = no + +[ req_distinguished_name ] +C = CA +ST = Ontario +L = Ottawa +O = Wind River Inc. +OU = Carrier Grade Communications Server +CN = *.wrs.com + diff --git a/storage-topology/storage-topology/LICENSE b/storage-topology/storage-topology/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/storage-topology/storage-topology/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/storage-topology/storage-topology/setup.py b/storage-topology/storage-topology/setup.py new file mode 100644 index 000000000..91c1da59a --- /dev/null +++ b/storage-topology/storage-topology/setup.py @@ -0,0 +1,19 @@ +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import setuptools + +setuptools.setup( + name='storage_topology', + description='Show openstack storage topology', + version='1.0.0', + license='Apache-2.0', + packages=['storage_topology', 'storage_topology.exec'], + entry_points={ + 'console_scripts': [ + 'storage-topology = storage_topology.exec.storage_topology:main', + ]} +) diff --git a/storage-topology/storage-topology/storage_topology/__init__.py b/storage-topology/storage-topology/storage_topology/__init__.py new file mode 100644 index 000000000..754a8f4ef --- /dev/null +++ b/storage-topology/storage-topology/storage_topology/__init__.py @@ -0,0 +1,5 @@ +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# diff --git a/storage-topology/storage-topology/storage_topology/exec/__init__.py b/storage-topology/storage-topology/storage_topology/exec/__init__.py new file mode 100644 index 000000000..754a8f4ef --- /dev/null +++ b/storage-topology/storage-topology/storage_topology/exec/__init__.py @@ -0,0 +1,5 @@ +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# diff --git a/storage-topology/storage-topology/storage_topology/exec/storage_topology.py b/storage-topology/storage-topology/storage_topology/exec/storage_topology.py new file mode 100644 index 000000000..5e2db3b85 --- /dev/null +++ b/storage-topology/storage-topology/storage_topology/exec/storage_topology.py @@ -0,0 +1,456 @@ +# +# Copyright (c) 2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +""" + +Usage: storage-topology [options] + options: + -d, --diskview view disk data of all server nodes. + -v, --vgview view VG data in all nodes. + -a, --all view both disk and vg view. ( selected by default if any + of the view options is NOT selected) + -e, --extended include additional parameters like uuids in selected + view(s) + -h, --help display this usage + +Tool to show a consolidated view of system physical disks and logical volume +groups data. +""" + +import os +import sys +import argparse +import datetime +import logging +import textwrap +import keyring +import subprocess +import math +from prettytable import PrettyTable +from cgtsclient.common import utils +from cgtsclient import client as cgts_client +from cgtsclient import exc + +"""---------------------------------------------------------------------------- +Global definitions +----------------------------------------------------------------------------""" + +# logger +logger = logging.getLogger(__name__) + +# show options +show = {} + + +def configure_debuggubg(debug): + if debug: + logging.basicConfig( + format="%(levelname)s (%(module)s:%(lineno)d) %(message)s", + level=logging.DEBUG) + else: + logging.basicConfig( + format="%(levelname)s %(message)s", + level=logging.WARNING) + + +def parse_arguments(show): + """ + Parse command line arguments. + """ + + parser = argparse.ArgumentParser( + prog=os.path.basename(sys.argv[0]), + formatter_class=argparse.RawDescriptionHelpFormatter, + description=textwrap.dedent('''\ + Tool to summarize server storage resouce usage. + '''), + epilog=textwrap.dedent('''\ + Tables and Field descriptions: + ------------------------------ + SERVER Physical DISK view: + Host - server host name + Device Node - device node name + Device Type - device node type ( extended view only) + UUID - device node uuid ( extended view only) + Size in GB - disk size in giga bytes + PV Name - name of physical volume + PV State - the physical volume state + PV UUID - the physical volume uuid + VG (name:state:uuid) + name - VG name + state - VG state + uuid - VG uuid (extended view only) + + + SERVER VOLUME GROUP view: + Host - server host name + Name - volume group name + UUID - volume group uuid + State - VG state + Size - VG size in GB + Current LVs - current Number of logical volumes (lv) + Current PVs - current Number of physical volumes (pv) + PV List (name:state:uuid) - Comma separated list of PVs + name - physical volume name + state - physical volume state + uuid - physical volume uuid (extended view only) + Parameters - list of VG parameters + + '''), + ) + + # Global arguments + + parser.add_argument('-d', '--diskview', + default=False, action='store_true', + help="view all physical disks across all nodes" + " including mapped physical volumes and" + "logical volume groups") + + parser.add_argument('-v', '--vgview', + default=False, action='store_true', + help="view information pertaining to VGs in all nodes") + + parser.add_argument('-a', '--all', + default=False, action='store_true', + help="view both disk and vg views") + + parser.add_argument('--debug', + default=bool(utils.env('SYSTEMCLIENT_DEBUG')), + action='store_true', + help=argparse.SUPPRESS) + + parser.add_argument('-e', '--extended', + default=False, action="store_true", + help="Print additional disk or vg information") + + # Parse arguments + args = parser.parse_args() + + show['diskview'] = args.diskview + show['vgview'] = args.vgview + show['all'] = args.all + show['extended'] = args.extended + show['debug'] = args.debug + + # Configure logging to appropriate level + + configure_debuggubg(show['debug']) + + +def get_system_creds(): + + """ Return keystone credentials by sourcing /etc/nova/openrc. """ + d = {} + + proc = subprocess.Popen(['bash', '-c', + 'source /etc/nova/openrc && env'], + stdout=subprocess.PIPE) + + for line in proc.stdout: + key, _, value = line.partition("=") + if key == 'OS_USERNAME': + d['os_username'] = value.strip() + elif key == 'OS_PASSWORD': + d['os_password'] = value.strip() + elif key == 'OS_TENANT_NAME': + d['os_tenant_name'] = value.strip() + elif key == 'OS_AUTH_URL': + d['os_auth_url'] = value.strip() + elif key == 'OS_REGION_NAME': + d['os_region_name'] = value.strip() + + proc.communicate() + return d + + +def convert_to_readable_size(size, orig_unit='B'): + """ Converts size to human readable unit """ + units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] + + # convert original size to bytes + try: + i = units.index(orig_unit) + except: + raise RuntimeError('Invalid size unit passed: %s' % (orig_unit)) + size = size * pow(1024, i) + + unitIndex = int(math.floor(math.log(size, 1024))) + # set size unit to PB max if size is greater than 1024 PB + if unitIndex > 5: + unitIndex = 5 + sizer = math.pow(1024, unitIndex) + newsize = round(size/sizer, 2) + return "%s %s" % (newsize, units[unitIndex]) + + +def print_disk_view(rows=None, extended=False): + + """ Print all summary Disk views using PrettyTable. """ + + disk_lables_extended = \ + ['Host', 'Device Node', 'Device Type', 'UUID', 'Size', + 'PV Name', 'PV State', 'PV UUID', 'VG (name:state:uuid)', ] + disk_lables_brief = \ + ['Host', 'Device Node', 'Size', 'PV Name', 'PV State', + 'VG (name:state)'] + + if len(rows) > 0: + print + print "DISKs: (Physical disk view)" + + pt = PrettyTable(disk_lables_extended) if extended else \ + PrettyTable(disk_lables_brief) + pt.align = 'l' + pt.align['Size'] = 'r' + for r in rows: + if len(r) == len(pt.field_names): + pt.add_row(r) + else: + print "Disk row has incorrect number of values: %s" % r + + print pt + + +def print_vg_view(rows=None, extended=False): + + """ Print all summary VG views using PrettyTable. """ + vg_labels_extended = \ + ['Host', 'VG Name', 'UUID', 'VG State', 'VG Size', 'Current LVs', + 'Current PVs', 'PV List (name:state:uuid)', 'VG Parameters'] + + vg_labels_brief = \ + ['Host', 'VG Name', 'VG State', 'VG Size', 'Current LVs', + 'Current PVs', 'PV List (name:state)', 'VG Parameters'] + + if len(rows) > 0: + print + print "VOLUME GROUPS: (VG view)" + + pt = PrettyTable(vg_labels_extended) if extended else \ + PrettyTable(vg_labels_brief) + pt.align = 'l' + for C in ['VG Size', 'Current LVs', 'Current PVs']: + pt.align[C] = 'r' + + for r in rows: + if len(r) == len(pt.field_names): + pt.add_row(r) + else: + print "VG row has incorrect number of values: %s" % r + + print pt + + +def get_info_and_display(cc, show=None): + """ Get storage information from server nodes. + + Display the following information in table format. + - disk data of all server nodes + - VG data of all servers nodes + """ + # get list of server hosts and for each host retrieve + # the disk, lvg. pv list objects. + + host_storage_attr = {} + hosts = cc.ihost.list() + hostnames = [] + for h in hosts: + hostname = getattr(h, 'hostname', '') + hostnames.append(hostname) + host_disks = cc.idisk.list(h.uuid) + host_pvs = cc.ipv.list(h.uuid) + host_lvgs = cc.ilvg.list(h.uuid) + host_storage_attr[hostname] = {'host_disks': host_disks, + 'host_pvs': host_pvs, + 'host_lvgs': host_lvgs} + + disk_view = [] + vg_view = [] + + pv_fields_ext = ['lvm_pv_name', 'pv_state', 'lvm_pv_uuid'] + pv_fields = ['lvm_pv_name', 'pv_state'] + disk_fields_ext = ['device_node', 'device_type', 'uuid', 'size_mib'] + disk_fields = ['device_node', 'size_mib'] + lvg_fields_ext = ['lvm_vg_name', 'uuid', 'vg_state', 'lvm_vg_size', + 'lvm_cur_lv', 'lvm_cur_pv'] + lvg_fields = ['lvm_vg_name', 'vg_state', 'lvm_vg_size', 'lvm_cur_lv', + 'lvm_cur_pv'] + + # padding empty values in case not pv in disk. + disk_pd_num_ext = 5 + disk_pd_num = 3 + pv_pd_num_ext = 4 + pv_pd_num = 3 + + for k, v in host_storage_attr.iteritems(): + if show['diskview'] or show['all']: + for disk_o in v['host_disks']: + device_node = getattr(disk_o, 'device_node', '') + drow = [k] + if show['extended']: + drow.extend([(getattr(disk_o, f, '')) + for f in disk_fields_ext]) + drow[4] = convert_to_readable_size( + getattr(disk_o, 'size_mib', ''), 'MB') + else: + drow.extend([(getattr(disk_o, f, '')) + for f in disk_fields]) + drow[2] = convert_to_readable_size( + getattr(disk_o, 'size_mib', ''), 'MB') + + if v['host_pvs']: + first = True + for pv_o in v['host_pvs']: + pv_node = getattr(pv_o, 'idisk_device_node', '') + if pv_node == device_node: + if first: + if show['extended']: + drow.extend([(getattr(pv_o, f, '')) + for f in pv_fields_ext]) + else: + drow.extend([(getattr(pv_o, f, '')) + for f in pv_fields]) + first = False + else: + disk_view.append(drow) + # new row for next pv + # padd for host, device_node, size + if show['extended']: + drow = [''] * disk_pd_num_ext + drow.extend([(getattr(pv_o, f, '')) + for f in pv_fields_ext]) + else: + drow = [''] * disk_pd_num + drow.extend([(getattr(pv_o, f, '')) + for f in pv_fields]) + + for vg_o in v['host_lvgs']: + vg_str = "" + if getattr(pv_o, 'lvm_vg_name', '') == \ + getattr(vg_o, 'lvm_vg_name', ''): + if show['extended']: + vg_str += ":".join( + [str(getattr(pv_o, 'lvm_vg_name', + '')), + str(getattr(vg_o, 'vg_state')), + str(getattr(vg_o, 'uuid'))]) + else: + vg_str += ":".join( + [str(getattr(pv_o, 'lvm_vg_name', + '')), + str(getattr(vg_o, 'vg_state'))]) + + drow.append(vg_str) + else: + if show['extended']: + drow.extend([''] * pv_pd_num_ext) + else: + drow.extend([''] * pv_pd_num) + + disk_view.append(drow) # add to disk row disk view rows + + if show['vgview'] or show['all']: + for vg_o in v['host_lvgs']: + vgrow = [k] + if show['extended']: + vgrow.extend([(getattr(vg_o, f, '')) + for f in lvg_fields_ext]) + vgrow[4] = convert_to_readable_size( + getattr(vg_o, 'lvm_vg_size', '')) + else: + vgrow.extend([(getattr(vg_o, f, '')) for f in lvg_fields]) + vgrow[3] = convert_to_readable_size( + getattr(vg_o, 'lvm_vg_size', '')) + + # list of current pvs for each VG + count = 0 + for pv_o in v['host_pvs']: + pv_str = "" + if getattr(vg_o, 'lvm_vg_name', '') == getattr( + pv_o, 'lvm_vg_name', ''): + count += 1 + if count > 1: + pv_str += ', ' + + if show['extended']: + pv_str += ":".join( + [str(getattr(pv_o, f, '')) + for f in pv_fields_ext]) + else: + pv_str += ":".join( + [str(getattr(pv_o, f, '')) for f in pv_fields]) + vgrow.append(pv_str) + + vgrow.append(getattr(vg_o, 'capabilities', '')) + + vg_view.append(vgrow) + + print_disk_view(rows=disk_view, extended=show['extended']) + print_vg_view(rows=vg_view, extended=show['extended']) + + +def main(): + try: + # Process command line options and arguments, configure logging, + # configure debug and show options + parse_arguments(show) + + if not show['diskview'] and not show['vgview']: + # both disk and vg views are printed + show['all'] = True + + api_version = utils.env('SYSTEM_API_VERSION', default='1') + + # Print selected options, and timestamp + prog = os.path.basename(sys.argv[0]) + ts = datetime.datetime.now() + if show['debug']: + print "%s: %s options: view:%s System api version: %s" \ + % (prog, ts.isoformat(), show, api_version) + + cgts_client_creds = get_system_creds() + if not cgts_client_creds['os_username']: + raise exc.CommandError("You must provide a username via " + "env[OS_USERNAME]") + if not cgts_client_creds['os_password']: + # priviledge check (only allow Keyring retrieval if we are root) + if os.geteuid() == 0: + cgts_client_creds['os_password'] = keyring.get_password( + 'CGCS', cgts_client_creds['os_username']) + else: + raise exc.CommandError("You must provide a password via " + "env[OS_PASSWORD]") + + if not cgts_client_creds['os_tenant_name']: + raise exc.CommandError("You must provide a tenant_id via " + "env[OS_TENANT_NAME]") + + if not cgts_client_creds['os_auth_url']: + raise exc.CommandError("You must provide a auth url via " + "env[OS_AUTH_URL]") + + if not cgts_client_creds['os_region_name']: + raise exc.CommandError("You must provide a region_name via " + "env[OS_REGION_NAME]") + + cc = cgts_client.get_client(api_version, **cgts_client_creds) + + # Get all info and display in table format + get_info_and_display(cc, show) + sys.exit(0) + + except KeyboardInterrupt as e: + logger.warning('caught: %r, shutting down', e) + sys.exit(0) + + except IOError as e: + logger.warning('caught: %r, shutting down', e) + sys.exit(0) + + except Exception as e: + logger.error('exception: %r', e, exc_info=1) + sys.exit(-4) diff --git a/support/libevent/.gitignore b/support/libevent/.gitignore new file mode 100644 index 000000000..567a2e0a8 --- /dev/null +++ b/support/libevent/.gitignore @@ -0,0 +1,7 @@ +!.distro +.distro/centos7/rpmbuild/RPMS +.distro/centos7/rpmbuild/SRPMS +.distro/centos7/rpmbuild/BUILD +.distro/centos7/rpmbuild/BUILDROOT +.distro/centos7/rpmbuild/SOURCES/libevent*tar.gz +.distro/centos7/rpmbuild/SOURCES/*.patch diff --git a/support/libevent/PKG-INFO b/support/libevent/PKG-INFO new file mode 100644 index 000000000..9e63d49ff --- /dev/null +++ b/support/libevent/PKG-INFO @@ -0,0 +1,19 @@ +Metadata-Version: 1.1 +Name: libevent +Version: 2.0.21 +Summary: Abstract asynchronous event notification library +Home-page: +Author: +Author-email: +License: BSD + +Description: +The libevent API provides a mechanism to execute a callback function +when a specific event occurs on a file descriptor or after a timeout +has been reached. libevent is meant to replace the asynchronous event +loop found in event driven network servers. An application just needs +to call event_dispatch() and can then add or remove events dynamically +without having to change the event loop. + + +Platform: UNKNOWN diff --git a/support/libevent/centos/build_srpm.data b/support/libevent/centos/build_srpm.data new file mode 100644 index 000000000..112ca54f4 --- /dev/null +++ b/support/libevent/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="files/*" +TIS_PATCH_VER=2 diff --git a/support/libevent/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/support/libevent/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..69fd4fcea --- /dev/null +++ b/support/libevent/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,24 @@ +From d63b56b8511b808a4c23c4c15ed81e368f9b020c Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 27 Sep 2016 10:59:20 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/libevent.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/libevent.spec b/SPECS/libevent.spec +index 9c6cc3e..7d98b8f 100644 +--- a/SPECS/libevent.spec ++++ b/SPECS/libevent.spec +@@ -1,6 +1,6 @@ + Name: libevent + Version: 2.0.21 +-Release: 4%{?dist} ++Release: 4.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: Abstract asynchronous event notification library + + Group: System Environment/Libraries +-- +1.8.3.1 + diff --git a/support/libevent/centos/meta_patches/PATCH_ORDER b/support/libevent/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..7ebccf68e --- /dev/null +++ b/support/libevent/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +spec-include-TiS-patches.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/support/libevent/centos/meta_patches/spec-include-TiS-patches.patch b/support/libevent/centos/meta_patches/spec-include-TiS-patches.patch new file mode 100644 index 000000000..3ee7472c6 --- /dev/null +++ b/support/libevent/centos/meta_patches/spec-include-TiS-patches.patch @@ -0,0 +1,22 @@ +diff --git a/SPECS/libevent.spec b/SPECS/libevent.spec +index fd59ca3..9c6cc3e 100644 +--- a/SPECS/libevent.spec ++++ b/SPECS/libevent.spec +@@ -13,6 +13,8 @@ BuildRequires: doxygen openssl-devel + Patch00: libevent-2.0.10-stable-configure.patch + # Disable network tests + Patch01: libevent-nonettests.patch ++Patch02: libevent-ipv6-client-socket.patch ++Patch03: libevent-disable-tests.patch + + %description + The libevent API provides a mechanism to execute a callback function +@@ -49,6 +51,8 @@ need to install %{name}-doc. + # 477685 - libevent-devel multilib conflict + %patch00 -p1 + %patch01 -p1 -b .nonettests ++%patch02 -p1 ++%patch03 -p1 + + %build + %configure \ diff --git a/support/libevent/centos/srpm_path b/support/libevent/centos/srpm_path new file mode 100644 index 000000000..9c7a677cf --- /dev/null +++ b/support/libevent/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/libevent-2.0.21-4.el7.src.rpm diff --git a/support/libevent/files/libevent-disable-tests.patch b/support/libevent/files/libevent-disable-tests.patch new file mode 100644 index 000000000..c23f84ede --- /dev/null +++ b/support/libevent/files/libevent-disable-tests.patch @@ -0,0 +1,26 @@ +diff --git a/Makefile.am b/Makefile.am +index 42879a3..dc90359 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -126,7 +126,7 @@ else + noinst_LTLIBRARIES = $(LIBEVENT_LIBS_LA) + endif + +-SUBDIRS = . include sample test ++SUBDIRS = . include sample + + if BUILD_WIN32 + +diff --git a/Makefile.in b/Makefile.in +index ac27389..aff0cf3 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -534,7 +534,7 @@ LIBEVENT_LIBS_LA = libevent.la libevent_core.la libevent_extra.la \ + @INSTALL_LIBEVENT_TRUE@lib_LTLIBRARIES = $(LIBEVENT_LIBS_LA) + @INSTALL_LIBEVENT_TRUE@pkgconfig_DATA = $(LIBEVENT_PKGCONFIG) + @INSTALL_LIBEVENT_FALSE@noinst_LTLIBRARIES = $(LIBEVENT_LIBS_LA) +-SUBDIRS = . include sample test ++SUBDIRS = . include sample + @BUILD_WIN32_FALSE@SYS_LIBS = + @BUILD_WIN32_TRUE@SYS_LIBS = -lws2_32 -lshell32 -ladvapi32 + @BUILD_WIN32_FALSE@SYS_SRC = $(am__append_5) $(am__append_6) \ diff --git a/support/libevent/files/libevent-ipv6-client-socket.patch b/support/libevent/files/libevent-ipv6-client-socket.patch new file mode 100644 index 000000000..d11e94225 --- /dev/null +++ b/support/libevent/files/libevent-ipv6-client-socket.patch @@ -0,0 +1,55 @@ +--- + http.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +--- a/http.c ++++ b/http.c +@@ -1325,6 +1325,9 @@ evhttp_error_cb(struct bufferevent *bufe + struct evhttp_connection *evcon = arg; + struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); + ++ if (evcon->fd == -1) ++ evcon->fd = bufferevent_getfd(bufev); ++ + switch (evcon->state) { + case EVCON_CONNECTING: + if (what & BEV_EVENT_TIMEOUT) { +@@ -1390,6 +1393,9 @@ evhttp_connection_cb(struct bufferevent + int error; + ev_socklen_t errsz = sizeof(error); + ++ if (evcon->fd == -1) ++ evcon->fd = bufferevent_getfd(bufev); ++ + if (!(what & BEV_EVENT_CONNECTED)) { + /* some operating systems return ECONNREFUSED immediately + * when connecting to a local address. the cleanup is going +@@ -2189,16 +2195,21 @@ evhttp_connection_connect(struct evhttp_ + EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING)); + evcon->flags |= EVHTTP_CON_OUTGOING; + +- evcon->fd = bind_socket( +- evcon->bind_address, evcon->bind_port, 0 /*reuse*/); +- if (evcon->fd == -1) { +- event_debug(("%s: failed to bind to \"%s\"", +- __func__, evcon->bind_address)); +- return (-1); ++ if (evcon->bind_address || evcon->bind_port) { ++ evcon->fd = bind_socket( ++ evcon->bind_address, evcon->bind_port, 0 /*reuse*/); ++ if (evcon->fd == -1) { ++ event_debug(("%s: failed to bind to \"%s\"", ++ __func__, evcon->bind_address)); ++ return (-1); ++ } ++ ++ bufferevent_setfd(evcon->bufev, evcon->fd); ++ } else { ++ bufferevent_setfd(evcon->bufev, -1); + } + + /* Set up a callback for successful connection setup */ +- bufferevent_setfd(evcon->bufev, evcon->fd); + bufferevent_setcb(evcon->bufev, + NULL /* evhttp_read_cb */, + NULL /* evhttp_write_cb */, diff --git a/support/libxslt/libxslt/CVE-2015-7995.patch b/support/libxslt/libxslt/CVE-2015-7995.patch new file mode 100644 index 000000000..2cbf8d68b --- /dev/null +++ b/support/libxslt/libxslt/CVE-2015-7995.patch @@ -0,0 +1,26 @@ +Fix for type confusion in preprocessing attributes + +CVE-2015-7995 http://www.openwall.com/lists/oss-security/2015/10/27/10 +We need to check that the parent node is an element before dereferencing +its namespace + +Upstream-Status: Backport + +https://git.gnome.org/browse/libxslt/commit/?id=7ca19df892ca22d9314e95d59ce2abdeff46b617 + +Signed-off-by: Armin Kuster + +Index: libxslt-1.1.28/libxslt/preproc.c +=================================================================== +--- libxslt-1.1.28.orig/libxslt/preproc.c ++++ libxslt-1.1.28/libxslt/preproc.c +@@ -2245,7 +2245,8 @@ xsltStylePreCompute(xsltStylesheetPtr st + } else if (IS_XSLT_NAME(inst, "attribute")) { + xmlNodePtr parent = inst->parent; + +- if ((parent == NULL) || (parent->ns == NULL) || ++ if ((parent == NULL) || ++ (parent->type != XML_ELEMENT_NODE) || (parent->ns == NULL) || + ((parent->ns != inst->ns) && + (!xmlStrEqual(parent->ns->href, inst->ns->href))) || + (!xmlStrEqual(parent->name, BAD_CAST "attribute-set"))) { diff --git a/support/lvm2/lvm2/Fix-regression-in-for_each_sub_lv.patch b/support/lvm2/lvm2/Fix-regression-in-for_each_sub_lv.patch new file mode 100644 index 000000000..bc1ae6840 --- /dev/null +++ b/support/lvm2/lvm2/Fix-regression-in-for_each_sub_lv.patch @@ -0,0 +1,44 @@ +From d05dd3f20fed08159875b9d4a78ab27ec02cfab6 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 9 May 2012 12:12:21 +0000 +Subject: [PATCH 2/3] Fix regression in for_each_sub_lv + +pool_lv is not a sub lv in terms for this function. +It has caused problem with renaming thin_volume, where it has tried to +rename pool LV as well. + +(cherry picked from commit 98f2e3d974bcceaf6dbac9f80f42a0eaf6512059) + +Conflicts: + WHATS_NEW +--- + WHATS_NEW | 4 ++++ + lib/metadata/lv_manip.c | 7 ------- + 2 files changed, 4 insertions(+), 7 deletions(-) + +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,7 @@ ++Version 2.02.95-wrs ++================================ ++ Fix lvrename for thin volumes (regression in for_each_sub_lv() 2.02.89). ++ + Version 2.02.95 - 6th March 2012 + ================================ + If unspecified, adjust thin pool metadata and chunk size to fit into 128MB. +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -2814,13 +2814,6 @@ int for_each_sub_lv(struct cmd_context * + return_0; + } + +- if (seg->pool_lv) { +- if (!fn(cmd, seg->pool_lv, data)) +- return_0; +- if (!for_each_sub_lv(cmd, seg->pool_lv, fn, data)) +- return_0; +- } +- + if (seg->metadata_lv) { + if (!fn(cmd, seg->metadata_lv, data)) + return_0; diff --git a/support/lvm2/lvm2/Sync-filesystem-for-thin-snapshots.patch b/support/lvm2/lvm2/Sync-filesystem-for-thin-snapshots.patch new file mode 100644 index 000000000..c640b0b28 --- /dev/null +++ b/support/lvm2/lvm2/Sync-filesystem-for-thin-snapshots.patch @@ -0,0 +1,48 @@ +From db5a5e67f7715e4087ae2a9685fdf4ff0c4fca17 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 5 Jun 2012 11:26:54 +0200 +Subject: [PATCH 3/3] Sync filesystem for thin snapshots + +Add missing lockfs option when suspend origin, before thin volume +snapshot is created + +(cherry picked from commit 2f99e5e35a9918c337e66b74aa6126cca9328c64) + +Conflicts: + WHATS_NEW +--- + WHATS_NEW | 1 + + lib/activate/activate.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,6 +1,7 @@ + Version 2.02.95-wrs + ================================ + Fix lvrename for thin volumes (regression in for_each_sub_lv() 2.02.89). ++ Fix missing sync of filesystem when creating thin volume snapshot. + + Version 2.02.95 - 6th March 2012 + ================================ +--- a/lib/activate/activate.c ++++ b/lib/activate/activate.c +@@ -1488,6 +1488,9 @@ static int _lv_suspend(struct cmd_contex + (lv_is_origin(lv_pre) || lv_is_cow(lv_pre))) + lockfs = 1; + ++ if (laopts->origin_only && lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre)) ++ lockfs = 1; ++ + /* + * Suspending an LV directly above a PVMOVE LV also + * suspends other LVs using that same PVMOVE LV. +@@ -1567,7 +1570,7 @@ static int _lv_resume(struct cmd_context + if (lv_is_thin_pool(lv) && laopts->origin_only) + messages_only = 1; + +- if (!lv_is_origin(lv)) ++ if (!lv_is_origin(lv) && !lv_is_thin_volume(lv)) + laopts->origin_only = 0; + + if (test_mode()) { diff --git a/support/lvm2/lvm2/fix_thin_provision_device_name.patch b/support/lvm2/lvm2/fix_thin_provision_device_name.patch new file mode 100644 index 000000000..b57182790 --- /dev/null +++ b/support/lvm2/lvm2/fix_thin_provision_device_name.patch @@ -0,0 +1,37 @@ +--- + lib/activate/dev_manager.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -1210,17 +1210,18 @@ static int _thin_pool_callback(struct dm + "global/thin_check_executable", + DEFAULT_THIN_CHECK_EXECUTABLE); + const struct logical_volume *mlv = first_seg(data->pool_lv)->metadata_lv; +- size_t len = strlen(dmdir) + strlen(mlv->vg->name) + strlen(mlv->name) + 3; ++ size_t len = strlen(dmdir) + 2 * strlen(mlv->vg->name) + strlen(mlv->name) + 3; + char meta_path[len]; + int args; + char *argv[19]; /* Max supported 15 args */ +- char *split; ++ char *split, *dm_name; + + if (!thin_check[0]) + return 1; /* Checking disabled */ + +- if (dm_snprintf(meta_path, len, "%s/%s-%s", dmdir, +- mlv->vg->name, mlv->name) < 0) { ++ if (!(dm_name = dm_build_dm_name(data->dm->mem, mlv->vg->name, ++ mlv->name, NULL)) || ++ (dm_snprintf(meta_path, len, "%s/%s", dmdir, dm_name) < 0)) { + log_error("Failed to build thin metadata path."); + return 0; + } +@@ -1263,6 +1264,7 @@ static int _thin_pool_callback(struct dm + } + + dm_pool_free(data->dm->mem, split); ++ dm_pool_free(data->dm->mem, dm_name); + + return ret; + } diff --git a/support/lvm2/lvm2/lvm2.sh b/support/lvm2/lvm2/lvm2.sh new file mode 100755 index 000000000..1155678a1 --- /dev/null +++ b/support/lvm2/lvm2/lvm2.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (c) 2013-2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +### BEGIN INIT INFO +# Provides: lvm2 +# Required-Start: +# Required-Stop: +# Default-Start: S +# Default-Stop: +# Short-Description: Activate volume groups +### END INIT INFO + +. /etc/init.d/functions + +case "$1" in + start) + /usr/sbin/vgscan --ignorelockingfailure > /dev/null 2> /dev/null && /usr/sbin/vgchange --ignorelockingfailure -a y > /dev/null 2> /dev/null + ;; + stop) + ;; + restart) + /usr/sbin/vgscan ; /usr/sbin/vgchange -a y + ;; + status) + /usr/sbin/vgdisplay + ;; + *) + echo "Usage: $0 {start|stop|status|restart}" + exit 1 +esac + +exit 0 diff --git a/support/lvm2/lvm2/move-thin_check_executable-var.patch b/support/lvm2/lvm2/move-thin_check_executable-var.patch new file mode 100644 index 000000000..71e34f7a1 --- /dev/null +++ b/support/lvm2/lvm2/move-thin_check_executable-var.patch @@ -0,0 +1,40 @@ +--- + doc/example.conf.in | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/doc/example.conf.in ++++ b/doc/example.conf.in +@@ -463,6 +463,16 @@ global { + # proper udev rules, all changes in block device configuration will be + # *ignored* until a manual 'vgscan' is performed. + use_lvmetad = 0 ++ ++ # Full path of the utility called to check that a thin metadata device ++ # is in a state that allows it to be used. ++ # Each time a thin pool needs to be activated, this utility is executed. ++ # The activation will only proceed if the utility has an exit status of 0. ++ # Set to "" to skip this check. (Not recommended.) ++ # The thin tools are available as part of the device-mapper-persistent-data ++ # package from https://github.com/jthornber/thin-provisioning-tools. ++ # ++ thin_check_executable = "/sbin/thin_check -q" + } + + activation { +@@ -650,16 +660,6 @@ activation { + thin_pool_autoextend_threshold = 100 + thin_pool_autoextend_percent = 20 + +- # Full path of the utility called to check that a thin metadata device +- # is in a state that allows it to be used. +- # Each time a thin pool needs to be activated, this utility is executed. +- # The activation will only proceed if the utility has an exit status of 0. +- # Set to "" to skip this check. (Not recommended.) +- # The thin tools are available as part of the device-mapper-persistent-data +- # package from https://github.com/jthornber/thin-provisioning-tools. +- # +- thin_check_executable = "/sbin/thin_check -q" +- + # While activating devices, I/O to devices being (re)configured is + # suspended, and as a precaution against deadlocks, LVM2 needs to pin + # any memory it is using so it is not paged out. Groups of pages that diff --git a/support/postgresql/files/0001-pgcrypto-Detect-and-report-too-short-crypt-salts.patch b/support/postgresql/files/0001-pgcrypto-Detect-and-report-too-short-crypt-salts.patch new file mode 100644 index 000000000..a7ccf52d5 --- /dev/null +++ b/support/postgresql/files/0001-pgcrypto-Detect-and-report-too-short-crypt-salts.patch @@ -0,0 +1,259 @@ +From 56232f9879768e961485d8ba218da18c38768413 Mon Sep 17 00:00:00 2001 +From: Noah Misch +Date: Mon, 5 Oct 2015 10:06:29 -0400 +Subject: [PATCH 1/2] pgcrypto: Detect and report too-short crypt() salts. + +Certain short salts crashed the backend or disclosed a few bytes of +backend memory. For existing salt-induced error conditions, emit a +message saying as much. Back-patch to 9.0 (all supported versions). + +Josh Kupershmidt + +Security: CVE-2015-5288 +--- + contrib/pgcrypto/crypt-blowfish.c | 19 +++++++++++++++++-- + contrib/pgcrypto/crypt-des.c | 22 +++++++++++++++++++--- + contrib/pgcrypto/expected/crypt-blowfish.out | 9 +++++++++ + contrib/pgcrypto/expected/crypt-des.out | 4 ++++ + contrib/pgcrypto/expected/crypt-xdes.out | 24 ++++++++++++++++++++++++ + contrib/pgcrypto/px-crypt.c | 2 +- + contrib/pgcrypto/sql/crypt-blowfish.sql | 9 +++++++++ + contrib/pgcrypto/sql/crypt-des.sql | 4 ++++ + contrib/pgcrypto/sql/crypt-xdes.sql | 16 ++++++++++++++++ + 9 files changed, 103 insertions(+), 6 deletions(-) + +diff --git a/contrib/pgcrypto/crypt-blowfish.c b/contrib/pgcrypto/crypt-blowfish.c +index fbaa3d7..4054e6a 100644 +--- a/contrib/pgcrypto/crypt-blowfish.c ++++ b/contrib/pgcrypto/crypt-blowfish.c +@@ -601,6 +601,17 @@ _crypt_blowfish_rn(const char *key, const char *setting, + if (size < 7 + 22 + 31 + 1) + return NULL; + ++ /* ++ * Blowfish salt value must be formatted as follows: "$2a$" or "$2x$", a ++ * two digit cost parameter, "$", and 22 digits from the alphabet ++ * "./0-9A-Za-z". -- from the PHP crypt docs. Apparently we enforce a few ++ * more restrictions on the count in the salt as well. ++ */ ++ if (strlen(setting) < 29) ++ ereport(ERROR, ++ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ++ errmsg("invalid salt"))); ++ + if (setting[0] != '$' || + setting[1] != '2' || + (setting[2] != 'a' && setting[2] != 'x') || +@@ -610,14 +621,18 @@ _crypt_blowfish_rn(const char *key, const char *setting, + (setting[4] == '3' && setting[5] > '1') || + setting[6] != '$') + { +- return NULL; ++ ereport(ERROR, ++ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ++ errmsg("invalid salt"))); + } + + count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); + if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) + { + memset(data.binary.salt, 0, sizeof(data.binary.salt)); +- return NULL; ++ ereport(ERROR, ++ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ++ errmsg("invalid salt"))); + } + BF_swap(data.binary.salt, 4); + +diff --git a/contrib/pgcrypto/crypt-des.c b/contrib/pgcrypto/crypt-des.c +index 4ed44be..2108be8 100644 +--- a/contrib/pgcrypto/crypt-des.c ++++ b/contrib/pgcrypto/crypt-des.c +@@ -681,9 +681,19 @@ px_crypt_des(const char *key, const char *setting) + if (*setting == _PASSWORD_EFMT1) + { + /* +- * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of +- * salt key - unlimited characters ++ * "new"-style: setting must be a 9-character (underscore, then 4 ++ * bytes of count, then 4 bytes of salt) string. See CRYPT(3) under ++ * the "Extended crypt" heading for further details. ++ * ++ * Unlimited characters of the input key are used. This is known as ++ * the "Extended crypt" DES method. ++ * + */ ++ if (strlen(setting) < 9) ++ ereport(ERROR, ++ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ++ errmsg("invalid salt"))); ++ + for (i = 1, count = 0L; i < 5; i++) + count |= ascii_to_bin(setting[i]) << (i - 1) * 6; + +@@ -723,10 +733,16 @@ px_crypt_des(const char *key, const char *setting) + #endif /* !DISABLE_XDES */ + { + /* +- * "old"-style: setting - 2 bytes of salt key - up to 8 characters ++ * "old"-style: setting - 2 bytes of salt key - only up to the first 8 ++ * characters of the input key are used. + */ + count = 25; + ++ if (strlen(setting) < 2) ++ ereport(ERROR, ++ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ++ errmsg("invalid salt"))); ++ + salt = (ascii_to_bin(setting[1]) << 6) + | ascii_to_bin(setting[0]); + +diff --git a/contrib/pgcrypto/expected/crypt-blowfish.out b/contrib/pgcrypto/expected/crypt-blowfish.out +index 329d78f..d79b0c0 100644 +--- a/contrib/pgcrypto/expected/crypt-blowfish.out ++++ b/contrib/pgcrypto/expected/crypt-blowfish.out +@@ -13,6 +13,15 @@ SELECT crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); + $2a$06$RQiOJ.3ELirrXwxIZY8q0OR3CVJrAfda1z26CCHPnB6mmVZD8p0/C + (1 row) + ++-- error, salt too short: ++SELECT crypt('foox', '$2a$'); ++ERROR: invalid salt ++-- error, first digit of count in salt invalid ++SELECT crypt('foox', '$2a$40$RQiOJ.3ELirrXwxIZY8q0O'); ++ERROR: invalid salt ++-- error, count in salt too small ++SELECT crypt('foox', '$2a$00$RQiOJ.3ELirrXwxIZY8q0O'); ++ERROR: invalid salt + CREATE TABLE ctest (data text, res text, salt text); + INSERT INTO ctest VALUES ('password', '', ''); + UPDATE ctest SET salt = gen_salt('bf', 8); +diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out +index b8b6050..a462dcd 100644 +--- a/contrib/pgcrypto/expected/crypt-des.out ++++ b/contrib/pgcrypto/expected/crypt-des.out +@@ -13,6 +13,10 @@ SELECT crypt('foox', 'NB'); + NB53EGGqrrb5E + (1 row) + ++-- We are supposed to pass in a 2-character salt. ++-- error since salt is too short: ++SELECT crypt('password', 'a'); ++ERROR: invalid salt + CREATE TABLE ctest (data text, res text, salt text); + INSERT INTO ctest VALUES ('password', '', ''); + UPDATE ctest SET salt = gen_salt('des'); +diff --git a/contrib/pgcrypto/expected/crypt-xdes.out b/contrib/pgcrypto/expected/crypt-xdes.out +index cdcdefb..8cf9075 100644 +--- a/contrib/pgcrypto/expected/crypt-xdes.out ++++ b/contrib/pgcrypto/expected/crypt-xdes.out +@@ -13,6 +13,30 @@ SELECT crypt('foox', '_J9..j2zz'); + _J9..j2zzAYKMvO2BYRY + (1 row) + ++-- check XDES handling of keys longer than 8 chars ++SELECT crypt('longlongpassword', '_J9..j2zz'); ++ crypt ++---------------------- ++ _J9..j2zz4BeseiQNwUg ++(1 row) ++ ++-- error, salt too short ++SELECT crypt('foox', '_J9..BWH'); ++ERROR: invalid salt ++-- error, count specified in the second argument is 0 ++SELECT crypt('password', '_........'); ++ERROR: crypt(3) returned NULL ++-- error, count will wind up still being 0 due to invalid encoding ++-- of the count: only chars ``./0-9A-Za-z' are valid ++SELECT crypt('password', '_..!!!!!!'); ++ERROR: crypt(3) returned NULL ++-- count should be non-zero here, will work ++SELECT crypt('password', '_/!!!!!!!'); ++ crypt ++---------------------- ++ _/!!!!!!!zqM49hRzxko ++(1 row) ++ + CREATE TABLE ctest (data text, res text, salt text); + INSERT INTO ctest VALUES ('password', '', ''); + UPDATE ctest SET salt = gen_salt('xdes', 1001); +diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c +index 7b003a7..e3246fc 100644 +--- a/contrib/pgcrypto/px-crypt.c ++++ b/contrib/pgcrypto/px-crypt.c +@@ -42,7 +42,7 @@ run_crypt_des(const char *psw, const char *salt, + char *res; + + res = px_crypt_des(psw, salt); +- if (strlen(res) > len - 1) ++ if (res == NULL || strlen(res) > len - 1) + return NULL; + strcpy(buf, res); + return buf; +diff --git a/contrib/pgcrypto/sql/crypt-blowfish.sql b/contrib/pgcrypto/sql/crypt-blowfish.sql +index 60c1140..3b5a681 100644 +--- a/contrib/pgcrypto/sql/crypt-blowfish.sql ++++ b/contrib/pgcrypto/sql/crypt-blowfish.sql +@@ -6,6 +6,15 @@ SELECT crypt('', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); + + SELECT crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); + ++-- error, salt too short: ++SELECT crypt('foox', '$2a$'); ++ ++-- error, first digit of count in salt invalid ++SELECT crypt('foox', '$2a$40$RQiOJ.3ELirrXwxIZY8q0O'); ++ ++-- error, count in salt too small ++SELECT crypt('foox', '$2a$00$RQiOJ.3ELirrXwxIZY8q0O'); ++ + CREATE TABLE ctest (data text, res text, salt text); + INSERT INTO ctest VALUES ('password', '', ''); + +diff --git a/contrib/pgcrypto/sql/crypt-des.sql b/contrib/pgcrypto/sql/crypt-des.sql +index fabdc65..a85ec1e 100644 +--- a/contrib/pgcrypto/sql/crypt-des.sql ++++ b/contrib/pgcrypto/sql/crypt-des.sql +@@ -6,6 +6,10 @@ SELECT crypt('', 'NB'); + + SELECT crypt('foox', 'NB'); + ++-- We are supposed to pass in a 2-character salt. ++-- error since salt is too short: ++SELECT crypt('password', 'a'); ++ + CREATE TABLE ctest (data text, res text, salt text); + INSERT INTO ctest VALUES ('password', '', ''); + +diff --git a/contrib/pgcrypto/sql/crypt-xdes.sql b/contrib/pgcrypto/sql/crypt-xdes.sql +index d4a74f7..8171cd8 100644 +--- a/contrib/pgcrypto/sql/crypt-xdes.sql ++++ b/contrib/pgcrypto/sql/crypt-xdes.sql +@@ -6,6 +6,22 @@ SELECT crypt('', '_J9..j2zz'); + + SELECT crypt('foox', '_J9..j2zz'); + ++-- check XDES handling of keys longer than 8 chars ++SELECT crypt('longlongpassword', '_J9..j2zz'); ++ ++-- error, salt too short ++SELECT crypt('foox', '_J9..BWH'); ++ ++-- error, count specified in the second argument is 0 ++SELECT crypt('password', '_........'); ++ ++-- error, count will wind up still being 0 due to invalid encoding ++-- of the count: only chars ``./0-9A-Za-z' are valid ++SELECT crypt('password', '_..!!!!!!'); ++ ++-- count should be non-zero here, will work ++SELECT crypt('password', '_/!!!!!!!'); ++ + CREATE TABLE ctest (data text, res text, salt text); + INSERT INTO ctest VALUES ('password', '', ''); + +-- +1.7.9.5 + diff --git a/support/postgresql/files/0002-Prevent-stack-overflow-in-json-related-functions.patch b/support/postgresql/files/0002-Prevent-stack-overflow-in-json-related-functions.patch new file mode 100644 index 000000000..750988ff3 --- /dev/null +++ b/support/postgresql/files/0002-Prevent-stack-overflow-in-json-related-functions.patch @@ -0,0 +1,44 @@ +From 8dacb29ca7c92814d69135f40e16a46f8cf9cbaf Mon Sep 17 00:00:00 2001 +From: Noah Misch +Date: Mon, 5 Oct 2015 10:06:29 -0400 +Subject: [PATCH 2/2] Prevent stack overflow in json-related functions. + +Sufficiently-deep recursion heretofore elicited a SIGSEGV. If an +application constructs PostgreSQL json or jsonb values from arbitrary +user input, application users could have exploited this to terminate all +active database connections. That applies to 9.3, where the json parser +adopted recursive descent, and later versions. Only row_to_json() and +array_to_json() were at risk in 9.2, both in a non-security capacity. +Back-patch to 9.2, where the json type was introduced. + +Oskari Saarenmaa, reviewed by Michael Paquier. + +Security: CVE-2015-5289 +--- + src/backend/utils/adt/json.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c +index f0cbb39..fd1d8fb 100644 +--- a/src/backend/utils/adt/json.c ++++ b/src/backend/utils/adt/json.c +@@ -18,6 +18,7 @@ + #include "lib/stringinfo.h" + #include "libpq/pqformat.h" + #include "mb/pg_wchar.h" ++#include "miscadmin.h" + #include "parser/parse_coerce.h" + #include "utils/array.h" + #include "utils/builtins.h" +@@ -895,6 +896,8 @@ datum_to_json(Datum val, bool is_null, StringInfo result, + bool numeric_error; + JsonLexContext dummy_lex; + ++ check_stack_depth(); ++ + if (is_null) + { + appendStringInfoString(result, "null"); +-- +1.7.9.5 + diff --git a/support/tgt/centos/build_srpm.data b/support/tgt/centos/build_srpm.data new file mode 100644 index 000000000..f56f69c16 --- /dev/null +++ b/support/tgt/centos/build_srpm.data @@ -0,0 +1,2 @@ +COPY_LIST="$DISTRO/files/*" +TIS_PATCH_VER=2 diff --git a/support/tgt/centos/files/tgtd.init b/support/tgt/centos/files/tgtd.init new file mode 100644 index 000000000..d221eeb5d --- /dev/null +++ b/support/tgt/centos/files/tgtd.init @@ -0,0 +1,156 @@ +#!/bin/sh +# +# Copyright (c) 2013-2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +### BEGIN INIT INFO +# Provides: tgtd +# Required-Start: $remote_fs $network $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: +# Default-Stop: +# Short-Description: SCSI target daemon +# Description: Linux SCSI target framework (tgt) +### END INIT INFO + +DESC="tgtd" +DAEMON="/usr/sbin/tgtd" +TGTD_CONFIG=/etc/tgt/targets.conf + +start () +{ + echo -n "Starting $DESC..." + tgt-admin -s >/dev/null 2>&1 + RETVAL=$? + if [ "$RETVAL" -ne 107 ] ; then + echo "$DESC is already running" + # Ensure tgtd is in the "ready" state. Handles the case where the + # init script was killed while tgtd was offline. + tgtadm --op update --mode sys --name State -v ready + exit 0 + fi + + # Start tgtd first + $DAEMON &>/dev/null + RETVAL=$? + if [ "$RETVAL" -ne 0 ]; then + echo "failed." + exit 1 + fi + + # Put tgtd into "offline" state until all the targets are configured. + # We don't want initiators to (re)connect and fail the connection + # if it's not ready. + tgtadm --op update --mode sys --name State -v offline + # Configure the targets. + tgt-admin -e -c $TGTD_CONFIG + # Put tgtd into "ready" state. + tgtadm --op update --mode sys --name State -v ready + + echo "done." +} + +stop () +{ + echo -n "Stopping $DESC..." + + # Remove all targets. It only removes targets which are not in use. + tgt-admin --update ALL -c /dev/null &>/dev/null + # tgtd will exit if all targets were removed + tgtadm --op delete --mode system &>/dev/null + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + exit 0 + elif [ "$RETVAL" -ne 0 ] ; then + echo "Some initiators are still connected - could not stop $DESC" + exit 2 + fi + echo -n +} + +forcedstop() +{ + # NOTE: Forced shutdown of the iscsi target may cause data corruption + # for initiators that are connected. + echo -n "Force stopping $DESC..." + + # Offline everything first. May be needed if we're rebooting, but + # expect the initiators to reconnect cleanly when we boot again + # (i.e. we don't want them to reconnect to a tgtd which is still + # working, but the target is gone). + tgtadm --op update --mode sys --name State -v offline &>/dev/null + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + exit 0 + else + tgt-admin --offline ALL + # Remove all targets, even if they are still in use. + tgt-admin --update ALL -c /dev/null -f + # It will shut down tgtd only after all targets were removed. + tgtadm --op delete --mode system + RETVAL=$? + if [ "$RETVAL" -ne 0 ] ; then + echo "Failed to shutdown $DESC" + exit 1 + fi + fi + echo -n +} + +reload() +{ + echo "Reloading configuration of $DESC" "$NAME" + # Update configuration for targets. Only targets which + # are not in use will be updated. + tgt-admin --update ALL -c $TGTD_CONFIG &>/dev/null + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + exit 1 + fi +} + +status() +{ + tgt-admin -s >/dev/null 2>&1 + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + # For lsb compliance... + exit 3 + else + echo "$DESC is running" + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + forcedstop) + forcedstop + ;; + restart|force-reload) + stop + start + ;; + reload) + reload + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|forcedstop|force-reload|restart|status|reload}" + exit 1 + ;; +esac + +exit 0 diff --git a/support/tgt/centos/files/tgtd.service b/support/tgt/centos/files/tgtd.service new file mode 100644 index 000000000..04c3a026a --- /dev/null +++ b/support/tgt/centos/files/tgtd.service @@ -0,0 +1,13 @@ +[Unit] +Description=tgtd iSCSI target daemon +After=network.target + +[Service] +Type=forking +ExecStart=/etc/init.d/tgtd start +ExecStop=/etc/init.d/tgtd stop +ExecReload=/etc/init.d/tgtd reload +#RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/support/tgt/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/support/tgt/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch new file mode 100644 index 000000000..c05fe5fd7 --- /dev/null +++ b/support/tgt/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch @@ -0,0 +1,25 @@ +From 61010c2ba23abfa0e69ab884f3fff0c252544c8b Mon Sep 17 00:00:00 2001 +From: Don Penney +Date: Tue, 27 Sep 2016 11:00:04 -0400 +Subject: [PATCH] Update package versioning for TIS format + +--- + SPECS/scsi-target-utils.spec | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/SPECS/scsi-target-utils.spec b/SPECS/scsi-target-utils.spec +index c97ada4..1778e8f 100644 +--- a/SPECS/scsi-target-utils.spec ++++ b/SPECS/scsi-target-utils.spec +@@ -14,7 +14,7 @@ + + Name: scsi-target-utils + Version: 1.0.55 +-Release: 4%{?dist} ++Release: 4.el7%{?_tis_dist}.%{tis_patch_ver} + Summary: The SCSI target daemon and utility programs + + Group: System Environment/Daemons +-- +1.8.3.1 + diff --git a/support/tgt/centos/meta_patches/PATCH_ORDER b/support/tgt/centos/meta_patches/PATCH_ORDER new file mode 100644 index 000000000..bfcf5e008 --- /dev/null +++ b/support/tgt/centos/meta_patches/PATCH_ORDER @@ -0,0 +1,2 @@ +spec-to-use-custom-startup-script.patch +0001-Update-package-versioning-for-TIS-format.patch diff --git a/support/tgt/centos/meta_patches/spec-to-use-custom-startup-script.patch b/support/tgt/centos/meta_patches/spec-to-use-custom-startup-script.patch new file mode 100644 index 000000000..f34ac4ef9 --- /dev/null +++ b/support/tgt/centos/meta_patches/spec-to-use-custom-startup-script.patch @@ -0,0 +1,44 @@ +scsi-target-utils: to use custom startup script + +CGCS has custom systemv startup script. This patch enables spec file to +to use CGCS custom startup script. Also puppet packstack expects the +original /etc/tgt/targets.conf file (not from fedora distro), so change +spec file to use the original targets.conf instead. + +diff --git a/tmp/scsi-target-utils.spec.org b/SPECS/scsi-target-utils.spec +index 4f134de..5394c3a 100644 +--- a/tmp/scsi-target-utils.spec.org ++++ b/SPECS/scsi-target-utils.spec +@@ -26,6 +26,7 @@ Source2: sysconfig.tgtd + Source3: targets.conf + Source4: sample.conf + Source5: tgtd.conf ++Source6: tgtd.init + Patch0: 0001-redhatify-docs.patch + Patch1: 0002-remove-check-for-xsltproc.patch + Patch2: 0003-default-config.patch +@@ -99,9 +100,11 @@ Adds support for the Gluster glfs backstore to scsi-target-utils. + %{__install} -p -m 0644 doc/manpages/tgt-admin.8 %{buildroot}/%{_mandir}/man8 + %{__install} -p -m 0644 doc/manpages/tgt-setup-lun.8 %{buildroot}/%{_mandir}/man8 + %{__install} -p -m 0600 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/tgtd +-%{__install} -p -m 0600 %{SOURCE3} %{buildroot}%{_sysconfdir}/tgt ++%{__install} -p -m 0600 conf/targets.conf %{buildroot}%{_sysconfdir}/tgt + %{__install} -p -m 0600 %{SOURCE4} %{buildroot}%{_sysconfdir}/tgt/conf.d +-%{__install} -p -m 0600 %{SOURCE5} %{buildroot}%{_sysconfdir}/tgt ++#%{__install} -p -m 0600 %{SOURCE5} %{buildroot}%{_sysconfdir}/tgt ++mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d/ ++%{__install} -p -m 0755 %{SOURCE6} %{buildroot}%{_sysconfdir}/rc.d/init.d/tgtd + + pushd usr + %{__make} install %{?with_rdma:ISCSI_RDMA=1} %{?with_rbd:CEPH_RBD=1} %{?with_glfs:GLFS_BD=1} SD_NOTIFY=1 DESTDIR=%{buildroot} sbindir=%{_sbindir} libdir=%{_libdir}/tgt +@@ -132,8 +135,9 @@ pushd usr + %{_unitdir}/tgtd.service + %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sysconfig/tgtd + %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/tgt/targets.conf +-%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/tgt/tgtd.conf ++#%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/tgt/tgtd.conf + %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/tgt/conf.d/sample.conf ++%attr(-,root,root) %{_sysconfdir}/rc.d/init.d/tgtd + + %if 0%{?with_rbd} + %files rbd diff --git a/support/tgt/centos/srpm_path b/support/tgt/centos/srpm_path new file mode 100644 index 000000000..694a9db57 --- /dev/null +++ b/support/tgt/centos/srpm_path @@ -0,0 +1 @@ +mirror:Source/scsi-target-utils-1.0.55-4.el7.src.rpm diff --git a/support/tgt/files/0001-usr-Makefile-WARNING-fix.patch b/support/tgt/files/0001-usr-Makefile-WARNING-fix.patch new file mode 100644 index 000000000..15f54820f --- /dev/null +++ b/support/tgt/files/0001-usr-Makefile-WARNING-fix.patch @@ -0,0 +1,31 @@ +From 2a336ec5bf939d86425570617471df60140d839e Mon Sep 17 00:00:00 2001 +From: Li xin +Date: Sun, 26 Jul 2015 04:23:51 +0900 +Subject: [PATCH] usr/Makefile: WARNING fix WARNING: QA Issue: tgt: + /work/i586-oe-linux/tgt/1.0.60+gitAUTOINC+ab51727a36-r0/ + packages-split/tgt/usr/sbin/tgtd contains probably-redundant RPATH /usr/lib + [useless-rpaths] + +Upstream-Status: pending + +Signed-off-by: Li Xin +--- + usr/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/usr/Makefile b/usr/Makefile +index 1fae7e7..2db109c 100644 +--- a/usr/Makefile ++++ b/usr/Makefile +@@ -63,7 +63,7 @@ TGTD_OBJS += tgtd.o mgmt.o target.o scsi.o log.o driver.o util.o work.o \ + + TGTD_DEP = $(TGTD_OBJS:.o=.d) + +-LDFLAGS = -Wl,-E,-rpath=$(libdir) ++LDFLAGS = -Wl,-E + + .PHONY:all + all: $(PROGRAMS) $(MODULES) +-- +1.8.4.2 + diff --git a/support/tgt/files/tgtd.init b/support/tgt/files/tgtd.init new file mode 100644 index 000000000..466c27413 --- /dev/null +++ b/support/tgt/files/tgtd.init @@ -0,0 +1,156 @@ +#!/bin/sh +# +# Copyright (c) 2013-2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +### BEGIN INIT INFO +# Provides: tgtd +# Required-Start: $remote_fs $network $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +# Short-Description: SCSI target daemon +# Description: Linux SCSI target framework (tgt) +### END INIT INFO + +DESC="tgtd" +DAEMON="/usr/sbin/tgtd" +TGTD_CONFIG=/etc/tgt/targets.conf + +start () +{ + echo -n "Starting $DESC..." + tgt-admin -s >/dev/null 2>&1 + RETVAL=$? + if [ "$RETVAL" -ne 107 ] ; then + echo "$DESC is already running" + # Ensure tgtd is in the "ready" state. Handles the case where the + # init script was killed while tgtd was offline. + tgtadm --op update --mode sys --name State -v ready + exit 0 + fi + + # Start tgtd first + $DAEMON &>/dev/null + RETVAL=$? + if [ "$RETVAL" -ne 0 ]; then + echo "failed." + exit 1 + fi + + # Put tgtd into "offline" state until all the targets are configured. + # We don't want initiators to (re)connect and fail the connection + # if it's not ready. + tgtadm --op update --mode sys --name State -v offline + # Configure the targets. + tgt-admin -e -c $TGTD_CONFIG + # Put tgtd into "ready" state. + tgtadm --op update --mode sys --name State -v ready + + echo "done." +} + +stop () +{ + echo -n "Stopping $DESC..." + + # Remove all targets. It only removes targets which are not in use. + tgt-admin --update ALL -c /dev/null &>/dev/null + # tgtd will exit if all targets were removed + tgtadm --op delete --mode system &>/dev/null + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + exit 0 + elif [ "$RETVAL" -ne 0 ] ; then + echo "Some initiators are still connected - could not stop $DESC" + exit 2 + fi + echo -n +} + +forcedstop() +{ + # NOTE: Forced shutdown of the iscsi target may cause data corruption + # for initiators that are connected. + echo -n "Force stopping $DESC..." + + # Offline everything first. May be needed if we're rebooting, but + # expect the initiators to reconnect cleanly when we boot again + # (i.e. we don't want them to reconnect to a tgtd which is still + # working, but the target is gone). + tgtadm --op update --mode sys --name State -v offline &>/dev/null + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + exit 0 + else + tgt-admin --offline ALL + # Remove all targets, even if they are still in use. + tgt-admin --update ALL -c /dev/null -f + # It will shut down tgtd only after all targets were removed. + tgtadm --op delete --mode system + RETVAL=$? + if [ "$RETVAL" -ne 0 ] ; then + echo "Failed to shutdown $DESC" + exit 1 + fi + fi + echo -n +} + +reload() +{ + echo "Reloading configuration of $DESC" "$NAME" + # Update configuration for targets. Only targets which + # are not in use will be updated. + tgt-admin --update ALL -c $TGTD_CONFIG &>/dev/null + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + exit 1 + fi +} + +status() +{ + tgt-admin -s >/dev/null 2>&1 + RETVAL=$? + if [ "$RETVAL" -eq 107 ] ; then + echo "$DESC is not running" + # For lsb compliance... + exit 3 + else + echo "$DESC is running" + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + forcedstop) + forcedstop + ;; + restart|force-reload) + stop + start + ;; + reload) + reload + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|forcedstop|force-reload|restart|status|reload}" + exit 1 + ;; +esac + +exit 0 diff --git a/vm-topology/centos/build_srpm.data b/vm-topology/centos/build_srpm.data new file mode 100644 index 000000000..0b28ab0c3 --- /dev/null +++ b/vm-topology/centos/build_srpm.data @@ -0,0 +1,4 @@ +PACKAGE_NAME=vm-topology +VERSION=1.0 +SRC_DIR=$PKG_BASE/$PACKAGE_NAME +TIS_PATCH_VER=1 diff --git a/vm-topology/centos/vm-topology.spec b/vm-topology/centos/vm-topology.spec new file mode 100644 index 000000000..236825652 --- /dev/null +++ b/vm-topology/centos/vm-topology.spec @@ -0,0 +1,49 @@ +%global pypi_name vm-topology + +Summary: vm_topology +Name: vm-topology +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: Wind River + +URL: unknown +Source0: %{pypi_name}-%{version}.tar.gz + +BuildArch: noarch + +BuildRequires: python +BuildRequires: python-setuptools +BuildRequires: python-keyring +BuildRequires: libvirt + +Requires: python +Requires: python-keyring +Requires: /usr/bin/env +Requires: libvirt + +%description +Show compute resources and VM topology + +%prep +%autosetup -p 1 -n %{pypi_name}-%{version} +# Remove bundled egg-info +rm -rf %{pypi_name}.egg-info +# Let RPM handle the dependencies +rm -f requirements.txt + +%build +%{__python2} setup.py build + +%install +%{__python2} setup.py install --skip-build --root %{buildroot} + + +%files +%defattr(-,root,root,-) +%license LICENSE +%{_bindir}/vm-topology +%{python2_sitelib}/vm_topology +%{python2_sitelib}/*.egg-info + diff --git a/vm-topology/vm-topology/LICENSE b/vm-topology/vm-topology/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vm-topology/vm-topology/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vm-topology/vm-topology/setup.py b/vm-topology/vm-topology/setup.py new file mode 100644 index 000000000..0b0a5a26f --- /dev/null +++ b/vm-topology/vm-topology/setup.py @@ -0,0 +1,19 @@ +# +# Copyright (c) 2013-2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import setuptools + +setuptools.setup( + name='vm_topology', + description='Show compute resources and VM topology', + version='1.0.0', + license='Apache-2.0', + packages=['vm_topology', 'vm_topology.exec'], + entry_points={ + 'console_scripts': [ + 'vm-topology = vm_topology.exec.vm_topology:main', + ]} +) diff --git a/vm-topology/vm-topology/vm_topology/__init__.py b/vm-topology/vm-topology/vm_topology/__init__.py new file mode 100644 index 000000000..147b74f99 --- /dev/null +++ b/vm-topology/vm-topology/vm_topology/__init__.py @@ -0,0 +1,5 @@ +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# diff --git a/vm-topology/vm-topology/vm_topology/exec/__init__.py b/vm-topology/vm-topology/vm_topology/exec/__init__.py new file mode 100644 index 000000000..147b74f99 --- /dev/null +++ b/vm-topology/vm-topology/vm_topology/exec/__init__.py @@ -0,0 +1,5 @@ +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# diff --git a/vm-topology/vm-topology/vm_topology/exec/vm_topology.py b/vm-topology/vm-topology/vm_topology/exec/vm_topology.py new file mode 100644 index 000000000..3dbb32a7b --- /dev/null +++ b/vm-topology/vm-topology/vm_topology/exec/vm_topology.py @@ -0,0 +1,2159 @@ +# +# Copyright (c) 2014-2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +""" +usage: vm-topology [-h] + [-s ] + +Tool to summarize server resource usage and vcpu placement +related attributes for nova and libvirt. + +Details: +- shows nova view of server attributes including extended resources: + - project, compute host, server name, libvirt name, image name, flavor + - vm status, task state, power state, uptime + - pinning, numa nodes, cpuset, cpulists, server groups +- shows nova view of compute resource usage, aggregates +- shows libvirt view of servers, running state +- shows migrations in-progress +- shows flavors used +- shows images used +""" + +import argparse +import datetime +import copy +import libvirt +import logging +from itertools import groupby +import multiprocessing +import os +import pprint +from prettytable import PrettyTable +import psutil +import re +import sys +import signal +import textwrap +import time + +from cinderclient import client as cinder_client +from glanceclient import client as glance_client +from keystoneclient.auth.identity import v3 as keystone_identity +from keystoneclient.v3 import client as keystone_client +from keystoneauth1 import loading as keystone +from keystoneauth1 import session +from novaclient import client as nova_client +from novaclient.v2 import migrations + +from oslo_serialization import jsonutils + +from sqlalchemy.ext.automap import automap_base +from sqlalchemy import create_engine +from sqlalchemy import MetaData +from sqlalchemy.sql import select + +from xml.dom import minidom +from xml.etree import ElementTree + +NOVACONF = '/etc/nova/nova.conf' +AUTHTOKEN_GROUP = 'keystone_authtoken' +NOVACLIENT_VERSION = '2.25' +CINDERCLIENT_VERSION = '2' + +# NOTE: Old glanceclient version 1 gives access to image properties +GLANCECLIENT_VERSION = '1' + +from keystonemiddleware.auth_token import _opts as keystone_auth_token_opts +from oslo_config import cfg +from oslo_config import types + +CONF = cfg.CONF + +"""---------------------------------------------------------------------------- +Global definitions +----------------------------------------------------------------------------""" + +# logger +logger = logging.getLogger(__name__) +logging.getLogger('multiprocessing').setLevel(logging.CRITICAL) +logging.getLogger('sqlalchemy.engine').setLevel(logging.CRITICAL) + +# debug and show options +debug = {} +show = {} + +# Constants +Ki = 1024 +Mi = Ki*Ki + +# Active worker pids +active_pids = multiprocessing.Manager().dict() + +# libvirt timeout parameters +LIBVIRT_TIMEOUT_SEC = 5.0 +LIBVIRT_REAP_SEC = LIBVIRT_TIMEOUT_SEC + 2.0 + +############################################################################### +## Subroutines +############################################################################### + + +# Define a context manager to suppress stdout and stderr. +class suppress_stdout_stderr(object): + ''' + A context manager for doing a "deep suppression" of stdout and stderr in + Python, i.e. will suppress all print, even if the print originates in a + compiled C/Fortran sub-function. + This will not suppress raised exceptions, since exceptions are printed + to stderr just before a script exits, and after the context manager has + exited (at least, I think that is why it lets exceptions through). + ''' + def __init__(self): + # Open a pair of null files + self.null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)] + # Save the actual stdout (1) and stderr (2) file descriptors. + self.save_fds = (os.dup(1), os.dup(2)) + + def __enter__(self): + # Assign the null pointers to stdout and stderr. + os.dup2(self.null_fds[0], 1) + os.dup2(self.null_fds[1], 2) + + def __exit__(self, *_): + # Re-assign the real stdout/stderr back to (1) and (2) + os.dup2(self.save_fds[0], 1) + os.dup2(self.save_fds[1], 2) + # Close the null files + os.close(self.null_fds[0]) + os.close(self.null_fds[1]) + + +def atoi(text): + return int(text) if text.isdigit() else text + + +def natural_keys(text): + ''' + alist.sort(key=natural_keys) sorts in human order + ''' + return [atoi(c) for c in re.split('(\d+)', text)] + + +def help_text_epilog(): + text = textwrap.dedent('''\ + Tables and Field descriptions: + ------------------------------ + + COMPUTE HOSTS: Legend: U = Used, A = Avail + Host - compute host name + status - host operational status + model - processor model + topology - processor cpu topology (sockets, cores, threads) + servers - number of servers + node - physical processor node (a.k.a., numa node) + pcpus - physical vcpus per numa node (avail to libvirt) + U:dedicated - used dedicated vcpus (a.k.a., pinned) + U:shared - used shared vcpus (a.k.a., float) + memory - host memory (MiB) available for libvirt + U:memory - used memory for servers (MiB) + A:mem_4K - available 4K host memory for servers (MiB) + A:mem_2M - available 2M host memory for servers (MiB) + A:mem_1G - available 1G host memory for servers (MiB) + Aggregate - list of host aggregate names + + Note: + - rows similar to 'nova hypervisor-show ' + - last row similar to 'nova hypervisor-stats' + + LOGICAL CPU TOPOLOGY (compute hosts): + cpu_id - logical cpu id + socket_id - socket id (a.k.a., processor node, numa node) + core_id - physical core id on a given socket_id + thread_id - hyperthread (SMT) index of a given core_id + sibling_id - hyperthread sibling cpu_id(s) (excludes cpu_id) + + SERVERS (nova view): + tenant - server tenant name (a.k.a. project) + ID - server uuid + instance_name - server libvirt name + name - server name + host - server host + vm_state - server vm state + task_state - server task state + power_state - server power state + image - server image name (or image volume booted from) + flavor - server flavor name + vcpus - server number of vcpus (scaling: min, cur, max) + memory - server memory (MiB) + instance_topology - server numa topology + (dedicated vs shared, pgsize, + mapping of vpus, pcpus, shared_vcpu, sibings) + in_libvirt - indicates server also seen in libvirt + + SERVERS (libvirt view): + uuid - server uuid + instance_name - server libvirt name + host - server host + id - server libvirt id + state - server libvirt state + vcpus - server number of vcpus + memory - server memory (MiB) + nodelist - server list of numa nodes + cpulist - server list of pcpu[i] for each vcpu i + in_nova - indicates server also seen in nova + + MIGRATIONS (in progress): Legend: S=Source, D=Destination + ID - server uuid + status - migration status + S:node - source node + D:node - destination node + S:compute - source compute + D:compute - destination compute + S:flavor[PKey] - source flavor primary key id + D:flavor[PKey] - destination flavor primary key id + created_at - timestamp of migration + + FLAVORS (in use): + id - flavor_id + name - flavor name + vcpus - number of vcpus + ram - memory (MiB) + disk - disk stgorage (GB) + ephemeral - ephemeral storage (GB) + swap - swap size (MiB) + rxtx_factor - RX/TX factor (default 1) + is_public - make flavor accessible to the public (default true) + extra_specs - metadata containing key=value pairs + + IMAGES (in use): + id - image id + name - image name + minDisk - minimum size of disk to boot image (GB) + minRam - minimum size of ram to boot image (MB) + size - image data size (MB) + status - image status + properties - metadata containing key=value pairs + + SERVER GROUPS (in use): + tenant - server tenant name (a.k.a., project) + id - server group uuid + name - server group name + policies - server group policies + metadata - metadata containing key=value pairs + ''') + return text + + +class ChoiceOpt(cfg.Opt): + r"""Option with List(String) type + Option with ``type`` :class:`oslo_config.types.List` + :param name: the option's name + :param choices: Optional sequence of either valid values or tuples of valid + values with descriptions. + :param bounds: if True the value should be inside "[" and "]" pair + :param \*\*kwargs: arbitrary keyword arguments passed to :class:`Opt` + .. versionchanged:: 2.5 + Added *item_type* and *bounds* parameters. + """ + + def __init__(self, name, choices=None, bounds=None, **kwargs): + type = types.List(item_type=types.String(choices=choices), bounds=bounds) + super(ChoiceOpt, self).__init__(name, type=type, **kwargs) + + +def parse_arguments(debug, show): + """ + Parse command line arguments. + """ + + # Initialize all debug flags to False + define_debug_flags(debug) + + # Initialized show option lists + (L_opts, L_brief, L_details, L_other) = define_options() + + # Select potentially multiple values from the following options + O = set([]) + O.update(L_brief) + O.update(L_details) + O.update(L_other) + S = sorted(O) + S[0:0] = L_opts + + # Enable debug option, but its usage/help is hidden. + D = debug.keys() + D.sort() + D.insert(0, 'all') + + # Parse arguments + cli_opts = [ + ChoiceOpt('show', + default=['brief'], + choices=sorted(list(set(S))), + metavar='<' + ','.join(str(x) for x in S) + '>', + help='Show summary of selected tables'), + ChoiceOpt('dbg', + default=[], + choices=sorted(list(set(D))), + metavar='<' + ','.join(str(x) for x in D) + '>', + help='Print debugging information for selected tables'), + ] + + CONF.register_cli_opts(cli_opts) + CONF.formatter_class = argparse.RawTextHelpFormatter + CONF(sys.argv[1:], + default_config_files=[NOVACONF], + prog=os.path.basename(sys.argv[0]), + description=( + 'Tool to summarize server resouce usage and vcpu placement' + 'related attributes for nova and libvirt.'), + # NOTE: oslo_config implementation of _CachedArgumentParser does not + # configure argparse formatter_class. The resulting epilog text is + # automatically text-wrapped which is not desired. Manually adding + # newlines does not work either. The epilog text is disabled for now. + #epilog=help_text_epilog(), + ) + + # Configure logging to appropriate level + level = logging.INFO + if CONF.dbg: + level = logging.DEBUG + configure_logging(logger, level=level) + + if CONF.dbg: + logger.debug('parse_args: debug=%r, show=%r' % (CONF.dbg, CONF.show)) + + # Flatten debug options list + L = list(set(CONF.dbg)) + + # Update debug options based on parsed options + {debug.update({e: True}) for e in L} + + # Enable all debug flags (except libvirt_xml) if 'all' is specified + x = debug['libvirt_xml'] + if debug['all']: + {debug.update({e: True}) for e in debug.keys()} + debug['libvirt_xml'] = x + + # Flatten show options list + L = list(set(CONF.show)) + if CONF.dbg: + L = [] + + # Update show options based on parsed options + define_option_flags(show, + options=L, + L_opts=L_opts, + L_brief=L_brief, + L_details=L_details, + L_other=L_other) + + +def configure_logging(logger, level=logging.DEBUG): + """ Configure logger streams and format. """ + logger.setLevel(level) + ch = logging.StreamHandler(sys.stdout) + ch.setLevel(level) + formatter = logging.Formatter( + '%(asctime)s %(process)s %(levelname)s %(module)s: %(message)s') + ch.setFormatter(formatter) + logger.addHandler(ch) + + +def _translate_keys(collection, convert): + """ For a collection of elements, translate _info field names + into human-readable names based on a list of conversion tuples. + """ + for k, item in collection.iteritems(): + keys = item.__dict__.keys() + for from_key, to_key in convert: + if from_key in keys and to_key not in keys: + try: + setattr(item, to_key, item._info[from_key]) + except AttributeError: + logger.error('_translate_keys: from_key:%r to_key:%r, ' + 'item._info[from_key]:%r' + % (from_key, to_key, item._info[from_key])) + + +def _translate_extended_states(collection): + """ Return human readable power-state string. """ + power_states = [ + 'NOSTATE', # 0x00 + 'Running', # 0x01 + '', # 0x02 + 'Paused', # 0x03 + 'Shutdown', # 0x04 + '', # 0x05 + 'Crashed', # 0x06 + 'Suspended' # 0x07 + ] + for k, item in collection.iteritems(): + try: + setattr(item, 'power_state', + power_states[getattr(item, 'power_state')]) + except AttributeError: + setattr(item, 'power_state', "N/A") + try: + getattr(item, 'task_state') + except AttributeError: + setattr(item, 'task_state', "N/A") + + +def _translate_virDomainState(state): + """ Return human readable virtual domain state string. """ + states = {} + states[0] = 'NOSTATE' + states[1] = 'Running' + states[2] = 'Blocked' + states[3] = 'Paused' + states[4] = 'Shutdown' + states[5] = 'Shutoff' + states[6] = 'Crashed' + states[7] = 'pmSuspended' + states[8] = 'Last' + return states[state] + + +def _translate_virVcpuState(state): + """ Return human readable virtual vpu state string. """ + states = {} + states[0] = 'Offline' + states[1] = 'Running' + states[2] = 'Blocked' + states[3] = 'Last' + return states[state] + + +def _mask_to_cpulist(mask=0): + """ Create cpulist from mask, list in socket-core-thread enumerated order. + + :param extended: extended info + :param mask: cpuset mask + :returns cpulist: list of cpus in socket-core-thread enumerated order + """ + cpulist = [] + if mask is None or mask <= 0: + return cpulist + + # Assume max number of cpus for now... + max_cpus = 128 + for cpu in xrange(max_cpus): + if ((1 << cpu) & mask): + cpulist.append(cpu) + return cpulist + + +def string_to_cpulist(cpus_str=''): + ''' Convert a string representation to cpulist + + :param cpus_str: string containing list cpus, eg., 1,2,6-7 + :returns cpulist + ''' + + # Create list of excluded cpus by parsing excluded_cpulist_str, + # example: 1,2,6-7 + cpulist = [] + re_digit = re.compile(r'^(\d+)$') + re_range = re.compile(r'^(\d+)-(\d+)$') + s = cpus_str.strip() + for ele in s.split(','): + match = re_digit.search(ele) + if match: + cpu = int(match.group(1)) + cpulist.append(cpu) + + match = re_range.search(ele) + if match: + cpu0 = int(match.group(1)) + cpu1 = int(match.group(2)) + if cpu1 > cpu0: + cpulist.extend(list(range(cpu0, cpu1 + 1))) + return cpulist + + +def list_to_range(L=[]): + """ Convert a list into a string of comma separate ranges. + E.g., [1,2,3,8,9,15] is converted to '1-3,8-9,15' + """ + G = (list(x) for _, x in groupby(enumerate(L), lambda (i, x): i - x)) + return ",".join( + "-".join(map(str, (g[0][1], g[-1][1])[:len(g)])) for g in G) + +def range_to_list(csv_range=None): + """ Convert a string of comma separate ranges into an expanded list of + integers. E.g., '1-3,8-9,15' is converted to [1,2,3,8,9,15] + """ + if not csv_range: + return [] + xranges = [(lambda L: xrange(L[0], L[-1] + 1))(map(int, r.split('-'))) + for r in csv_range.split(',')] + return [y for x in xranges for y in x] + + +class TimeoutError(Exception): + pass + + +def timeout_handler(signum, frame): + raise TimeoutError('timeout') + + +def libvirt_domain_info_worker((host)): + pid = os.getpid() + active_pids.update({pid: (host, time.time())}) + error = None + try: + (domain, topology) = do_libvirt_domain_info((host)) + except Exception as e: + domain = {} + topology = {} + error = 'cannot connect to libvirt: %s; %s' % (host, e) + del active_pids[pid] + return (host, domain, topology, time.time(), error) + + +def do_libvirt_domain_info((host)): + """ + Connect to libvirt for specified host, and retrieve per-domain information + including cpu affinity per vcpu. + """ + domains = {} + topology = {} + if not host: + return (domains, topology) + + # Connect to remote libvirt hypervisor + transport = 'tcp' + duri = "qemu+%s://%s/system" % (transport, host) + try: + signal.signal(signal.SIGALRM, timeout_handler) + signal.setitimer(signal.ITIMER_REAL, LIBVIRT_TIMEOUT_SEC) + with suppress_stdout_stderr(): + conn = libvirt.openReadOnly(duri) + signal.alarm(0) + except TimeoutError: + conn = None + raise + except Exception as e: + conn = None + raise + finally: + signal.alarm(0) + if conn is None: + return (domains, topology) + + # Get host capabilities (contains host topology) + caps_str = conn.getCapabilities() + doc = ElementTree.fromstring(caps_str) + caps = minidom.parseString(caps_str) + caps_host = caps.getElementsByTagName('host')[0] + caps_cells = caps_host.getElementsByTagName('cells')[0] + total_cpus = caps_cells.getElementsByTagName('cpu').length + + # Enumerate logical cpu topology using socket_id, core_id, thread_id + # indices. This generates the following dictionary: + # topology[socket_id][core_id][thread_id] = cpu_id + Thread_cnt = {} + topology = {} + cells = doc.findall('./host/topology/cells/cell') + for cell in cells: + cell_id = int(cell.get('id')) + for cpu in cell.findall('./cpus/cpu'): + # obtain core_id, cpu_id, and socket_id; ignore 'siblings' since + # that can be inferred by enumeration of thread_id. + core_id = int(cpu.get('core_id')) + cpu_id = int(cpu.get('id')) + socket_id = int(cpu.get('socket_id')) + + # thread_id's are enumerated assuming cpu_id is already sorted + if socket_id not in Thread_cnt: + Thread_cnt[socket_id] = {} + if core_id not in Thread_cnt[socket_id]: + Thread_cnt[socket_id][core_id] = 0 + else: + Thread_cnt[socket_id][core_id] += 1 + thread_id = Thread_cnt[socket_id][core_id] + + # save topology[socket_id][core_id][thread_id] + if socket_id not in topology: + topology[socket_id] = {} + if core_id not in topology[socket_id]: + topology[socket_id][core_id] = {} + topology[socket_id][core_id][thread_id] = cpu_id + + # Get domains (i.e., one per VM) + for dom in conn.listAllDomains(flags=0): + # Get overall domain info + d_name = dom.name() + d_id = dom.ID() + d_uuid = dom.UUIDString() + d_ostype = dom.OSType() + d_state, d_maxMem_KiB, d_memory_KiB, \ + d_nrVirtCpu, d_cpuTime = dom.info() + try: + with suppress_stdout_stderr(): + d_vcpus = dom.vcpus() + except Exception as e: + d_vcpus = tuple([d_nrVirtCpu*[], + d_nrVirtCpu*[tuple(total_cpus * [False])]]) + + # Obtain cpulist of pcpus in the order of vcpus. This applies to either + # pinned or floating vcpus, Note that the cpuinfo pcpu value can be + # stale if we scale down cpus since it reports cpu-last-run. + # For this reason use cpumap = d_vcpus[1][vcpu], instead of cpuinfo + # (i.e., vcpu, state, cpuTime, pcpu = d_vcpus[0][vcpu]). + cpulist_p = [] + cpulist_d = {} + cpuset_total = 0 + up_total = 0 + for vcpu in xrange(d_nrVirtCpu): + cpuset_b = d_vcpus[1][vcpu] + cpuset = 0 + for cpu, up in enumerate(cpuset_b): + if up: + cpulist_d[vcpu] = cpu + aff = 1 << cpu + cpuset |= aff + up_total += 1 + cpuset_total |= cpuset + cpulist_f = _mask_to_cpulist(mask=cpuset_total) + for key in sorted(cpulist_d.iterkeys()): + cpulist_p.append(cpulist_d[key]) + + # Determine if floating or pinned, display appropriate cpulist + d_cpuset = cpuset_total + if up_total > d_nrVirtCpu: + d_cpulist = cpulist_f + else: + d_cpulist = cpulist_p + + # Determine list of numa nodes (the hard way) + dom_xml = ElementTree.fromstring(dom.XMLDesc(0)) + nodeset = set([]) + for elem in dom_xml.findall('./numatune/memnode'): + nodes = range_to_list(elem.get('nodeset')) + nodeset.update(nodes) + d_nodelist = list(sorted(nodeset)) + + # Update dictionary with per-domain information + domains[d_uuid] = { + 'name': d_name, + 'id': d_id, + 'uuid': d_uuid, + 'ostype': d_ostype, + 'state': _translate_virDomainState(d_state), + 'maxMem': int(d_maxMem_KiB / 1024.0), + 'memory': int(d_memory_KiB / 1024.0), + 'vcpus': d_nrVirtCpu, + 'cputime': d_cpuTime, + 'cpuset': d_cpuset, + 'nodelist': d_nodelist, + 'cpulist': d_cpulist, + } + + # Dump XML string + if debug['libvirt_xml']: + dom_xml = ElementTree.fromstring(dom.XMLDesc(0)) + xml_str = ElementTree.tostring(dom_xml) + logger.debug('DOM[%s] : XML =\n%s' % (d_name, xml_str)) + + conn.close() + return (domains, topology) + + +def print_debug_info(tenants=None, regions=None, + endpoints=None, services=None, + hypervisors=None, statistics=None, + servers=None, server_groups=None, + migrations=None, flavors=None, extra_specs=None, + images=None, volumes=None, + aggregates=None, domains=None, + topologies=None, topologies_idx=None, topologies_sib=None, + computes_cell=None, + debug=None, show=None): + """ + Print debug information - pretty formatting of various data structures + """ + pp = pprint.PrettyPrinter(indent=2) + + if True in debug.values(): + print + logger.debug('OPTIONS:') + logger.debug('debug=\n%s' % (pp.pformat(debug))) + logger.debug('show=\n%s' % (pp.pformat(show))) + + if debug['creds']: + print + logger.debug('CREDENTIALS:') + logger.debug('regions:\n%s' % (pp.pformat(regions))) + logger.debug('tenants:\n%s' % (pp.pformat(tenants))) + logger.debug('services:\n%s' % (pp.pformat(services))) + logger.debug('endpoints:\n%s' % (pp.pformat(endpoints))) + + if debug['hypervisors']: + print + logger.debug('HYPERVISORS:') + for H in hypervisors.values(): + logger.debug('hypervisor:\n%s' % (pp.pformat(vars(H)))) + + print + logger.debug('HYPERVISORS: numa cells') + logger.debug('computes_cell:\n%s' % (pp.pformat(computes_cell))) + + if debug['statistics']: + print + logger.debug('STATISTICS:') + logger.debug('statistic:\n%s' % (pp.pformat(vars(statistics)))) + + if debug['images']: + print + logger.debug('IMAGES:') + for I in images.values(): + logger.debug('image: id=%r\n%s' % (I.id, pp.pformat(vars(I)))) + + if debug['volumes']: + print + logger.debug('VOLUMES:') + for V in volumes.values(): + logger.debug('volume: id=%r\n%s' % (V['volume_id'], pp.pformat(V))) + + if debug['servers']: + print + logger.debug('SERVERS:') + for S in servers.values(): + logger.debug('server: id=%r\n%s' % (S.id, pp.pformat(vars(S)))) + + if debug['server_groups']: + print + logger.debug('SERVER GROUPS:') + for S in server_groups.values(): + logger.debug( + 'server_group: id=%r\n%s' % (S.id, pp.pformat(vars(S)))) + + if debug['migrations']: + print + logger.debug('MIGRATIONS:') + for M in migrations.values(): + logger.debug('MIG: id=%r\n%s' % (M.id, pp.pformat(vars(M)))) + + if debug['flavors']: + print + logger.debug('FLAVORS:') + for F in flavors.values(): + logger.debug( + 'FLAVOR: id=%r\n%s\nextra_specs=%s' + % (F.id, pp.pformat(vars(F)), pp.pformat(extra_specs[F.id]))) + + if debug['aggregates']: + print + logger.debug('AGGREGATES:') + for A in aggregates.values(): + logger.debug('aggregate: %s' % (pp.pformat(vars(A)))) + + if debug['libvirt']: + print + logger.debug('LIBVIRT:') + logger.debug('domain:\n%s' % (pp.pformat(domains))) + + if debug['topology']: + print + logger.debug('TOPOLOGY:') + logger.debug('topologies:\n%s' % (pp.pformat(topologies))) + logger.debug('topologies_idx:\n%s' % (pp.pformat(topologies_idx))) + logger.debug('topologies_sib:\n%s' % (pp.pformat(topologies_sib))) + + if debug: + print + + +def define_debug_flags(debug): + """ Define dictionary of debug flags. """ + opts = ['all', + 'creds', + 'hypervisors', + 'statistics', + 'servers', + 'server_groups', + 'migrations', + 'flavors', + 'images', + 'volumes', + 'aggregates', + 'libvirt', + 'libvirt_xml', + 'topology', + 'mismatch', + ] + {debug.update({e: False}) for e in opts} + + +def define_options(L_opts=[], L_brief=[], L_details=[], L_other=[]): + """ Define several groupings with lists of show options. """ + L_opts = ['brief', + 'all', + ] + L_brief = ['computes', + 'servers', + 'server_groups', + 'migrations', + 'flavors', + 'images', + ] + L_details = ['computes', + 'servers', + 'server_groups', + 'libvirt', + 'migrations', + 'flavors', + 'images', + 'volumes', + ] + L_other = ['aggregates', 'topology', 'topology-long'] + return (L_opts, L_brief, L_details, L_other) + + +def define_option_flags(show, options=[], + L_opts=[], L_brief=[], L_details=[], L_other=[]): + """ Define dictionary of option flags. """ + + # Set all options to False + {show.update({e: False}) for e in L_opts + L_brief + L_details + L_other} + + # Enable specific options + show.update({'show': options}) + if 'brief' in options: + {show.update({e: True}) for e in L_brief} + if 'all' in options: + {show.update({e: True}) for e in L_brief + L_details} + for e in options: + if e in show.keys(): + show.update({e: True}) + + +def print_all_tables(tenants=None, + hypervisors=None, statistics=None, + servers=None, server_groups=None, + migrations=migrations, flavors=None, extra_specs=None, + images=None, volumes=None, + aggregates=None, domains=None, + topologies=None, topologies_idx=None, topologies_sib=None, + computes_cell=None, + agg_h=None, + flavors_in_use=None, + images_in_use=None, + server_groups_in_use=None, + debug=None, show=None): + """ Print all summary tables using PrettyTable. + """ + # Print list of aggregates + if show['aggregates']: + print + print "AGGREGATES:" + pt = PrettyTable( + ['Name', + 'Avail Zone', + 'Hosts', + 'Metadata', + ], caching=False) + pt.align = 'l' + for name, A in sorted(aggregates.items()): + pt.add_row( + [A.name, + str(A.availability_zone), + ", ".join([str(x) for x in A.hosts]), + str(A.metadata) + ]) + print pt + + # Print list of compute host hypervisors, showing per numa details + if show['computes']: + print + print 'COMPUTE HOSTS: ' \ + 'Legend: U = Used, A = Avail' + pt = PrettyTable( + ['Host', + 'status', + 'model', + 'topology', + 'servers', + 'node', + 'pcpus', + 'U:dedicated', + 'U:shared', + 'memory', + 'U:memory', + 'A:mem_4K', + 'A:mem_2M', + 'A:mem_1G', + 'Aggregate', + ]) + pt.align = 'l' + for C in ['servers', 'pcpus', 'U:dedicated', 'U:shared', + 'memory', 'U:memory', 'A:mem_4K', 'A:mem_2M', 'A:mem_1G']: + pt.align[C] = 'r' + for host_name, H in sorted(hypervisors.iteritems(), + key=lambda (k, v): (natural_keys(k))): + A = agg_h[host_name].keys() + + try: + topology_idx = topologies_idx[host_name] + cpu_ids = sorted(topology_idx.keys()) + except Exception: + topology_idx = {} + cpu_ids = [] + if len(cpu_ids) > 0: + # determine number of sockets, cores/socket, threads/core + topology = topologies[host_name] + cpu_id = 0 + socket_id = topology_idx[cpu_id]['s'] + core_id = topology_idx[cpu_id]['c'] + n_sockets = len(topology.keys()) + n_cores = len(topology[socket_id].keys()) + n_threads = len(topology[socket_id][core_id].keys()) + else: + if 'topology' in H.cpu_info: + topology = H.cpu_info['topology'] + n_sockets = topology['sockets'] + n_cores = topology['cores'] + n_threads = topology['threads'] + else: + n_sockets = 0 + n_cores = 0 + n_threads = 0 + if 'model' not in H.cpu_info: + H.cpu_info['model'] = None + + first = True + for cell in computes_cell[host_name]: + if first: + pt.add_row( + [host_name, + H.status, + H.cpu_info['model'], + "%ss,%sc,%st" % (n_sockets, + n_cores, + n_threads), + H.running_vms, + cell['id'], + cell['pcpus'], + cell['pinned_used'], + cell['shared_used'], + cell['memory'], + cell['memory_usage'], + cell['memory_avail_4K'], + cell['memory_avail_2M'], + cell['memory_avail_1G'], + textwrap.fill(", ".join([str(x) for x in A]), + width=75), + ]) + else: + pt.add_row( + ['', # host + '', # H.status, + '', # model + '', # topology + '', # H.running_vms, + cell['id'], + cell['pcpus'], + cell['pinned_used'], + cell['shared_used'], + cell['memory'], + cell['memory_usage'], + cell['memory_avail_4K'], + cell['memory_avail_2M'], + cell['memory_avail_1G'], + '', # agg + ]) + + first = False + if len(computes_cell[host_name]) < 1: + pt.add_row( + [host_name, + H.status, + H.cpu_info['model'], + "%ss,%sc,%st" % (n_sockets, + n_cores, + n_threads), + H.running_vms, + '-', # cell.id + '-', # pcpus + '-', # U:dedicated + '-', # U:shared + '-', # memory + '-', # memory_usage + '-', # memory_avail_4K + '-', # memory_avail_2M + '-', # memory_avail_1G + ", ".join([str(x) for x in A]), + ]) + + # Add row with statistics + Y = statistics + pt.add_row( + ['count: %s' % (Y.count), + '-', # status + '-', # model + '-', # topology + Y.running_vms, + '-', # node + Y.vcpus, # pcpus + '-', # U:dedicated + '-', # U:shared + Y.memory_mb, # memory + Y.memory_mb_used, # memory_usage + '-', # memory_avail_4K + '-', # memory_avail_2M + '-', # memory_avail_1G + '-', # agg + ]) + print pt + + # Print list of compute hosts topology + if show['topology']: + print + print 'LOGICAL CPU TOPOLOGY (compute hosts):' + for host_name, topology in sorted(topologies.iteritems(), + key=lambda (k, v): (natural_keys(k))): + H = hypervisors[host_name] + try: + topology_idx = topologies_idx[host_name] + cpu_ids = sorted(topology_idx.keys()) + siblings = topologies_sib[host_name] + except Exception: + topology_idx = {} + siblings = {} + cpu_ids = [] + if len(cpu_ids) < 1: + logger.info('%s libvirt info not available\n' % (host_name)) + continue + + # determine number of sockets, cores/socket, threads/core + cpu_id = 0 + socket_id = topology_idx[cpu_id]['s'] + core_id = topology_idx[cpu_id]['c'] + n_sockets = len(topology.keys()) + n_cores = len(topology[socket_id].keys()) + n_threads = len(topology[socket_id][core_id].keys()) + + print '%s: Model:%s, Arch:%s, Vendor:%s, ' \ + 'Sockets=%d, Cores/Socket=%d, Threads/Core=%d, Logical=%d' \ + % (host_name, + H.cpu_info['model'], + H.cpu_info['arch'], + H.cpu_info['vendor'], + n_sockets, n_cores, n_threads, len(cpu_ids)) + + # cpu_id row + L = ['cpu_id'] + {L.append(i) for i in cpu_ids} + pt = PrettyTable(L) + pt.align = 'r' + + # socket_id row + L = ['socket_id'] + {L.append(topology_idx[i]['s']) for i in cpu_ids} + pt.add_row(L) + + # core_id row + L = ['core_id'] + {L.append(topology_idx[i]['c']) for i in cpu_ids} + pt.add_row(L) + + # thread_id row + L = ['thread_id'] + {L.append(topology_idx[i]['t']) for i in cpu_ids} + pt.add_row(L) + + # sibling_id row + L = ['sibling_id'] + {L.append(','.join( + str(s) for s in siblings[i]) or '-') for i in cpu_ids} + pt.add_row(L) + print pt + print + + # Print list of compute hosts topology + if show['topology-long']: + print + print 'LOGICAL CPU TOPOLOGY (compute hosts):' + for host_name, topology in sorted(topologies.iteritems(), + key=lambda (k, v): (natural_keys(k))): + H = hypervisors[host_name] + try: + topology_idx = topologies_idx[host_name] + cpu_ids = sorted(topology_idx.keys()) + siblings = topologies_sib[host_name] + except Exception: + topology_idx = {} + siblings = {} + cpu_ids = [] + if len(cpu_ids) < 1: + logger.info('%s libvirt info not available\n' % (host_name)) + continue + + # determine number of sockets, cores/socket, threads/core + cpu_id = 0 + socket_id = topology_idx[cpu_id]['s'] + core_id = topology_idx[cpu_id]['c'] + n_sockets = len(topology.keys()) + n_cores = len(topology[socket_id].keys()) + n_threads = len(topology[socket_id][core_id].keys()) + + print '%s: Model:%s, Arch:%s, Vendor:%s, ' \ + 'Sockets=%d, Cores/Socket=%d, Threads/Core=%d, Logical=%d' \ + % (host_name, + H.cpu_info['model'], + H.cpu_info['arch'], + H.cpu_info['vendor'], + n_sockets, n_cores, n_threads, len(cpu_ids)) + pt = PrettyTable( + ['cpu_id', + 'socket_id', + 'core_id', + 'thread_id', + 'sibling_id', + 'affinity' + ]) + pt.align = 'r' + pt.align['affinity'] = 'l' + for i in cpu_ids: + pt.add_row( + [i, + topology_idx[i]['s'], + topology_idx[i]['c'], + topology_idx[i]['t'], + list_to_range(siblings[i]) or '-', + '0x%x' % (1 << i) + ]) + print pt + print + + # Print list of servers + if show['servers']: + re_server_group = re.compile(r'^(\S+)\s+\((\S+)\)$') + print + print 'SERVERS (nova view):' + pt = PrettyTable( + ['tenant', + 'ID', + 'instance_name', + 'name', + 'host', + 'state (vm, task, power)', + 'server_group', + 'image', + 'flavor', + 'vcpus', + 'memory', + 'instance_topology', + 'in_libvirt', + ]) + pt.align = 'l' + for C in ['vcpus', 'memory']: + pt.align[C] = 'r' + for C in ['in_libvirt']: + pt.align[C] = 'c' + for _, S in sorted(servers.iteritems(), + key=lambda (k, v): (natural_keys(v.host), + v.server_group, + v.instance_name) + if (v.host is not None) else 'None' + ): + if S.server_group is not None and S.server_group: + match = re_server_group.search(S.server_group) + if match: + server_group = match.group(1) + sgid = match.group(2) + else: + server_group = '-' + sgid = None + else: + server_group = '-' + sgid = None + + # Determine image name based on glance image id if it exists, + # or deduce from attached volume metadata. + try: + image_id = S.image['id'] + except Exception: + try: + image_id = volumes[S.id]['image_id'] + except Exception: + image_id = None + try: + image_name = images[image_id].name + except Exception: + image_name = '-' + + # Determine flavor name + flavor_id = S.flavor['id'] + try: + flavor_name = flavors[flavor_id].name + except Exception: + flavor_name = 'DELETED (%s)' % (flavor_id) + try: + flavor_vcpus = flavors[flavor_id].vcpus + flavor_ram = flavors[flavor_id].ram + except Exception: + flavor_vcpus = '-' + flavor_ram = '-' + + try: + vcpus_scale = ','.join(str(x) for x in S.vcpus_scale) + except Exception: + vcpus_scale = flavor_vcpus + + in_libvirt = False + for h, D in domains.iteritems(): + if S.id in D: + in_libvirt = True + break + tenant = tenants[S.tenant_id].name + + pt.add_row( + [tenant, + S.id, + S.instance_name, + S.name, + S.host, + '%7s, %s, %s' % (S.vm_state, S.task_state, S.power_state), + server_group, + image_name, + flavor_name, + vcpus_scale, + flavor_ram, + S.topology, + 'yes' if in_libvirt else 'NO', + ]) + print pt + + # Print each libvirt domain info + if show['libvirt']: + print + print 'SERVERS (libvirt view): ' \ + 'Legend: cpulist = [pcpu[i], ...]' + pt = PrettyTable( + ['uuid', + 'instance_name', + 'host', + 'id', + 'state', + 'vcpus', + 'memory', + 'nodelist', + 'cpulist', + 'in_nova', + ]) + pt.align = 'l' + for C in ['id', 'vcpus', 'memory', 'nodelist']: + pt.align[C] = 'r' + for C in ['in_nova']: + pt.align[C] = 'c' + for host, D in sorted(domains.iteritems(), + key=lambda (k, v): (natural_keys(k))): + for _, S in sorted(D.iteritems(), + key=lambda (k, v): (v['name'])): + in_nova = True if S['uuid'] in servers else False + pt.add_row( + [S['uuid'], + S['name'], + host, + S['id'], + S['state'], + S['vcpus'], + S['memory'], + list_to_range(S['nodelist']) or '-', + list_to_range(S['cpulist']) or '-', + 'yes' if in_nova else 'NO', + ]) + print pt + + # Print list of in-progress migrations + if show['migrations']: + print + print "MIGRATIONS (in progress): Legend: S=Source, D=Destination" + pt = PrettyTable( + ['ID', + 'status', + 'S:node', + 'D:node', + 'S:compute', + 'D:compute', + 'S:flavor[PKey]', + 'D:flavor[PKey]', + 'created_at', + ]) + pt.align = 'l' + for _, M in sorted(migrations.iteritems(), + key=lambda (k, v): (k)): + pt.add_row( + [M.instance_uuid, + M.status, + M.source_node, + M.dest_node, + M.source_compute, + M.dest_compute, + M.new_instance_type_id, + M.old_instance_type_id, + M.created_at, + ]) + print pt + + # Print flavors for instances currently in use + pp = pprint.PrettyPrinter(indent=1, width=40) + if show['flavors']: + print + print "FLAVORS (in use):" + pt = PrettyTable( + ['id', + 'name', + 'vcpus', + 'ram', + 'disk', + 'ephemeral', + 'swap', + 'rxtx_factor', + 'is_public', + 'extra_specs', + ]) + pt.align = 'l' + for C in ['id', 'vcpus', 'ram', 'disk', 'ephemeral', 'swap', + 'rxtx_factor']: + pt.align[C] = 'r' + for _, F in sorted(flavors.iteritems(), + key=lambda (k, v): (k)): + if F.id in flavors_in_use: + pt.add_row( + [F.id, + F.name, + F.vcpus, + F.ram, + F.disk, + F.ephemeral or '-', + F.swap or '-', + F.rxtx_factor, + F.is_public, + pp.pformat(extra_specs[F.id]), + ]) + print pt + + # Print images for instances currently in use + pp = pprint.PrettyPrinter(indent=1, width=40) + if show['images']: + print + print "IMAGES (in use):" + pt = PrettyTable( + ['id', + 'name', + 'min_disk', + 'min_ram', + 'size(MB)', + 'status', + 'properties', + ]) + pt.align = 'l' + for C in ['id', 'min_disk', 'min_ram', 'status']: + pt.align[C] = 'r' + for _, I in sorted(images.iteritems(), + key=lambda (k, v): (k)): + if I.id in images_in_use: + pt.add_row( + [I.id, + I.name, + I.min_disk, + I.min_ram, + '%.2f' % (I.size/1024.0/1024.0), + I.status, + I.properties, + ]) + print pt + + # Print server groups for instances currently in use (exclude members data) + if show['server_groups']: + print + print "SERVER GROUPS (in use):" + pt = PrettyTable( + ['Tenant', + 'Id', + 'Name', + 'Policies', + 'Metadata', + ]) + pt.align = 'l' + for _, S in sorted(server_groups.iteritems(), + key=lambda (k, v): (k)): + if S.id in server_groups_in_use: + tenant = tenants[S.project_id].name + pt.add_row( + [tenant, + S.id, + S.name, + str(S.policies), + str(S.metadata), + ]) + print pt + + +def _get_host_id(tenant_id=None, host_name=None): + """ Routine defined in nova/api/openstack/compute/views/servers.py . + """ + sha_hash = hashlib.sha224(tenant_id + host_name) + return sha_hash.hexdigest() + + +def start_process(): + logger.debug('Starting: %s, %d' + % (multiprocessing.current_process().name, os.getpid())) + + +def get_info_and_display(show=None): + """ Get information from various sources (keystone, nova, libvirt). + + Display the following information in table format. + - nova view of hypervisors and servers + - libvirt view of servers + - nova view of in-progress migrations + - nova view of flavors in-use + - nova view of volumes and images in-use + - nova view of server-groups in-use + """ + t0 = time.time() + + # Keep track of mismatches found when validating data sources + warnings = [] + + # Define list of server field conversions + convert = [ + ('OS-EXT-SRV-ATTR:host', 'host'), + ('OS-EXT-SRV-ATTR:hypervisor_hostname', 'nodename'), + ('OS-EXT-STS:task_state', 'task_state'), + ('OS-EXT-STS:vm_state', 'vm_state'), + ('OS-EXT-SRV-ATTR:instance_name', 'instance_name'), + ('OS-EXT-STS:power_state', 'power_state'), + ('OS-SRV-USG:launched_at', 'launched_at'), + ('OS-FLV-DISABLED:disabled', 'disabled'), + ('OS-FLV-EXT-DATA:ephemeral', '_ephemeral'), + ('os-flavor-access:is_public', '_is_public'), + ('os-extended-volumes:volumes_attached', 'volumes_attached'), + ('wrs-res:vcpus', 'vcpus_scale'), + ('OS-EXT-IMG-SIZE:size', 'size'), + ('wrs-res:topology', 'topology'), + ('wrs-sg:server_group', 'server_group'), + ('wrs-sg:project_id', 'project_id'), + ] + + # Define list of migration status that imply completed migration + migration_completed_list = [ + # live migration + 'live-post', 'live-rollback', + # cold migration + 'confirmed', 'reverted', 'finished', + # drop_resize_claim + 'drop-claim', + # error + 'error' + ] + + + # Get keystone credentials from nova.conf + auth = keystone.load_auth_from_conf_options(CONF, AUTHTOKEN_GROUP) + keystone_session = session.Session(auth=auth) + + # Define primary region_name (should be the same as keystone) + regions = {} + primary = 'primary' + regions[primary] = CONF.keystone_authtoken.region_name + + # Query sysinv database for region_name data. This is done directly from + # sysinv database, as that information is not exported via sysinv APIs. + # We have sufficient postgres credentials since we are on the same + # localhost as the DB and may use a local socket. We also execute as root. + engine = create_engine( + '{driver}://{user}:{passwd}@{host}:{port}/{dbname}'. + format( + driver='postgresql', + user='admin', + passwd='admin', + host='controller', + dbname='sysinv', + port='5432', + ), client_encoding='utf8') + conn = engine.connect() + + # Get sysinv i_system + metadata = MetaData() + metadata.reflect(engine, only=['i_system']) + Base = automap_base(metadata=metadata) + Base.prepare(engine) + S = Base.classes.i_system + q = select([S.name, + S.region_name, + S.deleted_at] + ).where(S.deleted_at == None) + result = conn.execute(q) + for row in result: + field = 'region_name' + if row[field] is None: + continue + regions[primary] = str(row[field]) + + # Get sysinv services + metadata = MetaData() + metadata.reflect(engine, only=['services']) + Base = automap_base(metadata=metadata) + Base.prepare(engine) + S = Base.classes.services + q = select([S.name, + S.region_name, + S.deleted_at] + ).where(S.deleted_at == None) + result = conn.execute(q) + for row in result: + name = str(row['name']) + field = 'region_name' + if row[field] is None: + region = regions[primary] + else: + region = str(row[field]) + regions[name] = region + + # Connect keystone client + region_keystone = CONF.keystone_authtoken.region_name + try: + kc = keystone_client.Client(session=keystone_session, + endpoint_type='internalURL', + region_name=region_keystone) + except Exception as e: + logger.error('cannot connect keystone client, %s', e) + sys.exit(1) + + # Connect nova client as admin + region_nova = regions.get('nova', CONF.keystone_authtoken.region_name) + try: + nc_admin = nova_client.Client(NOVACLIENT_VERSION, + session=keystone_session, + endpoint_type='internalURL', + region_name=region_nova) + except Exception as e: + logger.error('cannot connect nova client, %s', e) + sys.exit(1) + + # Get list of services, then transform into dictionary with 'name' as key + try: + services_ = kc.services.list() + except Exception as e: + logger.error('cannot list services', exc_info=1) + sys.exit(1) + services = dict((e.name, e) for e in services_) + del services_ + + # Get list of endpoints, then transform into dictionary with 'id' as key + try: + endpoints_ = kc.endpoints.list() + except Exception as e: + logger.error('cannot list endpoints', exc_info=1) + sys.exit(1) + endpoints = dict((e.id, e) for e in endpoints_) + del endpoints_ + + # Get list of tenants, then transform into dictionary with 'id' as key + try: + tenants_ = kc.projects.list() + except Exception as e: + logger.error('cannot list tenants', exc_info=1) + sys.exit(1) + tenants = dict((e.id, e) for e in tenants_) + del tenants_ + + # Connect cinder client as admin to access block storage volumes + region_cinder = regions.get('cinder', CONF.keystone_authtoken.region_name) + try: + cv_admin = cinder_client.Client(CINDERCLIENT_VERSION, + session=keystone_session, + endpoint_type='internalURL', + region_name=region_cinder) + except Exception as e: + logger.error('cannot connect cinder client, %s', e) + sys.exit(1) + + # Connect glanceclient as admin to access images + region_glance = regions.get('glance', CONF.keystone_authtoken.region_name) + try: + gc_admin = glance_client.Client(GLANCECLIENT_VERSION, + session=keystone_session, + interface='internalURL', + region_name=region_glance) + except Exception as e: + logger.error('cannot connect glance client, %s', e) + sys.exit(1) + + # Get list of images + try: + images_ = gc_admin.images.list(detailed=True) + except Exception as e: + if True in debug.values(): + logger.error('cannot list images', exc_info=1) + else: + logger.error('cannot list images, %s' % (e)) + images_ = [] + try: + images = dict((e.id, e) for e in images_) + except Exception as e: + if True in debug.values(): + logger.error('cannot list images', exc_info=1) + else: + logger.error('cannot list images, %s' % (e)) + images = {} + + # translate fields into human-readable names + _translate_keys(images, convert) + + for I_id, I in images.iteritems(): + meta = copy.deepcopy(I.properties) + I.properties = {} + for k, v in meta.items(): + I.properties[str(k)] = str(v) + + # Get list of servers for all tenants + try: + servers_ = nc_admin.servers.list(detailed=True, + search_opts={'all_tenants': True}) + except Exception as e: + logger.error('cannot list servers', exc_info=1) + sys.exit(1) + + servers = dict((e.id, e) for e in servers_) + del servers_ + # translate fields into human-readable names + _translate_keys(servers, convert) + _translate_extended_states(servers) + for S in servers.values(): + if S.host != S.nodename: + warnings.append( + 'Server ID=%s, instance_name=%s, name=%s, host=%s ' + 'does not match nodename=%s.' + % (S.id, S.instance_name, S.name, S.host, S.nodename)) + + # Get list of volumes attached to servers for all tenants + if show['volumes']: + try: + volumes_ = cv_admin.volumes.list(detailed=True, + search_opts={'all_tenants': True}) + except Exception as e: + if True in debug.values(): + logger.error('cannot list volumes', exc_info=1) + else: + logger.error('cannot list volumes, %s' % (e)) + volumes_ = [] + else: + volumes_ = [] + volumes = {} + # keep all fields for debug even though we do not display details. + for V in volumes_: + # image metadata (not always available) + try: + image_id = V.volume_image_metadata['image_id'] + image_name = V.volume_image_metadata['image_name'] + except Exception: + image_id = None + image_name = None + for A in V.attachments: + server_id = A['server_id'] + volume_id = A['volume_id'] + volumes[server_id] = {'volume_id': volume_id, + 'image_id': image_id, + 'image_name': image_name, + 'vars': vars(V), + } + del volumes_ + + # Get list of migrations, sort-by id which puts them in time order. + # Transform into dictionary with 'instance_uuid' as key. Keep only the + # most current, and only in-progress migrations. + try: + migrations_ = nc_admin.migrations.list() + except Exception as e: + logger.error('cannot list migrations', exc_info=1) + migrations_ = {} + migrations = {} + if migrations_: + migrations_.sort(key=lambda x: (x.id)) + for M in migrations_: + if M.instance_uuid in servers: + migrations.update({M.instance_uuid: M}) + for _, M in migrations.items(): + S = servers[M.instance_uuid] + if S.task_state is None or M.status in migration_completed_list: + del migrations[M.instance_uuid] + del migrations_ + + # Get list of flavors, then transform into dictionary with 'id' as key + try: + flavors_ = nc_admin.flavors.list(detailed=True) + except Exception as e: + logger.error('cannot list flavors', exc_info=1) + sys.exit(1) + flavors = dict((e.id, e) for e in flavors_) + del flavors_ + + # translate fields into human-readable names + _translate_keys(flavors, convert) + + # Get extra_specs + extra_specs = {} + for f_id, F in flavors.iteritems(): + try: + specs = F.get_keys() + except Exception as e: + specs = {} + logger.error('cannot get extra_specs for flavor:%s, error=%s' + % (f_id, e)) + extra_specs[f_id] = {} + for k, v in specs.items(): + extra_specs[f_id][str(k)] = str(v) + + # Get list of server groups, then transform into dictionary with 'id' + # as key + try: + server_groups_ = nc_admin.server_groups.list() + except Exception as e: + logger.error('cannot list server_groups', exc_info=1) + sys.exit(1) + server_groups = dict((e.id, e) for e in server_groups_) + del server_groups_ + + # translate fields into human-readable names + _translate_keys(server_groups, convert) + + # Generate server_groups_in_use, flavors in-use, images in-use + re_server_group = re.compile(r'^(\S+)\s+\((\S+)\)$') + server_groups_in_use = {} + flavors_in_use = {} + images_in_use = {} + for S in servers.values(): + if S.server_group is not None and S.server_group: + match = re_server_group.search(S.server_group) + if match: + server_group = match.group(1) + server_group_id = match.group(2) + server_groups_in_use[server_group_id] = True + + # Save flavors in use + flavor_id = S.flavor['id'] + flavors_in_use[flavor_id] = True + + # Save images in use. Look for glance image id. If glance image not + # available, then check for attached volume and store image name from + # volume metadata. + try: + image_id = S.image['id'] + except Exception: + try: + image_id = volumes[S.id]['image_id'] + images_in_use[image_id] = True + except Exception: + image_id = None + if image_id is not None: + images_in_use[image_id] = True + + # Get list of hypervisors, then transform into dictionary with + # 'hypervisor_hostname' as key + try: + hypervisors_ = nc_admin.hypervisors.list(detailed=True) + except Exception as e: + logger.error('cannot list hypervisors', exc_info=1) + sys.exit(1) + hypervisors = dict((e.hypervisor_hostname, e) for e in hypervisors_) + del hypervisors_ + for H in hypervisors.values(): + H.cpu_info = jsonutils.loads(H.cpu_info) if H.cpu_info else {} + del H._info, H._loaded, H.manager + + # Get hypervisor statisics (over all computes) + try: + statistics = nc_admin.hypervisors.statistics() + except Exception as e: + logger.error('cannot get overall hypervisors statistics', exc_info=1) + sys.exit(1) + + # Get list of aggregates, then transform into dictionary with 'id' as key + try: + aggregates_ = nc_admin.aggregates.list() + except Exception as e: + logger.error('cannot list aggregates', exc_info=1) + sys.exit(1) + aggregates = dict((e.id, e) for e in aggregates_) + del aggregates_ + + # Build up aggregate list per compute host + agg_h = {} + for H in hypervisors.keys(): + agg_h[H] = {} + for A in aggregates.values(): + for H in A.hosts: + agg_h[H] = {} + for A in aggregates.values(): + for H in A.hosts: + agg_h[H][str(A.name)] = A.metadata + + # Calculate number of workers we can handle + process = psutil.Process(os.getpid()) + avail_MiB = psutil.virtual_memory().available / float(Mi) + try: + process_MiB = process.get_memory_info().rss / float(Mi) + except Exception as e1: + try: + process_MiB = process.memory_info().rss / float(Mi) + except Exception as e2: + logger.error('WORKERS: psutil.memory_info(), error=%s' % (e2)) + process_MiB = 50.0 + pool_size = \ + max(1, + min(len(hypervisors), + max(1, + min(multiprocessing.cpu_count(), + int(0.6 * (avail_MiB - 100.0) / process_MiB) + ) + ) + ) + ) + logger.debug('WORKERS: avail=%.2f MiB, process=%.2f MiB, pool_size=%d' + % (avail_MiB, process_MiB, pool_size)) + + # Create pool of workers that connect to libvirt hypervisor. + try: + pool = multiprocessing.Pool(processes=pool_size, + initializer=start_process, + maxtasksperchild=2) + except Exception as e: + logger.error('Cannot create worker pool, %s' % (e)) + sys.exit(1) + + hosts = [] + for h in hypervisors.keys(): + hosts.append(h) + + # Launch tasks + results = [pool.apply_async(libvirt_domain_info_worker, + args=(x,)) for x in hosts] + pool.close() + + # Wait for active workers to complete + time.sleep(0.15) + while len(active_pids) > 0: + # Reap aged workers that exceed hang timeout + now = time.time() + reap = [] + for pid in active_pids.keys(): + if pid == 0: + continue + try: + host, age = active_pids[pid] + except: + continue + dt = now - age + if dt > LIBVIRT_REAP_SEC: + reap.append(pid) + logger.error('REAP: pid=%d, host=%s, age=%.2f s' + % (pid, host, dt)) + for pid in reap: + os.kill(pid, signal.SIGKILL) + del active_pids[pid] + time.sleep(0.25) + + # Collect outputs + # Since we have already waited, set timeout small. + outputs = [] + for p in results: + try: + outputs.append(p.get(timeout=0.005)) + except: + pass + + # Cleanup workers + pool.terminate() + pool.join() + + # Summarize per-domain and cpu topology per host. + domains = {} + topologies = {} + topologies_idx = {} + topologies_sib = {} + topologies_lib = {} + for (h, domain_lib, topology_lib, tm1, error) in outputs: + if error is None: + domains[h] = domain_lib + topologies_lib[h] = topology_lib + else: + domains[h] = {} + topologies_lib[h] = {} + logger.error('%s' % error) + topology = copy.deepcopy(topologies_lib[h]) + topologies[h] = copy.deepcopy(topology) + + # Define topology indices for each logical cpu + topology_idx = {} + for socket_id in topology: + for core_id in topology[socket_id]: + for thread_id in topology[socket_id][core_id]: + cpu_id = topology[socket_id][core_id][thread_id] + topology_idx[cpu_id] = {'s': socket_id, + 'c': core_id, + 't': thread_id} + topologies_idx[h] = copy.deepcopy(topology_idx) + + # Define siblings for each logical cpu + siblings = {} + for socket_id in topology: + for core_id in topology[socket_id]: + for thread_id in topology[socket_id][core_id]: + cpu_id = topology[socket_id][core_id][thread_id] + siblings[cpu_id] = [] + for sibling_id in topology[socket_id][core_id]: + if thread_id != sibling_id: + sibling_cpu_id = topology[socket_id][core_id][sibling_id] + siblings[cpu_id].append(sibling_cpu_id) + topologies_sib[h] = copy.deepcopy(siblings) + del outputs + + # Query nova database for compute_nodes table, which contains per NUMA cell + # data (i.e., numa_topology). This is done directly from nova database, + # as that information is not exported via nova APIs. + # We have sufficient postgres credentials since we are on the same + # localhost as the DB and may use a local socket. We also execute as root. + computes_cell = {} + engine = create_engine( + '{driver}://{user}:{passwd}@{host}:{port}/{dbname}'. + format( + driver='postgresql', + user='admin', + passwd='admin', + host='controller', + dbname='nova', + port='5432', + ), client_encoding='utf8') + conn = engine.connect() + metadata = MetaData() + metadata.reflect(engine, only=['compute_nodes']) + Base = automap_base(metadata=metadata) + Base.prepare(engine) + CN = Base.classes.compute_nodes + q = select([CN.hypervisor_hostname, + CN.numa_topology, + CN.deleted] + ).where(CN.deleted == 0) + result = conn.execute(q) + for row in result: + host = row['hypervisor_hostname'] + computes_cell[host] = [] + + # We need libvirt topology information to make sense of cpusets. + have_topology = True + try: + if len(topologies_idx[host].keys()) < 1: + have_topology = False + except: + have_topology = False + + field = 'numa_topology' + if field not in row or row[field] is None: + continue + try: + T = jsonutils.loads(row[field]) + except Exception as e: + T = {} + logger.warning('cannot json.loads(%s), error=%s' % (field, e)) + continue + try: + cells = T['nova_object.data']['cells'] + for C in cells: + cell = C['nova_object.data'] + cell_id = cell['id'] + cpu_usage = cell['cpu_usage'] + cpuset = cell['cpuset'] + pinned_cpus = cell['pinned_cpus'] + shared_pcpu = cell['shared_pcpu'] + siblings = cell['siblings'] + memory = cell['memory'] + memory_usage = cell['memory_usage'] + MP = cell['mempages'] + mempages = [] + for M in MP: + MS = M['nova_object.data'] + mempages.append(MS) + + pcpuset = [] + if have_topology: + for cpu in cpuset: + if topologies_idx[host][cpu]['s'] == cell_id: + pcpuset.append(cpu) + + # Store data for compute node numa cell + Cell = {} + Cell['id'] = cell_id + Cell['memory'] = memory + Cell['memory_usage'] = memory_usage + Cell['mempages'] = mempages + Cell['pinned_cpus'] = pinned_cpus + Cell['pcpuset'] = pcpuset + if have_topology: + Cell['pcpus'] = len(pcpuset) + else: + Cell['pcpus'] = '-' + Cell['shared_pcpu'] = shared_pcpu + Cell['siblings'] = siblings + Cell['pinned_used'] = len(pinned_cpus) + if have_topology: + Cell['pinned_avail'] = len(pcpuset) - len(pinned_cpus) + else: + Cell['pinned_avail'] = '-' + Cell['shared_used'] = cpu_usage - len(pinned_cpus) + for suf in ['4K', '2M', '1G']: + Cell['memory_total_' + suf] = 0 + Cell['memory_used_' + suf] = 0 + Cell['memory_avail_' + suf] = 0 + for pages in mempages: + suf = '' + if pages['size_kb'] == 4: + suf = '4K' + if pages['size_kb'] == 2048: + suf = '2M' + if pages['size_kb'] == 1048576: + suf = '1G' + Cell['memory_total_' + suf] = pages['size_kb'] * pages['total'] / Ki + Cell['memory_used_' + suf] = pages['size_kb'] * pages['used'] / Ki + Cell['memory_avail_' + suf] = pages['size_kb'] * (pages['total'] - pages['used']) / Ki + + computes_cell[host].append(Cell) + + except Exception as e: + logger.warning('cannot print numa_topology.cells, error=%s' % (e)) + + conn.close() + + # Detect mismatch where server is in nova but not in libvirt + server_mismatch = False + for S in servers.values(): + in_libvirt = False + for h, D in domains.iteritems(): + if S.id in D and S.host == h: + in_libvirt = True + break + if not in_libvirt: + server_mismatch = True + warnings.append('Server ID=%s, instance_name=%s, name=%s, ' + 'host=%s is in nova but not libvirt.' + % (S.id, S.instance_name, S.name, S.host)) + + # Detect mismatch where server is in libvirt but not in nova + for host, D in domains.iteritems(): + for k, S in D.iteritems(): + in_nova = False + uuid = S['uuid'] + if uuid in servers and servers[uuid].host == host: + in_nova = True + if not in_nova: + server_mismatch = True + warnings.append('Server ID=%s, instance_name=%s, host=%s ' + 'is in libvirt but not nova.' + % (S['uuid'], S['name'], host)) + + # Print out more details if we detect a mismatch, but only if we meant + # to display servers. + if server_mismatch and (show['servers'] or show['libvirt']): + show['servers'] = True + show['libvirt'] = True + + # Print debug information + if True in debug.values(): + print_debug_info(tenants=tenants, regions=regions, + endpoints=endpoints, services=services, + hypervisors=hypervisors, statistics=statistics, + servers=servers, server_groups=server_groups, + migrations=migrations, flavors=flavors, + extra_specs=extra_specs, + images=images, volumes=volumes, + aggregates=aggregates, domains=domains, + topologies=topologies, + topologies_idx=topologies_idx, + topologies_sib=topologies_sib, + computes_cell=computes_cell, + debug=debug, show=show) + + # Print all summary tables + print_all_tables(tenants=tenants, + hypervisors=hypervisors, statistics=statistics, + servers=servers, server_groups=server_groups, + migrations=migrations, flavors=flavors, + extra_specs=extra_specs, + images=images, volumes=volumes, + aggregates=aggregates, domains=domains, + topologies=topologies, + topologies_idx=topologies_idx, + topologies_sib=topologies_sib, + computes_cell=computes_cell, + agg_h=agg_h, + flavors_in_use=flavors_in_use, + images_in_use=images_in_use, + server_groups_in_use=server_groups_in_use, + debug=debug, show=show) + + # Print out warnings if we detect mismatches between nova and libvirt + if warnings: + print + print "WARNINGS (mismatch):" + pt = PrettyTable(['Message']) + pt.align = 'l' + for W in warnings: + pt.add_row([W]) + print pt + + if True in debug.values(): + logger.debug('done.') + + # Cleanup + del nc_admin, kc + + +def main(): + try: + # Enforce 'root' access since we need to read nova.conf . + if os.geteuid() != 0: + print ('Require sudo/root.') + os.execvp('sudo', ['sudo'] + sys.argv) + + # Process command line options and arguments, configure logging, + # configure debug and show options + parse_arguments(debug, show) + + # Print selected options, and timestamp + prog = os.path.basename(sys.argv[0]) + ts = datetime.datetime.now() + print "%s: %s options: show:%s" % (prog, ts.isoformat(), show['show']) + if show['volumes']: + logger.info('volumes selected: displaying will take some time') + + if debug['creds']: + CONF.log_opt_values(logger, logging.INFO) + + # Get all info and display in table format + get_info_and_display(show) + sys.exit(0) + + except KeyboardInterrupt as e: + logger.info('caught: %r, shutting down', e) + sys.exit(0) + + except IOError as e: + sys.exit(0) + + except Exception as e: + logger.error('exception: %r', e, exc_info=1) + sys.exit(-4)

    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 G^Zx^~w-_`4 literal 0 HcmV?d00001 diff --git a/restapi-doc/restapi-doc/rest-api-usage-example.pptx b/restapi-doc/restapi-doc/rest-api-usage-example.pptx new file mode 100644 index 0000000000000000000000000000000000000000..2119dc14347f84d3f12a2107ede0b03b216de1e0 GIT binary patch literal 418604 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