1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * SCSI Disk Emulator 5 * 6 * Copyright (c) 2002 Nate Lawson. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions, and the following disclaimer, 14 * without modification, immediately at the beginning of the file. 15 * 2. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $FreeBSD$ 31 */ 32 33 #include <sys/types.h> 34 #include <ctype.h> 35 #include <errno.h> 36 #include <err.h> 37 #include <fcntl.h> 38 #include <signal.h> 39 #include <stddef.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <sysexits.h> 44 #include <unistd.h> 45 #include <aio.h> 46 #include <assert.h> 47 #include <sys/stat.h> 48 #include <sys/queue.h> 49 #include <sys/event.h> 50 #include <sys/param.h> 51 #include <sys/disk.h> 52 #include <cam/cam_queue.h> 53 #include <cam/scsi/scsi_all.h> 54 #include <cam/scsi/scsi_targetio.h> 55 #include <cam/scsi/scsi_message.h> 56 #include "scsi_target.h" 57 58 /* Maximum amount to transfer per CTIO */ 59 #define MAX_XFER MAXPHYS 60 /* Maximum number of allocated CTIOs */ 61 #define MAX_CTIOS 64 62 /* Maximum sector size for emulated volume */ 63 #define MAX_SECTOR 32768 64 65 /* Global variables */ 66 int debug; 67 int notaio = 0; 68 off_t volume_size; 69 u_int sector_size; 70 size_t buf_size; 71 72 /* Local variables */ 73 static int targ_fd; 74 static int kq_fd; 75 static int file_fd; 76 static int num_ctios; 77 static struct ccb_queue pending_queue; 78 static struct ccb_queue work_queue; 79 static struct ioc_enable_lun ioc_enlun = { 80 CAM_BUS_WILDCARD, 81 CAM_TARGET_WILDCARD, 82 CAM_LUN_WILDCARD 83 }; 84 85 /* Local functions */ 86 static void cleanup(void); 87 static int init_ccbs(void); 88 static void request_loop(void); 89 static void handle_read(void); 90 /* static int work_atio(struct ccb_accept_tio *); */ 91 static void queue_io(struct ccb_scsiio *); 92 static int run_queue(struct ccb_accept_tio *); 93 static int work_inot(struct ccb_immediate_notify *); 94 static struct ccb_scsiio * 95 get_ctio(void); 96 /* static void free_ccb(union ccb *); */ 97 static cam_status get_sim_flags(u_int16_t *); 98 static void rel_simq(void); 99 static void abort_all_pending(void); 100 static void usage(void); 101 102 int 103 main(int argc, char *argv[]) 104 { 105 int ch; 106 char *file_name; 107 u_int16_t req_flags, sim_flags; 108 off_t user_size; 109 110 /* Initialize */ 111 debug = 0; 112 req_flags = sim_flags = 0; 113 user_size = 0; 114 targ_fd = file_fd = kq_fd = -1; 115 num_ctios = 0; 116 sector_size = SECTOR_SIZE; 117 buf_size = DFLTPHYS; 118 119 /* Prepare resource pools */ 120 TAILQ_INIT(&pending_queue); 121 TAILQ_INIT(&work_queue); 122 123 while ((ch = getopt(argc, argv, "AdSTYb:c:s:W:")) != -1) { 124 switch(ch) { 125 case 'A': 126 req_flags |= SID_Addr16; 127 break; 128 case 'd': 129 debug = 1; 130 break; 131 case 'S': 132 req_flags |= SID_Sync; 133 break; 134 case 'T': 135 req_flags |= SID_CmdQue; 136 break; 137 case 'b': 138 buf_size = atoi(optarg); 139 if (buf_size < 256 || buf_size > MAX_XFER) 140 errx(1, "Unreasonable buf size: %s", optarg); 141 break; 142 case 'c': 143 sector_size = atoi(optarg); 144 if (sector_size < 512 || sector_size > MAX_SECTOR) 145 errx(1, "Unreasonable sector size: %s", optarg); 146 break; 147 case 's': 148 { 149 int last, shift = 0; 150 151 last = strlen(optarg) - 1; 152 if (last > 0) { 153 switch (tolower(optarg[last])) { 154 case 'e': 155 shift += 10; 156 /* FALLTHROUGH */ 157 case 'p': 158 shift += 10; 159 /* FALLTHROUGH */ 160 case 't': 161 shift += 10; 162 /* FALLTHROUGH */ 163 case 'g': 164 shift += 10; 165 /* FALLTHROUGH */ 166 case 'm': 167 shift += 10; 168 /* FALLTHROUGH */ 169 case 'k': 170 shift += 10; 171 optarg[last] = 0; 172 break; 173 } 174 } 175 user_size = strtoll(optarg, (char **)NULL, /*base*/10); 176 user_size <<= shift; 177 if (user_size < 0) 178 errx(1, "Unreasonable volume size: %s", optarg); 179 break; 180 } 181 case 'W': 182 req_flags &= ~(SID_WBus16 | SID_WBus32); 183 switch (atoi(optarg)) { 184 case 8: 185 /* Leave req_flags zeroed */ 186 break; 187 case 16: 188 req_flags |= SID_WBus16; 189 break; 190 case 32: 191 req_flags |= SID_WBus32; 192 break; 193 default: 194 warnx("Width %s not supported", optarg); 195 usage(); 196 /* NOTREACHED */ 197 } 198 break; 199 case 'Y': 200 notaio = 1; 201 break; 202 default: 203 usage(); 204 /* NOTREACHED */ 205 } 206 } 207 argc -= optind; 208 argv += optind; 209 210 if (argc != 2) 211 usage(); 212 213 sscanf(argv[0], "%u:%u:%u", &ioc_enlun.path_id, &ioc_enlun.target_id, 214 &ioc_enlun.lun_id); 215 file_name = argv[1]; 216 217 if (ioc_enlun.path_id == CAM_BUS_WILDCARD || 218 ioc_enlun.target_id == CAM_TARGET_WILDCARD || 219 ioc_enlun.lun_id == CAM_LUN_WILDCARD) { 220 warnx("Incomplete target path specified"); 221 usage(); 222 /* NOTREACHED */ 223 } 224 /* We don't support any vendor-specific commands */ 225 ioc_enlun.grp6_len = 0; 226 ioc_enlun.grp7_len = 0; 227 228 /* Open backing store for IO */ 229 file_fd = open(file_name, O_RDWR); 230 if (file_fd < 0) 231 errx(EX_NOINPUT, "open backing store file"); 232 233 /* Check backing store size or use the size user gave us */ 234 if (user_size == 0) { 235 struct stat st; 236 237 if (fstat(file_fd, &st) < 0) 238 err(1, "fstat file"); 239 #if __FreeBSD_version >= 500000 240 if ((st.st_mode & S_IFCHR) != 0) { 241 /* raw device */ 242 off_t mediasize; 243 if (ioctl(file_fd, DIOCGMEDIASIZE, &mediasize) < 0) 244 err(1, "DIOCGMEDIASIZE"); 245 246 /* XXX get sector size by ioctl()?? */ 247 volume_size = mediasize / sector_size; 248 } else 249 #endif 250 volume_size = st.st_size / sector_size; 251 } else { 252 volume_size = user_size / sector_size; 253 } 254 if (debug) 255 warnx("volume_size: %d bytes x " OFF_FMT " sectors", 256 sector_size, volume_size); 257 258 if (volume_size <= 0) 259 errx(1, "volume must be larger than %d", sector_size); 260 261 if (notaio == 0) { 262 struct aiocb aio, *aiop; 263 264 /* See if we have we have working AIO support */ 265 memset(&aio, 0, sizeof(aio)); 266 aio.aio_buf = malloc(sector_size); 267 if (aio.aio_buf == NULL) 268 err(1, "malloc"); 269 aio.aio_fildes = file_fd; 270 aio.aio_offset = 0; 271 aio.aio_nbytes = sector_size; 272 signal(SIGSYS, SIG_IGN); 273 if (aio_read(&aio) != 0) { 274 printf("AIO support is not available- switchin to" 275 " single-threaded mode.\n"); 276 notaio = 1; 277 } else { 278 if (aio_waitcomplete(&aiop, NULL) != sector_size) 279 err(1, "aio_waitcomplete"); 280 assert(aiop == &aio); 281 signal(SIGSYS, SIG_DFL); 282 } 283 free((void *)aio.aio_buf); 284 if (debug && notaio == 0) 285 warnx("aio support tested ok"); 286 } 287 288 targ_fd = open("/dev/targ", O_RDWR); 289 if (targ_fd < 0) 290 err(1, "/dev/targ"); 291 else 292 warnx("opened /dev/targ"); 293 294 /* The first three are handled by kevent() later */ 295 signal(SIGHUP, SIG_IGN); 296 signal(SIGINT, SIG_IGN); 297 signal(SIGTERM, SIG_IGN); 298 signal(SIGPROF, SIG_IGN); 299 signal(SIGALRM, SIG_IGN); 300 signal(SIGSTOP, SIG_IGN); 301 signal(SIGTSTP, SIG_IGN); 302 303 /* Register a cleanup handler to run when exiting */ 304 atexit(cleanup); 305 306 /* Enable listening on the specified LUN */ 307 if (ioctl(targ_fd, TARGIOCENABLE, &ioc_enlun) != 0) 308 err(1, "TARGIOCENABLE"); 309 310 /* Enable debugging if requested */ 311 if (debug) { 312 if (ioctl(targ_fd, TARGIOCDEBUG, &debug) != 0) 313 warnx("TARGIOCDEBUG"); 314 } 315 316 /* Set up inquiry data according to what SIM supports */ 317 if (get_sim_flags(&sim_flags) != CAM_REQ_CMP) 318 errx(1, "get_sim_flags"); 319 320 if (tcmd_init(req_flags, sim_flags) != 0) 321 errx(1, "Initializing tcmd subsystem failed"); 322 323 /* Queue ATIOs and INOTs on descriptor */ 324 if (init_ccbs() != 0) 325 errx(1, "init_ccbs failed"); 326 327 if (debug) 328 warnx("main loop beginning"); 329 330 request_loop(); 331 332 exit(0); 333 } 334 335 static void 336 cleanup() 337 { 338 struct ccb_hdr *ccb_h; 339 340 if (debug) { 341 warnx("cleanup called"); 342 debug = 0; 343 ioctl(targ_fd, TARGIOCDEBUG, &debug); 344 } 345 ioctl(targ_fd, TARGIOCDISABLE, NULL); 346 close(targ_fd); 347 348 while ((ccb_h = TAILQ_FIRST(&pending_queue)) != NULL) { 349 TAILQ_REMOVE(&pending_queue, ccb_h, periph_links.tqe); 350 free_ccb((union ccb *)ccb_h); 351 } 352 while ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) { 353 TAILQ_REMOVE(&work_queue, ccb_h, periph_links.tqe); 354 free_ccb((union ccb *)ccb_h); 355 } 356 357 if (kq_fd != -1) 358 close(kq_fd); 359 } 360 361 /* Allocate ATIOs/INOTs and queue on HBA */ 362 static int 363 init_ccbs() 364 { 365 int i; 366 367 for (i = 0; i < MAX_INITIATORS; i++) { 368 struct ccb_accept_tio *atio; 369 struct atio_descr *a_descr; 370 struct ccb_immediate_notify *inot; 371 372 atio = (struct ccb_accept_tio *)malloc(sizeof(*atio)); 373 if (atio == NULL) { 374 warn("malloc ATIO"); 375 return (-1); 376 } 377 a_descr = (struct atio_descr *)malloc(sizeof(*a_descr)); 378 if (a_descr == NULL) { 379 free(atio); 380 warn("malloc atio_descr"); 381 return (-1); 382 } 383 atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; 384 atio->ccb_h.targ_descr = a_descr; 385 send_ccb((union ccb *)atio, /*priority*/1); 386 387 inot = (struct ccb_immediate_notify *)malloc(sizeof(*inot)); 388 if (inot == NULL) { 389 warn("malloc INOT"); 390 return (-1); 391 } 392 inot->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; 393 send_ccb((union ccb *)inot, /*priority*/1); 394 } 395 396 return (0); 397 } 398 399 static void 400 request_loop() 401 { 402 struct kevent events[MAX_EVENTS]; 403 struct timespec ts, *tptr; 404 int quit; 405 406 /* Register kqueue for event notification */ 407 if ((kq_fd = kqueue()) < 0) 408 err(1, "init kqueue"); 409 410 /* Set up some default events */ 411 EV_SET(&events[0], SIGHUP, EVFILT_SIGNAL, EV_ADD|EV_ENABLE, 0, 0, 0); 412 EV_SET(&events[1], SIGINT, EVFILT_SIGNAL, EV_ADD|EV_ENABLE, 0, 0, 0); 413 EV_SET(&events[2], SIGTERM, EVFILT_SIGNAL, EV_ADD|EV_ENABLE, 0, 0, 0); 414 EV_SET(&events[3], targ_fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); 415 if (kevent(kq_fd, events, 4, NULL, 0, NULL) < 0) 416 err(1, "kevent signal registration"); 417 418 ts.tv_sec = 0; 419 ts.tv_nsec = 0; 420 tptr = NULL; 421 quit = 0; 422 423 /* Loop until user signal */ 424 while (quit == 0) { 425 int retval, i, oo; 426 struct ccb_hdr *ccb_h; 427 428 /* Check for the next signal, read ready, or AIO completion */ 429 retval = kevent(kq_fd, NULL, 0, events, MAX_EVENTS, tptr); 430 if (retval < 0) { 431 if (errno == EINTR) { 432 if (debug) 433 warnx("EINTR, looping"); 434 continue; 435 } 436 else { 437 err(1, "kevent failed"); 438 } 439 } else if (retval > MAX_EVENTS) { 440 errx(1, "kevent returned more events than allocated?"); 441 } 442 443 /* Process all received events. */ 444 for (oo = i = 0; i < retval; i++) { 445 if ((events[i].flags & EV_ERROR) != 0) 446 errx(1, "kevent registration failed"); 447 448 switch (events[i].filter) { 449 case EVFILT_READ: 450 if (debug) 451 warnx("read ready"); 452 handle_read(); 453 break; 454 case EVFILT_AIO: 455 { 456 struct ccb_scsiio *ctio; 457 struct ctio_descr *c_descr; 458 if (debug) 459 warnx("aio ready"); 460 461 ctio = (struct ccb_scsiio *)events[i].udata; 462 c_descr = (struct ctio_descr *) 463 ctio->ccb_h.targ_descr; 464 c_descr->event = AIO_DONE; 465 /* Queue on the appropriate ATIO */ 466 queue_io(ctio); 467 /* Process any queued completions. */ 468 oo += run_queue(c_descr->atio); 469 break; 470 } 471 case EVFILT_SIGNAL: 472 if (debug) 473 warnx("signal ready, setting quit"); 474 quit = 1; 475 break; 476 default: 477 warnx("unknown event %d", events[i].filter); 478 break; 479 } 480 481 if (debug) 482 warnx("event %d done", events[i].filter); 483 } 484 485 if (oo) { 486 tptr = &ts; 487 continue; 488 } 489 490 /* Grab the first CCB and perform one work unit. */ 491 if ((ccb_h = TAILQ_FIRST(&work_queue)) != NULL) { 492 union ccb *ccb; 493 494 ccb = (union ccb *)ccb_h; 495 switch (ccb_h->func_code) { 496 case XPT_ACCEPT_TARGET_IO: 497 /* Start one more transfer. */ 498 retval = work_atio(&ccb->atio); 499 break; 500 case XPT_IMMEDIATE_NOTIFY: 501 retval = work_inot(&ccb->cin1); 502 break; 503 default: 504 warnx("Unhandled ccb type %#x on workq", 505 ccb_h->func_code); 506 abort(); 507 /* NOTREACHED */ 508 } 509 510 /* Assume work function handled the exception */ 511 if ((ccb_h->status & CAM_DEV_QFRZN) != 0) { 512 if (debug) { 513 warnx("Queue frozen receiving CCB, " 514 "releasing"); 515 } 516 rel_simq(); 517 } 518 519 /* No more work needed for this command. */ 520 if (retval == 0) { 521 TAILQ_REMOVE(&work_queue, ccb_h, 522 periph_links.tqe); 523 } 524 } 525 526 /* 527 * Poll for new events (i.e. completions) while we 528 * are processing CCBs on the work_queue. Once it's 529 * empty, use an infinite wait. 530 */ 531 if (!TAILQ_EMPTY(&work_queue)) 532 tptr = &ts; 533 else 534 tptr = NULL; 535 } 536 } 537 538 /* CCBs are ready from the kernel */ 539 static void 540 handle_read() 541 { 542 union ccb *ccb_array[MAX_INITIATORS], *ccb; 543 int ccb_count, i, oo; 544 545 ccb_count = read(targ_fd, ccb_array, sizeof(ccb_array)); 546 if (ccb_count <= 0) { 547 warn("read ccb ptrs"); 548 return; 549 } 550 ccb_count /= sizeof(union ccb *); 551 if (ccb_count < 1) { 552 warnx("truncated read ccb ptr?"); 553 return; 554 } 555 556 for (i = 0; i < ccb_count; i++) { 557 ccb = ccb_array[i]; 558 TAILQ_REMOVE(&pending_queue, &ccb->ccb_h, periph_links.tqe); 559 560 switch (ccb->ccb_h.func_code) { 561 case XPT_ACCEPT_TARGET_IO: 562 { 563 struct ccb_accept_tio *atio; 564 struct atio_descr *a_descr; 565 566 /* Initialize ATIO descr for this transaction */ 567 atio = &ccb->atio; 568 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 569 bzero(a_descr, sizeof(*a_descr)); 570 TAILQ_INIT(&a_descr->cmplt_io); 571 a_descr->flags = atio->ccb_h.flags & 572 (CAM_DIS_DISCONNECT | CAM_TAG_ACTION_VALID); 573 /* XXX add a_descr->priority */ 574 if ((atio->ccb_h.flags & CAM_CDB_POINTER) == 0) 575 a_descr->cdb = atio->cdb_io.cdb_bytes; 576 else 577 a_descr->cdb = atio->cdb_io.cdb_ptr; 578 579 /* ATIOs are processed in FIFO order */ 580 TAILQ_INSERT_TAIL(&work_queue, &ccb->ccb_h, 581 periph_links.tqe); 582 break; 583 } 584 case XPT_CONT_TARGET_IO: 585 { 586 struct ccb_scsiio *ctio; 587 struct ctio_descr *c_descr; 588 589 ctio = &ccb->ctio; 590 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr; 591 c_descr->event = CTIO_DONE; 592 /* Queue on the appropriate ATIO */ 593 queue_io(ctio); 594 /* Process any queued completions. */ 595 oo += run_queue(c_descr->atio); 596 break; 597 } 598 case XPT_IMMEDIATE_NOTIFY: 599 /* INOTs are handled with priority */ 600 TAILQ_INSERT_HEAD(&work_queue, &ccb->ccb_h, 601 periph_links.tqe); 602 break; 603 default: 604 warnx("Unhandled ccb type %#x in handle_read", 605 ccb->ccb_h.func_code); 606 break; 607 } 608 } 609 } 610 611 /* Process an ATIO CCB from the kernel */ 612 int 613 work_atio(struct ccb_accept_tio *atio) 614 { 615 struct ccb_scsiio *ctio; 616 struct atio_descr *a_descr; 617 struct ctio_descr *c_descr; 618 cam_status status; 619 int ret; 620 621 if (debug) 622 warnx("Working on ATIO %p", atio); 623 624 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 625 626 /* Get a CTIO and initialize it according to our known parameters */ 627 ctio = get_ctio(); 628 if (ctio == NULL) { 629 return (1); 630 } 631 ret = 0; 632 ctio->ccb_h.flags = a_descr->flags; 633 ctio->tag_id = atio->tag_id; 634 ctio->init_id = atio->init_id; 635 /* XXX priority needs to be added to a_descr */ 636 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr; 637 c_descr->atio = atio; 638 if ((a_descr->flags & CAM_DIR_IN) != 0) 639 c_descr->offset = a_descr->base_off + a_descr->targ_req; 640 else if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT) 641 c_descr->offset = a_descr->base_off + a_descr->init_req; 642 else 643 c_descr->offset = a_descr->base_off; 644 645 /* 646 * Return a check condition if there was an error while 647 * receiving this ATIO. 648 */ 649 if (atio->sense_len != 0) { 650 struct scsi_sense_data_fixed *sense; 651 652 if (debug) { 653 warnx("ATIO with %u bytes sense received", 654 atio->sense_len); 655 } 656 sense = (struct scsi_sense_data_fixed *)&atio->sense_data; 657 tcmd_sense(ctio->init_id, ctio, sense->flags, 658 sense->add_sense_code, sense->add_sense_code_qual); 659 send_ccb((union ccb *)ctio, /*priority*/1); 660 return (0); 661 } 662 663 status = atio->ccb_h.status & CAM_STATUS_MASK; 664 switch (status) { 665 case CAM_CDB_RECVD: 666 ret = tcmd_handle(atio, ctio, ATIO_WORK); 667 break; 668 case CAM_REQ_ABORTED: 669 warn("ATIO %p aborted", a_descr); 670 /* Requeue on HBA */ 671 TAILQ_REMOVE(&work_queue, &atio->ccb_h, periph_links.tqe); 672 send_ccb((union ccb *)atio, /*priority*/1); 673 ret = 1; 674 break; 675 default: 676 warnx("ATIO completed with unhandled status %#x", status); 677 abort(); 678 /* NOTREACHED */ 679 break; 680 } 681 682 return (ret); 683 } 684 685 static void 686 queue_io(struct ccb_scsiio *ctio) 687 { 688 struct ccb_hdr *ccb_h; 689 struct io_queue *ioq; 690 struct ctio_descr *c_descr; 691 692 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr; 693 if (c_descr->atio == NULL) { 694 errx(1, "CTIO %p has NULL ATIO", ctio); 695 } 696 ioq = &((struct atio_descr *)c_descr->atio->ccb_h.targ_descr)->cmplt_io; 697 698 if (TAILQ_EMPTY(ioq)) { 699 TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe); 700 return; 701 } 702 703 TAILQ_FOREACH_REVERSE(ccb_h, ioq, io_queue, periph_links.tqe) { 704 struct ctio_descr *curr_descr = 705 (struct ctio_descr *)ccb_h->targ_descr; 706 if (curr_descr->offset <= c_descr->offset) { 707 break; 708 } 709 } 710 711 if (ccb_h) { 712 TAILQ_INSERT_AFTER(ioq, ccb_h, &ctio->ccb_h, periph_links.tqe); 713 } else { 714 TAILQ_INSERT_HEAD(ioq, &ctio->ccb_h, periph_links.tqe); 715 } 716 } 717 718 /* 719 * Go through all completed AIO/CTIOs for a given ATIO and advance data 720 * counts, start continuation IO, etc. 721 */ 722 static int 723 run_queue(struct ccb_accept_tio *atio) 724 { 725 struct atio_descr *a_descr; 726 struct ccb_hdr *ccb_h; 727 int sent_status, event; 728 729 if (atio == NULL) 730 return (0); 731 732 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 733 734 while ((ccb_h = TAILQ_FIRST(&a_descr->cmplt_io)) != NULL) { 735 struct ccb_scsiio *ctio; 736 struct ctio_descr *c_descr; 737 738 ctio = (struct ccb_scsiio *)ccb_h; 739 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr; 740 741 if (ctio->ccb_h.status == CAM_REQ_ABORTED) { 742 TAILQ_REMOVE(&a_descr->cmplt_io, ccb_h, 743 periph_links.tqe); 744 free_ccb((union ccb *)ctio); 745 send_ccb((union ccb *)atio, /*priority*/1); 746 continue; 747 } 748 749 /* If completed item is in range, call handler */ 750 if ((c_descr->event == AIO_DONE && 751 c_descr->offset == a_descr->base_off + a_descr->targ_ack) 752 || (c_descr->event == CTIO_DONE && 753 c_descr->offset == a_descr->base_off + a_descr->init_ack)) { 754 sent_status = (ccb_h->flags & CAM_SEND_STATUS) != 0; 755 event = c_descr->event; 756 757 TAILQ_REMOVE(&a_descr->cmplt_io, ccb_h, 758 periph_links.tqe); 759 tcmd_handle(atio, ctio, c_descr->event); 760 761 /* If entire transfer complete, send back ATIO */ 762 if (sent_status != 0 && event == CTIO_DONE) 763 send_ccb((union ccb *)atio, /*priority*/1); 764 } else { 765 /* Gap in offsets so wait until later callback */ 766 if (/* debug */ 1) 767 warnx("IO %p:%p out of order %s", ccb_h, 768 a_descr, c_descr->event == AIO_DONE? 769 "aio" : "ctio"); 770 return (1); 771 } 772 } 773 return (0); 774 } 775 776 static int 777 work_inot(struct ccb_immediate_notify *inot) 778 { 779 cam_status status; 780 781 if (debug) 782 warnx("Working on INOT %p", inot); 783 784 status = inot->ccb_h.status; 785 status &= CAM_STATUS_MASK; 786 787 switch (status) { 788 case CAM_SCSI_BUS_RESET: 789 tcmd_ua(CAM_TARGET_WILDCARD, UA_BUS_RESET); 790 abort_all_pending(); 791 break; 792 case CAM_BDR_SENT: 793 tcmd_ua(CAM_TARGET_WILDCARD, UA_BDR); 794 abort_all_pending(); 795 break; 796 case CAM_MESSAGE_RECV: 797 switch (inot->arg) { 798 case MSG_TASK_COMPLETE: 799 case MSG_INITIATOR_DET_ERR: 800 case MSG_ABORT_TASK_SET: 801 case MSG_MESSAGE_REJECT: 802 case MSG_NOOP: 803 case MSG_PARITY_ERROR: 804 case MSG_TARGET_RESET: 805 case MSG_ABORT_TASK: 806 case MSG_CLEAR_TASK_SET: 807 default: 808 warnx("INOT message %#x", inot->arg); 809 break; 810 } 811 break; 812 case CAM_REQ_ABORTED: 813 warnx("INOT %p aborted", inot); 814 break; 815 default: 816 warnx("Unhandled INOT status %#x", status); 817 break; 818 } 819 820 /* Requeue on SIM */ 821 TAILQ_REMOVE(&work_queue, &inot->ccb_h, periph_links.tqe); 822 send_ccb((union ccb *)inot, /*priority*/1); 823 824 return (1); 825 } 826 827 void 828 send_ccb(union ccb *ccb, int priority) 829 { 830 if (debug) 831 warnx("sending ccb (%#x)", ccb->ccb_h.func_code); 832 ccb->ccb_h.pinfo.priority = priority; 833 if (XPT_FC_IS_QUEUED(ccb)) { 834 TAILQ_INSERT_TAIL(&pending_queue, &ccb->ccb_h, 835 periph_links.tqe); 836 } 837 if (write(targ_fd, &ccb, sizeof(ccb)) != sizeof(ccb)) { 838 warn("write ccb"); 839 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 840 } 841 } 842 843 /* Return a CTIO/descr/buf combo from the freelist or malloc one */ 844 static struct ccb_scsiio * 845 get_ctio() 846 { 847 struct ccb_scsiio *ctio; 848 struct ctio_descr *c_descr; 849 struct sigevent *se; 850 851 if (num_ctios == MAX_CTIOS) { 852 warnx("at CTIO max"); 853 return (NULL); 854 } 855 856 ctio = (struct ccb_scsiio *)malloc(sizeof(*ctio)); 857 if (ctio == NULL) { 858 warn("malloc CTIO"); 859 return (NULL); 860 } 861 c_descr = (struct ctio_descr *)malloc(sizeof(*c_descr)); 862 if (c_descr == NULL) { 863 free(ctio); 864 warn("malloc ctio_descr"); 865 return (NULL); 866 } 867 c_descr->buf = malloc(buf_size); 868 if (c_descr->buf == NULL) { 869 free(c_descr); 870 free(ctio); 871 warn("malloc backing store"); 872 return (NULL); 873 } 874 num_ctios++; 875 876 /* Initialize CTIO, CTIO descr, and AIO */ 877 ctio->ccb_h.func_code = XPT_CONT_TARGET_IO; 878 ctio->ccb_h.retry_count = 2; 879 ctio->ccb_h.timeout = CAM_TIME_INFINITY; 880 ctio->data_ptr = c_descr->buf; 881 ctio->ccb_h.targ_descr = c_descr; 882 c_descr->aiocb.aio_buf = c_descr->buf; 883 c_descr->aiocb.aio_fildes = file_fd; 884 se = &c_descr->aiocb.aio_sigevent; 885 se->sigev_notify = SIGEV_KEVENT; 886 se->sigev_notify_kqueue = kq_fd; 887 se->sigev_value.sival_ptr = ctio; 888 889 return (ctio); 890 } 891 892 void 893 free_ccb(union ccb *ccb) 894 { 895 switch (ccb->ccb_h.func_code) { 896 case XPT_CONT_TARGET_IO: 897 { 898 struct ctio_descr *c_descr; 899 900 c_descr = (struct ctio_descr *)ccb->ccb_h.targ_descr; 901 free(c_descr->buf); 902 num_ctios--; 903 /* FALLTHROUGH */ 904 } 905 case XPT_ACCEPT_TARGET_IO: 906 free(ccb->ccb_h.targ_descr); 907 /* FALLTHROUGH */ 908 case XPT_IMMEDIATE_NOTIFY: 909 default: 910 free(ccb); 911 break; 912 } 913 } 914 915 static cam_status 916 get_sim_flags(u_int16_t *flags) 917 { 918 struct ccb_pathinq cpi; 919 cam_status status; 920 921 /* Find SIM capabilities */ 922 bzero(&cpi, sizeof(cpi)); 923 cpi.ccb_h.func_code = XPT_PATH_INQ; 924 send_ccb((union ccb *)&cpi, /*priority*/1); 925 status = cpi.ccb_h.status & CAM_STATUS_MASK; 926 if (status != CAM_REQ_CMP) { 927 fprintf(stderr, "CPI failed, status %#x\n", status); 928 return (status); 929 } 930 931 /* Can only enable on controllers that support target mode */ 932 if ((cpi.target_sprt & PIT_PROCESSOR) == 0) { 933 fprintf(stderr, "HBA does not support target mode\n"); 934 status = CAM_PATH_INVALID; 935 return (status); 936 } 937 938 *flags = cpi.hba_inquiry; 939 return (status); 940 } 941 942 static void 943 rel_simq() 944 { 945 struct ccb_relsim crs; 946 947 bzero(&crs, sizeof(crs)); 948 crs.ccb_h.func_code = XPT_REL_SIMQ; 949 crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY; 950 crs.openings = 0; 951 crs.release_timeout = 0; 952 crs.qfrozen_cnt = 0; 953 send_ccb((union ccb *)&crs, /*priority*/0); 954 } 955 956 /* Cancel all pending CCBs. */ 957 static void 958 abort_all_pending() 959 { 960 struct ccb_abort cab; 961 struct ccb_hdr *ccb_h; 962 963 if (debug) 964 warnx("abort_all_pending"); 965 966 bzero(&cab, sizeof(cab)); 967 cab.ccb_h.func_code = XPT_ABORT; 968 TAILQ_FOREACH(ccb_h, &pending_queue, periph_links.tqe) { 969 if (debug) 970 warnx("Aborting pending CCB %p\n", ccb_h); 971 cab.abort_ccb = (union ccb *)ccb_h; 972 send_ccb((union ccb *)&cab, /*priority*/1); 973 if (cab.ccb_h.status != CAM_REQ_CMP) { 974 warnx("Unable to abort CCB, status %#x\n", 975 cab.ccb_h.status); 976 } 977 } 978 } 979 980 static void 981 usage() 982 { 983 fprintf(stderr, 984 "Usage: scsi_target [-AdSTY] [-b bufsize] [-c sectorsize]\n" 985 "\t\t[-r numbufs] [-s volsize] [-W 8,16,32]\n" 986 "\t\tbus:target:lun filename\n"); 987 exit(1); 988 } 989