master
c 497 lines 14.9 KB
Raw
1 /*
2 * Virtio-SCSI implementation for s390 machine loader for qemu
3 *
4 * Copyright 2015 IBM Corp.
5 * Author: Eugene "jno" Dvurechenski <jno@linux.vnet.ibm.com>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
8 * your option) any later version. See the COPYING file in the top-level
9 * directory.
10 */
11
12 #include <string.h>
13 #include <stdio.h>
14 #include "s390-ccw.h"
15 #include "virtio.h"
16 #include "scsi.h"
17 #include "virtio-scsi.h"
18 #include "virtio-ccw.h"
19 #include "s390-time.h"
20 #include "helper.h"
21
22 static ScsiDevice default_scsi_device;
23 static VirtioScsiCmdReq req;
24 static VirtioScsiCmdResp resp;
25
26 static uint8_t scsi_inquiry_std_response[256];
27 static ScsiInquiryEvpdPages scsi_inquiry_evpd_pages_response;
28 static ScsiInquiryEvpdBl scsi_inquiry_evpd_bl_response;
29
30 static inline bool vs_assert(bool term, const char **msgs)
31 {
32 if (!term) {
33 int i = 0;
34
35 printf("\n! ");
36 while (msgs[i]) {
37 printf("%s", msgs[i++]);
38 }
39 puts(" !");
40 }
41
42 return term;
43 }
44
45 static bool virtio_scsi_verify_response(VirtioScsiCmdResp *resp,
46 const char *title)
47 {
48 const char *mr[] = {
49 title, ": response ", virtio_scsi_response_msg(resp), 0
50 };
51 const char *ms[] = {
52 title,
53 CDB_STATUS_VALID(resp->status) ? ": " : ": invalid ",
54 scsi_cdb_status_msg(resp->status),
55 resp->status == CDB_STATUS_CHECK_CONDITION ? " " : 0,
56 resp->sense_len ? scsi_cdb_asc_msg(resp->sense)
57 : "no sense data",
58 scsi_sense_response(resp->sense) == 0x70 ? ", sure" : "?",
59 0
60 };
61
62 return vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr) &&
63 vs_assert(resp->status == CDB_STATUS_GOOD, ms);
64 }
65
66 static void prepare_request(VDev *vdev, const void *cdb, int cdb_size,
67 void *data, uint32_t data_size)
68 {
69 const ScsiDevice *sdev = vdev->scsi_device;
70
71 memset(&req, 0, sizeof(req));
72 req.lun = make_lun(sdev->channel, sdev->target, sdev->lun);
73 memcpy(&req.cdb, cdb, cdb_size);
74
75 memset(&resp, 0, sizeof(resp));
76 resp.status = 0xff; /* set invalid */
77 resp.response = 0xff; /* */
78
79 if (data && data_size) {
80 memset(data, 0, data_size);
81 }
82 }
83
84 static inline bool vs_io_assert(bool term, const char *msg)
85 {
86 if (!term && !virtio_scsi_verify_response(&resp, msg)) {
87 return false;
88 }
89
90 return true;
91 }
92
93 static int vs_run(const char *title, VirtioCmd *cmd, VDev *vdev,
94 const void *cdb, int cdb_size,
95 void *data, uint32_t data_size)
96 {
97 prepare_request(vdev, cdb, cdb_size, data, data_size);
98 if (!vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title)) {
99 puts(title);
100 return -EIO;
101 }
102
103 return 0;
104 }
105
106 /* SCSI protocol implementation routines */
107
108 static int scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page,
109 void *data, uint32_t data_size)
110 {
111 ScsiCdbInquiry cdb = {
112 .command = 0x12,
113 .b1 = evpd,
114 .b2 = page,
115 .alloc_len = data_size < 65535 ? data_size : 65535,
116 };
117 VirtioCmd inquiry[] = {
118 { &req, sizeof(req), VRING_DESC_F_NEXT },
119 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT },
120 { data, data_size, VRING_DESC_F_WRITE },
121 };
122
123 int ret = vs_run("inquiry", inquiry,
124 vdev, &cdb, sizeof(cdb), data, data_size);
125
126 return ret ? ret : virtio_scsi_response_ok(&resp);
127 }
128
129 static int scsi_test_unit_ready(VDev *vdev)
130 {
131 ScsiCdbTestUnitReady cdb = {
132 .command = 0x00,
133 };
134 VirtioCmd test_unit_ready[] = {
135 { &req, sizeof(req), VRING_DESC_F_NEXT },
136 { &resp, sizeof(resp), VRING_DESC_F_WRITE },
137 };
138
139 prepare_request(vdev, &cdb, sizeof(cdb), 0, 0);
140 virtio_run(vdev, VR_REQUEST, test_unit_ready); /* ignore errors here */
141
142 return virtio_scsi_response_ok(&resp);
143 }
144
145 static int scsi_report_luns(VDev *vdev, void *data, uint32_t data_size)
146 {
147 ScsiCdbReportLuns cdb = {
148 .command = 0xa0,
149 .select_report = 0x02, /* REPORT ALL */
150 .alloc_len = data_size,
151 };
152 VirtioCmd report_luns[] = {
153 { &req, sizeof(req), VRING_DESC_F_NEXT },
154 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT },
155 { data, data_size, VRING_DESC_F_WRITE },
156 };
157
158 int ret = vs_run("report luns", report_luns,
159 vdev, &cdb, sizeof(cdb), data, data_size);
160
161 return ret ? ret : virtio_scsi_response_ok(&resp);
162 }
163
164 static int scsi_read_10(VDev *vdev,
165 unsigned long sector, int sectors, void *data,
166 unsigned int data_size)
167 {
168 ScsiCdbRead10 cdb = {
169 .command = 0x28,
170 .lba = sector,
171 .xfer_length = sectors,
172 };
173 VirtioCmd read_10[] = {
174 { &req, sizeof(req), VRING_DESC_F_NEXT },
175 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT },
176 { data, data_size, VRING_DESC_F_WRITE },
177 };
178
179 debug_print_int("read_10 sector", sector);
180 debug_print_int("read_10 sectors", sectors);
181
182 int ret = vs_run("read(10)", read_10,
183 vdev, &cdb, sizeof(cdb), data, data_size);
184
185 return ret ? ret : virtio_scsi_response_ok(&resp);
186 }
187
188 static int scsi_read_capacity(VDev *vdev,
189 void *data, uint32_t data_size)
190 {
191 ScsiCdbReadCapacity16 cdb = {
192 .command = 0x9e, /* SERVICE_ACTION_IN_16 */
193 .service_action = 0x10, /* SA_READ_CAPACITY */
194 .alloc_len = data_size,
195 };
196 VirtioCmd read_capacity_16[] = {
197 { &req, sizeof(req), VRING_DESC_F_NEXT },
198 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT },
199 { data, data_size, VRING_DESC_F_WRITE },
200 };
201
202 int ret = vs_run("read capacity", read_capacity_16,
203 vdev, &cdb, sizeof(cdb), data, data_size);
204
205 return ret ? ret : virtio_scsi_response_ok(&resp);
206 }
207
208 /* virtio-scsi routines */
209
210 /*
211 * Tries to locate a SCSI device and adds the information for the found
212 * device to the vdev->scsi_device structure.
213 * Returns 0 if SCSI device could be located, or a error code < 0 otherwise
214 */
215 static int virtio_scsi_locate_device(VDev *vdev)
216 {
217 const uint16_t channel = 0; /* again, it's what QEMU does */
218 uint16_t target;
219 static uint8_t data[16 + 8 * 63];
220 ScsiLunReport *r = (void *) data;
221 ScsiDevice *sdev = vdev->scsi_device;
222 int i, ret, luns;
223
224 /* QEMU has hardcoded channel #0 in many places.
225 * If this hardcoded value is ever changed, we'll need to add code for
226 * vdev->config.scsi.max_channel != 0 here.
227 */
228 debug_print_int("config.scsi.max_channel", vdev->config.scsi.max_channel);
229 debug_print_int("config.scsi.max_target ", vdev->config.scsi.max_target);
230 debug_print_int("config.scsi.max_lun ", vdev->config.scsi.max_lun);
231 debug_print_int("config.scsi.max_sectors", vdev->config.scsi.max_sectors);
232
233 if (vdev->scsi_device_selected) {
234 sdev->channel = vdev->selected_scsi_device.channel;
235 sdev->target = vdev->selected_scsi_device.target;
236 sdev->lun = vdev->selected_scsi_device.lun;
237
238 IPL_check(sdev->channel == 0, "non-zero channel requested");
239 IPL_check(sdev->target <= vdev->config.scsi.max_target, "target# high");
240 IPL_check(sdev->lun <= vdev->config.scsi.max_lun, "LUN# high");
241 return 0;
242 }
243
244 for (target = 0; target <= vdev->config.scsi.max_target; target++) {
245 sdev->channel = channel;
246 sdev->target = target;
247 sdev->lun = 0; /* LUN has to be 0 for REPORT LUNS */
248 ret = scsi_report_luns(vdev, data, sizeof(data));
249 if (ret < 0) {
250 return ret;
251 }
252
253 else if (ret == 0) {
254 if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) {
255 continue;
256 }
257 printf("target 0x%X\n", target);
258 if (!virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs")) {
259 return -EIO;
260 }
261 }
262
263 if (r->lun_list_len == 0) {
264 printf("no LUNs for target 0x%X\n", target);
265 continue;
266 }
267 luns = r->lun_list_len / 8;
268 debug_print_int("LUNs reported", luns);
269 if (luns == 1) {
270 /* There is no ",lun=#" arg for -device or ",lun=0" given.
271 * Hence, the only LUN reported.
272 * Usually, it's 0.
273 */
274 sdev->lun = r->lun[0].v16[0]; /* it's returned this way */
275 debug_print_int("Have to use LUN", sdev->lun);
276 return 0; /* we have to use this device */
277 }
278 for (i = 0; i < luns; i++) {
279 if (r->lun[i].v64) {
280 /* Look for non-zero LUN - we have where to choose from */
281 sdev->lun = r->lun[i].v16[0];
282 debug_print_int("Will use LUN", sdev->lun);
283 return 0; /* we have found a device */
284 }
285 }
286 }
287
288 puts("Warning: Could not locate a usable virtio-scsi device");
289 return -ENODEV;
290 }
291
292 int virtio_scsi_read_many(VDev *vdev,
293 unsigned long sector, void *load_addr, int sec_num)
294 {
295 int sector_count;
296 int f = vdev->blk_factor;
297 unsigned int data_size;
298 unsigned int max_transfer = MIN_NON_ZERO(vdev->config.scsi.max_sectors,
299 vdev->max_transfer);
300
301 do {
302 sector_count = MIN_NON_ZERO(sec_num, max_transfer);
303 data_size = sector_count * virtio_get_block_size() * f;
304 if (!scsi_read_10(vdev, sector * f, sector_count * f, load_addr,
305 data_size)) {
306 if (!virtio_scsi_verify_response(&resp, "virtio-scsi:read_many")) {
307 return -1;
308 }
309 }
310 load_addr += data_size;
311 sector += sector_count;
312 sec_num -= sector_count;
313 } while (sec_num > 0);
314
315 return 0;
316 }
317
318 static bool virtio_scsi_inquiry_response_is_cdrom(void *data)
319 {
320 const ScsiInquiryStd *response = data;
321 const int resp_data_fmt = response->b3 & 0x0f;
322 int i;
323
324 IPL_check(resp_data_fmt == 2, "Wrong INQUIRY response format");
325 if (resp_data_fmt != 2) {
326 return false; /* cannot decode */
327 }
328
329 if ((response->peripheral_qdt & 0x1f) == SCSI_INQ_RDT_CDROM) {
330 return true;
331 }
332
333 for (i = 0; i < sizeof(response->prod_id); i++) {
334 if (response->prod_id[i] != QEMU_CDROM_SIGNATURE[i]) {
335 return false;
336 }
337 }
338 return true;
339 }
340
341 static void scsi_parse_capacity_report(void *data,
342 uint64_t *last_lba, uint32_t *lb_len)
343 {
344 ScsiReadCapacity16Data *p = data;
345
346 if (last_lba) {
347 *last_lba = p->ret_lba;
348 }
349
350 if (lb_len) {
351 *lb_len = p->lb_len;
352 }
353 }
354
355 static int virtio_scsi_setup(VDev *vdev)
356 {
357 int retry_test_unit_ready = 3;
358 uint8_t data[256];
359 uint32_t data_size = sizeof(data);
360 ScsiInquiryEvpdPages *evpd = &scsi_inquiry_evpd_pages_response;
361 ScsiInquiryEvpdBl *evpd_bl = &scsi_inquiry_evpd_bl_response;
362 int i, ret;
363
364 vdev->scsi_device = &default_scsi_device;
365 ret = virtio_scsi_locate_device(vdev);
366 if (ret < 0) {
367 return ret;
368 }
369
370 /* We have to "ping" the device before it becomes readable */
371 while (!scsi_test_unit_ready(vdev)) {
372
373 if (!virtio_scsi_response_ok(&resp)) {
374 uint8_t code = resp.sense[0] & SCSI_SENSE_CODE_MASK;
375 uint8_t sense_key = resp.sense[2] & SCSI_SENSE_KEY_MASK;
376
377 if (resp.sense_len == 0) {
378 puts("virtio-scsi: setup: no SENSE data");
379 return -EINVAL;
380 }
381
382 if (!retry_test_unit_ready || code != 0x70 ||
383 sense_key != SCSI_SENSE_KEY_UNIT_ATTENTION) {
384 puts("virtio-scsi:setup: cannot retry");
385 return -EIO;
386 }
387
388 /* retry on CHECK_CONDITION/UNIT_ATTENTION as it
389 * may not designate a real error, but it may be
390 * a result of device reset, etc.
391 */
392 retry_test_unit_ready--;
393 sleep(1);
394 continue;
395 }
396
397 if (!virtio_scsi_verify_response(&resp, "virtio-scsi:setup")) {
398 return -1;
399 }
400 }
401
402 /* read and cache SCSI INQUIRY response */
403 ret = scsi_inquiry(vdev,
404 SCSI_INQUIRY_STANDARD,
405 SCSI_INQUIRY_STANDARD_NONE,
406 scsi_inquiry_std_response,
407 sizeof(scsi_inquiry_std_response));
408 if (ret < 1) {
409 if (ret != 0 || !virtio_scsi_verify_response(&resp,
410 "virtio-scsi:setup:inquiry")) {
411 return -1;
412 }
413 }
414
415 if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) {
416 puts("SCSI CD-ROM detected.");
417 vdev->is_cdrom = true;
418 vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE;
419 }
420
421 ret = scsi_inquiry(vdev,
422 SCSI_INQUIRY_EVPD,
423 SCSI_INQUIRY_EVPD_SUPPORTED_PAGES,
424 evpd,
425 sizeof(*evpd));
426 if (ret < 1) {
427 if (ret != 0 || !virtio_scsi_verify_response(&resp,
428 "virtio-scsi:setup:supported_pages")) {
429 return -1;
430 }
431 }
432
433 debug_print_int("EVPD length", evpd->page_length);
434
435 for (i = 0; i <= evpd->page_length; i++) {
436 debug_print_int("supported EVPD page", evpd->byte[i]);
437
438 if (evpd->byte[i] != SCSI_INQUIRY_EVPD_BLOCK_LIMITS) {
439 continue;
440 }
441
442 ret = scsi_inquiry(vdev,
443 SCSI_INQUIRY_EVPD,
444 SCSI_INQUIRY_EVPD_BLOCK_LIMITS,
445 evpd_bl,
446 sizeof(*evpd_bl));
447 if (ret < 1) {
448 if (ret != 0 || !virtio_scsi_verify_response(&resp,
449 "virtio-scsi:setup:blocklimits")) {
450 return -1;
451 }
452 }
453
454 debug_print_int("max transfer", evpd_bl->max_transfer);
455 vdev->max_transfer = evpd_bl->max_transfer;
456 }
457
458 /*
459 * The host sg driver will often be unhappy with particularly large
460 * I/Os that exceed the block iovec limits. Let's enforce something
461 * reasonable, despite what the device configuration tells us.
462 */
463
464 vdev->max_transfer = MIN_NON_ZERO(VIRTIO_SCSI_MAX_SECTORS,
465 vdev->max_transfer);
466
467 ret = scsi_read_capacity(vdev, data, data_size);
468 if (ret < 1) {
469 if (ret != 0 || !virtio_scsi_verify_response(&resp,
470 "virtio-scsi:setup:read_capacity")) {
471 return -1;
472 }
473 }
474 scsi_parse_capacity_report(data, &vdev->scsi_last_block,
475 (uint32_t *) &vdev->scsi_block_size);
476
477 return 0;
478 }
479
480 int virtio_scsi_setup_device(VDev *vdev)
481 {
482 virtio_ccw_setup(vdev);
483
484 if (vdev->config.scsi.sense_size != VIRTIO_SCSI_SENSE_SIZE) {
485 puts("Config: sense size mismatch");
486 return -EINVAL;
487 }
488
489 if (vdev->config.scsi.cdb_size != VIRTIO_SCSI_CDB_SIZE) {
490 puts("Config: CDB size mismatch");
491 return -EINVAL;
492 }
493
494 puts("Using virtio-scsi.");
495
496 return virtio_scsi_setup(vdev);
497 }