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>
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/types.h>
46 #include <sys/malloc.h>
47 #include <sys/bus.h>
48 #include <sys/sysctl.h>
49 #include <machine/atomic.h>
50 #include <machine/bus.h>
51 #include <sys/sbuf.h>
53 #include <cam/cam.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/cam_sim.h>
56 #include <cam/cam_xpt_sim.h>
57 #include <cam/cam_xpt.h>
58 #include <cam/cam_periph.h>
59 #include <cam/scsi/scsi_all.h>
60 #include <cam/scsi/scsi_message.h>
61 #include <cam/ctl/ctl_io.h>
62 #include <cam/ctl/ctl.h>
63 #include <cam/ctl/ctl_frontend.h>
64 #include <cam/ctl/ctl_debug.h>
85 * We can't handle CCBs with these flags. For the most part, we just don't
86 * handle physical addresses yet. That would require mapping things in
87 * order to do the copy.
104 * sense data and sense residual handling code. This sets the maximum
105 * amount of SCSI sense data that we will report to CAM.
116 .name = "camsim",
117 .init = cfcs_init,
118 .shutdown = cfcs_shutdown,
155 * ahead and set something random. in cfcs_init()
251 if (xpt_create_path(&ccb->ccb_h.path, NULL, in cfcs_onoffline()
274 * This function is very similar to ctl_ioctl_do_datamove(). Is there a
277 * XXX KDM may need to move this into a thread. We're doing a bcopy in the
278 * caller's context, which will usually be the backend. That may not be a
279 * good thing.
293 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; in cfcs_datamove()
297 * CCBs with "bad" flags are returned with CAM_REQ_INVALID. This in cfcs_datamove()
300 * support those modes of operation. in cfcs_datamove()
302 KASSERT(((ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS) == 0), ("invalid " in cfcs_datamove()
303 "CAM flags %#x", (ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS))); in cfcs_datamove()
307 * single entry S/G list. in cfcs_datamove()
309 switch ((ccb->ccb_h.flags & CAM_DATA_MASK)) { in cfcs_datamove()
313 cam_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr; in cfcs_datamove()
314 cam_sg_count = ccb->csio.sglist_cnt; in cfcs_datamove()
319 if ((len_seen + cam_sglist[i].ds_len) >= in cfcs_datamove()
320 io->scsiio.kern_rel_offset) { in cfcs_datamove()
322 cam_sg_offset = io->scsiio.kern_rel_offset - in cfcs_datamove()
326 len_seen += cam_sglist[i].ds_len; in cfcs_datamove()
332 cam_sglist[0].ds_len = ccb->csio.dxfer_len; in cfcs_datamove()
333 cam_sglist[0].ds_addr = (bus_addr_t)(uintptr_t)ccb->csio.data_ptr; in cfcs_datamove()
336 cam_sg_offset = io->scsiio.kern_rel_offset; in cfcs_datamove()
339 panic("Invalid CAM flags %#x", ccb->ccb_h.flags); in cfcs_datamove()
342 if (io->scsiio.kern_sg_entries > 0) { in cfcs_datamove()
343 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; in cfcs_datamove()
344 ctl_sg_count = io->scsiio.kern_sg_entries; in cfcs_datamove()
347 ctl_sglist->addr = io->scsiio.kern_data_ptr; in cfcs_datamove()
348 ctl_sglist->len = io->scsiio.kern_data_len; in cfcs_datamove()
358 len_to_copy = MIN(cam_sglist[i].ds_len - cam_watermark, in cfcs_datamove()
359 ctl_sglist[j].len - ctl_watermark); in cfcs_datamove()
361 cam_ptr = (uint8_t *)(uintptr_t)cam_sglist[i].ds_addr; in cfcs_datamove()
363 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) { in cfcs_datamove()
369 kern_ptr = bus_to_virt(kern_sglist[j].addr); in cfcs_datamove()
372 ctl_ptr = (uint8_t *)ctl_sglist[j].addr; in cfcs_datamove()
375 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == in cfcs_datamove()
390 io->scsiio.ext_data_filled += len_to_copy; in cfcs_datamove()
391 io->scsiio.kern_data_resid -= len_to_copy; in cfcs_datamove()
394 if (cam_sglist[i].ds_len == cam_watermark) { in cfcs_datamove()
400 if (ctl_sglist[j].len == ctl_watermark) { in cfcs_datamove()
406 if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) { in cfcs_datamove()
407 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = NULL; in cfcs_datamove()
408 io->io_hdr.flags |= CTL_FLAG_STATUS_SENT; in cfcs_datamove()
409 ccb->csio.resid = ccb->csio.dxfer_len - in cfcs_datamove()
410 io->scsiio.ext_data_filled; in cfcs_datamove()
411 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in cfcs_datamove()
412 ccb->ccb_h.status |= CAM_REQ_CMP; in cfcs_datamove()
424 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; in cfcs_done()
431 * At this point we should have status. If we don't, that's a bug. in cfcs_done()
433 KASSERT(((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE), in cfcs_done()
434 ("invalid CTL status %#x", io->io_hdr.status)); in cfcs_done()
437 * Translate CTL status to CAM status. in cfcs_done()
439 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in cfcs_done()
440 ccb->csio.resid = ccb->csio.dxfer_len - in cfcs_done()
441 io->scsiio.ext_data_filled; in cfcs_done()
443 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in cfcs_done()
444 switch (io->io_hdr.status & CTL_STATUS_MASK) { in cfcs_done()
446 ccb->ccb_h.status |= CAM_REQ_CMP; in cfcs_done()
449 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; in cfcs_done()
450 ccb->csio.scsi_status = io->scsiio.scsi_status; in cfcs_done()
451 bcopy(&io->scsiio.sense_data, &ccb->csio.sense_data, in cfcs_done()
452 min(io->scsiio.sense_len, ccb->csio.sense_len)); in cfcs_done()
453 if (ccb->csio.sense_len > io->scsiio.sense_len) in cfcs_done()
454 ccb->csio.sense_resid = ccb->csio.sense_len - in cfcs_done()
455 io->scsiio.sense_len; in cfcs_done()
457 ccb->csio.sense_resid = 0; in cfcs_done()
458 if ((ccb->csio.sense_len - ccb->csio.sense_resid) > in cfcs_done()
460 ccb->csio.sense_resid = ccb->csio.sense_len - in cfcs_done()
465 ccb->ccb_h.status |= CAM_REQ_ABORTED; in cfcs_done()
469 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; in cfcs_done()
473 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP && in cfcs_done()
474 (ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { in cfcs_done()
475 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_done()
476 ccb->ccb_h.status |= CAM_DEV_QFRZN; in cfcs_done()
489 switch (ccb->ccb_h.func_code) { in cfcs_action()
498 * indicate situations we currently can't handle. in cfcs_action()
500 if (ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS) { in cfcs_action()
501 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
503 __func__, ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS, in cfcs_action()
504 ccb->ccb_h.flags); in cfcs_action()
510 * If we aren't online, there are no devices to see. in cfcs_action()
513 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
518 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
521 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
522 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
528 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
529 ccb->ccb_h.io_ptr = io; in cfcs_action()
532 * Only SCSI I/O comes down this path, resets, etc. come in cfcs_action()
533 * down via the XPT_RESET_BUS/LUN CCBs below. in cfcs_action()
535 io->io_hdr.io_type = CTL_IO_SCSI; in cfcs_action()
536 io->io_hdr.nexus.initid = 1; in cfcs_action()
537 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
538 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
539 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
540 io->scsiio.priority = csio->priority; in cfcs_action()
544 * in a high I/O environment. But it should work well in cfcs_action()
545 * enough for now. Since we're using unsigned ints, in cfcs_action()
546 * they'll just wrap around. in cfcs_action()
548 io->scsiio.tag_num = atomic_fetchadd_32(&softc->cur_tag_num, 1); in cfcs_action()
549 csio->tag_id = io->scsiio.tag_num; in cfcs_action()
552 io->scsiio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
555 io->scsiio.tag_type = CTL_TAG_SIMPLE; in cfcs_action()
558 io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE; in cfcs_action()
561 io->scsiio.tag_type = CTL_TAG_ORDERED; in cfcs_action()
564 io->scsiio.tag_type = CTL_TAG_ACA; in cfcs_action()
567 io->scsiio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
572 if (csio->cdb_len > sizeof(io->scsiio.cdb)) { in cfcs_action()
574 __func__, csio->cdb_len, sizeof(io->scsiio.cdb)); in cfcs_action()
576 io->scsiio.cdb_len = min(csio->cdb_len, sizeof(io->scsiio.cdb)); in cfcs_action()
577 bcopy(scsiio_cdb_ptr(csio), io->scsiio.cdb, io->scsiio.cdb_len); in cfcs_action()
579 ccb->ccb_h.status |= CAM_SIM_QUEUED; in cfcs_action()
584 ccb->ccb_h.func_code, err); in cfcs_action()
586 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
596 abort_ccb = ccb->cab.abort_ccb; in cfcs_action()
598 if (abort_ccb->ccb_h.func_code != XPT_SCSI_IO) { in cfcs_action()
599 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
604 * If we aren't online, there are no devices to talk to. in cfcs_action()
607 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
612 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
614 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
615 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
622 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
623 ccb->ccb_h.io_ptr = io; in cfcs_action()
625 io->io_hdr.io_type = CTL_IO_TASK; in cfcs_action()
626 io->io_hdr.nexus.initid = 1; in cfcs_action()
627 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
628 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
629 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
630 io->taskio.task_action = CTL_TASK_ABORT_TASK; in cfcs_action()
631 io->taskio.tag_num = abort_ccb->csio.tag_id; in cfcs_action()
632 switch (abort_ccb->csio.tag_action) { in cfcs_action()
634 io->taskio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
637 io->taskio.tag_type = CTL_TAG_SIMPLE; in cfcs_action()
640 io->taskio.tag_type = CTL_TAG_HEAD_OF_QUEUE; in cfcs_action()
643 io->taskio.tag_type = CTL_TAG_ORDERED; in cfcs_action()
646 io->taskio.tag_type = CTL_TAG_ACA; in cfcs_action()
649 io->taskio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
651 abort_ccb->csio.tag_action); in cfcs_action()
658 ccb->ccb_h.func_code, err); in cfcs_action()
669 scsi = &cts->proto_specific.scsi; in cfcs_action()
670 fc = &cts->xport_specific.fc; in cfcs_action()
684 fc->port = softc->port.targ_port; in cfcs_action()
687 ccb->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
692 ccb->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
699 * If we aren't online, there are no devices to talk to. in cfcs_action()
702 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
707 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
709 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
710 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
717 if (ccb->ccb_h.func_code == XPT_RESET_DEV) in cfcs_action()
718 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
719 ccb->ccb_h.io_ptr = io; in cfcs_action()
721 io->io_hdr.io_type = CTL_IO_TASK; in cfcs_action()
722 io->io_hdr.nexus.initid = 1; in cfcs_action()
723 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
724 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
725 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
726 if (ccb->ccb_h.func_code == XPT_RESET_BUS) in cfcs_action()
727 io->taskio.task_action = CTL_TASK_BUS_RESET; in cfcs_action()
729 io->taskio.task_action = CTL_TASK_LUN_RESET; in cfcs_action()
735 ccb->ccb_h.func_code, err); in cfcs_action()
771 * Pretend to be Fibre Channel. in cfcs_action()
775 cpi->xport_specific.fc.wwnn = softc->wwnn; in cfcs_action()
776 cpi->xport_specific.fc.wwpn = softc->wwpn; in cfcs_action()
777 cpi->xport_specific.fc.port = softc->port.targ_port; in cfcs_action()
778 cpi->xport_specific.fc.bitrate = 8 * 1000 * 1000; in cfcs_action()
779 cpi->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
783 ccb->ccb_h.status = CAM_PROVIDE_FAIL; in cfcs_action()
785 ccb->ccb_h.func_code); in cfcs_action()