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/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/types.h>
45 #include <sys/malloc.h>
46 #include <sys/bus.h>
47 #include <sys/sysctl.h>
48 #include <machine/atomic.h>
49 #include <machine/bus.h>
50 #include <sys/sbuf.h>
52 #include <cam/cam.h>
53 #include <cam/cam_ccb.h>
54 #include <cam/cam_sim.h>
55 #include <cam/cam_xpt_sim.h>
56 #include <cam/cam_xpt.h>
57 #include <cam/cam_periph.h>
58 #include <cam/scsi/scsi_all.h>
59 #include <cam/scsi/scsi_message.h>
60 #include <cam/ctl/ctl_io.h>
61 #include <cam/ctl/ctl.h>
62 #include <cam/ctl/ctl_frontend.h>
63 #include <cam/ctl/ctl_debug.h>
84 * We can't handle CCBs with these flags. For the most part, we just don't
85 * handle physical addresses yet. That would require mapping things in
86 * order to do the copy.
103 * sense data and sense residual handling code. This sets the maximum
104 * amount of SCSI sense data that we will report to CAM.
115 .name = "camsim",
116 .init = cfcs_init,
117 .shutdown = cfcs_shutdown,
154 * ahead and set something random. in cfcs_init()
250 if (xpt_create_path(&ccb->ccb_h.path, NULL, in cfcs_onoffline()
273 * This function is very similar to ctl_ioctl_do_datamove(). Is there a
276 * XXX KDM may need to move this into a thread. We're doing a bcopy in the
277 * caller's context, which will usually be the backend. That may not be a
278 * good thing.
292 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; in cfcs_datamove()
296 * CCBs with "bad" flags are returned with CAM_REQ_INVALID. This in cfcs_datamove()
299 * support those modes of operation. in cfcs_datamove()
301 KASSERT(((ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS) == 0), ("invalid " in cfcs_datamove()
302 "CAM flags %#x", (ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS))); in cfcs_datamove()
306 * single entry S/G list. in cfcs_datamove()
308 switch ((ccb->ccb_h.flags & CAM_DATA_MASK)) { in cfcs_datamove()
312 cam_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr; in cfcs_datamove()
313 cam_sg_count = ccb->csio.sglist_cnt; in cfcs_datamove()
318 if ((len_seen + cam_sglist[i].ds_len) >= in cfcs_datamove()
319 io->scsiio.kern_rel_offset) { in cfcs_datamove()
321 cam_sg_offset = io->scsiio.kern_rel_offset - in cfcs_datamove()
325 len_seen += cam_sglist[i].ds_len; in cfcs_datamove()
331 cam_sglist[0].ds_len = ccb->csio.dxfer_len; in cfcs_datamove()
332 cam_sglist[0].ds_addr = (bus_addr_t)(uintptr_t)ccb->csio.data_ptr; in cfcs_datamove()
335 cam_sg_offset = io->scsiio.kern_rel_offset; in cfcs_datamove()
338 panic("Invalid CAM flags %#x", ccb->ccb_h.flags); in cfcs_datamove()
341 if (io->scsiio.kern_sg_entries > 0) { in cfcs_datamove()
342 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; in cfcs_datamove()
343 ctl_sg_count = io->scsiio.kern_sg_entries; in cfcs_datamove()
346 ctl_sglist->addr = io->scsiio.kern_data_ptr; in cfcs_datamove()
347 ctl_sglist->len = io->scsiio.kern_data_len; in cfcs_datamove()
357 len_to_copy = MIN(cam_sglist[i].ds_len - cam_watermark, in cfcs_datamove()
358 ctl_sglist[j].len - ctl_watermark); in cfcs_datamove()
360 cam_ptr = (uint8_t *)(uintptr_t)cam_sglist[i].ds_addr; in cfcs_datamove()
362 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) { in cfcs_datamove()
368 kern_ptr = bus_to_virt(kern_sglist[j].addr); in cfcs_datamove()
371 ctl_ptr = (uint8_t *)ctl_sglist[j].addr; in cfcs_datamove()
374 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == in cfcs_datamove()
389 io->scsiio.ext_data_filled += len_to_copy; in cfcs_datamove()
390 io->scsiio.kern_data_resid -= len_to_copy; in cfcs_datamove()
393 if (cam_sglist[i].ds_len == cam_watermark) { in cfcs_datamove()
399 if (ctl_sglist[j].len == ctl_watermark) { in cfcs_datamove()
405 if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS) { in cfcs_datamove()
406 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = NULL; in cfcs_datamove()
407 io->io_hdr.flags |= CTL_FLAG_STATUS_SENT; in cfcs_datamove()
408 ccb->csio.resid = ccb->csio.dxfer_len - in cfcs_datamove()
409 io->scsiio.ext_data_filled; in cfcs_datamove()
410 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in cfcs_datamove()
411 ccb->ccb_h.status |= CAM_REQ_CMP; in cfcs_datamove()
423 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; in cfcs_done()
430 * At this point we should have status. If we don't, that's a bug. in cfcs_done()
432 KASSERT(((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE), in cfcs_done()
433 ("invalid CTL status %#x", io->io_hdr.status)); in cfcs_done()
436 * Translate CTL status to CAM status. in cfcs_done()
438 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in cfcs_done()
439 ccb->csio.resid = ccb->csio.dxfer_len - in cfcs_done()
440 io->scsiio.ext_data_filled; in cfcs_done()
442 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in cfcs_done()
443 switch (io->io_hdr.status & CTL_STATUS_MASK) { in cfcs_done()
445 ccb->ccb_h.status |= CAM_REQ_CMP; in cfcs_done()
448 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; in cfcs_done()
449 ccb->csio.scsi_status = io->scsiio.scsi_status; in cfcs_done()
450 bcopy(&io->scsiio.sense_data, &ccb->csio.sense_data, in cfcs_done()
451 min(io->scsiio.sense_len, ccb->csio.sense_len)); in cfcs_done()
452 if (ccb->csio.sense_len > io->scsiio.sense_len) in cfcs_done()
453 ccb->csio.sense_resid = ccb->csio.sense_len - in cfcs_done()
454 io->scsiio.sense_len; in cfcs_done()
456 ccb->csio.sense_resid = 0; in cfcs_done()
457 if ((ccb->csio.sense_len - ccb->csio.sense_resid) > in cfcs_done()
459 ccb->csio.sense_resid = ccb->csio.sense_len - in cfcs_done()
464 ccb->ccb_h.status |= CAM_REQ_ABORTED; in cfcs_done()
468 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; in cfcs_done()
472 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP && in cfcs_done()
473 (ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { in cfcs_done()
474 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_done()
475 ccb->ccb_h.status |= CAM_DEV_QFRZN; in cfcs_done()
488 switch (ccb->ccb_h.func_code) { in cfcs_action()
497 * indicate situations we currently can't handle. in cfcs_action()
499 if (ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS) { in cfcs_action()
500 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
502 __func__, ccb->ccb_h.flags & CFCS_BAD_CCB_FLAGS, in cfcs_action()
503 ccb->ccb_h.flags); in cfcs_action()
509 * If we aren't online, there are no devices to see. in cfcs_action()
512 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
517 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
520 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
521 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
527 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
528 ccb->ccb_h.io_ptr = io; in cfcs_action()
531 * Only SCSI I/O comes down this path, resets, etc. come in cfcs_action()
532 * down via the XPT_RESET_BUS/LUN CCBs below. in cfcs_action()
534 io->io_hdr.io_type = CTL_IO_SCSI; in cfcs_action()
535 io->io_hdr.nexus.initid = 1; in cfcs_action()
536 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
537 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
538 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
539 io->scsiio.priority = csio->priority; in cfcs_action()
543 * in a high I/O environment. But it should work well in cfcs_action()
544 * enough for now. Since we're using unsigned ints, in cfcs_action()
545 * they'll just wrap around. in cfcs_action()
547 io->scsiio.tag_num = atomic_fetchadd_32(&softc->cur_tag_num, 1); in cfcs_action()
548 csio->tag_id = io->scsiio.tag_num; in cfcs_action()
551 io->scsiio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
554 io->scsiio.tag_type = CTL_TAG_SIMPLE; in cfcs_action()
557 io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE; in cfcs_action()
560 io->scsiio.tag_type = CTL_TAG_ORDERED; in cfcs_action()
563 io->scsiio.tag_type = CTL_TAG_ACA; in cfcs_action()
566 io->scsiio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
571 if (csio->cdb_len > sizeof(io->scsiio.cdb)) { in cfcs_action()
573 __func__, csio->cdb_len, sizeof(io->scsiio.cdb)); in cfcs_action()
575 io->scsiio.cdb_len = min(csio->cdb_len, sizeof(io->scsiio.cdb)); in cfcs_action()
576 bcopy(scsiio_cdb_ptr(csio), io->scsiio.cdb, io->scsiio.cdb_len); in cfcs_action()
578 ccb->ccb_h.status |= CAM_SIM_QUEUED; in cfcs_action()
583 ccb->ccb_h.func_code, err); in cfcs_action()
585 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
595 abort_ccb = ccb->cab.abort_ccb; in cfcs_action()
597 if (abort_ccb->ccb_h.func_code != XPT_SCSI_IO) { in cfcs_action()
598 ccb->ccb_h.status = CAM_REQ_INVALID; in cfcs_action()
603 * If we aren't online, there are no devices to talk to. in cfcs_action()
606 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
611 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
613 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
614 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
621 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
622 ccb->ccb_h.io_ptr = io; in cfcs_action()
624 io->io_hdr.io_type = CTL_IO_TASK; in cfcs_action()
625 io->io_hdr.nexus.initid = 1; in cfcs_action()
626 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
627 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
628 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
629 io->taskio.task_action = CTL_TASK_ABORT_TASK; in cfcs_action()
630 io->taskio.tag_num = abort_ccb->csio.tag_id; in cfcs_action()
631 switch (abort_ccb->csio.tag_action) { in cfcs_action()
633 io->taskio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
636 io->taskio.tag_type = CTL_TAG_SIMPLE; in cfcs_action()
639 io->taskio.tag_type = CTL_TAG_HEAD_OF_QUEUE; in cfcs_action()
642 io->taskio.tag_type = CTL_TAG_ORDERED; in cfcs_action()
645 io->taskio.tag_type = CTL_TAG_ACA; in cfcs_action()
648 io->taskio.tag_type = CTL_TAG_UNTAGGED; in cfcs_action()
650 abort_ccb->csio.tag_action); in cfcs_action()
657 ccb->ccb_h.func_code, err); in cfcs_action()
668 scsi = &cts->proto_specific.scsi; in cfcs_action()
669 fc = &cts->xport_specific.fc; in cfcs_action()
683 fc->port = softc->port.targ_port; in cfcs_action()
686 ccb->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
691 ccb->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
698 * If we aren't online, there are no devices to talk to. in cfcs_action()
701 ccb->ccb_h.status = CAM_DEV_NOT_THERE; in cfcs_action()
706 io = ctl_alloc_io_nowait(softc->port.ctl_pool_ref); in cfcs_action()
708 ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; in cfcs_action()
709 xpt_freeze_devq(ccb->ccb_h.path, 1); in cfcs_action()
716 if (ccb->ccb_h.func_code == XPT_RESET_DEV) in cfcs_action()
717 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = ccb; in cfcs_action()
718 ccb->ccb_h.io_ptr = io; in cfcs_action()
720 io->io_hdr.io_type = CTL_IO_TASK; in cfcs_action()
721 io->io_hdr.nexus.initid = 1; in cfcs_action()
722 io->io_hdr.nexus.targ_port = softc->port.targ_port; in cfcs_action()
723 io->io_hdr.nexus.targ_lun = ctl_decode_lun( in cfcs_action()
724 CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); in cfcs_action()
725 if (ccb->ccb_h.func_code == XPT_RESET_BUS) in cfcs_action()
726 io->taskio.task_action = CTL_TASK_BUS_RESET; in cfcs_action()
728 io->taskio.task_action = CTL_TASK_LUN_RESET; in cfcs_action()
734 ccb->ccb_h.func_code, err); in cfcs_action()
770 * Pretend to be Fibre Channel. in cfcs_action()
774 cpi->xport_specific.fc.wwnn = softc->wwnn; in cfcs_action()
775 cpi->xport_specific.fc.wwpn = softc->wwpn; in cfcs_action()
776 cpi->xport_specific.fc.port = softc->port.targ_port; in cfcs_action()
777 cpi->xport_specific.fc.bitrate = 8 * 1000 * 1000; in cfcs_action()
778 cpi->ccb_h.status = CAM_REQ_CMP; in cfcs_action()
782 ccb->ccb_h.status = CAM_PROVIDE_FAIL; in cfcs_action()
784 ccb->ccb_h.func_code); in cfcs_action()