summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_sim.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam/cam_sim.c')
-rw-r--r--sys/cam/cam_sim.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/sys/cam/cam_sim.c b/sys/cam/cam_sim.c
index 322915f..cc8f86d 100644
--- a/sys/cam/cam_sim.c
+++ b/sys/cam/cam_sim.c
@@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -58,39 +60,42 @@ cam_simq_free(struct cam_devq *devq)
struct cam_sim *
cam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll,
const char *sim_name, void *softc, u_int32_t unit,
- int max_dev_transactions,
+ struct mtx *mtx, int max_dev_transactions,
int max_tagged_dev_transactions, struct cam_devq *queue)
{
struct cam_sim *sim;
- /*
- * If this is the xpt layer creating a sim, then it's OK
- * to wait for an allocation.
- *
- * XXX Should we pass in a flag to indicate that wait is OK?
- */
- if (strcmp(sim_name, "xpt") == 0)
- sim = (struct cam_sim *)malloc(sizeof(struct cam_sim),
- M_CAMSIM, M_WAITOK);
- else
- sim = (struct cam_sim *)malloc(sizeof(struct cam_sim),
- M_CAMSIM, M_NOWAIT);
-
- if (sim != NULL) {
- sim->sim_action = sim_action;
- sim->sim_poll = sim_poll;
- sim->sim_name = sim_name;
- sim->softc = softc;
- sim->path_id = CAM_PATH_ANY;
- sim->unit_number = unit;
- sim->bus_id = 0; /* set in xpt_bus_register */
- sim->max_tagged_dev_openings = max_tagged_dev_transactions;
- sim->max_dev_openings = max_dev_transactions;
- sim->flags = 0;
- callout_handle_init(&sim->c_handle);
- sim->devq = queue;
+ if (mtx == NULL)
+ return (NULL);
+
+ sim = (struct cam_sim *)malloc(sizeof(struct cam_sim),
+ M_CAMSIM, M_NOWAIT);
+
+ if (sim == NULL)
+ return (NULL);
+
+ sim->sim_action = sim_action;
+ sim->sim_poll = sim_poll;
+ sim->sim_name = sim_name;
+ sim->softc = softc;
+ sim->path_id = CAM_PATH_ANY;
+ sim->unit_number = unit;
+ sim->bus_id = 0; /* set in xpt_bus_register */
+ sim->max_tagged_dev_openings = max_tagged_dev_transactions;
+ sim->max_dev_openings = max_dev_transactions;
+ sim->flags = 0;
+ sim->devq = queue;
+ sim->mtx = mtx;
+ if (mtx == &Giant) {
+ sim->flags |= 0;
+ callout_init(&sim->callout, 0);
+ } else {
+ sim->flags |= CAM_SIM_MPSAFE;
+ callout_init(&sim->callout, 1);
}
+ SLIST_INIT(&sim->ccb_freeq);
+
return (sim);
}
OpenPOWER on IntegriCloud