Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_io.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @file
35  * Provide IO object allocation.
36  */
37 
38 /*!
39  * @defgroup io_alloc IO allocation
40  */
41 
42 #include "ocs.h"
43 #include "ocs_scsi_fc.h"
44 #include "ocs_pool.h"
45 
46 void ocs_mgmt_io_list(ocs_textbuf_t *textbuf, void *io);
47 void ocs_mgmt_io_get_all(ocs_textbuf_t *textbuf, void *io);
48 int ocs_mgmt_io_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *io);
49 
52  .get_handler = ocs_mgmt_io_get,
53  .get_all_handler = ocs_mgmt_io_get_all,
54 };
55 
56 /**
57  * @brief IO pool.
58  *
59  * Structure encapsulating a pool of IO objects.
60  *
61  */
62 
63 struct ocs_io_pool_s {
64  ocs_t *ocs; /* Pointer to device object */
65  ocs_lock_t lock; /* IO pool lock */
66  uint32_t io_num_ios; /* Total IOs allocated */
67  ocs_pool_t *pool;
68 };
69 
70 /**
71  * @brief Create a pool of IO objects.
72  *
73  * @par Description
74  * This function allocates memory in larger chucks called
75  * "slabs" which are a fixed size. It calculates the number of IO objects that
76  * fit within each "slab" and determines the number of "slabs" required to
77  * allocate the number of IOs requested. Each of the slabs is allocated and
78  * then it grabs each IO object within the slab and adds it to the free list.
79  * Individual command, response and SGL DMA buffers are allocated for each IO.
80  *
81  * "Slabs"
82  * +----------------+
83  * | |
84  * +----------------+ |
85  * | IO | |
86  * +----------------+ |
87  * | ... | |
88  * +----------------+__+
89  * | IO |
90  * +----------------+
91  *
92  * @param ocs Driver instance's software context.
93  * @param num_io Number of IO contexts to allocate.
94  * @param num_sgl Number of SGL entries to allocate for each IO.
95  *
96  * @return Returns a pointer to a new ocs_io_pool_t on success,
97  * or NULL on failure.
98  */
99 
100 ocs_io_pool_t *
101 ocs_io_pool_create(ocs_t *ocs, uint32_t num_io, uint32_t num_sgl)
102 {
103  uint32_t i = 0;
104  int32_t rc = -1;
105  ocs_io_pool_t *io_pool;
106 
107  /* Allocate the IO pool */
108  io_pool = ocs_malloc(ocs, sizeof(*io_pool), OCS_M_ZERO | OCS_M_NOWAIT);
109  if (!io_pool) {
110  ocs_log_err(ocs, "allocate of IO pool failed\n");
111  goto free_io_pool;
112  }
113 
114  io_pool->ocs = ocs;
115  io_pool->io_num_ios = num_io;
116 
117  /* initialize IO pool lock */
118  ocs_lock_init(ocs, &io_pool->lock, "io_pool lock[%d]", ocs->instance_index);
119 
120  io_pool->pool = ocs_pool_alloc(ocs, sizeof(ocs_io_t), io_pool->io_num_ios, FALSE);
121  if (!io_pool->pool) {
122  ocs_log_err(ocs, "allocation of memory IO pool failed\n");
123  goto free_io_pool;
124  }
125 
126  for (i = 0; i < io_pool->io_num_ios; i++) {
127  ocs_io_t *io = ocs_pool_get_instance(io_pool->pool, i);
128  if (!io) {
129  ocs_log_err(ocs, "ocs_pool_get_instance failed\n");
130  goto free_io_pool;
131  }
132 
133  io->tag = i;
134  io->instance_index = i;
135  io->ocs = ocs;
136 
137  /* allocate a command/response dma buffer */
138  if (ocs->enable_ini) {
139  rc = ocs_dma_alloc(ocs, &io->cmdbuf, SCSI_CMD_BUF_LENGTH, OCS_MIN_DMA_ALIGNMENT);
140  if (rc) {
141  ocs_log_err(ocs, "ocs_dma_alloc cmdbuf failed\n");
142  goto free_io_pool;
143  }
144  }
145 
146  /* Allocate a response buffer */
147  rc = ocs_dma_alloc(ocs, &io->rspbuf, SCSI_RSP_BUF_LENGTH, OCS_MIN_DMA_ALIGNMENT);
148  if (rc) {
149  ocs_log_err(ocs, "ocs_dma_alloc rspbuf failed\n");
150  goto free_io_pool;
151  }
152 
153  /* Allocate SGL */
154  io->sgl_allocated = num_sgl;
155  io->sgl_count = 0;
156  io->sgl = ocs_malloc(ocs, sizeof(*io->sgl) * num_sgl, OCS_M_NOWAIT | OCS_M_ZERO);
157  if (!io->sgl) {
158  ocs_log_err(ocs, "malloc sgl's failed\n");
159  goto free_io_pool;
160  }
161 
162  /* Make IO backend call to initialize IO */
165  }
166 
167  return io_pool;
168 
169 free_io_pool:
170  ocs_io_pool_free(io_pool);
171  return NULL;
172 }
173 
174 /**
175  * @brief Free IO objects pool
176  *
177  * @par Description
178  * The pool of IO objects are freed.
179  *
180  * @param io_pool Pointer to IO pool object.
181  *
182  * @return Returns 0 on success, or a negative error code value on failure.
183  */
184 int32_t
185 ocs_io_pool_free(ocs_io_pool_t *io_pool)
186 {
187  ocs_t *ocs;
188  uint32_t i;
189  ocs_io_t *io;
190 
191  if (!io_pool) {
192  return 0;
193  }
194 
195  ocs = io_pool->ocs;
196  if (io_pool->pool) {
197  for (i = 0; i < io_pool->io_num_ios; i++) {
198  io = ocs_pool_get_instance(io_pool->pool, i);
199  if (!io) {
200  continue;
201  }
202 
205 
206  if (io->sgl) {
207  ocs_free(ocs, io->sgl, sizeof(*io->sgl) * io->sgl_allocated);
208  io->sgl = NULL;
209  }
210  io->sgl_allocated = 0;
211 
212  ocs_dma_free(ocs, &io->cmdbuf);
213  ocs_dma_free(ocs, &io->rspbuf);
214  }
215 
216  ocs_pool_free(io_pool->pool);
217  }
218 
219  ocs_lock_free(&io_pool->lock);
220  ocs_free(ocs, io_pool, sizeof(*io_pool));
221  ocs->xport->io_pool = NULL;
222  return 0;
223 }
224 
225 uint32_t ocs_io_pool_allocated(ocs_io_pool_t *io_pool)
226 {
227  return io_pool->io_num_ios;
228 }
229 
230 /**
231  * @ingroup io_alloc
232  * @brief Allocate an object used to track an IO.
233  *
234  * @param io_pool Pointer to the IO pool.
235  *
236  * @return Returns the pointer to a new object, or NULL if none available.
237  */
238 ocs_io_t *
239 ocs_io_pool_io_alloc(ocs_io_pool_t *io_pool)
240 {
241  ocs_io_t *io = NULL;
242  ocs_t *ocs;
243 
244  ocs_assert(io_pool, NULL);
245 
246  ocs = io_pool->ocs;
247 
248  ocs_lock(&io_pool->lock);
249  if ((io = ocs_pool_get(io_pool->pool)) != NULL) {
250  ocs_unlock(&io_pool->lock);
251 
252  io->io_type = OCS_IO_TYPE_MAX;
253  io->hio_type = OCS_HAL_IO_MAX;
254  io->hio = NULL;
255  io->transferred = 0;
256  io->ocs = ocs;
257  io->timeout = 0;
258  io->sgl_count = 0;
259  io->tgt_task_tag = 0;
260  io->init_task_tag = 0;
261  io->hw_tag = 0;
262  io->display_name = "pending";
263  io->seq_init = 0;
264  io->els_req_free = 0;
265  io->mgmt_functions = &io_mgmt_functions;
266  io->io_free = 0;
267  ocs_atomic_add_return(&ocs->xport->io_active_count, 1);
268  ocs_atomic_add_return(&ocs->xport->io_total_alloc, 1);
269  } else {
270  ocs_unlock(&io_pool->lock);
271  }
272  return io;
273 }
274 
275 /**
276  * @ingroup io_alloc
277  * @brief Free an object used to track an IO.
278  *
279  * @param io_pool Pointer to IO pool object.
280  * @param io Pointer to the IO object.
281  */
282 void
283 ocs_io_pool_io_free(ocs_io_pool_t *io_pool, ocs_io_t *io)
284 {
285  ocs_t *ocs;
286  ocs_hal_io_t *hio = NULL;
287 
288  ocs_assert(io_pool);
289 
290  ocs = io_pool->ocs;
291 
292  ocs_lock(&io_pool->lock);
293  hio = io->hio;
294  io->hio = NULL;
295  io->io_free = 1;
296  ocs_pool_put_head(io_pool->pool, io);
297  ocs_unlock(&io_pool->lock);
298 
299  if (hio) {
300  ocs_hal_io_free(&ocs->hal, hio);
301  }
302  ocs_atomic_sub_return(&ocs->xport->io_active_count, 1);
303  ocs_atomic_add_return(&ocs->xport->io_total_free, 1);
304 }
305 
306 /**
307  * @ingroup io_alloc
308  * @brief Find an I/O given it's node and ox_id.
309  *
310  * @param ocs Driver instance's software context.
311  * @param node Pointer to node.
312  * @param ox_id OX_ID to find.
313  * @param rx_id RX_ID to find (0xffff for unassigned).
314  */
315 ocs_io_t *
316 ocs_io_find_tgt_io(ocs_t *ocs, ocs_node_t *node, uint16_t ox_id, uint16_t rx_id)
317 {
318  ocs_io_t *io = NULL;
319 
320  ocs_lock(&node->active_ios_lock);
321  ocs_list_foreach(&node->active_ios, io)
322  if ((io->cmd_tgt && (io->init_task_tag == ox_id)) &&
323  ((rx_id == 0xffff) || (io->tgt_task_tag == rx_id))) {
324  break;
325  }
326  ocs_unlock(&node->active_ios_lock);
327  return io;
328 }
329 /**
330  * @ingroup ocs_io_find_init_els_io
331  * @brief Find an els I/O given it's node and ox_id.
332  *
333  * @param ocs Driver instance's software context.
334  * @param node Pointer to node.
335  * @param ox_id OX_ID to find.
336  */
337 
338 ocs_io_t *
339 ocs_io_find_init_els_io(ocs_t *ocs, ocs_node_t *node, uint16_t ox_id)
340 {
341  ocs_io_t *io = NULL;
342 
343  ocs_lock(&node->active_ios_lock);
344  ocs_list_foreach(&node->els_io_active_list, io) {
345  if ((io->cmd_ini && (io->init_task_tag == ox_id))) {
346  break;
347  }
348  }
349  ocs_unlock(&node->active_ios_lock);
350  return io;
351 }
352 
353 /**
354  * @ingroup io_alloc
355  * @brief Return IO context given the instance index.
356  *
357  * @par Description
358  * Returns a pointer to the IO context given by the instance index.
359  *
360  * @param ocs Pointer to driver structure.
361  * @param index IO instance index to return.
362  *
363  * @return Returns a pointer to the IO context, or NULL if not found.
364  */
365 ocs_io_t *
366 ocs_io_get_instance(ocs_t *ocs, uint32_t index)
367 {
368  ocs_xport_t *xport = ocs->xport;
369  ocs_io_pool_t *io_pool = xport->io_pool;
370  return ocs_pool_get_instance(io_pool->pool, index);
371 }
372 
373 /**
374  * @brief Generate IO context ddump data.
375  *
376  * The ddump data for an IO context is generated.
377  *
378  * @param textbuf Pointer to text buffer.
379  * @param io Pointer to IO context.
380  *
381  * @return None.
382  */
383 
384 void
385 ocs_ddump_io(ocs_textbuf_t *textbuf, ocs_io_t *io)
386 {
387  ocs_ddump_section(textbuf, "io", io->instance_index);
388  ocs_ddump_value(textbuf, "display_name", "%s", io->display_name);
389  ocs_ddump_value(textbuf, "node_name", "%s", io->node->display_name);
390 
391  ocs_ddump_value(textbuf, "ref_count", "%d", ocs_ref_read_count(&io->ref));
392  ocs_ddump_value(textbuf, "io_type", "%d", io->io_type);
393  ocs_ddump_value(textbuf, "hio_type", "%d", io->hio_type);
394  ocs_ddump_value(textbuf, "cmd_tgt", "%d", io->cmd_tgt);
395  ocs_ddump_value(textbuf, "cmd_ini", "%d", io->cmd_ini);
396  ocs_ddump_value(textbuf, "send_abts", "%d", io->send_abts);
397  ocs_ddump_value(textbuf, "init_task_tag", "0x%x", io->init_task_tag);
398  ocs_ddump_value(textbuf, "tgt_task_tag", "0x%x", io->tgt_task_tag);
399  ocs_ddump_value(textbuf, "hw_tag", "0x%x", io->hw_tag);
400  ocs_ddump_value(textbuf, "tag", "0x%x", io->tag);
401  ocs_ddump_value(textbuf, "timeout", "%d", io->timeout);
402  ocs_ddump_value(textbuf, "tmf_cmd", "%d", io->tmf_cmd);
403  ocs_ddump_value(textbuf, "abort_rx_id", "0x%x", io->abort_rx_id);
404 #if defined(OCS_INCLUDE_SCST)
405  ocs_ddump_value(textbuf, "iostate", "%08x", ocs_scsi_tgt_io_state(io));
406 #endif
407  ocs_ddump_value(textbuf, "busy", "%d", ocs_io_busy(io));
408  ocs_ddump_value(textbuf, "transferred", "%zu", io->transferred);
409  ocs_ddump_value(textbuf, "auto_resp", "%d", io->auto_resp);
410  ocs_ddump_value(textbuf, "exp_xfer_len", "%d", io->exp_xfer_len);
411  ocs_ddump_value(textbuf, "xfer_req", "%" PRIu64, io->xfer_req);
412  ocs_ddump_value(textbuf, "seq_init", "%d", io->seq_init);
413 
414  ocs_ddump_value(textbuf, "alloc_link", "%d", ocs_list_on_list(&io->io_alloc_link));
415  ocs_ddump_value(textbuf, "pending_link", "%d", ocs_list_on_list(&io->io_pending_link));
416  ocs_ddump_value(textbuf, "backend_link", "%d", ocs_list_on_list(&io->link));
417 
418  if (io->hio) {
419  ocs_ddump_value(textbuf, "hal_tag", "%#x", io->hio->reqtag);
420  ocs_ddump_value(textbuf, "hal_xri", "%#x", io->hio->indicator);
421  ocs_ddump_value(textbuf, "hal_type", "%#x", io->hio->type);
422  } else {
423  ocs_ddump_value(textbuf, "hal_tag", "%s", "pending");
424  ocs_ddump_value(textbuf, "hal_xri", "%s", "pending");
425  ocs_ddump_value(textbuf, "hal_type", "%s", "pending");
426  }
427 
430 
431  ocs_ddump_endsection(textbuf, "io", io->instance_index);
432 }
433 
434 
435 void
436 ocs_mgmt_io_list(ocs_textbuf_t *textbuf, void *object)
437 {
438 
439  /* Readonly values */
440  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "display_name");
441  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "init_task_tag");
442  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "tag");
443  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "transferred");
444  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "auto_resp");
445  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "exp_xfer_len");
446  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "xfer_req");
447 }
448 
449 int
450 ocs_mgmt_io_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *object)
451 {
452  char qualifier[80];
453  int retval = -1;
454  ocs_io_t *io = (ocs_io_t *) object;
455 
456  snprintf(qualifier, sizeof(qualifier), "%s/io[%d]", parent, io->instance_index);
457 
458  /* If it doesn't start with my qualifier I don't know what to do with it */
459  if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
460  char *unqualified_name = name + strlen(qualifier) +1;
461 
462  /* See if it's a value I can supply */
463  if (ocs_strcmp(unqualified_name, "display_name") == 0) {
464  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", io->display_name);
465  retval = 0;
466  } else if (ocs_strcmp(unqualified_name, "init_task_tag") == 0) {
467  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "init_task_tag", "0x%x", io->init_task_tag);
468  retval = 0;
469  } else if (ocs_strcmp(unqualified_name, "tgt_task_tag") == 0) {
470  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tgt_task_tag", "0x%x", io->tgt_task_tag);
471  retval = 0;
472  } else if (ocs_strcmp(unqualified_name, "hw_tag") == 0) {
473  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hw_tag", "0x%x", io->hw_tag);
474  retval = 0;
475  } else if (ocs_strcmp(unqualified_name, "tag") == 0) {
476  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tag", "0x%x", io->tag);
477  retval = 0;
478  } else if (ocs_strcmp(unqualified_name, "transferred") == 0) {
479  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "transferred", "%zu", io->transferred);
480  retval = 0;
481  } else if (ocs_strcmp(unqualified_name, "auto_resp") == 0) {
482  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "auto_resp", io->auto_resp);
483  retval = 0;
484  } else if (ocs_strcmp(unqualified_name, "exp_xfer_len") == 0) {
485  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "exp_xfer_len", "%d", io->exp_xfer_len);
486  retval = 0;
487  } else if (ocs_strcmp(unqualified_name, "xfer_req") == 0) {
488  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "xfer_req", "%" PRIu64, io->xfer_req);
489  retval = 0;
490  }
491  }
492 
493  return retval;
494 }
495 
496 void
497 ocs_mgmt_io_get_all(ocs_textbuf_t *textbuf, void *object)
498 {
499  ocs_io_t *io = (ocs_io_t *) object;
500 
501  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", io->display_name);
502  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "init_task_tag", "0x%x", io->init_task_tag);
503  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tgt_task_tag", "0x%x", io->tgt_task_tag);
504  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hw_tag", "0x%x", io->hw_tag);
505  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tag", "0x%x", io->tag);
506  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "transferred", "%zu", io->transferred);
507  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "auto_resp", io->auto_resp);
508  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "exp_xfer_len", "%d", io->exp_xfer_len);
509  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "xfer_req", "%" PRIu64, io->xfer_req);
510 
511 }
512 
513 
514 
515 
int32_t ocs_hal_io_free(ocs_hal_t *hal, ocs_hal_io_t *io)
Free a previously-allocated HAL IO object.
Definition: ocs_hal.c:4001
static int32_t ocs_io_busy(ocs_io_t *io)
Test if IO object is busy.
Definition: ocs_io.h:191
static int32_t ocs_list_on_list(ocs_list_link_t *link)
Test if object is on a list.
Definition: ocs_list.h:460
int32_t ocs_scsi_tgt_io_exit(ocs_io_t *io)
Un-initialize SCSI IO.
Definition: ocs_ramd.c:450
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.
Definition: ocs_io.c:101
ocs_io_t * ocs_io_pool_io_alloc(ocs_io_pool_t *io_pool)
Allocate an object used to track an IO.
Definition: ocs_io.c:239
void * ocs_pool_get(ocs_pool_t *pool)
Allocate a memory pool item.
Definition: ocs_pool.c:197
int32_t ocs_scsi_tgt_io_init(ocs_io_t *io)
Initialize SCSI IO.
Definition: ocs_ramd.c:433
ocs_lock_t lock
Definition: ocs_io.c:65
uint32_t ocs_scsi_tgt_io_state(ocs_io_t *io)
Set SCST IO state.
Definition: ocs_ramd.c:415
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.
void ocs_pool_put_head(ocs_pool_t *pool, void *item)
free memory pool item
Definition: ocs_pool.c:261
const char * name
Definition: ocs_ddump.h:54
ocs_io_t * ocs_io_find_init_els_io(ocs_t *ocs, ocs_node_t *node, uint16_t ox_id)
Find an els I/O given it&#39;s node and ox_id.
Definition: ocs_io.c:339
void ocs_mgmt_io_get_all(ocs_textbuf_t *textbuf, void *io)
Definition: ocs_io.c:497
void ocs_ddump_section(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section start data.
Definition: ocs_ddumplib.c:90
int32_t ocs_scsi_ini_io_exit(ocs_io_t *io)
Uninitialize SCSI IO.
Definition: ocs_ini_stub.c:85
ocs_pool_t * pool
Definition: ocs_io.c:67
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.
ocs_pool_t * ocs_pool_alloc(ocs_os_handle_t os, uint32_t size, uint32_t count, uint32_t use_lock)
Allocate a memory pool.
Definition: ocs_pool.c:88
void ocs_pool_free(ocs_pool_t *pool)
Free a previously allocated memory pool.
Definition: ocs_pool.c:173
int32_t ocs_scsi_ini_io_init(ocs_io_t *io)
Initialize SCSI IO.
Definition: ocs_ini_stub.c:69
void ocs_io_pool_io_free(ocs_io_pool_t *io_pool, ocs_io_t *io)
Free an object used to track an IO.
Definition: ocs_io.c:283
uint32_t ocs_io_pool_allocated(ocs_io_pool_t *io_pool)
Definition: ocs_io.c:225
void ocs_mgmt_io_list(ocs_textbuf_t *textbuf, void *io)
Definition: ocs_io.c:436
ocs_io_t * ocs_io_get_instance(ocs_t *ocs, uint32_t index)
Return IO context given the instance index.
Definition: ocs_io.c:366
void * ocs_pool_get_instance(ocs_pool_t *pool, uint32_t idx)
Return item given an index.
Definition: ocs_pool.c:315
void ocs_ddump_endsection(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section end data.
Definition: ocs_ddumplib.c:108
ocs_mgmt_get_list_handler get_list_handler
Definition: ocs_mgmt.h:83
#define MGMT_MODE_RD
Definition: ocs_mgmt.h:47
#define SCSI_RSP_BUF_LENGTH
Definition: ocs_io.h:54
#define SCSI_CMD_BUF_LENGTH
FCP IO context.
Definition: ocs_io.h:53
void ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
Definition: ocs_ramd.c:6580
void ocs_ddump_io(ocs_textbuf_t *textbuf, ocs_io_t *io)
Generate IO context ddump data.
Definition: ocs_io.c:385
static ocs_mgmt_functions_t io_mgmt_functions
Definition: ocs_io.c:50
uint32_t io_num_ios
Definition: ocs_io.c:66
int32_t ocs_io_pool_free(ocs_io_pool_t *io_pool)
Free IO objects pool.
Definition: ocs_io.c:185
int ocs_mgmt_io_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *io)
Definition: ocs_io.c:450
ocs_t * ocs
Definition: ocs_io.c:64
#define ocs_assert(cond,...)
Definition: ocs_debug.h:176
IO pool.
Definition: ocs_io.c:63
void ocs_mgmt_emit_string(ocs_textbuf_t *textbuf, int access, const char *name, const char *value)
Generate a property with a string value in a management XML document.
ocs_io_t * ocs_io_find_tgt_io(ocs_t *ocs, ocs_node_t *node, uint16_t ox_id, uint16_t rx_id)
Find an I/O given it&#39;s node and ox_id.
Definition: ocs_io.c:316
#define ocs_list_foreach(list, item)
Iterate a linked list.
Definition: ocs_list.h:428
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.
Definition: ocs_ddumplib.c:126
void ocs_scsi_ini_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
Definition: ocs_ini_stub.c:266