Lines Matching +full:test2 +full:. +full:good
4 * Copyright (c) 2008, 2009 Silicon Graphics International Corp.
5 * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org>
6 * All rights reserved.
11 * 1. Redistributions of source code must retain the above copyright
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * binary redistribution.
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * POSSIBILITY OF SUCH DAMAGES.
33 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/scsi_ctl.c#4 $
36 * Peripheral driver interface between CAM and CTL (CAM Target Layer).
38 * Author: Ken Merry <ken@FreeBSD.org>
41 #include <sys/param.h>
42 #include <sys/queue.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/condvar.h>
48 #include <sys/malloc.h>
49 #include <sys/bus.h>
50 #include <sys/endian.h>
51 #include <sys/sbuf.h>
52 #include <sys/sysctl.h>
53 #include <sys/types.h>
54 #include <sys/systm.h>
55 #include <sys/taskqueue.h>
56 #include <machine/bus.h>
58 #include <cam/cam.h>
59 #include <cam/cam_ccb.h>
60 #include <cam/cam_periph.h>
61 #include <cam/cam_queue.h>
62 #include <cam/cam_xpt_periph.h>
63 #include <cam/cam_debug.h>
64 #include <cam/cam_sim.h>
65 #include <cam/cam_xpt.h>
67 #include <cam/scsi/scsi_all.h>
68 #include <cam/scsi/scsi_message.h>
70 #include <cam/ctl/ctl_io.h>
71 #include <cam/ctl/ctl.h>
72 #include <cam/ctl/ctl_frontend.h>
73 #include <cam/ctl/ctl_util.h>
74 #include <cam/ctl/ctl_error.h>
108 LIST_HEAD(, ccb_hdr) atio_list; /* List of ATIOs queued to SIM. */
109 LIST_HEAD(, ccb_hdr) inot_list; /* List of INOTs queued to SIM. */
124 * bytes on amd64. So with 32 elements, this is 256 bytes on
125 * i386 and 512 bytes on amd64.
133 * allocated. This should be the maximum supported by the adapter, but we
134 * currently don't have a way to get that back from the path inquiry.
135 * XXX KDM add that to the path inquiry.
140 * adapter per LUN.
145 * Number of Immediate Notify CCBs (used for aborts, resets, etc.) to
146 * allocate and queue down to the adapter per LUN.
157 * Turn this on to enable extra debugging prints.
170 #define PRIV_CCB(io) ((io)->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptrs[0])
171 #define PRIV_INFO(io) ((io)->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptrs[1])
204 TAILQ_HEAD_INITIALIZER(ctlfe_driver.units), /*generation*/ 0,
211 .name = "camtgt",
212 .init = ctlfeinitialize,
213 .fe_dump = ctlfe_dump,
214 .shutdown = ctlfeshutdown,
257 /* XXX: It would be good to tear down active ports here. */
258 if (!TAILQ_EMPTY(&ctlfe_driver.units))
282 * mode, go ahead and attach. Later on, we may need to be more
283 * selective, but for now this will be sufficient.
312 * use M_NOWAIT. Of course this means trouble if we
313 * can't allocate memory.
322 softc->path_id = cpi->ccb_h.path_id;
352 * frontend structure itself.
433 "remove", softc->port.targ_port,
469 /* Increase device openings to maximum for the SIM. */
480 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NONE);
481 ccb.ccb_h.func_code = XPT_EN_LUN;
482 ccb.cel.grp6_len = 0;
483 ccb.cel.grp7_len = 0;
484 ccb.cel.enable = 1;
486 status = (ccb.ccb_h.status & CAM_STATUS_MASK);
489 __func__, ccb.ccb_h.status);
506 new_io = ctl_alloc_io_nowait(bus_softc->port.ctl_pool_ref);
522 new_ccb->ccb_h.io_ptr = new_io;
523 LIST_INSERT_HEAD(&softc->atio_list, &new_ccb->ccb_h, periph_links.le);
526 new_ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
527 new_ccb->ccb_h.cbfcnp = ctlfedone;
528 new_ccb->ccb_h.flags |= CAM_UNLOCKED;
530 status = new_ccb->ccb_h.status;
562 new_io = ctl_alloc_io_nowait(bus_softc->port.ctl_pool_ref);
569 new_ccb->ccb_h.io_ptr = new_io;
570 LIST_INSERT_HEAD(&softc->inot_list, &new_ccb->ccb_h, periph_links.le);
573 new_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
574 new_ccb->ccb_h.cbfcnp = ctlfedone;
575 new_ccb->ccb_h.flags |= CAM_UNLOCKED;
577 status = new_ccb->ccb_h.status;
580 * Note that we don't free the CCB here. If the
584 * XPT_IMMEDIATE_NOTIFY CCB. i.e. it supports the
585 * older API. In that case, it'll call xpt_done()
587 * routine as a result.
613 /* Abort all ATIOs and INOTs queued to SIM. */
615 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NONE);
616 ccb.ccb_h.func_code = XPT_ABORT;
617 LIST_FOREACH(hdr, &softc->atio_list, periph_links.le) {
618 ccb.cab.abort_ccb = (union ccb *)hdr;
621 LIST_FOREACH(hdr, &softc->inot_list, periph_links.le) {
622 ccb.cab.abort_ccb = (union ccb *)hdr;
626 /* Disable the LUN in SIM. */
627 ccb.ccb_h.func_code = XPT_EN_LUN;
628 ccb.cel.grp6_len = 0;
629 ccb.cel.grp7_len = 0;
630 ccb.cel.enable = 0;
632 status = (ccb.ccb_h.status & CAM_STATUS_MASK);
635 __func__, ccb.ccb_h.status);
682 * Set the direction, relative to the initiator.
685 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN)
694 if (io->scsiio.kern_sg_entries == 0) { /* No S/G list. */
696 /* One time shift for SRR offset. */
697 off += io->scsiio.ext_data_filled;
698 io->scsiio.ext_data_filled = 0;
700 *data_ptr = io->scsiio.kern_data_ptr + off;
701 if (io->scsiio.kern_data_len - off <= bus_softc->maxio) {
702 *dxfer_len = io->scsiio.kern_data_len - off;
710 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
714 } else { /* S/G list with physical or virtual pointers. */
715 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
717 /* One time shift for SRR offset. */
718 while (io->scsiio.ext_data_filled >= ctl_sglist[idx].len - off) {
719 io->scsiio.ext_data_filled -= ctl_sglist[idx].len - off;
723 off += io->scsiio.ext_data_filled;
724 io->scsiio.ext_data_filled = 0;
728 for (i = 0; i < io->scsiio.kern_sg_entries - idx; i++) {
729 cam_sglist[i].ds_addr = (bus_addr_t)(uintptr_t)ctl_sglist[i + idx].addr + off;
730 if (ctl_sglist[i + idx].len - off <= bus_softc->maxio - *dxfer_len) {
731 cam_sglist[i].ds_len = ctl_sglist[idx + i].len - off;
732 *dxfer_len += cam_sglist[i].ds_len;
734 cam_sglist[i].ds_len = bus_softc->maxio - *dxfer_len;
736 cmd_info->cur_transfer_off = cam_sglist[i].ds_len + off;
738 *dxfer_len += cam_sglist[i].ds_len;
739 if (ctl_sglist[i].len != 0)
744 idx + i < (io->scsiio.kern_sg_entries - 1)) {
754 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
785 STAILQ_REMOVE_HEAD(&softc->work_queue, periph_links.stqe);
790 flags = atio->ccb_h.flags &
797 if (io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) {
799 * Datamove call, we need to setup the S/G list.
805 * We're done, send status back.
807 if ((io->io_hdr.flags & CTL_FLAG_ABORT) &&
808 (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) {
809 io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED;
815 KASSERT(atio->ccb_h.func_code == XPT_ACCEPT_TARGET_IO,
816 ("func_code %#x is not ATIO", atio->ccb_h.func_code));
817 start_ccb->ccb_h.func_code = XPT_ABORT;
818 start_ccb->cab.abort_ccb = (union ccb *)atio;
824 /* XPT_ABORT is not queued, so we can take next I/O. */
832 if ((io->io_hdr.flags & CTL_FLAG_STATUS_QUEUED) &&
834 ((io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) == 0 ||
835 io->io_hdr.status == CTL_SUCCESS)) {
837 scsi_status = io->scsiio.scsi_status;
838 csio->sense_len = io->scsiio.sense_len;
841 atio->tag_id, io->io_hdr.status);
844 csio->sense_data = io->scsiio.sense_data;
880 atio->tag_id, io->io_hdr.status);
894 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
895 start_ccb->ccb_h.ccb_atio = atio;
896 if (io->io_hdr.flags & CTL_FLAG_DMA_QUEUED)
897 io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;
898 io->io_hdr.flags &= ~(CTL_FLAG_DMA_QUEUED | CTL_FLAG_STATUS_QUEUED);
908 * If we still have work to do, ask for another CCB.
937 io = ccb->ccb_h.io_ptr;
939 switch (ccb->ccb_h.func_code) {
963 * reference on the peripheral driver. It will probably go away
964 * now.
978 * Send the ATIO/INOT back to the SIM, or free it if periph was invalidated.
994 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO)
995 LIST_INSERT_HEAD(&softc->atio_list, &ccb->ccb_h, periph_links.le);
997 LIST_INSERT_HEAD(&softc->inot_list, &ccb->ccb_h, periph_links.le);
1003 * target/lun. Reset the target and LUN fields back to the wildcard
1004 * values before we send them back down to the SIM.
1007 ccb->ccb_h.flags);
1090 KASSERT((done_ccb->ccb_h.flags & CAM_UNLOCKED) != 0,
1094 done_ccb->ccb_h.func_code);
1098 * At this point CTL has no known use case for device queue freezes.
1099 * In case some SIM think different -- drop its freeze right here.
1101 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1107 done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
1115 switch (done_ccb->ccb_h.func_code) {
1117 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
1119 status = atio->ccb_h.status & CAM_STATUS_MASK;
1128 * datamove or done.
1131 io = done_ccb->ccb_h.io_ptr;
1138 done_ccb->ccb_h.io_ptr = io;
1141 * Only SCSI I/O comes down this path, resets, etc. come
1142 * down the immediate notify path below.
1144 io->io_hdr.io_type = CTL_IO_SCSI;
1145 io->io_hdr.nexus.initid = atio->init_id;
1146 io->io_hdr.nexus.targ_port = bus_softc->port.targ_port;
1148 io->io_hdr.nexus.targ_lun = ctl_decode_lun(
1149 CAM_EXTLUN_BYTE_SWIZZLE(atio->ccb_h.target_lun));
1151 io->io_hdr.nexus.targ_lun = atio->ccb_h.target_lun;
1153 io->scsiio.priority = atio->priority;
1154 io->scsiio.tag_num = atio->tag_id;
1157 io->scsiio.tag_type = CTL_TAG_UNTAGGED;
1160 io->scsiio.tag_type = CTL_TAG_SIMPLE;
1163 io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE;
1166 io->scsiio.tag_type = CTL_TAG_ORDERED;
1169 io->scsiio.tag_type = CTL_TAG_ACA;
1172 io->scsiio.tag_type = CTL_TAG_UNTAGGED;
1177 if (atio->cdb_len > sizeof(io->scsiio.cdb)) {
1179 __func__, atio->cdb_len, sizeof(io->scsiio.cdb));
1181 io->scsiio.cdb_len = min(atio->cdb_len, sizeof(io->scsiio.cdb));
1182 bcopy(atio_cdb_ptr(atio), io->scsiio.cdb, io->scsiio.cdb_len);
1186 io->io_hdr.nexus.initid,
1187 io->io_hdr.nexus.targ_port,
1188 io->io_hdr.nexus.targ_lun,
1189 io->scsiio.tag_num, io->scsiio.cdb[0]);
1199 atio = (struct ccb_accept_tio *)done_ccb->ccb_h.ccb_atio;
1200 io = (union ctl_io *)atio->ccb_h.io_ptr;
1205 __func__, atio->tag_id, done_ccb->ccb_h.flags);
1210 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_MESSAGE_RECV
1211 && done_ccb->csio.msg_ptr != NULL
1212 && done_ccb->csio.msg_ptr[0] == MSG_EXTENDED
1213 && done_ccb->csio.msg_ptr[1] == 5
1214 && done_ccb->csio.msg_ptr[2] == 0) {
1217 (done_ccb->csio.msg_ptr[3] << 24)
1218 | (done_ccb->csio.msg_ptr[4] << 16)
1219 | (done_ccb->csio.msg_ptr[5] << 8)
1220 | (done_ccb->csio.msg_ptr[6]);
1225 * should be able to adjust offsets and cycle again.
1226 * It is possible only if offset is from this datamove.
1228 if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) &&
1229 srr_off >= io->scsiio.kern_rel_offset &&
1230 srr_off < io->scsiio.kern_rel_offset +
1231 io->scsiio.kern_data_len) {
1232 io->scsiio.kern_data_resid =
1233 io->scsiio.kern_rel_offset +
1234 io->scsiio.kern_data_len - srr_off;
1235 io->scsiio.ext_data_filled = srr_off;
1236 io->scsiio.io_hdr.status = CTL_STATUS_NONE;
1237 io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED;
1240 periph_links.stqe);
1246 * If status was being sent, the back end data is now history.
1247 * Hack it up and resubmit a new command with the CDB adjusted.
1249 * should work.
1251 if (srr && (io->io_hdr.flags & CTL_FLAG_DMA_INPROG) == 0) {
1258 * Fall through to doom....
1262 if ((done_ccb->ccb_h.flags & CAM_SEND_STATUS) &&
1263 (done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
1264 io->io_hdr.flags |= CTL_FLAG_STATUS_SENT;
1268 * resources. If we were doing a datamove, call the
1269 * datamove done routine.
1271 if ((io->io_hdr.flags & CTL_FLAG_DMA_INPROG) == 0) {
1274 * queue the I/O back to CTL for later REQUEST SENSE.
1276 if ((done_ccb->ccb_h.flags & CAM_SEND_SENSE) != 0 &&
1277 (done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
1278 (done_ccb->ccb_h.status & CAM_SENT_SENSE) == 0 &&
1279 (io = ctl_alloc_io_nowait(bus_softc->port.ctl_pool_ref)) != NULL) {
1281 (union ctl_io *)atio->ccb_h.io_ptr);
1282 ctl_queue_sense(atio->ccb_h.io_ptr);
1283 atio->ccb_h.io_ptr = io;
1286 /* Abort ATIO if CTIO sending status has failed. */
1287 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) !=
1289 done_ccb->ccb_h.func_code = XPT_ABORT;
1290 done_ccb->cab.abort_ccb = (union ccb *)atio;
1305 io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG;
1308 * Translate CAM status to CTL status. Success
1309 * does not change the overall, ctl_io status. In
1310 * that case we just set port_status to 0. If we
1312 * for the overall ctl_io.
1314 switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) {
1316 io->scsiio.kern_data_resid -=
1318 io->io_hdr.port_status = 0;
1325 * data transfer failure. A data phase
1327 * data transfer error of some sort.
1330 * a clue what happened.
1332 io->io_hdr.port_status = 0xbad1;
1335 * XXX KDM figure out residual.
1342 * continue sending pieces if necessary.
1345 io->io_hdr.port_status == 0 && csio->resid == 0) {
1350 flags = atio->ccb_h.flags &
1365 io->io_hdr.status);
1381 csio->ccb_h.flags |= CAM_UNLOCKED;
1383 csio->ccb_h.ccb_atio = atio;
1384 io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;
1390 * Release the CTIO. The ATIO will be sent back
1391 * down to the SIM once we send status.
1407 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
1409 io = done_ccb->ccb_h.io_ptr;
1414 io->io_hdr.io_type = CTL_IO_TASK;
1416 inot->ccb_h.io_ptr = io;
1417 io->io_hdr.nexus.initid = inot->initiator_id;
1418 io->io_hdr.nexus.targ_port = bus_softc->port.targ_port;
1420 io->io_hdr.nexus.targ_lun = ctl_decode_lun(
1421 CAM_EXTLUN_BYTE_SWIZZLE(inot->ccb_h.target_lun));
1423 io->io_hdr.nexus.targ_lun = inot->ccb_h.target_lun;
1426 io->taskio.tag_num = inot->seq_id;
1428 status = inot->ccb_h.status & CAM_STATUS_MASK;
1431 io->taskio.task_action = CTL_TASK_BUS_RESET;
1434 io->taskio.task_action = CTL_TASK_TARGET_RESET;
1439 io->taskio.task_action =
1443 io->taskio.task_action = CTL_TASK_TARGET_RESET;
1446 io->taskio.task_action = CTL_TASK_ABORT_TASK;
1449 io->taskio.task_action = CTL_TASK_LUN_RESET;
1452 io->taskio.task_action =
1456 io->taskio.task_action = CTL_TASK_CLEAR_ACA;
1459 io->taskio.task_action = CTL_TASK_QUERY_TASK;
1462 io->taskio.task_action =
1466 io->taskio.task_action =
1496 done_ccb->ccb_h.status = CAM_REQ_INPROG;
1497 done_ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
1503 /* Queue this back down to the SIM as an immediate notify. */
1504 done_ccb->ccb_h.status = CAM_REQ_INPROG;
1505 done_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
1514 done_ccb->ccb_h.func_code);
1539 ccb->ccb_h.func_code = XPT_GET_SIM_KNOB;
1542 /* Check whether we should change WWNs. */
1544 if ((ccb->knob.xport_specific.valid & KNOB_VALID_ADDRESS) != 0){
1547 ccb->knob.xport_specific.fc.wwnn);
1550 ccb->knob.xport_specific.fc.wwpn);
1554 * down to the SIM. Otherwise, record what the SIM
1555 * has reported.
1557 if (bus_softc->port.wwnn != 0 && bus_softc->port.wwnn
1558 != ccb->knob.xport_specific.fc.wwnn) {
1559 ccb->knob.xport_specific.fc.wwnn =
1560 bus_softc->port.wwnn;
1564 true, ccb->knob.xport_specific.fc.wwnn,
1567 if (bus_softc->port.wwpn != 0 && bus_softc->port.wwpn
1568 != ccb->knob.xport_specific.fc.wwpn) {
1569 ccb->knob.xport_specific.fc.wwpn =
1570 bus_softc->port.wwpn;
1575 true, ccb->knob.xport_specific.fc.wwpn);
1580 if (bus_softc->port.wwnn != 0) {
1581 ccb->knob.xport_specific.fc.wwnn =
1582 bus_softc->port.wwnn;
1585 if (bus_softc->port.wwpn != 0) {
1586 ccb->knob.xport_specific.fc.wwpn =
1587 bus_softc->port.wwpn;
1593 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
1594 ccb->knob.xport_specific.valid = KNOB_VALID_ADDRESS;
1596 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1599 ccb->ccb_h.status);
1603 ccb->knob.xport_specific.fc.wwnn);
1606 ccb->knob.xport_specific.fc.wwpn);
1610 /* Check whether we should change role. */
1611 if ((ccb->knob.xport_specific.valid & KNOB_VALID_ROLE) == 0 ||
1613 ((ccb->knob.xport_specific.fc.role & KNOB_ROLE_TARGET) != 0)) != 0) {
1614 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB;
1615 ccb->knob.xport_specific.valid = KNOB_VALID_ROLE;
1617 ccb->knob.xport_specific.fc.role |= KNOB_ROLE_TARGET;
1619 ccb->knob.xport_specific.fc.role &= ~KNOB_ROLE_TARGET;
1621 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1624 online ? "enable" : "disable", ccb->ccb_h.status);
1648 * Create the wildcard LUN before bringing the port online.
1664 /* We've already got a periph, no need to alloc a new one. */
1713 * the port offline.
1732 * CTL. So we only need to create a path/periph for this particular bus.
1760 /* We've already got a periph, no need to alloc a new one. */
1796 * on every bus that is attached to CTL.
1844 * Assumes that the SIM lock is held.
1855 xpt_setup_ccb(&cgds.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1856 cgds.ccb_h.func_code = XPT_GDEV_STATS;
1858 if ((cgds.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1861 cgds.dev_openings, cgds.dev_active, cgds.allocated,
1862 cgds.queued, cgds.held);
1867 STAILQ_FOREACH(hdr, &softc->work_queue, periph_links.stqe) {
1874 * queue, so we can print sense here. There may be no
1876 * print out the CCB as well.
1879 * CTL is merged in with CAM.
1884 * Print DMA status if we are DMA_QUEUED.
1886 if (io->io_hdr.flags & CTL_FLAG_DMA_QUEUED) {
1889 io->scsiio.kern_total_len,
1890 io->scsiio.kern_data_len,
1891 io->scsiio.kern_data_resid);
1900 * Datamove/done routine called by CTL. Put ourselves on the queue to
1902 * to the adapter.
1913 io->scsiio.ext_data_filled = 0;
1915 periph = xpt_path_periph(ccb->ccb_h.path);
1918 io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED;
1919 if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
1920 io->io_hdr.flags |= CTL_FLAG_STATUS_QUEUED;
1922 periph_links.stqe);
1935 periph = xpt_path_periph(ccb->ccb_h.path);
1939 if (io->io_hdr.io_type == CTL_IO_TASK) {
1942 * know we processed the task management command.
1944 ccb->ccb_h.status = CAM_REQ_INPROG;
1945 ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE;
1946 switch (io->taskio.task_status) {
1948 ccb->cna2.arg = CAM_RSP_TMF_COMPLETE;
1951 ccb->cna2.arg = CAM_RSP_TMF_SUCCEEDED;
1952 ccb->ccb_h.flags |= CAM_SEND_STATUS;
1955 ccb->cna2.arg = CAM_RSP_TMF_REJECTED;
1956 ccb->ccb_h.flags |= CAM_SEND_STATUS;
1959 ccb->cna2.arg = CAM_RSP_TMF_INCORRECT_LUN;
1960 ccb->ccb_h.flags |= CAM_SEND_STATUS;
1963 ccb->cna2.arg = CAM_RSP_TMF_FAILED;
1964 ccb->ccb_h.flags |= CAM_SEND_STATUS;
1967 ccb->cna2.arg |= scsi_3btoul(io->taskio.task_resp) << 8;
1969 } else if (io->io_hdr.flags & CTL_FLAG_STATUS_SENT) {
1973 io->io_hdr.flags |= CTL_FLAG_STATUS_QUEUED;
1975 periph_links.stqe);