Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[S390] ap: toleration support for ap device type 10

Add toleration support for ap devices with device type 10.

Signed-off-by: Holger Dengler <hd@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Holger Dengler and committed by
Martin Schwidefsky
6bed05bc fdb204d1

+107 -43
+86 -42
drivers/s390/crypto/ap_bus.c
··· 6 6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 7 * Ralph Wuerthner <rwuerthn@de.ibm.com> 8 8 * Felix Beck <felix.beck@de.ibm.com> 9 + * Holger Dengler <hd@linux.vnet.ibm.com> 9 10 * 10 11 * Adjunct processor bus. 11 12 * ··· 223 222 } 224 223 #endif 225 224 226 - static inline struct ap_queue_status __ap_4096_commands_available(ap_qid_t qid, 227 - int *support) 225 + #ifdef CONFIG_64BIT 226 + static inline struct ap_queue_status 227 + __ap_query_functions(ap_qid_t qid, unsigned int *functions) 228 228 { 229 229 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23); 230 - register struct ap_queue_status reg1 asm ("1"); 231 - register unsigned long reg2 asm ("2") = 0UL; 230 + register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID; 231 + register unsigned long reg2 asm ("2"); 232 232 233 233 asm volatile( 234 234 ".long 0xb2af0000\n" 235 - "0: la %1,0\n" 236 - "1:\n" 237 - EX_TABLE(0b, 1b) 238 - : "+d" (reg0), "=d" (reg1), "=d" (reg2) 235 + "0:\n" 236 + EX_TABLE(0b, 0b) 237 + : "+d" (reg0), "+d" (reg1), "=d" (reg2) 239 238 : 240 239 : "cc"); 241 240 242 - if (reg2 & 0x6000000000000000ULL) 243 - *support = 1; 244 - else 245 - *support = 0; 246 - 241 + *functions = (unsigned int)(reg2 >> 32); 247 242 return reg1; 243 + } 244 + #endif 245 + 246 + /** 247 + * ap_query_functions(): Query supported functions. 248 + * @qid: The AP queue number 249 + * @functions: Pointer to functions field. 250 + * 251 + * Returns 252 + * 0 on success. 253 + * -ENODEV if queue not valid. 254 + * -EBUSY if device busy. 255 + * -EINVAL if query function is not supported 256 + */ 257 + static int ap_query_functions(ap_qid_t qid, unsigned int *functions) 258 + { 259 + #ifdef CONFIG_64BIT 260 + struct ap_queue_status status; 261 + int i; 262 + status = __ap_query_functions(qid, functions); 263 + 264 + for (i = 0; i < AP_MAX_RESET; i++) { 265 + if (ap_queue_status_invalid_test(&status)) 266 + return -ENODEV; 267 + 268 + switch (status.response_code) { 269 + case AP_RESPONSE_NORMAL: 270 + return 0; 271 + case AP_RESPONSE_RESET_IN_PROGRESS: 272 + case AP_RESPONSE_BUSY: 273 + break; 274 + case AP_RESPONSE_Q_NOT_AVAIL: 275 + case AP_RESPONSE_DECONFIGURED: 276 + case AP_RESPONSE_CHECKSTOPPED: 277 + case AP_RESPONSE_INVALID_ADDRESS: 278 + return -ENODEV; 279 + case AP_RESPONSE_OTHERWISE_CHANGED: 280 + break; 281 + default: 282 + break; 283 + } 284 + if (i < AP_MAX_RESET - 1) { 285 + udelay(5); 286 + status = __ap_query_functions(qid, functions); 287 + } 288 + } 289 + return -EBUSY; 290 + #else 291 + return -EINVAL; 292 + #endif 248 293 } 249 294 250 295 /** ··· 302 255 */ 303 256 int ap_4096_commands_available(ap_qid_t qid) 304 257 { 305 - struct ap_queue_status status; 306 - int i, support = 0; 307 - status = __ap_4096_commands_available(qid, &support); 258 + unsigned int functions; 308 259 309 - for (i = 0; i < AP_MAX_RESET; i++) { 310 - switch (status.response_code) { 311 - case AP_RESPONSE_NORMAL: 312 - return support; 313 - case AP_RESPONSE_RESET_IN_PROGRESS: 314 - case AP_RESPONSE_BUSY: 315 - break; 316 - case AP_RESPONSE_Q_NOT_AVAIL: 317 - case AP_RESPONSE_DECONFIGURED: 318 - case AP_RESPONSE_CHECKSTOPPED: 319 - case AP_RESPONSE_INVALID_ADDRESS: 320 - return 0; 321 - case AP_RESPONSE_OTHERWISE_CHANGED: 322 - break; 323 - default: 324 - break; 325 - } 326 - if (i < AP_MAX_RESET - 1) { 327 - udelay(5); 328 - status = __ap_4096_commands_available(qid, &support); 329 - } 330 - } 331 - return support; 260 + if (ap_query_functions(qid, &functions)) 261 + return 0; 262 + 263 + return test_ap_facility(functions, 1) && 264 + test_ap_facility(functions, 2); 332 265 } 333 266 EXPORT_SYMBOL(ap_4096_commands_available); 334 267 ··· 1162 1135 struct device *dev; 1163 1136 ap_qid_t qid; 1164 1137 int queue_depth, device_type; 1138 + unsigned int device_functions; 1165 1139 int rc, i; 1166 1140 1167 1141 if (ap_select_domain() != 0) ··· 1211 1183 INIT_LIST_HEAD(&ap_dev->list); 1212 1184 setup_timer(&ap_dev->timeout, ap_request_timeout, 1213 1185 (unsigned long) ap_dev); 1214 - if (device_type == 0) { 1186 + switch (device_type) { 1187 + case 0: 1215 1188 if (ap_probe_device_type(ap_dev)) { 1216 1189 kfree(ap_dev); 1217 1190 continue; 1218 1191 } 1219 - } 1220 - else 1192 + break; 1193 + case 10: 1194 + if (ap_query_functions(qid, &device_functions)) { 1195 + kfree(ap_dev); 1196 + continue; 1197 + } 1198 + if (test_ap_facility(device_functions, 3)) 1199 + ap_dev->device_type = AP_DEVICE_TYPE_CEX3C; 1200 + else if (test_ap_facility(device_functions, 4)) 1201 + ap_dev->device_type = AP_DEVICE_TYPE_CEX3A; 1202 + else { 1203 + kfree(ap_dev); 1204 + continue; 1205 + } 1206 + break; 1207 + default: 1221 1208 ap_dev->device_type = device_type; 1209 + } 1222 1210 1223 1211 ap_dev->device.bus = &ap_bus_type; 1224 1212 ap_dev->device.parent = ap_root_device;
+21 -1
drivers/s390/crypto/ap_bus.h
··· 6 6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 7 * Ralph Wuerthner <rwuerthn@de.ibm.com> 8 8 * Felix Beck <felix.beck@de.ibm.com> 9 + * Holger Dengler <hd@linux.vnet.ibm.com> 9 10 * 10 11 * Adjunct processor bus header file. 11 12 * ··· 73 72 unsigned int int_enabled : 1; 74 73 unsigned int response_code : 8; 75 74 unsigned int pad2 : 16; 76 - }; 75 + } __packed; 76 + 77 + #define AP_QUEUE_STATUS_INVALID \ 78 + { 1, 1, 1, 0xF, 1, 0xFF, 0xFFFF } 79 + 80 + static inline 81 + int ap_queue_status_invalid_test(struct ap_queue_status *status) 82 + { 83 + struct ap_queue_status invalid = AP_QUEUE_STATUS_INVALID; 84 + return !(memcmp(status, &invalid, sizeof(struct ap_queue_status))); 85 + } 86 + 87 + #define MAX_AP_FACILITY 31 88 + 89 + static inline int test_ap_facility(unsigned int function, unsigned int nr) 90 + { 91 + if (nr > MAX_AP_FACILITY) 92 + return 0; 93 + return function & (unsigned int)(0x80000000 >> nr); 94 + } 77 95 78 96 #define AP_RESPONSE_NORMAL 0x00 79 97 #define AP_RESPONSE_Q_NOT_AVAIL 0x01