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