| .. | .. |
|---|
| 29 | 29 | .send_mask = EVTYP_SDIAS_MASK, |
|---|
| 30 | 30 | }; |
|---|
| 31 | 31 | |
|---|
| 32 | | -static struct sdias_sccb sccb __attribute__((aligned(4096))); |
|---|
| 32 | +static struct sdias_sccb *sclp_sdias_sccb; |
|---|
| 33 | 33 | static struct sdias_evbuf sdias_evbuf; |
|---|
| 34 | 34 | |
|---|
| 35 | 35 | static DECLARE_COMPLETION(evbuf_accepted); |
|---|
| .. | .. |
|---|
| 58 | 58 | |
|---|
| 59 | 59 | static int sdias_sclp_send(struct sclp_req *req) |
|---|
| 60 | 60 | { |
|---|
| 61 | + struct sdias_sccb *sccb = sclp_sdias_sccb; |
|---|
| 61 | 62 | int retries; |
|---|
| 62 | 63 | int rc; |
|---|
| 63 | 64 | |
|---|
| .. | .. |
|---|
| 78 | 79 | continue; |
|---|
| 79 | 80 | } |
|---|
| 80 | 81 | /* if not accepted, retry */ |
|---|
| 81 | | - if (!(sccb.evbuf.hdr.flags & 0x80)) { |
|---|
| 82 | + if (!(sccb->evbuf.hdr.flags & 0x80)) { |
|---|
| 82 | 83 | TRACE("sclp request failed: flags=%x\n", |
|---|
| 83 | | - sccb.evbuf.hdr.flags); |
|---|
| 84 | + sccb->evbuf.hdr.flags); |
|---|
| 84 | 85 | continue; |
|---|
| 85 | 86 | } |
|---|
| 86 | 87 | /* |
|---|
| 87 | 88 | * for the sync interface the response is in the initial sccb |
|---|
| 88 | 89 | */ |
|---|
| 89 | 90 | if (!sclp_sdias_register.receiver_fn) { |
|---|
| 90 | | - memcpy(&sdias_evbuf, &sccb.evbuf, sizeof(sdias_evbuf)); |
|---|
| 91 | + memcpy(&sdias_evbuf, &sccb->evbuf, sizeof(sdias_evbuf)); |
|---|
| 91 | 92 | TRACE("sync request done\n"); |
|---|
| 92 | 93 | return 0; |
|---|
| 93 | 94 | } |
|---|
| .. | .. |
|---|
| 104 | 105 | */ |
|---|
| 105 | 106 | int sclp_sdias_blk_count(void) |
|---|
| 106 | 107 | { |
|---|
| 108 | + struct sdias_sccb *sccb = sclp_sdias_sccb; |
|---|
| 107 | 109 | struct sclp_req request; |
|---|
| 108 | 110 | int rc; |
|---|
| 109 | 111 | |
|---|
| 110 | 112 | mutex_lock(&sdias_mutex); |
|---|
| 111 | 113 | |
|---|
| 112 | | - memset(&sccb, 0, sizeof(sccb)); |
|---|
| 114 | + memset(sccb, 0, sizeof(*sccb)); |
|---|
| 113 | 115 | memset(&request, 0, sizeof(request)); |
|---|
| 114 | 116 | |
|---|
| 115 | | - sccb.hdr.length = sizeof(sccb); |
|---|
| 116 | | - sccb.evbuf.hdr.length = sizeof(struct sdias_evbuf); |
|---|
| 117 | | - sccb.evbuf.hdr.type = EVTYP_SDIAS; |
|---|
| 118 | | - sccb.evbuf.event_qual = SDIAS_EQ_SIZE; |
|---|
| 119 | | - sccb.evbuf.data_id = SDIAS_DI_FCP_DUMP; |
|---|
| 120 | | - sccb.evbuf.event_id = 4712; |
|---|
| 121 | | - sccb.evbuf.dbs = 1; |
|---|
| 117 | + sccb->hdr.length = sizeof(*sccb); |
|---|
| 118 | + sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf); |
|---|
| 119 | + sccb->evbuf.hdr.type = EVTYP_SDIAS; |
|---|
| 120 | + sccb->evbuf.event_qual = SDIAS_EQ_SIZE; |
|---|
| 121 | + sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP; |
|---|
| 122 | + sccb->evbuf.event_id = 4712; |
|---|
| 123 | + sccb->evbuf.dbs = 1; |
|---|
| 122 | 124 | |
|---|
| 123 | | - request.sccb = &sccb; |
|---|
| 125 | + request.sccb = sccb; |
|---|
| 124 | 126 | request.command = SCLP_CMDW_WRITE_EVENT_DATA; |
|---|
| 125 | 127 | request.status = SCLP_REQ_FILLED; |
|---|
| 126 | 128 | request.callback = sdias_callback; |
|---|
| .. | .. |
|---|
| 130 | 132 | pr_err("sclp_send failed for get_nr_blocks\n"); |
|---|
| 131 | 133 | goto out; |
|---|
| 132 | 134 | } |
|---|
| 133 | | - if (sccb.hdr.response_code != 0x0020) { |
|---|
| 134 | | - TRACE("send failed: %x\n", sccb.hdr.response_code); |
|---|
| 135 | + if (sccb->hdr.response_code != 0x0020) { |
|---|
| 136 | + TRACE("send failed: %x\n", sccb->hdr.response_code); |
|---|
| 135 | 137 | rc = -EIO; |
|---|
| 136 | 138 | goto out; |
|---|
| 137 | 139 | } |
|---|
| .. | .. |
|---|
| 163 | 165 | */ |
|---|
| 164 | 166 | int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) |
|---|
| 165 | 167 | { |
|---|
| 168 | + struct sdias_sccb *sccb = sclp_sdias_sccb; |
|---|
| 166 | 169 | struct sclp_req request; |
|---|
| 167 | 170 | int rc; |
|---|
| 168 | 171 | |
|---|
| 169 | 172 | mutex_lock(&sdias_mutex); |
|---|
| 170 | 173 | |
|---|
| 171 | | - memset(&sccb, 0, sizeof(sccb)); |
|---|
| 174 | + memset(sccb, 0, sizeof(*sccb)); |
|---|
| 172 | 175 | memset(&request, 0, sizeof(request)); |
|---|
| 173 | 176 | |
|---|
| 174 | | - sccb.hdr.length = sizeof(sccb); |
|---|
| 175 | | - sccb.evbuf.hdr.length = sizeof(struct sdias_evbuf); |
|---|
| 176 | | - sccb.evbuf.hdr.type = EVTYP_SDIAS; |
|---|
| 177 | | - sccb.evbuf.hdr.flags = 0; |
|---|
| 178 | | - sccb.evbuf.event_qual = SDIAS_EQ_STORE_DATA; |
|---|
| 179 | | - sccb.evbuf.data_id = SDIAS_DI_FCP_DUMP; |
|---|
| 180 | | - sccb.evbuf.event_id = 4712; |
|---|
| 181 | | - sccb.evbuf.asa_size = SDIAS_ASA_SIZE_64; |
|---|
| 182 | | - sccb.evbuf.event_status = 0; |
|---|
| 183 | | - sccb.evbuf.blk_cnt = nr_blks; |
|---|
| 184 | | - sccb.evbuf.asa = (unsigned long)dest; |
|---|
| 185 | | - sccb.evbuf.fbn = start_blk; |
|---|
| 186 | | - sccb.evbuf.lbn = 0; |
|---|
| 187 | | - sccb.evbuf.dbs = 1; |
|---|
| 177 | + sccb->hdr.length = sizeof(*sccb); |
|---|
| 178 | + sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf); |
|---|
| 179 | + sccb->evbuf.hdr.type = EVTYP_SDIAS; |
|---|
| 180 | + sccb->evbuf.hdr.flags = 0; |
|---|
| 181 | + sccb->evbuf.event_qual = SDIAS_EQ_STORE_DATA; |
|---|
| 182 | + sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP; |
|---|
| 183 | + sccb->evbuf.event_id = 4712; |
|---|
| 184 | + sccb->evbuf.asa_size = SDIAS_ASA_SIZE_64; |
|---|
| 185 | + sccb->evbuf.event_status = 0; |
|---|
| 186 | + sccb->evbuf.blk_cnt = nr_blks; |
|---|
| 187 | + sccb->evbuf.asa = (unsigned long)dest; |
|---|
| 188 | + sccb->evbuf.fbn = start_blk; |
|---|
| 189 | + sccb->evbuf.lbn = 0; |
|---|
| 190 | + sccb->evbuf.dbs = 1; |
|---|
| 188 | 191 | |
|---|
| 189 | | - request.sccb = &sccb; |
|---|
| 192 | + request.sccb = sccb; |
|---|
| 190 | 193 | request.command = SCLP_CMDW_WRITE_EVENT_DATA; |
|---|
| 191 | 194 | request.status = SCLP_REQ_FILLED; |
|---|
| 192 | 195 | request.callback = sdias_callback; |
|---|
| .. | .. |
|---|
| 196 | 199 | pr_err("sclp_send failed: %x\n", rc); |
|---|
| 197 | 200 | goto out; |
|---|
| 198 | 201 | } |
|---|
| 199 | | - if (sccb.hdr.response_code != 0x0020) { |
|---|
| 200 | | - TRACE("copy failed: %x\n", sccb.hdr.response_code); |
|---|
| 202 | + if (sccb->hdr.response_code != 0x0020) { |
|---|
| 203 | + TRACE("copy failed: %x\n", sccb->hdr.response_code); |
|---|
| 201 | 204 | rc = -EIO; |
|---|
| 202 | 205 | goto out; |
|---|
| 203 | 206 | } |
|---|
| .. | .. |
|---|
| 211 | 214 | break; |
|---|
| 212 | 215 | case SDIAS_EVSTATE_NO_DATA: |
|---|
| 213 | 216 | TRACE("no data\n"); |
|---|
| 214 | | - /* fall through */ |
|---|
| 217 | + fallthrough; |
|---|
| 215 | 218 | default: |
|---|
| 216 | 219 | pr_err("Error from SCLP while copying hsa. Event status = %x\n", |
|---|
| 217 | 220 | sdias_evbuf.event_status); |
|---|
| .. | .. |
|---|
| 254 | 257 | |
|---|
| 255 | 258 | int __init sclp_sdias_init(void) |
|---|
| 256 | 259 | { |
|---|
| 257 | | - if (ipl_info.type != IPL_TYPE_FCP_DUMP) |
|---|
| 260 | + if (!is_ipl_type_dump()) |
|---|
| 258 | 261 | return 0; |
|---|
| 262 | + sclp_sdias_sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA); |
|---|
| 263 | + BUG_ON(!sclp_sdias_sccb); |
|---|
| 259 | 264 | sdias_dbf = debug_register("dump_sdias", 4, 1, 4 * sizeof(long)); |
|---|
| 260 | 265 | debug_register_view(sdias_dbf, &debug_sprintf_view); |
|---|
| 261 | 266 | debug_set_level(sdias_dbf, 6); |
|---|
| .. | .. |
|---|
| 264 | 269 | if (sclp_sdias_init_async() == 0) |
|---|
| 265 | 270 | goto out; |
|---|
| 266 | 271 | TRACE("init failed\n"); |
|---|
| 272 | + free_page((unsigned long) sclp_sdias_sccb); |
|---|
| 267 | 273 | return -ENODEV; |
|---|
| 268 | 274 | out: |
|---|
| 269 | 275 | TRACE("init done\n"); |
|---|
| 270 | 276 | return 0; |
|---|
| 271 | | -} |
|---|
| 272 | | - |
|---|
| 273 | | -void __exit sclp_sdias_exit(void) |
|---|
| 274 | | -{ |
|---|
| 275 | | - debug_unregister(sdias_dbf); |
|---|
| 276 | | - sclp_unregister(&sclp_sdias_register); |
|---|
| 277 | 277 | } |
|---|