Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/cam_xpt.c
| Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
| #include <cam/cam_debug.h> | #include <cam/cam_debug.h> | ||||
| #include <cam/cam_compat.h> | #include <cam/cam_compat.h> | ||||
| #include <cam/scsi/scsi_all.h> | #include <cam/scsi/scsi_all.h> | ||||
| #include <cam/scsi/scsi_message.h> | #include <cam/scsi/scsi_message.h> | ||||
| #include <cam/scsi/scsi_pass.h> | #include <cam/scsi/scsi_pass.h> | ||||
| /* SDT Probes */ | |||||
| SDT_PROBE_DEFINE1(cam, , xpt, action, "union ccb *"); | |||||
| SDT_PROBE_DEFINE1(cam, , xpt, done, "union ccb *"); | |||||
| SDT_PROBE_DEFINE4(cam, , xpt, async__cb, "void *", "uint32_t", | |||||
| "struct cam_path *", "void *"); | |||||
| /* Wild guess based on not wanting to grow the stack too much */ | /* Wild guess based on not wanting to grow the stack too much */ | ||||
| #define XPT_PRINT_MAXLEN 512 | #define XPT_PRINT_MAXLEN 512 | ||||
| #ifdef PRINTF_BUFR_SIZE | #ifdef PRINTF_BUFR_SIZE | ||||
| #define XPT_PRINT_LEN PRINTF_BUFR_SIZE | #define XPT_PRINT_LEN PRINTF_BUFR_SIZE | ||||
| #else | #else | ||||
| #define XPT_PRINT_LEN 128 | #define XPT_PRINT_LEN 128 | ||||
| #endif | #endif | ||||
| _Static_assert(XPT_PRINT_LEN <= XPT_PRINT_MAXLEN, "XPT_PRINT_LEN is too large"); | _Static_assert(XPT_PRINT_LEN <= XPT_PRINT_MAXLEN, "XPT_PRINT_LEN is too large"); | ||||
| ▲ Show 20 Lines • Show All 2,393 Lines • ▼ Show 20 Lines | if ((device->flags & CAM_DEV_UNCONFIGURED) != 0) | ||||
| return (1); | return (1); | ||||
| xpt_compile_path(&path, | xpt_compile_path(&path, | ||||
| NULL, | NULL, | ||||
| device->target->bus->path_id, | device->target->bus->path_id, | ||||
| device->target->target_id, | device->target->target_id, | ||||
| device->lun_id); | device->lun_id); | ||||
| xpt_gdev_type(&cgd, &path); | xpt_gdev_type(&cgd, &path); | ||||
| CAM_PROBE4(xpt, async__cb, csa->callback_arg, | |||||
| AC_FOUND_DEVICE, &path, &cgd); | |||||
| csa->callback(csa->callback_arg, | csa->callback(csa->callback_arg, | ||||
| AC_FOUND_DEVICE, | AC_FOUND_DEVICE, | ||||
| &path, &cgd); | &path, &cgd); | ||||
| xpt_release_path(&path); | xpt_release_path(&path); | ||||
| return(1); | return(1); | ||||
| } | } | ||||
| static int | static int | ||||
| xptsetasyncbusfunc(struct cam_eb *bus, void *arg) | xptsetasyncbusfunc(struct cam_eb *bus, void *arg) | ||||
| { | { | ||||
| struct cam_path path; | struct cam_path path; | ||||
| struct ccb_pathinq cpi; | struct ccb_pathinq cpi; | ||||
| struct ccb_setasync *csa = (struct ccb_setasync *)arg; | struct ccb_setasync *csa = (struct ccb_setasync *)arg; | ||||
| xpt_compile_path(&path, /*periph*/NULL, | xpt_compile_path(&path, /*periph*/NULL, | ||||
| bus->path_id, | bus->path_id, | ||||
| CAM_TARGET_WILDCARD, | CAM_TARGET_WILDCARD, | ||||
| CAM_LUN_WILDCARD); | CAM_LUN_WILDCARD); | ||||
| xpt_path_lock(&path); | xpt_path_lock(&path); | ||||
| xpt_path_inq(&cpi, &path); | xpt_path_inq(&cpi, &path); | ||||
| CAM_PROBE4(xpt, async__cb, csa->callback_arg, | |||||
| AC_PATH_REGISTERED, &path, &cpi); | |||||
| csa->callback(csa->callback_arg, | csa->callback(csa->callback_arg, | ||||
| AC_PATH_REGISTERED, | AC_PATH_REGISTERED, | ||||
| &path, &cpi); | &path, &cpi); | ||||
| xpt_path_unlock(&path); | xpt_path_unlock(&path); | ||||
| xpt_release_path(&path); | xpt_release_path(&path); | ||||
| return(1); | return(1); | ||||
| } | } | ||||
| Show All 10 Lines | xpt_action(union ccb *start_ccb) | ||||
| * Either it isn't queued, or it has a real priority. There still too | * Either it isn't queued, or it has a real priority. There still too | ||||
| * many places that reuse CCBs with a real priority to do immediate | * many places that reuse CCBs with a real priority to do immediate | ||||
| * queries to do the other side of this assert. | * queries to do the other side of this assert. | ||||
| */ | */ | ||||
| KASSERT((start_ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0 || | KASSERT((start_ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0 || | ||||
| start_ccb->ccb_h.pinfo.priority != CAM_PRIORITY_NONE, | start_ccb->ccb_h.pinfo.priority != CAM_PRIORITY_NONE, | ||||
| ("%s: queued ccb and CAM_PRIORITY_NONE illegal.", __func__)); | ("%s: queued ccb and CAM_PRIORITY_NONE illegal.", __func__)); | ||||
| CAM_PROBE1(xpt, action, start_ccb); | |||||
| start_ccb->ccb_h.status = CAM_REQ_INPROG; | start_ccb->ccb_h.status = CAM_REQ_INPROG; | ||||
| (*(start_ccb->ccb_h.path->bus->xport->ops->action))(start_ccb); | (*(start_ccb->ccb_h.path->bus->xport->ops->action))(start_ccb); | ||||
| } | } | ||||
| void | void | ||||
| xpt_action_default(union ccb *start_ccb) | xpt_action_default(union ccb *start_ccb) | ||||
| { | { | ||||
| struct cam_path *path; | struct cam_path *path; | ||||
| ▲ Show 20 Lines • Show All 1,718 Lines • ▼ Show 20 Lines | while (cur_entry != NULL) { | ||||
| * can delete its async callback entry. | * can delete its async callback entry. | ||||
| */ | */ | ||||
| next_entry = SLIST_NEXT(cur_entry, links); | next_entry = SLIST_NEXT(cur_entry, links); | ||||
| if ((cur_entry->event_enable & async_code) != 0) { | if ((cur_entry->event_enable & async_code) != 0) { | ||||
| mtx = cur_entry->event_lock ? | mtx = cur_entry->event_lock ? | ||||
| path->device->sim->mtx : NULL; | path->device->sim->mtx : NULL; | ||||
| if (mtx) | if (mtx) | ||||
| mtx_lock(mtx); | mtx_lock(mtx); | ||||
| CAM_PROBE4(xpt, async__cb, cur_entry->callback_arg, | |||||
| async_code, path, async_arg); | |||||
| cur_entry->callback(cur_entry->callback_arg, | cur_entry->callback(cur_entry->callback_arg, | ||||
| async_code, path, | async_code, path, | ||||
| async_arg); | async_arg); | ||||
| if (mtx) | if (mtx) | ||||
| mtx_unlock(mtx); | mtx_unlock(mtx); | ||||
| } | } | ||||
| cur_entry = next_entry; | cur_entry = next_entry; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | if (done_ccb->ccb_h.func_code == XPT_SCSI_IO && | ||||
| biotrack(done_ccb->csio.bio, __func__); | biotrack(done_ccb->csio.bio, __func__); | ||||
| #endif | #endif | ||||
| CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, | CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, | ||||
| ("xpt_done: func= %#x %s status %#x\n", | ("xpt_done: func= %#x %s status %#x\n", | ||||
| done_ccb->ccb_h.func_code, | done_ccb->ccb_h.func_code, | ||||
| xpt_action_name(done_ccb->ccb_h.func_code), | xpt_action_name(done_ccb->ccb_h.func_code), | ||||
| done_ccb->ccb_h.status)); | done_ccb->ccb_h.status)); | ||||
| if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0) | if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0) { | ||||
| CAM_PROBE1(xpt, done, done_ccb); | |||||
| return; | return; | ||||
| } | |||||
| /* Store the time the ccb was in the sim */ | /* Store the time the ccb was in the sim */ | ||||
| done_ccb->ccb_h.qos.periph_data = cam_iosched_delta_t(done_ccb->ccb_h.qos.periph_data); | done_ccb->ccb_h.qos.periph_data = cam_iosched_delta_t(done_ccb->ccb_h.qos.periph_data); | ||||
| done_ccb->ccb_h.status |= CAM_QOS_VALID; | done_ccb->ccb_h.status |= CAM_QOS_VALID; | ||||
| hash = (u_int)(done_ccb->ccb_h.path_id + done_ccb->ccb_h.target_id + | hash = (u_int)(done_ccb->ccb_h.path_id + done_ccb->ccb_h.target_id + | ||||
| done_ccb->ccb_h.target_lun) % cam_num_doneqs; | done_ccb->ccb_h.target_lun) % cam_num_doneqs; | ||||
| queue = &cam_doneqs[hash]; | queue = &cam_doneqs[hash]; | ||||
| mtx_lock(&queue->cam_doneq_mtx); | mtx_lock(&queue->cam_doneq_mtx); | ||||
| ▲ Show 20 Lines • Show All 859 Lines • ▼ Show 20 Lines | if ((ccb_h->flags & CAM_UNLOCKED) == 0) { | ||||
| } | } | ||||
| } else { | } else { | ||||
| if (mtx != NULL) { | if (mtx != NULL) { | ||||
| mtx_unlock(mtx); | mtx_unlock(mtx); | ||||
| mtx = NULL; | mtx = NULL; | ||||
| } | } | ||||
| } | } | ||||
| /* | |||||
| * Call as late as possible. Do we want an early one too before the | |||||
| * unfreeze / releases above? | |||||
| */ | |||||
| CAM_PROBE1(xpt, done, (union ccb *)ccb_h); /* container_of? */ | |||||
| /* Call the peripheral driver's callback */ | /* Call the peripheral driver's callback */ | ||||
| ccb_h->pinfo.index = CAM_UNQUEUED_INDEX; | ccb_h->pinfo.index = CAM_UNQUEUED_INDEX; | ||||
| (*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h); | (*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h); | ||||
| if (mtx != NULL) | if (mtx != NULL) | ||||
| mtx_unlock(mtx); | mtx_unlock(mtx); | ||||
| } | } | ||||
| /* | /* | ||||
| ▲ Show 20 Lines • Show All 217 Lines • Show Last 20 Lines | |||||