Lines Matching +full:is +full:- +full:wired

1 /*-
4 * SPDX-License-Identifier: BSD-2-Clause
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
65 u_int newunit, bool wired,
110 &periph_mapmem_thresh, 0, "Threshold for user-space buffer mapping");
143 /* If driver marked as early or it is late now, initialize it. */ in periphdriver_register()
144 if (((drv->flags & CAM_PERIPH_DRV_EARLY) != 0 && initialized > 0) || in periphdriver_register()
146 (*drv->init)(); in periphdriver_register()
155 /* If driver marked as early or it is late now, deinitialize it. */ in periphdriver_unregister()
156 if (((drv->flags & CAM_PERIPH_DRV_EARLY) != 0 && initialized > 0) || in periphdriver_unregister()
158 if (drv->deinit == NULL) { in periphdriver_unregister()
160 drv->driver_name); in periphdriver_unregister()
163 error = drv->deinit(); in periphdriver_unregister()
172 ("Periph driver '%s' was not registered", drv->driver_name)); in periphdriver_unregister()
176 nperiph_drivers--; in periphdriver_unregister()
188 early = (periph_drivers[i]->flags & CAM_PERIPH_DRV_EARLY) ? 1 : 2; in periphdriver_init()
190 (*periph_drivers[i]->init)(); in periphdriver_init()
213 * Handle Hot-Plug scenarios. If there is already a peripheral in cam_periph_alloc()
215 * final close on an old, invalidated, peripheral. If this is in cam_periph_alloc()
217 * handler. If it looks like a mistaken re-allocation, complain. in cam_periph_alloc()
220 if ((periph->flags & CAM_PERIPH_INVALID) != 0 in cam_periph_alloc()
221 && (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) == 0) { in cam_periph_alloc()
222 periph->flags |= CAM_PERIPH_NEW_DEV_FOUND; in cam_periph_alloc()
223 periph->deferred_callback = ac_callback; in cam_periph_alloc()
224 periph->deferred_ac = code; in cam_periph_alloc()
227 printf("cam_periph_alloc: attempt to re-allocate " in cam_periph_alloc()
229 "refcount %d\n", periph->periph_name, in cam_periph_alloc()
230 periph->unit_number, periph->flags, in cam_periph_alloc()
231 periph->refcount); in cam_periph_alloc()
248 periph->periph_start = periph_start; in cam_periph_alloc()
249 periph->periph_dtor = periph_dtor; in cam_periph_alloc()
250 periph->periph_oninval = periph_oninvalidate; in cam_periph_alloc()
251 periph->type = type; in cam_periph_alloc()
252 periph->periph_name = name; in cam_periph_alloc()
253 periph->scheduled_priority = CAM_PRIORITY_NONE; in cam_periph_alloc()
254 periph->immediate_priority = CAM_PRIORITY_NONE; in cam_periph_alloc()
255 periph->refcount = 1; /* Dropped by invalidation. */ in cam_periph_alloc()
256 periph->sim = sim; in cam_periph_alloc()
257 SLIST_INIT(&periph->ccb_list); in cam_periph_alloc()
261 periph->path = path; in cam_periph_alloc()
265 if (strcmp((*p_drv)->driver_name, name) == 0) in cam_periph_alloc()
271 xpt_free_path(periph->path); in cam_periph_alloc()
275 periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id, in cam_periph_alloc()
276 path->device->serial_num); in cam_periph_alloc()
277 cur_periph = TAILQ_FIRST(&(*p_drv)->units); in cam_periph_alloc()
279 && cur_periph->unit_number < periph->unit_number) in cam_periph_alloc()
282 KASSERT(cur_periph->unit_number != periph->unit_number, in cam_periph_alloc()
286 TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links); in cam_periph_alloc()
287 (*p_drv)->generation++; in cam_periph_alloc()
298 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph created\n")); in cam_periph_alloc()
311 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph destroyed\n")); in cam_periph_alloc()
316 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); in cam_periph_alloc()
318 xpt_free_path(periph->path); in cam_periph_alloc()
334 * and (optionally) type. If the name is NULL, this function will return
345 if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0)) in cam_periph_find()
348 TAILQ_FOREACH(periph, &(*p_drv)->units, unit_links) { in cam_periph_find()
349 if (xpt_path_comp(periph->path, path) == 0) { in cam_periph_find()
382 TAILQ_FOREACH(periph, &(*p_drv)->units, unit_links) { in cam_periph_list()
383 if (xpt_path_comp(periph->path, path) != 0) in cam_periph_list()
389 sbuf_printf(&local_sb, "%s%d", periph->periph_name, in cam_periph_list()
390 periph->unit_number); in cam_periph_list()
420 if ((periph->flags & CAM_PERIPH_INVALID) == 0) { in cam_periph_acquire()
421 periph->refcount++; in cam_periph_acquire()
434 KASSERT(periph->refcount >= 1, in cam_periph_doacquire()
435 ("cam_periph_doacquire() with refcount == %d", periph->refcount)); in cam_periph_doacquire()
436 periph->refcount++; in cam_periph_doacquire()
445 KASSERT(periph->refcount >= 1, ("periph->refcount >= 1")); in cam_periph_release_locked_buses()
446 if (--periph->refcount == 0) in cam_periph_release_locked_buses()
499 while ((periph->flags & CAM_PERIPH_LOCKED) != 0) { in cam_periph_hold()
500 periph->flags |= CAM_PERIPH_LOCK_WANTED; in cam_periph_hold()
506 if (periph->flags & CAM_PERIPH_INVALID) { in cam_periph_hold()
512 periph->flags |= CAM_PERIPH_LOCKED; in cam_periph_hold()
522 periph->flags &= ~CAM_PERIPH_LOCKED; in cam_periph_unhold()
523 if ((periph->flags & CAM_PERIPH_LOCK_WANTED) != 0) { in cam_periph_unhold()
524 periph->flags &= ~CAM_PERIPH_LOCK_WANTED; in cam_periph_unhold()
535 root_mount_hold_token(periph->periph_name, &periph->periph_rootmount); in cam_periph_hold_boot()
542 root_mount_rel(&periph->periph_rootmount); in cam_periph_release_boot()
546 * Look for the next unit number that is not currently in use for this
549 * is a potential wired device. Only assume that the device is "wired" the
554 camperiphnextunit(struct periph_driver *p_drv, u_int newunit, bool wired, in camperiphnextunit() argument
562 periph_name = p_drv->driver_name; in camperiphnextunit()
564 for (periph = TAILQ_FIRST(&p_drv->units); in camperiphnextunit()
565 periph != NULL && periph->unit_number != newunit; in camperiphnextunit()
569 if (periph != NULL && periph->unit_number == newunit) { in camperiphnextunit()
570 if (wired) { in camperiphnextunit()
571 xpt_print(periph->path, "Duplicate Wired " in camperiphnextunit()
573 xpt_print(periph->path, "Second device (%s " in camperiphnextunit()
575 "not be wired\n", periph_name, pathid, in camperiphnextunit()
577 wired = false; in camperiphnextunit()
581 if (wired) in camperiphnextunit()
586 * means that it is for a wired down entry. Instead, insist that in camperiphnextunit()
615 bool wired = false; in camperiphunit() local
621 periph_name = p_drv->driver_name; in camperiphunit()
627 for (wired = false; resource_find_dev(&i, dname, &dunit, NULL, NULL) == 0; in camperiphunit()
628 wired = false) { in camperiphunit()
632 wired = true; in camperiphunit()
637 wired = true; in camperiphunit()
642 wired = true; in camperiphunit()
647 wired = true; in camperiphunit()
649 if (wired) { in camperiphunit()
661 unit = camperiphnextunit(p_drv, unit, wired, pathid, target, lun); in camperiphunit()
672 * We only tear down the device the first time a peripheral is in cam_periph_invalidate()
675 if ((periph->flags & CAM_PERIPH_INVALID) != 0) in cam_periph_invalidate()
678 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n")); in cam_periph_invalidate()
679 if ((periph->flags & CAM_PERIPH_ANNOUNCED) && !rebooting) { in cam_periph_invalidate()
688 periph->flags |= CAM_PERIPH_INVALID; in cam_periph_invalidate()
689 periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND; in cam_periph_invalidate()
690 if (periph->periph_oninval != NULL) in cam_periph_invalidate()
691 periph->periph_oninval(periph); in cam_periph_invalidate()
702 KASSERT(periph->periph_allocating == 0, ("%s%d: freed while allocating", in camperiphfree()
703 periph->periph_name, periph->unit_number)); in camperiphfree()
705 if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0) in camperiphfree()
709 printf("camperiphfree: attempt to free non-existant periph\n"); in camperiphfree()
714 * periph_driver is added or removed from the array (see in camperiphfree()
724 * let anyone who is traversing the list that this peripheral is in camperiphfree()
728 periph->flags |= CAM_PERIPH_FREE; in camperiphfree()
744 * aren't fully cleaned up until the destructor is run. If the in camperiphfree()
745 * unit number is reused before the devfs instance is fully gone, in camperiphfree()
748 if (periph->periph_dtor != NULL) in camperiphfree()
749 periph->periph_dtor(periph); in camperiphfree()
752 * The peripheral list is protected by the topology lock. We have to in camperiphfree()
758 TAILQ_REMOVE(&drv->units, periph, unit_links); in camperiphfree()
759 drv->generation++; in camperiphfree()
764 if ((periph->flags & CAM_PERIPH_ANNOUNCED) && !rebooting) in camperiphfree()
765 xpt_print(periph->path, "Periph destroyed\n"); in camperiphfree()
767 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph destroyed\n")); in camperiphfree()
769 if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) { in camperiphfree()
774 switch (periph->deferred_ac) { in camperiphfree()
777 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); in camperiphfree()
782 xpt_path_inq(&ccb.cpi, periph->path); in camperiphfree()
789 periph->deferred_callback(NULL, periph->deferred_ac, in camperiphfree()
790 periph->path, arg); in camperiphfree()
792 xpt_free_path(periph->path); in camperiphfree()
799 * access the memory. This is now a generic function that centralizes most
818 switch(ccb->ccb_h.func_code) { in cam_periph_mapmem()
820 if (ccb->cdm.match_buf_len == 0) { in cam_periph_mapmem()
825 if (ccb->cdm.pattern_buf_len > 0) { in cam_periph_mapmem()
826 data_ptrs[0] = (uint8_t **)&ccb->cdm.patterns; in cam_periph_mapmem()
827 lengths[0] = ccb->cdm.pattern_buf_len; in cam_periph_mapmem()
829 data_ptrs[1] = (uint8_t **)&ccb->cdm.matches; in cam_periph_mapmem()
830 lengths[1] = ccb->cdm.match_buf_len; in cam_periph_mapmem()
834 data_ptrs[0] = (uint8_t **)&ccb->cdm.matches; in cam_periph_mapmem()
835 lengths[0] = ccb->cdm.match_buf_len; in cam_periph_mapmem()
841 * to be so strict. vmapbuf() is able to map up to maxphys. in cam_periph_mapmem()
847 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) in cam_periph_mapmem()
849 if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) in cam_periph_mapmem()
851 data_ptrs[0] = &ccb->csio.data_ptr; in cam_periph_mapmem()
852 lengths[0] = ccb->csio.dxfer_len; in cam_periph_mapmem()
853 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_mapmem()
857 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) in cam_periph_mapmem()
859 if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) in cam_periph_mapmem()
861 data_ptrs[0] = &ccb->ataio.data_ptr; in cam_periph_mapmem()
862 lengths[0] = ccb->ataio.dxfer_len; in cam_periph_mapmem()
863 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_mapmem()
867 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) in cam_periph_mapmem()
869 /* Two mappings: one for cmd->data and one for cmd->data->data */ in cam_periph_mapmem()
870 data_ptrs[0] = (unsigned char **)&ccb->mmcio.cmd.data; in cam_periph_mapmem()
872 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_mapmem()
873 data_ptrs[1] = (unsigned char **)&ccb->mmcio.cmd.data->data; in cam_periph_mapmem()
874 lengths[1] = ccb->mmcio.cmd.data->len; in cam_periph_mapmem()
875 dirs[1] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_mapmem()
879 data_ptrs[0] = &ccb->smpio.smp_request; in cam_periph_mapmem()
880 lengths[0] = ccb->smpio.smp_request_len; in cam_periph_mapmem()
882 data_ptrs[1] = &ccb->smpio.smp_response; in cam_periph_mapmem()
883 lengths[1] = ccb->smpio.smp_response_len; in cam_periph_mapmem()
889 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) in cam_periph_mapmem()
891 if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) in cam_periph_mapmem()
893 data_ptrs[0] = &ccb->nvmeio.data_ptr; in cam_periph_mapmem()
894 lengths[0] = ccb->nvmeio.dxfer_len; in cam_periph_mapmem()
895 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_mapmem()
899 if (ccb->cdai.bufsiz == 0) in cam_periph_mapmem()
902 data_ptrs[0] = (uint8_t **)&ccb->cdai.buf; in cam_periph_mapmem()
903 lengths[0] = ccb->cdai.bufsiz; in cam_periph_mapmem()
909 * to be so strict. vmapbuf() is able to map up to maxphys. in cam_periph_mapmem()
925 "which is greater than %lu\n", in cam_periph_mapmem()
933 mapinfo->orig[i] = *data_ptrs[i]; in cam_periph_mapmem()
938 * small allocations malloc is backed by UMA, and so much in cam_periph_mapmem()
942 ccb->ccb_h.func_code != XPT_MMC_IO) { in cam_periph_mapmem()
946 if (copyin(mapinfo->orig[i], *data_ptrs[i], in cam_periph_mapmem()
949 *data_ptrs[i] = mapinfo->orig[i]; in cam_periph_mapmem()
960 mapinfo->bp[i] = uma_zalloc(pbuf_zone, M_WAITOK); in cam_periph_mapmem()
963 mapinfo->bp[i]->b_iocmd = (dirs[i] == CAM_DIR_OUT) ? in cam_periph_mapmem()
967 if (vmapbuf(mapinfo->bp[i], *data_ptrs[i], lengths[i], 1) < 0) { in cam_periph_mapmem()
968 uma_zfree(pbuf_zone, mapinfo->bp[i]); in cam_periph_mapmem()
973 *data_ptrs[i] = mapinfo->bp[i]->b_data; in cam_periph_mapmem()
982 if (mapinfo->bp[i]) in cam_periph_mapmem()
983 BUF_KERNPROC(mapinfo->bp[i]); in cam_periph_mapmem()
986 mapinfo->num_bufs_used = numbufs; in cam_periph_mapmem()
990 for (i--; i >= 0; i--) { in cam_periph_mapmem()
991 if (mapinfo->bp[i]) { in cam_periph_mapmem()
992 vunmapbuf(mapinfo->bp[i]); in cam_periph_mapmem()
993 uma_zfree(pbuf_zone, mapinfo->bp[i]); in cam_periph_mapmem()
996 *data_ptrs[i] = mapinfo->orig[i]; in cam_periph_mapmem()
1013 if (mapinfo->num_bufs_used <= 0) { in cam_periph_unmapmem()
1018 switch (ccb->ccb_h.func_code) { in cam_periph_unmapmem()
1020 if (ccb->cdm.pattern_buf_len > 0) { in cam_periph_unmapmem()
1021 data_ptrs[0] = (uint8_t **)&ccb->cdm.patterns; in cam_periph_unmapmem()
1022 lengths[0] = ccb->cdm.pattern_buf_len; in cam_periph_unmapmem()
1024 data_ptrs[1] = (uint8_t **)&ccb->cdm.matches; in cam_periph_unmapmem()
1025 lengths[1] = ccb->cdm.match_buf_len; in cam_periph_unmapmem()
1029 data_ptrs[0] = (uint8_t **)&ccb->cdm.matches; in cam_periph_unmapmem()
1030 lengths[0] = ccb->cdm.match_buf_len; in cam_periph_unmapmem()
1037 data_ptrs[0] = &ccb->csio.data_ptr; in cam_periph_unmapmem()
1038 lengths[0] = ccb->csio.dxfer_len; in cam_periph_unmapmem()
1039 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_unmapmem()
1043 data_ptrs[0] = &ccb->ataio.data_ptr; in cam_periph_unmapmem()
1044 lengths[0] = ccb->ataio.dxfer_len; in cam_periph_unmapmem()
1045 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_unmapmem()
1049 data_ptrs[0] = (uint8_t **)&ccb->mmcio.cmd.data; in cam_periph_unmapmem()
1051 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_unmapmem()
1052 data_ptrs[1] = (uint8_t **)&ccb->mmcio.cmd.data->data; in cam_periph_unmapmem()
1053 lengths[1] = ccb->mmcio.cmd.data->len; in cam_periph_unmapmem()
1054 dirs[1] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_unmapmem()
1058 data_ptrs[0] = &ccb->smpio.smp_request; in cam_periph_unmapmem()
1059 lengths[0] = ccb->smpio.smp_request_len; in cam_periph_unmapmem()
1061 data_ptrs[1] = &ccb->smpio.smp_response; in cam_periph_unmapmem()
1062 lengths[1] = ccb->smpio.smp_response_len; in cam_periph_unmapmem()
1068 data_ptrs[0] = &ccb->nvmeio.data_ptr; in cam_periph_unmapmem()
1069 lengths[0] = ccb->nvmeio.dxfer_len; in cam_periph_unmapmem()
1070 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; in cam_periph_unmapmem()
1074 data_ptrs[0] = (uint8_t **)&ccb->cdai.buf; in cam_periph_unmapmem()
1075 lengths[0] = ccb->cdai.bufsiz; in cam_periph_unmapmem()
1086 if (mapinfo->bp[i]) { in cam_periph_unmapmem()
1088 vunmapbuf(mapinfo->bp[i]); in cam_periph_unmapmem()
1091 uma_zfree(pbuf_zone, mapinfo->bp[i]); in cam_periph_unmapmem()
1096 error1 = copyout(*data_ptrs[i], mapinfo->orig[i], in cam_periph_unmapmem()
1105 *data_ptrs[i] = mapinfo->orig[i]; in cam_periph_unmapmem()
1127 xpt_setup_ccb(&ccb->ccb_h, in cam_periph_ioctl()
1128 ccb->ccb_h.path, in cam_periph_ioctl()
1130 ccb->ccb_h.func_code = XPT_GDEVLIST; in cam_periph_ioctl()
1133 * Basically, the point of this is that we go through in cam_periph_ioctl()
1137 * with is by its name. in cam_periph_ioctl()
1140 ccb->cgdl.index = 0; in cam_periph_ioctl()
1141 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS; in cam_periph_ioctl()
1142 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) { in cam_periph_ioctl()
1145 if (strncmp(ccb->cgdl.periph_name, in cam_periph_ioctl()
1151 if ((ccb->cgdl.status == CAM_GDEVLIST_LAST_DEVICE) && in cam_periph_ioctl()
1153 ccb->cgdl.periph_name[0] = '\0'; in cam_periph_ioctl()
1154 ccb->cgdl.unit_number = 0; in cam_periph_ioctl()
1185 xpt_path_assert(done_ccb->ccb_h.path, MA_OWNED); in cam_periph_done()
1186 done_ccb->ccb_h.cbfcnp = cam_periph_done_panic; in cam_periph_done()
1187 wakeup(&done_ccb->ccb_h.cbfcnp); in cam_periph_done()
1194 if ((ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) { in cam_periph_ccbwait()
1195 while (ccb->ccb_h.cbfcnp != cam_periph_done_panic) in cam_periph_ccbwait()
1196 xpt_path_sleep(ccb->ccb_h.path, &ccb->ccb_h.cbfcnp, in cam_periph_ccbwait()
1199 KASSERT(ccb->ccb_h.pinfo.index == CAM_UNQUEUED_INDEX && in cam_periph_ccbwait()
1200 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG, in cam_periph_ccbwait()
1202 "status=%#x, index=%d", __func__, ccb, ccb->ccb_h.func_code, in cam_periph_ccbwait()
1203 ccb->ccb_h.status, ccb->ccb_h.pinfo.index)); in cam_periph_ccbwait()
1208 * callback function (ccb->ccb_h.cbfcnp), it will be overwritten and lost.
1225 xpt_path_assert(ccb->ccb_h.path, MA_OWNED); in cam_periph_runccb()
1226 KASSERT((ccb->ccb_h.flags & CAM_UNLOCKED) == 0, in cam_periph_runccb()
1228 ccb->ccb_h.func_code, ccb->ccb_h.flags)); in cam_periph_runccb()
1235 (ccb->ccb_h.func_code == XPT_SCSI_IO || in cam_periph_runccb()
1236 ccb->ccb_h.func_code == XPT_ATA_IO || in cam_periph_runccb()
1237 ccb->ccb_h.func_code == XPT_NVME_IO)) { in cam_periph_runccb()
1244 * We must poll the I/O while we're dumping. The scheduler is normally in cam_periph_runccb()
1246 * scheduler is running in this case, we still need to poll the I/O to in cam_periph_runccb()
1259 ccb->ccb_h.cbfcnp = cam_periph_done; in cam_periph_runccb()
1268 if (cam_sim_pollable(ccb->ccb_h.path->bus->sim)) in cam_periph_runccb()
1275 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; in cam_periph_runccb()
1282 timeout = ccb->ccb_h.timeout * 10; in cam_periph_runccb()
1286 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) in cam_periph_runccb()
1290 * cbfcnp is modified by cam_periph_ccbwait so in cam_periph_runccb()
1294 ccb->ccb_h.cbfcnp = cam_periph_done; in cam_periph_runccb()
1301 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { in cam_periph_runccb()
1302 cam_release_devq(ccb->ccb_h.path, in cam_periph_runccb()
1307 ccb->ccb_h.status &= ~CAM_DEV_QFRZN; in cam_periph_runccb()
1315 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in cam_periph_runccb()
1316 bytes = ccb->csio.dxfer_len - ccb->csio.resid; in cam_periph_runccb()
1317 tag = (devstat_tag_type)(ccb->csio.tag_action & 0x3); in cam_periph_runccb()
1318 } else if (ccb->ccb_h.func_code == XPT_ATA_IO) { in cam_periph_runccb()
1319 bytes = ccb->ataio.dxfer_len - ccb->ataio.resid; in cam_periph_runccb()
1321 } else if (ccb->ccb_h.func_code == XPT_NVME_IO) { in cam_periph_runccb()
1322 bytes = ccb->nvmeio.dxfer_len; /* NB: resid no possible */ in cam_periph_runccb()
1329 ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) ? in cam_periph_runccb()
1330 DEVSTAT_NO_DATA : (ccb->ccb_h.flags & CAM_DIR_OUT) ? in cam_periph_runccb()
1381 &done_ccb->csio.cdb_io.cdb_bytes; in camperiphdone()
1382 status = done_ccb->ccb_h.status; in camperiphdone()
1388 * If the error is "invalid field in CDB", in camperiphdone()
1389 * and the load/eject flag is set, turn the in camperiphdone()
1390 * flag off and try again. This is just in in camperiphdone()
1396 if ((scsi_cmd->opcode == START_STOP_UNIT) && in camperiphdone()
1397 ((scsi_cmd->how & SSS_LOEJ) != 0) && in camperiphdone()
1399 scsi_cmd->how &= ~SSS_LOEJ; in camperiphdone()
1401 cam_release_devq(done_ccb->ccb_h.path, in camperiphdone()
1403 done_ccb->ccb_h.status &= in camperiphdone()
1414 if (done_ccb->ccb_h.status & CAM_DEV_QFRZN) { in camperiphdone()
1415 cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0); in camperiphdone()
1416 done_ccb->ccb_h.status &= ~CAM_DEV_QFRZN; in camperiphdone()
1421 * ready to ready state, re-scan the device and re-get in camperiphdone()
1426 if (scsi_cmd->opcode == START_STOP_UNIT) in camperiphdone()
1427 xpt_async(AC_INQ_CHANGED, done_ccb->ccb_h.path, NULL); in camperiphdone()
1431 if ((periph->flags & CAM_PERIPH_RECOVERY_WAIT) && in camperiphdone()
1432 (done_ccb->csio.cdb_io.cdb_bytes[0] == TEST_UNIT_READY)) { in camperiphdone()
1433 periph->flags &= ~CAM_PERIPH_RECOVERY_WAIT; in camperiphdone()
1434 if (error != 0 && done_ccb->ccb_h.retry_count == 0) in camperiphdone()
1435 periph->flags |= CAM_PERIPH_RECOVERY_WAIT_FAILED; in camperiphdone()
1447 saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr; in camperiphdone()
1448 KASSERT(saved_ccb->ccb_h.func_code == XPT_SCSI_IO, in camperiphdone()
1450 __func__, saved_ccb->ccb_h.func_code)); in camperiphdone()
1451 KASSERT(done_ccb->ccb_h.func_code == XPT_SCSI_IO, in camperiphdone()
1453 __func__, done_ccb->ccb_h.func_code)); in camperiphdone()
1454 saved_ccb->ccb_h.periph_links = done_ccb->ccb_h.periph_links; in camperiphdone()
1455 done_flags = done_ccb->ccb_h.alloc_flags; in camperiphdone()
1457 done_ccb->ccb_h.alloc_flags = done_flags; in camperiphdone()
1459 if (done_ccb->ccb_h.cbfcnp != camperiphdone) in camperiphdone()
1460 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG; in camperiphdone()
1462 done_ccb->ccb_h.retry_count = 0; in camperiphdone()
1467 cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0); in camperiphdone()
1494 xpt_setup_ccb(&cgds.ccb_h, periph->path, CAM_PRIORITY_NORMAL); in cam_periph_bus_settle()
1519 cam_freeze_devq(periph->path); in cam_periph_freeze_after_event()
1520 cam_release_devq(periph->path, in cam_periph_freeze_after_event()
1538 switch (ccb->csio.scsi_status) { in camperiphscsistatuserror()
1567 ccb->ccb_h.path, in camperiphscsistatuserror()
1619 periph = xpt_path_periph(ccb->ccb_h.path); in camperiphscsistatuserror()
1620 if (periph->flags & CAM_PERIPH_INVALID) { in camperiphscsistatuserror()
1624 ccb->ccb_h.retry_count > 0) { in camperiphscsistatuserror()
1626 ccb->ccb_h.retry_count--; in camperiphscsistatuserror()
1656 if (ccb->ccb_h.func_code == XPT_SCSI_IO && ccb->csio.bio != NULL) in camperiphscsisenseerror()
1657 biotrack(ccb->csio.bio, __func__); in camperiphscsisenseerror()
1660 periph = xpt_path_periph(ccb->ccb_h.path); in camperiphscsisenseerror()
1661 recoveryccb = (ccb->ccb_h.cbfcnp == camperiphdone); in camperiphscsisenseerror()
1662 if ((periph->flags & CAM_PERIPH_RECOVERY_INPROG) && !recoveryccb) { in camperiphscsisenseerror()
1664 * If error recovery is already in progress, don't attempt in camperiphscsisenseerror()
1667 * completed. This failed command is probably related to in camperiphscsisenseerror()
1671 * code assumes that only one recovery action is in progress in camperiphscsisenseerror()
1673 * (e.g. only one saved CCB for error recovery) so it is in camperiphscsisenseerror()
1686 xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path, CAM_PRIORITY_NORMAL); in camperiphscsisenseerror()
1690 err_action = scsi_error_action(&ccb->csio, &cgd.inq_data, in camperiphscsisenseerror()
1706 * Avoid recovery recursion if recovery action is the same. in camperiphscsisenseerror()
1710 ccb->csio.cdb_io.cdb_bytes[0] == START_STOP_UNIT) || in camperiphscsisenseerror()
1712 (ccb->csio.cdb_io.cdb_bytes[0] == TEST_UNIT_READY))) { in camperiphscsisenseerror()
1724 if (ccb->ccb_h.retry_count > 0 && in camperiphscsisenseerror()
1725 (periph->flags & CAM_PERIPH_INVALID) == 0) in camperiphscsisenseerror()
1726 ccb->ccb_h.retry_count--; in camperiphscsisenseerror()
1747 ccb->ccb_h.status &= ~CAM_DEV_QFRZN; in camperiphscsisenseerror()
1749 KASSERT(ccb->ccb_h.func_code == XPT_SCSI_IO, in camperiphscsisenseerror()
1751 __func__, ccb->ccb_h.func_code)); in camperiphscsisenseerror()
1752 flags = orig_ccb->ccb_h.alloc_flags; in camperiphscsisenseerror()
1754 orig_ccb->ccb_h.alloc_flags = flags; in camperiphscsisenseerror()
1778 periph->flags |= CAM_PERIPH_RECOVERY_INPROG; in camperiphscsisenseerror()
1789 scsi_start_stop(&ccb->csio, in camperiphscsisenseerror()
1804 * If the 'many' flag is set, we send 120 in camperiphscsisenseerror()
1812 if ((err_action & SSQ_MANY) != 0 && (periph->flags & in camperiphscsisenseerror()
1814 periph->flags |= CAM_PERIPH_RECOVERY_WAIT; in camperiphscsisenseerror()
1821 periph->flags |= CAM_PERIPH_RECOVERY_INPROG; in camperiphscsisenseerror()
1822 scsi_test_unit_ready(&ccb->csio, in camperiphscsisenseerror()
1844 * CCB is the first to execute. Freeze the queue in camperiphscsisenseerror()
1845 * after this command is sent so that we can in camperiphscsisenseerror()
1850 ccb->ccb_h.pinfo.priority--; in camperiphscsisenseerror()
1851 ccb->ccb_h.flags |= CAM_DEV_QFREEZE; in camperiphscsisenseerror()
1852 ccb->ccb_h.saved_ccb_ptr = orig_ccb; in camperiphscsisenseerror()
1882 periph = xpt_path_periph(ccb->ccb_h.path); in cam_periph_error()
1884 status = ccb->ccb_h.status; in cam_periph_error()
1891 switch (ccb->ccb_h.status & CAM_STATUS_MASK) { in cam_periph_error()
1930 if (ccb->ccb_h.retry_count > 0 && in cam_periph_error()
1931 (periph->flags & CAM_PERIPH_INVALID) == 0) { in cam_periph_error()
1932 ccb->ccb_h.retry_count--; in cam_periph_error()
1971 /* Unconditional requeue if device is still there */ in cam_periph_error()
1972 if (periph->flags & CAM_PERIPH_INVALID) { in cam_periph_error()
2003 if (periph->flags & CAM_PERIPH_INVALID) { in cam_periph_error()
2006 } else if (ccb->ccb_h.retry_count == 0) { in cam_periph_error()
2013 ccb->ccb_h.retry_count--; in cam_periph_error()
2020 CAM_DEBUGGED(ccb->ccb_h.path, CAM_DEBUG_INFO)) in cam_periph_error()
2030 xpt_print(ccb->ccb_h.path, "Error %d, %s\n", in cam_periph_error()
2033 xpt_print(ccb->ccb_h.path, "%s\n", action_string); in cam_periph_error()
2035 xpt_print(ccb->ccb_h.path, in cam_periph_error()
2037 ccb->ccb_h.retry_count); in cam_periph_error()
2049 * the target to be gone. If the status is CAM_DEV_NOT_THERE, in cam_periph_error()
2056 lun_id = xpt_path_lun_id(ccb->ccb_h.path); in cam_periph_error()
2060 xpt_path_path_id(ccb->ccb_h.path), in cam_periph_error()
2061 xpt_path_target_id(ccb->ccb_h.path), in cam_periph_error()
2074 xpt_async(AC_UNIT_ATTENTION, orig_ccb->ccb_h.path, orig_ccb); in cam_periph_error()
2079 xpt_path_path_id(ccb->ccb_h.path), in cam_periph_error()
2080 xpt_path_target_id(ccb->ccb_h.path), in cam_periph_error()
2084 scan_ccb->ccb_h.path = newpath; in cam_periph_error()
2085 scan_ccb->ccb_h.func_code = XPT_SCAN_TGT; in cam_periph_error()
2086 scan_ccb->crcn.flags = 0; in cam_periph_error()
2099 ccb->ccb_h.status &= ~CAM_DEV_QFRZN; in cam_periph_error()
2103 cam_release_devq(ccb->ccb_h.path, in cam_periph_error()
2130 periph = xpt_path_periph(ccb->ccb_h.path); in cam_periph_devctl_notify()
2131 sbuf_printf(&sb, "device=%s%d ", periph->periph_name, in cam_periph_devctl_notify()
2132 periph->unit_number); in cam_periph_devctl_notify()
2136 xpt_setup_ccb(&cgd->ccb_h, ccb->ccb_h.path, in cam_periph_devctl_notify()
2138 cgd->ccb_h.func_code = XPT_GDEV_TYPE; in cam_periph_devctl_notify()
2141 if (cgd->ccb_h.status == CAM_REQ_CMP) in cam_periph_devctl_notify()
2142 sbuf_bcat(&sb, cgd->serial_num, cgd->serial_num_len); in cam_periph_devctl_notify()
2146 sbuf_printf(&sb, "cam_status=\"0x%x\" ", ccb->ccb_h.status); in cam_periph_devctl_notify()
2148 switch (ccb->ccb_h.status & CAM_STATUS_MASK) { in cam_periph_devctl_notify()
2150 sbuf_printf(&sb, "timeout=%d ", ccb->ccb_h.timeout); in cam_periph_devctl_notify()
2154 sbuf_printf(&sb, "scsi_status=%d ", ccb->csio.scsi_status); in cam_periph_devctl_notify()
2162 ata_res_sbuf(&ccb->ataio.res, &sb); in cam_periph_devctl_notify()
2168 struct ccb_nvmeio *n = &ccb->nvmeio; in cam_periph_devctl_notify()
2171 NVME_STATUS_GET_SCT(n->cpl.status), in cam_periph_devctl_notify()
2172 NVME_STATUS_GET_SC(n->cpl.status), n->cpl.cdw0); in cam_periph_devctl_notify()
2182 switch (ccb->ccb_h.func_code) { in cam_periph_devctl_notify()
2185 scsi_cdb_sbuf(scsiio_cdb_ptr(&ccb->csio), &sb); in cam_periph_devctl_notify()
2190 ata_cmd_sbuf(&ccb->ataio.cmd, &sb); in cam_periph_devctl_notify()
2196 struct ccb_nvmeio *n = &ccb->nvmeio; in cam_periph_devctl_notify()
2197 struct nvme_command *cmd = &n->cmd; in cam_periph_devctl_notify()
2203 cmd->opc, cmd->fuse, cmd->cid, cmd->nsid, cmd->cdw10, in cam_periph_devctl_notify()
2204 cmd->cdw11, cmd->cdw12, cmd->cdw13, cmd->cdw14, cmd->cdw15); in cam_periph_devctl_notify()
2230 if (error != 0 || req->newptr == NULL || value != 1) in cam_periph_invalidate_sysctl()