/* locks: must only be called with zfcp_data.config_sema taken */ int zfcp_qdio_allocate_queues(struct zfcp_adapter *adapter) { int buffer_count; int retval = 0; buffer_count = zfcp_qdio_buffers_enqueue(&(adapter->request_queue.buffer[0]), QDIO_MAX_BUFFERS_PER_Q); if (buffer_count < QDIO_MAX_BUFFERS_PER_Q) { ZFCP_LOG_DEBUG("only %d QDIO buffers allocated for request " "queue\n", buffer_count); zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]), buffer_count); retval = -ENOMEM; goto out; } buffer_count = zfcp_qdio_buffers_enqueue(&(adapter->response_queue.buffer[0]), QDIO_MAX_BUFFERS_PER_Q); if (buffer_count < QDIO_MAX_BUFFERS_PER_Q) { ZFCP_LOG_DEBUG("only %d QDIO buffers allocated for response " "queue", buffer_count); zfcp_qdio_buffers_dequeue(&(adapter->response_queue.buffer[0]), buffer_count); ZFCP_LOG_TRACE("freeing request_queue buffers\n"); zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]), QDIO_MAX_BUFFERS_PER_Q); retval = -ENOMEM; goto out; } out: return retval; }
/* locks: must only be called with zfcp_data.config_sema taken */ void zfcp_qdio_free_queues(struct zfcp_adapter *adapter) { ZFCP_LOG_TRACE("freeing request_queue buffers\n"); zfcp_qdio_buffers_dequeue(adapter->request_queue.buffer); ZFCP_LOG_TRACE("freeing response_queue buffers\n"); zfcp_qdio_buffers_dequeue(adapter->response_queue.buffer); }
/* locks: must only be called with zfcp_data.config_sema taken */ void zfcp_qdio_free_queues(struct zfcp_adapter *adapter) { ZFCP_LOG_TRACE("freeing request_queue buffers\n"); zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]), QDIO_MAX_BUFFERS_PER_Q); ZFCP_LOG_TRACE("freeing response_queue buffers\n"); zfcp_qdio_buffers_dequeue(&(adapter->response_queue.buffer[0]), QDIO_MAX_BUFFERS_PER_Q); }
/* * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t * array in the adapter struct. * Cur_buf is the pointer array * * returns: zero on success else -ENOMEM * locks: must only be called with zfcp_data.config_sema taken */ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbuf) { int pos; for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) { sbuf[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL); if (!sbuf[pos]) { zfcp_qdio_buffers_dequeue(sbuf); return -ENOMEM; } } for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos++) if (pos % QBUFF_PER_PAGE) sbuf[pos] = sbuf[pos - 1] + 1; return 0; }