1 /* $OpenBSD: vioscsi.c,v 1.25 2024/09/26 01:45:13 jsg Exp $ */ 2 3 /* 4 * Copyright (c) 2017 Carlos Cardenas <ccardenas@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 21 #include <dev/pci/virtio_pcireg.h> 22 #include <dev/pv/vioscsireg.h> 23 #include <scsi/scsi_all.h> 24 #include <scsi/scsi_disk.h> 25 #include <scsi/scsiconf.h> 26 #include <scsi/cd.h> 27 28 #include <stdlib.h> 29 #include <string.h> 30 31 #include "vmd.h" 32 #include "vioscsi.h" 33 #include "virtio.h" 34 35 extern char *__progname; 36 37 static void 38 vioscsi_prepare_resp(struct virtio_scsi_res_hdr *resp, uint8_t vio_status, 39 uint8_t scsi_status, uint8_t err_flags, uint8_t add_sense_code, 40 uint8_t add_sense_code_qual) 41 { 42 /* Set lower 8 bits of status and response fields */ 43 resp->response &= 0xFFFFFF00; 44 resp->response |= vio_status; 45 resp->status &= 0xFFFFFF00; 46 resp->status |= scsi_status; 47 48 resp->sense_len = 0; 49 50 /* determine if we need to populate the sense field */ 51 if (scsi_status == SCSI_CHECK) { 52 /* 53 * sense data is a 96 byte field. 54 * We only need to use the first 14 bytes 55 * - set the sense_len accordingly 56 * - set error_code to Current Command 57 * ref scsi/scsi_all.h:struct scsi_sense_data 58 */ 59 memset(resp->sense, 0, VIOSCSI_SENSE_LEN); 60 resp->sense_len = RESP_SENSE_LEN; 61 resp->sense[0] = SSD_ERRCODE_CURRENT; 62 resp->sense[2] = err_flags; 63 resp->sense[12] = add_sense_code; 64 resp->sense[13] = add_sense_code_qual; 65 } 66 } 67 68 static struct vring_desc* 69 vioscsi_next_ring_desc(struct vring_desc* desc, struct vring_desc* cur, 70 uint16_t *idx) 71 { 72 *idx = cur->next & VIOSCSI_QUEUE_MASK; 73 return &desc[*idx]; 74 } 75 76 static void 77 vioscsi_next_ring_item(struct vioscsi_dev *dev, struct vring_avail *avail, 78 struct vring_used *used, struct vring_desc *desc, uint16_t idx) 79 { 80 used->ring[used->idx & VIOSCSI_QUEUE_MASK].id = idx; 81 used->ring[used->idx & VIOSCSI_QUEUE_MASK].len = desc->len; 82 __sync_synchronize(); 83 used->idx++; 84 85 dev->vq[dev->cfg.queue_notify].last_avail = 86 avail->idx & VIOSCSI_QUEUE_MASK; 87 } 88 89 static const char * 90 vioscsi_op_names(uint8_t type) 91 { 92 switch (type) { 93 /* defined in scsi_all.h */ 94 case TEST_UNIT_READY: return "TEST_UNIT_READY"; 95 case REQUEST_SENSE: return "REQUEST_SENSE"; 96 case INQUIRY: return "INQUIRY"; 97 case MODE_SELECT: return "MODE_SELECT"; 98 case RESERVE: return "RESERVE"; 99 case RELEASE: return "RELEASE"; 100 case MODE_SENSE: return "MODE_SENSE"; 101 case START_STOP: return "START_STOP"; 102 case RECEIVE_DIAGNOSTIC: return "RECEIVE_DIAGNOSTIC"; 103 case SEND_DIAGNOSTIC: return "SEND_DIAGNOSTIC"; 104 case PREVENT_ALLOW: return "PREVENT_ALLOW"; 105 case POSITION_TO_ELEMENT: return "POSITION_TO_ELEMENT"; 106 case WRITE_BUFFER: return "WRITE_BUFFER"; 107 case READ_BUFFER: return "READ_BUFFER"; 108 case CHANGE_DEFINITION: return "CHANGE_DEFINITION"; 109 case MODE_SELECT_BIG: return "MODE_SELECT_BIG"; 110 case MODE_SENSE_BIG: return "MODE_SENSE_BIG"; 111 case REPORT_LUNS: return "REPORT_LUNS"; 112 /* defined in scsi_disk.h */ 113 case REASSIGN_BLOCKS: return "REASSIGN_BLOCKS"; 114 case READ_COMMAND: return "READ_COMMAND"; 115 case WRITE_COMMAND: return "WRITE_COMMAND"; 116 case READ_CAPACITY: return "READ_CAPACITY"; 117 case READ_CAPACITY_16: return "READ_CAPACITY_16"; 118 case READ_10: return "READ_10"; 119 case WRITE_10: return "WRITE_10"; 120 case READ_12: return "READ_12"; 121 case WRITE_12: return "WRITE_12"; 122 case READ_16: return "READ_16"; 123 case WRITE_16: return "WRITE_16"; 124 case SYNCHRONIZE_CACHE: return "SYNCHRONIZE_CACHE"; 125 case WRITE_SAME_10: return "WRITE_SAME_10"; 126 case WRITE_SAME_16: return "WRITE_SAME_16"; 127 /* defined in cd.h */ 128 case READ_SUBCHANNEL: return "READ_SUBCHANNEL"; 129 case READ_TOC: return "READ_TOC"; 130 case READ_HEADER: return "READ_HEADER"; 131 case PLAY: return "PLAY"; 132 case PLAY_MSF: return "PLAY_MSF"; 133 case PLAY_TRACK: return "PLAY_TRACK"; 134 case PLAY_TRACK_REL: return "PLAY_TRACK_REL"; 135 case PAUSE: return "PAUSE"; 136 case READ_TRACK_INFO: return "READ_TRACK_INFO"; 137 case CLOSE_TRACK: return "CLOSE_TRACK"; 138 case BLANK: return "BLANK"; 139 case PLAY_BIG: return "PLAY_BIG"; 140 case LOAD_UNLOAD: return "LOAD_UNLOAD"; 141 case PLAY_TRACK_REL_BIG: return "PLAY_TRACK_REL_BIG"; 142 case SET_CD_SPEED: return "SET_CD_SPEED"; 143 /* defined locally */ 144 case READ_DISC_INFORMATION: return "READ_DISC_INFORMATION"; 145 case GET_CONFIGURATION: return "GET_CONFIGURATION"; 146 case MECHANISM_STATUS: return "MECHANISM_STATUS"; 147 case GET_EVENT_STATUS_NOTIFICATION: 148 return "GET_EVENT_STATUS_NOTIFICATION"; 149 default: return "UNKNOWN"; 150 } 151 } 152 153 static const char * 154 vioscsi_reg_name(uint8_t reg) 155 { 156 switch (reg) { 157 case VIRTIO_CONFIG_DEVICE_FEATURES: return "device feature"; 158 case VIRTIO_CONFIG_GUEST_FEATURES: return "guest feature"; 159 case VIRTIO_CONFIG_QUEUE_PFN: return "queue pfn"; 160 case VIRTIO_CONFIG_QUEUE_SIZE: return "queue size"; 161 case VIRTIO_CONFIG_QUEUE_SELECT: return "queue select"; 162 case VIRTIO_CONFIG_QUEUE_NOTIFY: return "queue notify"; 163 case VIRTIO_CONFIG_DEVICE_STATUS: return "device status"; 164 case VIRTIO_CONFIG_ISR_STATUS: return "isr status"; 165 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI: return "num_queues"; 166 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 4: return "seg_max"; 167 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 8: return "max_sectors"; 168 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 12: return "cmd_per_lun"; 169 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 16: return "event_info_size"; 170 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 20: return "sense_size"; 171 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 24: return "cdb_size"; 172 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 28: return "max_channel"; 173 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 30: return "max_target"; 174 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 32: return "max_lun"; 175 default: return "unknown"; 176 } 177 } 178 179 static void 180 vioscsi_free_info(struct ioinfo *info) 181 { 182 if (!info) 183 return; 184 free(info->buf); 185 free(info); 186 } 187 188 static struct ioinfo * 189 vioscsi_start_read(struct vioscsi_dev *dev, off_t block, size_t n_blocks) 190 { 191 struct ioinfo *info; 192 193 /* Limit to 64M for now */ 194 if (n_blocks * VIOSCSI_BLOCK_SIZE_CDROM > (1 << 26)) { 195 log_warnx("%s: read size exceeded 64M", __func__); 196 return (NULL); 197 } 198 199 info = calloc(1, sizeof(*info)); 200 if (!info) 201 goto nomem; 202 info->buf = malloc(n_blocks * VIOSCSI_BLOCK_SIZE_CDROM); 203 if (info->buf == NULL) 204 goto nomem; 205 info->len = n_blocks * VIOSCSI_BLOCK_SIZE_CDROM; 206 info->offset = block * VIOSCSI_BLOCK_SIZE_CDROM; 207 208 return info; 209 210 nomem: 211 free(info); 212 log_warn("malloc error vioscsi read"); 213 return (NULL); 214 } 215 216 static const uint8_t * 217 vioscsi_finish_read(struct vioscsi_dev *dev, struct ioinfo *info) 218 { 219 struct virtio_backing *f = &dev->file; 220 221 if (f->pread(f->p, info->buf, info->len, info->offset) != info->len) { 222 log_warn("vioscsi read error"); 223 return NULL; 224 } 225 226 return info->buf; 227 } 228 229 static int 230 vioscsi_handle_tur(struct vioscsi_dev *dev, struct virtio_scsi_req_hdr *req, 231 struct virtio_vq_acct *acct) 232 { 233 int ret = 0; 234 struct virtio_scsi_res_hdr resp; 235 236 memset(&resp, 0, sizeof(resp)); 237 /* Move index for response */ 238 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 239 &(acct->resp_idx)); 240 241 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 242 243 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 244 log_warnx("%s: unable to write OK resp status data @ 0x%llx", 245 __func__, acct->resp_desc->addr); 246 } else { 247 ret = 1; 248 dev->cfg.isr_status = 1; 249 /* Move ring indexes */ 250 vioscsi_next_ring_item(dev, acct->avail, acct->used, 251 acct->req_desc, acct->req_idx); 252 } 253 254 return (ret); 255 } 256 257 static int 258 vioscsi_handle_inquiry(struct vioscsi_dev *dev, 259 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 260 { 261 int ret = 0; 262 struct virtio_scsi_res_hdr resp; 263 struct scsi_inquiry_data *inq_data; 264 265 #if DEBUG 266 struct scsi_inquiry *inq = (struct scsi_inquiry *)(req->cdb); 267 log_debug("%s: INQ - EVPD %d PAGE_CODE 0x%08x LEN %d", __func__, 268 inq->flags & SI_EVPD, inq->pagecode, _2btol(inq->length)); 269 #endif /* DEBUG */ 270 271 memset(&resp, 0, sizeof(resp)); 272 vioscsi_prepare_resp(&resp, 273 VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 274 275 inq_data = calloc(1, sizeof(struct scsi_inquiry_data)); 276 277 if (inq_data == NULL) { 278 log_warnx("%s: cannot alloc inq_data", __func__); 279 goto inq_out; 280 } 281 282 inq_data->device = T_CDROM; 283 inq_data->dev_qual2 = SID_REMOVABLE; 284 /* Leave version zero to say we don't comply */ 285 inq_data->response_format = SID_SCSI2_RESPONSE; 286 inq_data->additional_length = SID_SCSI2_ALEN; 287 memcpy(inq_data->vendor, INQUIRY_VENDOR, INQUIRY_VENDOR_LEN); 288 memcpy(inq_data->product, INQUIRY_PRODUCT, INQUIRY_PRODUCT_LEN); 289 memcpy(inq_data->revision, INQUIRY_REVISION, INQUIRY_REVISION_LEN); 290 291 /* Move index for response */ 292 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 293 &(acct->resp_idx)); 294 295 DPRINTF("%s: writing resp to 0x%llx size %d at local " 296 "idx %d req_idx %d global_idx %d", __func__, acct->resp_desc->addr, 297 acct->resp_desc->len, acct->resp_idx, acct->req_idx, acct->idx); 298 299 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 300 log_warnx("%s: unable to write OK resp status data @ 0x%llx", 301 __func__, acct->resp_desc->addr); 302 goto free_inq; 303 } 304 305 /* Move index for inquiry_data */ 306 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 307 &(acct->resp_idx)); 308 309 DPRINTF("%s: writing inq_data to 0x%llx size %d at " 310 "local idx %d req_idx %d global_idx %d", 311 __func__, acct->resp_desc->addr, acct->resp_desc->len, 312 acct->resp_idx, acct->req_idx, acct->idx); 313 314 if (write_mem(acct->resp_desc->addr, inq_data, 315 sizeof(struct scsi_inquiry_data))) { 316 log_warnx("%s: unable to write inquiry" 317 " response to gpa @ 0x%llx", 318 __func__, acct->resp_desc->addr); 319 } else { 320 ret = 1; 321 dev->cfg.isr_status = 1; 322 /* Move ring indexes */ 323 vioscsi_next_ring_item(dev, acct->avail, acct->used, 324 acct->req_desc, acct->req_idx); 325 } 326 327 free_inq: 328 free(inq_data); 329 inq_out: 330 return (ret); 331 } 332 333 static int 334 vioscsi_handle_mode_sense(struct vioscsi_dev *dev, 335 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 336 { 337 int ret = 0; 338 struct virtio_scsi_res_hdr resp; 339 uint8_t mode_page_ctl; 340 uint8_t mode_page_code; 341 uint8_t *mode_reply; 342 uint8_t mode_reply_len = 0; 343 struct scsi_mode_sense *mode_sense; 344 345 memset(&resp, 0, sizeof(resp)); 346 mode_sense = (struct scsi_mode_sense *)(req->cdb); 347 mode_page_ctl = mode_sense->page & SMS_PAGE_CTRL; 348 mode_page_code = mode_sense->page & SMS_PAGE_CODE; 349 350 DPRINTF("%s: M_SENSE - DBD %d Page Ctrl 0x%x Code 0x%x Len %u", 351 __func__, mode_sense->byte2 & SMS_DBD, mode_page_ctl, 352 mode_page_code, mode_sense->length); 353 354 if (mode_page_ctl == SMS_PAGE_CTRL_CURRENT && 355 (mode_page_code == ERR_RECOVERY_PAGE || 356 mode_page_code == CDVD_CAPABILITIES_PAGE)) { 357 /* 358 * mode sense header is 4 bytes followed 359 * by a variable page 360 * ERR_RECOVERY_PAGE is 12 bytes 361 * CDVD_CAPABILITIES_PAGE is 32 bytes 362 */ 363 switch (mode_page_code) { 364 case ERR_RECOVERY_PAGE: 365 mode_reply_len = 16; 366 mode_reply = 367 (uint8_t*)calloc(mode_reply_len, sizeof(uint8_t)); 368 if (mode_reply == NULL) 369 goto mode_sense_out; 370 371 /* set the page header */ 372 *mode_reply = mode_reply_len - 1; 373 *(mode_reply + 1) = MODE_MEDIUM_TYPE_CODE; 374 375 /* set the page data, 7.3.2.1 mmc-5 */ 376 *(mode_reply + 4) = MODE_ERR_RECOVERY_PAGE_CODE; 377 *(mode_reply + 5) = MODE_ERR_RECOVERY_PAGE_LEN; 378 *(mode_reply + 7) = MODE_READ_RETRY_COUNT; 379 break; 380 case CDVD_CAPABILITIES_PAGE: 381 mode_reply_len = 36; 382 mode_reply = 383 (uint8_t*)calloc(mode_reply_len, sizeof(uint8_t)); 384 if (mode_reply == NULL) 385 goto mode_sense_out; 386 387 /* set the page header */ 388 *mode_reply = mode_reply_len - 1; 389 *(mode_reply + 1) = MODE_MEDIUM_TYPE_CODE; 390 391 /* set the page data, 6.3.11 mmc-3 */ 392 *(mode_reply + 4) = MODE_CDVD_CAP_PAGE_CODE; 393 *(mode_reply + 5) = mode_reply_len - 6; 394 *(mode_reply + 6) = MODE_CDVD_CAP_READ_CODE; 395 _lto2b(MODE_CDVD_CAP_NUM_LEVELS, mode_reply + 14); 396 break; 397 default: 398 goto mode_sense_error; 399 break; 400 } 401 402 /* Move index for response */ 403 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 404 acct->req_desc, &(acct->resp_idx)); 405 406 DPRINTF("%s: writing resp to 0x%llx size %d " 407 "at local idx %d req_idx %d global_idx %d", 408 __func__, acct->resp_desc->addr, mode_reply_len, 409 acct->resp_idx, acct->req_idx, acct->idx); 410 411 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 412 log_warnx("%s: unable to write OK" 413 " resp status data @ 0x%llx", 414 __func__, acct->resp_desc->addr); 415 free(mode_reply); 416 goto mode_sense_out; 417 } 418 419 /* Move index for mode_reply */ 420 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 421 acct->resp_desc, &(acct->resp_idx)); 422 423 DPRINTF("%s: writing mode_reply to 0x%llx " 424 "size %d at local idx %d req_idx %d " 425 "global_idx %d", __func__, acct->resp_desc->addr, 426 mode_reply_len, acct->resp_idx, acct->req_idx, acct->idx); 427 428 if (write_mem(acct->resp_desc->addr, mode_reply, 429 mode_reply_len)) { 430 log_warnx("%s: unable to write " 431 "mode_reply to gpa @ 0x%llx", 432 __func__, acct->resp_desc->addr); 433 free(mode_reply); 434 goto mode_sense_out; 435 } 436 437 free(mode_reply); 438 439 ret = 1; 440 dev->cfg.isr_status = 1; 441 /* Move ring indexes */ 442 vioscsi_next_ring_item(dev, acct->avail, acct->used, 443 acct->req_desc, acct->req_idx); 444 } else { 445 mode_sense_error: 446 /* send back un-supported */ 447 vioscsi_prepare_resp(&resp, 448 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 449 SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); 450 451 /* Move index for response */ 452 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 453 acct->req_desc, &(acct->resp_idx)); 454 455 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 456 log_warnx("%s: unable to set ERR status data @ 0x%llx", 457 __func__, acct->resp_desc->addr); 458 goto mode_sense_out; 459 } 460 461 ret = 1; 462 dev->cfg.isr_status = 1; 463 /* Move ring indexes */ 464 vioscsi_next_ring_item(dev, acct->avail, acct->used, 465 acct->req_desc, acct->req_idx); 466 } 467 mode_sense_out: 468 return (ret); 469 } 470 471 static int 472 vioscsi_handle_mode_sense_big(struct vioscsi_dev *dev, 473 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 474 { 475 int ret = 0; 476 struct virtio_scsi_res_hdr resp; 477 uint8_t mode_page_ctl; 478 uint8_t mode_page_code; 479 uint8_t *mode_reply; 480 uint8_t mode_reply_len = 0; 481 struct scsi_mode_sense_big *mode_sense_10; 482 483 memset(&resp, 0, sizeof(resp)); 484 mode_sense_10 = (struct scsi_mode_sense_big *)(req->cdb); 485 mode_page_ctl = mode_sense_10->page & SMS_PAGE_CTRL; 486 mode_page_code = mode_sense_10->page & SMS_PAGE_CODE; 487 488 DPRINTF("%s: M_SENSE_10 - DBD %d Page Ctrl 0x%x Code 0x%x Len %u", 489 __func__, mode_sense_10->byte2 & SMS_DBD, mode_page_ctl, 490 mode_page_code, (uint16_t)_2btol(mode_sense_10->length)); 491 492 if (mode_page_ctl == SMS_PAGE_CTRL_CURRENT && 493 (mode_page_code == ERR_RECOVERY_PAGE || 494 mode_page_code == CDVD_CAPABILITIES_PAGE)) { 495 /* 496 * mode sense header is 8 bytes followed 497 * by a variable page 498 * ERR_RECOVERY_PAGE is 12 bytes 499 * CDVD_CAPABILITIES_PAGE is 32 bytes 500 */ 501 switch (mode_page_code) { 502 case ERR_RECOVERY_PAGE: 503 mode_reply_len = 20; 504 mode_reply = 505 (uint8_t*)calloc(mode_reply_len, sizeof(uint8_t)); 506 if (mode_reply == NULL) 507 goto mode_sense_big_out; 508 509 /* set the page header */ 510 _lto2b(mode_reply_len - 2, mode_reply); 511 *(mode_reply + 2) = MODE_MEDIUM_TYPE_CODE; 512 513 /* set the page data, 7.3.2.1 mmc-5 */ 514 *(mode_reply + 8) = MODE_ERR_RECOVERY_PAGE_CODE; 515 *(mode_reply + 9) = MODE_ERR_RECOVERY_PAGE_LEN; 516 *(mode_reply + 11) = MODE_READ_RETRY_COUNT; 517 break; 518 case CDVD_CAPABILITIES_PAGE: 519 mode_reply_len = 40; 520 mode_reply = 521 (uint8_t*)calloc(mode_reply_len, sizeof(uint8_t)); 522 if (mode_reply == NULL) 523 goto mode_sense_big_out; 524 525 /* set the page header */ 526 _lto2b(mode_reply_len - 2, mode_reply); 527 *(mode_reply + 2) = MODE_MEDIUM_TYPE_CODE; 528 529 /* set the page data, 6.3.11 mmc-3 */ 530 *(mode_reply + 8) = MODE_CDVD_CAP_PAGE_CODE; 531 *(mode_reply + 9) = mode_reply_len - 6; 532 *(mode_reply + 10) = MODE_CDVD_CAP_READ_CODE; 533 _lto2b(MODE_CDVD_CAP_NUM_LEVELS, mode_reply + 18); 534 break; 535 default: 536 goto mode_sense_big_error; 537 break; 538 } 539 540 /* Move index for response */ 541 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 542 acct->req_desc, &(acct->resp_idx)); 543 544 DPRINTF("%s: writing resp to 0x%llx size %d " 545 "at local idx %d req_idx %d global_idx %d", 546 __func__, acct->resp_desc->addr, acct->resp_desc->len, 547 acct->resp_idx, acct->req_idx, acct->idx); 548 549 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 550 log_warnx("%s: unable to write OK" 551 " resp status data @ 0x%llx", 552 __func__, acct->resp_desc->addr); 553 free(mode_reply); 554 goto mode_sense_big_out; 555 } 556 557 /* Move index for mode_reply */ 558 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 559 acct->resp_desc, &(acct->resp_idx)); 560 561 DPRINTF("%s: writing mode_reply to 0x%llx " 562 "size %d at local idx %d req_idx %d global_idx %d", 563 __func__, acct->resp_desc->addr, mode_reply_len, 564 acct->resp_idx, acct->req_idx, acct->idx); 565 566 if (write_mem(acct->resp_desc->addr, mode_reply, 567 mode_reply_len)) { 568 log_warnx("%s: unable to write " 569 "mode_reply to gpa @ 0x%llx", 570 __func__, acct->resp_desc->addr); 571 free(mode_reply); 572 goto mode_sense_big_out; 573 } 574 575 free(mode_reply); 576 577 ret = 1; 578 dev->cfg.isr_status = 1; 579 /* Move ring indexes */ 580 vioscsi_next_ring_item(dev, acct->avail, acct->used, 581 acct->req_desc, acct->req_idx); 582 } else { 583 mode_sense_big_error: 584 /* send back un-supported */ 585 vioscsi_prepare_resp(&resp, 586 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 587 SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); 588 589 /* Move index for response */ 590 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 591 acct->req_desc, &(acct->resp_idx)); 592 593 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 594 log_warnx("%s: unable to set ERR status data @ 0x%llx", 595 __func__, acct->resp_desc->addr); 596 goto mode_sense_big_out; 597 } 598 599 ret = 1; 600 dev->cfg.isr_status = 1; 601 /* Move ring indexes */ 602 vioscsi_next_ring_item(dev, acct->avail, acct->used, 603 acct->req_desc, acct->req_idx); 604 } 605 mode_sense_big_out: 606 return (ret); 607 } 608 609 static int 610 vioscsi_handle_read_capacity(struct vioscsi_dev *dev, 611 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 612 { 613 int ret = 0; 614 struct virtio_scsi_res_hdr resp; 615 struct scsi_read_cap_data *r_cap_data; 616 617 #if DEBUG 618 struct scsi_read_capacity *r_cap = 619 (struct scsi_read_capacity *)(req->cdb); 620 log_debug("%s: %s - Addr 0x%08x", __func__, 621 vioscsi_op_names(r_cap->opcode), _4btol(r_cap->addr)); 622 #endif /* DEBUG */ 623 624 memset(&resp, 0, sizeof(resp)); 625 vioscsi_prepare_resp(&resp, 626 VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 627 628 r_cap_data = calloc(1, sizeof(struct scsi_read_cap_data)); 629 630 if (r_cap_data == NULL) { 631 log_warnx("%s: cannot alloc r_cap_data", __func__); 632 goto read_capacity_out; 633 } 634 635 DPRINTF("%s: ISO has %lld bytes and %lld blocks", 636 __func__, dev->sz, dev->n_blocks); 637 638 /* 639 * determine if num blocks of iso image > UINT32_MAX 640 * if it is, set addr to UINT32_MAX (0xffffffff) 641 * indicating to hosts that READ_CAPACITY_16 should 642 * be called to retrieve the full size 643 */ 644 if (dev->n_blocks >= UINT32_MAX) { 645 _lto4b(UINT32_MAX, r_cap_data->addr); 646 _lto4b(VIOSCSI_BLOCK_SIZE_CDROM, r_cap_data->length); 647 log_warnx("%s: ISO sz %lld is bigger than " 648 "UINT32_MAX %u, all data may not be read", 649 __func__, dev->sz, UINT32_MAX); 650 } else { 651 _lto4b(dev->n_blocks - 1, r_cap_data->addr); 652 _lto4b(VIOSCSI_BLOCK_SIZE_CDROM, r_cap_data->length); 653 } 654 655 /* Move index for response */ 656 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 657 &(acct->resp_idx)); 658 659 DPRINTF("%s: writing resp to 0x%llx size %d at local " 660 "idx %d req_idx %d global_idx %d", 661 __func__, acct->resp_desc->addr, acct->resp_desc->len, 662 acct->resp_idx, acct->req_idx, acct->idx); 663 664 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 665 log_warnx("%s: unable to write OK resp status data @ 0x%llx", 666 __func__, acct->resp_desc->addr); 667 goto free_read_capacity; 668 } 669 670 /* Move index for r_cap_data */ 671 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 672 &(acct->resp_idx)); 673 674 DPRINTF("%s: writing r_cap_data to 0x%llx size %d at " 675 "local idx %d req_idx %d global_idx %d", 676 __func__, acct->resp_desc->addr, acct->resp_desc->len, 677 acct->resp_idx, acct->req_idx, acct->idx); 678 679 if (write_mem(acct->resp_desc->addr, r_cap_data, 680 sizeof(struct scsi_read_cap_data))) { 681 log_warnx("%s: unable to write read_cap_data" 682 " response to gpa @ 0x%llx", 683 __func__, acct->resp_desc->addr); 684 } else { 685 ret = 1; 686 dev->cfg.isr_status = 1; 687 /* Move ring indexes */ 688 vioscsi_next_ring_item(dev, acct->avail, acct->used, 689 acct->req_desc, acct->req_idx); 690 } 691 692 free_read_capacity: 693 free(r_cap_data); 694 read_capacity_out: 695 return (ret); 696 } 697 698 static int 699 vioscsi_handle_read_capacity_16(struct vioscsi_dev *dev, 700 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 701 { 702 int ret = 0; 703 struct virtio_scsi_res_hdr resp; 704 struct scsi_read_cap_data_16 *r_cap_data_16; 705 706 #if DEBUG 707 struct scsi_read_capacity_16 *r_cap_16 = 708 (struct scsi_read_capacity_16 *)(req->cdb); 709 log_debug("%s: %s - Addr 0x%016llx", __func__, 710 vioscsi_op_names(r_cap_16->opcode), _8btol(r_cap_16->addr)); 711 #endif /* DEBUG */ 712 713 memset(&resp, 0, sizeof(resp)); 714 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 715 716 r_cap_data_16 = calloc(1, sizeof(struct scsi_read_cap_data_16)); 717 718 if (r_cap_data_16 == NULL) { 719 log_warnx("%s: cannot alloc r_cap_data_16", 720 __func__); 721 goto read_capacity_16_out; 722 } 723 724 DPRINTF("%s: ISO has %lld bytes and %lld blocks", __func__, 725 dev->sz, dev->n_blocks); 726 727 _lto8b(dev->n_blocks - 1, r_cap_data_16->addr); 728 _lto4b(VIOSCSI_BLOCK_SIZE_CDROM, r_cap_data_16->length); 729 730 /* Move index for response */ 731 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 732 &(acct->resp_idx)); 733 734 DPRINTF("%s: writing resp to 0x%llx size %d at local " 735 "idx %d req_idx %d global_idx %d", 736 __func__, acct->resp_desc->addr, acct->resp_desc->len, 737 acct->resp_idx, acct->req_idx, acct->idx); 738 739 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 740 log_warnx("%s: unable to write OK resp status " 741 "data @ 0x%llx", __func__, acct->resp_desc->addr); 742 goto free_read_capacity_16; 743 } 744 745 /* Move index for r_cap_data_16 */ 746 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 747 &(acct->resp_idx)); 748 749 DPRINTF("%s: writing r_cap_data_16 to 0x%llx size %d " 750 "at local idx %d req_idx %d global_idx %d", 751 __func__, acct->resp_desc->addr, acct->resp_desc->len, 752 acct->resp_idx, acct->req_idx, acct->idx); 753 754 if (write_mem(acct->resp_desc->addr, r_cap_data_16, 755 sizeof(struct scsi_read_cap_data_16))) { 756 log_warnx("%s: unable to write read_cap_data_16" 757 " response to gpa @ 0x%llx", 758 __func__, acct->resp_desc->addr); 759 } else { 760 ret = 1; 761 dev->cfg.isr_status = 1; 762 /* Move ring indexes */ 763 vioscsi_next_ring_item(dev, acct->avail, acct->used, 764 acct->req_desc, acct->req_idx); 765 } 766 767 free_read_capacity_16: 768 free(r_cap_data_16); 769 read_capacity_16_out: 770 return (ret); 771 } 772 773 static int 774 vioscsi_handle_report_luns(struct vioscsi_dev *dev, 775 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 776 { 777 int ret = 0; 778 struct virtio_scsi_res_hdr resp; 779 uint32_t rpl_length; 780 struct scsi_report_luns *rpl; 781 struct vioscsi_report_luns_data *reply_rpl; 782 783 memset(&resp, 0, sizeof(resp)); 784 rpl = (struct scsi_report_luns *)(req->cdb); 785 rpl_length = _4btol(rpl->length); 786 787 DPRINTF("%s: REPORT_LUNS Report 0x%x Length %d", __func__, 788 rpl->selectreport, rpl_length); 789 790 if (rpl_length < RPL_MIN_SIZE) { 791 DPRINTF("%s: RPL_Length %d < %d (RPL_MIN_SIZE)", __func__, 792 rpl_length, RPL_MIN_SIZE); 793 794 vioscsi_prepare_resp(&resp, 795 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 796 SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); 797 798 /* Move index for response */ 799 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 800 acct->req_desc, &(acct->resp_idx)); 801 802 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 803 log_warnx("%s: unable to set ERR " 804 "status data @ 0x%llx", __func__, 805 acct->resp_desc->addr); 806 } else { 807 ret = 1; 808 dev->cfg.isr_status = 1; 809 /* Move ring indexes */ 810 vioscsi_next_ring_item(dev, acct->avail, acct->used, 811 acct->req_desc, acct->req_idx); 812 } 813 goto rpl_out; 814 815 } 816 817 reply_rpl = calloc(1, sizeof(struct vioscsi_report_luns_data)); 818 819 if (reply_rpl == NULL) { 820 log_warnx("%s: cannot alloc reply_rpl", __func__); 821 goto rpl_out; 822 } 823 824 _lto4b(RPL_SINGLE_LUN, reply_rpl->length); 825 memcpy(reply_rpl->lun, req->lun, RPL_SINGLE_LUN); 826 827 vioscsi_prepare_resp(&resp, 828 VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 829 830 /* Move index for response */ 831 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 832 &(acct->resp_idx)); 833 834 DPRINTF("%s: writing resp to 0x%llx size %d at local " 835 "idx %d req_idx %d global_idx %d", __func__, acct->resp_desc->addr, 836 acct->resp_desc->len, acct->resp_idx, acct->req_idx, acct->idx); 837 838 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 839 log_warnx("%s: unable to write OK resp status data @ 0x%llx", 840 __func__, acct->resp_desc->addr); 841 goto free_rpl; 842 } 843 844 /* Move index for reply_rpl */ 845 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 846 &(acct->resp_idx)); 847 848 DPRINTF("%s: writing reply_rpl to 0x%llx size %d at " 849 "local idx %d req_idx %d global_idx %d", 850 __func__, acct->resp_desc->addr, acct->resp_desc->len, 851 acct->resp_idx, acct->req_idx, acct->idx); 852 853 if (write_mem(acct->resp_desc->addr, reply_rpl, 854 sizeof(struct vioscsi_report_luns_data))) { 855 log_warnx("%s: unable to write reply_rpl" 856 " response to gpa @ 0x%llx", 857 __func__, acct->resp_desc->addr); 858 } else { 859 ret = 1; 860 dev->cfg.isr_status = 1; 861 /* Move ring indexes */ 862 vioscsi_next_ring_item(dev, acct->avail, acct->used, 863 acct->req_desc, acct->req_idx); 864 } 865 866 free_rpl: 867 free(reply_rpl); 868 rpl_out: 869 return (ret); 870 } 871 872 static int 873 vioscsi_handle_read_6(struct vioscsi_dev *dev, 874 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 875 { 876 int ret = 0; 877 struct virtio_scsi_res_hdr resp; 878 const uint8_t *read_buf; 879 uint32_t read_lba; 880 struct ioinfo *info; 881 struct scsi_rw *read_6; 882 883 memset(&resp, 0, sizeof(resp)); 884 read_6 = (struct scsi_rw *)(req->cdb); 885 read_lba = ((read_6->addr[0] & SRW_TOPADDR) << 16 ) | 886 (read_6->addr[1] << 8) | read_6->addr[2]; 887 888 DPRINTF("%s: READ Addr 0x%08x Len %d (%d)", 889 __func__, read_lba, read_6->length, read_6->length * dev->max_xfer); 890 891 /* check if lba is in range */ 892 if (read_lba > dev->n_blocks - 1) { 893 DPRINTF("%s: requested block out of range req: %ud max: %lld", 894 __func__, read_lba, dev->n_blocks); 895 896 vioscsi_prepare_resp(&resp, 897 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 898 SENSE_LBA_OUT_OF_RANGE, SENSE_DEFAULT_ASCQ); 899 900 /* Move index for response */ 901 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 902 acct->req_desc, &(acct->resp_idx)); 903 904 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 905 log_warnx("%s: unable to set ERR " 906 "status data @ 0x%llx", __func__, 907 acct->resp_desc->addr); 908 } else { 909 ret = 1; 910 dev->cfg.isr_status = 1; 911 /* Move ring indexes */ 912 vioscsi_next_ring_item(dev, acct->avail, acct->used, 913 acct->req_desc, acct->req_idx); 914 } 915 goto read_6_out; 916 } 917 918 info = vioscsi_start_read(dev, read_lba, read_6->length); 919 920 if (info == NULL) { 921 log_warnx("%s: cannot alloc for read", __func__); 922 goto read_6_out; 923 } 924 925 /* read block */ 926 read_buf = vioscsi_finish_read(dev, info); 927 928 if (read_buf == NULL) { 929 log_warnx("%s: error reading position %ud", 930 __func__, read_lba); 931 vioscsi_prepare_resp(&resp, 932 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_MEDIUM_ERROR, 933 SENSE_MEDIUM_NOT_PRESENT, SENSE_DEFAULT_ASCQ); 934 935 /* Move index for response */ 936 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 937 acct->req_desc, &(acct->resp_idx)); 938 939 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 940 log_warnx("%s: unable to set ERR " 941 "status data @ 0x%llx", __func__, 942 acct->resp_desc->addr); 943 } else { 944 ret = 1; 945 dev->cfg.isr_status = 1; 946 /* Move ring indexes */ 947 vioscsi_next_ring_item(dev, acct->avail, acct->used, 948 acct->req_desc, acct->req_idx); 949 } 950 951 goto free_read_6; 952 } 953 954 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 955 956 /* Move index for response */ 957 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 958 &(acct->resp_idx)); 959 960 DPRINTF("%s: writing resp to 0x%llx size %d at local " 961 "idx %d req_idx %d global_idx %d", 962 __func__, acct->resp_desc->addr, acct->resp_desc->len, 963 acct->resp_idx, acct->req_idx, acct->idx); 964 965 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 966 log_warnx("%s: unable to write OK resp status " 967 "data @ 0x%llx", __func__, acct->resp_desc->addr); 968 goto free_read_6; 969 } 970 971 /* Move index for read_buf */ 972 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 973 &(acct->resp_idx)); 974 975 DPRINTF("%s: writing read_buf to 0x%llx size %d at " 976 "local idx %d req_idx %d global_idx %d", 977 __func__, acct->resp_desc->addr, acct->resp_desc->len, 978 acct->resp_idx, acct->req_idx, acct->idx); 979 980 if (write_mem(acct->resp_desc->addr, read_buf, info->len)) { 981 log_warnx("%s: unable to write read_buf to gpa @ 0x%llx", 982 __func__, acct->resp_desc->addr); 983 } else { 984 ret = 1; 985 dev->cfg.isr_status = 1; 986 /* Move ring indexes */ 987 vioscsi_next_ring_item(dev, acct->avail, acct->used, 988 acct->req_desc, acct->req_idx); 989 } 990 991 free_read_6: 992 vioscsi_free_info(info); 993 read_6_out: 994 return (ret); 995 } 996 997 static int 998 vioscsi_handle_read_10(struct vioscsi_dev *dev, 999 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1000 { 1001 int ret = 0; 1002 struct virtio_scsi_res_hdr resp; 1003 const uint8_t *read_buf; 1004 uint32_t read_lba; 1005 uint16_t read_10_len; 1006 off_t chunk_offset; 1007 struct ioinfo *info; 1008 struct scsi_rw_10 *read_10; 1009 size_t chunk_len = 0; 1010 1011 memset(&resp, 0, sizeof(resp)); 1012 read_10 = (struct scsi_rw_10 *)(req->cdb); 1013 read_lba = _4btol(read_10->addr); 1014 read_10_len = _2btol(read_10->length); 1015 chunk_offset = 0; 1016 1017 DPRINTF("%s: READ_10 Addr 0x%08x Len %d (%d)", 1018 __func__, read_lba, read_10_len, read_10_len * dev->max_xfer); 1019 1020 /* check if lba is in range */ 1021 if (read_lba > dev->n_blocks - 1) { 1022 DPRINTF("%s: requested block out of range req: %ud max: %lld", 1023 __func__, read_lba, dev->n_blocks); 1024 1025 vioscsi_prepare_resp(&resp, 1026 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 1027 SENSE_LBA_OUT_OF_RANGE, SENSE_DEFAULT_ASCQ); 1028 1029 /* Move index for response */ 1030 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1031 acct->req_desc, &(acct->resp_idx)); 1032 1033 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1034 log_warnx("%s: unable to set ERR status data @ 0x%llx", 1035 __func__, acct->resp_desc->addr); 1036 } else { 1037 ret = 1; 1038 dev->cfg.isr_status = 1; 1039 /* Move ring indexes */ 1040 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1041 acct->req_desc, acct->req_idx); 1042 } 1043 1044 goto read_10_out; 1045 } 1046 1047 info = vioscsi_start_read(dev, read_lba, read_10_len); 1048 1049 if (info == NULL) { 1050 log_warnx("%s: cannot alloc for read", __func__); 1051 goto read_10_out; 1052 } 1053 1054 /* read block */ 1055 read_buf = vioscsi_finish_read(dev, info); 1056 1057 if (read_buf == NULL) { 1058 log_warnx("%s: error reading position %ud", __func__, read_lba); 1059 vioscsi_prepare_resp(&resp, 1060 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_MEDIUM_ERROR, 1061 SENSE_MEDIUM_NOT_PRESENT, SENSE_DEFAULT_ASCQ); 1062 1063 /* Move index for response */ 1064 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1065 acct->req_desc, &(acct->resp_idx)); 1066 1067 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1068 log_warnx("%s: unable to set ERR status data @ 0x%llx", 1069 __func__, acct->resp_desc->addr); 1070 } else { 1071 ret = 1; 1072 dev->cfg.isr_status = 1; 1073 /* Move ring indexes */ 1074 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1075 acct->req_desc, acct->req_idx); 1076 } 1077 1078 goto free_read_10; 1079 } 1080 1081 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 1082 1083 /* Move index for response */ 1084 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 1085 &(acct->resp_idx)); 1086 1087 DPRINTF("%s: writing resp to 0x%llx size %d at local " 1088 "idx %d req_idx %d global_idx %d", 1089 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1090 acct->resp_idx, acct->req_idx, acct->idx); 1091 1092 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1093 log_warnx("%s: unable to write OK resp status " 1094 "data @ 0x%llx", __func__, acct->resp_desc->addr); 1095 goto free_read_10; 1096 } 1097 1098 /* 1099 * Perform possible chunking of writes of read_buf 1100 * based on the segment length allocated by the host. 1101 * At least one write will be performed. 1102 * If chunk_offset == info->len, no more writes 1103 */ 1104 do { 1105 /* Move index for read_buf */ 1106 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1107 acct->resp_desc, &(acct->resp_idx)); 1108 1109 DPRINTF("%s: writing read_buf to 0x%llx size " 1110 "%d at local idx %d req_idx %d global_idx %d", 1111 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1112 acct->resp_idx, acct->req_idx, acct->idx); 1113 1114 /* Check we don't read beyond read_buf boundaries. */ 1115 if (acct->resp_desc->len > info->len - chunk_offset) { 1116 log_warnx("%s: descriptor length beyond read_buf len", 1117 __func__); 1118 chunk_len = info->len - chunk_offset; 1119 } else 1120 chunk_len = acct->resp_desc->len; 1121 1122 if (write_mem(acct->resp_desc->addr, read_buf + chunk_offset, 1123 chunk_len)) { 1124 log_warnx("%s: unable to write read_buf" 1125 " to gpa @ 0x%llx", __func__, 1126 acct->resp_desc->addr); 1127 goto free_read_10; 1128 } 1129 chunk_offset += acct->resp_desc->len; 1130 } while (chunk_offset < info->len); 1131 1132 ret = 1; 1133 dev->cfg.isr_status = 1; 1134 /* Move ring indexes */ 1135 vioscsi_next_ring_item(dev, acct->avail, acct->used, acct->req_desc, 1136 acct->req_idx); 1137 1138 free_read_10: 1139 vioscsi_free_info(info); 1140 read_10_out: 1141 return (ret); 1142 } 1143 1144 static int 1145 vioscsi_handle_prevent_allow(struct vioscsi_dev *dev, 1146 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1147 { 1148 int ret = 0; 1149 struct virtio_scsi_res_hdr resp; 1150 1151 memset(&resp, 0, sizeof(resp)); 1152 /* Move index for response */ 1153 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 1154 &(acct->resp_idx)); 1155 1156 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 1157 1158 if (dev->locked) { 1159 DPRINTF("%s: unlocking medium", __func__); 1160 } else { 1161 DPRINTF("%s: locking medium", __func__); 1162 } 1163 1164 dev->locked = dev->locked ? 0 : 1; 1165 1166 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1167 log_warnx("%s: unable to write OK resp status data @ 0x%llx", 1168 __func__, acct->resp_desc->addr); 1169 } else { 1170 ret = 1; 1171 dev->cfg.isr_status = 1; 1172 /* Move ring indexes */ 1173 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1174 acct->req_desc, acct->req_idx); 1175 } 1176 1177 return (ret); 1178 } 1179 1180 static int 1181 vioscsi_handle_mechanism_status(struct vioscsi_dev *dev, 1182 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1183 { 1184 int ret = 0; 1185 struct virtio_scsi_res_hdr resp; 1186 struct scsi_mechanism_status_header *mech_status_header; 1187 1188 DPRINTF("%s: MECH_STATUS Len %u", __func__, 1189 _2btol(((struct scsi_mechanism_status *)(req->cdb))->length)); 1190 1191 mech_status_header = calloc(1, 1192 sizeof(struct scsi_mechanism_status_header)); 1193 1194 if (mech_status_header == NULL) 1195 goto mech_out; 1196 1197 /* return a 0 header since we are not a changer */ 1198 memset(&resp, 0, sizeof(resp)); 1199 vioscsi_prepare_resp(&resp, 1200 VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 1201 1202 /* Move index for response */ 1203 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1204 acct->req_desc, &(acct->resp_idx)); 1205 1206 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1207 log_warnx("%s: unable to set ERR status data @ 0x%llx", 1208 __func__, acct->resp_desc->addr); 1209 goto free_mech; 1210 } 1211 1212 /* Move index for mech_status_header */ 1213 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 1214 &(acct->resp_idx)); 1215 1216 if (write_mem(acct->resp_desc->addr, mech_status_header, 1217 sizeof(struct scsi_mechanism_status_header))) { 1218 log_warnx("%s: unable to write " 1219 "mech_status_header response to " 1220 "gpa @ 0x%llx", 1221 __func__, acct->resp_desc->addr); 1222 } else { 1223 ret = 1; 1224 dev->cfg.isr_status = 1; 1225 /* Move ring indexes */ 1226 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1227 acct->req_desc, acct->req_idx); 1228 } 1229 1230 free_mech: 1231 free(mech_status_header); 1232 mech_out: 1233 return (ret); 1234 } 1235 1236 static int 1237 vioscsi_handle_read_toc(struct vioscsi_dev *dev, 1238 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1239 { 1240 int ret = 0; 1241 struct virtio_scsi_res_hdr resp; 1242 uint16_t toc_data_len; 1243 uint8_t toc_data[TOC_DATA_SIZE]; 1244 uint8_t *toc_data_p; 1245 struct scsi_read_toc *toc = (struct scsi_read_toc *)(req->cdb); 1246 1247 DPRINTF("%s: %s - MSF %d Track 0x%02x Addr 0x%04x", 1248 __func__, vioscsi_op_names(toc->opcode), ((toc->byte2 >> 1) & 1), 1249 toc->from_track, _2btol(toc->data_len)); 1250 1251 /* Tracks should be 0, 1, or LEAD_OUT_TRACK, 0xaa */ 1252 if (toc->from_track > 1 && 1253 toc->from_track != READ_TOC_LEAD_OUT_TRACK) { 1254 /* illegal request */ 1255 log_warnx("%s: illegal request Track 0x%02x", 1256 __func__, toc->from_track); 1257 1258 memset(&resp, 0, sizeof(resp)); 1259 vioscsi_prepare_resp(&resp, 1260 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 1261 SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); 1262 1263 /* Move index for response */ 1264 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1265 acct->req_desc, &(acct->resp_idx)); 1266 1267 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1268 log_warnx("%s: unable to set ERR status data @ 0x%llx", 1269 __func__, acct->resp_desc->addr); 1270 goto read_toc_out; 1271 } 1272 1273 ret = 1; 1274 dev->cfg.isr_status = 1; 1275 /* Move ring indexes */ 1276 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1277 acct->req_desc, acct->req_idx); 1278 1279 goto read_toc_out; 1280 } 1281 1282 /* 1283 * toc_data is defined as: 1284 * [0-1]: TOC Data Length, typically 0x1a 1285 * [2]: First Track, 1 1286 * [3]: Last Track, 1 1287 * 1288 * Track 1 Descriptor 1289 * [0]: Reserved, 0 1290 * [1]: ADR,Control, 0x14 1291 * [2]: Track #, 1 1292 * [3]: Reserved, 0 1293 * [4-7]: Track Start Address, LBA 1294 * 1295 * Track 0xaa (Lead Out) Descriptor 1296 * [0]: Reserved, 0 1297 * [1]: ADR,Control, 0x14 1298 * [2]: Track #, 0xaa 1299 * [3]: Reserved, 0 1300 * [4-7]: Track Start Address, LBA 1301 */ 1302 memset(toc_data, 0, sizeof(toc_data)); 1303 toc_data_p = toc_data + 2; 1304 *toc_data_p++ = READ_TOC_START_TRACK; 1305 *toc_data_p++ = READ_TOC_LAST_TRACK; 1306 if (toc->from_track <= 1) { 1307 /* first track descriptor */ 1308 *toc_data_p++ = 0x0; 1309 *toc_data_p++ = READ_TOC_ADR_CTL; 1310 *toc_data_p++ = READ_TOC_START_TRACK; 1311 *toc_data_p++ = 0x0; 1312 /* start addr for first track is 0 */ 1313 *toc_data_p++ = 0x0; 1314 *toc_data_p++ = 0x0; 1315 *toc_data_p++ = 0x0; 1316 *toc_data_p++ = 0x0; 1317 } 1318 1319 /* last track descriptor */ 1320 *toc_data_p++ = 0x0; 1321 *toc_data_p++ = READ_TOC_ADR_CTL; 1322 *toc_data_p++ = READ_TOC_LEAD_OUT_TRACK; 1323 *toc_data_p++ = 0x0; 1324 1325 _lto4b((uint32_t)dev->n_blocks, toc_data_p); 1326 toc_data_p += 4; 1327 1328 toc_data_len = toc_data_p - toc_data; 1329 _lto2b((uint32_t)toc_data_len - 2, toc_data); 1330 1331 memset(&resp, 0, sizeof(resp)); 1332 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 1333 1334 /* Move index for response */ 1335 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 1336 &(acct->resp_idx)); 1337 1338 DPRINTF("%s: writing resp to 0x%llx size %d at local " 1339 "idx %d req_idx %d global_idx %d", 1340 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1341 acct->resp_idx, acct->req_idx, acct->idx); 1342 1343 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1344 log_warnx("%s: unable to write OK resp status data @ 0x%llx", 1345 __func__, acct->resp_desc->addr); 1346 goto read_toc_out; 1347 } 1348 1349 /* Move index for toc descriptor */ 1350 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 1351 &(acct->resp_idx)); 1352 1353 DPRINTF("%s: writing toc_data to 0x%llx size %d at " 1354 "local idx %d req_idx %d global_idx %d", 1355 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1356 acct->resp_idx, acct->req_idx, acct->idx); 1357 1358 if (write_mem(acct->resp_desc->addr, toc_data, sizeof(toc_data))) { 1359 log_warnx("%s: unable to write toc descriptor data @ 0x%llx", 1360 __func__, acct->resp_desc->addr); 1361 } else { 1362 ret = 1; 1363 dev->cfg.isr_status = 1; 1364 /* Move ring indexes */ 1365 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1366 acct->req_desc, acct->req_idx); 1367 } 1368 1369 read_toc_out: 1370 return (ret); 1371 } 1372 1373 static int 1374 vioscsi_handle_read_disc_info(struct vioscsi_dev *dev, 1375 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1376 { 1377 int ret = 0; 1378 struct virtio_scsi_res_hdr resp; 1379 1380 DPRINTF("%s: Disc Info %x", __func__, 1381 ((struct scsi_read_disc_information *)(req->cdb))->byte2); 1382 1383 /* send back unsupported */ 1384 memset(&resp, 0, sizeof(resp)); 1385 vioscsi_prepare_resp(&resp, 1386 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 1387 SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); 1388 1389 /* Move index for response */ 1390 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1391 acct->req_desc, &(acct->resp_idx)); 1392 1393 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1394 log_warnx("%s: unable to set ERR status data @ 0x%llx", 1395 __func__, acct->resp_desc->addr); 1396 } else { 1397 ret = 1; 1398 dev->cfg.isr_status = 1; 1399 /* Move ring indexes */ 1400 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1401 acct->req_desc, acct->req_idx); 1402 } 1403 1404 return (ret); 1405 } 1406 1407 static int 1408 vioscsi_handle_gesn(struct vioscsi_dev *dev, 1409 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1410 { 1411 int ret = 0; 1412 struct virtio_scsi_res_hdr resp; 1413 uint8_t gesn_reply[GESN_SIZE]; 1414 struct scsi_gesn *gesn; 1415 struct scsi_gesn_event_header *gesn_event_header; 1416 struct scsi_gesn_power_event *gesn_power_event; 1417 1418 memset(&resp, 0, sizeof(resp)); 1419 gesn = (struct scsi_gesn *)(req->cdb); 1420 DPRINTF("%s: GESN Method %s", __func__, 1421 gesn->byte2 ? "Polling" : "Asynchronous"); 1422 1423 if (gesn->byte2 == 0) { 1424 /* we don't support asynchronous */ 1425 vioscsi_prepare_resp(&resp, 1426 VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, 1427 SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); 1428 1429 /* Move index for response */ 1430 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1431 acct->req_desc, &(acct->resp_idx)); 1432 1433 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1434 log_warnx("%s: unable to set ERR status data @ 0x%llx", 1435 __func__, acct->resp_desc->addr); 1436 goto gesn_out; 1437 } 1438 1439 ret = 1; 1440 dev->cfg.isr_status = 1; 1441 /* Move ring indexes */ 1442 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1443 acct->req_desc, acct->req_idx); 1444 1445 goto gesn_out; 1446 } 1447 memset(gesn_reply, 0, sizeof(gesn_reply)); 1448 gesn_event_header = (struct scsi_gesn_event_header *)(gesn_reply); 1449 gesn_power_event = (struct scsi_gesn_power_event *)(gesn_reply + 4); 1450 /* set event header length and notification */ 1451 _lto2b(GESN_HEADER_LEN, gesn_event_header->length); 1452 gesn_event_header->notification = GESN_NOTIFY_POWER_MGMT; 1453 gesn_event_header->supported_event = GESN_EVENT_POWER_MGMT; 1454 1455 /* set event descriptor */ 1456 gesn_power_event->event_code = GESN_CODE_NOCHG; 1457 if (dev->locked) 1458 gesn_power_event->status = GESN_STATUS_ACTIVE; 1459 else 1460 gesn_power_event->status = GESN_STATUS_IDLE; 1461 1462 /* Move index for response */ 1463 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, 1464 &(acct->resp_idx)); 1465 1466 DPRINTF("%s: writing resp to 0x%llx size %d at local " 1467 "idx %d req_idx %d global_idx %d", 1468 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1469 acct->resp_idx, acct->req_idx, acct->idx); 1470 1471 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1472 log_warnx("%s: unable to write OK resp status " 1473 "data @ 0x%llx", __func__, acct->resp_desc->addr); 1474 goto gesn_out; 1475 } 1476 1477 /* Move index for gesn_reply */ 1478 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 1479 &(acct->resp_idx)); 1480 1481 DPRINTF("%s: writing gesn_reply to 0x%llx size %d at " 1482 "local idx %d req_idx %d global_idx %d", 1483 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1484 acct->resp_idx, acct->req_idx, acct->idx); 1485 1486 if (write_mem(acct->resp_desc->addr, gesn_reply, sizeof(gesn_reply))) { 1487 log_warnx("%s: unable to write gesn_reply" 1488 " response to gpa @ 0x%llx", 1489 __func__, acct->resp_desc->addr); 1490 } else { 1491 ret = 1; 1492 dev->cfg.isr_status = 1; 1493 /* Move ring indexes */ 1494 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1495 acct->req_desc, acct->req_idx); 1496 } 1497 1498 gesn_out: 1499 return (ret); 1500 } 1501 1502 static int 1503 vioscsi_handle_get_config(struct vioscsi_dev *dev, 1504 struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) 1505 { 1506 int ret = 0; 1507 struct virtio_scsi_res_hdr resp; 1508 uint8_t *get_conf_reply; 1509 struct scsi_config_feature_header *config_feature_header; 1510 struct scsi_config_generic_descriptor *config_generic_desc; 1511 struct scsi_config_profile_descriptor *config_profile_desc; 1512 struct scsi_config_core_descriptor *config_core_desc; 1513 struct scsi_config_morphing_descriptor *config_morphing_desc; 1514 struct scsi_config_remove_media_descriptor *config_remove_media_desc; 1515 struct scsi_config_random_read_descriptor *config_random_read_desc; 1516 1517 #if DEBUG 1518 struct scsi_get_configuration *get_configuration = 1519 (struct scsi_get_configuration *)(req->cdb); 1520 log_debug("%s: Conf RT %x Feature %d Len %d", __func__, 1521 get_configuration->byte2, _2btol(get_configuration->feature), 1522 _2btol(get_configuration->length)); 1523 #endif /* DEBUG */ 1524 1525 get_conf_reply = (uint8_t*)calloc(G_CONFIG_REPLY_SIZE, sizeof(uint8_t)); 1526 1527 if (get_conf_reply == NULL) 1528 goto get_config_out; 1529 1530 /* 1531 * Use MMC-5 6.6 for structure and 1532 * MMC-5 5.2 to send back: 1533 * feature header - 8 bytes 1534 * feature descriptor for profile list - 8 bytes 1535 * feature descriptor for core feature - 12 bytes 1536 * feature descriptor for morphing feature - 8 bytes 1537 * feature descriptor for removable media - 8 bytes 1538 * feature descriptor for random read feature - 12 bytes 1539 */ 1540 1541 config_feature_header = 1542 (struct scsi_config_feature_header *)(get_conf_reply); 1543 config_generic_desc = 1544 (struct scsi_config_generic_descriptor *)(get_conf_reply + 8); 1545 config_profile_desc = 1546 (struct scsi_config_profile_descriptor *)(get_conf_reply + 12); 1547 config_core_desc = 1548 (struct scsi_config_core_descriptor *)(get_conf_reply + 16); 1549 config_morphing_desc = 1550 (struct scsi_config_morphing_descriptor *)(get_conf_reply + 28); 1551 config_remove_media_desc = 1552 (struct scsi_config_remove_media_descriptor *)(get_conf_reply + 36); 1553 config_random_read_desc = 1554 (struct scsi_config_random_read_descriptor *)(get_conf_reply + 44); 1555 1556 /* set size to be get_conf_reply - size field */ 1557 _lto4b(G_CONFIG_REPLY_SIZE_HEX, config_feature_header->length); 1558 /* set current profile to be non-conforming */ 1559 _lto2b(CONFIG_PROFILE_NON_CONFORM, 1560 config_feature_header->current_profile); 1561 1562 /* fill out profile list feature */ 1563 _lto2b(CONFIG_FEATURE_CODE_PROFILE, config_generic_desc->feature_code); 1564 config_generic_desc->byte3 = CONFIG_PROFILELIST_BYTE3; 1565 config_generic_desc->length = CONFIG_PROFILELIST_LENGTH; 1566 /* fill out profile descriptor for NON_COFORM */ 1567 _lto2b(CONFIG_PROFILE_NON_CONFORM, config_profile_desc->profile_number); 1568 config_profile_desc->byte3 = CONFIG_PROFILE_BYTE3; 1569 1570 /* fill out core feature */ 1571 _lto2b(CONFIG_FEATURE_CODE_CORE, config_core_desc->feature_code); 1572 config_core_desc->byte3 = CONFIG_CORE_BYTE3; 1573 config_core_desc->length = CONFIG_CORE_LENGTH; 1574 _lto4b(CONFIG_CORE_PHY_SCSI, config_core_desc->phy_std); 1575 1576 /* fill out morphing feature */ 1577 _lto2b(CONFIG_FEATURE_CODE_MORPHING, 1578 config_morphing_desc->feature_code); 1579 config_morphing_desc->byte3 = CONFIG_MORPHING_BYTE3; 1580 config_morphing_desc->length = CONFIG_MORPHING_LENGTH; 1581 config_morphing_desc->byte5 = CONFIG_MORPHING_BYTE5; 1582 1583 /* fill out removable media feature */ 1584 _lto2b(CONFIG_FEATURE_CODE_REMOVE_MEDIA, 1585 config_remove_media_desc->feature_code); 1586 config_remove_media_desc->byte3 = CONFIG_REMOVE_MEDIA_BYTE3; 1587 config_remove_media_desc->length = CONFIG_REMOVE_MEDIA_LENGTH; 1588 config_remove_media_desc->byte5 = CONFIG_REMOVE_MEDIA_BYTE5; 1589 1590 /* fill out random read feature */ 1591 _lto2b(CONFIG_FEATURE_CODE_RANDOM_READ, 1592 config_random_read_desc->feature_code); 1593 config_random_read_desc->byte3 = CONFIG_RANDOM_READ_BYTE3; 1594 config_random_read_desc->length = CONFIG_RANDOM_READ_LENGTH; 1595 if (dev->n_blocks >= UINT32_MAX) 1596 _lto4b(UINT32_MAX, config_random_read_desc->block_size); 1597 else 1598 _lto4b(dev->n_blocks - 1, config_random_read_desc->block_size); 1599 _lto2b(CONFIG_RANDOM_READ_BLOCKING_TYPE, 1600 config_random_read_desc->blocking_type); 1601 1602 memset(&resp, 0, sizeof(resp)); 1603 vioscsi_prepare_resp(&resp, VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); 1604 1605 /* Move index for response */ 1606 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, 1607 acct->req_desc, &(acct->resp_idx)); 1608 1609 DPRINTF("%s: writing resp to 0x%llx size %d at local " 1610 "idx %d req_idx %d global_idx %d", 1611 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1612 acct->resp_idx, acct->req_idx, acct->idx); 1613 1614 if (write_mem(acct->resp_desc->addr, &resp, sizeof(resp))) { 1615 log_warnx("%s: unable to set Ok status data @ 0x%llx", 1616 __func__, acct->resp_desc->addr); 1617 goto free_get_config; 1618 } 1619 1620 /* Move index for get_conf_reply */ 1621 acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, 1622 &(acct->resp_idx)); 1623 1624 DPRINTF("%s: writing get_conf_reply to 0x%llx size %d " 1625 "at local idx %d req_idx %d global_idx %d", 1626 __func__, acct->resp_desc->addr, acct->resp_desc->len, 1627 acct->resp_idx, acct->req_idx, acct->idx); 1628 1629 if (write_mem(acct->resp_desc->addr, get_conf_reply, 1630 G_CONFIG_REPLY_SIZE)) { 1631 log_warnx("%s: unable to write get_conf_reply" 1632 " response to gpa @ 0x%llx", 1633 __func__, acct->resp_desc->addr); 1634 } else { 1635 ret = 1; 1636 dev->cfg.isr_status = 1; 1637 /* Move ring indexes */ 1638 vioscsi_next_ring_item(dev, acct->avail, acct->used, 1639 acct->req_desc, acct->req_idx); 1640 } 1641 1642 free_get_config: 1643 free(get_conf_reply); 1644 get_config_out: 1645 return (ret); 1646 } 1647 1648 int 1649 vioscsi_io(int dir, uint16_t reg, uint32_t *data, uint8_t *intr, 1650 void *cookie, uint8_t sz) 1651 { 1652 struct vioscsi_dev *dev = (struct vioscsi_dev *)cookie; 1653 1654 *intr = 0xFF; 1655 1656 DPRINTF("%s: request %s reg %u, %s sz %u", __func__, 1657 dir ? "READ" : "WRITE", reg, vioscsi_reg_name(reg), sz); 1658 1659 if (dir == 0) { 1660 switch (reg) { 1661 case VIRTIO_CONFIG_DEVICE_FEATURES: 1662 case VIRTIO_CONFIG_QUEUE_SIZE: 1663 case VIRTIO_CONFIG_ISR_STATUS: 1664 log_warnx("%s: illegal write %x to %s", 1665 __progname, *data, vioscsi_reg_name(reg)); 1666 break; 1667 case VIRTIO_CONFIG_GUEST_FEATURES: 1668 dev->cfg.guest_feature = *data; 1669 DPRINTF("%s: guest feature set to %u", 1670 __func__, dev->cfg.guest_feature); 1671 break; 1672 case VIRTIO_CONFIG_QUEUE_PFN: 1673 dev->cfg.queue_pfn = *data; 1674 vioscsi_update_qa(dev); 1675 break; 1676 case VIRTIO_CONFIG_QUEUE_SELECT: 1677 dev->cfg.queue_select = *data; 1678 vioscsi_update_qs(dev); 1679 break; 1680 case VIRTIO_CONFIG_QUEUE_NOTIFY: 1681 dev->cfg.queue_notify = *data; 1682 if (vioscsi_notifyq(dev)) 1683 *intr = 1; 1684 break; 1685 case VIRTIO_CONFIG_DEVICE_STATUS: 1686 dev->cfg.device_status = *data; 1687 DPRINTF("%s: device status set to %u", 1688 __func__, dev->cfg.device_status); 1689 if (dev->cfg.device_status == 0) { 1690 log_debug("%s: device reset", __func__); 1691 dev->cfg.guest_feature = 0; 1692 dev->cfg.queue_pfn = 0; 1693 vioscsi_update_qa(dev); 1694 dev->cfg.queue_size = 0; 1695 vioscsi_update_qs(dev); 1696 dev->cfg.queue_select = 0; 1697 dev->cfg.queue_notify = 0; 1698 dev->cfg.isr_status = 0; 1699 dev->vq[0].last_avail = 0; 1700 dev->vq[1].last_avail = 0; 1701 dev->vq[2].last_avail = 0; 1702 } 1703 break; 1704 default: 1705 break; 1706 } 1707 } else { 1708 switch (reg) { 1709 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI: 1710 /* VIRTIO_SCSI_CONFIG_NUM_QUEUES, 32bit */ 1711 if (sz == 4) 1712 *data = (uint32_t)VIOSCSI_NUM_QUEUES; 1713 else if (sz == 1) { 1714 /* read first byte of num_queues */ 1715 *data &= 0xFFFFFF00; 1716 *data |= (uint32_t)(VIOSCSI_NUM_QUEUES) & 0xFF; 1717 } 1718 break; 1719 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 1: 1720 if (sz == 1) { 1721 /* read second byte of num_queues */ 1722 *data &= 0xFFFFFF00; 1723 *data |= 1724 (uint32_t)(VIOSCSI_NUM_QUEUES >> 8) & 0xFF; 1725 } 1726 break; 1727 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 2: 1728 if (sz == 1) { 1729 /* read third byte of num_queues */ 1730 *data &= 0xFFFFFF00; 1731 *data |= 1732 (uint32_t)(VIOSCSI_NUM_QUEUES >> 16) & 0xFF; 1733 } 1734 break; 1735 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 3: 1736 if (sz == 1) { 1737 /* read fourth byte of num_queues */ 1738 *data &= 0xFFFFFF00; 1739 *data |= 1740 (uint32_t)(VIOSCSI_NUM_QUEUES >> 24) & 0xFF; 1741 } 1742 break; 1743 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 4: 1744 /* VIRTIO_SCSI_CONFIG_SEG_MAX, 32bit */ 1745 if (sz == 4) 1746 *data = (uint32_t)(VIOSCSI_SEG_MAX); 1747 else if (sz == 1) { 1748 /* read first byte of seg_max */ 1749 *data &= 0xFFFFFF00; 1750 *data |= (uint32_t)(VIOSCSI_SEG_MAX) & 0xFF; 1751 } 1752 break; 1753 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 5: 1754 if (sz == 1) { 1755 /* read second byte of seg_max */ 1756 *data &= 0xFFFFFF00; 1757 *data |= 1758 (uint32_t)(VIOSCSI_SEG_MAX >> 8) & 0xFF; 1759 } 1760 break; 1761 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 6: 1762 if (sz == 1) { 1763 /* read third byte of seg_max */ 1764 *data &= 0xFFFFFF00; 1765 *data |= 1766 (uint32_t)(VIOSCSI_SEG_MAX >> 16) & 0xFF; 1767 } 1768 break; 1769 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 7: 1770 if (sz == 1) { 1771 /* read fourth byte of seg_max */ 1772 *data &= 0xFFFFFF00; 1773 *data |= 1774 (uint32_t)(VIOSCSI_SEG_MAX >> 24) & 0xFF; 1775 } 1776 break; 1777 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 8: 1778 /* VIRTIO_SCSI_CONFIG_MAX_SECTORS, 32bit */ 1779 if (sz == 4) 1780 *data = (uint32_t)(dev->max_xfer); 1781 else if (sz == 1) { 1782 /* read first byte of max_xfer */ 1783 *data &= 0xFFFFFF00; 1784 *data |= (uint32_t)(dev->max_xfer) & 0xFF; 1785 } 1786 break; 1787 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 9: 1788 if (sz == 1) { 1789 /* read second byte of max_xfer */ 1790 *data &= 0xFFFFFF00; 1791 *data |= 1792 (uint32_t)(dev->max_xfer >> 8) & 0xFF; 1793 } 1794 break; 1795 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 10: 1796 if (sz == 1) { 1797 /* read third byte of max_xfer */ 1798 *data &= 0xFFFFFF00; 1799 *data |= 1800 (uint32_t)(dev->max_xfer >> 16) & 0xFF; 1801 } 1802 break; 1803 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 11: 1804 if (sz == 1) { 1805 /* read fourth byte of max_xfer */ 1806 *data &= 0xFFFFFF00; 1807 *data |= 1808 (uint32_t)(dev->max_xfer >> 24) & 0xFF; 1809 } 1810 break; 1811 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 12: 1812 /* VIRTIO_SCSI_CONFIG_CMD_PER_LUN, 32bit */ 1813 if (sz == 4) 1814 *data = (uint32_t)(VIOSCSI_CMD_PER_LUN); 1815 else if (sz == 1) { 1816 /* read first byte of cmd_per_lun */ 1817 *data &= 0xFFFFFF00; 1818 *data |= (uint32_t)(VIOSCSI_CMD_PER_LUN) & 0xFF; 1819 } 1820 break; 1821 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 13: 1822 if (sz == 1) { 1823 /* read second byte of cmd_per_lun */ 1824 *data &= 0xFFFFFF00; 1825 *data |= 1826 (uint32_t)(VIOSCSI_CMD_PER_LUN >> 8) & 0xFF; 1827 } 1828 break; 1829 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 14: 1830 if (sz == 1) { 1831 /* read third byte of cmd_per_lun */ 1832 *data &= 0xFFFFFF00; 1833 *data |= (uint32_t)(VIOSCSI_CMD_PER_LUN >> 16) 1834 & 0xFF; 1835 } 1836 break; 1837 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 15: 1838 if (sz == 1) { 1839 /* read fourth byte of cmd_per_lun */ 1840 *data &= 0xFFFFFF00; 1841 *data |= (uint32_t)(VIOSCSI_CMD_PER_LUN >> 24) 1842 & 0xFF; 1843 } 1844 break; 1845 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 16: 1846 /* VIRTIO_SCSI_CONFIG_EVENT_INFO_SIZE, 32bit */ 1847 *data = 0x00; 1848 break; 1849 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 20: 1850 /* VIRTIO_SCSI_CONFIG_SENSE_SIZE, 32bit */ 1851 if (sz == 4) 1852 *data = (uint32_t)(VIOSCSI_SENSE_LEN); 1853 else if (sz == 1) { 1854 /* read first byte of sense_size */ 1855 *data &= 0xFFFFFF00; 1856 *data |= (uint32_t)(VIOSCSI_SENSE_LEN) & 0xFF; 1857 } 1858 break; 1859 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 21: 1860 if (sz == 1) { 1861 /* read second byte of sense_size */ 1862 *data &= 0xFFFFFF00; 1863 *data |= 1864 (uint32_t)(VIOSCSI_SENSE_LEN >> 8) & 0xFF; 1865 } 1866 break; 1867 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 22: 1868 if (sz == 1) { 1869 /* read third byte of sense_size */ 1870 *data &= 0xFFFFFF00; 1871 *data |= 1872 (uint32_t)(VIOSCSI_SENSE_LEN >> 16) & 0xFF; 1873 } 1874 break; 1875 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 23: 1876 if (sz == 1) { 1877 /* read fourth byte of sense_size */ 1878 *data &= 0xFFFFFF00; 1879 *data |= 1880 (uint32_t)(VIOSCSI_SENSE_LEN >> 24) & 0xFF; 1881 } 1882 break; 1883 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 24: 1884 /* VIRTIO_SCSI_CONFIG_CDB_SIZE, 32bit */ 1885 if (sz == 4) 1886 *data = (uint32_t)(VIOSCSI_CDB_LEN); 1887 else if (sz == 1) { 1888 /* read first byte of cdb_len */ 1889 *data &= 0xFFFFFF00; 1890 *data |= (uint32_t)(VIOSCSI_CDB_LEN) & 0xFF; 1891 } 1892 break; 1893 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 25: 1894 if (sz == 1) { 1895 /* read second byte of cdb_len */ 1896 *data &= 0xFFFFFF00; 1897 *data |= 1898 (uint32_t)(VIOSCSI_CDB_LEN >> 8) & 0xFF; 1899 } 1900 break; 1901 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 26: 1902 if (sz == 1) { 1903 /* read third byte of cdb_len */ 1904 *data &= 0xFFFFFF00; 1905 *data |= 1906 (uint32_t)(VIOSCSI_CDB_LEN >> 16) & 0xFF; 1907 } 1908 break; 1909 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 27: 1910 if (sz == 1) { 1911 /* read fourth byte of cdb_len */ 1912 *data &= 0xFFFFFF00; 1913 *data |= 1914 (uint32_t)(VIOSCSI_CDB_LEN >> 24) & 0xFF; 1915 } 1916 break; 1917 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 28: 1918 /* VIRTIO_SCSI_CONFIG_MAX_CHANNEL, 16bit */ 1919 1920 /* defined by standard to be zero */ 1921 *data &= 0xFFFF0000; 1922 break; 1923 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 29: 1924 /* defined by standard to be zero */ 1925 *data &= 0xFFFF0000; 1926 break; 1927 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 30: 1928 /* VIRTIO_SCSI_CONFIG_MAX_TARGET, 16bit */ 1929 if (sz == 2) { 1930 *data &= 0xFFFF0000; 1931 *data |= 1932 (uint32_t)(VIOSCSI_MAX_TARGET) & 0xFFFF; 1933 } else if (sz == 1) { 1934 /* read first byte of max_target */ 1935 *data &= 0xFFFFFF00; 1936 *data |= 1937 (uint32_t)(VIOSCSI_MAX_TARGET) & 0xFF; 1938 } 1939 break; 1940 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 31: 1941 if (sz == 1) { 1942 /* read second byte of max_target */ 1943 *data &= 0xFFFFFF00; 1944 *data |= 1945 (uint32_t)(VIOSCSI_MAX_TARGET >> 8) & 0xFF; 1946 } 1947 break; 1948 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 32: 1949 /* VIRTIO_SCSI_CONFIG_MAX_LUN, 32bit */ 1950 if (sz == 4) 1951 *data = (uint32_t)(VIOSCSI_MAX_LUN); 1952 else if (sz == 1) { 1953 /* read first byte of max_lun */ 1954 *data &= 0xFFFFFF00; 1955 *data |= (uint32_t)(VIOSCSI_MAX_LUN) & 0xFF; 1956 } 1957 break; 1958 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 33: 1959 if (sz == 1) { 1960 /* read second byte of max_lun */ 1961 *data &= 0xFFFFFF00; 1962 *data |= 1963 (uint32_t)(VIOSCSI_MAX_LUN >> 8) & 0xFF; 1964 } 1965 break; 1966 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 34: 1967 if (sz == 1) { 1968 /* read third byte of max_lun */ 1969 *data &= 0xFFFFFF00; 1970 *data |= 1971 (uint32_t)(VIOSCSI_MAX_LUN >> 16) & 0xFF; 1972 } 1973 break; 1974 case VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI + 35: 1975 if (sz == 1) { 1976 /* read fourth byte of max_lun */ 1977 *data &= 0xFFFFFF00; 1978 *data |= 1979 (uint32_t)(VIOSCSI_MAX_LUN >> 24) & 0xFF; 1980 } 1981 break; 1982 case VIRTIO_CONFIG_DEVICE_FEATURES: 1983 *data = dev->cfg.device_feature; 1984 break; 1985 case VIRTIO_CONFIG_GUEST_FEATURES: 1986 *data = dev->cfg.guest_feature; 1987 break; 1988 case VIRTIO_CONFIG_QUEUE_PFN: 1989 *data = dev->cfg.queue_pfn; 1990 break; 1991 case VIRTIO_CONFIG_QUEUE_SIZE: 1992 if (sz == 4) 1993 *data = dev->cfg.queue_size; 1994 else if (sz == 2) { 1995 *data &= 0xFFFF0000; 1996 *data |= (uint16_t)dev->cfg.queue_size; 1997 } else if (sz == 1) { 1998 *data &= 0xFFFFFF00; 1999 *data |= (uint8_t)dev->cfg.queue_size; 2000 } 2001 break; 2002 case VIRTIO_CONFIG_QUEUE_SELECT: 2003 *data = dev->cfg.queue_select; 2004 break; 2005 case VIRTIO_CONFIG_QUEUE_NOTIFY: 2006 *data = dev->cfg.queue_notify; 2007 break; 2008 case VIRTIO_CONFIG_DEVICE_STATUS: 2009 if (sz == 4) 2010 *data = dev->cfg.device_status; 2011 else if (sz == 2) { 2012 *data &= 0xFFFF0000; 2013 *data |= (uint16_t)dev->cfg.device_status; 2014 } else if (sz == 1) { 2015 *data &= 0xFFFFFF00; 2016 *data |= (uint8_t)dev->cfg.device_status; 2017 } 2018 break; 2019 case VIRTIO_CONFIG_ISR_STATUS: 2020 *data = dev->cfg.isr_status; 2021 dev->cfg.isr_status = 0; 2022 break; 2023 } 2024 } 2025 2026 2027 return (0); 2028 } 2029 2030 void 2031 vioscsi_update_qs(struct vioscsi_dev *dev) 2032 { 2033 struct virtio_vq_info *vq_info; 2034 2035 /* Invalid queue? */ 2036 if (dev->cfg.queue_select >= VIRTIO_MAX_QUEUES) { 2037 dev->cfg.queue_size = 0; 2038 return; 2039 } 2040 2041 vq_info = &dev->vq[dev->cfg.queue_select]; 2042 2043 /* Update queue pfn/size based on queue select */ 2044 dev->cfg.queue_pfn = vq_info->q_gpa >> 12; 2045 dev->cfg.queue_size = vq_info->qs; 2046 } 2047 2048 void 2049 vioscsi_update_qa(struct vioscsi_dev *dev) 2050 { 2051 struct virtio_vq_info *vq_info; 2052 void *hva = NULL; 2053 2054 /* Invalid queue? */ 2055 if (dev->cfg.queue_select >= VIRTIO_MAX_QUEUES) 2056 return; 2057 2058 vq_info = &dev->vq[dev->cfg.queue_select]; 2059 vq_info->q_gpa = (uint64_t)dev->cfg.queue_pfn * VIRTIO_PAGE_SIZE; 2060 2061 hva = hvaddr_mem(vq_info->q_gpa, vring_size(VIOSCSI_QUEUE_SIZE)); 2062 if (hva == NULL) 2063 fatal("vioscsi_update_qa"); 2064 vq_info->q_hva = hva; 2065 } 2066 2067 /* 2068 * Process message(s) in the queue(s) 2069 * vioscsi driver will be placing the following in the queue for each iteration 2070 * virtio_scsi_req_hdr with a possible SCSI_DATA_OUT buffer 2071 * along with a virtio_scsi_res_hdr with a possible SCSI_DATA_IN buffer 2072 * for consumption. 2073 * 2074 * Return 1 if an interrupt should be generated (response written) 2075 * 0 otherwise 2076 */ 2077 int 2078 vioscsi_notifyq(struct vioscsi_dev *dev) 2079 { 2080 int cnt, ret = 0; 2081 char *vr; 2082 struct virtio_scsi_req_hdr req; 2083 struct virtio_scsi_res_hdr resp; 2084 struct virtio_vq_acct acct; 2085 struct virtio_vq_info *vq_info; 2086 2087 ret = 0; 2088 2089 /* Invalid queue? */ 2090 if (dev->cfg.queue_notify >= VIRTIO_MAX_QUEUES) 2091 return (ret); 2092 2093 vq_info = &dev->vq[dev->cfg.queue_notify]; 2094 vr = vq_info->q_hva; 2095 if (vr == NULL) 2096 fatalx("%s: null vring", __func__); 2097 2098 /* Compute offsets in ring of descriptors, avail ring, and used ring */ 2099 acct.desc = (struct vring_desc *)(vr); 2100 acct.avail = (struct vring_avail *)(vr + vq_info->vq_availoffset); 2101 acct.used = (struct vring_used *)(vr + vq_info->vq_usedoffset); 2102 2103 acct.idx = vq_info->last_avail & VIOSCSI_QUEUE_MASK; 2104 2105 if ((acct.avail->idx & VIOSCSI_QUEUE_MASK) == acct.idx) { 2106 log_debug("%s - nothing to do?", __func__); 2107 return (0); 2108 } 2109 2110 cnt = 0; 2111 while (acct.idx != (acct.avail->idx & VIOSCSI_QUEUE_MASK)) { 2112 2113 /* Guard against infinite descriptor chains */ 2114 if (++cnt >= VIOSCSI_QUEUE_SIZE) { 2115 log_warnx("%s: invalid descriptor table", __func__); 2116 goto out; 2117 } 2118 2119 acct.req_idx = acct.avail->ring[acct.idx] & VIOSCSI_QUEUE_MASK; 2120 acct.req_desc = &(acct.desc[acct.req_idx]); 2121 2122 /* Clear resp for next message */ 2123 memset(&resp, 0, sizeof(resp)); 2124 2125 if ((acct.req_desc->flags & VRING_DESC_F_NEXT) == 0) { 2126 log_warnx("%s: unchained req descriptor received " 2127 "(idx %d)", __func__, acct.req_idx); 2128 goto out; 2129 } 2130 2131 /* Read command from descriptor ring */ 2132 if (read_mem(acct.req_desc->addr, &req, sizeof(req))) { 2133 log_warnx("%s: command read_mem error @ 0x%llx", 2134 __func__, acct.req_desc->addr); 2135 goto out; 2136 } 2137 2138 /* 2139 * req.lun is defined by virtio as 2140 * lun[0] - Always set to 1 2141 * lun[1] - Target, negotiated as VIOSCSI_MAX_TARGET 2142 * lun[2-3] - represent single level LUN structure 2143 * lun[4-7] - Zero 2144 * At this current time, we are only servicing one device per 2145 * bus (1:0:X:0). 2146 * 2147 * Various implementations will attempt to scan all possible 2148 * targets (256) looking for devices or scan for all possible 2149 * LUNs in a single level. When Target is greater than 2150 * VIOSCSI_MAX_TARGET or when lun[3] is greater than zero, 2151 * respond with a BAD_TARGET response. 2152 */ 2153 if (req.lun[1] >= VIOSCSI_MAX_TARGET || req.lun[3] > 0) { 2154 DPRINTF("%s: Ignore CMD 0x%02x,%s on lun %u:%u:%u:%u", 2155 __func__, req.cdb[0], vioscsi_op_names(req.cdb[0]), 2156 req.lun[0], req.lun[1], req.lun[2], req.lun[3]); 2157 /* Move index for response */ 2158 acct.resp_desc = vioscsi_next_ring_desc(acct.desc, 2159 acct.req_desc, &(acct.resp_idx)); 2160 2161 vioscsi_prepare_resp(&resp, 2162 VIRTIO_SCSI_S_BAD_TARGET, SCSI_OK, 0, 0, 0); 2163 2164 if (acct.resp_desc->len > sizeof(resp)) { 2165 log_warnx("%s: invalid descriptor length", 2166 __func__); 2167 goto out; 2168 } 2169 if (write_mem(acct.resp_desc->addr, &resp, 2170 sizeof(resp))) { 2171 log_warnx("%s: unable to write BAD_TARGET" 2172 " resp status data @ 0x%llx", 2173 __func__, acct.resp_desc->addr); 2174 goto out; 2175 } 2176 2177 ret = 1; 2178 dev->cfg.isr_status = 1; 2179 2180 /* Move ring indexes (updates the used ring index) */ 2181 vioscsi_next_ring_item(dev, acct.avail, acct.used, 2182 acct.req_desc, acct.req_idx); 2183 goto next_msg; 2184 } 2185 2186 DPRINTF("%s: Queue %d id 0x%llx lun %u:%u:%u:%u" 2187 " cdb OP 0x%02x,%s", 2188 __func__, dev->cfg.queue_notify, req.id, 2189 req.lun[0], req.lun[1], req.lun[2], req.lun[3], 2190 req.cdb[0], vioscsi_op_names(req.cdb[0])); 2191 2192 /* opcode is first byte */ 2193 switch (req.cdb[0]) { 2194 case TEST_UNIT_READY: 2195 case START_STOP: 2196 ret = vioscsi_handle_tur(dev, &req, &acct); 2197 break; 2198 case PREVENT_ALLOW: 2199 ret = vioscsi_handle_prevent_allow(dev, &req, &acct); 2200 break; 2201 case READ_TOC: 2202 ret = vioscsi_handle_read_toc(dev, &req, &acct); 2203 break; 2204 case READ_CAPACITY: 2205 ret = vioscsi_handle_read_capacity(dev, &req, &acct); 2206 break; 2207 case READ_CAPACITY_16: 2208 ret = vioscsi_handle_read_capacity_16(dev, &req, &acct); 2209 break; 2210 case READ_COMMAND: 2211 ret = vioscsi_handle_read_6(dev, &req, &acct); 2212 break; 2213 case READ_10: 2214 ret = vioscsi_handle_read_10(dev, &req, &acct); 2215 break; 2216 case INQUIRY: 2217 ret = vioscsi_handle_inquiry(dev, &req, &acct); 2218 break; 2219 case MODE_SENSE: 2220 ret = vioscsi_handle_mode_sense(dev, &req, &acct); 2221 break; 2222 case MODE_SENSE_BIG: 2223 ret = vioscsi_handle_mode_sense_big(dev, &req, &acct); 2224 break; 2225 case GET_EVENT_STATUS_NOTIFICATION: 2226 ret = vioscsi_handle_gesn(dev, &req, &acct); 2227 break; 2228 case READ_DISC_INFORMATION: 2229 ret = vioscsi_handle_read_disc_info(dev, &req, &acct); 2230 break; 2231 case GET_CONFIGURATION: 2232 ret = vioscsi_handle_get_config(dev, &req, &acct); 2233 break; 2234 case MECHANISM_STATUS: 2235 ret = vioscsi_handle_mechanism_status(dev, &req, &acct); 2236 break; 2237 case REPORT_LUNS: 2238 ret = vioscsi_handle_report_luns(dev, &req, &acct); 2239 break; 2240 default: 2241 log_warnx("%s: unsupported opcode 0x%02x,%s", 2242 __func__, req.cdb[0], vioscsi_op_names(req.cdb[0])); 2243 /* Move ring indexes */ 2244 vioscsi_next_ring_item(dev, acct.avail, acct.used, 2245 acct.req_desc, acct.req_idx); 2246 break; 2247 } 2248 next_msg: 2249 /* Increment to the next queue slot */ 2250 acct.idx = (acct.idx + 1) & VIOSCSI_QUEUE_MASK; 2251 } 2252 out: 2253 return (ret); 2254 } 2255