diff options
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r-- | drivers/scsi/megaraid/mega_common.h | 1 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_mbox.c | 185 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_mbox.h | 4 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_mm.c | 3 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 116 |
5 files changed, 73 insertions, 236 deletions
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h index 26e1e6c5565..fef9ac95875 100644 --- a/drivers/scsi/megaraid/mega_common.h +++ b/drivers/scsi/megaraid/mega_common.h @@ -21,6 +21,7 @@ #include <linux/types.h> #include <linux/pci.h> #include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/blkdev.h> diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 04d0b6918c6..c6a53dccc16 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -454,7 +454,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_master(pdev); // Allocate the per driver initialization structure - adapter = kmalloc(sizeof(adapter_t), GFP_KERNEL); + adapter = kzalloc(sizeof(adapter_t), GFP_KERNEL); if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -462,7 +462,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto out_probe_one; } - memset(adapter, 0, sizeof(adapter_t)); // set up PCI related soft state and other pre-known parameters @@ -746,10 +745,9 @@ megaraid_init_mbox(adapter_t *adapter) * Allocate and initialize the init data structure for mailbox * controllers */ - raid_dev = kmalloc(sizeof(mraid_device_t), GFP_KERNEL); + raid_dev = kzalloc(sizeof(mraid_device_t), GFP_KERNEL); if (raid_dev == NULL) return -1; - memset(raid_dev, 0, sizeof(mraid_device_t)); /* * Attach the adapter soft state to raid device soft state @@ -1050,8 +1048,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) * since the calling routine does not yet know the number of available * commands. */ - adapter->kscb_list = kmalloc(sizeof(scb_t) * MBOX_MAX_SCSI_CMDS, - GFP_KERNEL); + adapter->kscb_list = kcalloc(MBOX_MAX_SCSI_CMDS, sizeof(scb_t), GFP_KERNEL); if (adapter->kscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -1059,7 +1056,6 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) __LINE__)); goto out_free_ibuf; } - memset(adapter->kscb_list, 0, sizeof(scb_t) * MBOX_MAX_SCSI_CMDS); // memory allocation for our command packets if (megaraid_mbox_setup_dma_pools(adapter) != 0) { @@ -1378,8 +1374,6 @@ megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb) { struct scatterlist *sgl; mbox_ccb_t *ccb; - struct page *page; - unsigned long offset; struct scsi_cmnd *scp; int sgcnt; int i; @@ -1388,48 +1382,16 @@ megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb) scp = scb->scp; ccb = (mbox_ccb_t *)scb->ccb; + sgcnt = scsi_dma_map(scp); + BUG_ON(sgcnt < 0 || sgcnt > adapter->sglen); + // no mapping required if no data to be transferred - if (!scp->request_buffer || !scp->request_bufflen) + if (!sgcnt) return 0; - if (!scp->use_sg) { /* scatter-gather list not used */ - - page = virt_to_page(scp->request_buffer); - - offset = ((unsigned long)scp->request_buffer & ~PAGE_MASK); - - ccb->buf_dma_h = pci_map_page(adapter->pdev, page, offset, - scp->request_bufflen, - scb->dma_direction); - scb->dma_type = MRAID_DMA_WBUF; - - /* - * We need to handle special 64-bit commands that need a - * minimum of 1 SG - */ - sgcnt = 1; - ccb->sgl64[0].address = ccb->buf_dma_h; - ccb->sgl64[0].length = scp->request_bufflen; - - return sgcnt; - } - - sgl = (struct scatterlist *)scp->request_buffer; - - // The number of sg elements returned must not exceed our limit - sgcnt = pci_map_sg(adapter->pdev, sgl, scp->use_sg, - scb->dma_direction); - - if (sgcnt > adapter->sglen) { - con_log(CL_ANN, (KERN_CRIT - "megaraid critical: too many sg elements:%d\n", - sgcnt)); - BUG(); - } - scb->dma_type = MRAID_DMA_WSG; - for (i = 0; i < sgcnt; i++, sgl++) { + scsi_for_each_sg(scp, sgl, sgcnt, i) { ccb->sgl64[i].address = sg_dma_address(sgl); ccb->sgl64[i].length = sg_dma_len(sgl); } @@ -1489,19 +1451,11 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb) adapter->outstanding_cmds++; - if (scb->dma_direction == PCI_DMA_TODEVICE) { - if (!scb->scp->use_sg) { // sg list not used - pci_dma_sync_single_for_device(adapter->pdev, - ccb->buf_dma_h, - scb->scp->request_bufflen, - PCI_DMA_TODEVICE); - } - else { - pci_dma_sync_sg_for_device(adapter->pdev, - scb->scp->request_buffer, - scb->scp->use_sg, PCI_DMA_TODEVICE); - } - } + if (scb->dma_direction == PCI_DMA_TODEVICE) + pci_dma_sync_sg_for_device(adapter->pdev, + scsi_sglist(scb->scp), + scsi_sg_count(scb->scp), + PCI_DMA_TODEVICE); mbox->busy = 1; // Set busy mbox->poll = 0; @@ -1624,29 +1578,26 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) return scb; case MODE_SENSE: - if (scp->use_sg) { - struct scatterlist *sgl; - caddr_t vaddr; + { + struct scatterlist *sgl; + caddr_t vaddr; - sgl = (struct scatterlist *)scp->request_buffer; - if (sgl->page) { - vaddr = (caddr_t) - (page_address((&sgl[0])->page) - + (&sgl[0])->offset); + sgl = scsi_sglist(scp); + if (sgl->page) { + vaddr = (caddr_t) + (page_address((&sgl[0])->page) + + (&sgl[0])->offset); - memset(vaddr, 0, scp->cmnd[4]); - } - else { - con_log(CL_ANN, (KERN_WARNING - "megaraid mailbox: invalid sg:%d\n", - __LINE__)); - } + memset(vaddr, 0, scp->cmnd[4]); } else { - memset(scp->request_buffer, 0, scp->cmnd[4]); + con_log(CL_ANN, (KERN_WARNING + "megaraid mailbox: invalid sg:%d\n", + __LINE__)); } - scp->result = (DID_OK << 16); - return NULL; + } + scp->result = (DID_OK << 16); + return NULL; case INQUIRY: /* @@ -1716,7 +1667,7 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) mbox->cmd = MBOXCMD_PASSTHRU64; scb->dma_direction = scp->sc_data_direction; - pthru->dataxferlen = scp->request_bufflen; + pthru->dataxferlen = scsi_bufflen(scp); pthru->dataxferaddr = ccb->sgl_dma_h; pthru->numsge = megaraid_mbox_mksgl(adapter, scb); @@ -2050,8 +2001,8 @@ megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb, memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); - if (scp->request_bufflen) { - pthru->dataxferlen = scp->request_bufflen; + if (scsi_bufflen(scp)) { + pthru->dataxferlen = scsi_bufflen(scp); pthru->dataxferaddr = ccb->sgl_dma_h; pthru->numsge = megaraid_mbox_mksgl(adapter, scb); } @@ -2099,8 +2050,8 @@ megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb, memcpy(epthru->cdb, scp->cmnd, scp->cmd_len); - if (scp->request_bufflen) { - epthru->dataxferlen = scp->request_bufflen; + if (scsi_bufflen(scp)) { + epthru->dataxferlen = scsi_bufflen(scp); epthru->dataxferaddr = ccb->sgl_dma_h; epthru->numsge = megaraid_mbox_mksgl(adapter, scb); } @@ -2266,37 +2217,13 @@ megaraid_mbox_sync_scb(adapter_t *adapter, scb_t *scb) ccb = (mbox_ccb_t *)scb->ccb; - switch (scb->dma_type) { - - case MRAID_DMA_WBUF: - if (scb->dma_direction == PCI_DMA_FROMDEVICE) { - pci_dma_sync_single_for_cpu(adapter->pdev, - ccb->buf_dma_h, - scb->scp->request_bufflen, + if (scb->dma_direction == PCI_DMA_FROMDEVICE) + pci_dma_sync_sg_for_cpu(adapter->pdev, + scsi_sglist(scb->scp), + scsi_sg_count(scb->scp), PCI_DMA_FROMDEVICE); - } - - pci_unmap_page(adapter->pdev, ccb->buf_dma_h, - scb->scp->request_bufflen, scb->dma_direction); - - break; - - case MRAID_DMA_WSG: - if (scb->dma_direction == PCI_DMA_FROMDEVICE) { - pci_dma_sync_sg_for_cpu(adapter->pdev, - scb->scp->request_buffer, - scb->scp->use_sg, PCI_DMA_FROMDEVICE); - } - - pci_unmap_sg(adapter->pdev, scb->scp->request_buffer, - scb->scp->use_sg, scb->dma_direction); - - break; - - default: - break; - } + scsi_dma_unmap(scb->scp); return; } @@ -2399,24 +2326,16 @@ megaraid_mbox_dpc(unsigned long devp) if (scp->cmnd[0] == INQUIRY && status == 0 && islogical == 0 && IS_RAID_CH(raid_dev, scb->dev_channel)) { - if (scp->use_sg) { - sgl = (struct scatterlist *) - scp->request_buffer; - - if (sgl->page) { - c = *(unsigned char *) + sgl = scsi_sglist(scp); + if (sgl->page) { + c = *(unsigned char *) (page_address((&sgl[0])->page) + - (&sgl[0])->offset); - } - else { - con_log(CL_ANN, (KERN_WARNING - "megaraid mailbox: invalid sg:%d\n", - __LINE__)); - c = 0; - } - } - else { - c = *(uint8_t *)scp->request_buffer; + (&sgl[0])->offset); + } else { + con_log(CL_ANN, (KERN_WARNING + "megaraid mailbox: invalid sg:%d\n", + __LINE__)); + c = 0; } if ((c & 0x1F ) == TYPE_DISK) { @@ -3572,8 +3491,7 @@ megaraid_cmm_register(adapter_t *adapter) int i; // Allocate memory for the base list of scb for management module. - adapter->uscb_list = kmalloc(sizeof(scb_t) * MBOX_MAX_USER_CMDS, - GFP_KERNEL); + adapter->uscb_list = kcalloc(MBOX_MAX_USER_CMDS, sizeof(scb_t), GFP_KERNEL); if (adapter->uscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -3581,7 +3499,6 @@ megaraid_cmm_register(adapter_t *adapter) __LINE__)); return -1; } - memset(adapter->uscb_list, 0, sizeof(scb_t) * MBOX_MAX_USER_CMDS); // Initialize the synchronization parameters for resources for @@ -3957,7 +3874,7 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter) megaraid_sysfs_free_resources(adapter); } - sema_init(&raid_dev->sysfs_sem, 1); + mutex_init(&raid_dev->sysfs_mtx); init_waitqueue_head(&raid_dev->sysfs_wait_q); @@ -4058,7 +3975,7 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) /* * Allow only one read at a time to go through the sysfs attributes */ - down(&raid_dev->sysfs_sem); + mutex_lock(&raid_dev->sysfs_mtx); uioc = raid_dev->sysfs_uioc; mbox64 = raid_dev->sysfs_mbox64; @@ -4134,7 +4051,7 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) del_timer_sync(timerp); - up(&raid_dev->sysfs_sem); + mutex_unlock(&raid_dev->sysfs_mtx); return rval; } diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h index 9de803cebd4..626459d1e90 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.h +++ b/drivers/scsi/megaraid/megaraid_mbox.h @@ -168,7 +168,7 @@ typedef struct { * @hw_error : set if FW not responding * @fast_load : If set, skip physical device scanning * @channel_class : channel class, RAID or SCSI - * @sysfs_sem : semaphore to serialize access to sysfs res. + * @sysfs_mtx : mutex to serialize access to sysfs res. * @sysfs_uioc : management packet to issue FW calls from sysfs * @sysfs_mbox64 : mailbox packet to issue FW calls from sysfs * @sysfs_buffer : data buffer for FW commands issued from sysfs @@ -208,7 +208,7 @@ typedef struct { int hw_error; int fast_load; uint8_t channel_class; - struct semaphore sysfs_sem; + struct mutex sysfs_mtx; uioc_t *sysfs_uioc; mbox64_t *sysfs_mbox64; caddr_t sysfs_buffer; diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 84d9c27133d..b6587a6d848 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -890,12 +890,11 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) if (lld_adp->drvr_type != DRVRTYPE_MBOX) return (-EINVAL); - adapter = kmalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); + adapter = kzalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); if (!adapter) return -ENOMEM; - memset(adapter, 0, sizeof(mraid_mmadp_t)); adapter->unique_id = lld_adp->unique_id; adapter->drvr_type = lld_adp->drvr_type; diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index e2cf12ef368..ebb948c016b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -433,34 +433,15 @@ megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp, int sge_count; struct scatterlist *os_sgl; - /* - * Return 0 if there is no data transfer - */ - if (!scp->request_buffer || !scp->request_bufflen) - return 0; + sge_count = scsi_dma_map(scp); + BUG_ON(sge_count < 0); - if (!scp->use_sg) { - mfi_sgl->sge32[0].phys_addr = pci_map_single(instance->pdev, - scp-> - request_buffer, - scp-> - request_bufflen, - scp-> - sc_data_direction); - mfi_sgl->sge32[0].length = scp->request_bufflen; - - return 1; - } - - os_sgl = (struct scatterlist *)scp->request_buffer; - sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg, - scp->sc_data_direction); - - for (i = 0; i < sge_count; i++, os_sgl++) { - mfi_sgl->sge32[i].length = sg_dma_len(os_sgl); - mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl); + if (sge_count) { + scsi_for_each_sg(scp, os_sgl, sge_count, i) { + mfi_sgl->sge32[i].length = sg_dma_len(os_sgl); + mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl); + } } - return sge_count; } @@ -481,35 +462,15 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, int sge_count; struct scatterlist *os_sgl; - /* - * Return 0 if there is no data transfer - */ - if (!scp->request_buffer || !scp->request_bufflen) - return 0; - - if (!scp->use_sg) { - mfi_sgl->sge64[0].phys_addr = pci_map_single(instance->pdev, - scp-> - request_buffer, - scp-> - request_bufflen, - scp-> - sc_data_direction); - - mfi_sgl->sge64[0].length = scp->request_bufflen; - - return 1; - } - - os_sgl = (struct scatterlist *)scp->request_buffer; - sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg, - scp->sc_data_direction); + sge_count = scsi_dma_map(scp); + BUG_ON(sge_count < 0); - for (i = 0; i < sge_count; i++, os_sgl++) { - mfi_sgl->sge64[i].length = sg_dma_len(os_sgl); - mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl); + if (sge_count) { + scsi_for_each_sg(scp, os_sgl, sge_count, i) { + mfi_sgl->sge64[i].length = sg_dma_len(os_sgl); + mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl); + } } - return sge_count; } @@ -593,7 +554,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, pthru->cdb_len = scp->cmd_len; pthru->timeout = 0; pthru->flags = flags; - pthru->data_xfer_len = scp->request_bufflen; + pthru->data_xfer_len = scsi_bufflen(scp); memcpy(pthru->cdb, scp->cmnd, scp->cmd_len); @@ -1195,45 +1156,6 @@ megasas_complete_abort(struct megasas_instance *instance, } /** - * megasas_unmap_sgbuf - Unmap SG buffers - * @instance: Adapter soft state - * @cmd: Completed command - */ -static void -megasas_unmap_sgbuf(struct megasas_instance *instance, struct megasas_cmd *cmd) -{ - dma_addr_t buf_h; - u8 opcode; - - if (cmd->scmd->use_sg) { - pci_unmap_sg(instance->pdev, cmd->scmd->request_buffer, - cmd->scmd->use_sg, cmd->scmd->sc_data_direction); - return; - } - - if (!cmd->scmd->request_bufflen) - return; - - opcode = cmd->frame->hdr.cmd; - - if ((opcode == MFI_CMD_LD_READ) || (opcode == MFI_CMD_LD_WRITE)) { - if (IS_DMA64) - buf_h = cmd->frame->io.sgl.sge64[0].phys_addr; - else - buf_h = cmd->frame->io.sgl.sge32[0].phys_addr; - } else { - if (IS_DMA64) - buf_h = cmd->frame->pthru.sgl.sge64[0].phys_addr; - else - buf_h = cmd->frame->pthru.sgl.sge32[0].phys_addr; - } - - pci_unmap_single(instance->pdev, buf_h, cmd->scmd->request_bufflen, - cmd->scmd->sc_data_direction); - return; -} - -/** * megasas_complete_cmd - Completes a command * @instance: Adapter soft state * @cmd: Command to be completed @@ -1281,7 +1203,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, atomic_dec(&instance->fw_outstanding); - megasas_unmap_sgbuf(instance, cmd); + scsi_dma_unmap(cmd->scmd); cmd->scmd->scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd); @@ -1329,7 +1251,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, atomic_dec(&instance->fw_outstanding); - megasas_unmap_sgbuf(instance, cmd); + scsi_dma_unmap(cmd->scmd); cmd->scmd->scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd); @@ -1714,15 +1636,13 @@ static int megasas_alloc_cmds(struct megasas_instance *instance) * Allocate the dynamic array first and then allocate individual * commands. */ - instance->cmd_list = kmalloc(sizeof(struct megasas_cmd *) * max_cmd, - GFP_KERNEL); + instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL); if (!instance->cmd_list) { printk(KERN_DEBUG "megasas: out of memory\n"); return -ENOMEM; } - memset(instance->cmd_list, 0, sizeof(struct megasas_cmd *) * max_cmd); for (i = 0; i < max_cmd; i++) { instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd), |