# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Red Hat, Inc. # This file is distributed under the same license as the PACKAGE package. # # Translators: msgid "" msgstr "" "Project-Id-Version: SSSD\n" "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n" "POT-Creation-Date: 2013-08-28 22:37+0200\n" "PO-Revision-Date: 2013-07-24 12:27+0000\n" "Last-Translator: jhrozek \n" "Language-Team: Chinese (Taiwan) \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/config/SSSDConfig/__init__.py.in:39 msgid "Set the verbosity of the debug logging" msgstr "" #: src/config/SSSDConfig/__init__.py.in:40 msgid "Include timestamps in debug logs" msgstr "在除錯日誌內加入時間戳記" #: src/config/SSSDConfig/__init__.py.in:41 msgid "Include microseconds in timestamps in debug logs" msgstr "" #: src/config/SSSDConfig/__init__.py.in:42 msgid "Write debug messages to logfiles" msgstr "將除錯訊息寫入日誌檔" #: src/config/SSSDConfig/__init__.py.in:43 msgid "Ping timeout before restarting service" msgstr "" #: src/config/SSSDConfig/__init__.py.in:44 msgid "" "Timeout between three failed ping checks and forcibly killing the service" msgstr "" #: src/config/SSSDConfig/__init__.py.in:45 msgid "Command to start service" msgstr "啟動服務的指令" #: src/config/SSSDConfig/__init__.py.in:46 msgid "Number of times to attempt connection to Data Providers" msgstr "" #: src/config/SSSDConfig/__init__.py.in:47 msgid "The number of file descriptors that may be opened by this responder" msgstr "" #: src/config/SSSDConfig/__init__.py.in:48 msgid "Idle time before automatic disconnection of a client" msgstr "" #: src/config/SSSDConfig/__init__.py.in:51 msgid "SSSD Services to start" msgstr "要啟動的 SSSD 服務" #: src/config/SSSDConfig/__init__.py.in:52 msgid "SSSD Domains to start" msgstr "要啟動的 SSSD 網域" #: src/config/SSSDConfig/__init__.py.in:53 msgid "Timeout for messages sent over the SBUS" msgstr "" #: src/config/SSSDConfig/__init__.py.in:54 msgid "Regex to parse username and domain" msgstr "用來解析使用者名稱與網域的正規表示式" #: src/config/SSSDConfig/__init__.py.in:55 msgid "Printf-compatible format for displaying fully-qualified names" msgstr "" #: src/config/SSSDConfig/__init__.py.in:56 msgid "" "Directory on the filesystem where SSSD should store Kerberos replay cache " "files." msgstr "" #: src/config/SSSDConfig/__init__.py.in:57 msgid "Domain to add to names without a domain component." msgstr "" #: src/config/SSSDConfig/__init__.py.in:60 msgid "Enumeration cache timeout length (seconds)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:61 msgid "Entry cache background update timeout length (seconds)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:62 #: src/config/SSSDConfig/__init__.py.in:88 msgid "Negative cache timeout length (seconds)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:63 msgid "Users that SSSD should explicitly ignore" msgstr "SSSD 應該明確忽略的使用者" #: src/config/SSSDConfig/__init__.py.in:64 msgid "Groups that SSSD should explicitly ignore" msgstr "SSSD 應該明確忽略的群組" #: src/config/SSSDConfig/__init__.py.in:65 msgid "Should filtered users appear in groups" msgstr "過濾的使用者是否應該顯現在群組內" #: src/config/SSSDConfig/__init__.py.in:66 msgid "The value of the password field the NSS provider should return" msgstr "" #: src/config/SSSDConfig/__init__.py.in:67 msgid "Override homedir value from the identity provider with this value" msgstr "" #: src/config/SSSDConfig/__init__.py.in:68 msgid "" "Substitute empty homedir value from the identity provider with this value" msgstr "" #: src/config/SSSDConfig/__init__.py.in:69 msgid "Override shell value from the identity provider with this value" msgstr "" #: src/config/SSSDConfig/__init__.py.in:70 msgid "The list of shells users are allowed to log in with" msgstr "" #: src/config/SSSDConfig/__init__.py.in:71 msgid "" "The list of shells that will be vetoed, and replaced with the fallback shell" msgstr "" #: src/config/SSSDConfig/__init__.py.in:72 msgid "" "If a shell stored in central directory is allowed but not available, use " "this fallback" msgstr "" #: src/config/SSSDConfig/__init__.py.in:73 msgid "Shell to use if the provider does not list one" msgstr "" #: src/config/SSSDConfig/__init__.py.in:74 msgid "How long will be in-memory cache records valid" msgstr "" #: src/config/SSSDConfig/__init__.py.in:77 msgid "How long to allow cached logins between online logins (days)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:78 msgid "How many failed logins attempts are allowed when offline" msgstr "" #: src/config/SSSDConfig/__init__.py.in:79 msgid "" "How long (minutes) to deny login after offline_failed_login_attempts has " "been reached" msgstr "" #: src/config/SSSDConfig/__init__.py.in:80 msgid "What kind of messages are displayed to the user during authentication" msgstr "" #: src/config/SSSDConfig/__init__.py.in:81 msgid "How many seconds to keep identity information cached for PAM requests" msgstr "" #: src/config/SSSDConfig/__init__.py.in:82 msgid "How many days before password expiration a warning should be displayed" msgstr "" #: src/config/SSSDConfig/__init__.py.in:85 msgid "Whether to evaluate the time-based attributes in sudo rules" msgstr "" #: src/config/SSSDConfig/__init__.py.in:91 msgid "Whether to hash host names and addresses in the known_hosts file" msgstr "" #: src/config/SSSDConfig/__init__.py.in:92 msgid "" "How many seconds to keep a host in the known_hosts file after its host keys " "were requested" msgstr "" #: src/config/SSSDConfig/__init__.py.in:95 msgid "List of UIDs or user names allowed to access the PAC responder" msgstr "" #: src/config/SSSDConfig/__init__.py.in:98 msgid "Identity provider" msgstr "身分提供者" #: src/config/SSSDConfig/__init__.py.in:99 msgid "Authentication provider" msgstr "認證提供者" #: src/config/SSSDConfig/__init__.py.in:100 msgid "Access control provider" msgstr "存取控制提供者" #: src/config/SSSDConfig/__init__.py.in:101 msgid "Password change provider" msgstr "密碼變更提供者" #: src/config/SSSDConfig/__init__.py.in:102 msgid "SUDO provider" msgstr "" #: src/config/SSSDConfig/__init__.py.in:103 msgid "Autofs provider" msgstr "" #: src/config/SSSDConfig/__init__.py.in:104 msgid "Session-loading provider" msgstr "" #: src/config/SSSDConfig/__init__.py.in:105 msgid "Host identity provider" msgstr "" #: src/config/SSSDConfig/__init__.py.in:108 msgid "Minimum user ID" msgstr "最小的使用者 ID" #: src/config/SSSDConfig/__init__.py.in:109 msgid "Maximum user ID" msgstr "最大的使用者 ID" #: src/config/SSSDConfig/__init__.py.in:110 msgid "Enable enumerating all users/groups" msgstr "啟用所有使用者或群組的列舉" #: src/config/SSSDConfig/__init__.py.in:111 msgid "Cache credentials for offline login" msgstr "供離線登入使用的快取憑證" #: src/config/SSSDConfig/__init__.py.in:112 msgid "Store password hashes" msgstr "" #: src/config/SSSDConfig/__init__.py.in:113 msgid "Display users/groups in fully-qualified form" msgstr "" #: src/config/SSSDConfig/__init__.py.in:114 msgid "Don't include group members in group lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:115 #: src/config/SSSDConfig/__init__.py.in:122 #: src/config/SSSDConfig/__init__.py.in:123 #: src/config/SSSDConfig/__init__.py.in:124 #: src/config/SSSDConfig/__init__.py.in:125 #: src/config/SSSDConfig/__init__.py.in:126 #: src/config/SSSDConfig/__init__.py.in:127 msgid "Entry cache timeout length (seconds)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:116 msgid "" "Restrict or prefer a specific address family when performing DNS lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:117 msgid "How long to keep cached entries after last successful login (days)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:118 msgid "How long to wait for replies from DNS when resolving servers (seconds)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:119 msgid "The domain part of service discovery DNS query" msgstr "" #: src/config/SSSDConfig/__init__.py.in:120 msgid "Override GID value from the identity provider with this value" msgstr "" #: src/config/SSSDConfig/__init__.py.in:121 msgid "Treat usernames as case sensitive" msgstr "" #: src/config/SSSDConfig/__init__.py.in:128 msgid "How often should expired entries be refreshed in background" msgstr "" #: src/config/SSSDConfig/__init__.py.in:129 msgid "Whether to automatically update the client's DNS entry" msgstr "" #: src/config/SSSDConfig/__init__.py.in:130 #: src/config/SSSDConfig/__init__.py.in:144 msgid "The TTL to apply to the client's DNS entry after updating it" msgstr "" #: src/config/SSSDConfig/__init__.py.in:131 #: src/config/SSSDConfig/__init__.py.in:145 msgid "The interface whose IP should be used for dynamic DNS updates" msgstr "" #: src/config/SSSDConfig/__init__.py.in:132 msgid "How often to periodically update the client's DNS entry" msgstr "" #: src/config/SSSDConfig/__init__.py.in:133 msgid "Whether the provider should explicitly update the PTR record as well" msgstr "" #: src/config/SSSDConfig/__init__.py.in:134 msgid "Whether the nsupdate utility should default to using TCP" msgstr "" #: src/config/SSSDConfig/__init__.py.in:135 msgid "What kind of authentication should be used to perform the DNS update" msgstr "" #: src/config/SSSDConfig/__init__.py.in:136 msgid "Control enumeration of trusted domains" msgstr "" #: src/config/SSSDConfig/__init__.py.in:139 msgid "IPA domain" msgstr "IPA 網域" #: src/config/SSSDConfig/__init__.py.in:140 msgid "IPA server address" msgstr "IPA 伺服器位址" #: src/config/SSSDConfig/__init__.py.in:141 msgid "Address of backup IPA server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:142 msgid "IPA client hostname" msgstr "IPA 客戶端主機名稱" #: src/config/SSSDConfig/__init__.py.in:143 msgid "Whether to automatically update the client's DNS entry in FreeIPA" msgstr "" #: src/config/SSSDConfig/__init__.py.in:146 msgid "Search base for HBAC related objects" msgstr "" #: src/config/SSSDConfig/__init__.py.in:147 msgid "" "The amount of time between lookups of the HBAC rules against the IPA server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:148 msgid "" "The amount of time in seconds between lookups of the SELinux maps against " "the IPA server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:149 msgid "If DENY rules are present, either DENY_ALL or IGNORE" msgstr "" #: src/config/SSSDConfig/__init__.py.in:150 msgid "If set to false, host argument given by PAM will be ignored" msgstr "" #: src/config/SSSDConfig/__init__.py.in:151 msgid "The automounter location this IPA client is using" msgstr "" #: src/config/SSSDConfig/__init__.py.in:152 msgid "Search base for object containing info about IPA domain" msgstr "" #: src/config/SSSDConfig/__init__.py.in:153 msgid "Search base for objects containing info about ID ranges" msgstr "" #: src/config/SSSDConfig/__init__.py.in:154 #: src/config/SSSDConfig/__init__.py.in:161 msgid "Enable DNS sites - location based service discovery" msgstr "" #: src/config/SSSDConfig/__init__.py.in:157 msgid "Active Directory domain" msgstr "" #: src/config/SSSDConfig/__init__.py.in:158 msgid "Active Directory server address" msgstr "" #: src/config/SSSDConfig/__init__.py.in:159 msgid "Active Directory backup server address" msgstr "" #: src/config/SSSDConfig/__init__.py.in:160 msgid "Active Directory client hostname" msgstr "" #: src/config/SSSDConfig/__init__.py.in:164 #: src/config/SSSDConfig/__init__.py.in:165 msgid "Kerberos server address" msgstr "Kerberos 伺服器位址" #: src/config/SSSDConfig/__init__.py.in:166 msgid "Kerberos backup server address" msgstr "" #: src/config/SSSDConfig/__init__.py.in:167 msgid "Kerberos realm" msgstr "" #: src/config/SSSDConfig/__init__.py.in:168 msgid "Authentication timeout" msgstr "認證逾時" #: src/config/SSSDConfig/__init__.py.in:169 msgid "Whether to create kdcinfo files" msgstr "" #: src/config/SSSDConfig/__init__.py.in:172 msgid "Directory to store credential caches" msgstr "儲存憑證快取的目錄" #: src/config/SSSDConfig/__init__.py.in:173 msgid "Location of the user's credential cache" msgstr "使用者憑證快取的位置" #: src/config/SSSDConfig/__init__.py.in:174 msgid "Location of the keytab to validate credentials" msgstr "驗證憑證用的金鑰表格位置" #: src/config/SSSDConfig/__init__.py.in:175 msgid "Enable credential validation" msgstr "啟用憑證驗證" #: src/config/SSSDConfig/__init__.py.in:176 msgid "Store password if offline for later online authentication" msgstr "" #: src/config/SSSDConfig/__init__.py.in:177 msgid "Renewable lifetime of the TGT" msgstr "" #: src/config/SSSDConfig/__init__.py.in:178 msgid "Lifetime of the TGT" msgstr "" #: src/config/SSSDConfig/__init__.py.in:179 msgid "Time between two checks for renewal" msgstr "" #: src/config/SSSDConfig/__init__.py.in:180 msgid "Enables FAST" msgstr "" #: src/config/SSSDConfig/__init__.py.in:181 msgid "Selects the principal to use for FAST" msgstr "" #: src/config/SSSDConfig/__init__.py.in:182 msgid "Enables principal canonicalization" msgstr "" #: src/config/SSSDConfig/__init__.py.in:183 msgid "Enables enterprise principals" msgstr "" #: src/config/SSSDConfig/__init__.py.in:186 #: src/config/SSSDConfig/__init__.py.in:187 msgid "Server where the change password service is running if not on the KDC" msgstr "" #: src/config/SSSDConfig/__init__.py.in:190 msgid "ldap_uri, The URI of the LDAP server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:191 msgid "ldap_backup_uri, The URI of the LDAP server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:192 msgid "The default base DN" msgstr "" #: src/config/SSSDConfig/__init__.py.in:193 msgid "The Schema Type in use on the LDAP server, rfc2307" msgstr "" #: src/config/SSSDConfig/__init__.py.in:194 msgid "The default bind DN" msgstr "" #: src/config/SSSDConfig/__init__.py.in:195 msgid "The type of the authentication token of the default bind DN" msgstr "" #: src/config/SSSDConfig/__init__.py.in:196 msgid "The authentication token of the default bind DN" msgstr "" #: src/config/SSSDConfig/__init__.py.in:197 msgid "Length of time to attempt connection" msgstr "" #: src/config/SSSDConfig/__init__.py.in:198 msgid "Length of time to attempt synchronous LDAP operations" msgstr "" #: src/config/SSSDConfig/__init__.py.in:199 msgid "Length of time between attempts to reconnect while offline" msgstr "" #: src/config/SSSDConfig/__init__.py.in:200 msgid "Use only the upper case for realm names" msgstr "" #: src/config/SSSDConfig/__init__.py.in:201 msgid "File that contains CA certificates" msgstr "" #: src/config/SSSDConfig/__init__.py.in:202 msgid "Path to CA certificate directory" msgstr "" #: src/config/SSSDConfig/__init__.py.in:203 msgid "File that contains the client certificate" msgstr "" #: src/config/SSSDConfig/__init__.py.in:204 msgid "File that contains the client key" msgstr "" #: src/config/SSSDConfig/__init__.py.in:205 msgid "List of possible ciphers suites" msgstr "" #: src/config/SSSDConfig/__init__.py.in:206 msgid "Require TLS certificate verification" msgstr "需要 TLS 憑證驗證" #: src/config/SSSDConfig/__init__.py.in:207 msgid "Specify the sasl mechanism to use" msgstr "指定要使用的 sasl 機制" #: src/config/SSSDConfig/__init__.py.in:208 msgid "Specify the sasl authorization id to use" msgstr "指定要使用的 sasl 認證 id" #: src/config/SSSDConfig/__init__.py.in:209 msgid "Specify the sasl authorization realm to use" msgstr "" #: src/config/SSSDConfig/__init__.py.in:210 msgid "Specify the minimal SSF for LDAP sasl authorization" msgstr "" #: src/config/SSSDConfig/__init__.py.in:211 msgid "Kerberos service keytab" msgstr "" #: src/config/SSSDConfig/__init__.py.in:212 msgid "Use Kerberos auth for LDAP connection" msgstr "" #: src/config/SSSDConfig/__init__.py.in:213 msgid "Follow LDAP referrals" msgstr "" #: src/config/SSSDConfig/__init__.py.in:214 msgid "Lifetime of TGT for LDAP connection" msgstr "" #: src/config/SSSDConfig/__init__.py.in:215 msgid "How to dereference aliases" msgstr "" #: src/config/SSSDConfig/__init__.py.in:216 msgid "Service name for DNS service lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:217 msgid "The number of records to retrieve in a single LDAP query" msgstr "" #: src/config/SSSDConfig/__init__.py.in:218 msgid "The number of members that must be missing to trigger a full deref" msgstr "" #: src/config/SSSDConfig/__init__.py.in:219 msgid "" "Whether the LDAP library should perform a reverse lookup to canonicalize the " "host name during a SASL bind" msgstr "" #: src/config/SSSDConfig/__init__.py.in:221 msgid "entryUSN attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:222 msgid "lastUSN attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:224 msgid "How long to retain a connection to the LDAP server before disconnecting" msgstr "" #: src/config/SSSDConfig/__init__.py.in:226 msgid "Disable the LDAP paging control" msgstr "" #: src/config/SSSDConfig/__init__.py.in:227 msgid "Disable Active Directory range retrieval" msgstr "" #: src/config/SSSDConfig/__init__.py.in:230 msgid "Length of time to wait for a search request" msgstr "搜尋請求的等候時間長度" #: src/config/SSSDConfig/__init__.py.in:231 msgid "Length of time to wait for a enumeration request" msgstr "" #: src/config/SSSDConfig/__init__.py.in:232 msgid "Length of time between enumeration updates" msgstr "" #: src/config/SSSDConfig/__init__.py.in:233 msgid "Length of time between cache cleanups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:234 msgid "Require TLS for ID lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:235 msgid "Use ID-mapping of objectSID instead of pre-set IDs" msgstr "" #: src/config/SSSDConfig/__init__.py.in:236 msgid "Base DN for user lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:237 msgid "Scope of user lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:238 msgid "Filter for user lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:239 msgid "Objectclass for users" msgstr "" #: src/config/SSSDConfig/__init__.py.in:240 msgid "Username attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:242 msgid "UID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:243 msgid "Primary GID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:244 msgid "GECOS attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:245 msgid "Home directory attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:246 msgid "Shell attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:247 msgid "UUID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:248 #: src/config/SSSDConfig/__init__.py.in:284 msgid "objectSID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:249 msgid "Active Directory primary group attribute for ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:250 msgid "User principal attribute (for Kerberos)" msgstr "" #: src/config/SSSDConfig/__init__.py.in:251 msgid "Full Name" msgstr "全名" #: src/config/SSSDConfig/__init__.py.in:252 msgid "memberOf attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:253 msgid "Modification time attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:255 msgid "shadowLastChange attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:256 msgid "shadowMin attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:257 msgid "shadowMax attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:258 msgid "shadowWarning attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:259 msgid "shadowInactive attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:260 msgid "shadowExpire attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:261 msgid "shadowFlag attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:262 msgid "Attribute listing authorized PAM services" msgstr "" #: src/config/SSSDConfig/__init__.py.in:263 msgid "Attribute listing authorized server hosts" msgstr "" #: src/config/SSSDConfig/__init__.py.in:264 msgid "krbLastPwdChange attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:265 msgid "krbPasswordExpiration attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:266 msgid "Attribute indicating that server side password policies are active" msgstr "" #: src/config/SSSDConfig/__init__.py.in:267 msgid "accountExpires attribute of AD" msgstr "" #: src/config/SSSDConfig/__init__.py.in:268 msgid "userAccountControl attribute of AD" msgstr "" #: src/config/SSSDConfig/__init__.py.in:269 msgid "nsAccountLock attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:270 msgid "loginDisabled attribute of NDS" msgstr "" #: src/config/SSSDConfig/__init__.py.in:271 msgid "loginExpirationTime attribute of NDS" msgstr "" #: src/config/SSSDConfig/__init__.py.in:272 msgid "loginAllowedTimeMap attribute of NDS" msgstr "" #: src/config/SSSDConfig/__init__.py.in:273 msgid "SSH public key attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:275 msgid "Base DN for group lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:278 msgid "Objectclass for groups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:279 msgid "Group name" msgstr "" #: src/config/SSSDConfig/__init__.py.in:280 msgid "Group password" msgstr "" #: src/config/SSSDConfig/__init__.py.in:281 msgid "GID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:282 msgid "Group member attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:283 msgid "Group UUID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:285 msgid "Modification time attribute for groups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:287 msgid "Maximum nesting level SSSd will follow" msgstr "" #: src/config/SSSDConfig/__init__.py.in:289 msgid "Base DN for netgroup lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:290 msgid "Objectclass for netgroups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:291 msgid "Netgroup name" msgstr "" #: src/config/SSSDConfig/__init__.py.in:292 msgid "Netgroups members attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:293 msgid "Netgroup triple attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:294 msgid "Netgroup UUID attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:295 msgid "Modification time attribute for netgroups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:297 msgid "Base DN for service lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:298 msgid "Objectclass for services" msgstr "" #: src/config/SSSDConfig/__init__.py.in:299 msgid "Service name attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:300 msgid "Service port attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:301 msgid "Service protocol attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:304 msgid "Lower bound for ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:305 msgid "Upper bound for ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:306 msgid "Number of IDs for each slice when ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:307 msgid "Use autorid-compatible algorithm for ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:308 msgid "Name of the default domain for ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:309 msgid "SID of the default domain for ID-mapping" msgstr "" #: src/config/SSSDConfig/__init__.py.in:311 msgid "Use LDAP_MATCHING_RULE_IN_CHAIN for group lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:312 msgid "Use LDAP_MATCHING_RULE_IN_CHAIN for initgroup lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:313 msgid "Set lower boundary for allowed IDs from the LDAP server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:314 msgid "Set upper boundary for allowed IDs from the LDAP server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:317 msgid "Policy to evaluate the password expiration" msgstr "評估密碼過期時效的策略" #: src/config/SSSDConfig/__init__.py.in:320 msgid "LDAP filter to determine access privileges" msgstr "" #: src/config/SSSDConfig/__init__.py.in:321 msgid "Which attributes shall be used to evaluate if an account is expired" msgstr "" #: src/config/SSSDConfig/__init__.py.in:322 msgid "Which rules should be used to evaluate access control" msgstr "" #: src/config/SSSDConfig/__init__.py.in:325 msgid "URI of an LDAP server where password changes are allowed" msgstr "" #: src/config/SSSDConfig/__init__.py.in:326 msgid "URI of a backup LDAP server where password changes are allowed" msgstr "" #: src/config/SSSDConfig/__init__.py.in:327 msgid "DNS service name for LDAP password change server" msgstr "" #: src/config/SSSDConfig/__init__.py.in:328 msgid "" "Whether to update the ldap_user_shadow_last_change attribute after a " "password change" msgstr "" #: src/config/SSSDConfig/__init__.py.in:331 msgid "Base DN for sudo rules lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:332 msgid "Automatic full refresh period" msgstr "" #: src/config/SSSDConfig/__init__.py.in:333 msgid "Automatic smart refresh period" msgstr "" #: src/config/SSSDConfig/__init__.py.in:334 msgid "Whether to filter rules by hostname, IP addresses and network" msgstr "" #: src/config/SSSDConfig/__init__.py.in:335 msgid "" "Hostnames and/or fully qualified domain names of this machine to filter sudo " "rules" msgstr "" #: src/config/SSSDConfig/__init__.py.in:336 msgid "IPv4 or IPv6 addresses or network of this machine to filter sudo rules" msgstr "" #: src/config/SSSDConfig/__init__.py.in:337 msgid "Whether to include rules that contains netgroup in host attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:338 msgid "" "Whether to include rules that contains regular expression in host attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:339 msgid "Object class for sudo rules" msgstr "" #: src/config/SSSDConfig/__init__.py.in:340 msgid "Sudo rule name" msgstr "" #: src/config/SSSDConfig/__init__.py.in:341 msgid "Sudo rule command attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:342 msgid "Sudo rule host attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:343 msgid "Sudo rule user attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:344 msgid "Sudo rule option attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:345 msgid "Sudo rule runasuser attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:346 msgid "Sudo rule runasgroup attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:347 msgid "Sudo rule notbefore attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:348 msgid "Sudo rule notafter attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:349 msgid "Sudo rule order attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:352 msgid "Object class for automounter maps" msgstr "" #: src/config/SSSDConfig/__init__.py.in:353 msgid "Automounter map name attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:354 msgid "Object class for automounter map entries" msgstr "" #: src/config/SSSDConfig/__init__.py.in:355 msgid "Automounter map entry key attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:356 msgid "Automounter map entry value attribute" msgstr "" #: src/config/SSSDConfig/__init__.py.in:357 msgid "Base DN for automounter map lookups" msgstr "" #: src/config/SSSDConfig/__init__.py.in:360 msgid "Comma separated list of allowed users" msgstr "許可的使用者清單,請使用半形逗號作為分隔" #: src/config/SSSDConfig/__init__.py.in:361 msgid "Comma separated list of prohibited users" msgstr "被禁止的使用者清單,請使用半形逗號作為分隔" #: src/config/SSSDConfig/__init__.py.in:364 msgid "Default shell, /bin/bash" msgstr "預設 shell,/bin/bash" #: src/config/SSSDConfig/__init__.py.in:365 msgid "Base for home directories" msgstr "" #: src/config/SSSDConfig/__init__.py.in:368 msgid "The name of the NSS library to use" msgstr "要使用的 NSS 函式庫名稱" #: src/config/SSSDConfig/__init__.py.in:369 msgid "Whether to look up canonical group name from cache if possible" msgstr "" #: src/config/SSSDConfig/__init__.py.in:372 msgid "PAM stack to use" msgstr "要使用的 PAM 堆疊" #: src/monitor/monitor.c:2646 msgid "Become a daemon (default)" msgstr "作為幕後程式 (預設)" #: src/monitor/monitor.c:2648 msgid "Run interactive (not a daemon)" msgstr "以互動方式執行 (非幕後程式)" #: src/monitor/monitor.c:2650 src/tools/sss_debuglevel.c:71 msgid "Specify a non-default config file" msgstr "指定非預設的配置檔" #: src/monitor/monitor.c:2652 msgid "Print version number and exit" msgstr "" #: src/providers/krb5/krb5_child.c:2227 src/providers/ldap/ldap_child.c:435 #: src/util/util.h:93 msgid "Debug level" msgstr "除錯層級" #: src/providers/krb5/krb5_child.c:2229 src/providers/ldap/ldap_child.c:437 #: src/util/util.h:97 msgid "Add debug timestamps" msgstr "加入除錯時間戳記" #: src/providers/krb5/krb5_child.c:2231 src/providers/ldap/ldap_child.c:439 #: src/util/util.h:99 msgid "Show timestamps with microseconds" msgstr "" #: src/providers/krb5/krb5_child.c:2233 src/providers/ldap/ldap_child.c:441 msgid "An open file descriptor for the debug logs" msgstr "" #: src/providers/data_provider_be.c:2850 msgid "Domain of the information provider (mandatory)" msgstr "" #: src/sss_client/common.c:946 msgid "Privileged socket has wrong ownership or permissions." msgstr "" #: src/sss_client/common.c:949 msgid "Public socket has wrong ownership or permissions." msgstr "" #: src/sss_client/common.c:952 msgid "Unexpected format of the server credential message." msgstr "" #: src/sss_client/common.c:955 msgid "SSSD is not run by root." msgstr "" #: src/sss_client/common.c:960 msgid "An error occurred, but no description can be found." msgstr "" #: src/sss_client/common.c:966 msgid "Unexpected error while looking for an error description" msgstr "" #: src/sss_client/pam_sss.c:387 msgid "Passwords do not match" msgstr "密碼不相符" #: src/sss_client/pam_sss.c:575 msgid "Password reset by root is not supported." msgstr "" #: src/sss_client/pam_sss.c:616 msgid "Authenticated with cached credentials" msgstr "" #: src/sss_client/pam_sss.c:617 msgid ", your cached password will expire at: " msgstr ",您快取的密碼將在此刻過期:" #: src/sss_client/pam_sss.c:647 #, c-format msgid "Your password has expired. You have %1$d grace login(s) remaining." msgstr "" #: src/sss_client/pam_sss.c:693 #, c-format msgid "Your password will expire in %1$d %2$s." msgstr "" #: src/sss_client/pam_sss.c:742 msgid "Authentication is denied until: " msgstr "" #: src/sss_client/pam_sss.c:763 msgid "System is offline, password change not possible" msgstr "系統已離線,不可能作密碼變更" #: src/sss_client/pam_sss.c:793 src/sss_client/pam_sss.c:806 msgid "Password change failed. " msgstr "密碼變更失敗。" #: src/sss_client/pam_sss.c:796 src/sss_client/pam_sss.c:807 msgid "Server message: " msgstr "伺服器訊息:" #: src/sss_client/pam_sss.c:1231 msgid "New Password: " msgstr "新密碼:" #: src/sss_client/pam_sss.c:1232 msgid "Reenter new Password: " msgstr "再次輸入新密碼:" #: src/sss_client/pam_sss.c:1318 msgid "Password: " msgstr "密碼:" #: src/sss_client/pam_sss.c:1350 msgid "Current Password: " msgstr "目前的密碼:" #: src/sss_client/pam_sss.c:1497 msgid "Password expired. Change your password now." msgstr "密碼已過期。請立刻變更您的密碼。" #: src/sss_client/ssh/sss_ssh_authorizedkeys.c:40 #: src/sss_client/ssh/sss_ssh_knownhostsproxy.c:192 src/tools/sss_useradd.c:48 #: src/tools/sss_groupadd.c:41 src/tools/sss_groupdel.c:44 #: src/tools/sss_groupmod.c:42 src/tools/sss_groupshow.c:652 #: src/tools/sss_userdel.c:134 src/tools/sss_usermod.c:47 #: src/tools/sss_cache.c:528 src/tools/sss_debuglevel.c:69 msgid "The debug level to run with" msgstr "" #: src/sss_client/ssh/sss_ssh_authorizedkeys.c:42 #: src/sss_client/ssh/sss_ssh_knownhostsproxy.c:196 msgid "The SSSD domain to use" msgstr "" #: src/sss_client/ssh/sss_ssh_authorizedkeys.c:57 src/tools/sss_useradd.c:73 #: src/tools/sss_groupadd.c:58 src/tools/sss_groupdel.c:53 #: src/tools/sss_groupmod.c:65 src/tools/sss_groupshow.c:663 #: src/tools/sss_userdel.c:151 src/tools/sss_usermod.c:74 #: src/tools/sss_cache.c:561 msgid "Error setting the locale\n" msgstr "設定區域設置時發生錯誤\n" #: src/sss_client/ssh/sss_ssh_authorizedkeys.c:64 msgid "Not enough memory\n" msgstr "" #: src/sss_client/ssh/sss_ssh_authorizedkeys.c:83 msgid "User not specified\n" msgstr "" #: src/sss_client/ssh/sss_ssh_authorizedkeys.c:92 msgid "Error looking up public keys\n" msgstr "" #: src/sss_client/ssh/sss_ssh_knownhostsproxy.c:194 msgid "The port to use to connect to the host" msgstr "" #: src/sss_client/ssh/sss_ssh_knownhostsproxy.c:238 msgid "Invalid port\n" msgstr "" #: src/sss_client/ssh/sss_ssh_knownhostsproxy.c:243 msgid "Host not specified\n" msgstr "" #: src/sss_client/ssh/sss_ssh_knownhostsproxy.c:249 msgid "The path to the proxy command must be absolute\n" msgstr "" #: src/tools/sss_useradd.c:49 src/tools/sss_usermod.c:48 msgid "The UID of the user" msgstr "使用者的 UID" #: src/tools/sss_useradd.c:50 src/tools/sss_usermod.c:50 msgid "The comment string" msgstr "註解字串" #: src/tools/sss_useradd.c:51 src/tools/sss_usermod.c:51 msgid "Home directory" msgstr "家目錄" #: src/tools/sss_useradd.c:52 src/tools/sss_usermod.c:52 msgid "Login shell" msgstr "登入用 shell" #: src/tools/sss_useradd.c:53 msgid "Groups" msgstr "群組" #: src/tools/sss_useradd.c:54 msgid "Create user's directory if it does not exist" msgstr "如果使用者的目錄不存在便將它建立" #: src/tools/sss_useradd.c:55 msgid "Never create user's directory, overrides config" msgstr "永遠不建立使用者的目錄,凌駕配置" #: src/tools/sss_useradd.c:56 msgid "Specify an alternative skeleton directory" msgstr "指定替代的骨幹目錄" #: src/tools/sss_useradd.c:57 src/tools/sss_usermod.c:57 msgid "The SELinux user for user's login" msgstr "" #: src/tools/sss_useradd.c:86 src/tools/sss_groupmod.c:78 #: src/tools/sss_usermod.c:87 msgid "Specify group to add to\n" msgstr "" #: src/tools/sss_useradd.c:110 msgid "Specify user to add\n" msgstr "指定要加入的使用者\n" #: src/tools/sss_useradd.c:119 src/tools/sss_groupadd.c:84 #: src/tools/sss_groupdel.c:78 src/tools/sss_groupmod.c:111 #: src/tools/sss_groupshow.c:696 src/tools/sss_userdel.c:196 #: src/tools/sss_usermod.c:128 msgid "Error initializing the tools - no local domain\n" msgstr "初始化工具時發生錯誤 - 沒有本機網域\n" #: src/tools/sss_useradd.c:121 src/tools/sss_groupadd.c:86 #: src/tools/sss_groupdel.c:80 src/tools/sss_groupmod.c:113 #: src/tools/sss_groupshow.c:698 src/tools/sss_userdel.c:198 #: src/tools/sss_usermod.c:130 msgid "Error initializing the tools\n" msgstr "初始化工具時發生錯誤\n" #: src/tools/sss_useradd.c:130 src/tools/sss_groupadd.c:95 #: src/tools/sss_groupdel.c:89 src/tools/sss_groupmod.c:121 #: src/tools/sss_groupshow.c:707 src/tools/sss_userdel.c:207 #: src/tools/sss_usermod.c:139 msgid "Invalid domain specified in FQDN\n" msgstr "在 FQDN 內指定了無效的網域\n" #: src/tools/sss_useradd.c:139 src/tools/sss_groupmod.c:141 #: src/tools/sss_groupmod.c:168 src/tools/sss_usermod.c:162 #: src/tools/sss_usermod.c:189 msgid "Internal error while parsing parameters\n" msgstr "當解析參數時發生內部錯誤\n" #: src/tools/sss_useradd.c:147 src/tools/sss_usermod.c:170 #: src/tools/sss_usermod.c:197 msgid "Groups must be in the same domain as user\n" msgstr "群組必須位於與使用者相同的網域內\n" #: src/tools/sss_useradd.c:155 #, c-format msgid "Cannot find group %1$s in local domain\n" msgstr "" #: src/tools/sss_useradd.c:170 src/tools/sss_userdel.c:217 msgid "Cannot set default values\n" msgstr "無法設定預設值\n" #: src/tools/sss_useradd.c:177 src/tools/sss_usermod.c:153 msgid "The selected UID is outside the allowed range\n" msgstr "所選的 UID 位於許可的範圍外\n" #: src/tools/sss_useradd.c:206 src/tools/sss_usermod.c:264 msgid "Cannot set SELinux login context\n" msgstr "" #: src/tools/sss_useradd.c:221 msgid "Cannot get info about the user\n" msgstr "無法取得關於這位使用者的資訊\n" #: src/tools/sss_useradd.c:233 msgid "User's home directory already exists, not copying data from skeldir\n" msgstr "使用者的家目錄已經存在,不會從骨幹目錄複製資料\n" #: src/tools/sss_useradd.c:236 #, c-format msgid "Cannot create user's home directory: %1$s\n" msgstr "" #: src/tools/sss_useradd.c:247 #, c-format msgid "Cannot create user's mail spool: %1$s\n" msgstr "" #: src/tools/sss_useradd.c:266 msgid "Could not allocate ID for the user - domain full?\n" msgstr "無法為使用者分配 ID - 網域已滿?\n" #: src/tools/sss_useradd.c:270 msgid "A user or group with the same name or ID already exists\n" msgstr "已經存在相同名稱的使用者或群組\n" #: src/tools/sss_useradd.c:276 msgid "Transaction error. Could not add user.\n" msgstr "處理事項發生錯誤。無法加入使用者。\n" #: src/tools/sss_groupadd.c:43 src/tools/sss_groupmod.c:48 msgid "The GID of the group" msgstr "群組的 GID" #: src/tools/sss_groupadd.c:75 msgid "Specify group to add\n" msgstr "指定要加入的群組\n" #: src/tools/sss_groupadd.c:104 src/tools/sss_groupmod.c:192 msgid "The selected GID is outside the allowed range\n" msgstr "所選的 GID 位於許可的範圍外\n" #: src/tools/sss_groupadd.c:141 msgid "Could not allocate ID for the group - domain full?\n" msgstr "無法為群組分配 ID - 網域已滿?\n" #: src/tools/sss_groupadd.c:145 msgid "A group with the same name or GID already exists\n" msgstr "已經存在相同名稱的群組或 GID\n" #: src/tools/sss_groupadd.c:150 msgid "Transaction error. Could not add group.\n" msgstr "處理事項發生錯誤。無法加入群組。\n" #: src/tools/sss_groupdel.c:69 msgid "Specify group to delete\n" msgstr "指定要刪除的群組\n" #: src/tools/sss_groupdel.c:102 #, c-format msgid "Group %1$s is outside the defined ID range for domain\n" msgstr "" #: src/tools/sss_groupdel.c:117 src/tools/sss_groupmod.c:219 #: src/tools/sss_groupmod.c:226 src/tools/sss_groupmod.c:233 #: src/tools/sss_userdel.c:294 src/tools/sss_usermod.c:241 #: src/tools/sss_usermod.c:248 src/tools/sss_usermod.c:255 #, c-format msgid "NSS request failed (%1$d). Entry might remain in memory cache.\n" msgstr "" #: src/tools/sss_groupdel.c:129 msgid "" "No such group in local domain. Removing groups only allowed in local " "domain.\n" msgstr "在本機網域內沒有這樣的群組。只許可在本機網域內移除群組。\n" #: src/tools/sss_groupdel.c:134 msgid "Internal error. Could not remove group.\n" msgstr "內部錯誤。無法移除群組。\n" #: src/tools/sss_groupmod.c:44 msgid "Groups to add this group to" msgstr "" #: src/tools/sss_groupmod.c:46 msgid "Groups to remove this group from" msgstr "" #: src/tools/sss_groupmod.c:86 src/tools/sss_usermod.c:95 msgid "Specify group to remove from\n" msgstr "" #: src/tools/sss_groupmod.c:100 msgid "Specify group to modify\n" msgstr "指定要修改的群組\n" #: src/tools/sss_groupmod.c:128 msgid "" "Cannot find group in local domain, modifying groups is allowed only in local " "domain\n" msgstr "在本機網域內找不到群組,只許可在本機網域內修改群組\n" #: src/tools/sss_groupmod.c:149 src/tools/sss_groupmod.c:176 msgid "Member groups must be in the same domain as parent group\n" msgstr "成員群組必須位於與親代群組相同的網域內\n" #: src/tools/sss_groupmod.c:157 src/tools/sss_groupmod.c:184 #: src/tools/sss_usermod.c:178 src/tools/sss_usermod.c:205 #, c-format msgid "" "Cannot find group %1$s in local domain, only groups in local domain are " "allowed\n" msgstr "" #: src/tools/sss_groupmod.c:250 msgid "Could not modify group - check if member group names are correct\n" msgstr "" #: src/tools/sss_groupmod.c:254 msgid "Could not modify group - check if groupname is correct\n" msgstr "無法修改群組 - 請檢查群組名稱是否正確\n" #: src/tools/sss_groupmod.c:258 msgid "Transaction error. Could not modify group.\n" msgstr "處理事項發生錯誤。無法修改群組。\n" #: src/tools/sss_groupshow.c:599 #, c-format msgid "%1$s%2$sGroup: %3$s\n" msgstr "" #: src/tools/sss_groupshow.c:600 msgid "Magic Private " msgstr "魔法隱私" #: src/tools/sss_groupshow.c:602 #, c-format msgid "%1$sGID number: %2$d\n" msgstr "" #: src/tools/sss_groupshow.c:604 #, c-format msgid "%1$sMember users: " msgstr "" #: src/tools/sss_groupshow.c:611 #, c-format msgid "" "\n" "%1$sIs a member of: " msgstr "" #: src/tools/sss_groupshow.c:618 #, c-format msgid "" "\n" "%1$sMember groups: " msgstr "" #: src/tools/sss_groupshow.c:654 msgid "Print indirect group members recursively" msgstr "遞迴地列出間接的群組成員" #: src/tools/sss_groupshow.c:687 msgid "Specify group to show\n" msgstr "指定要顯示的群組\n" #: src/tools/sss_groupshow.c:726 msgid "" "No such group in local domain. Printing groups only allowed in local " "domain.\n" msgstr "本機網域內沒有這樣的群組。只許可在本機網域內列出群組。\n" #: src/tools/sss_groupshow.c:731 msgid "Internal error. Could not print group.\n" msgstr "內部錯誤。無法列出群組。\n" #: src/tools/sss_userdel.c:136 msgid "Remove home directory and mail spool" msgstr "" #: src/tools/sss_userdel.c:138 msgid "Do not remove home directory and mail spool" msgstr "" #: src/tools/sss_userdel.c:140 msgid "Force removal of files not owned by the user" msgstr "強制檔案的移除並非由使用者所擁有" #: src/tools/sss_userdel.c:142 msgid "Kill users' processes before removing him" msgstr "" #: src/tools/sss_userdel.c:187 msgid "Specify user to delete\n" msgstr "指定要刪除的使用者\n" #: src/tools/sss_userdel.c:233 #, c-format msgid "User %1$s is outside the defined ID range for domain\n" msgstr "" #: src/tools/sss_userdel.c:258 msgid "Cannot reset SELinux login context\n" msgstr "" #: src/tools/sss_userdel.c:270 #, c-format msgid "WARNING: The user (uid %1$lu) was still logged in when deleted.\n" msgstr "" #: src/tool/* * IBM Hot Plug Controller Driver * * Written By: Jyoti Shah, IBM Corporation * * Copyright (C) 2001-2003 IBM Corp. * * All rights reserved. * * 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, GOOD TITLE or * NON INFRINGEMENT. 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * Send feedback to <gregkh@us.ibm.com> * <jshah@us.ibm.com> * */ #include <linux/wait.h> #include <linux/time.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/mutex.h> #include <linux/sched.h> #include <linux/kthread.h> #include "ibmphp.h" static int to_debug = 0; #define debug_polling(fmt, arg...) do { if (to_debug) debug (fmt, arg); } while (0) //---------------------------------------------------------------------------- // timeout values //---------------------------------------------------------------------------- #define CMD_COMPLETE_TOUT_SEC 60 // give HPC 60 sec to finish cmd #define HPC_CTLR_WORKING_TOUT 60 // give HPC 60 sec to finish cmd #define HPC_GETACCESS_TIMEOUT 60 // seconds #define POLL_INTERVAL_SEC 2 // poll HPC every 2 seconds #define POLL_LATCH_CNT 5 // poll latch 5 times, then poll slots //---------------------------------------------------------------------------- // Winnipeg Architected Register Offsets //---------------------------------------------------------------------------- #define WPG_I2CMBUFL_OFFSET 0x08 // I2C Message Buffer Low #define WPG_I2CMOSUP_OFFSET 0x10 // I2C Master Operation Setup Reg #define WPG_I2CMCNTL_OFFSET 0x20 // I2C Master Control Register #define WPG_I2CPARM_OFFSET 0x40 // I2C Parameter Register #define WPG_I2CSTAT_OFFSET 0x70 // I2C Status Register //---------------------------------------------------------------------------- // Winnipeg Store Type commands (Add this commands to the register offset) //---------------------------------------------------------------------------- #define WPG_I2C_AND 0x1000 // I2C AND operation #define WPG_I2C_OR 0x2000 // I2C OR operation //---------------------------------------------------------------------------- // Command set for I2C Master Operation Setup Register //---------------------------------------------------------------------------- #define WPG_READATADDR_MASK 0x00010000 // read,bytes,I2C shifted,index #define WPG_WRITEATADDR_MASK 0x40010000 // write,bytes,I2C shifted,index #define WPG_READDIRECT_MASK 0x10010000 #define WPG_WRITEDIRECT_MASK 0x60010000 //---------------------------------------------------------------------------- // bit masks for I2C Master Control Register //---------------------------------------------------------------------------- #define WPG_I2CMCNTL_STARTOP_MASK 0x00000002 // Start the Operation //---------------------------------------------------------------------------- // //---------------------------------------------------------------------------- #define WPG_I2C_IOREMAP_SIZE 0x2044 // size of linear address interval //---------------------------------------------------------------------------- // command index //---------------------------------------------------------------------------- #define WPG_1ST_SLOT_INDEX 0x01 // index - 1st slot for ctlr #define WPG_CTLR_INDEX 0x0F // index - ctlr #define WPG_1ST_EXTSLOT_INDEX 0x10 // index - 1st ext slot for ctlr #define WPG_1ST_BUS_INDEX 0x1F // index - 1st bus for ctlr //---------------------------------------------------------------------------- // macro utilities //---------------------------------------------------------------------------- // if bits 20,22,25,26,27,29,30 are OFF return 1 #define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? 0 : 1)) //---------------------------------------------------------------------------- // global variables //---------------------------------------------------------------------------- static struct mutex sem_hpcaccess; // lock access to HPC static struct semaphore semOperations; // lock all operations and // access to data structures static struct semaphore sem_exit; // make sure polling thread goes away static struct task_struct *ibmphp_poll_thread; //---------------------------------------------------------------------------- // local function prototypes //---------------------------------------------------------------------------- static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8); static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8); static u8 hpc_writecmdtoindex (u8, u8); static u8 hpc_readcmdtoindex (u8, u8); static void get_hpc_access (void); static void free_hpc_access (void); static int poll_hpc(void *data); static int process_changeinstatus (struct slot *, struct slot *); static int process_changeinlatch (u8, u8, struct controller *); static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *); //---------------------------------------------------------------------------- /*---------------------------------------------------------------------- * Name: ibmphp_hpc_initvars * * Action: initialize semaphores and variables *---------------------------------------------------------------------*/ void __init ibmphp_hpc_initvars (void) { debug ("%s - Entry\n", __func__); mutex_init(&sem_hpcaccess); init_MUTEX (&semOperations); init_MUTEX_LOCKED (&sem_exit); to_debug = 0; debug ("%s - Exit\n", __func__); } /*---------------------------------------------------------------------- * Name: i2c_ctrl_read * * Action: read from HPC over I2C * *---------------------------------------------------------------------*/ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index) { u8 status; int i; void __iomem *wpg_addr; // base addr + offset unsigned long wpg_data; // data to/from WPG LOHI format unsigned long ultemp; unsigned long data; // actual data HILO format debug_polling ("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index); //-------------------------------------------------------------------- // READ - step 1 // read at address, byte length, I2C address (shifted), index // or read direct, byte length, index if (ctlr_ptr->ctlr_type == 0x02) { data = WPG_READATADDR_MASK; // fill in I2C address ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr; ultemp = ultemp >> 1; data |= (ultemp << 8); // fill in index data |= (unsigned long)index; } else if (ctlr_ptr->ctlr_type == 0x04) { data = WPG_READDIRECT_MASK; // fill in index ultemp = (unsigned long)index; ultemp = ultemp << 8; data |= ultemp; } else { err ("this controller type is not supported \n"); return HPC_ERROR; } wpg_data = swab32 (data); // swap data before writing wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // READ - step 2 : clear the message buffer data = 0x00000000; wpg_data = swab32 (data); wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // READ - step 3 : issue start operation, I2C master control bit 30:ON // 2020 : [20] OR operation at [20] offset 0x20 data = WPG_I2CMCNTL_STARTOP_MASK; wpg_data = swab32 (data); wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // READ - step 4 : wait until start operation bit clears i = CMD_COMPLETE_TOUT_SEC; while (i) { msleep(10); wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (!(data & WPG_I2CMCNTL_STARTOP_MASK)) break; i--; } if (i == 0) { debug ("%s - Error : WPG timeout\n", __func__); return HPC_ERROR; } //-------------------------------------------------------------------- // READ - step 5 : read I2C status register i = CMD_COMPLETE_TOUT_SEC; while (i) { msleep(10); wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (HPC_I2CSTATUS_CHECK (data)) break; i--; } if (i == 0) { debug ("ctrl_read - Exit Error:I2C timeout\n"); return HPC_ERROR; } //-------------------------------------------------------------------- // READ - step 6 : get DATA wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); status = (u8) data; debug_polling ("%s - Exit index[%x] status[%x]\n", __func__, index, status); return (status); } /*---------------------------------------------------------------------- * Name: i2c_ctrl_write * * Action: write to HPC over I2C * * Return 0 or error codes *---------------------------------------------------------------------*/ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd) { u8 rc; void __iomem *wpg_addr; // base addr + offset unsigned long wpg_data; // data to/from WPG LOHI format unsigned long ultemp; unsigned long data; // actual data HILO format int i; debug_polling ("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __func__, WPGBbar, index, cmd); rc = 0; //-------------------------------------------------------------------- // WRITE - step 1 // write at address, byte length, I2C address (shifted), index // or write direct, byte length, index data = 0x00000000; if (ctlr_ptr->ctlr_type == 0x02) { data = WPG_WRITEATADDR_MASK; // fill in I2C address ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr; ultemp = ultemp >> 1; data |= (ultemp << 8); // fill in index data |= (unsigned long)index; } else if (ctlr_ptr->ctlr_type == 0x04) { data = WPG_WRITEDIRECT_MASK; // fill in index ultemp = (unsigned long)index; ultemp = ultemp << 8; data |= ultemp; } else { err ("this controller type is not supported \n"); return HPC_ERROR; } wpg_data = swab32 (data); // swap data before writing wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // WRITE - step 2 : clear the message buffer data = 0x00000000 | (unsigned long)cmd; wpg_data = swab32 (data); wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // WRITE - step 3 : issue start operation,I2C master control bit 30:ON // 2020 : [20] OR operation at [20] offset 0x20 data = WPG_I2CMCNTL_STARTOP_MASK; wpg_data = swab32 (data); wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // WRITE - step 4 : wait until start operation bit clears i = CMD_COMPLETE_TOUT_SEC; while (i) { msleep(10); wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (!(data & WPG_I2CMCNTL_STARTOP_MASK)) break; i--; } if (i == 0) { debug ("%s - Exit Error:WPG timeout\n", __func__); rc = HPC_ERROR; } //-------------------------------------------------------------------- // WRITE - step 5 : read I2C status register i = CMD_COMPLETE_TOUT_SEC; while (i) { msleep(10); wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (HPC_I2CSTATUS_CHECK (data)) break; i--; } if (i == 0) { debug ("ctrl_read - Error : I2C timeout\n"); rc = HPC_ERROR; } debug_polling ("%s Exit rc[%x]\n", __func__, rc); return (rc); } //------------------------------------------------------------ // Read from ISA type HPC //------------------------------------------------------------ static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset) { u16 start_address; u16 end_address; u8 data; start_address = ctlr_ptr->u.isa_ctlr.io_start; end_address = ctlr_ptr->u.isa_ctlr.io_end; data = inb (start_address + offset); return data; } //-------------------------------------------------------------- // Write to ISA type HPC //-------------------------------------------------------------- static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data) { u16 start_address; u16 port_address; start_address = ctlr_ptr->u.isa_ctlr.io_start; port_address = start_address + (u16) offset; outb (data, port_address); } static u8 pci_ctrl_read (struct controller *ctrl, u8 offset) { u8 data = 0x00; debug ("inside pci_ctrl_read\n"); if (ctrl->ctrl_dev) pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data); return data; } static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data) { u8 rc = -ENODEV; debug ("inside pci_ctrl_write\n"); if (ctrl->ctrl_dev) { pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data); rc = 0; } return rc; } static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset) { u8 rc; switch (ctlr->ctlr_type) { case 0: rc = isa_ctrl_read (ctlr, offset); break; case 1: rc = pci_ctrl_read (ctlr, offset); break; case 2: case 4: rc = i2c_ctrl_read (ctlr, base, offset); break; default: return -ENODEV; } return rc; } static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data) { u8 rc = 0; switch (ctlr->ctlr_type) { case 0: isa_ctrl_write(ctlr, offset, data); break; case 1: rc = pci_ctrl_write (ctlr, offset, data); break; case 2: case 4: rc = i2c_ctrl_write(ctlr, base, offset, data); break; default: return -ENODEV; } return rc; } /*---------------------------------------------------------------------- * Name: hpc_writecmdtoindex() * * Action: convert a write command to proper index within a controller * * Return index, HPC_ERROR *---------------------------------------------------------------------*/ static u8 hpc_writecmdtoindex (u8 cmd, u8 index) { u8 rc; switch (cmd) { case HPC_CTLR_ENABLEIRQ: // 0x00.N.15 case HPC_CTLR_CLEARIRQ: // 0x06.N.15 case HPC_CTLR_RESET: // 0x07.N.15 case HPC_CTLR_IRQSTEER: // 0x08.N.15 case HPC_CTLR_DISABLEIRQ: // 0x01.N.15 case HPC_ALLSLOT_ON: // 0x11.N.15 case HPC_ALLSLOT_OFF: // 0x12.N.15 rc = 0x0F; break; case HPC_SLOT_OFF: // 0x02.Y.0-14 case HPC_SLOT_ON: // 0x03.Y.0-14 case HPC_SLOT_ATTNOFF: // 0x04.N.0-14 case HPC_SLOT_ATTNON: // 0x05.N.0-14 case HPC_SLOT_BLINKLED: // 0x13.N.0-14 rc = index; break; case HPC_BUS_33CONVMODE: case HPC_BUS_66CONVMODE: case HPC_BUS_66PCIXMODE: case HPC_BUS_100PCIXMODE: case HPC_BUS_133PCIXMODE: rc = index + WPG_1ST_BUS_INDEX - 1; break; default: err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd); rc = HPC_ERROR; } return rc; } /*---------------------------------------------------------------------- * Name: hpc_readcmdtoindex() * * Action: convert a read command to proper index within a controller * * Return index, HPC_ERROR *---------------------------------------------------------------------*/ static u8 hpc_readcmdtoindex (u8 cmd, u8 index) { u8 rc; switch (cmd) { case READ_CTLRSTATUS: rc = 0x0F; break; case READ_SLOTSTATUS: case READ_ALLSTAT: rc = index; break; case READ_EXTSLOTSTATUS: rc = index + WPG_1ST_EXTSLOT_INDEX; break; case READ_BUSSTATUS: rc = index + WPG_1ST_BUS_INDEX - 1; break; case READ_SLOTLATCHLOWREG: rc = 0x28; break; case READ_REVLEVEL: rc = 0x25; break; case READ_HPCOPTIONS: rc = 0x27; break; default: rc = HPC_ERROR; } return rc; } /*---------------------------------------------------------------------- * Name: HPCreadslot() * * Action: issue a READ command to HPC * * Input: pslot - cannot be NULL for READ_ALLSTAT * pstatus - can be NULL for READ_ALLSTAT * * Return 0 or error codes *---------------------------------------------------------------------*/ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) { void __iomem *wpg_bbar = NULL; struct controller *ctlr_ptr; struct list_head *pslotlist; u8 index, status; int rc = 0; int busindex; debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus); if ((pslot == NULL) || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) { rc = -EINVAL; err ("%s - Error invalid pointer, rc[%d]\n", __func__, rc); return rc; } if (cmd == READ_BUSSTATUS) { busindex = ibmphp_get_bus_index (pslot->bus); if (busindex < 0) { rc = -EINVAL; err ("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc); return rc; } else index = (u8) busindex; } else index = pslot->ctlr_index; index = hpc_readcmdtoindex (cmd, index); if (index == HPC_ERROR) { rc = -EINVAL; err ("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc); return rc; } ctlr_ptr = pslot->ctrl; get_hpc_access (); //-------------------------------------------------------------------- // map physical address to logical address //-------------------------------------------------------------------- if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); //-------------------------------------------------------------------- // check controller status before reading //-------------------------------------------------------------------- rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { switch (cmd) { case READ_ALLSTAT: // update the slot structure pslot->ctrl->status = status; pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index); rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX); break; case READ_SLOTSTATUS: // DO NOT update the slot structure *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_EXTSLOTSTATUS: // DO NOT update the slot structure *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_CTLRSTATUS: // DO NOT update the slot structure *pstatus = status; break; case READ_BUSSTATUS: pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_REVLEVEL: *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_HPCOPTIONS: *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_SLOTLATCHLOWREG: // DO NOT update the slot structure *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; // Not used case READ_ALLSLOT: list_for_each (pslotlist, &ibmphp_slot_head) { pslot = list_entry (pslotlist, struct slot, ibm_slot_list); index = pslot->ctlr_index; rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index); rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX); } else { err ("%s - Error ctrl_read failed\n", __func__); rc = -EINVAL; break; } } break; default: rc = -EINVAL; break; } } //-------------------------------------------------------------------- // cleanup //-------------------------------------------------------------------- // remove physical to logical address mapping if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) iounmap (wpg_bbar); free_hpc_access (); debug_polling ("%s - Exit rc[%d]\n", __func__, rc); return rc; } /*---------------------------------------------------------------------- * Name: ibmphp_hpc_writeslot() * * Action: issue a WRITE command to HPC *---------------------------------------------------------------------*/ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) { void __iomem *wpg_bbar = NULL; struct controller *ctlr_ptr; u8 index, status; int busindex; u8 done; int rc = 0; int timeout; debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd); if (pslot == NULL) { rc = -EINVAL; err ("%s - Error Exit rc[%d]\n", __func__, rc); return rc; } if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) || (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) || (cmd == HPC_BUS_133PCIXMODE)) { busindex = ibmphp_get_bus_index (pslot->bus); if (busindex < 0) { rc = -EINVAL; err ("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc); return rc; } else index = (u8) busindex; } else index = pslot->ctlr_index; index = hpc_writecmdtoindex (cmd, index); if (index == HPC_ERROR) { rc = -EINVAL; err ("%s - Error Exit rc[%d]\n", __func__, rc); return rc; } ctlr_ptr = pslot->ctrl; get_hpc_access (); //-------------------------------------------------------------------- // map physical address to logical address //-------------------------------------------------------------------- if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) { wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__, ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar, ctlr_ptr->u.wpeg_ctlr.i2c_addr); } //-------------------------------------------------------------------- // check controller status before writing //-------------------------------------------------------------------- rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { ctrl_write (ctlr_ptr, wpg_bbar, index, cmd); //-------------------------------------------------------------------- // check controller is still not working on the command //-------------------------------------------------------------------- timeout = CMD_COMPLETE_TOUT_SEC; done = 0; while (!done) { rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { if (NEEDTOCHECK_CMDSTATUS (cmd)) { if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES) done = 1; } else done = 1; } if (!done) { msleep(1000); if (timeout < 1) { done = 1; err ("%s - Error command complete timeout\n", __func__); rc = -EFAULT; } else timeout--; } } ctlr_ptr->status = status; } // cleanup // remove physical to logical address mapping if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) iounmap (wpg_bbar); free_hpc_access (); debug_polling ("%s - Exit rc[%d]\n", __func__, rc); return rc; } /*---------------------------------------------------------------------- * Name: get_hpc_access() * * Action: make sure only one process can access HPC at one time *---------------------------------------------------------------------*/ static void get_hpc_access (void) { mutex_lock(&sem_hpcaccess); } /*---------------------------------------------------------------------- * Name: free_hpc_access() *---------------------------------------------------------------------*/ void free_hpc_access (void) { mutex_unlock(&sem_hpcaccess); } /*---------------------------------------------------------------------- * Name: ibmphp_lock_operations() * * Action: make sure only one process can change the data structure *---------------------------------------------------------------------*/ void ibmphp_lock_operations (void) { down (&semOperations); to_debug = 1; } /*---------------------------------------------------------------------- * Name: ibmphp_unlock_operations() *---------------------------------------------------------------------*/ void ibmphp_unlock_operations (void) { debug ("%s - Entry\n", __func__); up (&semOperations); to_debug = 0; debug ("%s - Exit\n", __func__); } /*---------------------------------------------------------------------- * Name: poll_hpc() *---------------------------------------------------------------------*/ #define POLL_LATCH_REGISTER 0 #define POLL_SLOTS 1 #define POLL_SLEEP 2 static int poll_hpc(void *data) { struct slot myslot; struct slot *pslot = NULL; struct list_head *pslotlist; int rc; int poll_state = POLL_LATCH_REGISTER; u8 oldlatchlow = 0x00; u8 curlatchlow = 0x00; int poll_count = 0; u8 ctrl_count = 0x00; debug ("%s - Entry\n", __func__); while (!kthread_should_stop()) { /* try to get the lock to do some kind of hardware access */ down (&semOperations); switch (poll_state) { case POLL_LATCH_REGISTER: oldlatchlow = curlatchlow; ctrl_count = 0x00; list_for_each (pslotlist, &ibmphp_slot_head) { if (ctrl_count >= ibmphp_get_total_controllers()) break; pslot = list_entry (pslotlist, struct slot, ibm_slot_list); if (pslot->ctrl->ctlr_relative_id == ctrl_count) { ctrl_count++; if (READ_SLOT_LATCH (pslot->ctrl)) { rc = ibmphp_hpc_readslot (pslot, READ_SLOTLATCHLOWREG, &curlatchlow); if (oldlatchlow != curlatchlow) process_changeinlatch (oldlatchlow, curlatchlow, pslot->ctrl); } } } ++poll_count; poll_state = POLL_SLEEP; break; case POLL_SLOTS: list_for_each (pslotlist, &ibmphp_slot_head) { pslot = list_entry (pslotlist, struct slot, ibm_slot_list); // make a copy of the old status memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot)); rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL); if ((myslot.status != pslot->status) || (myslot.ext_status != pslot->ext_status)) process_changeinstatus (pslot, &myslot); } ctrl_count = 0x00; list_for_each (pslotlist, &ibmphp_slot_head) { if (ctrl_count >= ibmphp_get_total_controllers()) break; pslot = list_entry (pslotlist, struct slot, ibm_slot_list); if (pslot->ctrl->ctlr_relative_id == ctrl_count) { ctrl_count++; if (READ_SLOT_LATCH (pslot->ctrl)) rc = ibmphp_hpc_readslot (pslot, READ_SLOTLATCHLOWREG, &curlatchlow); } } ++poll_count; poll_state = POLL_SLEEP; break; case POLL_SLEEP: /* don't sleep with a lock on the hardware */ up (&semOperations); msleep(POLL_INTERVAL_SEC * 1000); if (kthread_should_stop()) goto out_sleep; down (&semOperations); if (poll_count >= POLL_LATCH_CNT) { poll_count = 0; poll_state = POLL_SLOTS; } else poll_state = POLL_LATCH_REGISTER; break; } /* give up the hardware semaphore */ up (&semOperations); /* sleep for a short time just for good measure */ out_sleep: msleep(100); } up (&sem_exit); debug ("%s - Exit\n", __func__); return 0; } /*---------------------------------------------------------------------- * Name: process_changeinstatus * * Action: compare old and new slot status, process the change in status * * Input: pointer to slot struct, old slot struct * * Return 0 or error codes * Value: * * Side * Effects: None. * * Notes: *---------------------------------------------------------------------*/ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot) { u8 status; int rc = 0; u8 disable = 0; u8 update = 0; debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot); // bit 0 - HPC_SLOT_POWER if ((pslot->status & 0x01) != (poldslot->status & 0x01)) update = 1; // bit 1 - HPC_SLOT_CONNECT // ignore // bit 2 - HPC_SLOT_ATTN if ((pslot->status & 0x04) != (poldslot->status & 0x04)) update = 1; // bit 3 - HPC_SLOT_PRSNT2 // bit 4 - HPC_SLOT_PRSNT1 if (((pslot->status & 0x08) != (poldslot->status & 0x08)) || ((pslot->status & 0x10) != (poldslot->status & 0x10))) update = 1; // bit 5 - HPC_SLOT_PWRGD if ((pslot->status & 0x20) != (poldslot->status & 0x20)) // OFF -> ON: ignore, ON -> OFF: disable slot if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) disable = 1; // bit 6 - HPC_SLOT_BUS_SPEED // ignore // bit 7 - HPC_SLOT_LATCH if ((pslot->status & 0x80) != (poldslot->status & 0x80)) { update = 1; // OPEN -> CLOSE if (pslot->status & 0x80) { if (SLOT_PWRGD (pslot->status)) { // power goes on and off after closing latch // check again to make sure power is still ON msleep(1000); rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status); if (SLOT_PWRGD (status)) update = 1; else // overwrite power in pslot to OFF pslot->status &= ~HPC_SLOT_POWER; } } // CLOSE -> OPEN else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) { disable = 1; } // else - ignore } // bit 4 - HPC_SLOT_BLINK_ATTN if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08)) update = 1; if (disable) { debug ("process_changeinstatus - disable slot\n"); pslot->flag = 0; rc = ibmphp_do_disable_slot (pslot); } if (update || disable) { ibmphp_update_slot_info (pslot); } debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update); return rc; } /*---------------------------------------------------------------------- * Name: process_changeinlatch * * Action: compare old and new latch reg status, process the change * * Input: old and current latch register status * * Return 0 or error codes * Value: *---------------------------------------------------------------------*/ static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl) { struct slot myslot, *pslot; u8 i; u8 mask; int rc = 0; debug ("%s - Entry old[%x], new[%x]\n", __func__, old, new); // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) { mask = 0x01 << i; if ((mask & old) != (mask & new)) { pslot = ibmphp_get_slot_from_physical_num (i); if (pslot) { memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot)); rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL); debug ("%s - call process_changeinstatus for slot[%d]\n", __func__, i); process_changeinstatus (pslot, &myslot); } else { rc = -EINVAL; err ("%s - Error bad pointer for slot[%d]\n", __func__, i); } } } debug ("%s - Exit rc[%d]\n", __func__, rc); return rc; } /*---------------------------------------------------------------------- * Name: ibmphp_hpc_start_poll_thread * * Action: start polling thread *---------------------------------------------------------------------*/ int __init ibmphp_hpc_start_poll_thread (void) { debug ("%s - Entry\n", __func__); ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll"); if (IS_ERR(ibmphp_poll_thread)) { err ("%s - Error, thread not started\n", __func__); return PTR_ERR(ibmphp_poll_thread); } return 0; } /*---------------------------------------------------------------------- * Name: ibmphp_hpc_stop_poll_thread * * Action: stop polling thread and cleanup *---------------------------------------------------------------------*/ void __exit ibmphp_hpc_stop_poll_thread (void) { debug ("%s - Entry\n", __func__); kthread_stop(ibmphp_poll_thread); debug ("before locking operations \n"); ibmphp_lock_operations (); debug ("after locking operations \n"); // wait for poll thread to exit debug ("before sem_exit down \n"); down (&sem_exit); debug ("after sem_exit down \n"); // cleanup debug ("before free_hpc_access \n"); free_hpc_access (); debug ("after free_hpc_access \n"); ibmphp_unlock_operations (); debug ("after unlock operations \n"); up (&sem_exit); debug ("after sem exit up\n"); debug ("%s - Exit\n", __func__); } /*---------------------------------------------------------------------- * Name: hpc_wait_ctlr_notworking * * Action: wait until the controller is in a not working state * * Return 0, HPC_ERROR * Value: *---------------------------------------------------------------------*/ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar, u8 * pstatus) { int rc = 0; u8 done = 0; debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout); while (!done) { *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX); if (*pstatus == HPC_ERROR) { rc = HPC_ERROR; done = 1; } if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO) done = 1; if (!done) { msleep(1000); if (timeout < 1) { done = 1; err ("HPCreadslot - Error ctlr timeout\n"); rc = HPC_ERROR; } else timeout--; } } debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus); return rc; }