55 #define OCS_IO_MAX_ALLOCATION (64*1024)
97 ocs_io_pool_t *io_pool;
101 io_pool = ocs_malloc(ocs,
sizeof(*io_pool), OCS_M_ZERO | OCS_M_NOWAIT);
102 if (io_pool == NULL) {
103 ocs_log_err(ocs,
"allocate of IO pool failed\n");
110 io_pool->io_slab_count = (num_io + io_pool->io_per_slab - 1) / io_pool->io_per_slab;
111 io_pool->io_slabs = ocs_malloc(ocs,
sizeof(
ocs_io_slab_t) * io_pool->io_slab_count, OCS_M_ZERO | OCS_M_NOWAIT);
113 if (io_pool->io_slabs == NULL) {
114 ocs_log_err(ocs,
"allocate of io_slabs failed\n");
115 ocs_free(ocs, io_pool,
sizeof(*io_pool));
118 io_pool->io_num_ios = num_io;
121 ocs_lock_init(ocs, &io_pool->lock,
"io_pool lock[%d]", ocs->instance_index);
124 ocs_list_init(&io_pool->io_free_list, ocs_io_t, io_alloc_link);
127 for (idx = 0, i = 0, slab = io_pool->io_slabs; i < io_pool->io_slab_count; i++, slab++, idx += io_pool->io_per_slab) {
128 slab->
count = io_pool->io_per_slab;
129 slab->
ios = ocs_malloc(ocs, slab->
count*
sizeof(ocs_io_t), OCS_M_ZERO | OCS_M_NOWAIT);
130 if (slab->
ios == NULL) {
131 ocs_log_err(ocs,
"slab ios allocation failed\n");
137 for (j = 0, io = slab->
ios; (j < slab->count) && ((idx + j) < num_io); j++, io++) {
139 io->instance_index = idx + j;
145 rc = ocs_dma_alloc(ocs, &io->sensebuf, 256 + 2, 16);
147 ocs_log_err(ocs,
"ocs_dma_alloc cmdbuf failed\n");
153 io->sgl = ocs_malloc(ocs,
sizeof(*io->sgl) * num_sgl, OCS_M_NOWAIT | OCS_M_ZERO);
154 if (io->sgl == NULL) {
155 ocs_log_err(ocs,
"malloc sgl's failed\n");
159 io->sgl_allocated = num_sgl;
192 if (io_pool->io_slabs) {
193 for (i = 0, slab = io_pool->io_slabs; i < io_pool->io_slab_count; i++, slab++) {
198 for (j = 0, io = slab->
ios; j < slab->count; j++, io++) {
203 ocs_free(ocs, io->sgl,
sizeof(*io->sgl) * io->sgl_allocated);
206 ocs_dma_free(io_pool->ocs, &io->sensebuf);
208 ocs_free(ocs, slab->
ios, slab->
count*
sizeof(ocs_io_t));
211 ocs_free(ocs, io_pool->io_slabs, io_pool->io_slab_count*
sizeof(
ocs_io_slab_t));
212 io_pool->io_slabs = NULL;
215 ocs_lock_free(&io_pool->lock);
216 ocs_free(ocs, io_pool,
sizeof(*io_pool));
222 return io_pool->io_num_ios;
245 ocs_t *ocs = io_pool->ocs;
249 ocs_lock(&io_pool->lock);
256 io->tgt_task_tag = 0;
260 ocs_unlock(&io_pool->lock);
274 ocs_t *ocs = io_pool->ocs;
278 ocs_lock(&io_pool->lock);
284 ocs_unlock(&io_pool->lock);
303 ocs_io_pool_t *io_pool = ocs->io_pool;
307 if (index >= io_pool->io_num_ios) {
311 slab_idx = index / io_pool->io_per_slab;
312 idx = index % io_pool->io_per_slab;
314 return &io_pool->io_slabs[slab_idx].ios[idx];
357 ocs_io_t *io = (ocs_io_t *)
object;
374 ocs_io_t *io = (ocs_io_t *)
object;
379 snprintf(qualifier,
sizeof(qualifier),
"%s.io%d", parent, io->instance_index);
382 if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
383 char *unqualified_name = name + strlen(qualifier) +1;
386 if (ocs_strcmp(unqualified_name,
"init_task_tag") == 0) {
389 }
else if (ocs_strcmp(unqualified_name,
"tag") == 0) {
392 }
else if (ocs_strcmp(unqualified_name,
"auto_resp") == 0) {
395 }
else if (ocs_strcmp(unqualified_name,
"busy") == 0) {
408 ocs_io_t *io = (ocs_io_t *)
object;
static int32_t ocs_io_busy(ocs_io_t *io)
Test if IO object is busy.
int32_t ocs_scsi_tgt_io_exit(ocs_io_t *io)
Un-initialize SCSI IO.
ocs_io_pool_t * ocs_io_pool_create(ocs_t *ocs, uint32_t num_io, uint32_t num_sgl)
Create a pool of IO objects.
ocs_io_t * ocs_io_pool_io_alloc(ocs_io_pool_t *io_pool)
Allocate an object used to track an IO.
int32_t ocs_scsi_tgt_io_init(ocs_io_t *io)
Initialize SCSI IO.
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
void ocs_mgmt_emit_int(ocs_textbuf_t *textbuf, int mode, const char *name, const char *fmt,...)
Generate a property with an integer value in a management XML document.
static void * ocs_list_get_head(ocs_list_t *list)
Return the first item in the list.
void ocs_mgmt_io_get_all(ocs_textbuf_t *textbuf, void *io)
void ocs_ddump_section(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section start data.
int32_t ocs_scsi_ini_io_exit(ocs_io_t *io)
void ocs_mgmt_start_section(ocs_textbuf_t *textbuf, const char *name, int index)
Generate the beginning of a numbered section in a management XML document.
int const char const char void ocs_mgmt_emit_boolean(ocs_textbuf_t *textbuf, int access, const char *name, const int value)
Generate a property with a boolean value in a management XML document.
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
int32_t ocs_scsi_ini_io_init(ocs_io_t *io)
#define ocs_list_init(head, type, link)
void ocs_io_pool_io_free(ocs_io_pool_t *io_pool, ocs_io_t *io)
Free an object used to track an IO.
uint32_t ocs_io_pool_allocated(ocs_io_pool_t *io_pool)
void ocs_mgmt_io_list(ocs_textbuf_t *textbuf, void *io)
ocs_io_t * ocs_io_get_instance(ocs_t *ocs, uint32_t index)
return pointer to IO object given instance index
void ocs_mgmt_end_section(ocs_textbuf_t *textbuf, const char *name, int index)
Generate the indexed end of a section in a management XML document.
void ocs_ddump_endsection(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section end data.
ocs_mgmt_get_list_handler get_list_handler
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
void ocs_hal_io_free(ocs_hal_t *hal, ocs_hal_io_t *io)
Free a previously allocated HAL IO object.
void ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
void ocs_ddump_io(ocs_textbuf_t *textbuf, ocs_io_t *io)
generate IO context ddump data
static ocs_mgmt_functions_t io_mgmt_functions
int32_t ocs_io_pool_free(ocs_io_pool_t *io_pool)
Free IO objects pool.
int ocs_mgmt_io_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *io)
#define ocs_assert(cond,...)
#define OCS_IO_MAX_ALLOCATION
void ocs_mgmt_emit_property_name(ocs_textbuf_t *textbuf, int access, const char *name)
Generate a property, with no value, in a management XML document.
void ocs_ddump_value(ocs_textbuf_t *textbuf, const char *name, const char *fmt,...)
Generate driver dump data for a given value.