1 /* 2 * Implementation of a simple Target Mode SCSI Proccessor Target driver for CAM. 3 * 4 * Copyright (c) 1998 Justin T. Gibbs. 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 * $Id: scsi_target.c,v 1.5 1998/12/15 08:15:15 gibbs Exp $ 29 */ 30 #include <stddef.h> /* For offsetof */ 31 32 #include <sys/param.h> 33 #include <sys/queue.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/types.h> 37 #include <sys/buf.h> 38 #include <sys/conf.h> 39 #include <sys/devicestat.h> 40 #include <sys/malloc.h> 41 #include <sys/poll.h> 42 #include <sys/select.h> /* For struct selinfo. */ 43 #include <sys/uio.h> 44 45 #include <cam/cam.h> 46 #include <cam/cam_ccb.h> 47 #include <cam/cam_extend.h> 48 #include <cam/cam_periph.h> 49 #include <cam/cam_queue.h> 50 #include <cam/cam_xpt_periph.h> 51 #include <cam/cam_debug.h> 52 53 #include <cam/scsi/scsi_all.h> 54 #include <cam/scsi/scsi_pt.h> 55 #include <cam/scsi/scsi_targetio.h> 56 #include <cam/scsi/scsi_message.h> 57 58 typedef enum { 59 TARG_STATE_NORMAL, 60 TARG_STATE_EXCEPTION, 61 TARG_STATE_TEARDOWN 62 } targ_state; 63 64 typedef enum { 65 TARG_FLAG_NONE = 0x00, 66 TARG_FLAG_SEND_EOF = 0x01, 67 TARG_FLAG_RECEIVE_EOF = 0x02, 68 TARG_FLAG_LUN_ENABLED = 0x04 69 } targ_flags; 70 71 typedef enum { 72 TARG_CCB_WORKQ, 73 TARG_CCB_WAITING 74 } targ_ccb_types; 75 76 #define MAX_ACCEPT 16 77 #define MAX_IMMEDIATE 16 78 #define MAX_BUF_SIZE 256 /* Max inquiry/sense/mode page transfer */ 79 #define MAX_INITIATORS 16 /* XXX More for Fibre-Channel */ 80 81 #define MIN(a, b) ((a > b) ? b : a) 82 83 /* Offsets into our private CCB area for storing accept information */ 84 #define ccb_type ppriv_field0 85 #define ccb_descr ppriv_ptr1 86 87 /* We stick a pointer to the originating accept TIO in each continue I/O CCB */ 88 #define ccb_atio ppriv_ptr1 89 90 TAILQ_HEAD(ccb_queue, ccb_hdr); 91 92 struct targ_softc { 93 struct ccb_queue pending_queue; 94 struct ccb_queue work_queue; 95 struct ccb_queue snd_ccb_queue; 96 struct ccb_queue rcv_ccb_queue; 97 struct ccb_queue unknown_atio_queue; 98 struct buf_queue_head snd_buf_queue; 99 struct buf_queue_head rcv_buf_queue; 100 struct devstat device_stats; 101 struct selinfo snd_select; 102 struct selinfo rcv_select; 103 targ_state state; 104 targ_flags flags; 105 targ_exception exceptions; 106 u_int init_level; 107 u_int inq_data_len; 108 struct scsi_inquiry_data *inq_data; 109 struct ccb_accept_tio *accept_tio_list; 110 struct ccb_hdr_slist immed_notify_slist; 111 struct initiator_state istate[MAX_INITIATORS]; 112 }; 113 114 struct targ_cmd_desc { 115 struct ccb_accept_tio* atio_link; 116 u_int data_resid; /* How much left to transfer */ 117 u_int data_increment;/* Amount to send before next disconnect */ 118 void* data; /* The data. Can be from backing_store or not */ 119 void* backing_store;/* Backing store allocated for this descriptor*/ 120 struct buf *bp; /* Buffer for this transfer */ 121 u_int max_size; /* Size of backing_store */ 122 u_int32_t timeout; 123 u_int8_t status; /* Status to return to initiator */ 124 }; 125 126 static d_open_t targopen; 127 static d_close_t targclose; 128 static d_read_t targread; 129 static d_write_t targwrite; 130 static d_ioctl_t targioctl; 131 static d_poll_t targpoll; 132 static d_strategy_t targstrategy; 133 134 #define TARG_CDEV_MAJOR 65 135 static struct cdevsw targ_cdevsw = { 136 /*d_open*/ targopen, 137 /*d_close*/ targclose, 138 /*d_read*/ targread, 139 /*d_write*/ targwrite, 140 /*d_ioctl*/ targioctl, 141 /*d_stop*/ nostop, 142 /*d_reset*/ noreset, 143 /*d_devtotty*/ nodevtotty, 144 /*d_poll*/ targpoll, 145 /*d_mmap*/ nommap, 146 /*d_strategy*/ targstrategy, 147 /*d_name*/ "targ", 148 /*d_spare*/ NULL, 149 /*d_maj*/ -1, 150 /*d_dump*/ nodump, 151 /*d_psize*/ nopsize, 152 /*d_flags*/ 0, 153 /*d_maxio*/ 0, 154 /*b_maj*/ -1 155 }; 156 157 static int targsendccb(struct cam_periph *periph, union ccb *ccb, 158 union ccb *inccb); 159 static periph_init_t targinit; 160 static void targasync(void *callback_arg, u_int32_t code, 161 struct cam_path *path, void *arg); 162 static cam_status targenlun(struct cam_periph *periph); 163 static cam_status targdislun(struct cam_periph *periph); 164 static periph_ctor_t targctor; 165 static periph_dtor_t targdtor; 166 static void targrunqueue(struct cam_periph *periph, 167 struct targ_softc *softc); 168 static periph_start_t targstart; 169 static void targdone(struct cam_periph *periph, 170 union ccb *done_ccb); 171 static void targfireexception(struct cam_periph *periph, 172 struct targ_softc *softc); 173 static int targerror(union ccb *ccb, u_int32_t cam_flags, 174 u_int32_t sense_flags); 175 static struct targ_cmd_desc* allocdescr(void); 176 static void freedescr(struct targ_cmd_desc *buf); 177 static void fill_sense(struct scsi_sense_data *sense, 178 u_int error_code, u_int sense_key, 179 u_int asc, u_int ascq); 180 181 static struct periph_driver targdriver = 182 { 183 targinit, "targ", 184 TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0 185 }; 186 187 DATA_SET(periphdriver_set, targdriver); 188 189 static struct extend_array *targperiphs; 190 191 static void 192 targinit(void) 193 { 194 cam_status status; 195 struct cam_path *path; 196 197 /* 198 * Create our extend array for storing the devices we attach to. 199 */ 200 targperiphs = cam_extend_new(); 201 if (targperiphs == NULL) { 202 printf("targ: Failed to alloc extend array!\n"); 203 return; 204 } 205 206 /* 207 * Install a global async callback. This callback will 208 * receive async callbacks like "new path registered". 209 */ 210 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID, 211 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); 212 213 if (status == CAM_REQ_CMP) { 214 struct ccb_setasync csa; 215 216 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5); 217 csa.ccb_h.func_code = XPT_SASYNC_CB; 218 csa.event_enable = AC_PATH_REGISTERED; 219 csa.callback = targasync; 220 csa.callback_arg = NULL; 221 xpt_action((union ccb *)&csa); 222 status = csa.ccb_h.status; 223 xpt_free_path(path); 224 } 225 226 if (status != CAM_REQ_CMP) { 227 printf("targ: Failed to attach master async callback " 228 "due to status 0x%x!\n", status); 229 } else { 230 /* If we were successfull, register our devsw */ 231 dev_t dev; 232 233 dev = makedev(TARG_CDEV_MAJOR, 0); 234 cdevsw_add(&dev,&targ_cdevsw, NULL); 235 } 236 } 237 238 static void 239 targasync(void *callback_arg, u_int32_t code, 240 struct cam_path *path, void *arg) 241 { 242 struct cam_periph *periph; 243 244 periph = (struct cam_periph *)callback_arg; 245 switch (code) { 246 case AC_PATH_REGISTERED: 247 { 248 struct ccb_pathinq *cpi; 249 struct cam_path *new_path; 250 cam_status status; 251 252 cpi = (struct ccb_pathinq *)arg; 253 254 /* Only attach to controllers that support target mode */ 255 if ((cpi->target_sprt & PIT_PROCESSOR) == 0) 256 break; 257 258 /* 259 * Allocate a peripheral instance for 260 * this target instance. 261 */ 262 status = xpt_create_path(&new_path, NULL, 263 xpt_path_path_id(path), 264 cpi->initiator_id, /*lun*/0); 265 if (status != CAM_REQ_CMP) { 266 printf("targasync: Unable to create path " 267 "due to status 0x%x\n", status); 268 break; 269 } 270 status = cam_periph_alloc(targctor, NULL, targdtor, targstart, 271 "targ", CAM_PERIPH_BIO, 272 new_path, targasync, 273 AC_PATH_REGISTERED, 274 cpi); 275 xpt_free_path(new_path); 276 if (status != CAM_REQ_CMP 277 && status != CAM_REQ_INPROG) 278 printf("targasync: Unable to attach to new device " 279 "due to status 0x%x\n", status); 280 break; 281 } 282 case AC_PATH_DEREGISTERED: 283 { 284 /* XXX Implement */ 285 break; 286 } 287 case AC_BUS_RESET: 288 { 289 /* Flush transaction queue */ 290 } 291 default: 292 break; 293 } 294 } 295 296 /* Attempt to enable our lun */ 297 static cam_status 298 targenlun(struct cam_periph *periph) 299 { 300 union ccb immed_ccb; 301 struct targ_softc *softc; 302 cam_status status; 303 int i; 304 305 softc = (struct targ_softc *)periph->softc; 306 307 if ((softc->flags & TARG_FLAG_LUN_ENABLED) != 0) 308 return (CAM_REQ_CMP); 309 310 xpt_setup_ccb(&immed_ccb.ccb_h, periph->path, /*priority*/1); 311 immed_ccb.ccb_h.func_code = XPT_EN_LUN; 312 313 /* Don't need support for any vendor specific commands */ 314 immed_ccb.cel.grp6_len = 0; 315 immed_ccb.cel.grp7_len = 0; 316 immed_ccb.cel.enable = 1; 317 xpt_action(&immed_ccb); 318 status = immed_ccb.ccb_h.status; 319 if (status != CAM_REQ_CMP) { 320 xpt_print_path(periph->path); 321 printf("targenlun - Enable Lun Rejected for status 0x%x\n", 322 status); 323 return (status); 324 } 325 326 softc->flags |= TARG_FLAG_LUN_ENABLED; 327 328 /* 329 * Build up a buffer of accept target I/O 330 * operations for incoming selections. 331 */ 332 for (i = 0; i < MAX_ACCEPT; i++) { 333 struct ccb_accept_tio *atio; 334 335 atio = (struct ccb_accept_tio*)malloc(sizeof(*atio), M_DEVBUF, 336 M_NOWAIT); 337 if (atio == NULL) { 338 status = CAM_RESRC_UNAVAIL; 339 break; 340 } 341 342 atio->ccb_h.ccb_descr = allocdescr(); 343 344 if (atio->ccb_h.ccb_descr == NULL) { 345 free(atio, M_DEVBUF); 346 status = CAM_RESRC_UNAVAIL; 347 break; 348 } 349 350 xpt_setup_ccb(&atio->ccb_h, periph->path, /*priority*/1); 351 atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; 352 atio->ccb_h.cbfcnp = targdone; 353 xpt_action((union ccb *)atio); 354 status = atio->ccb_h.status; 355 if (status != CAM_REQ_INPROG) { 356 freedescr(atio->ccb_h.ccb_descr); 357 free(atio, M_DEVBUF); 358 break; 359 } 360 ((struct targ_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link = 361 softc->accept_tio_list; 362 softc->accept_tio_list = atio; 363 } 364 365 if (i == 0) { 366 xpt_print_path(periph->path); 367 printf("targenlun - Could not allocate accept tio CCBs: " 368 "status = 0x%x\n", status); 369 targdislun(periph); 370 return (CAM_REQ_CMP_ERR); 371 } 372 373 /* 374 * Build up a buffer of immediate notify CCBs 375 * so the SIM can tell us of asynchronous target mode events. 376 */ 377 for (i = 0; i < MAX_ACCEPT; i++) { 378 struct ccb_immed_notify *inot; 379 380 inot = (struct ccb_immed_notify*)malloc(sizeof(*inot), M_DEVBUF, 381 M_NOWAIT); 382 383 if (inot == NULL) { 384 status = CAM_RESRC_UNAVAIL; 385 break; 386 } 387 388 xpt_setup_ccb(&inot->ccb_h, periph->path, /*priority*/1); 389 inot->ccb_h.func_code = XPT_IMMED_NOTIFY; 390 inot->ccb_h.cbfcnp = targdone; 391 xpt_action((union ccb *)inot); 392 status = inot->ccb_h.status; 393 if (status != CAM_REQ_INPROG) { 394 free(inot, M_DEVBUF); 395 break; 396 } 397 SLIST_INSERT_HEAD(&softc->immed_notify_slist, &inot->ccb_h, 398 periph_links.sle); 399 } 400 401 if (i == 0) { 402 xpt_print_path(periph->path); 403 printf("targenlun - Could not allocate immediate notify CCBs: " 404 "status = 0x%x\n", status); 405 targdislun(periph); 406 return (CAM_REQ_CMP_ERR); 407 } 408 409 return (CAM_REQ_CMP); 410 } 411 412 static cam_status 413 targdislun(struct cam_periph *periph) 414 { 415 union ccb ccb; 416 struct targ_softc *softc; 417 struct ccb_accept_tio* atio; 418 struct ccb_hdr *ccb_h; 419 420 softc = (struct targ_softc *)periph->softc; 421 if ((softc->flags & TARG_FLAG_LUN_ENABLED) == 0) 422 return CAM_REQ_CMP; 423 424 /* XXX Block for Continue I/O completion */ 425 426 /* Kill off all ACCECPT and IMMEDIATE CCBs */ 427 while ((atio = softc->accept_tio_list) != NULL) { 428 429 softc->accept_tio_list = 430 ((struct targ_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link; 431 xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, /*priority*/1); 432 ccb.cab.ccb_h.func_code = XPT_ABORT; 433 ccb.cab.abort_ccb = (union ccb *)atio; 434 xpt_action(&ccb); 435 } 436 437 while ((ccb_h = SLIST_FIRST(&softc->immed_notify_slist)) != NULL) { 438 SLIST_REMOVE_HEAD(&softc->immed_notify_slist, periph_links.sle); 439 xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, /*priority*/1); 440 ccb.cab.ccb_h.func_code = XPT_ABORT; 441 ccb.cab.abort_ccb = (union ccb *)ccb_h; 442 xpt_action(&ccb); 443 } 444 445 /* 446 * Dissable this lun. 447 */ 448 xpt_setup_ccb(&ccb.cel.ccb_h, periph->path, /*priority*/1); 449 ccb.cel.ccb_h.func_code = XPT_EN_LUN; 450 ccb.cel.enable = 0; 451 xpt_action(&ccb); 452 453 if (ccb.cel.ccb_h.status != CAM_REQ_CMP) 454 printf("targdislun - Disabling lun on controller failed " 455 "with status 0x%x\n", ccb.cel.ccb_h.status); 456 else 457 softc->flags &= ~TARG_FLAG_LUN_ENABLED; 458 return (ccb.cel.ccb_h.status); 459 } 460 461 static cam_status 462 targctor(struct cam_periph *periph, void *arg) 463 { 464 struct ccb_pathinq *cpi; 465 struct targ_softc *softc; 466 int i; 467 468 cpi = (struct ccb_pathinq *)arg; 469 470 /* Allocate our per-instance private storage */ 471 softc = (struct targ_softc *)malloc(sizeof(*softc), M_DEVBUF, M_NOWAIT); 472 if (softc == NULL) { 473 printf("targctor: unable to malloc softc\n"); 474 return (CAM_REQ_CMP_ERR); 475 } 476 477 bzero(softc, sizeof(softc)); 478 TAILQ_INIT(&softc->pending_queue); 479 TAILQ_INIT(&softc->work_queue); 480 TAILQ_INIT(&softc->snd_ccb_queue); 481 TAILQ_INIT(&softc->rcv_ccb_queue); 482 TAILQ_INIT(&softc->unknown_atio_queue); 483 bufq_init(&softc->snd_buf_queue); 484 bufq_init(&softc->rcv_buf_queue); 485 softc->accept_tio_list = NULL; 486 SLIST_INIT(&softc->immed_notify_slist); 487 softc->state = TARG_STATE_NORMAL; 488 periph->softc = softc; 489 softc->init_level++; 490 491 cam_extend_set(targperiphs, periph->unit_number, periph); 492 493 /* 494 * We start out life with a UA to indicate power-on/reset. 495 */ 496 for (i = 0; i < MAX_INITIATORS; i++) 497 softc->istate[i].pending_ua = UA_POWER_ON; 498 499 /* 500 * Allocate an initial inquiry data buffer. We might allow the 501 * user to override this later via an ioctl. 502 */ 503 softc->inq_data_len = sizeof(*softc->inq_data); 504 softc->inq_data = malloc(softc->inq_data_len, M_DEVBUF, M_NOWAIT); 505 if (softc->inq_data == NULL) { 506 printf("targctor - Unable to malloc inquiry data\n"); 507 targdtor(periph); 508 } 509 bzero(softc->inq_data, softc->inq_data_len); 510 softc->inq_data->device = T_PROCESSOR | (SID_QUAL_LU_CONNECTED << 5); 511 softc->inq_data->version = 2; 512 softc->inq_data->response_format = 2; /* SCSI2 Inquiry Format */ 513 softc->inq_data->flags = 514 cpi->hba_inquiry & (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32); 515 softc->inq_data->additional_length = softc->inq_data_len - 4; 516 strncpy(softc->inq_data->vendor, "FreeBSD ", SID_VENDOR_SIZE); 517 strncpy(softc->inq_data->product, "TM-PT ", SID_PRODUCT_SIZE); 518 strncpy(softc->inq_data->revision, "0.0 ", SID_REVISION_SIZE); 519 softc->init_level++; 520 521 return (CAM_REQ_CMP); 522 } 523 524 static void 525 targdtor(struct cam_periph *periph) 526 { 527 struct targ_softc *softc; 528 529 softc = (struct targ_softc *)periph->softc; 530 531 softc->state = TARG_STATE_TEARDOWN; 532 533 targdislun(periph); 534 535 switch (softc->init_level) { 536 default: 537 /* FALLTHROUGH */ 538 case 2: 539 free(softc->inq_data, M_DEVBUF); 540 /* FALLTHROUGH */ 541 case 1: 542 free(softc, M_DEVBUF); 543 break; 544 case 0: 545 panic("targdtor - impossible init level");; 546 } 547 } 548 549 static int 550 targopen(dev_t dev, int flags, int fmt, struct proc *p) 551 { 552 struct cam_periph *periph; 553 u_int unit; 554 cam_status status; 555 int error; 556 int s; 557 558 unit = minor(dev); 559 560 s = splsoftcam(); 561 periph = cam_extend_get(targperiphs, unit); 562 if (periph == NULL) { 563 return (ENXIO); 564 splx(s); 565 } 566 if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0) { 567 splx(s); 568 return (error); 569 } 570 splx(s); 571 572 status = targenlun(periph); 573 switch (status) { 574 case CAM_REQ_CMP: 575 error = 0; 576 break; 577 case CAM_RESRC_UNAVAIL: 578 error = ENOMEM; 579 break; 580 case CAM_LUN_ALRDY_ENA: 581 error = EADDRINUSE; 582 break; 583 default: 584 error = ENXIO; 585 break; 586 } 587 cam_periph_unlock(periph); 588 return (error); 589 } 590 591 static int 592 targclose(dev_t dev, int flag, int fmt, struct proc *p) 593 { 594 struct cam_periph *periph; 595 struct targ_softc *softc; 596 u_int unit; 597 int s; 598 int error; 599 600 unit = minor(dev); 601 s = splsoftcam(); 602 periph = cam_extend_get(targperiphs, unit); 603 if (periph == NULL) { 604 splx(s); 605 return (ENXIO); 606 } 607 if ((error = cam_periph_lock(periph, PRIBIO)) != 0) 608 return (error); 609 softc = (struct targ_softc *)periph->softc; 610 splx(s); 611 612 targdislun(periph); 613 614 cam_periph_unlock(periph); 615 616 return (0); 617 } 618 619 static int 620 targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 621 { 622 struct cam_periph *periph; 623 struct targ_softc *softc; 624 u_int unit; 625 int error; 626 627 unit = minor(dev); 628 periph = cam_extend_get(targperiphs, unit); 629 if (periph == NULL) 630 return (ENXIO); 631 softc = (struct targ_softc *)periph->softc; 632 error = 0; 633 switch (cmd) { 634 case TARGIOCFETCHEXCEPTION: 635 *((targ_exception *)addr) = softc->exceptions; 636 break; 637 case TARGIOCCLEAREXCEPTION: 638 { 639 targ_exception clear_mask; 640 641 clear_mask = *((targ_exception *)addr); 642 if ((clear_mask & TARG_EXCEPT_UNKNOWN_ATIO) != 0) { 643 struct ccb_hdr *ccbh; 644 645 ccbh = TAILQ_FIRST(&softc->unknown_atio_queue); 646 if (ccbh != NULL) { 647 TAILQ_REMOVE(&softc->unknown_atio_queue, 648 ccbh, periph_links.tqe); 649 ccbh = TAILQ_FIRST(&softc->unknown_atio_queue); 650 } 651 if (ccbh != NULL) 652 clear_mask &= ~TARG_EXCEPT_UNKNOWN_ATIO; 653 } 654 softc->exceptions &= ~clear_mask; 655 if (softc->exceptions == TARG_EXCEPT_NONE 656 && softc->state == TARG_STATE_EXCEPTION) { 657 softc->state = TARG_STATE_NORMAL; 658 targrunqueue(periph, softc); 659 } 660 break; 661 } 662 case TARGIOCFETCHATIO: 663 { 664 struct ccb_hdr *ccbh; 665 666 ccbh = TAILQ_FIRST(&softc->unknown_atio_queue); 667 if (ccbh != NULL) { 668 bcopy(ccbh, addr, sizeof(struct ccb_accept_tio)); 669 } else { 670 error = ENOENT; 671 } 672 break; 673 } 674 case TARGIOCCOMMAND: 675 { 676 union ccb *inccb; 677 union ccb *ccb; 678 679 /* 680 * XXX JGibbs 681 * This code is lifted directly from the pass-thru driver. 682 * Perhaps this should be moved to a library???? 683 */ 684 inccb = (union ccb *)addr; 685 ccb = cam_periph_getccb(periph, inccb->ccb_h.pinfo.priority); 686 687 error = targsendccb(periph, ccb, inccb); 688 689 xpt_release_ccb(ccb); 690 691 break; 692 } 693 case TARGIOCGETISTATE: 694 case TARGIOCSETISTATE: 695 { 696 struct ioc_initiator_state *ioc_istate; 697 698 ioc_istate = (struct ioc_initiator_state *)addr; 699 if (ioc_istate->initiator_id > MAX_INITIATORS) { 700 error = EINVAL; 701 break; 702 } 703 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 704 ("GET/SETISTATE for %d\n", ioc_istate->initiator_id)); 705 if (cmd == TARGIOCGETISTATE) { 706 bcopy(&softc->istate[ioc_istate->initiator_id], 707 &ioc_istate->istate, sizeof(ioc_istate->istate)); 708 } else { 709 bcopy(&ioc_istate->istate, 710 &softc->istate[ioc_istate->initiator_id], 711 sizeof(ioc_istate->istate)); 712 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 713 ("pending_ca now %x\n", 714 softc->istate[ioc_istate->initiator_id].pending_ca)); 715 } 716 break; 717 } 718 default: 719 error = ENOTTY; 720 break; 721 } 722 return (error); 723 } 724 725 /* 726 * XXX JGibbs lifted from pass-thru driver. 727 * Generally, "ccb" should be the CCB supplied by the kernel. "inccb" 728 * should be the CCB that is copied in from the user. 729 */ 730 static int 731 targsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) 732 { 733 struct targ_softc *softc; 734 struct cam_periph_map_info mapinfo; 735 int error, need_unmap; 736 737 softc = (struct targ_softc *)periph->softc; 738 739 need_unmap = 0; 740 741 /* 742 * There are some fields in the CCB header that need to be 743 * preserved, the rest we get from the user. 744 */ 745 xpt_merge_ccb(ccb, inccb); 746 747 /* 748 * There's no way for the user to have a completion 749 * function, so we put our own completion function in here. 750 */ 751 ccb->ccb_h.cbfcnp = targdone; 752 753 /* 754 * We only attempt to map the user memory into kernel space 755 * if they haven't passed in a physical memory pointer, 756 * and if there is actually an I/O operation to perform. 757 * Right now cam_periph_mapmem() only supports SCSI and device 758 * match CCBs. For the SCSI CCBs, we only pass the CCB in if 759 * there's actually data to map. cam_periph_mapmem() will do the 760 * right thing, even if there isn't data to map, but since CCBs 761 * without data are a reasonably common occurance (e.g. test unit 762 * ready), it will save a few cycles if we check for it here. 763 */ 764 if (((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) 765 && (((ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) 766 && ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)) 767 || (ccb->ccb_h.func_code == XPT_DEV_MATCH))) { 768 769 bzero(&mapinfo, sizeof(mapinfo)); 770 771 error = cam_periph_mapmem(ccb, &mapinfo); 772 773 /* 774 * cam_periph_mapmem returned an error, we can't continue. 775 * Return the error to the user. 776 */ 777 if (error) 778 return(error); 779 780 /* 781 * We successfully mapped the memory in, so we need to 782 * unmap it when the transaction is done. 783 */ 784 need_unmap = 1; 785 } 786 787 /* 788 * If the user wants us to perform any error recovery, then honor 789 * that request. Otherwise, it's up to the user to perform any 790 * error recovery. 791 */ 792 error = cam_periph_runccb(ccb, 793 (ccb->ccb_h.flags & CAM_PASS_ERR_RECOVER) ? 794 targerror : NULL, 795 /* cam_flags */ 0, 796 /* sense_flags */SF_RETRY_UA, 797 &softc->device_stats); 798 799 if (need_unmap != 0) 800 cam_periph_unmapmem(ccb, &mapinfo); 801 802 ccb->ccb_h.cbfcnp = NULL; 803 ccb->ccb_h.periph_priv = inccb->ccb_h.periph_priv; 804 bcopy(ccb, inccb, sizeof(union ccb)); 805 806 return(error); 807 } 808 809 810 static int 811 targpoll(dev_t dev, int poll_events, struct proc *p) 812 { 813 struct cam_periph *periph; 814 struct targ_softc *softc; 815 u_int unit; 816 int revents; 817 int s; 818 819 unit = minor(dev); 820 periph = cam_extend_get(targperiphs, unit); 821 if (periph == NULL) 822 return (ENXIO); 823 softc = (struct targ_softc *)periph->softc; 824 825 revents = 0; 826 s = splcam(); 827 if ((poll_events & (POLLOUT | POLLWRNORM)) != 0) { 828 if (TAILQ_FIRST(&softc->rcv_ccb_queue) != NULL 829 && bufq_first(&softc->rcv_buf_queue) == NULL) 830 revents |= poll_events & (POLLOUT | POLLWRNORM); 831 } 832 if ((poll_events & (POLLIN | POLLRDNORM)) != 0) { 833 if (TAILQ_FIRST(&softc->snd_ccb_queue) != NULL 834 && bufq_first(&softc->snd_buf_queue) == NULL) 835 revents |= poll_events & (POLLIN | POLLRDNORM); 836 } 837 838 if (softc->state != TARG_STATE_NORMAL) 839 revents |= POLLERR; 840 841 if (revents == 0) { 842 if (poll_events & (POLLOUT | POLLWRNORM)) 843 selrecord(p, &softc->rcv_select); 844 if (poll_events & (POLLIN | POLLRDNORM)) 845 selrecord(p, &softc->snd_select); 846 } 847 splx(s); 848 return (revents); 849 } 850 851 static int 852 targread(dev_t dev, struct uio *uio, int ioflag) 853 { 854 if (uio->uio_iovcnt == 0 855 || uio->uio_iov->iov_len == 0) { 856 /* EOF */ 857 struct cam_periph *periph; 858 struct targ_softc *softc; 859 u_int unit; 860 int s; 861 862 s = splcam(); 863 unit = minor(dev); 864 periph = cam_extend_get(targperiphs, unit); 865 if (periph == NULL) 866 return (ENXIO); 867 softc = (struct targ_softc *)periph->softc; 868 softc->flags |= TARG_FLAG_SEND_EOF; 869 splx(s); 870 targrunqueue(periph, softc); 871 return (0); 872 } 873 return(physio(targstrategy, NULL, dev, 1, minphys, uio)); 874 } 875 876 static int 877 targwrite(dev_t dev, struct uio *uio, int ioflag) 878 { 879 if (uio->uio_iovcnt == 0 880 || uio->uio_iov->iov_len == 0) { 881 /* EOF */ 882 struct cam_periph *periph; 883 struct targ_softc *softc; 884 u_int unit; 885 int s; 886 887 s = splcam(); 888 unit = minor(dev); 889 periph = cam_extend_get(targperiphs, unit); 890 if (periph == NULL) 891 return (ENXIO); 892 softc = (struct targ_softc *)periph->softc; 893 softc->flags |= TARG_FLAG_RECEIVE_EOF; 894 splx(s); 895 targrunqueue(periph, softc); 896 return (0); 897 } 898 return(physio(targstrategy, NULL, dev, 0, minphys, uio)); 899 } 900 901 /* 902 * Actually translate the requested transfer into one the physical driver 903 * can understand. The transfer is described by a buf and will include 904 * only one physical transfer. 905 */ 906 static void 907 targstrategy(struct buf *bp) 908 { 909 struct cam_periph *periph; 910 struct targ_softc *softc; 911 u_int unit; 912 int s; 913 914 unit = minor(bp->b_dev); 915 periph = cam_extend_get(targperiphs, unit); 916 if (periph == NULL) { 917 bp->b_error = ENXIO; 918 goto bad; 919 } 920 softc = (struct targ_softc *)periph->softc; 921 922 /* 923 * Mask interrupts so that the device cannot be invalidated until 924 * after we are in the queue. Otherwise, we might not properly 925 * clean up one of the buffers. 926 */ 927 s = splbio(); 928 929 /* 930 * If there is an exception pending, error out 931 */ 932 if (softc->state != TARG_STATE_NORMAL) { 933 splx(s); 934 if (softc->state == TARG_STATE_EXCEPTION 935 && (softc->exceptions & TARG_EXCEPT_DEVICE_INVALID) == 0) 936 bp->b_error = EBUSY; 937 else 938 bp->b_error = ENXIO; 939 goto bad; 940 } 941 942 /* 943 * Place it in the queue of buffers available for either 944 * SEND or RECEIVE commands. 945 * 946 */ 947 bp->b_resid = bp->b_bcount; 948 if ((bp->b_flags & B_READ) != 0) { 949 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 950 ("Queued a SEND buffer\n")); 951 bufq_insert_tail(&softc->snd_buf_queue, bp); 952 } else { 953 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 954 ("Queued a RECEIVE buffer\n")); 955 bufq_insert_tail(&softc->rcv_buf_queue, bp); 956 } 957 958 splx(s); 959 960 /* 961 * Attempt to use the new buffer to service any pending 962 * target commands. 963 */ 964 targrunqueue(periph, softc); 965 966 return; 967 bad: 968 bp->b_flags |= B_ERROR; 969 970 /* 971 * Correctly set the buf to indicate a completed xfer 972 */ 973 bp->b_resid = bp->b_bcount; 974 biodone(bp); 975 } 976 977 static void 978 targrunqueue(struct cam_periph *periph, struct targ_softc *softc) 979 { 980 struct ccb_queue *pending_queue; 981 struct ccb_accept_tio *atio; 982 struct buf_queue_head *bufq; 983 struct buf *bp; 984 struct targ_cmd_desc *desc; 985 struct ccb_hdr *ccbh; 986 int s; 987 988 s = splbio(); 989 pending_queue = NULL; 990 bufq = NULL; 991 ccbh = NULL; 992 /* Only run one request at a time to maintain data ordering. */ 993 if (softc->state != TARG_STATE_NORMAL 994 || TAILQ_FIRST(&softc->work_queue) != NULL 995 || TAILQ_FIRST(&softc->pending_queue) != NULL) { 996 splx(s); 997 return; 998 } 999 1000 if (((bp = bufq_first(&softc->snd_buf_queue)) != NULL 1001 || (softc->flags & TARG_FLAG_SEND_EOF) != 0) 1002 && (ccbh = TAILQ_FIRST(&softc->snd_ccb_queue)) != NULL) { 1003 1004 if (bp == NULL) 1005 softc->flags &= ~TARG_FLAG_SEND_EOF; 1006 else { 1007 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1008 ("De-Queued a SEND buffer %ld\n", 1009 bp->b_bcount)); 1010 } 1011 bufq = &softc->snd_buf_queue; 1012 pending_queue = &softc->snd_ccb_queue; 1013 } else if (((bp = bufq_first(&softc->rcv_buf_queue)) != NULL 1014 || (softc->flags & TARG_FLAG_RECEIVE_EOF) != 0) 1015 && (ccbh = TAILQ_FIRST(&softc->rcv_ccb_queue)) != NULL) { 1016 1017 if (bp == NULL) 1018 softc->flags &= ~TARG_FLAG_RECEIVE_EOF; 1019 else { 1020 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1021 ("De-Queued a RECEIVE buffer %ld\n", 1022 bp->b_bcount)); 1023 } 1024 bufq = &softc->rcv_buf_queue; 1025 pending_queue = &softc->rcv_ccb_queue; 1026 } 1027 1028 if (pending_queue != NULL) { 1029 /* Process a request */ 1030 atio = (struct ccb_accept_tio *)ccbh; 1031 TAILQ_REMOVE(pending_queue, ccbh, periph_links.tqe); 1032 desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr; 1033 desc->bp = bp; 1034 if (bp == NULL) { 1035 /* EOF */ 1036 desc->data = NULL; 1037 desc->data_increment = 0; 1038 desc->data_resid = 0; 1039 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1040 atio->ccb_h.flags |= CAM_DIR_NONE; 1041 } else { 1042 bufq_remove(bufq, bp); 1043 desc->data = &bp->b_data[bp->b_bcount - bp->b_resid]; 1044 desc->data_increment = 1045 MIN(desc->data_resid, bp->b_resid); 1046 } 1047 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1048 ("Buffer command: data %x: datacnt %d\n", 1049 (intptr_t)desc->data, desc->data_increment)); 1050 TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h, 1051 periph_links.tqe); 1052 } 1053 if (TAILQ_FIRST(&softc->work_queue) != NULL) { 1054 splx(s); 1055 xpt_schedule(periph, /*XXX priority*/1); 1056 } else 1057 splx(s); 1058 } 1059 1060 static void 1061 targstart(struct cam_periph *periph, union ccb *start_ccb) 1062 { 1063 struct targ_softc *softc; 1064 struct ccb_hdr *ccbh; 1065 struct ccb_accept_tio *atio; 1066 struct targ_cmd_desc *desc; 1067 struct ccb_scsiio *csio; 1068 ccb_flags flags; 1069 int s; 1070 1071 softc = (struct targ_softc *)periph->softc; 1072 1073 s = splbio(); 1074 ccbh = TAILQ_FIRST(&softc->work_queue); 1075 if (periph->immediate_priority <= periph->pinfo.priority) { 1076 start_ccb->ccb_h.ccb_type = TARG_CCB_WAITING; 1077 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 1078 periph_links.sle); 1079 periph->immediate_priority = CAM_PRIORITY_NONE; 1080 splx(s); 1081 wakeup(&periph->ccb_list); 1082 } else if (ccbh == NULL) { 1083 splx(s); 1084 xpt_release_ccb(start_ccb); 1085 } else { 1086 TAILQ_REMOVE(&softc->work_queue, ccbh, periph_links.tqe); 1087 TAILQ_INSERT_HEAD(&softc->pending_queue, ccbh, 1088 periph_links.tqe); 1089 splx(s); 1090 atio = (struct ccb_accept_tio*)ccbh; 1091 desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr; 1092 1093 /* Is this a tagged request? */ 1094 flags = atio->ccb_h.flags & (CAM_TAG_ACTION_VALID|CAM_DIR_MASK); 1095 1096 /* 1097 * If we are done with the transaction, tell the 1098 * controller to send status and perform a CMD_CMPLT. 1099 */ 1100 if (desc->data_resid == desc->data_increment) 1101 flags |= CAM_SEND_STATUS; 1102 1103 csio = &start_ccb->csio; 1104 cam_fill_ctio(csio, 1105 /*retries*/2, 1106 targdone, 1107 flags, 1108 /*tag_action*/MSG_SIMPLE_Q_TAG, 1109 atio->tag_id, 1110 atio->init_id, 1111 desc->status, 1112 /*data_ptr*/desc->data_increment == 0 1113 ? NULL : desc->data, 1114 /*dxfer_len*/desc->data_increment, 1115 /*timeout*/desc->timeout); 1116 1117 start_ccb->ccb_h.ccb_type = TARG_CCB_WORKQ; 1118 start_ccb->ccb_h.ccb_atio = atio; 1119 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1120 ("Sending a CTIO\n")); 1121 xpt_action(start_ccb); 1122 s = splbio(); 1123 ccbh = TAILQ_FIRST(&softc->work_queue); 1124 splx(s); 1125 } 1126 if (ccbh != NULL) 1127 targrunqueue(periph, softc); 1128 } 1129 1130 static void 1131 targdone(struct cam_periph *periph, union ccb *done_ccb) 1132 { 1133 struct targ_softc *softc; 1134 1135 softc = (struct targ_softc *)periph->softc; 1136 1137 if (done_ccb->ccb_h.ccb_type == TARG_CCB_WAITING) { 1138 /* Caller will release the CCB */ 1139 wakeup(&done_ccb->ccb_h.cbfcnp); 1140 return; 1141 } 1142 1143 switch (done_ccb->ccb_h.func_code) { 1144 case XPT_ACCEPT_TARGET_IO: 1145 { 1146 struct ccb_accept_tio *atio; 1147 struct targ_cmd_desc *descr; 1148 struct initiator_state *istate; 1149 u_int8_t *cdb; 1150 1151 atio = &done_ccb->atio; 1152 descr = (struct targ_cmd_desc*)atio->ccb_h.ccb_descr; 1153 istate = &softc->istate[atio->init_id]; 1154 cdb = atio->cdb_io.cdb_bytes; 1155 if (softc->state == TARG_STATE_TEARDOWN 1156 || atio->ccb_h.status == CAM_REQ_ABORTED) { 1157 printf("Freed an accept tio\n"); 1158 freedescr(descr); 1159 free(done_ccb, M_DEVBUF); 1160 return; 1161 } 1162 1163 if (istate->pending_ca == 0 1164 && istate->pending_ua != 0 1165 && cdb[0] != INQUIRY) { 1166 /* Pending UA, tell initiator */ 1167 /* Direction is always relative to the initator */ 1168 istate->pending_ca = CA_UNIT_ATTN; 1169 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1170 atio->ccb_h.flags |= CAM_DIR_NONE; 1171 descr->data_resid = 0; 1172 descr->data_increment = 0; 1173 descr->timeout = 5 * 1000; 1174 descr->status = SCSI_STATUS_CHECK_COND; 1175 } else { 1176 /* 1177 * Save the current CA and UA status so 1178 * they can be used by this command. 1179 */ 1180 ua_types pending_ua; 1181 ca_types pending_ca; 1182 1183 pending_ua = istate->pending_ua; 1184 pending_ca = istate->pending_ca; 1185 1186 /* 1187 * As per the SCSI2 spec, any command that occurs 1188 * after a CA is reported, clears the CA. If the 1189 * command is not an inquiry, we are also supposed 1190 * to clear the UA condition, if any, that caused 1191 * the CA to occur assuming the UA is not a 1192 * persistant state. 1193 */ 1194 istate->pending_ca = CA_NONE; 1195 if ((pending_ca 1196 & (CA_CMD_SENSE|CA_UNIT_ATTN)) == CA_UNIT_ATTN 1197 && cdb[0] != INQUIRY) 1198 istate->pending_ua = UA_NONE; 1199 1200 /* 1201 * Determine the type of incoming command and 1202 * setup our buffer for a response. 1203 */ 1204 switch (cdb[0]) { 1205 case INQUIRY: 1206 { 1207 struct scsi_inquiry *inq; 1208 struct scsi_sense_data *sense; 1209 1210 inq = (struct scsi_inquiry *)cdb; 1211 sense = &istate->sense_data; 1212 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1213 ("Saw an inquiry!\n")); 1214 /* 1215 * Validate the command. We don't 1216 * support any VPD pages, so complain 1217 * if EVPD is set. 1218 */ 1219 if ((inq->byte2 & SI_EVPD) != 0 1220 || inq->page_code != 0) { 1221 istate->pending_ca = CA_CMD_SENSE; 1222 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1223 atio->ccb_h.flags |= CAM_DIR_NONE; 1224 descr->data_resid = 0; 1225 descr->data_increment = 0; 1226 descr->status = SCSI_STATUS_CHECK_COND; 1227 fill_sense(sense, 1228 SSD_CURRENT_ERROR, 1229 SSD_KEY_ILLEGAL_REQUEST, 1230 /*asc*/0x24, /*ascq*/0x00); 1231 sense->extra_len = 1232 offsetof(struct scsi_sense_data, 1233 extra_bytes) 1234 - offsetof(struct scsi_sense_data, 1235 extra_len); 1236 } 1237 1238 if ((inq->byte2 & SI_EVPD) != 0) { 1239 sense->sense_key_spec[0] = 1240 SSD_SCS_VALID|SSD_FIELDPTR_CMD 1241 |SSD_BITPTR_VALID| /*bit value*/1; 1242 sense->sense_key_spec[1] = 0; 1243 sense->sense_key_spec[2] = 1244 offsetof(struct scsi_inquiry, 1245 byte2); 1246 break; 1247 } else if (inq->page_code != 0) { 1248 sense->sense_key_spec[0] = 1249 SSD_SCS_VALID|SSD_FIELDPTR_CMD; 1250 sense->sense_key_spec[1] = 0; 1251 sense->sense_key_spec[2] = 1252 offsetof(struct scsi_inquiry, 1253 page_code); 1254 break; 1255 } 1256 /* 1257 * Direction is always relative 1258 * to the initator. 1259 */ 1260 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1261 atio->ccb_h.flags |= CAM_DIR_IN; 1262 descr->data = softc->inq_data; 1263 descr->data_resid = MIN(softc->inq_data_len, 1264 inq->length); 1265 descr->data_increment = descr->data_resid; 1266 descr->timeout = 5 * 1000; 1267 descr->status = SCSI_STATUS_OK; 1268 break; 1269 } 1270 case TEST_UNIT_READY: 1271 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1272 atio->ccb_h.flags |= CAM_DIR_NONE; 1273 descr->data_resid = 0; 1274 descr->data_increment = 0; 1275 descr->status = SCSI_STATUS_OK; 1276 break; 1277 case REQUEST_SENSE: 1278 { 1279 struct scsi_request_sense *rsense; 1280 struct scsi_sense_data *sense; 1281 1282 rsense = (struct scsi_request_sense *)cdb; 1283 sense = &istate->sense_data; 1284 if (pending_ca == 0) { 1285 fill_sense(sense, SSD_CURRENT_ERROR, 1286 SSD_KEY_NO_SENSE, 0x00, 1287 0x00); 1288 CAM_DEBUG(periph->path, 1289 CAM_DEBUG_SUBTRACE, 1290 ("No pending CA!\n")); 1291 } else if (pending_ca == CA_UNIT_ATTN) { 1292 u_int ascq; 1293 1294 if (pending_ua == UA_POWER_ON) 1295 ascq = 0x1; 1296 else 1297 ascq = 0x2; 1298 fill_sense(sense, SSD_CURRENT_ERROR, 1299 SSD_KEY_UNIT_ATTENTION, 1300 0x29, ascq); 1301 CAM_DEBUG(periph->path, 1302 CAM_DEBUG_SUBTRACE, 1303 ("Pending UA!\n")); 1304 } 1305 /* 1306 * Direction is always relative 1307 * to the initator. 1308 */ 1309 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1310 atio->ccb_h.flags |= CAM_DIR_IN; 1311 descr->data = sense; 1312 descr->data_resid = 1313 offsetof(struct scsi_sense_data, 1314 extra_len) 1315 + sense->extra_len; 1316 descr->data_resid = MIN(descr->data_resid, 1317 rsense->length); 1318 descr->data_increment = descr->data_resid; 1319 descr->timeout = 5 * 1000; 1320 descr->status = SCSI_STATUS_OK; 1321 break; 1322 } 1323 case RECEIVE: 1324 case SEND: 1325 { 1326 struct scsi_send_receive *sr; 1327 1328 sr = (struct scsi_send_receive *)cdb; 1329 1330 /* 1331 * Direction is always relative 1332 * to the initator. 1333 */ 1334 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1335 if (cdb[0] == SEND) { 1336 atio->ccb_h.flags |= CAM_DIR_OUT; 1337 CAM_DEBUG(periph->path, 1338 CAM_DEBUG_SUBTRACE, 1339 ("Saw a SEND!\n")); 1340 atio->ccb_h.flags |= CAM_DIR_OUT; 1341 TAILQ_INSERT_TAIL(&softc->snd_ccb_queue, 1342 &atio->ccb_h, 1343 periph_links.tqe); 1344 selwakeup(&softc->snd_select); 1345 } else { 1346 atio->ccb_h.flags |= CAM_DIR_IN; 1347 CAM_DEBUG(periph->path, 1348 CAM_DEBUG_SUBTRACE, 1349 ("Saw a RECEIVE!\n")); 1350 TAILQ_INSERT_TAIL(&softc->rcv_ccb_queue, 1351 &atio->ccb_h, 1352 periph_links.tqe); 1353 selwakeup(&softc->rcv_select); 1354 } 1355 descr->data_resid = scsi_3btoul(sr->xfer_len); 1356 descr->timeout = 5 * 1000; 1357 descr->status = SCSI_STATUS_OK; 1358 /* 1359 * Attempt to satisfy this request with 1360 * a user buffer. 1361 */ 1362 targrunqueue(periph, softc); 1363 return; 1364 } 1365 default: 1366 /* 1367 * Queue for consumption by our userland 1368 * counterpart and transition to the exception 1369 * state. 1370 */ 1371 TAILQ_INSERT_TAIL(&softc->unknown_atio_queue, 1372 &atio->ccb_h, 1373 periph_links.tqe); 1374 softc->exceptions |= TARG_EXCEPT_UNKNOWN_ATIO; 1375 targfireexception(periph, softc); 1376 return; 1377 } 1378 } 1379 1380 /* Queue us up to receive a Continue Target I/O ccb. */ 1381 TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h, 1382 periph_links.tqe); 1383 xpt_schedule(periph, /*priority*/1); 1384 break; 1385 } 1386 case XPT_CONT_TARGET_IO: 1387 { 1388 struct ccb_accept_tio *atio; 1389 struct targ_cmd_desc *desc; 1390 struct buf *bp; 1391 1392 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1393 ("Received completed CTIO\n")); 1394 atio = (struct ccb_accept_tio*)done_ccb->ccb_h.ccb_atio; 1395 desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr; 1396 1397 TAILQ_REMOVE(&softc->pending_queue, &atio->ccb_h, 1398 periph_links.tqe); 1399 1400 /* XXX Check for errors */ 1401 desc->data_resid -= desc->data_increment; 1402 if ((bp = desc->bp) != NULL) { 1403 1404 bp->b_resid -= desc->data_increment; 1405 bp->b_error = 0; 1406 1407 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1408 ("Buffer I/O Completed - Resid %ld:%d\n", 1409 bp->b_resid, desc->data_resid)); 1410 /* 1411 * Send the buffer back to the client if 1412 * either the command has completed or all 1413 * buffer space has been consumed. 1414 */ 1415 if (desc->data_resid == 0 1416 || bp->b_resid == 0) { 1417 if (bp->b_resid != 0) 1418 /* Short transfer */ 1419 bp->b_flags |= B_ERROR; 1420 1421 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1422 ("Completing a buffer\n")); 1423 biodone(bp); 1424 desc->bp = NULL; 1425 } 1426 } 1427 1428 xpt_release_ccb(done_ccb); 1429 if (softc->state != TARG_STATE_TEARDOWN) { 1430 1431 if (desc->data_resid == 0) { 1432 /* 1433 * Send the original accept TIO back to the 1434 * controller to handle more work. 1435 */ 1436 CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE, 1437 ("Returning ATIO to target\n")); 1438 xpt_action((union ccb *)atio); 1439 break; 1440 } 1441 1442 if (desc->bp != NULL) 1443 panic("targ%d: desc->bp should be NULL", 1444 periph->unit_number); 1445 1446 /* Queue us up for another buffer */ 1447 if (atio->cdb_io.cdb_bytes[0] == SEND) { 1448 TAILQ_INSERT_HEAD(&softc->snd_ccb_queue, 1449 &atio->ccb_h, 1450 periph_links.tqe); 1451 } else { 1452 TAILQ_INSERT_HEAD(&softc->rcv_ccb_queue, 1453 &atio->ccb_h, 1454 periph_links.tqe); 1455 } 1456 desc->bp = NULL; 1457 targrunqueue(periph, softc); 1458 } else { 1459 if (desc->bp != NULL) { 1460 bp->b_flags |= B_ERROR; 1461 bp->b_error = ENXIO; 1462 biodone(bp); 1463 } 1464 freedescr(desc); 1465 free(atio, M_DEVBUF); 1466 } 1467 break; 1468 } 1469 case XPT_IMMED_NOTIFY: 1470 { 1471 if (softc->state == TARG_STATE_TEARDOWN 1472 || done_ccb->ccb_h.status == CAM_REQ_ABORTED) { 1473 printf("Freed an immediate notify\n"); 1474 free(done_ccb, M_DEVBUF); 1475 } 1476 break; 1477 } 1478 } 1479 } 1480 1481 /* 1482 * Transition to the exception state and notify our symbiotic 1483 * userland process of the change. 1484 */ 1485 static void 1486 targfireexception(struct cam_periph *periph, struct targ_softc *softc) 1487 { 1488 /* 1489 * return all pending buffers with short read/write status so our 1490 * process unblocks, and do a selwakeup on any process queued 1491 * waiting for reads or writes. When the selwakeup is performed, 1492 * the waking process will wakeup, call our poll routine again, 1493 * and pick up the exception. 1494 */ 1495 struct buf *bp; 1496 1497 if (softc->state != TARG_STATE_NORMAL) 1498 /* Already either tearing down or in exception state */ 1499 return; 1500 1501 softc->state = TARG_STATE_EXCEPTION; 1502 1503 while ((bp = bufq_first(&softc->snd_buf_queue)) != NULL) { 1504 bufq_remove(&softc->snd_buf_queue, bp); 1505 bp->b_flags |= B_ERROR; 1506 biodone(bp); 1507 } 1508 1509 while ((bp = bufq_first(&softc->rcv_buf_queue)) != NULL) { 1510 bufq_remove(&softc->snd_buf_queue, bp); 1511 bp->b_flags |= B_ERROR; 1512 biodone(bp); 1513 } 1514 1515 selwakeup(&softc->snd_select); 1516 selwakeup(&softc->rcv_select); 1517 } 1518 1519 static int 1520 targerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) 1521 { 1522 return 0; 1523 } 1524 1525 static struct targ_cmd_desc* 1526 allocdescr() 1527 { 1528 struct targ_cmd_desc* descr; 1529 1530 /* Allocate the targ_descr structure */ 1531 descr = (struct targ_cmd_desc *)malloc(sizeof(*descr), 1532 M_DEVBUF, M_NOWAIT); 1533 if (descr == NULL) 1534 return (NULL); 1535 1536 bzero(descr, sizeof(*descr)); 1537 1538 /* Allocate buffer backing store */ 1539 descr->backing_store = malloc(MAX_BUF_SIZE, M_DEVBUF, M_NOWAIT); 1540 if (descr->backing_store == NULL) { 1541 free(descr, M_DEVBUF); 1542 return (NULL); 1543 } 1544 descr->max_size = MAX_BUF_SIZE; 1545 return (descr); 1546 } 1547 1548 static void 1549 freedescr(struct targ_cmd_desc *descr) 1550 { 1551 free(descr->backing_store, M_DEVBUF); 1552 free(descr, M_DEVBUF); 1553 } 1554 1555 static void 1556 fill_sense(struct scsi_sense_data *sense, u_int error_code, u_int sense_key, 1557 u_int asc, u_int ascq) 1558 { 1559 bzero(sense, sizeof(*sense)); 1560 sense->error_code = error_code; 1561 sense->flags = sense_key; 1562 sense->add_sense_code = asc; 1563 sense->add_sense_code_qual = ascq; 1564 1565 sense->extra_len = offsetof(struct scsi_sense_data, fru) 1566 - offsetof(struct scsi_sense_data, extra_len); 1567 } 1568