1 /* 2 * SCSI Disk Emulator 3 * 4 * Copyright (c) 2002 Nate Lawson. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <sys/types.h> 32 #include <ctype.h> 33 #include <errno.h> 34 #include <err.h> 35 #include <fcntl.h> 36 #include <signal.h> 37 #include <stddef.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <sysexits.h> 42 #include <unistd.h> 43 #include <aio.h> 44 #include <assert.h> 45 #include <sys/stat.h> 46 #include <sys/queue.h> 47 #include <sys/event.h> 48 #include <sys/param.h> 49 #include <sys/disk.h> 50 #include <cam/cam_queue.h> 51 #include <cam/scsi/scsi_all.h> 52 #include <cam/scsi/scsi_targetio.h> 53 #include <cam/scsi/scsi_message.h> 54 #include "scsi_target.h" 55 56 /* Maximum amount to transfer per CTIO */ 57 #define MAX_XFER MAXPHYS 58 /* Maximum number of allocated CTIOs */ 59 #define MAX_CTIOS 64 60 /* Maximum sector size for emulated volume */ 61 #define MAX_SECTOR 32768 62 63 /* Global variables */ 64 int debug; 65 int notaio = 0; 66 off_t volume_size; 67 u_int sector_size; 68 size_t buf_size; 69 70 /* Local variables */ 71 static int targ_fd; 72 static int kq_fd; 73 static int file_fd; 74 static int num_ctios; 75 static struct ccb_queue pending_queue; 76 static struct ccb_queue work_queue; 77 static struct ioc_enable_lun ioc_enlun = { 78 CAM_BUS_WILDCARD, 79 CAM_TARGET_WILDCARD, 80 CAM_LUN_WILDCARD 81 }; 82 83 /* Local functions */ 84 static void cleanup(void); 85 static int init_ccbs(void); 86 static void request_loop(void); 87 static void handle_read(void); 88 /* static int work_atio(struct ccb_accept_tio *); */ 89 static void queue_io(struct ccb_scsiio *); 90 static int run_queue(struct ccb_accept_tio *); 91 static int work_inot(struct ccb_immed_notify *); 92 static struct ccb_scsiio * 93 get_ctio(void); 94 /* static void free_ccb(union ccb *); */ 95 static cam_status get_sim_flags(u_int16_t *); 96 static void rel_simq(void); 97 static void abort_all_pending(void); 98 static void usage(void); 99 100 int 101 main(int argc, char *argv[]) 102 { 103 int ch, unit; 104 char *file_name, targname[16]; 105 u_int16_t req_flags, sim_flags; 106 off_t user_size; 107 108 /* Initialize */ 109 debug = 0; 110 req_flags = sim_flags = 0; 111 user_size = 0; 112 targ_fd = file_fd = kq_fd = -1; 113 num_ctios = 0; 114 sector_size = SECTOR_SIZE; 115 buf_size = DFLTPHYS; 116 117 /* Prepare resource pools */ 118 TAILQ_INIT(&pending_queue); 119 TAILQ_INIT(&work_queue); 120 121 while ((ch = getopt(argc, argv, "AdSTYb:c:s:W:")) != -1) { 122 switch(ch) { 123 case 'A': 124 req_flags |= SID_Addr16; 125 break; 126 case 'd': 127 debug = 1; 128 break; 129 case 'S': 130 req_flags |= SID_Sync; 131 break; 132 case 'T': 133 req_flags |= SID_CmdQue; 134 break; 135 case 'b': 136 buf_size = atoi(optarg); 137 if (buf_size < 256 || buf_size > MAX_XFER) 138 errx(1, "Unreasonable buf size: %s", optarg); 139 break; 140 case 'c': 141 sector_size = atoi(optarg); 142 if (sector_size < 512 || sector_size > MAX_SECTOR) 143 errx(1, "Unreasonable sector size: %s", optarg); 144 break; 145 case 's': 146 { 147 int last, shift = 0; 148 149 last = strlen(optarg) - 1; 150 if (last > 0) { 151 switch (tolower(optarg[last])) { 152 case 'e': 153 shift += 10; 154 /* FALLTHROUGH */ 155 case 'p': 156 shift += 10; 157 /* FALLTHROUGH */ 158 case 't': 159 shift += 10; 160 /* FALLTHROUGH */ 161 case 'g': 162 shift += 10; 163 /* FALLTHROUGH */ 164 case 'm': 165 shift += 10; 166 /* FALLTHROUGH */ 167 case 'k': 168 shift += 10; 169 optarg[last] = 0; 170 break; 171 } 172 } 173 user_size = strtoll(optarg, (char **)NULL, /*base*/10); 174 user_size <<= shift; 175 if (user_size < 0) 176 errx(1, "Unreasonable volume size: %s", optarg); 177 break; 178 } 179 case 'W': 180 req_flags &= ~(SID_WBus16 | SID_WBus32); 181 switch (atoi(optarg)) { 182 case 8: 183 /* Leave req_flags zeroed */ 184 break; 185 case 16: 186 req_flags |= SID_WBus16; 187 break; 188 case 32: 189 req_flags |= SID_WBus32; 190 break; 191 default: 192 warnx("Width %s not supported", optarg); 193 usage(); 194 /* NOTREACHED */ 195 } 196 break; 197 case 'Y': 198 notaio = 1; 199 break; 200 default: 201 usage(); 202 /* NOTREACHED */ 203 } 204 } 205 argc -= optind; 206 argv += optind; 207 208 if (argc != 2) 209 usage(); 210 211 sscanf(argv[0], "%u:%u:%u", &ioc_enlun.path_id, &ioc_enlun.target_id, 212 &ioc_enlun.lun_id); 213 file_name = argv[1]; 214 215 if (ioc_enlun.path_id == CAM_BUS_WILDCARD || 216 ioc_enlun.target_id == CAM_TARGET_WILDCARD || 217 ioc_enlun.lun_id == CAM_LUN_WILDCARD) { 218 warnx("Incomplete target path specified"); 219 usage(); 220 /* NOTREACHED */ 221 } 222 /* We don't support any vendor-specific commands */ 223 ioc_enlun.grp6_len = 0; 224 ioc_enlun.grp7_len = 0; 225 226 /* Open backing store for IO */ 227 file_fd = open(file_name, O_RDWR); 228 if (file_fd < 0) 229 err(1, "open backing store file"); 230 231 /* Check backing store size or use the size user gave us */ 232 if (user_size == 0) { 233 struct stat st; 234 235 if (fstat(file_fd, &st) < 0) 236 err(1, "fstat file"); 237 #if __FreeBSD_version >= 500000 238 if ((st.st_mode & S_IFCHR) != 0) { 239 /* raw device */ 240 off_t mediasize; 241 if (ioctl(file_fd, DIOCGMEDIASIZE, &mediasize) < 0) 242 err(1, "DIOCGMEDIASIZE"); 243 244 /* XXX get sector size by ioctl()?? */ 245 volume_size = mediasize / sector_size; 246 } else 247 #endif 248 volume_size = st.st_size / sector_size; 249 } else { 250 volume_size = user_size / sector_size; 251 } 252 if (debug) 253 warnx("volume_size: %d bytes x " OFF_FMT " sectors", 254 sector_size, volume_size); 255 256 if (volume_size <= 0) 257 errx(1, "volume must be larger than %d", sector_size); 258 259 if (notaio == 0) { 260 struct aiocb aio, *aiop; 261 262 /* See if we have we have working AIO support */ 263 memset(&aio, 0, sizeof(aio)); 264 aio.aio_buf = malloc(sector_size); 265 if (aio.aio_buf == NULL) 266 err(1, "malloc"); 267 aio.aio_fildes = file_fd; 268 aio.aio_offset = 0; 269 aio.aio_nbytes = sector_size; 270 signal(SIGSYS, SIG_IGN); 271 if (aio_read(&aio) != 0) { 272 printf("AIO support is not available- switchin to" 273 " single-threaded mode.\n"); 274 notaio = 1; 275 } else { 276 if (aio_waitcomplete(&aiop, NULL) != sector_size) 277 err(1, "aio_waitcomplete"); 278 assert(aiop == &aio); 279 signal(SIGSYS, SIG_DFL); 280 } 281 free((void *)aio.aio_buf); 282 if (debug && notaio == 0) 283 warnx("aio support tested ok"); 284 } 285 286 /* Go through all the control devices and find one that isn't busy. */ 287 unit = 0; 288 do { 289 snprintf(targname, sizeof(targname), "/dev/targ%d", unit++); 290 targ_fd = open(targname, O_RDWR); 291 } while (targ_fd < 0 && errno == EBUSY); 292 293 if (targ_fd < 0) 294 err(1, "Tried to open %d devices, none available", unit); 295 296 /* The first three are handled by kevent() later */ 297 signal(SIGHUP, SIG_IGN); 298 signal(SIGINT, SIG_IGN); 299 signal(SIGTERM, SIG_IGN); 300 signal(SIGPROF, SIG_IGN); 301 signal(SIGALRM, SIG_IGN); 302 signal(SIGSTOP, SIG_IGN); 303 signal(SIGTSTP, SIG_IGN); 304 305 /* Register a cleanup handler to run when exiting */ 306 atexit(cleanup); 307 308 /* Enable listening on the specified LUN */ 309 if (ioctl(targ_fd, TARGIOCENABLE, &ioc_enlun) != 0) 310 err(1, "TARGIOCENABLE"); 311 312 /* Enable debugging if requested */ 313 if (debug) { 314 if (ioctl(targ_fd, TARGIOCDEBUG, &debug) != 0) 315 warnx("TARGIOCDEBUG"); 316 } 317 318 /* Set up inquiry data according to what SIM supports */ 319 if (get_sim_flags(&sim_flags) != CAM_REQ_CMP) 320 errx(1, "get_sim_flags"); 321 if (tcmd_init(req_flags, sim_flags) != 0) 322 errx(1, "Initializing tcmd subsystem failed"); 323 324 /* Queue ATIOs and INOTs on descriptor */ 325 if (init_ccbs() != 0) 326 errx(1, "init_ccbs failed"); 327 328 if (debug) 329 warnx("main loop beginning"); 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_immed_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_immed_notify *)malloc(sizeof(*inot)); 388 if (inot == NULL) { 389 warn("malloc INOT"); 390 return (-1); 391 } 392 inot->ccb_h.func_code = XPT_IMMED_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_IMMED_NOTIFY: 501 retval = work_inot(&ccb->cin); 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_IMMED_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 *sense; 651 652 if (debug) { 653 warnx("ATIO with %u bytes sense received", 654 atio->sense_len); 655 } 656 sense = &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_immed_notify *inot) 778 { 779 cam_status status; 780 int sense; 781 782 if (debug) 783 warnx("Working on INOT %p", inot); 784 785 status = inot->ccb_h.status; 786 sense = (status & CAM_AUTOSNS_VALID) != 0; 787 status &= CAM_STATUS_MASK; 788 789 switch (status) { 790 case CAM_SCSI_BUS_RESET: 791 tcmd_ua(CAM_TARGET_WILDCARD, UA_BUS_RESET); 792 abort_all_pending(); 793 break; 794 case CAM_BDR_SENT: 795 tcmd_ua(CAM_TARGET_WILDCARD, UA_BDR); 796 abort_all_pending(); 797 break; 798 case CAM_MESSAGE_RECV: 799 switch (inot->message_args[0]) { 800 case MSG_TASK_COMPLETE: 801 case MSG_INITIATOR_DET_ERR: 802 case MSG_ABORT_TASK_SET: 803 case MSG_MESSAGE_REJECT: 804 case MSG_NOOP: 805 case MSG_PARITY_ERROR: 806 case MSG_TARGET_RESET: 807 case MSG_ABORT_TASK: 808 case MSG_CLEAR_TASK_SET: 809 default: 810 warnx("INOT message %#x", inot->message_args[0]); 811 break; 812 } 813 break; 814 case CAM_REQ_ABORTED: 815 warnx("INOT %p aborted", inot); 816 break; 817 default: 818 warnx("Unhandled INOT status %#x", status); 819 break; 820 } 821 822 /* If there is sense data, use it */ 823 if (sense != 0) { 824 struct scsi_sense_data *sense; 825 826 sense = &inot->sense_data; 827 tcmd_sense(inot->initiator_id, NULL, sense->flags, 828 sense->add_sense_code, sense->add_sense_code_qual); 829 if (debug) 830 warnx("INOT has sense: %#x", sense->flags); 831 } 832 833 /* Requeue on SIM */ 834 TAILQ_REMOVE(&work_queue, &inot->ccb_h, periph_links.tqe); 835 send_ccb((union ccb *)inot, /*priority*/1); 836 837 return (1); 838 } 839 840 void 841 send_ccb(union ccb *ccb, int priority) 842 { 843 if (debug) 844 warnx("sending ccb (%#x)", ccb->ccb_h.func_code); 845 ccb->ccb_h.pinfo.priority = priority; 846 if (XPT_FC_IS_QUEUED(ccb)) { 847 TAILQ_INSERT_TAIL(&pending_queue, &ccb->ccb_h, 848 periph_links.tqe); 849 } 850 if (write(targ_fd, &ccb, sizeof(ccb)) != sizeof(ccb)) { 851 warn("write ccb"); 852 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 853 } 854 } 855 856 /* Return a CTIO/descr/buf combo from the freelist or malloc one */ 857 static struct ccb_scsiio * 858 get_ctio() 859 { 860 struct ccb_scsiio *ctio; 861 struct ctio_descr *c_descr; 862 struct sigevent *se; 863 864 if (num_ctios == MAX_CTIOS) { 865 warnx("at CTIO max"); 866 return (NULL); 867 } 868 869 ctio = (struct ccb_scsiio *)malloc(sizeof(*ctio)); 870 if (ctio == NULL) { 871 warn("malloc CTIO"); 872 return (NULL); 873 } 874 c_descr = (struct ctio_descr *)malloc(sizeof(*c_descr)); 875 if (c_descr == NULL) { 876 free(ctio); 877 warn("malloc ctio_descr"); 878 return (NULL); 879 } 880 c_descr->buf = malloc(buf_size); 881 if (c_descr->buf == NULL) { 882 free(c_descr); 883 free(ctio); 884 warn("malloc backing store"); 885 return (NULL); 886 } 887 num_ctios++; 888 889 /* Initialize CTIO, CTIO descr, and AIO */ 890 ctio->ccb_h.func_code = XPT_CONT_TARGET_IO; 891 ctio->ccb_h.retry_count = 2; 892 ctio->ccb_h.timeout = CAM_TIME_INFINITY; 893 ctio->data_ptr = c_descr->buf; 894 ctio->ccb_h.targ_descr = c_descr; 895 c_descr->aiocb.aio_buf = c_descr->buf; 896 c_descr->aiocb.aio_fildes = file_fd; 897 se = &c_descr->aiocb.aio_sigevent; 898 se->sigev_notify = SIGEV_KEVENT; 899 se->sigev_notify_kqueue = kq_fd; 900 se->sigev_value.sival_ptr = ctio; 901 902 return (ctio); 903 } 904 905 void 906 free_ccb(union ccb *ccb) 907 { 908 switch (ccb->ccb_h.func_code) { 909 case XPT_CONT_TARGET_IO: 910 { 911 struct ctio_descr *c_descr; 912 913 c_descr = (struct ctio_descr *)ccb->ccb_h.targ_descr; 914 free(c_descr->buf); 915 num_ctios--; 916 /* FALLTHROUGH */ 917 } 918 case XPT_ACCEPT_TARGET_IO: 919 free(ccb->ccb_h.targ_descr); 920 /* FALLTHROUGH */ 921 case XPT_IMMED_NOTIFY: 922 default: 923 free(ccb); 924 break; 925 } 926 } 927 928 static cam_status 929 get_sim_flags(u_int16_t *flags) 930 { 931 struct ccb_pathinq cpi; 932 cam_status status; 933 934 /* Find SIM capabilities */ 935 bzero(&cpi, sizeof(cpi)); 936 cpi.ccb_h.func_code = XPT_PATH_INQ; 937 send_ccb((union ccb *)&cpi, /*priority*/1); 938 status = cpi.ccb_h.status & CAM_STATUS_MASK; 939 if (status != CAM_REQ_CMP) { 940 fprintf(stderr, "CPI failed, status %#x\n", status); 941 return (status); 942 } 943 944 /* Can only enable on controllers that support target mode */ 945 if ((cpi.target_sprt & PIT_PROCESSOR) == 0) { 946 fprintf(stderr, "HBA does not support target mode\n"); 947 status = CAM_PATH_INVALID; 948 return (status); 949 } 950 951 *flags = cpi.hba_inquiry; 952 return (status); 953 } 954 955 static void 956 rel_simq() 957 { 958 struct ccb_relsim crs; 959 960 bzero(&crs, sizeof(crs)); 961 crs.ccb_h.func_code = XPT_REL_SIMQ; 962 crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY; 963 crs.openings = 0; 964 crs.release_timeout = 0; 965 crs.qfrozen_cnt = 0; 966 send_ccb((union ccb *)&crs, /*priority*/0); 967 } 968 969 /* Cancel all pending CCBs. */ 970 static void 971 abort_all_pending() 972 { 973 struct ccb_abort cab; 974 struct ccb_hdr *ccb_h; 975 976 if (debug) 977 warnx("abort_all_pending"); 978 979 bzero(&cab, sizeof(cab)); 980 cab.ccb_h.func_code = XPT_ABORT; 981 TAILQ_FOREACH(ccb_h, &pending_queue, periph_links.tqe) { 982 if (debug) 983 warnx("Aborting pending CCB %p\n", ccb_h); 984 cab.abort_ccb = (union ccb *)ccb_h; 985 send_ccb((union ccb *)&cab, /*priority*/1); 986 if (cab.ccb_h.status != CAM_REQ_CMP) { 987 warnx("Unable to abort CCB, status %#x\n", 988 cab.ccb_h.status); 989 } 990 } 991 } 992 993 static void 994 usage() 995 { 996 fprintf(stderr, 997 "Usage: scsi_target [-AdSTY] [-b bufsize] [-c sectorsize]\n" 998 "\t\t[-r numbufs] [-s volsize] [-W 8,16,32]\n" 999 "\t\tbus:target:lun filename\n"); 1000 exit(1); 1001 } 1002