|
@@ -204,10 +204,8 @@ static int qla2x00_do_dpc(void *data);
|
|
|
|
|
|
static void qla2x00_rst_aen(scsi_qla_host_t *);
|
|
|
|
|
|
-static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);
|
|
|
+static int qla2x00_mem_alloc(scsi_qla_host_t *);
|
|
|
static void qla2x00_mem_free(scsi_qla_host_t *ha);
|
|
|
-static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
|
|
|
-static void qla2x00_free_sp_pool(scsi_qla_host_t *ha);
|
|
|
static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
@@ -2032,196 +2030,109 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
|
|
|
*
|
|
|
* Returns:
|
|
|
* 0 = success.
|
|
|
-* 1 = failure.
|
|
|
+* !0 = failure.
|
|
|
*/
|
|
|
-static uint8_t
|
|
|
+static int
|
|
|
qla2x00_mem_alloc(scsi_qla_host_t *ha)
|
|
|
{
|
|
|
char name[16];
|
|
|
- uint8_t status = 1;
|
|
|
- int retry= 10;
|
|
|
-
|
|
|
- do {
|
|
|
- /*
|
|
|
- * This will loop only once if everything goes well, else some
|
|
|
- * number of retries will be performed to get around a kernel
|
|
|
- * bug where available mem is not allocated until after a
|
|
|
- * little delay and a retry.
|
|
|
- */
|
|
|
- ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
- (ha->request_q_length + 1) * sizeof(request_t),
|
|
|
- &ha->request_dma, GFP_KERNEL);
|
|
|
- if (ha->request_ring == NULL) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - request_ring\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
- (ha->response_q_length + 1) * sizeof(response_t),
|
|
|
- &ha->response_dma, GFP_KERNEL);
|
|
|
- if (ha->response_ring == NULL) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - response_ring\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
|
|
|
- &ha->gid_list_dma, GFP_KERNEL);
|
|
|
- if (ha->gid_list == NULL) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - gid_list\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- /* get consistent memory allocated for init control block */
|
|
|
- ha->init_cb = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
- ha->init_cb_size, &ha->init_cb_dma, GFP_KERNEL);
|
|
|
- if (ha->init_cb == NULL) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - init_cb\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
- memset(ha->init_cb, 0, ha->init_cb_size);
|
|
|
-
|
|
|
- snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
|
|
|
- ha->host_no);
|
|
|
- ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
|
|
|
- DMA_POOL_SIZE, 8, 0);
|
|
|
- if (ha->s_dma_pool == NULL) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - s_dma_pool\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (qla2x00_allocate_sp_pool(ha)) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - "
|
|
|
- "qla2x00_allocate_sp_pool()\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- /* Allocate memory for SNS commands */
|
|
|
- if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
|
|
- /* Get consistent memory allocated for SNS commands */
|
|
|
- ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
- sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma,
|
|
|
- GFP_KERNEL);
|
|
|
- if (ha->sns_cmd == NULL) {
|
|
|
- /* error */
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - sns_cmd\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
- memset(ha->sns_cmd, 0, sizeof(struct sns_cmd_pkt));
|
|
|
- } else {
|
|
|
- /* Get consistent memory allocated for MS IOCB */
|
|
|
- ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
|
|
|
- &ha->ms_iocb_dma);
|
|
|
- if (ha->ms_iocb == NULL) {
|
|
|
- /* error */
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - ms_iocb\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
- memset(ha->ms_iocb, 0, sizeof(ms_iocb_entry_t));
|
|
|
-
|
|
|
- /*
|
|
|
- * Get consistent memory allocated for CT SNS
|
|
|
- * commands
|
|
|
- */
|
|
|
- ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
- sizeof(struct ct_sns_pkt), &ha->ct_sns_dma,
|
|
|
- GFP_KERNEL);
|
|
|
- if (ha->ct_sns == NULL) {
|
|
|
- /* error */
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - ct_sns\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
- memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
|
|
|
-
|
|
|
- if (IS_FWI2_CAPABLE(ha)) {
|
|
|
- /*
|
|
|
- * Get consistent memory allocated for SFP
|
|
|
- * block.
|
|
|
- */
|
|
|
- ha->sfp_data = dma_pool_alloc(ha->s_dma_pool,
|
|
|
- GFP_KERNEL, &ha->sfp_data_dma);
|
|
|
- if (ha->sfp_data == NULL) {
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - "
|
|
|
- "sfp_data\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
- memset(ha->sfp_data, 0, SFP_BLOCK_SIZE);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Get memory for cached NVRAM */
|
|
|
- ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
|
|
|
- if (ha->nvram == NULL) {
|
|
|
- /* error */
|
|
|
- qla_printk(KERN_WARNING, ha,
|
|
|
- "Memory Allocation failed - nvram cache\n");
|
|
|
-
|
|
|
- qla2x00_mem_free(ha);
|
|
|
- msleep(100);
|
|
|
-
|
|
|
- continue;
|
|
|
- }
|
|
|
|
|
|
- /* Done all allocations without any error. */
|
|
|
- status = 0;
|
|
|
+ ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
+ (ha->request_q_length + 1) * sizeof(request_t), &ha->request_dma,
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!ha->request_ring)
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
+ (ha->response_q_length + 1) * sizeof(response_t),
|
|
|
+ &ha->response_dma, GFP_KERNEL);
|
|
|
+ if (!ha->response_ring)
|
|
|
+ goto fail_free_request_ring;
|
|
|
+
|
|
|
+ ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
|
|
|
+ &ha->gid_list_dma, GFP_KERNEL);
|
|
|
+ if (!ha->gid_list)
|
|
|
+ goto fail_free_response_ring;
|
|
|
+
|
|
|
+ ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
|
|
|
+ &ha->init_cb_dma, GFP_KERNEL);
|
|
|
+ if (!ha->init_cb)
|
|
|
+ goto fail_free_gid_list;
|
|
|
+
|
|
|
+ snprintf(name, sizeof(name), "%s_%ld", QLA2XXX_DRIVER_NAME,
|
|
|
+ ha->host_no);
|
|
|
+ ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
|
|
|
+ DMA_POOL_SIZE, 8, 0);
|
|
|
+ if (!ha->s_dma_pool)
|
|
|
+ goto fail_free_init_cb;
|
|
|
|
|
|
- } while (retry-- && status != 0);
|
|
|
+ ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
|
|
|
+ if (!ha->srb_mempool)
|
|
|
+ goto fail_free_s_dma_pool;
|
|
|
+
|
|
|
+ /* Get memory for cached NVRAM */
|
|
|
+ ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
|
|
|
+ if (!ha->nvram)
|
|
|
+ goto fail_free_srb_mempool;
|
|
|
+
|
|
|
+ /* Allocate memory for SNS commands */
|
|
|
+ if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
|
|
|
+ /* Get consistent memory allocated for SNS commands */
|
|
|
+ ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
+ sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL);
|
|
|
+ if (!ha->sns_cmd)
|
|
|
+ goto fail_free_nvram;
|
|
|
+ } else {
|
|
|
+ /* Get consistent memory allocated for MS IOCB */
|
|
|
+ ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
|
|
|
+ &ha->ms_iocb_dma);
|
|
|
+ if (!ha->ms_iocb)
|
|
|
+ goto fail_free_nvram;
|
|
|
|
|
|
- if (status) {
|
|
|
- printk(KERN_WARNING
|
|
|
- "%s(): **** FAILED ****\n", __func__);
|
|
|
+ /* Get consistent memory allocated for CT SNS commands */
|
|
|
+ ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
|
|
|
+ sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
|
|
|
+ if (!ha->ct_sns)
|
|
|
+ goto fail_free_ms_iocb;
|
|
|
}
|
|
|
|
|
|
- return(status);
|
|
|
+ return 0;
|
|
|
+
|
|
|
+fail_free_ms_iocb:
|
|
|
+ dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
|
|
|
+ ha->ms_iocb = NULL;
|
|
|
+ ha->ms_iocb_dma = 0;
|
|
|
+fail_free_nvram:
|
|
|
+ kfree(ha->nvram);
|
|
|
+ ha->nvram = NULL;
|
|
|
+fail_free_srb_mempool:
|
|
|
+ mempool_destroy(ha->srb_mempool);
|
|
|
+ ha->srb_mempool = NULL;
|
|
|
+fail_free_s_dma_pool:
|
|
|
+ dma_pool_destroy(ha->s_dma_pool);
|
|
|
+ ha->s_dma_pool = NULL;
|
|
|
+fail_free_init_cb:
|
|
|
+ dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb,
|
|
|
+ ha->init_cb_dma);
|
|
|
+ ha->init_cb = NULL;
|
|
|
+ ha->init_cb_dma = 0;
|
|
|
+fail_free_gid_list:
|
|
|
+ dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
|
|
|
+ ha->gid_list_dma);
|
|
|
+ ha->gid_list = NULL;
|
|
|
+ ha->gid_list_dma = 0;
|
|
|
+fail_free_response_ring:
|
|
|
+ dma_free_coherent(&ha->pdev->dev, (ha->response_q_length + 1) *
|
|
|
+ sizeof(response_t), ha->response_ring, ha->response_dma);
|
|
|
+ ha->response_ring = NULL;
|
|
|
+ ha->response_dma = 0;
|
|
|
+fail_free_request_ring:
|
|
|
+ dma_free_coherent(&ha->pdev->dev, (ha->request_q_length + 1) *
|
|
|
+ sizeof(request_t), ha->request_ring, ha->request_dma);
|
|
|
+ ha->request_ring = NULL;
|
|
|
+ ha->request_dma = 0;
|
|
|
+fail:
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2237,14 +2148,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|
|
struct list_head *fcpl, *fcptemp;
|
|
|
fc_port_t *fcport;
|
|
|
|
|
|
- if (ha == NULL) {
|
|
|
- /* error */
|
|
|
- DEBUG2(printk("%s(): ERROR invalid ha pointer.\n", __func__));
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* free sp pool */
|
|
|
- qla2x00_free_sp_pool(ha);
|
|
|
+ if (ha->srb_mempool)
|
|
|
+ mempool_destroy(ha->srb_mempool);
|
|
|
|
|
|
if (ha->fce)
|
|
|
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
|
|
@@ -2292,6 +2197,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|
|
(ha->request_q_length + 1) * sizeof(request_t),
|
|
|
ha->request_ring, ha->request_dma);
|
|
|
|
|
|
+ ha->srb_mempool = NULL;
|
|
|
ha->eft = NULL;
|
|
|
ha->eft_dma = 0;
|
|
|
ha->sns_cmd = NULL;
|
|
@@ -2330,44 +2236,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
|
|
kfree(ha->nvram);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * qla2x00_allocate_sp_pool
|
|
|
- * This routine is called during initialization to allocate
|
|
|
- * memory for local srb_t.
|
|
|
- *
|
|
|
- * Input:
|
|
|
- * ha = adapter block pointer.
|
|
|
- *
|
|
|
- * Context:
|
|
|
- * Kernel context.
|
|
|
- */
|
|
|
-static int
|
|
|
-qla2x00_allocate_sp_pool(scsi_qla_host_t *ha)
|
|
|
-{
|
|
|
- int rval;
|
|
|
-
|
|
|
- rval = QLA_SUCCESS;
|
|
|
- ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
|
|
|
- if (ha->srb_mempool == NULL) {
|
|
|
- qla_printk(KERN_INFO, ha, "Unable to allocate SRB mempool.\n");
|
|
|
- rval = QLA_FUNCTION_FAILED;
|
|
|
- }
|
|
|
- return (rval);
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * This routine frees all adapter allocated memory.
|
|
|
- *
|
|
|
- */
|
|
|
-static void
|
|
|
-qla2x00_free_sp_pool( scsi_qla_host_t *ha)
|
|
|
-{
|
|
|
- if (ha->srb_mempool) {
|
|
|
- mempool_destroy(ha->srb_mempool);
|
|
|
- ha->srb_mempool = NULL;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/**************************************************************************
|
|
|
* qla2x00_do_dpc
|
|
|
* This kernel thread is a task that is schedule by the interrupt handler
|