1 /*- 2 * Generic SCSI Target Kernel Mode Driver 3 * 4 * Copyright (c) 2002 Nate Lawson. 5 * Copyright (c) 1998, 1999, 2001, 2002 Justin T. Gibbs. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/conf.h> 38 #include <sys/malloc.h> 39 #include <sys/poll.h> 40 #include <sys/vnode.h> 41 #include <sys/lock.h> 42 #include <sys/mutex.h> 43 #include <sys/devicestat.h> 44 #include <sys/proc.h> 45 /* Includes to support callout */ 46 #include <sys/types.h> 47 #include <sys/systm.h> 48 49 #include <cam/cam.h> 50 #include <cam/cam_ccb.h> 51 #include <cam/cam_periph.h> 52 #include <cam/cam_xpt_periph.h> 53 #include <cam/cam_sim.h> 54 #include <cam/scsi/scsi_targetio.h> 55 56 57 /* Transaction information attached to each CCB sent by the user */ 58 struct targ_cmd_descr { 59 struct cam_periph_map_info mapinfo; 60 TAILQ_ENTRY(targ_cmd_descr) tqe; 61 union ccb *user_ccb; 62 int priority; 63 int func_code; 64 }; 65 66 /* Offset into the private CCB area for storing our descriptor */ 67 #define targ_descr periph_priv.entries[1].ptr 68 69 TAILQ_HEAD(descr_queue, targ_cmd_descr); 70 71 typedef enum { 72 TARG_STATE_RESV = 0x00, /* Invalid state */ 73 TARG_STATE_OPENED = 0x01, /* Device opened, softc initialized */ 74 TARG_STATE_LUN_ENABLED = 0x02 /* Device enabled for a path */ 75 } targ_state; 76 77 /* Per-instance device software context */ 78 struct targ_softc { 79 /* CCBs (CTIOs, ATIOs, INOTs) pending on the controller */ 80 struct ccb_queue pending_ccb_queue; 81 82 /* Command descriptors awaiting CTIO resources from the XPT */ 83 struct descr_queue work_queue; 84 85 /* Command descriptors that have been aborted back to the user. */ 86 struct descr_queue abort_queue; 87 88 /* 89 * Queue of CCBs that have been copied out to userland, but our 90 * userland daemon has not yet seen. 91 */ 92 struct ccb_queue user_ccb_queue; 93 94 struct cam_periph *periph; 95 struct cam_path *path; 96 targ_state state; 97 u_int maxio; 98 struct selinfo read_select; 99 struct devstat device_stats; 100 }; 101 102 static d_open_t targopen; 103 static d_read_t targread; 104 static d_write_t targwrite; 105 static d_ioctl_t targioctl; 106 static d_poll_t targpoll; 107 static d_kqfilter_t targkqfilter; 108 static void targreadfiltdetach(struct knote *kn); 109 static int targreadfilt(struct knote *kn, long hint); 110 static struct filterops targread_filtops = { 111 .f_isfd = 1, 112 .f_detach = targreadfiltdetach, 113 .f_event = targreadfilt, 114 }; 115 116 static struct cdevsw targ_cdevsw = { 117 .d_version = D_VERSION, 118 .d_flags = D_NEEDGIANT, 119 .d_open = targopen, 120 .d_read = targread, 121 .d_write = targwrite, 122 .d_ioctl = targioctl, 123 .d_poll = targpoll, 124 .d_name = "targ", 125 .d_kqfilter = targkqfilter 126 }; 127 128 static cam_status targendislun(struct cam_path *path, int enable, 129 int grp6_len, int grp7_len); 130 static cam_status targenable(struct targ_softc *softc, 131 struct cam_path *path, 132 int grp6_len, int grp7_len); 133 static cam_status targdisable(struct targ_softc *softc); 134 static periph_ctor_t targctor; 135 static periph_dtor_t targdtor; 136 static periph_start_t targstart; 137 static int targusermerge(struct targ_softc *softc, 138 struct targ_cmd_descr *descr, 139 union ccb *ccb); 140 static int targsendccb(struct targ_softc *softc, union ccb *ccb, 141 struct targ_cmd_descr *descr); 142 static void targdone(struct cam_periph *periph, 143 union ccb *done_ccb); 144 static int targreturnccb(struct targ_softc *softc, 145 union ccb *ccb); 146 static union ccb * targgetccb(struct targ_softc *softc, xpt_opcode type, 147 int priority); 148 static void targfreeccb(struct targ_softc *softc, union ccb *ccb); 149 static struct targ_cmd_descr * 150 targgetdescr(struct targ_softc *softc); 151 static periph_init_t targinit; 152 static void targasync(void *callback_arg, u_int32_t code, 153 struct cam_path *path, void *arg); 154 static void abort_all_pending(struct targ_softc *softc); 155 static void notify_user(struct targ_softc *softc); 156 static int targcamstatus(cam_status status); 157 static size_t targccblen(xpt_opcode func_code); 158 159 static struct periph_driver targdriver = 160 { 161 targinit, "targ", 162 TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0 163 }; 164 PERIPHDRIVER_DECLARE(targ, targdriver); 165 166 static MALLOC_DEFINE(M_TARG, "TARG", "TARG data"); 167 168 /* Disable LUN if enabled and teardown softc */ 169 static void 170 targcdevdtor(void *data) 171 { 172 struct targ_softc *softc; 173 struct cam_periph *periph; 174 175 softc = data; 176 if (softc->periph == NULL) { 177 printf("%s: destroying non-enabled target\n", __func__); 178 free(softc, M_TARG); 179 return; 180 } 181 182 /* 183 * Acquire a hold on the periph so that it doesn't go away before 184 * we are ready at the end of the function. 185 */ 186 periph = softc->periph; 187 cam_periph_acquire(periph); 188 cam_periph_lock(periph); 189 (void)targdisable(softc); 190 if (softc->periph != NULL) { 191 cam_periph_invalidate(softc->periph); 192 softc->periph = NULL; 193 } 194 cam_periph_unlock(periph); 195 cam_periph_release(periph); 196 free(softc, M_TARG); 197 } 198 199 /* 200 * Create softc and initialize it. There is no locking here because a 201 * periph doesn't get created until an ioctl is issued to do so, and 202 * that can't happen until this method returns. 203 */ 204 static int 205 targopen(struct cdev *dev, int flags, int fmt, struct thread *td) 206 { 207 struct targ_softc *softc; 208 209 /* Allocate its softc, initialize it */ 210 softc = malloc(sizeof(*softc), M_TARG, 211 M_WAITOK | M_ZERO); 212 softc->state = TARG_STATE_OPENED; 213 softc->periph = NULL; 214 softc->path = NULL; 215 216 TAILQ_INIT(&softc->pending_ccb_queue); 217 TAILQ_INIT(&softc->work_queue); 218 TAILQ_INIT(&softc->abort_queue); 219 TAILQ_INIT(&softc->user_ccb_queue); 220 knlist_init_mtx(&softc->read_select.si_note, NULL); 221 222 devfs_set_cdevpriv(softc, targcdevdtor); 223 return (0); 224 } 225 226 /* Enable/disable LUNs, set debugging level */ 227 static int 228 targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) 229 { 230 struct targ_softc *softc; 231 cam_status status; 232 233 devfs_get_cdevpriv((void **)&softc); 234 235 switch (cmd) { 236 case TARGIOCENABLE: 237 { 238 struct ioc_enable_lun *new_lun; 239 struct cam_path *path; 240 241 new_lun = (struct ioc_enable_lun *)addr; 242 status = xpt_create_path(&path, /*periph*/NULL, 243 new_lun->path_id, 244 new_lun->target_id, 245 new_lun->lun_id); 246 if (status != CAM_REQ_CMP) { 247 printf("Couldn't create path, status %#x\n", status); 248 break; 249 } 250 xpt_path_lock(path); 251 status = targenable(softc, path, new_lun->grp6_len, 252 new_lun->grp7_len); 253 xpt_path_unlock(path); 254 xpt_free_path(path); 255 break; 256 } 257 case TARGIOCDISABLE: 258 if (softc->periph == NULL) { 259 status = CAM_DEV_NOT_THERE; 260 break; 261 } 262 cam_periph_lock(softc->periph); 263 status = targdisable(softc); 264 cam_periph_unlock(softc->periph); 265 break; 266 case TARGIOCDEBUG: 267 { 268 struct ccb_debug cdbg; 269 270 /* If no periph available, disallow debugging changes */ 271 if ((softc->state & TARG_STATE_LUN_ENABLED) == 0) { 272 status = CAM_DEV_NOT_THERE; 273 break; 274 } 275 bzero(&cdbg, sizeof cdbg); 276 if (*((int *)addr) != 0) 277 cdbg.flags = CAM_DEBUG_PERIPH; 278 else 279 cdbg.flags = CAM_DEBUG_NONE; 280 xpt_setup_ccb(&cdbg.ccb_h, softc->path, CAM_PRIORITY_NORMAL); 281 cdbg.ccb_h.func_code = XPT_DEBUG; 282 cdbg.ccb_h.cbfcnp = targdone; 283 xpt_action((union ccb *)&cdbg); 284 status = cdbg.ccb_h.status & CAM_STATUS_MASK; 285 break; 286 } 287 default: 288 status = CAM_PROVIDE_FAIL; 289 break; 290 } 291 292 return (targcamstatus(status)); 293 } 294 295 /* Writes are always ready, reads wait for user_ccb_queue or abort_queue */ 296 static int 297 targpoll(struct cdev *dev, int poll_events, struct thread *td) 298 { 299 struct targ_softc *softc; 300 int revents; 301 302 devfs_get_cdevpriv((void **)&softc); 303 304 /* Poll for write() is always ok. */ 305 revents = poll_events & (POLLOUT | POLLWRNORM); 306 if ((poll_events & (POLLIN | POLLRDNORM)) != 0) { 307 /* Poll for read() depends on user and abort queues. */ 308 cam_periph_lock(softc->periph); 309 if (!TAILQ_EMPTY(&softc->user_ccb_queue) || 310 !TAILQ_EMPTY(&softc->abort_queue)) { 311 revents |= poll_events & (POLLIN | POLLRDNORM); 312 } 313 cam_periph_unlock(softc->periph); 314 /* Only sleep if the user didn't poll for write. */ 315 if (revents == 0) 316 selrecord(td, &softc->read_select); 317 } 318 319 return (revents); 320 } 321 322 static int 323 targkqfilter(struct cdev *dev, struct knote *kn) 324 { 325 struct targ_softc *softc; 326 327 devfs_get_cdevpriv((void **)&softc); 328 kn->kn_hook = (caddr_t)softc; 329 kn->kn_fop = &targread_filtops; 330 knlist_add(&softc->read_select.si_note, kn, 0); 331 return (0); 332 } 333 334 static void 335 targreadfiltdetach(struct knote *kn) 336 { 337 struct targ_softc *softc; 338 339 softc = (struct targ_softc *)kn->kn_hook; 340 knlist_remove(&softc->read_select.si_note, kn, 0); 341 } 342 343 /* Notify the user's kqueue when the user queue or abort queue gets a CCB */ 344 static int 345 targreadfilt(struct knote *kn, long hint) 346 { 347 struct targ_softc *softc; 348 int retval; 349 350 softc = (struct targ_softc *)kn->kn_hook; 351 cam_periph_lock(softc->periph); 352 retval = !TAILQ_EMPTY(&softc->user_ccb_queue) || 353 !TAILQ_EMPTY(&softc->abort_queue); 354 cam_periph_unlock(softc->periph); 355 return (retval); 356 } 357 358 /* Send the HBA the enable/disable message */ 359 static cam_status 360 targendislun(struct cam_path *path, int enable, int grp6_len, int grp7_len) 361 { 362 struct ccb_en_lun en_ccb; 363 cam_status status; 364 365 /* Tell the lun to begin answering selects */ 366 xpt_setup_ccb(&en_ccb.ccb_h, path, CAM_PRIORITY_NORMAL); 367 en_ccb.ccb_h.func_code = XPT_EN_LUN; 368 /* Don't need support for any vendor specific commands */ 369 en_ccb.grp6_len = grp6_len; 370 en_ccb.grp7_len = grp7_len; 371 en_ccb.enable = enable ? 1 : 0; 372 xpt_action((union ccb *)&en_ccb); 373 status = en_ccb.ccb_h.status & CAM_STATUS_MASK; 374 if (status != CAM_REQ_CMP) { 375 xpt_print(path, "%sable lun CCB rejected, status %#x\n", 376 enable ? "en" : "dis", status); 377 } 378 return (status); 379 } 380 381 /* Enable target mode on a LUN, given its path */ 382 static cam_status 383 targenable(struct targ_softc *softc, struct cam_path *path, int grp6_len, 384 int grp7_len) 385 { 386 struct cam_periph *periph; 387 struct ccb_pathinq cpi; 388 cam_status status; 389 390 if ((softc->state & TARG_STATE_LUN_ENABLED) != 0) 391 return (CAM_LUN_ALRDY_ENA); 392 393 /* Make sure SIM supports target mode */ 394 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL); 395 cpi.ccb_h.func_code = XPT_PATH_INQ; 396 xpt_action((union ccb *)&cpi); 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