2 * Common functions for SCSI Interface Modules (SIMs).
4 * Copyright (c) 1997 Justin T. Gibbs.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/kernel.h>
37 #include <sys/mutex.h>
40 #include <cam/cam_ccb.h>
41 #include <cam/cam_sim.h>
42 #include <cam/cam_queue.h>
43 #include <cam/cam_xpt.h>
45 #define CAM_PATH_ANY (u_int32_t)-1
47 static MALLOC_DEFINE(M_CAMSIM
, "CAM SIM", "CAM SIM buffers");
50 cam_simq_alloc(u_int32_t max_sim_transactions
)
52 return (cam_devq_alloc(/*size*/0, max_sim_transactions
));
56 cam_simq_free(struct cam_devq
*devq
)
62 cam_sim_alloc(sim_action_func sim_action
, sim_poll_func sim_poll
,
63 const char *sim_name
, void *softc
, u_int32_t unit
,
64 struct mtx
*mtx
, int max_dev_transactions
,
65 int max_tagged_dev_transactions
, struct cam_devq
*queue
)
72 sim
= (struct cam_sim
*)malloc(sizeof(struct cam_sim
),
73 M_CAMSIM
, M_ZERO
| M_NOWAIT
);
78 sim
->sim_action
= sim_action
;
79 sim
->sim_poll
= sim_poll
;
80 sim
->sim_name
= sim_name
;
82 sim
->path_id
= CAM_PATH_ANY
;
83 sim
->unit_number
= unit
;
84 sim
->bus_id
= 0; /* set in xpt_bus_register */
85 sim
->max_tagged_dev_openings
= max_tagged_dev_transactions
;
86 sim
->max_dev_openings
= max_dev_transactions
;
93 callout_init(&sim
->callout
, 0);
95 sim
->flags
|= CAM_SIM_MPSAFE
;
96 callout_init(&sim
->callout
, 1);
102 cam_sim_free(struct cam_sim
*sim
, int free_devq
)
106 mtx_assert(sim
->mtx
, MA_OWNED
);
108 if (sim
->refcount
> 0) {
109 error
= msleep(sim
, sim
->mtx
, PRIBIO
, "simfree", 0);
110 KASSERT(error
== 0, ("invalid error value for msleep(9)"));
113 KASSERT(sim
->refcount
== 0, ("sim->refcount == 0"));
116 cam_simq_free(sim
->devq
);
121 cam_sim_release(struct cam_sim
*sim
)
125 lock
= (mtx_owned(sim
->mtx
) == 0);
128 KASSERT(sim
->refcount
>= 1, ("sim->refcount >= 1"));
130 if (sim
->refcount
== 0)
137 cam_sim_hold(struct cam_sim
*sim
)
141 lock
= (mtx_owned(sim
->mtx
) == 0);
144 KASSERT(sim
->refcount
>= 1, ("sim->refcount >= 1"));
151 cam_sim_set_path(struct cam_sim
*sim
, u_int32_t path_id
)
153 sim
->path_id
= path_id
;