1 /*- 2 * Generic SCSI Target Kernel Mode Driver 3 * 4 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 5 * 6 * Copyright (c) 2002 Nate Lawson. 7 * Copyright (c) 1998, 1999, 2001, 2002 Justin T. Gibbs. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions, and the following disclaimer, 15 * without modification, immediately at the beginning of the file. 16 * 2. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/conf.h> 40 #include <sys/malloc.h> 41 #include <sys/poll.h> 42 #include <sys/vnode.h> 43 #include <sys/lock.h> 44 #include <sys/mutex.h> 45 #include <sys/devicestat.h> 46 #include <sys/proc.h> 47 /* Includes to support callout */ 48 #include <sys/types.h> 49 #include <sys/systm.h> 50 51 #include <cam/cam.h> 52 #include <cam/cam_ccb.h> 53 #include <cam/cam_periph.h> 54 #include <cam/cam_xpt_periph.h> 55 #include <cam/cam_sim.h> 56 #include <cam/scsi/scsi_targetio.h> 57 58 59 /* Transaction information attached to each CCB sent by the user */ 60 struct targ_cmd_descr { 61 struct cam_periph_map_info mapinfo; 62 TAILQ_ENTRY(targ_cmd_descr) tqe; 63 union ccb *user_ccb; 64 int priority; 65 int func_code; 66 }; 67 68 /* Offset into the private CCB area for storing our descriptor */ 69 #define targ_descr periph_priv.entries[1].ptr 70 71 TAILQ_HEAD(descr_queue, targ_cmd_descr); 72 73 typedef enum { 74 TARG_STATE_RESV = 0x00, /* Invalid state */ 75 TARG_STATE_OPENED = 0x01, /* Device opened, softc initialized */ 76 TARG_STATE_LUN_ENABLED = 0x02 /* Device enabled for a path */ 77 } targ_state; 78 79 /* Per-instance device software context */ 80 struct targ_softc { 81 /* CCBs (CTIOs, ATIOs, INOTs) pending on the controller */ 82 struct ccb_queue pending_ccb_queue; 83 84 /* Command descriptors awaiting CTIO resources from the XPT */ 85 struct descr_queue work_queue; 86 87 /* Command descriptors that have been aborted back to the user. */ 88 struct descr_queue abort_queue; 89 90 /* 91 * Queue of CCBs that have been copied out to userland, but our 92 * userland daemon has not yet seen. 93 */ 94 struct ccb_queue user_ccb_queue; 95 96 struct cam_periph *periph; 97 struct cam_path *path; 98 targ_state state; 99 u_int maxio; 100 struct selinfo read_select; 101 struct devstat device_stats; 102 }; 103 104 static d_open_t targopen; 105 static d_read_t targread; 106 static d_write_t targwrite; 107 static d_ioctl_t targioctl; 108 static d_poll_t targpoll; 109 static d_kqfilter_t targkqfilter; 110 static void targreadfiltdetach(struct knote *kn); 111 static int targreadfilt(struct knote *kn, long hint); 112 static struct filterops targread_filtops = { 113 .f_isfd = 1, 114 .f_detach = targreadfiltdetach, 115 .f_event = targreadfilt, 116 }; 117 118 static struct cdevsw targ_cdevsw = { 119 .d_version = D_VERSION, 120 .d_flags = D_NEEDGIANT, 121 .d_open = targopen, 122 .d_read = targread, 123 .d_write = targwrite, 124 .d_ioctl = targioctl, 125 .d_poll = targpoll, 126 .d_name = "targ", 127 .d_kqfilter = targkqfilter 128 }; 129 130 static cam_status targendislun(struct cam_path *path, int enable, 131 int grp6_len, int grp7_len); 132 static cam_status targenable(struct targ_softc *softc, 133 struct cam_path *path, 134 int grp6_len, int grp7_len); 135 static cam_status targdisable(struct targ_softc *softc); 136 static periph_ctor_t targctor; 137 static periph_dtor_t targdtor; 138 static periph_start_t targstart; 139 static int targusermerge(struct targ_softc *softc, 140 struct targ_cmd_descr *descr, 141 union ccb *ccb); 142 static int targsendccb(struct targ_softc *softc, union ccb *ccb, 143 struct targ_cmd_descr *descr); 144 static void targdone(struct cam_periph *periph, 145 union ccb *done_ccb); 146 static int targreturnccb(struct targ_softc *softc, 147 union ccb *ccb); 148 static union ccb * targgetccb(struct targ_softc *softc, xpt_opcode type, 149 int priority); 150 static void targfreeccb(struct targ_softc *softc, union ccb *ccb); 151 static struct targ_cmd_descr * 152 targgetdescr(struct targ_softc *softc); 153 static periph_init_t targinit; 154 static void targasync(void *callback_arg, u_int32_t code, 155 struct cam_path *path, void *arg); 156 static void abort_all_pending(struct targ_softc *softc); 157 static void notify_user(struct targ_softc *softc); 158 static int targcamstatus(cam_status status); 159 static size_t targccblen(xpt_opcode func_code); 160 161 static struct periph_driver targdriver = 162 { 163 targinit, "targ", 164 TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0 165 }; 166 PERIPHDRIVER_DECLARE(targ, targdriver); 167 168 static MALLOC_DEFINE(M_TARG, "TARG", "TARG data"); 169 170 /* Disable LUN if enabled and teardown softc */ 171 static void 172 targcdevdtor(void *data) 173 { 174 struct targ_softc *softc; 175 struct cam_periph *periph; 176 177 softc = data; 178 if (softc->periph == NULL) { 179 printf("%s: destroying non-enabled target\n", __func__); 180 free(softc, M_TARG); 181 return; 182 } 183 184 /* 185 * Acquire a hold on the periph so that it doesn't go away before 186 * we are ready at the end of the function. 187 */ 188 periph = softc->periph; 189 cam_periph_acquire(periph); 190 cam_periph_lock(periph); 191 (void)targdisable(softc); 192 if (softc->periph != NULL) { 193 cam_periph_invalidate(softc->periph); 194 softc->periph = NULL; 195 } 196 cam_periph_unlock(periph); 197 cam_periph_release(periph); 198 free(softc, M_TARG); 199 } 200 201 /* 202 * Create softc and initialize it. There is no locking here because a 203 * periph doesn't get created until an ioctl is issued to do so, and 204 * that can't happen until this method returns. 205 */ 206 static int 207 targopen(struct cdev *dev, int flags, int fmt, struct thread *td) 208 { 209 struct targ_softc *softc; 210 211 /* Allocate its softc, initialize it */ 212 softc = malloc(sizeof(*softc), M_TARG, 213 M_WAITOK | M_ZERO); 214 softc->state = TARG_STATE_OPENED; 215 softc->periph = NULL; 216 softc->path = NULL; 217 218 TAILQ_INIT(&softc->pending_ccb_queue); 219 TAILQ_INIT(&softc->work_queue); 220 TAILQ_INIT(&softc->abort_queue); 221 TAILQ_INIT(&softc->user_ccb_queue); 222 knlist_init_mtx(&softc->read_select.si_note, NULL); 223 224 devfs_set_cdevpriv(softc, targcdevdtor); 225 return (0); 226 } 227 228 /* Enable/disable LUNs, set debugging level */ 229 static int 230 targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) 231 { 232 struct targ_softc *softc; 233 cam_status status; 234 235 devfs_get_cdevpriv((void **)&softc); 236 237 switch (cmd) { 238 case TARGIOCENABLE: 239 { 240 struct ioc_enable_lun *new_lun; 241 struct cam_path *path; 242 243 new_lun = (struct ioc_enable_lun *)addr; 244 status = xpt_create_path(&path, /*periph*/NULL, 245 new_lun->path_id, 246 new_lun->target_id, 247 new_lun->lun_id); 248 if (status != CAM_REQ_CMP) { 249 printf("Couldn't create path, status %#x\n", status); 250 break; 251 } 252 xpt_path_lock(path); 253 status = targenable(softc, path, new_lun->grp6_len, 254 new_lun->grp7_len); 255 xpt_path_unlock(path); 256 xpt_free_path(path); 257 break; 258 } 259 case TARGIOCDISABLE: 260 if (softc->periph == NULL) { 261 status = CAM_DEV_NOT_THERE; 262 break; 263 } 264 cam_periph_lock(softc->periph); 265 status = targdisable(softc); 266 cam_periph_unlock(softc->periph); 267 break; 268 case TARGIOCDEBUG: 269 { 270 struct ccb_debug cdbg; 271 272 /* If no periph available, disallow debugging changes */ 273 if ((softc->state & TARG_STATE_LUN_ENABLED) == 0) { 274 status = CAM_DEV_NOT_THERE; 275 break; 276 } 277 bzero(&cdbg, sizeof cdbg); 278 if (*((int *)addr) != 0) 279 cdbg.flags = CAM_DEBUG_PERIPH; 280 else 281 cdbg.flags = CAM_DEBUG_NONE; 282 xpt_setup_ccb(&cdbg.ccb_h, softc->path, CAM_PRIORITY_NORMAL); 283 cdbg.ccb_h.func_code = XPT_DEBUG; 284 cdbg.ccb_h.cbfcnp = targdone; 285 xpt_action((union ccb *)&cdbg); 286 status = cdbg.ccb_h.status & CAM_STATUS_MASK; 287 break; 288 } 289 default: 290 status = CAM_PROVIDE_FAIL; 291 break; 292 } 293 294 return (targcamstatus(status)); 295 } 296 297 /* Writes are always ready, reads wait for user_ccb_queue or abort_queue */ 298 static int 299 targpoll(struct cdev *dev, int poll_events, struct thread *td) 300 { 301 struct targ_softc *softc; 302 int revents; 303 304 devfs_get_cdevpriv((void **)&softc); 305 306 /* Poll for write() is always ok. */ 307 revents = poll_events & (POLLOUT | POLLWRNORM); 308 if ((poll_events & (POLLIN | POLLRDNORM)) != 0) { 309 /* Poll for read() depends on user and abort queues. */ 310 cam_periph_lock(softc->periph); 311 if (!TAILQ_EMPTY(&softc->user_ccb_queue) || 312 !TAILQ_EMPTY(&softc->abort_queue)) { 313 revents |= poll_events & (POLLIN | POLLRDNORM); 314 } 315 cam_periph_unlock(softc->periph); 316 /* Only sleep if the user didn't poll for write. */ 317 if (revents == 0) 318 selrecord(td, &softc->read_select); 319 } 320 321 return (revents); 322 } 323 324 static int 325 targkqfilter(struct cdev *dev, struct knote *kn) 326 { 327 struct targ_softc *softc; 328 329 devfs_get_cdevpriv((void **)&softc); 330 kn->kn_hook = (caddr_t)softc; 331 kn->kn_fop = &targread_filtops; 332 knlist_add(&softc->read_select.si_note, kn, 0); 333 return (0); 334 } 335 336 static void 337 targreadfiltdetach(struct knote *kn) 338 { 339 struct targ_softc *softc; 340 341 softc = (struct targ_softc *)kn->kn_hook; 342 knlist_remove(&softc->read_select.si_note, kn, 0); 343 } 344 345 /* Notify the user's kqueue when the user queue or abort queue gets a CCB */ 346 static int 347 targreadfilt(struct knote *kn, long hint) 348 { 349 struct targ_softc *softc; 350 int retval; 351 352 softc = (struct targ_softc *)kn->kn_hook; 353 cam_periph_lock(softc->periph); 354 retval = !TAILQ_EMPTY(&softc->user_ccb_queue) || 355 !TAILQ_EMPTY(&softc->abort_queue); 356 cam_periph_unlock(softc->periph); 357 return (retval); 358 } 359 360 /* Send the HBA the enable/disable message */ 361 static cam_status 362 targendislun(struct cam_path *path, int enable, int grp6_len, int grp7_len) 363 { 364 struct ccb_en_lun en_ccb; 365 cam_status status; 366 367 /* Tell the lun to begin answering selects */ 368 xpt_setup_ccb(&en_ccb.ccb_h, path, CAM_PRIORITY_NORMAL); 369 en_ccb.ccb_h.func_code = XPT_EN_LUN; 370 /* Don't need support for any vendor specific commands */ 371 en_ccb.grp6_len = grp6_len; 372 en_ccb.grp7_len = grp7_len; 373 en_ccb.enable = enable ? 1 : 0; 374 xpt_action((union ccb *)&en_ccb); 375 status = en_ccb.ccb_h.status & CAM_STATUS_MASK; 376 if (status != CAM_REQ_CMP) { 377 xpt_print(path, "%sable lun CCB rejected, status %#x\n", 378 enable ? "en" : "dis", status); 379 } 380 return (status); 381 } 382 383 /* Enable target mode on a LUN, given its path */ 384 static cam_status 385 targenable(struct targ_softc *softc, struct cam_path *path, int grp6_len, 386 int grp7_len) 387 { 388 struct cam_periph *periph; 389 struct ccb_pathinq cpi; 390 cam_status status; 391 392 if ((softc->state & TARG_STATE_LUN_ENABLED) != 0) 393 return (CAM_LUN_ALRDY_ENA); 394 395 /* Make sure SIM supports target mode */ 396 xpt_path_inq(&cpi, path); 397 status = cpi.ccb_h.status & CAM_STATUS_MASK; 398 if (status != CAM_REQ_CMP) { 399 printf("pathinq failed, status %#x\n", status); 400 goto enable_fail; 401 } 402 if ((cpi.target_sprt & PIT_PROCESSOR) == 0) { 403 printf("controller does not support target mode\n"); 404 status = CAM_FUNC_NOTAVAIL; 405 goto enable_fail; 406 } 407 if (cpi.maxio == 0) 408 softc->maxio = DFLTPHYS; /* traditional default */ 409 else if (cpi.maxio > MAXPHYS) 410 softc->maxio = MAXPHYS; /* for safety */ 411 else 412 softc->maxio = cpi.maxio; /* real value */ 413 414 /* Destroy any periph on our path if it is disabled */ 415 periph = cam_periph_find(path, "targ"); 416 if (periph != NULL) { 417 struct targ_softc *del_softc; 418 419 del_softc = (struct targ_softc *)periph->softc; 420 if ((del_softc->state & TARG_STATE_LUN_ENABLED) == 0) { 421 cam_periph_invalidate(del_softc->periph); 422 del_softc->periph = NULL; 423 } else { 424 printf("Requested path still in use by targ%d\n", 425 periph->unit_number); 426 status = CAM_LUN_ALRDY_ENA; 427 goto enable_fail; 428 } 429 } 430 431 /* Create a periph instance attached to this path */ 432 status = cam_periph_alloc(targctor, NULL, targdtor, targstart, 433 "targ", CAM_PERIPH_BIO, path, targasync, 0, softc); 434 if (status != CAM_REQ_CMP) { 435 printf("cam_periph_alloc failed, status %#x\n", status); 436 goto enable_fail; 437 } 438 439 /* Ensure that the periph now exists. */ 440 if (cam_periph_find(path, "targ") == NULL) { 441 panic("targenable: succeeded but no periph?"); 442 /* NOTREACHED */ 443 } 444 445 /* Send the enable lun message */ 446 status = targendislun(path, /*enable*/1, grp6_len, grp7_len); 447 if (status != CAM_REQ_CMP) { 448 printf("enable lun failed, status %#x\n", status); 449 goto enable_fail; 450 } 451 softc->state |= TARG_STATE_LUN_ENABLED; 452 453 enable_fail: 454 return (status); 455 } 456 457 /* Disable this softc's target instance if enabled */ 458 static cam_status 459 targdisable(struct targ_softc *softc) 460 { 461 cam_status status; 462 463 if ((softc->state & TARG_STATE_LUN_ENABLED) == 0) 464 return (CAM_REQ_CMP); 465 466 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targdisable\n")); 467 468 /* Abort any ccbs pending on the controller */ 469 abort_all_pending(softc); 470 471 /* Disable this lun */ 472 status = targendislun(softc->path, /*enable*/0, 473 /*grp6_len*/0, /*grp7_len*/0); 474 if (status == CAM_REQ_CMP) 475 softc->state &= ~TARG_STATE_LUN_ENABLED; 476 else 477 printf("Disable lun failed, status %#x\n", status); 478 479 return (status); 480 } 481 482 /* Initialize a periph (called from cam_periph_alloc) */ 483 static cam_status 484 targctor(struct cam_periph *periph, void *arg) 485 { 486 struct targ_softc *softc; 487 488 /* Store pointer to softc for periph-driven routines */ 489 softc = (struct targ_softc *)arg; 490 periph->softc = softc; 491 softc->periph = periph; 492 softc->path = periph->path; 493 return (CAM_REQ_CMP); 494 } 495 496 static void 497 targdtor(struct cam_periph *periph) 498 { 499 struct targ_softc *softc; 500 struct ccb_hdr *ccb_h; 501 struct targ_cmd_descr *descr; 502 503 softc = (struct targ_softc *)periph->softc; 504 505 /* 506 * targdisable() aborts CCBs back to the user and leaves them 507 * on user_ccb_queue and abort_queue in case the user is still 508 * interested in them. We free them now. 509 */ 510 while ((ccb_h = TAILQ_FIRST(&softc->user_ccb_queue)) != NULL) { 511 TAILQ_REMOVE(&softc->user_ccb_queue, ccb_h, periph_links.tqe); 512 targfreeccb(softc, (union ccb *)ccb_h); 513 } 514 while ((descr = TAILQ_FIRST(&softc->abort_queue)) != NULL) { 515 TAILQ_REMOVE(&softc->abort_queue, descr, tqe); 516 free(descr, M_TARG); 517 } 518 519 softc->periph = NULL; 520 softc->path = NULL; 521 periph->softc = NULL; 522 } 523 524 /* Receive CCBs from user mode proc and send them to the HBA */ 525 static int 526 targwrite(struct cdev *dev, struct uio *uio, int ioflag) 527 { 528 union ccb *user_ccb; 529 struct targ_softc *softc; 530 struct targ_cmd_descr *descr; 531 int write_len, error; 532 int func_code, priority; 533 534 devfs_get_cdevpriv((void **)&softc); 535 write_len = error = 0; 536 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 537 ("write - uio_resid %zd\n", uio->uio_resid)); 538 while (uio->uio_resid >= sizeof(user_ccb) && error == 0) { 539 union ccb *ccb; 540 541 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio); 542 if (error != 0) { 543 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 544 ("write - uiomove failed (%d)\n", error)); 545 break; 546 } 547 priority = fuword32(&user_ccb->ccb_h.pinfo.priority); 548 if (priority == CAM_PRIORITY_NONE) { 549 error = EINVAL; 550 break; 551 } 552 func_code = fuword32(&user_ccb->ccb_h.func_code); 553 switch (func_code) { 554 case XPT_ACCEPT_TARGET_IO: 555 case XPT_IMMED_NOTIFY: 556 case XPT_IMMEDIATE_NOTIFY: 557 cam_periph_lock(softc->periph); 558 ccb = targgetccb(softc, func_code, priority); 559 descr = (struct targ_cmd_descr *)ccb->ccb_h.targ_descr; 560 descr->user_ccb = user_ccb; 561 descr->func_code = func_code; 562 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 563 ("Sent ATIO/INOT (%p)\n", user_ccb)); 564 xpt_action(ccb); 565 TAILQ_INSERT_TAIL(&softc->pending_ccb_queue, 566 &ccb->ccb_h, 567 periph_links.tqe); 568 cam_periph_unlock(softc->periph); 569 break; 570 default: 571 cam_periph_lock(softc->periph); 572 if ((func_code & XPT_FC_QUEUED) != 0) { 573 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 574 ("Sending queued ccb %#x (%p)\n", 575 func_code, user_ccb)); 576 descr = targgetdescr(softc); 577 descr->user_ccb = user_ccb; 578 descr->priority = priority; 579 descr->func_code = func_code; 580 TAILQ_INSERT_TAIL(&softc->work_queue, 581 descr, tqe); 582 xpt_schedule(softc->periph, priority); 583 } else { 584 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 585 ("Sending inline ccb %#x (%p)\n", 586 func_code, user_ccb)); 587 ccb = targgetccb(softc, func_code, priority); 588 descr = (struct targ_cmd_descr *) 589 ccb->ccb_h.targ_descr; 590 descr->user_ccb = user_ccb; 591 descr->priority = priority; 592 descr->func_code = func_code; 593 if (targusermerge(softc, descr, ccb) != EFAULT) 594 targsendccb(softc, ccb, descr); 595 targreturnccb(softc, ccb); 596 } 597 cam_periph_unlock(softc->periph); 598 break; 599 } 600 write_len += sizeof(user_ccb); 601 } 602 603 /* 604 * If we've successfully taken in some amount of 605 * data, return success for that data first. If 606 * an error is persistent, it will be reported 607 * on the next write. 608 */ 609 if (error != 0 && write_len == 0) 610 return (error); 611 if (write_len == 0 && uio->uio_resid != 0) 612 return (ENOSPC); 613 return (0); 614 } 615 616 /* Process requests (descrs) via the periph-supplied CCBs */ 617 static void 618 targstart(struct cam_periph *periph, union ccb *start_ccb) 619 { 620 struct targ_softc *softc; 621 struct targ_cmd_descr *descr, *next_descr; 622 int error; 623 624 softc = (struct targ_softc *)periph->softc; 625 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targstart %p\n", start_ccb)); 626 627 descr = TAILQ_FIRST(&softc->work_queue); 628 if (descr == NULL) { 629 xpt_release_ccb(start_ccb); 630 } else { 631 TAILQ_REMOVE(&softc->work_queue, descr, tqe); 632 next_descr = TAILQ_FIRST(&softc->work_queue); 633 634 /* Initiate a transaction using the descr and supplied CCB */ 635 error = targusermerge(softc, descr, start_ccb); 636 if (error == 0) 637 error = targsendccb(softc, start_ccb, descr); 638 if (error != 0) { 639 xpt_print(periph->path, 640 "targsendccb failed, err %d\n", error); 641 xpt_release_ccb(start_ccb); 642 suword(&descr->user_ccb->ccb_h.status, 643 CAM_REQ_CMP_ERR); 644 TAILQ_INSERT_TAIL(&softc->abort_queue, descr, tqe); 645 notify_user(softc); 646 } 647 648 /* If we have more work to do, stay scheduled */ 649 if (next_descr != NULL) 650 xpt_schedule(periph, next_descr->priority); 651 } 652 } 653 654 static int 655 targusermerge(struct targ_softc *softc, struct targ_cmd_descr *descr, 656 union ccb *ccb) 657 { 658 struct ccb_hdr *u_ccbh, *k_ccbh; 659 size_t ccb_len; 660 int error; 661 662 u_ccbh = &descr->user_ccb->ccb_h; 663 k_ccbh = &ccb->ccb_h; 664 665 /* 666 * There are some fields in the CCB header that need to be 667 * preserved, the rest we get from the user ccb. (See xpt_merge_ccb) 668 */ 669 xpt_setup_ccb(k_ccbh, softc->path, descr->priority); 670 k_ccbh->retry_count = fuword32(&u_ccbh->retry_count); 671 k_ccbh->func_code = descr->func_code; 672 k_ccbh->flags = fuword32(&u_ccbh->flags); 673 k_ccbh->timeout = fuword32(&u_ccbh->timeout); 674 ccb_len = targccblen(k_ccbh->func_code) - sizeof(struct ccb_hdr); 675 error = copyin(u_ccbh + 1, k_ccbh + 1, ccb_len); 676 if (error != 0) { 677 k_ccbh->status = CAM_REQ_CMP_ERR; 678 return (error); 679 } 680 681 /* Translate usermode abort_ccb pointer to its kernel counterpart */ 682 if (k_ccbh->func_code == XPT_ABORT) { 683 struct ccb_abort *cab; 684 struct ccb_hdr *ccb_h; 685 686 cab = (struct ccb_abort *)ccb; 687 TAILQ_FOREACH(ccb_h, &softc->pending_ccb_queue, 688 periph_links.tqe) { 689 struct targ_cmd_descr *ab_descr; 690 691 ab_descr = (struct targ_cmd_descr *)ccb_h->targ_descr; 692 if (ab_descr->user_ccb == cab->abort_ccb) { 693 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 694 ("Changing abort for %p to %p\n", 695 cab->abort_ccb, ccb_h)); 696 cab->abort_ccb = (union ccb *)ccb_h; 697 break; 698 } 699 } 700 /* CCB not found, set appropriate status */ 701 if (ccb_h == NULL) { 702 k_ccbh->status = CAM_PATH_INVALID; 703 error = ESRCH; 704 } 705 } 706 707 return (error); 708 } 709 710 /* Build and send a kernel CCB formed from descr->user_ccb */ 711 static int 712 targsendccb(struct targ_softc *softc, union ccb *ccb, 713 struct targ_cmd_descr *descr) 714 { 715 struct cam_periph_map_info *mapinfo; 716 struct ccb_hdr *ccb_h; 717 int error; 718 719 ccb_h = &ccb->ccb_h; 720 mapinfo = &descr->mapinfo; 721 mapinfo->num_bufs_used = 0; 722 723 /* 724 * There's no way for the user to have a completion 725 * function, so we put our own completion function in here. 726 * We also stash in a reference to our descriptor so targreturnccb() 727 * can find our mapping info. 728 */ 729 ccb_h->cbfcnp = targdone; 730 ccb_h->targ_descr = descr; 731 732 if ((ccb_h->func_code == XPT_CONT_TARGET_IO) || 733 (ccb_h->func_code == XPT_DEV_MATCH)) { 734 735 error = cam_periph_mapmem(ccb, mapinfo, softc->maxio); 736 737 /* 738 * cam_periph_mapmem returned an error, we can't continue. 739 * Return the error to the user. 740 */ 741 if (error) { 742 ccb_h->status = CAM_REQ_CMP_ERR; 743 mapinfo->num_bufs_used = 0; 744 return (error); 745 } 746 } 747 748 /* 749 * Once queued on the pending CCB list, this CCB will be protected 750 * by our error recovery handler. 751 */ 752 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("sendccb %p\n", ccb)); 753 if (XPT_FC_IS_QUEUED(ccb)) { 754 TAILQ_INSERT_TAIL(&softc->pending_ccb_queue, ccb_h, 755 periph_links.tqe); 756 } 757 xpt_action(ccb); 758 759 return (0); 760 } 761 762 /* Completion routine for CCBs (called at splsoftcam) */ 763 static void 764 targdone(struct cam_periph *periph, union ccb *done_ccb) 765 { 766 struct targ_softc *softc; 767 cam_status status; 768 769 CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH, ("targdone %p\n", done_ccb)); 770 softc = (struct targ_softc *)periph->softc; 771 TAILQ_REMOVE(&softc->pending_ccb_queue, &done_ccb->ccb_h, 772 periph_links.tqe); 773 status = done_ccb->ccb_h.status & CAM_STATUS_MASK; 774 775 /* If we're no longer enabled, throw away CCB */ 776 if ((softc->state & TARG_STATE_LUN_ENABLED) == 0) { 777 targfreeccb(softc, done_ccb); 778 return; 779 } 780 /* abort_all_pending() waits for pending queue to be empty */ 781 if (TAILQ_EMPTY(&softc->pending_ccb_queue)) 782 wakeup(&softc->pending_ccb_queue); 783 784 switch (done_ccb->ccb_h.func_code) { 785 /* All FC_*_QUEUED CCBs go back to userland */ 786 case XPT_IMMED_NOTIFY: 787 case XPT_IMMEDIATE_NOTIFY: 788 case XPT_ACCEPT_TARGET_IO: 789 case XPT_CONT_TARGET_IO: 790 TAILQ_INSERT_TAIL(&softc->user_ccb_queue, &done_ccb->ccb_h, 791 periph_links.tqe); 792 cam_periph_unlock(softc->periph); 793 notify_user(softc); 794 cam_periph_lock(softc->periph); 795 break; 796 default: 797 panic("targdone: impossible xpt opcode %#x", 798 done_ccb->ccb_h.func_code); 799 /* NOTREACHED */ 800 } 801 } 802 803 /* Return CCBs to the user from the user queue and abort queue */ 804 static int 805 targread(struct cdev *dev, struct uio *uio, int ioflag) 806 { 807 struct descr_queue *abort_queue; 808 struct targ_cmd_descr *user_descr; 809 struct targ_softc *softc; 810 struct ccb_queue *user_queue; 811 struct ccb_hdr *ccb_h; 812 union ccb *user_ccb; 813 int read_len, error; 814 815 error = 0; 816 read_len = 0; 817 devfs_get_cdevpriv((void **)&softc); 818 user_queue = &softc->user_ccb_queue; 819 abort_queue = &softc->abort_queue; 820 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targread\n")); 821 822 /* If no data is available, wait or return immediately */ 823 cam_periph_lock(softc->periph); 824 ccb_h = TAILQ_FIRST(user_queue); 825 user_descr = TAILQ_FIRST(abort_queue); 826 while (ccb_h == NULL && user_descr == NULL) { 827 if ((ioflag & IO_NDELAY) == 0) { 828 error = cam_periph_sleep(softc->periph, user_queue, 829 PRIBIO | PCATCH, "targrd", 0); 830 ccb_h = TAILQ_FIRST(user_queue); 831 user_descr = TAILQ_FIRST(abort_queue); 832 if (error != 0) { 833 if (error == ERESTART) { 834 continue; 835 } else { 836 goto read_fail; 837 } 838 } 839 } else { 840 cam_periph_unlock(softc->periph); 841 return (EAGAIN); 842 } 843 } 844 845 /* Data is available so fill the user's buffer */ 846 while (ccb_h != NULL) { 847 struct targ_cmd_descr *descr; 848 849 if (uio->uio_resid < sizeof(user_ccb)) 850 break; 851 TAILQ_REMOVE(user_queue, ccb_h, periph_links.tqe); 852 descr = (struct targ_cmd_descr *)ccb_h->targ_descr; 853 user_ccb = descr->user_ccb; 854 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 855 ("targread ccb %p (%p)\n", ccb_h, user_ccb)); 856 error = targreturnccb(softc, (union ccb *)ccb_h); 857 if (error != 0) 858 goto read_fail; 859 cam_periph_unlock(softc->periph); 860 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio); 861 cam_periph_lock(softc->periph); 862 if (error != 0) 863 goto read_fail; 864 read_len += sizeof(user_ccb); 865 866 ccb_h = TAILQ_FIRST(user_queue); 867 } 868 869 /* Flush out any aborted descriptors */ 870 while (user_descr != NULL) { 871 if (uio->uio_resid < sizeof(user_ccb)) 872 break; 873 TAILQ_REMOVE(abort_queue, user_descr, tqe); 874 user_ccb = user_descr->user_ccb; 875 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 876 ("targread aborted descr %p (%p)\n", 877 user_descr, user_ccb)); 878 suword(&user_ccb->ccb_h.status, CAM_REQ_ABORTED); 879 cam_periph_unlock(softc->periph); 880 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio); 881 cam_periph_lock(softc->periph); 882 if (error != 0) 883 goto read_fail; 884 read_len += sizeof(user_ccb); 885 886 user_descr = TAILQ_FIRST(abort_queue); 887 } 888 889 /* 890 * If we've successfully read some amount of data, don't report an 891 * error. If the error is persistent, it will be reported on the 892 * next read(). 893 */ 894 if (read_len == 0 && uio->uio_resid != 0) 895 error = ENOSPC; 896 897 read_fail: 898 cam_periph_unlock(softc->periph); 899 return (error); 900 } 901 902 /* Copy completed ccb back to the user */ 903 static int 904 targreturnccb(struct targ_softc *softc, union ccb *ccb) 905 { 906 struct targ_cmd_descr *descr; 907 struct ccb_hdr *u_ccbh; 908 size_t ccb_len; 909 int error; 910 911 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targreturnccb %p\n", ccb)); 912 descr = (struct targ_cmd_descr *)ccb->ccb_h.targ_descr; 913 u_ccbh = &descr->user_ccb->ccb_h; 914 915 /* Copy out the central portion of the ccb_hdr */ 916 copyout(&ccb->ccb_h.retry_count, &u_ccbh->retry_count, 917 offsetof(struct ccb_hdr, periph_priv) - 918 offsetof(struct ccb_hdr, retry_count)); 919 920 /* Copy out the rest of the ccb (after the ccb_hdr) */ 921 ccb_len = targccblen(ccb->ccb_h.func_code) - sizeof(struct ccb_hdr); 922 if (descr->mapinfo.num_bufs_used != 0) 923 cam_periph_unmapmem(ccb, &descr->mapinfo); 924 error = copyout(&ccb->ccb_h + 1, u_ccbh + 1, ccb_len); 925 if (error != 0) { 926 xpt_print(softc->path, 927 "targreturnccb - CCB copyout failed (%d)\n", error); 928 } 929 /* Free CCB or send back to devq. */ 930 targfreeccb(softc, ccb); 931 932 return (error); 933 } 934 935 static union ccb * 936 targgetccb(struct targ_softc *softc, xpt_opcode type, int priority) 937 { 938 union ccb *ccb; 939 int ccb_len; 940 941 ccb_len = targccblen(type); 942 ccb = malloc(ccb_len, M_TARG, M_NOWAIT); 943 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("getccb %p\n", ccb)); 944 if (ccb == NULL) { 945 return (ccb); 946 } 947 xpt_setup_ccb(&ccb->ccb_h, softc->path, priority); 948 ccb->ccb_h.func_code = type; 949 ccb->ccb_h.cbfcnp = targdone; 950 ccb->ccb_h.targ_descr = targgetdescr(softc); 951 if (ccb->ccb_h.targ_descr == NULL) { 952 free (ccb, M_TARG); 953 ccb = NULL; 954 } 955 return (ccb); 956 } 957 958 static void 959 targfreeccb(struct targ_softc *softc, union ccb *ccb) 960 { 961 CAM_DEBUG_PRINT(CAM_DEBUG_PERIPH, ("targfreeccb descr %p and\n", 962 ccb->ccb_h.targ_descr)); 963 free(ccb->ccb_h.targ_descr, M_TARG); 964 965 switch (ccb->ccb_h.func_code) { 966 case XPT_ACCEPT_TARGET_IO: 967 case XPT_IMMED_NOTIFY: 968 case XPT_IMMEDIATE_NOTIFY: 969 CAM_DEBUG_PRINT(CAM_DEBUG_PERIPH, ("freeing ccb %p\n", ccb)); 970 free(ccb, M_TARG); 971 break; 972 default: 973 /* Send back CCB if we got it from the periph */ 974 if (XPT_FC_IS_QUEUED(ccb)) { 975 CAM_DEBUG_PRINT(CAM_DEBUG_PERIPH, 976 ("returning queued ccb %p\n", ccb)); 977 xpt_release_ccb(ccb); 978 } else { 979 CAM_DEBUG_PRINT(CAM_DEBUG_PERIPH, 980 ("freeing ccb %p\n", ccb)); 981 free(ccb, M_TARG); 982 } 983 break; 984 } 985 } 986 987 static struct targ_cmd_descr * 988 targgetdescr(struct targ_softc *softc) 989 { 990 struct targ_cmd_descr *descr; 991 992 descr = malloc(sizeof(*descr), M_TARG, 993 M_NOWAIT); 994 if (descr) { 995 descr->mapinfo.num_bufs_used = 0; 996 } 997 return (descr); 998 } 999 1000 static void 1001 targinit(void) 1002 { 1003 struct cdev *dev; 1004 1005 /* Add symbolic link to targ0 for compatibility. */ 1006 dev = make_dev(&targ_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "targ"); 1007 make_dev_alias(dev, "targ0"); 1008 } 1009 1010 static void 1011 targasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) 1012 { 1013 /* All events are handled in usermode by INOTs */ 1014 panic("targasync() called, should be an INOT instead"); 1015 } 1016 1017 /* Cancel all pending requests and CCBs awaiting work. */ 1018 static void 1019 abort_all_pending(struct targ_softc *softc) 1020 { 1021 struct targ_cmd_descr *descr; 1022 struct ccb_abort cab; 1023 struct ccb_hdr *ccb_h; 1024 1025 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("abort_all_pending\n")); 1026 1027 /* First abort the descriptors awaiting resources */ 1028 while ((descr = TAILQ_FIRST(&softc->work_queue)) != NULL) { 1029 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 1030 ("Aborting descr from workq %p\n", descr)); 1031 TAILQ_REMOVE(&softc->work_queue, descr, tqe); 1032 TAILQ_INSERT_TAIL(&softc->abort_queue, descr, tqe); 1033 } 1034 1035 /* 1036 * Then abort all pending CCBs. 1037 * targdone() will return the aborted CCB via user_ccb_queue 1038 */ 1039 xpt_setup_ccb(&cab.ccb_h, softc->path, CAM_PRIORITY_NORMAL); 1040 cab.ccb_h.func_code = XPT_ABORT; 1041 cab.ccb_h.status = CAM_REQ_CMP_ERR; 1042 TAILQ_FOREACH(ccb_h, &softc->pending_ccb_queue, periph_links.tqe) { 1043 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, 1044 ("Aborting pending CCB %p\n", ccb_h)); 1045 cab.abort_ccb = (union ccb *)ccb_h; 1046 xpt_action((union ccb *)&cab); 1047 if (cab.ccb_h.status != CAM_REQ_CMP) { 1048 xpt_print(cab.ccb_h.path, 1049 "Unable to abort CCB, status %#x\n", 1050 cab.ccb_h.status); 1051 } 1052 } 1053 1054 /* If we aborted at least one pending CCB ok, wait for it. */ 1055 if (cab.ccb_h.status == CAM_REQ_CMP) { 1056 cam_periph_sleep(softc->periph, &softc->pending_ccb_queue, 1057 PRIBIO | PCATCH, "tgabrt", 0); 1058 } 1059 1060 /* If we aborted anything from the work queue, wakeup user. */ 1061 if (!TAILQ_EMPTY(&softc->user_ccb_queue) 1062 || !TAILQ_EMPTY(&softc->abort_queue)) { 1063 cam_periph_unlock(softc->periph); 1064 notify_user(softc); 1065 cam_periph_lock(softc->periph); 1066 } 1067 } 1068 1069 /* Notify the user that data is ready */ 1070 static void 1071 notify_user(struct targ_softc *softc) 1072 { 1073 /* 1074 * Notify users sleeping via poll(), kqueue(), and 1075 * blocking read(). 1076 */ 1077 selwakeuppri(&softc->read_select, PRIBIO); 1078 KNOTE_UNLOCKED(&softc->read_select.si_note, 0); 1079 wakeup(&softc->user_ccb_queue); 1080 } 1081 1082 /* Convert CAM status to errno values */ 1083 static int 1084 targcamstatus(cam_status status) 1085 { 1086 switch (status & CAM_STATUS_MASK) { 1087 case CAM_REQ_CMP: /* CCB request completed without error */ 1088 return (0); 1089 case CAM_REQ_INPROG: /* CCB request is in progress */ 1090 return (EINPROGRESS); 1091 case CAM_REQ_CMP_ERR: /* CCB request completed with an error */ 1092 return (EIO); 1093 case CAM_PROVIDE_FAIL: /* Unable to provide requested capability */ 1094 return (ENOTTY); 1095 case CAM_FUNC_NOTAVAIL: /* The requested function is not available */ 1096 return (ENOTSUP); 1097 case CAM_LUN_ALRDY_ENA: /* LUN is already enabled for target mode */ 1098 return (EADDRINUSE); 1099 case CAM_PATH_INVALID: /* Supplied Path ID is invalid */ 1100 case CAM_DEV_NOT_THERE: /* SCSI Device Not Installed/there */ 1101 return (ENOENT); 1102 case CAM_REQ_ABORTED: /* CCB request aborted by the host */ 1103 return (ECANCELED); 1104 case CAM_CMD_TIMEOUT: /* Command timeout */ 1105 return (ETIMEDOUT); 1106 case CAM_REQUEUE_REQ: /* Requeue to preserve transaction ordering */ 1107 return (EAGAIN); 1108 case CAM_REQ_INVALID: /* CCB request was invalid */ 1109 return (EINVAL); 1110 case CAM_RESRC_UNAVAIL: /* Resource Unavailable */ 1111 return (ENOMEM); 1112 case CAM_BUSY: /* CAM subsystem is busy */ 1113 case CAM_UA_ABORT: /* Unable to abort CCB request */ 1114 return (EBUSY); 1115 default: 1116 return (ENXIO); 1117 } 1118 } 1119 1120 static size_t 1121 targccblen(xpt_opcode func_code) 1122 { 1123 int len; 1124 1125 /* Codes we expect to see as a target */ 1126 switch (func_code) { 1127 case XPT_CONT_TARGET_IO: 1128 case XPT_SCSI_IO: 1129 len = sizeof(struct ccb_scsiio); 1130 break; 1131 case XPT_ACCEPT_TARGET_IO: 1132 len = sizeof(struct ccb_accept_tio); 1133 break; 1134 case XPT_IMMED_NOTIFY: 1135 len = sizeof(struct ccb_immed_notify); 1136 break; 1137 case XPT_IMMEDIATE_NOTIFY: 1138 len = sizeof(struct ccb_immediate_notify); 1139 break; 1140 case XPT_REL_SIMQ: 1141 len = sizeof(struct ccb_relsim); 1142 break; 1143 case XPT_PATH_INQ: 1144 len = sizeof(struct ccb_pathinq); 1145 break; 1146 case XPT_DEBUG: 1147 len = sizeof(struct ccb_debug); 1148 break; 1149 case XPT_ABORT: 1150 len = sizeof(struct ccb_abort); 1151 break; 1152 case XPT_EN_LUN: 1153 len = sizeof(struct ccb_en_lun); 1154 break; 1155 default: 1156 len = sizeof(union ccb); 1157 break; 1158 } 1159 1160 return (len); 1161 } 1162