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