Lines Matching +full:test2 +full:. +full:good

4  * Copyright (c) 2009 Silicon Graphics International Corp.
5 * All rights reserved.
10 * 1. Redistributions of source code must retain the above copyright
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17 * binary redistribution.
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * POSSIBILITY OF SUCH DAMAGES.
32 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_frontend_cam_sim.c#4 $
35 * CTL frontend to CAM SIM interface. This allows access to CTL LUNs via
36 * the da(4) and pass(4) drivers from inside the system.
38 * Author: Ken Merry <ken@FreeBSD.org>
41 #include <sys/cdefs.h>
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/types.h>
48 #include <sys/malloc.h>
49 #include <sys/bus.h>
50 #include <sys/sysctl.h>
51 #include <machine/atomic.h>
52 #include <machine/bus.h>
53 #include <sys/sbuf.h>
55 #include <cam/cam.h>
56 #include <cam/cam_ccb.h>
57 #include <cam/cam_sim.h>
58 #include <cam/cam_xpt_sim.h>
59 #include <cam/cam_xpt.h>
60 #include <cam/cam_periph.h>
61 #include <cam/scsi/scsi_all.h>
62 #include <cam/scsi/scsi_message.h>
63 #include <cam/ctl/ctl_io.h>
64 #include <cam/ctl/ctl.h>
65 #include <cam/ctl/ctl_frontend.h>
66 #include <cam/ctl/ctl_debug.h>
87 * We can't handle CCBs with these flags. For the most part, we just don't
88 * handle physical addresses yet. That would require mapping things in
89 * order to do the copy.
106 * sense data and sense residual handling code. This sets the maximum
107 * amount of SCSI sense data that we will report to CAM.
118 .name = "camsim",
119 .init = cfcs_init,
120 .shutdown = cfcs_shutdown,
157 * ahead and set something random. in cfcs_init()
253 if (xpt_create_path(&ccb->ccb_h.path, NULL, in cfcs_onoffline()
276 * This function is very similar to ctl_ioctl_do_datamove(). Is there a
279 * XXX KDM may need to move this into a thread. We're doing a bcopy in the
280 * caller's context, which will usually be the backend. That may not be a
281 * good thing.
295 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; in cfcs_datamove()
299 * CCBs with "bad" flags are returned with CAM_REQ_INVALID. This in cfcs_datamove()
302 * support those modes of operation. in cfcs_datamove()
304 KASSERT(((ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS) == 0), ("invalid " in cfcs_datamove()
305 "CAM flags %#x", (ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS))); in cfcs_datamove()
309 * single entry S/G list. in cfcs_datamove()
311 switch ((ccb->ccb_h.flags & CAM_DATA_MASK)) { in cfcs_datamove()
315 cam_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr; in cfcs_datamove()
316 cam_sg_count = ccb->csio.sglist_cnt; in cfcs_datamove()
321 if ((len_seen + cam_sglist[i].ds_len) >= in cfcs_datamove()
322 io->scsiio.kern_rel_offset) { in cfcs_datamove()
324 cam_sg_offset = io->scsiio.kern_rel_offset - in cfcs_datamove()
328 len_seen += cam_sglist[i].ds_len; in cfcs_datamove()
334 cam_sglist[0].ds_len = ccb->csio.dxfer_len; in cfcs_datamove()
335 cam_sglist[0].ds_addr = (bus_addr_t)(uintptr_t)ccb->csio.data_ptr; in cfcs_datamove()
338 cam_sg_offset = io->scsiio.kern_rel_offset; in cfcs_datamove()
341 panic("Invalid CAM flags %#x", ccb->ccb_h.flags); in cfcs_datamove()
344 if (io->scsiio.kern_sg_entries > 0) { in cfcs_datamove()
345 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; in cfcs_datamove()
346 ctl_sg_count = io->scsiio.kern_sg_entries; in cfcs_datamove()
349 ctl_sglist->addr = io->scsiio.kern_data_ptr; in cfcs_datamove()
350 ctl_sglist->len = io->scsiio.kern_data_len; in cfcs_datamove()
360 len_to_copy = MIN(cam_sglist[i].ds_len - cam_watermark, in cfcs_datamove()
361 ctl_sglist[j].len - ctl_watermark); in cfcs_datamove()
363 cam_ptr = (uint8_t *)(uintptr_t)cam_sglist[i].ds_addr; in cfcs_datamove()
365 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) { in cfcs_datamove()
371 kern_ptr = bus_to_virt(kern_sglist[j].addr); in cfcs_datamove()
374 ctl_ptr = (uint8_t *)ctl_sglist[j].addr; in cfcs_datamove()
377 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == in cfcs_datamove()
392 io->scsiio.ext_data_filled += len_to_copy; in cfcs_datamove()
393 io->scsiio.kern_data_resid -= len_to_copy; in cfcs_datamove()
396 if (cam_sglist[i].ds_len == cam_watermark) { in cfcs_datamove()
402 if (ctl_sglist[j].len == ctl_watermark) { in cfcs_datamove()
408 if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) { in cfcs_datamove()
409 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = NULL; in cfcs_datamove()
410 io->io_hdr.flags |= CTL_FLAG_STATUS_SENT; in cfcs_datamove()
411 ccb->csio.resid = ccb->csio.dxfer_len - in cfcs_datamove()
412 io->scsiio.ext_data_filled; in cfcs_datamove()
413 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in cfcs_datamove()
414 ccb->ccb_h.status |= CAM_REQ_CMP; in cfcs_datamove()
426 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; in cfcs_done()
433 * At this point we should have status. If we don't, that's a bug. in cfcs_done()
435 KASSERT(((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE), in cfcs_done()
436 ("invalid CTL status %#x", io->io_hdr.status)); in cfcs_done()
439 * Translate CTL status to CAM status. in cfcs_done()
441 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in cfcs_done()
442 ccb->csio.resid = ccb->csio.dxfer_len - in cfcs_done()
443 io->scsiio.ext_data_filled; in cfcs_done()
445 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in cfcs_done()
446 switch (io->io_hdr.status & CTL_STATUS_MASK) { in cfcs_done()
448 ccb->ccb_h.status |= CAM_REQ_CMP; in cfcs_done()
451 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; in cfcs_done()
452 ccb->csio.scsi_status = io->scsiio.scsi_status; in cfcs_done()
453 bcopy(&io->scsiio.sense_data, &ccb->csio.sense_data, in cfcs_done()
454 min(io->scsiio.sense_len, ccb->csio.sense_len)); in cfcs_done()
455 if (ccb->csio.sense_len > io->scsiio.sense_len) in cfcs_done()
456 ccb->csio.sense_resid = ccb->csio.sense_len - in cfcs_done()
457 io->scsiio.sense_len; in cfcs_done()
459 ccb->csio.sense_resid = 0; in cfcs_done()
460 if ((ccb->csio.sense_len - ccb->csio.sense_resid) > in cfcs_done()
462 ccb->csio.sense_resid = ccb->csio.sense_len - in cfcs_done()
467 ccb->ccb_h.status |= CAM_REQ_ABORTED; in cfcs_done()
471 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; in cfcs_done()
475 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP && in cfcs_done()
476 (ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { in cfcs_done()
477 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_done()
478 ccb->ccb_h.status |= CAM_DEV_QFRZN; in cfcs_done()
491 switch (ccb->ccb_h.func_code) { in cfcs_action()
500 * indicate situations we currently can't handle. in cfcs_action()
502 if (ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS) { in cfcs_action()
503 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
505 __func__, ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS, in cfcs_action()
506 ccb->ccb_h.flags); in cfcs_action()
512 * If we aren't online, there are no devices to see. in cfcs_action()
515 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
520 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
523 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
524 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
530 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
531 ccb->ccb_h.io_ptr = io; in cfcs_action()
534 * Only SCSI I/O comes down this path, resets, etc. come in cfcs_action()
535 * down via the XPT_RESET_BUS/LUN CCBs below. in cfcs_action()
537 io->io_hdr.io_type = CTL_IO_SCSI; in cfcs_action()
538 io->io_hdr.nexus.initid = 1; in cfcs_action()
539 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
540 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
541 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
542 io->scsiio.priority = csio->priority; in cfcs_action()
546 * in a high I/O environment. But it should work well in cfcs_action()
547 * enough for now. Since we're using unsigned ints, in cfcs_action()
548 * they'll just wrap around. in cfcs_action()
550 io->scsiio.tag_num = atomic_fetchadd_32(&softc->cur_tag_num, 1); in cfcs_action()
551 csio->tag_id = io->scsiio.tag_num; in cfcs_action()
554 io->scsiio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
557 io->scsiio.tag_type = CTL_TAG_SIMPLE; in cfcs_action()
560 io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE; in cfcs_action()
563 io->scsiio.tag_type = CTL_TAG_ORDERED; in cfcs_action()
566 io->scsiio.tag_type = CTL_TAG_ACA; in cfcs_action()
569 io->scsiio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
574 if (csio->cdb_len > sizeof(io->scsiio.cdb)) { in cfcs_action()
576 __func__, csio->cdb_len, sizeof(io->scsiio.cdb)); in cfcs_action()
578 io->scsiio.cdb_len = min(csio->cdb_len, sizeof(io->scsiio.cdb)); in cfcs_action()
579 bcopy(scsiio_cdb_ptr(csio), io->scsiio.cdb, io->scsiio.cdb_len); in cfcs_action()
581 ccb->ccb_h.status |= CAM_SIM_QUEUED; in cfcs_action()
586 ccb->ccb_h.func_code, err); in cfcs_action()
588 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
598 abort_ccb = ccb->cab.abort_ccb; in cfcs_action()
600 if (abort_ccb->ccb_h.func_code != XPT_SCSI_IO) { in cfcs_action()
601 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
606 * If we aren't online, there are no devices to talk to. in cfcs_action()
609 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
614 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
616 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
617 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
624 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
625 ccb->ccb_h.io_ptr = io; in cfcs_action()
627 io->io_hdr.io_type = CTL_IO_TASK; in cfcs_action()
628 io->io_hdr.nexus.initid = 1; in cfcs_action()
629 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
630 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
631 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
632 io->taskio.task_action = CTL_TASK_ABORT_TASK; in cfcs_action()
633 io->taskio.tag_num = abort_ccb->csio.tag_id; in cfcs_action()
634 switch (abort_ccb->csio.tag_action) { in cfcs_action()
636 io->taskio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
639 io->taskio.tag_type = CTL_TAG_SIMPLE; in cfcs_action()
642 io->taskio.tag_type = CTL_TAG_HEAD_OF_QUEUE; in cfcs_action()
645 io->taskio.tag_type = CTL_TAG_ORDERED; in cfcs_action()
648 io->taskio.tag_type = CTL_TAG_ACA; in cfcs_action()
651 io->taskio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
653 abort_ccb->csio.tag_action); in cfcs_action()
660 ccb->ccb_h.func_code, err); in cfcs_action()
671 scsi = &cts->proto_specific.scsi; in cfcs_action()
672 fc = &cts->xport_specific.fc; in cfcs_action()
686 fc->port = softc->port.targ_port; in cfcs_action()
689 ccb->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
694 ccb->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
701 * If we aren't online, there are no devices to talk to. in cfcs_action()
704 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
709 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
711 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
712 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
719 if (ccb->ccb_h.func_code == XPT_RESET_DEV) in cfcs_action()
720 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
721 ccb->ccb_h.io_ptr = io; in cfcs_action()
723 io->io_hdr.io_type = CTL_IO_TASK; in cfcs_action()
724 io->io_hdr.nexus.initid = 1; in cfcs_action()
725 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
726 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
727 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
728 if (ccb->ccb_h.func_code == XPT_RESET_BUS) in cfcs_action()
729 io->taskio.task_action = CTL_TASK_BUS_RESET; in cfcs_action()
731 io->taskio.task_action = CTL_TASK_LUN_RESET; in cfcs_action()
737 ccb->ccb_h.func_code, err); in cfcs_action()
773 * Pretend to be Fibre Channel. in cfcs_action()
777 cpi->xport_specific.fc.wwnn = softc->wwnn; in cfcs_action()
778 cpi->xport_specific.fc.wwpn = softc->wwpn; in cfcs_action()
779 cpi->xport_specific.fc.port = softc->port.targ_port; in cfcs_action()
780 cpi->xport_specific.fc.bitrate = 8 * 1000 * 1000; in cfcs_action()
781 cpi->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
785 ccb->ccb_h.status = CAM_PROVIDE_FAIL; in cfcs_action()
787 ccb->ccb_h.func_code); in cfcs_action()