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 "s390-ccw.h" 13 #include "virtio.h" 14 #include "scsi.h" 15 #include "virtio-scsi.h" 16 17 static ScsiDevice default_scsi_device; 18 static VirtioScsiCmdReq req; 19 static VirtioScsiCmdResp resp; 20 21 static uint8_t scsi_inquiry_std_response[256]; 22 23 static inline void vs_assert(bool term, const char **msgs) 24 { 25 if (!term) { 26 int i = 0; 27 28 sclp_print("\n! "); 29 while (msgs[i]) { 30 sclp_print(msgs[i++]); 31 } 32 panic(" !\n"); 33 } 34 } 35 36 static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp, 37 const char *title) 38 { 39 const char *mr[] = { 40 title, ": response ", virtio_scsi_response_msg(resp), 0 41 }; 42 const char *ms[] = { 43 title, 44 CDB_STATUS_VALID(resp->status) ? ": " : ": invalid ", 45 scsi_cdb_status_msg(resp->status), 46 resp->status == CDB_STATUS_CHECK_CONDITION ? " " : 0, 47 resp->sense_len ? scsi_cdb_asc_msg(resp->sense) 48 : "no sense data", 49 scsi_sense_response(resp->sense) == 0x70 ? ", sure" : "?", 50 0 51 }; 52 53 vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr); 54 vs_assert(resp->status == CDB_STATUS_GOOD, ms); 55 } 56 57 static void prepare_request(VDev *vdev, const void *cdb, int cdb_size, 58 void *data, uint32_t data_size) 59 { 60 const ScsiDevice *sdev = vdev->scsi_device; 61 62 memset(&req, 0, sizeof(req)); 63 req.lun = make_lun(sdev->channel, sdev->target, sdev->lun); 64 memcpy(&req.cdb, cdb, cdb_size); 65 66 memset(&resp, 0, sizeof(resp)); 67 resp.status = 0xff; /* set invalid */ 68 resp.response = 0xff; /* */ 69 70 if (data && data_size) { 71 memset(data, 0, data_size); 72 } 73 } 74 75 static inline void vs_io_assert(bool term, const char *msg) 76 { 77 if (!term) { 78 virtio_scsi_verify_response(&resp, msg); 79 } 80 } 81 82 static void vs_run(const char *title, VirtioCmd *cmd, VDev *vdev, 83 const void *cdb, int cdb_size, 84 void *data, uint32_t data_size) 85 { 86 prepare_request(vdev, cdb, cdb_size, data, data_size); 87 vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title); 88 } 89 90 /* SCSI protocol implementation routines */ 91 92 static bool scsi_inquiry(VDev *vdev, void *data, uint32_t data_size) 93 { 94 ScsiCdbInquiry cdb = { 95 .command = 0x12, 96 .alloc_len = data_size < 65535 ? data_size : 65535, 97 }; 98 VirtioCmd inquiry[] = { 99 { &req, sizeof(req), VRING_DESC_F_NEXT }, 100 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, 101 { data, data_size, VRING_DESC_F_WRITE }, 102 }; 103 104 vs_run("inquiry", inquiry, vdev, &cdb, sizeof(cdb), data, data_size); 105 106 return virtio_scsi_response_ok(&resp); 107 } 108 109 static bool scsi_test_unit_ready(VDev *vdev) 110 { 111 ScsiCdbTestUnitReady cdb = { 112 .command = 0x00, 113 }; 114 VirtioCmd test_unit_ready[] = { 115 { &req, sizeof(req), VRING_DESC_F_NEXT }, 116 { &resp, sizeof(resp), VRING_DESC_F_WRITE }, 117 }; 118 119 prepare_request(vdev, &cdb, sizeof(cdb), 0, 0); 120 virtio_run(vdev, VR_REQUEST, test_unit_ready); /* ignore errors here */ 121 122 return virtio_scsi_response_ok(&resp); 123 } 124 125 static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) 126 { 127 ScsiCdbReportLuns cdb = { 128 .command = 0xa0, 129 .select_report = 0x02, /* REPORT ALL */ 130 .alloc_len = data_size, 131 }; 132 VirtioCmd report_luns[] = { 133 { &req, sizeof(req), VRING_DESC_F_NEXT }, 134 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, 135 { data, data_size, VRING_DESC_F_WRITE }, 136 }; 137 138 vs_run("report luns", report_luns, 139 vdev, &cdb, sizeof(cdb), data, data_size); 140 141 return virtio_scsi_response_ok(&resp); 142 } 143 144 static bool scsi_read_10(VDev *vdev, 145 ulong sector, int sectors, void *data) 146 { 147 int f = vdev->blk_factor; 148 unsigned int data_size = sectors * virtio_get_block_size() * f; 149 ScsiCdbRead10 cdb = { 150 .command = 0x28, 151 .lba = sector * f, 152 .xfer_length = sectors * f, 153 }; 154 VirtioCmd read_10[] = { 155 { &req, sizeof(req), VRING_DESC_F_NEXT }, 156 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, 157 { data, data_size * f, VRING_DESC_F_WRITE }, 158 }; 159 160 debug_print_int("read_10 sector", sector); 161 debug_print_int("read_10 sectors", sectors); 162 163 vs_run("read(10)", read_10, vdev, &cdb, sizeof(cdb), data, data_size); 164 165 return virtio_scsi_response_ok(&resp); 166 } 167 168 static bool scsi_read_capacity(VDev *vdev, 169 void *data, uint32_t data_size) 170 { 171 ScsiCdbReadCapacity16 cdb = { 172 .command = 0x9e, /* SERVICE_ACTION_IN_16 */ 173 .service_action = 0x10, /* SA_READ_CAPACITY */ 174 .alloc_len = data_size, 175 }; 176 VirtioCmd read_capacity_16[] = { 177 { &req, sizeof(req), VRING_DESC_F_NEXT }, 178 { &resp, sizeof(resp), VRING_DESC_F_WRITE | VRING_DESC_F_NEXT }, 179 { data, data_size, VRING_DESC_F_WRITE }, 180 }; 181 182 vs_run("read capacity", read_capacity_16, 183 vdev, &cdb, sizeof(cdb), data, data_size); 184 185 return virtio_scsi_response_ok(&resp); 186 } 187 188 /* virtio-scsi routines */ 189 190 static void virtio_scsi_locate_device(VDev *vdev) 191 { 192 const uint16_t channel = 0; /* again, it's what QEMU does */ 193 uint16_t target; 194 static uint8_t data[16 + 8 * 63]; 195 ScsiLunReport *r = (void *) data; 196 ScsiDevice *sdev = vdev->scsi_device; 197 int i, luns; 198 199 /* QEMU has hardcoded channel #0 in many places. 200 * If this hardcoded value is ever changed, we'll need to add code for 201 * vdev->config.scsi.max_channel != 0 here. 202 */ 203 debug_print_int("config.scsi.max_channel", vdev->config.scsi.max_channel); 204 debug_print_int("config.scsi.max_target ", vdev->config.scsi.max_target); 205 debug_print_int("config.scsi.max_lun ", vdev->config.scsi.max_lun); 206 207 for (target = 0; target <= vdev->config.scsi.max_target; target++) { 208 sdev->channel = channel; 209 sdev->target = target; /* sdev->lun will be 0 here */ 210 if (!scsi_report_luns(vdev, data, sizeof(data))) { 211 if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { 212 continue; 213 } 214 print_int("target", target); 215 virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); 216 } 217 if (r->lun_list_len == 0) { 218 print_int("no LUNs for target", target); 219 continue; 220 } 221 luns = r->lun_list_len / 8; 222 debug_print_int("LUNs reported", luns); 223 if (luns == 1) { 224 /* There is no ",lun=#" arg for -device or ",lun=0" given. 225 * Hence, the only LUN reported. 226 * Usually, it's 0. 227 */ 228 sdev->lun = r->lun[0].v16[0]; /* it's returned this way */ 229 debug_print_int("Have to use LUN", sdev->lun); 230 return; /* we have to use this device */ 231 } 232 for (i = 0; i < luns; i++) { 233 if (r->lun[i].v64) { 234 /* Look for non-zero LUN - we have where to choose from */ 235 sdev->lun = r->lun[i].v16[0]; 236 debug_print_int("Will use LUN", sdev->lun); 237 return; /* we have found a device */ 238 } 239 } 240 } 241 panic("\n! Cannot locate virtio-scsi device !\n"); 242 } 243 244 int virtio_scsi_read_many(VDev *vdev, 245 ulong sector, void *load_addr, int sec_num) 246 { 247 if (!scsi_read_10(vdev, sector, sec_num, load_addr)) { 248 virtio_scsi_verify_response(&resp, "virtio-scsi:read_many"); 249 } 250 251 return 0; 252 } 253 254 static bool virtio_scsi_inquiry_response_is_cdrom(void *data) 255 { 256 const ScsiInquiryStd *response = data; 257 const int resp_data_fmt = response->b3 & 0x0f; 258 int i; 259 260 IPL_check(resp_data_fmt == 2, "Wrong INQUIRY response format"); 261 if (resp_data_fmt != 2) { 262 return false; /* cannot decode */ 263 } 264 265 if ((response->peripheral_qdt & 0x1f) == SCSI_INQ_RDT_CDROM) { 266 return true; 267 } 268 269 for (i = 0; i < sizeof(response->prod_id); i++) { 270 if (response->prod_id[i] != QEMU_CDROM_SIGNATURE[i]) { 271 return false; 272 } 273 } 274 return true; 275 } 276 277 static void scsi_parse_capacity_report(void *data, 278 uint64_t *last_lba, uint32_t *lb_len) 279 { 280 ScsiReadCapacity16Data *p = data; 281 282 if (last_lba) { 283 *last_lba = p->ret_lba; 284 } 285 286 if (lb_len) { 287 *lb_len = p->lb_len; 288 } 289 } 290 291 void virtio_scsi_setup(VDev *vdev) 292 { 293 int retry_test_unit_ready = 3; 294 uint8_t data[256]; 295 uint32_t data_size = sizeof(data); 296 297 vdev->scsi_device = &default_scsi_device; 298 virtio_scsi_locate_device(vdev); 299 300 /* We have to "ping" the device before it becomes readable */ 301 while (!scsi_test_unit_ready(vdev)) { 302 303 if (!virtio_scsi_response_ok(&resp)) { 304 uint8_t code = resp.sense[0] & SCSI_SENSE_CODE_MASK; 305 uint8_t sense_key = resp.sense[2] & SCSI_SENSE_KEY_MASK; 306 307 IPL_assert(resp.sense_len != 0, "virtio-scsi:setup: no SENSE data"); 308 309 IPL_assert(retry_test_unit_ready && code == 0x70 && 310 sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION, 311 "virtio-scsi:setup: cannot retry"); 312 313 /* retry on CHECK_CONDITION/UNIT_ATTENTION as it 314 * may not designate a real error, but it may be 315 * a result of device reset, etc. 316 */ 317 retry_test_unit_ready--; 318 sleep(1); 319 continue; 320 } 321 322 virtio_scsi_verify_response(&resp, "virtio-scsi:setup"); 323 } 324 325 /* read and cache SCSI INQUIRY response */ 326 if (!scsi_inquiry(vdev, scsi_inquiry_std_response, 327 sizeof(scsi_inquiry_std_response))) { 328 virtio_scsi_verify_response(&resp, "virtio-scsi:setup:inquiry"); 329 } 330 331 if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { 332 sclp_print("SCSI CD-ROM detected.\n"); 333 vdev->is_cdrom = true; 334 vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; 335 } 336 337 if (!scsi_read_capacity(vdev, data, data_size)) { 338 virtio_scsi_verify_response(&resp, "virtio-scsi:setup:read_capacity"); 339 } 340 scsi_parse_capacity_report(data, &vdev->scsi_last_block, 341 (uint32_t *) &vdev->scsi_block_size); 342 } 343