aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Beck <felix.beck@de.ibm.com>2011-01-05 06:47:44 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 06:47:27 -0500
commitb1f933da570576d1f290ea4dc9b896404cbd285d (patch)
treef995659952ac3ccdfde34c13e7d484ced01b6777
parent2fcb3686e1601cff992e026dceeab1b22dc81178 (diff)
[S390] zcrypt: Introduce check for 4096 bit support.
Implemented an asm in the ap bus and made it accessible for the card specific parts of the zcrypt driver. Thus when a cex3a is recognized a check can be performed to dermine whether the card supports 4096 bit RSA keys. Signed-off-by: Felix Beck <felix.beck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/crypto/ap_bus.c63
-rw-r--r--drivers/s390/crypto/ap_bus.h2
2 files changed, 65 insertions, 0 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 4f37c45ee114..67302b944ab3 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -222,6 +222,69 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind)
222} 222}
223#endif 223#endif
224 224
225static inline struct ap_queue_status __ap_4096_commands_available(ap_qid_t qid,
226 int *support)
227{
228 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
229 register struct ap_queue_status reg1 asm ("1");
230 register unsigned long reg2 asm ("2") = 0UL;
231
232 asm volatile(
233 ".long 0xb2af0000\n"
234 "0: la %1,0\n"
235 "1:\n"
236 EX_TABLE(0b, 1b)
237 : "+d" (reg0), "=d" (reg1), "=d" (reg2)
238 :
239 : "cc");
240
241 if (reg2 & 0x6000000000000000ULL)
242 *support = 1;
243 else
244 *support = 0;
245
246 return reg1;
247}
248
249/**
250 * ap_4096_commands_availablen(): Check for availability of 4096 bit RSA
251 * support.
252 * @qid: The AP queue number
253 *
254 * Returns 1 if 4096 bit RSA keys are support fo the AP, returns 0 if not.
255 */
256int ap_4096_commands_available(ap_qid_t qid)
257{
258 struct ap_queue_status status;
259 int i, support = 0;
260 status = __ap_4096_commands_available(qid, &support);
261
262 for (i = 0; i < AP_MAX_RESET; i++) {
263 switch (status.response_code) {
264 case AP_RESPONSE_NORMAL:
265 return support;
266 case AP_RESPONSE_RESET_IN_PROGRESS:
267 case AP_RESPONSE_BUSY:
268 break;
269 case AP_RESPONSE_Q_NOT_AVAIL:
270 case AP_RESPONSE_DECONFIGURED:
271 case AP_RESPONSE_CHECKSTOPPED:
272 case AP_RESPONSE_INVALID_ADDRESS:
273 return 0;
274 case AP_RESPONSE_OTHERWISE_CHANGED:
275 break;
276 default:
277 break;
278 }
279 if (i < AP_MAX_RESET - 1) {
280 udelay(5);
281 status = __ap_4096_commands_available(qid, &support);
282 }
283 }
284 return support;
285}
286EXPORT_SYMBOL(ap_4096_commands_available);
287
225/** 288/**
226 * ap_queue_enable_interruption(): Enable interruption on an AP. 289 * ap_queue_enable_interruption(): Enable interruption on an AP.
227 * @qid: The AP queue number 290 * @qid: The AP queue number
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 4785d07cd447..08b9738285b4 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -196,4 +196,6 @@ void ap_flush_queue(struct ap_device *ap_dev);
196int ap_module_init(void); 196int ap_module_init(void);
197void ap_module_exit(void); 197void ap_module_exit(void);
198 198
199int ap_4096_commands_available(ap_qid_t qid);
200
199#endif /* _AP_BUS_H_ */ 201#endif /* _AP_BUS_H_ */