0001
0002
0003
0004
0005
0006
0007
0008
0009 #define KMSG_COMPONENT "sclp_sdias"
0010 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0011
0012 #include <linux/completion.h>
0013 #include <linux/sched.h>
0014 #include <asm/sclp.h>
0015 #include <asm/debug.h>
0016 #include <asm/ipl.h>
0017
0018 #include "sclp_sdias.h"
0019 #include "sclp.h"
0020 #include "sclp_rw.h"
0021
0022 #define TRACE(x...) debug_sprintf_event(sdias_dbf, 1, x)
0023
0024 #define SDIAS_RETRIES 300
0025
0026 static struct debug_info *sdias_dbf;
0027
0028 static struct sclp_register sclp_sdias_register = {
0029 .send_mask = EVTYP_SDIAS_MASK,
0030 };
0031
0032 static struct sdias_sccb *sclp_sdias_sccb;
0033 static struct sdias_evbuf sdias_evbuf;
0034
0035 static DECLARE_COMPLETION(evbuf_accepted);
0036 static DECLARE_COMPLETION(evbuf_done);
0037 static DEFINE_MUTEX(sdias_mutex);
0038
0039
0040
0041
0042 static void sclp_sdias_receiver_fn(struct evbuf_header *evbuf)
0043 {
0044 memcpy(&sdias_evbuf, evbuf,
0045 min_t(unsigned long, sizeof(sdias_evbuf), evbuf->length));
0046 complete(&evbuf_done);
0047 TRACE("sclp_sdias_receiver_fn done\n");
0048 }
0049
0050
0051
0052
0053 static void sdias_callback(struct sclp_req *request, void *data)
0054 {
0055 complete(&evbuf_accepted);
0056 TRACE("callback done\n");
0057 }
0058
0059 static int sdias_sclp_send(struct sclp_req *req)
0060 {
0061 struct sdias_sccb *sccb = sclp_sdias_sccb;
0062 int retries;
0063 int rc;
0064
0065 for (retries = SDIAS_RETRIES; retries; retries--) {
0066 TRACE("add request\n");
0067 rc = sclp_add_request(req);
0068 if (rc) {
0069
0070 set_current_state(TASK_INTERRUPTIBLE);
0071 TRACE("add request failed: rc = %i\n",rc);
0072 schedule_timeout(msecs_to_jiffies(500));
0073 continue;
0074 }
0075
0076 wait_for_completion(&evbuf_accepted);
0077 if (req->status == SCLP_REQ_FAILED) {
0078 TRACE("sclp request failed\n");
0079 continue;
0080 }
0081
0082 if (!(sccb->evbuf.hdr.flags & 0x80)) {
0083 TRACE("sclp request failed: flags=%x\n",
0084 sccb->evbuf.hdr.flags);
0085 continue;
0086 }
0087
0088
0089
0090 if (!sclp_sdias_register.receiver_fn) {
0091 memcpy(&sdias_evbuf, &sccb->evbuf, sizeof(sdias_evbuf));
0092 TRACE("sync request done\n");
0093 return 0;
0094 }
0095
0096 wait_for_completion(&evbuf_done);
0097 TRACE("request done\n");
0098 return 0;
0099 }
0100 return -EIO;
0101 }
0102
0103
0104
0105
0106 int sclp_sdias_blk_count(void)
0107 {
0108 struct sdias_sccb *sccb = sclp_sdias_sccb;
0109 struct sclp_req request;
0110 int rc;
0111
0112 mutex_lock(&sdias_mutex);
0113
0114 memset(sccb, 0, sizeof(*sccb));
0115 memset(&request, 0, sizeof(request));
0116
0117 sccb->hdr.length = sizeof(*sccb);
0118 sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
0119 sccb->evbuf.hdr.type = EVTYP_SDIAS;
0120 sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
0121 sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
0122 sccb->evbuf.event_id = 4712;
0123 sccb->evbuf.dbs = 1;
0124
0125 request.sccb = sccb;
0126 request.command = SCLP_CMDW_WRITE_EVENT_DATA;
0127 request.status = SCLP_REQ_FILLED;
0128 request.callback = sdias_callback;
0129
0130 rc = sdias_sclp_send(&request);
0131 if (rc) {
0132 pr_err("sclp_send failed for get_nr_blocks\n");
0133 goto out;
0134 }
0135 if (sccb->hdr.response_code != 0x0020) {
0136 TRACE("send failed: %x\n", sccb->hdr.response_code);
0137 rc = -EIO;
0138 goto out;
0139 }
0140
0141 switch (sdias_evbuf.event_status) {
0142 case 0:
0143 rc = sdias_evbuf.blk_cnt;
0144 break;
0145 default:
0146 pr_err("SCLP error: %x\n", sdias_evbuf.event_status);
0147 rc = -EIO;
0148 goto out;
0149 }
0150 TRACE("%i blocks\n", rc);
0151 out:
0152 mutex_unlock(&sdias_mutex);
0153 return rc;
0154 }
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
0167 {
0168 struct sdias_sccb *sccb = sclp_sdias_sccb;
0169 struct sclp_req request;
0170 int rc;
0171
0172 mutex_lock(&sdias_mutex);
0173
0174 memset(sccb, 0, sizeof(*sccb));
0175 memset(&request, 0, sizeof(request));
0176
0177 sccb->hdr.length = sizeof(*sccb);
0178 sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
0179 sccb->evbuf.hdr.type = EVTYP_SDIAS;
0180 sccb->evbuf.hdr.flags = 0;
0181 sccb->evbuf.event_qual = SDIAS_EQ_STORE_DATA;
0182 sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
0183 sccb->evbuf.event_id = 4712;
0184 sccb->evbuf.asa_size = SDIAS_ASA_SIZE_64;
0185 sccb->evbuf.event_status = 0;
0186 sccb->evbuf.blk_cnt = nr_blks;
0187 sccb->evbuf.asa = __pa(dest);
0188 sccb->evbuf.fbn = start_blk;
0189 sccb->evbuf.lbn = 0;
0190 sccb->evbuf.dbs = 1;
0191
0192 request.sccb = sccb;
0193 request.command = SCLP_CMDW_WRITE_EVENT_DATA;
0194 request.status = SCLP_REQ_FILLED;
0195 request.callback = sdias_callback;
0196
0197 rc = sdias_sclp_send(&request);
0198 if (rc) {
0199 pr_err("sclp_send failed: %x\n", rc);
0200 goto out;
0201 }
0202 if (sccb->hdr.response_code != 0x0020) {
0203 TRACE("copy failed: %x\n", sccb->hdr.response_code);
0204 rc = -EIO;
0205 goto out;
0206 }
0207
0208 switch (sdias_evbuf.event_status) {
0209 case SDIAS_EVSTATE_ALL_STORED:
0210 TRACE("all stored\n");
0211 break;
0212 case SDIAS_EVSTATE_PART_STORED:
0213 TRACE("part stored: %i\n", sdias_evbuf.blk_cnt);
0214 break;
0215 case SDIAS_EVSTATE_NO_DATA:
0216 TRACE("no data\n");
0217 fallthrough;
0218 default:
0219 pr_err("Error from SCLP while copying hsa. Event status = %x\n",
0220 sdias_evbuf.event_status);
0221 rc = -EIO;
0222 }
0223 out:
0224 mutex_unlock(&sdias_mutex);
0225 return rc;
0226 }
0227
0228 static int __init sclp_sdias_register_check(void)
0229 {
0230 int rc;
0231
0232 rc = sclp_register(&sclp_sdias_register);
0233 if (rc)
0234 return rc;
0235 if (sclp_sdias_blk_count() == 0) {
0236 sclp_unregister(&sclp_sdias_register);
0237 return -ENODEV;
0238 }
0239 return 0;
0240 }
0241
0242 static int __init sclp_sdias_init_sync(void)
0243 {
0244 TRACE("Try synchronous mode\n");
0245 sclp_sdias_register.receive_mask = 0;
0246 sclp_sdias_register.receiver_fn = NULL;
0247 return sclp_sdias_register_check();
0248 }
0249
0250 static int __init sclp_sdias_init_async(void)
0251 {
0252 TRACE("Try asynchronous mode\n");
0253 sclp_sdias_register.receive_mask = EVTYP_SDIAS_MASK;
0254 sclp_sdias_register.receiver_fn = sclp_sdias_receiver_fn;
0255 return sclp_sdias_register_check();
0256 }
0257
0258 int __init sclp_sdias_init(void)
0259 {
0260 if (!is_ipl_type_dump())
0261 return 0;
0262 sclp_sdias_sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA);
0263 BUG_ON(!sclp_sdias_sccb);
0264 sdias_dbf = debug_register("dump_sdias", 4, 1, 4 * sizeof(long));
0265 debug_register_view(sdias_dbf, &debug_sprintf_view);
0266 debug_set_level(sdias_dbf, 6);
0267 if (sclp_sdias_init_sync() == 0)
0268 goto out;
0269 if (sclp_sdias_init_async() == 0)
0270 goto out;
0271 TRACE("init failed\n");
0272 free_page((unsigned long) sclp_sdias_sccb);
0273 return -ENODEV;
0274 out:
0275 TRACE("init done\n");
0276 return 0;
0277 }