#include <asm/facility.h>
#include <linux/crypto.h>
#include <linux/mod_devicetable.h>
+#include <linux/debugfs.h>
#include "ap_bus.h"
#include "ap_asm.h"
+#include "ap_debug.h"
/*
* Module description.
static struct ap_config_info *ap_configuration;
static bool initialised;
+/*
+ * AP bus related debug feature things.
+ */
+static struct dentry *ap_dbf_root;
+debug_info_t *ap_dbf_info;
+
/*
* Workqueue timer for bus rescan.
*/
static void ap_bus_suspend(void)
{
+ AP_DBF(DBF_DEBUG, "ap_bus_suspend running\n");
+
ap_suspend_flag = 1;
/*
* Disable scanning for devices, thus we do not want to scan
{
int rc;
+ AP_DBF(DBF_DEBUG, "ap_bus_resume running\n");
+
/* remove all queue devices */
bus_for_each_dev(&ap_bus_type, NULL, NULL,
__ap_queue_devices_unregister);
spin_lock_bh(&ap_domain_lock);
ap_domain_index = domain;
spin_unlock_bh(&ap_domain_lock);
+
+ AP_DBF(DBF_DEBUG, "store new default domain=%d\n", domain);
+
return count;
}
unsigned int functions = 0;
int rc, id, dom, borked, domains;
+ AP_DBF(DBF_DEBUG, "ap_scan_bus running\n");
+
ap_query_configuration();
if (ap_select_domain() != 0)
goto out;
.fn = ap_reset_all,
};
+int __init ap_debug_init(void)
+{
+ ap_dbf_root = debugfs_create_dir("ap", NULL);
+ ap_dbf_info = debug_register("ap", 1, 1,
+ DBF_MAX_SPRINTF_ARGS * sizeof(long));
+ debug_register_view(ap_dbf_info, &debug_sprintf_view);
+ debug_set_level(ap_dbf_info, DBF_ERR);
+
+ return 0;
+}
+
+void ap_debug_exit(void)
+{
+ debugfs_remove(ap_dbf_root);
+ debug_unregister(ap_dbf_info);
+}
+
/**
* ap_module_init(): The module initialization code.
*
int max_domain_id;
int rc, i;
+ rc = ap_debug_init();
+ if (rc)
+ return rc;
+
if (ap_instructions_available() != 0) {
pr_warn("The hardware system does not support AP instructions\n");
return -ENODEV;
unregister_reset_call(&ap_reset_call);
if (ap_using_interrupts())
unregister_adapter_interrupt(&ap_airq);
+
+ ap_debug_exit();
}
module_init(ap_module_init);
--- /dev/null
+/*
+ * Copyright IBM Corp. 2016
+ * Author(s): Harald Freudenberger <freude@de.ibm.com>
+ */
+#ifndef AP_DEBUG_H
+#define AP_DEBUG_H
+
+#include <asm/debug.h>
+
+#define DBF_ERR 3 /* error conditions */
+#define DBF_WARN 4 /* warning conditions */
+#define DBF_INFO 5 /* informational */
+#define DBF_DEBUG 6 /* for debugging only */
+
+#define RC2ERR(rc) ((rc) ? DBF_ERR : DBF_INFO)
+#define RC2WARN(rc) ((rc) ? DBF_WARN : DBF_INFO)
+
+#define DBF_MAX_SPRINTF_ARGS 5
+
+#define AP_DBF(...) \
+ debug_sprintf_event(ap_dbf_info, ##__VA_ARGS__)
+
+extern debug_info_t *ap_dbf_info;
+
+int ap_debug_init(void);
+void ap_debug_exit(void);
+
+#endif /* AP_DEBUG_H */
#include <linux/debugfs.h>
#include <asm/debug.h>
-#include "zcrypt_debug.h"
#include "zcrypt_api.h"
+#include "zcrypt_debug.h"
#include "zcrypt_msgtype6.h"
#include "zcrypt_msgtype50.h"
static LIST_HEAD(zcrypt_ops_list);
-static struct dentry *debugfs_root;
-debug_info_t *zcrypt_dbf_common;
-debug_info_t *zcrypt_dbf_devices;
-debug_info_t *zcrypt_dbf_cards;
+/* Zcrypt related debug feature stuff. */
+static struct dentry *zcrypt_dbf_root;
+debug_info_t *zcrypt_dbf_info;
/**
* Process a rescan of the transport layer.
atomic_set(&zcrypt_rescan_req, 0);
atomic_inc(&zcrypt_rescan_count);
ap_bus_force_rescan();
- ZCRYPT_DBF_COMMON(DBF_INFO, "rescan%07d",
- atomic_inc_return(&zcrypt_rescan_count));
+ ZCRYPT_DBF(DBF_INFO, "rescan count=%07d",
+ atomic_inc_return(&zcrypt_rescan_count));
return 1;
}
return 0;
int __init zcrypt_debug_init(void)
{
- debugfs_root = debugfs_create_dir("zcrypt", NULL);
-
- zcrypt_dbf_common = debug_register("zcrypt_common", 1, 1, 16);
- debug_register_view(zcrypt_dbf_common, &debug_hex_ascii_view);
- debug_set_level(zcrypt_dbf_common, DBF_ERR);
-
- zcrypt_dbf_devices = debug_register("zcrypt_devices", 1, 1, 16);
- debug_register_view(zcrypt_dbf_devices, &debug_hex_ascii_view);
- debug_set_level(zcrypt_dbf_devices, DBF_ERR);
-
- zcrypt_dbf_cards = debug_register("zcrypt_cards", 1, 1, 16);
- debug_register_view(zcrypt_dbf_cards, &debug_hex_ascii_view);
- debug_set_level(zcrypt_dbf_cards, DBF_ERR);
+ zcrypt_dbf_root = debugfs_create_dir("zcrypt", NULL);
+ zcrypt_dbf_info = debug_register("zcrypt", 1, 1,
+ DBF_MAX_SPRINTF_ARGS * sizeof(long));
+ debug_register_view(zcrypt_dbf_info, &debug_sprintf_view);
+ debug_set_level(zcrypt_dbf_info, DBF_ERR);
return 0;
}
void zcrypt_debug_exit(void)
{
- debugfs_remove(debugfs_root);
- debug_unregister(zcrypt_dbf_common);
- debug_unregister(zcrypt_dbf_devices);
+ debugfs_remove(zcrypt_dbf_root);
+ debug_unregister(zcrypt_dbf_info);
}
/**
{
remove_proc_entry("driver/z90crypt", NULL);
misc_deregister(&zcrypt_misc_device);
- zcrypt_debug_exit();
zcrypt_msgtype6_exit();
zcrypt_msgtype50_exit();
+ zcrypt_debug_exit();
}
module_init(zcrypt_api_init);
atomic_t load; /* Utilization of the crypto device */
int request_count; /* # current requests. */
-
- debug_info_t *dbf_area; /* debugging */
};
struct zcrypt_queue {
int request_count; /* # current requests. */
struct ap_message reply; /* Per-device reply structure. */
-
- debug_info_t *dbf_area; /* debugging */
};
/* transport layer rescanning */
extern int zcrypt_device_count;
extern struct list_head zcrypt_card_list;
-extern debug_info_t *zcrypt_dbf_common;
-extern debug_info_t *zcrypt_dbf_devices;
-extern debug_info_t *zcrypt_dbf_cards;
-
#define for_each_zcrypt_card(_zc) \
list_for_each_entry(_zc, &zcrypt_card_list, list)
zc->online = online;
id = zc->card->id;
- ZCRYPT_DBF_DEV(DBF_INFO, zc, "card%02xo%dman", id, online);
+
+ ZCRYPT_DBF(DBF_INFO, "card=%02x online=%d\n", id, online);
+
spin_lock(&zcrypt_list_lock);
list_for_each_entry(zq, &zc->zqueues, list)
zcrypt_queue_force_online(zq, online);
return NULL;
INIT_LIST_HEAD(&zc->list);
INIT_LIST_HEAD(&zc->zqueues);
- zc->dbf_area = zcrypt_dbf_cards;
kref_init(&zc->refcount);
return zc;
}
spin_unlock(&zcrypt_list_lock);
zc->online = 1;
+
+ ZCRYPT_DBF(DBF_INFO, "card=%02x register online=1\n", zc->card->id);
+
return rc;
}
EXPORT_SYMBOL(zcrypt_card_register);
*/
void zcrypt_card_unregister(struct zcrypt_card *zc)
{
+ ZCRYPT_DBF(DBF_INFO, "card=%02x unregister\n", zc->card->id);
+
spin_lock(&zcrypt_list_lock);
list_del_init(&zc->list);
spin_unlock(&zcrypt_list_lock);
/*
- * Copyright IBM Corp. 2012
+ * Copyright IBM Corp. 2016
* Author(s): Holger Dengler (hd@linux.vnet.ibm.com)
+ * Harald Freudenberger <freude@de.ibm.com>
*/
#ifndef ZCRYPT_DEBUG_H
#define ZCRYPT_DEBUG_H
#include <asm/debug.h>
-#include "zcrypt_api.h"
-/* that gives us 15 characters in the text event views */
-#define ZCRYPT_DBF_LEN 16
-
-#define DBF_ERR 3 /* error conditions */
-#define DBF_WARN 4 /* warning conditions */
-#define DBF_INFO 6 /* informational */
+#define DBF_ERR 3 /* error conditions */
+#define DBF_WARN 4 /* warning conditions */
+#define DBF_INFO 5 /* informational */
+#define DBF_DEBUG 6 /* for debugging only */
+#define RC2ERR(rc) ((rc) ? DBF_ERR : DBF_INFO)
#define RC2WARN(rc) ((rc) ? DBF_WARN : DBF_INFO)
-#define ZCRYPT_DBF_COMMON(level, text...) \
- do { \
- if (debug_level_enabled(zcrypt_dbf_common, level)) { \
- char debug_buffer[ZCRYPT_DBF_LEN]; \
- snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
- debug_text_event(zcrypt_dbf_common, level, \
- debug_buffer); \
- } \
- } while (0)
-
-#define ZCRYPT_DBF_DEVICES(level, text...) \
- do { \
- if (debug_level_enabled(zcrypt_dbf_devices, level)) { \
- char debug_buffer[ZCRYPT_DBF_LEN]; \
- snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
- debug_text_event(zcrypt_dbf_devices, level, \
- debug_buffer); \
- } \
- } while (0)
-
-#define ZCRYPT_DBF_DEV(level, device, text...) \
- do { \
- if (debug_level_enabled(device->dbf_area, level)) { \
- char debug_buffer[ZCRYPT_DBF_LEN]; \
- snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
- debug_text_event(device->dbf_area, level, \
- debug_buffer); \
- } \
- } while (0)
+#define DBF_MAX_SPRINTF_ARGS 5
+
+#define ZCRYPT_DBF(...) \
+ debug_sprintf_event(zcrypt_dbf_info, ##__VA_ARGS__)
+
+extern debug_info_t *zcrypt_dbf_info;
int zcrypt_debug_init(void);
void zcrypt_debug_exit(void);
struct ap_message *reply)
{
struct error_hdr *ehdr = reply->message;
+ int card = AP_QID_CARD(zq->queue->qid);
+ int queue = AP_QID_QUEUE(zq->queue->qid);
switch (ehdr->reply_code) {
case REP82_ERROR_OPERAND_INVALID:
// REP88_ERROR_OPERAND // '84' CEX2A
// REP88_ERROR_OPERAND_EVEN_MOD // '85' CEX2A
/* Invalid input data. */
+ ZCRYPT_DBF(DBF_WARN,
+ "device=%02x.%04x reply=0x%02x => rc=EINVAL\n",
+ card, queue, ehdr->reply_code);
return -EINVAL;
case REP82_ERROR_MESSAGE_TYPE:
// REP88_ERROR_MESSAGE_TYPE // '20' CEX2A
atomic_set(&zcrypt_rescan_req, 1);
zq->online = 0;
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%drc%d",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid), zq->online,
- ehdr->reply_code);
+ card, queue);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n",
+ card, queue, ehdr->reply_code);
return -EAGAIN;
case REP82_ERROR_TRANSPORT_FAIL:
case REP82_ERROR_MACHINE_FAILURE:
atomic_set(&zcrypt_rescan_req, 1);
zq->online = 0;
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%drc%d",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid), zq->online,
- ehdr->reply_code);
+ card, queue);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n",
+ card, queue, ehdr->reply_code);
return -EAGAIN;
default:
zq->online = 0;
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%drc%d",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid), zq->online,
- ehdr->reply_code);
+ card, queue);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n",
+ card, queue, ehdr->reply_code);
return -EAGAIN; /* repeat the request on a different device. */
}
}
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%drc%d",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online, t80h->code);
-
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x code=0x%02x => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ t80h->code);
return -EAGAIN; /* repeat the request on a different device. */
}
if (zq->zcard->user_space_type == ZCRYPT_CEX2A)
unsigned int outputdatalength)
{
/* Response type byte is the second byte in the response. */
- switch (((unsigned char *) reply->message)[1]) {
+ unsigned char rtype = ((unsigned char *) reply->message)[1];
+
+ switch (rtype) {
case TYPE82_RSP_CODE:
case TYPE88_RSP_CODE:
return convert_error(zq, reply);
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%dfail",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (unsigned int) rtype);
return -EAGAIN; /* repeat the request on a different device. */
}
}
service_rc = msg->cprbx.ccp_rtcode;
if (unlikely(service_rc != 0)) {
service_rs = msg->cprbx.ccp_rscode;
- if (service_rc == 8 && service_rs == 66)
- return -EINVAL;
- if (service_rc == 8 && service_rs == 65)
- return -EINVAL;
- if (service_rc == 8 && service_rs == 770)
+ if ((service_rc == 8 && service_rs == 66) ||
+ (service_rc == 8 && service_rs == 65) ||
+ (service_rc == 8 && service_rs == 72) ||
+ (service_rc == 8 && service_rs == 770) ||
+ (service_rc == 12 && service_rs == 769)) {
+ ZCRYPT_DBF(DBF_DEBUG,
+ "device=%02x.%04x rc/rs=%d/%d => rc=EINVAL\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) service_rc, (int) service_rs);
return -EINVAL;
+ }
if (service_rc == 8 && service_rs == 783) {
zq->zcard->min_mod_size =
PCIXCC_MIN_MOD_SIZE_OLD;
+ ZCRYPT_DBF(DBF_DEBUG,
+ "device=%02x.%04x rc/rs=%d/%d => rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) service_rc, (int) service_rs);
return -EAGAIN;
}
- if (service_rc == 12 && service_rs == 769)
- return -EINVAL;
- if (service_rc == 8 && service_rs == 72)
- return -EINVAL;
zq->online = 0;
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%drc%d",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online,
- msg->hdr.reply_code);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x rc/rs=%d/%d => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) service_rc, (int) service_rs);
return -EAGAIN; /* repeat the request on a different device. */
}
data = msg->text;
{
struct type86x_reply *msg = reply->message;
- /* Response type byte is the second byte in the response. */
- switch (((unsigned char *) reply->message)[1]) {
+ switch (msg->hdr.type) {
case TYPE82_RSP_CODE:
case TYPE88_RSP_CODE:
return convert_error(zq, reply);
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%dfail",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) msg->hdr.type);
return -EAGAIN; /* repeat the request on a different device. */
}
}
{
struct type86x_reply *msg = reply->message;
- /* Response type byte is the second byte in the response. */
- switch (((unsigned char *) reply->message)[1]) {
+ switch (msg->hdr.type) {
case TYPE82_RSP_CODE:
case TYPE88_RSP_CODE:
xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%dfail",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) msg->hdr.type);
return -EAGAIN; /* repeat the request on a different device. */
}
}
{
struct type86_ep11_reply *msg = reply->message;
- /* Response type byte is the second byte in the response. */
- switch (((unsigned char *)reply->message)[1]) {
+ switch (msg->hdr.type) {
case TYPE82_RSP_CODE:
case TYPE87_RSP_CODE:
return convert_error(zq, reply);
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%dfail",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) msg->hdr.type);
return -EAGAIN; /* repeat the request on a different device. */
}
}
pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
- ZCRYPT_DBF_DEV(DBF_ERR, zq, "dev%02x%04xo%dfail",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online);
+ ZCRYPT_DBF(DBF_ERR,
+ "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ (int) msg->hdr.type);
return -EAGAIN; /* repeat the request on a different device. */
}
}
if (online && !zc->online)
return -EINVAL;
zq->online = online;
- ZCRYPT_DBF_DEV(DBF_INFO, zq, "dev%02x%04xo%dman",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid), online);
+
+ ZCRYPT_DBF(DBF_INFO, "queue=%02x.%04x online=%d\n",
+ AP_QID_CARD(zq->queue->qid),
+ AP_QID_QUEUE(zq->queue->qid),
+ online);
+
if (!online)
ap_flush_queue(zq->queue);
return count;
goto out_free;
zq->reply.length = max_response_size;
INIT_LIST_HEAD(&zq->list);
- zq->dbf_area = zcrypt_dbf_devices;
kref_init(&zq->refcount);
return zq;
zcrypt_card_get(zc);
zq->zcard = zc;
zq->online = 1; /* New devices are online by default. */
- ZCRYPT_DBF_DEV(DBF_INFO, zq, "dev%02x%04xo%dreg",
- AP_QID_CARD(zq->queue->qid),
- AP_QID_QUEUE(zq->queue->qid),
- zq->online);
+
+ ZCRYPT_DBF(DBF_INFO, "queue=%02x.%04x register online=1\n",
+ AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid));
+
list_add_tail(&zq->list, &zc->zqueues);
zcrypt_device_count++;
spin_unlock(&zcrypt_list_lock);
{
struct zcrypt_card *zc;
+ ZCRYPT_DBF(DBF_INFO, "queue=%02x.%04x unregister\n",
+ AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid));
+
zc = zq->zcard;
spin_lock(&zcrypt_list_lock);
list_del_init(&zq->list);