diff --git a/drivers/scsi/sssraid/sssraid.h b/drivers/scsi/sssraid/sssraid.h index adcfdf6612738cc2f42ca653990f3c8f8784e552..f2a5979361187a43d99e6e696fb8cebf9f3da0cd 100644 --- a/drivers/scsi/sssraid/sssraid.h +++ b/drivers/scsi/sssraid/sssraid.h @@ -12,7 +12,7 @@ #define SSSRAID_DRIVER_NAME "sssraid" #define SSSRAID_NAME_LENGTH 32 - +#define BSG_NAME_SIZE 15 /* * SSSRAID Vendor ID and Device IDs */ @@ -92,6 +92,13 @@ extern u32 admin_tmout; #define SSSRAID_DMA_MSK_BIT_MAX 64 +enum { + SCSI_6_BYTE_CDB_LEN = 6, + SCSI_10_BYTE_CDB_LEN = 10, + SCSI_12_BYTE_CDB_LEN = 12, + SCSI_16_BYTE_CDB_LEN = 16, +}; + enum { SSSRAID_SGL_FMT_DATA_DESC = 0x00, SSSRAID_SGL_FMT_SEG_DESC = 0x02, diff --git a/drivers/scsi/sssraid/sssraid_fw.c b/drivers/scsi/sssraid/sssraid_fw.c index 25129abb30858d0625e3aa09225433331aaf4fe1..6f553003e19f9a5ce37bbe5aa6bb7c7a885ee972 100644 --- a/drivers/scsi/sssraid/sssraid_fw.c +++ b/drivers/scsi/sssraid/sssraid_fw.c @@ -188,14 +188,18 @@ static int sssraid_alloc_resources(struct sssraid_ioc *sdioc) return -ENOMEM; retval = sssraid_create_dma_pools(sdioc); - if (retval) + if (retval) { + ioc_err(sdioc, "err: failure at create dma pool!\n"); goto free_ctrl_info; + } + /* not num_online_cpus */ nqueue = num_possible_cpus() + 1; sdioc->cqinfo = kcalloc_node(nqueue, sizeof(struct sssraid_cqueue), GFP_KERNEL, sdioc->numa_node); if (!sdioc->cqinfo) { retval = -ENOMEM; + ioc_err(sdioc, "err: failure at alloc memory for cqueue!"); goto destroy_dma_pools; } @@ -203,6 +207,7 @@ static int sssraid_alloc_resources(struct sssraid_ioc *sdioc) GFP_KERNEL, sdioc->numa_node); if (!sdioc->sqinfo) { retval = -ENOMEM; + ioc_err(sdioc, "err: failure at alloc memory for squeue!"); goto free_cqueues; } @@ -263,7 +268,7 @@ static int sssraid_setup_resources(struct sssraid_ioc *sdioc) */ retval = sssraid_remap_bar(sdioc, SSSRAID_REG_DBS + 4096); if (retval) { - retval = -ENODEV; + ioc_err(sdioc, "Failed to re-map bar, error %d\n", retval); goto out_failed; } @@ -282,7 +287,7 @@ static int sssraid_setup_resources(struct sssraid_ioc *sdioc) maskbit = SSSRAID_CAP_DMAMASK(sdioc->cap); if (maskbit < 32 || maskbit > SSSRAID_DMA_MSK_BIT_MAX) { - ioc_err(sdioc, "err: DMA MASK BIT invalid[%llu], set to default\n", maskbit); + ioc_notice(sdioc, "err: DMA MASK BIT invalid[%llu], set to default\n", maskbit); maskbit = SSSRAID_DMA_MSK_BIT_MAX; } @@ -352,13 +357,16 @@ static int sssraid_alloc_qpair(struct sssraid_ioc *sdioc, u16 qidx, u16 depth) cqinfo->cqes = dma_alloc_coherent(&sdioc->pdev->dev, CQ_SIZE(depth), &cqinfo->cq_dma_addr, GFP_KERNEL | __GFP_ZERO); - if (!cqinfo->cqes) + if (!cqinfo->cqes) { + ioc_err(sdioc, "failure at alloc dma space for cqueue.\n"); return -ENOMEM; + } sqinfo->sq_cmds = dma_alloc_coherent(&sdioc->pdev->dev, SQ_SIZE(qidx, depth), &sqinfo->sq_dma_addr, GFP_KERNEL); if (!sqinfo->sq_cmds) { retval = -ENOMEM; + ioc_err(sdioc, "failure at alloc dma space for squeue cmds.\n"); goto free_cqes; } @@ -367,6 +375,7 @@ static int sssraid_alloc_qpair(struct sssraid_ioc *sdioc, u16 qidx, u16 depth) &sqinfo->sense_dma_addr, GFP_KERNEL | __GFP_ZERO); if (!sqinfo->sense) { retval = -ENOMEM; + ioc_err(sdioc, "failure at alloc dma space for sense data.\n"); goto free_sq_cmds; } @@ -420,8 +429,10 @@ static int sssraid_setup_admin_qpair(struct sssraid_ioc *sdioc) ioc_info(sdioc, "Starting disable ctrl...\n"); retval = sssraid_disable_ctrl(sdioc); - if (retval) + if (retval) { + ioc_err(sdioc, "disable ctrl failed\n"); return retval; + } /* this func don't alloc admin queue */ @@ -435,6 +446,7 @@ static int sssraid_setup_admin_qpair(struct sssraid_ioc *sdioc) retval = sssraid_enable_ctrl(sdioc); if (retval) { + ioc_err(sdioc, "enable ctrl failed\n"); retval = -ENODEV; return retval; } @@ -633,7 +645,7 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one) goto out_failed; } if (i != max_vectors) { - ioc_info(sdioc, + ioc_warn(sdioc, "Allocated vectors (%d) are less than requested (%d)\n", i, max_vectors); @@ -643,7 +655,8 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one) sdioc->intr_info = kzalloc(sizeof(struct sssraid_intr_info) * max_vectors, GFP_KERNEL); if (!sdioc->intr_info) { - retval = -1; + retval = -ENOMEM; + ioc_err(sdioc, "err: failed to alloc memory for intr_info!\n"); pci_free_irq_vectors(sdioc->pdev); goto out_failed; } @@ -651,6 +664,7 @@ static int sssraid_setup_isr(struct sssraid_ioc *sdioc, u8 setup_one) for (i = 0; i < max_vectors; i++) { retval = sssraid_request_irq(sdioc, i); if (retval) { + ioc_err(sdioc, "err: request irq for pci device failed.\n"); sdioc->intr_info_count = i; /* =i is for offload interrupt loop counter */ goto out_failed; } @@ -1174,14 +1188,16 @@ static inline void sssraid_send_all_aen(struct sssraid_ioc *sdioc) sssraid_send_event_ack(sdioc, 0, 0, i + SSSRAID_AMDQ_BLK_MQ_DEPTH); } -static int sssraid_dev_list_init(struct sssraid_ioc *sdioc) +static int sssraid_disk_list_init(struct sssraid_ioc *sdioc) { u32 nd = le32_to_cpu(sdioc->ctrl_info->nd); sdioc->devices = kzalloc_node(nd * sizeof(struct sssraid_dev_info), GFP_KERNEL, sdioc->numa_node); - if (!sdioc->devices) + if (!sdioc->devices) { + ioc_err(sdioc, "err: failed to alloc memory for device info.\n"); return -ENOMEM; + } return 0; } @@ -1331,7 +1347,7 @@ int sssraid_init_ioc(struct sssraid_ioc *sdioc, u8 re_init) sssraid_send_all_aen(sdioc); if (!re_init) { - retval = sssraid_dev_list_init(sdioc); + retval = sssraid_disk_list_init(sdioc); if (retval) { ioc_err(sdioc, "Failed to init device list, error %d\n", retval); @@ -1358,6 +1374,7 @@ void sssraid_cleanup_resources(struct sssraid_ioc *sdioc) { struct pci_dev *pdev = sdioc->pdev; + pci_set_drvdata(pdev, NULL); sssraid_cleanup_isr(sdioc); if (sdioc->bar) { @@ -1372,6 +1389,12 @@ void sssraid_cleanup_resources(struct sssraid_ioc *sdioc) } } +static void sssraid_free_disk_list(struct sssraid_ioc *sdioc) +{ + kfree(sdioc->devices); + sdioc->devices = NULL; +} + static void sssraid_free_ioq_ptcmds(struct sssraid_ioc *sdioc) { kfree(sdioc->ioq_ptcmds); @@ -1382,7 +1405,7 @@ static void sssraid_free_ioq_ptcmds(struct sssraid_ioc *sdioc) static void sssraid_delete_io_queues(struct sssraid_ioc *sdioc) { - u16 queues = sdioc->init_done_queue_cnt - 1; + u16 queues = sdioc->init_done_queue_cnt - SSSRAID_ADM_QUEUE_NUM; u8 opcode = SSSRAID_ADM_DELETE_SQ; u16 i, pass; @@ -1391,7 +1414,7 @@ static void sssraid_delete_io_queues(struct sssraid_ioc *sdioc) return; } - if (sdioc->init_done_queue_cnt < 2) { + if (sdioc->init_done_queue_cnt <= SSSRAID_ADM_QUEUE_NUM) { ioc_err(sdioc, "Err: io queue has been delete\n"); return; } @@ -1669,8 +1692,10 @@ static void sssraid_free_resources(struct sssraid_ioc *sdioc) void sssraid_cleanup_ioc(struct sssraid_ioc *sdioc, u8 re_init) { - if (!re_init) + if (!re_init) { + sssraid_free_disk_list(sdioc); sssraid_free_ioq_ptcmds(sdioc); + } sssraid_delete_io_queues(sdioc); sssraid_disable_admin_queue(sdioc, !re_init); diff --git a/drivers/scsi/sssraid/sssraid_os.c b/drivers/scsi/sssraid/sssraid_os.c index ac49a439b68e770ce39c60a88dba97995758f630..45542dc0e0e1c4203548ba2d1389e64d14d72fd5 100644 --- a/drivers/scsi/sssraid/sssraid_os.c +++ b/drivers/scsi/sssraid/sssraid_os.c @@ -308,7 +308,7 @@ void sssraid_cleanup_fwevt_list(struct sssraid_ioc *sdioc) */ static int sssraid_npages_prp(struct sssraid_ioc *sdioc) { - u32 size = 1U << ((sdioc->ctrl_info->mdts) * 1U) << 12; + u32 size = (1U << ((sdioc->ctrl_info->mdts) * 1U)) << 12; u32 nprps = DIV_ROUND_UP(size + sdioc->page_size, sdioc->page_size); return DIV_ROUND_UP(PRP_ENTRY_SIZE * nprps, sdioc->page_size - PRP_ENTRY_SIZE); @@ -619,7 +619,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, } /* 6-byte READ(0x08) or WRITE(0x0A) cdb */ - if (scmd->cmd_len == 6) { + if (scmd->cmd_len == SCSI_6_BYTE_CDB_LEN) { datalength = (u32)(scmd->cmnd[4] == 0 ? IO_6_DEFAULT_TX_LEN : scmd->cmnd[4]); start_lba_lo = (u32)get_unaligned_be24(&scmd->cmnd[1]); @@ -628,7 +628,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, } /* 10-byte READ(0x28) or WRITE(0x2A) cdb */ - else if (scmd->cmd_len == 10) { + else if (scmd->cmd_len == SCSI_10_BYTE_CDB_LEN) { datalength = (u32)get_unaligned_be16(&scmd->cmnd[7]); start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]); @@ -637,7 +637,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, } /* 12-byte READ(0xA8) or WRITE(0xAA) cdb */ - else if (scmd->cmd_len == 12) { + else if (scmd->cmd_len == SCSI_12_BYTE_CDB_LEN) { datalength = get_unaligned_be32(&scmd->cmnd[6]); start_lba_lo = get_unaligned_be32(&scmd->cmnd[2]); @@ -645,7 +645,7 @@ static int sssraid_setup_rw_cmd(struct sssraid_ioc *sdioc, control |= SSSRAID_RW_FUA; } /* 16-byte READ(0x88) or WRITE(0x8A) cdb */ - else if (scmd->cmd_len == 16) { + else if (scmd->cmd_len == SCSI_16_BYTE_CDB_LEN) { datalength = get_unaligned_be32(&scmd->cmnd[10]); start_lba_lo = get_unaligned_be32(&scmd->cmnd[6]); start_lba_hi = get_unaligned_be32(&scmd->cmnd[2]); @@ -1068,6 +1068,7 @@ bool sssraid_change_host_state(struct sssraid_ioc *sdioc, enum sssraid_state new default: break; } + if (change) sdioc->state = newstate; spin_unlock_irqrestore(&sdioc->state_lock, flags); @@ -1387,14 +1388,6 @@ static int sssraid_bsg_host_dispatch(struct bsg_job *job) return 0; } -static inline void sssraid_remove_bsg(struct sssraid_ioc *sdioc) -{ - if (sdioc->bsg_queue) { - bsg_unregister_queue(sdioc->bsg_queue); - blk_cleanup_queue(sdioc->bsg_queue); - } -} - static void sssraid_back_fault_cqe(struct sssraid_squeue *sqinfo, struct sssraid_completion *cqe) { struct sssraid_ioc *sdioc = sqinfo->sdioc; @@ -2102,7 +2095,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct sssraid_ioc *sdioc; struct Scsi_Host *shost; int node; - char bsg_name[15]; + char bsg_name[BSG_NAME_SIZE]; int retval = 0; node = dev_to_node(&pdev->dev); @@ -2114,14 +2107,15 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) shost = scsi_host_alloc(&sssraid_driver_template, sizeof(*sdioc)); if (!shost) { retval = -ENODEV; - ioc_err(sdioc, "err: failed to allocate scsi host\n"); + dev_err(&pdev->dev, "err: failed to allocate scsi host\n"); goto shost_failed; } sdioc = shost_priv(shost); sdioc->numa_node = node; sdioc->instance = shost->host_no; /* for device instance */ - sprintf(sdioc->name, "%s%d", SSSRAID_DRIVER_NAME, sdioc->instance); + snprintf(sdioc->name, sizeof(sdioc->name), + "%s%d", SSSRAID_DRIVER_NAME, sdioc->instance); init_rwsem(&sdioc->devices_rwsem); spin_lock_init(&sdioc->state_lock); @@ -2131,7 +2125,6 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&sdioc->fwevt_list); -// logging_level = 1; //garden test sdioc->logging_level = logging_level; /* according to log_debug_switch*/ snprintf(sdioc->fwevt_worker_name, sizeof(sdioc->fwevt_worker_name), @@ -2139,8 +2132,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) sdioc->fwevt_worker_thread = alloc_ordered_workqueue( sdioc->fwevt_worker_name, WQ_MEM_RECLAIM); if (!sdioc->fwevt_worker_thread) { - ioc_err(sdioc, "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__); + ioc_err(sdioc, "err: fail to alloc workqueue for fwevt_work!\n"); retval = -ENODEV; goto out_fwevtthread_failed; } @@ -2149,8 +2141,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) sdioc->pdev = pdev; if (sssraid_init_ioc(sdioc, 0)) { - ioc_err(sdioc, "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__); + ioc_err(sdioc, "err: failure at init sssraid_ioc!\n"); retval = -ENODEV; goto out_iocinit_failed; } @@ -2159,8 +2150,7 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) retval = scsi_add_host(shost, &pdev->dev); if (retval) { - ioc_err(sdioc, "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__); + ioc_err(sdioc, "err: add shost to system failed!\n"); goto addhost_failed; } @@ -2168,16 +2158,22 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) sdioc->bsg_queue = bsg_setup_queue(&shost->shost_gendev, bsg_name, sssraid_bsg_host_dispatch, NULL, sssraid_cmd_size(sdioc)); if (IS_ERR(sdioc->bsg_queue)) { - ioc_err(sdioc, "err: setup bsg failed\n"); + ioc_err(sdioc, "err: setup bsg failed!\n"); sdioc->bsg_queue = NULL; goto bsg_setup_failed; } - sssraid_change_host_state(sdioc, SSSRAID_LIVE); + if (!sssraid_change_host_state(sdioc, SSSRAID_LIVE)) { + retval = -ENODEV; + ioc_err(sdioc, "err: change host state failed!\n"); + goto sssraid_state_change_failed; + } scsi_scan_host(shost); return retval; +sssraid_state_change_failed: + bsg_remove_queue(sdioc->bsg_queue); bsg_setup_failed: scsi_remove_host(shost); addhost_failed: @@ -2193,15 +2189,15 @@ sssraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void sssraid_remove(struct pci_dev *pdev) { struct Scsi_Host *shost = pci_get_drvdata(pdev); - struct sssraid_ioc *sdioc; + struct sssraid_ioc *sdioc = NULL; - if (!shost) + if (!shost) { + dev_err(&pdev->dev, "driver probe process failed, remove not be allowed.\n"); return; - - ioc_info(sdioc, "sssraid remove entry\n"); - + } sdioc = shost_priv(shost); + ioc_info(sdioc, "sssraid remove entry\n"); sssraid_change_host_state(sdioc, SSSRAID_DELETING); if (!pci_device_is_present(pdev)) @@ -2210,7 +2206,7 @@ static void sssraid_remove(struct pci_dev *pdev) sssraid_cleanup_fwevt_list(sdioc); destroy_workqueue(sdioc->fwevt_worker_thread); - sssraid_remove_bsg(sdioc); + bsg_remove_queue(sdioc->bsg_queue); scsi_remove_host(shost); sssraid_cleanup_ioc(sdioc, 0); @@ -2399,11 +2395,11 @@ static int __init sssraid_init(void) static void __exit sssraid_exit(void) { + pci_unregister_driver(&sssraid_pci_driver); + class_destroy(sssraid_class); + pr_info("Unloading %s version %s\n", SSSRAID_DRIVER_NAME, SSSRAID_DRIVER_VERSION); - - class_destroy(sssraid_class); - pci_unregister_driver(&sssraid_pci_driver); } MODULE_AUTHOR("steven.song@3snic.com");