From a684b8da35a429a246ec2a91e2742bdff5209709 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 24 Jan 2011 14:57:28 +0100 Subject: [SCSI] remove flush_scheduled_work() usages Simple conversions to drop flush_scheduled_work() usages in drivers/scsi. More involved ones will be done in separate patches. * NCR5380, megaraid_sas: cancel_delayed_work() + flush_scheduled_work() -> cancel_delayed_work_sync(). * mpt2sas_scsih: drop unnecessary flush_scheduled_work(). * arcmsr_hba, ipr, pmcraid: flush the used work explicitly instead of using flush_scheduled_work(). Signed-off-by: Tejun Heo Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5d6d07bd1cd0..e7c9b41def7b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4242,9 +4242,8 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) /* cancel the delayed work if this work still in queue */ if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; - cancel_delayed_work( + cancel_delayed_work_sync( (struct delayed_work *)&ev->hotplug_work); - flush_scheduled_work(); instance->ev = NULL; } @@ -4417,9 +4416,8 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev) /* cancel the delayed work if this work still in queue*/ if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; - cancel_delayed_work( + cancel_delayed_work_sync( (struct delayed_work *)&ev->hotplug_work); - flush_scheduled_work(); instance->ev = NULL; } -- cgit v1.2.1 From 98cb7e4413d189cd2b54daf993a4667d9788c0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 19 Jan 2011 10:01:14 +0100 Subject: [SCSI] megaraid_sas: Sanity check user supplied length before passing it to dma_alloc_coherent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ioc->sgl[i].iov_len value is supplied by the ioctl caller, and can be zero in some cases. Assume that's valid and continue without error. Fixes (multiple individual reports of the same problem for quite a while): http://marc.info/?l=linux-ide&m=128941801715301 http://bugs.debian.org/604627 http://www.mail-archive.com/linux-poweredge@dell.com/msg02575.html megasas: Failed to alloc kernel SGL buffer for IOCTL and [ 69.162538] ------------[ cut here ]------------ [ 69.162806] kernel BUG at /build/buildd/linux-2.6.32/lib/swiotlb.c:368! [ 69.163134] invalid opcode: 0000 [#1] SMP [ 69.163570] last sysfs file: /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_map [ 69.163975] CPU 0 [ 69.164227] Modules linked in: fbcon tileblit font bitblit softcursor vga16fb vgastate ioatdma radeon ttm drm_kms_helper shpchp drm i2c_algo_bit lp parport floppy pata_jmicron megaraid_sas igb dca [ 69.167419] Pid: 1206, comm: smartctl Tainted: G W 2.6.32-25-server #45-Ubuntu X8DTN [ 69.167843] RIP: 0010:[] [] map_single+0x255/0x260 [ 69.168370] RSP: 0018:ffff88081c0ebc58 EFLAGS: 00010246 [ 69.168655] RAX: 000000000003bffc RBX: 00000000ffffffff RCX: 0000000000000002 [ 69.169000] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88001dffe000 [ 69.169346] RBP: ffff88081c0ebcb8 R08: 0000000000000000 R09: ffff880000030840 [ 69.169691] R10: 0000000000100000 R11: 0000000000000000 R12: 0000000000000000 [ 69.170036] R13: 00000000ffffffff R14: 0000000000000001 R15: 0000000000200000 [ 69.170382] FS: 00007fb8de189720(0000) GS:ffff88001de00000(0000) knlGS:0000000000000000 [ 69.170794] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 69.171094] CR2: 00007fb8dd59237c CR3: 000000081a790000 CR4: 00000000000006f0 [ 69.171439] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 69.171784] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 69.172130] Process smartctl (pid: 1206, threadinfo ffff88081c0ea000, task ffff88081a760000) [ 69.194513] Stack: [ 69.205788] 0000000000000034 00000002817e3390 0000000000000000 ffff88081c0ebe00 [ 69.217739] <0> 0000000000000000 000000000003bffc 0000000000000000 0000000000000000 [ 69.241250] <0> 0000000000000000 00000000ffffffff ffff88081c5b4080 ffff88081c0ebe00 [ 69.277310] Call Trace: [ 69.289278] [] swiotlb_alloc_coherent+0xec/0x130 [ 69.301118] [] x86_swiotlb_alloc_coherent+0x61/0x70 [ 69.313045] [] megasas_mgmt_fw_ioctl+0x1ae/0x690 [megaraid_sas] [ 69.336399] [] megasas_mgmt_ioctl_fw+0x198/0x240 [megaraid_sas] [ 69.359346] [] megasas_mgmt_ioctl+0x35/0x50 [megaraid_sas] [ 69.370902] [] vfs_ioctl+0x22/0xa0 [ 69.382322] [] ? alloc_fd+0x10a/0x150 [ 69.393622] [] do_vfs_ioctl+0x81/0x410 [ 69.404696] [] ? do_page_fault+0x153/0x3b0 [ 69.415761] [] sys_ioctl+0x81/0xa0 [ 69.426640] [] system_call_fastpath+0x16/0x1b [ 69.437491] Code: fe ff ff 48 8b 3d 74 38 76 00 41 bf 00 00 20 00 e8 51 f5 d7 ff 83 e0 ff 48 05 ff 07 00 00 48 c1 e8 0b 48 89 45 c8 e9 13 fe ff ff <0f> 0b eb fe 0f 1f 80 00 00 00 00 55 48 89 e5 48 83 ec 20 4c 89 [ 69.478216] RIP [] map_single+0x255/0x260 [ 69.489668] RSP [ 69.500975] ---[ end trace 6a2181b634e2abc7 ]--- Reported-by: Bokhan Artem Reported by: Marc-Christian Petersen Signed-off-by: Bjørn Mork Cc: "Benz, Michael" Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index e7c9b41def7b..b71caa3f44ea 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4609,6 +4609,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, * For each user buffer, create a mirror buffer and copy in */ for (i = 0; i < ioc->sge_count; i++) { + if (!ioc->sgl[i].iov_len) + continue; + kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev, ioc->sgl[i].iov_len, &buf_handle, GFP_KERNEL); -- cgit v1.2.1 From eb1b12377376e43aae4be338ffbbc32931ca4d10 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:55:56 -0800 Subject: [SCSI] megaraid_sas: Fix failure gotos Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 17 ++++++++--------- drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 ++++-- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b71caa3f44ea..c4ac4a5a075a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3424,7 +3424,6 @@ fail_reply_queue: megasas_free_cmds(instance); fail_alloc_cmds: - iounmap(instance->reg_set); return 1; } @@ -3494,7 +3493,7 @@ static int megasas_init_fw(struct megasas_instance *instance) /* Get operational params, sge flags, send init cmd to controller */ if (instance->instancet->init_adapter(instance)) - return -ENODEV; + goto fail_init_adapter; printk(KERN_ERR "megasas: INIT adapter done\n"); @@ -3553,6 +3552,7 @@ static int megasas_init_fw(struct megasas_instance *instance) MEGASAS_COMPLETION_TIMER_INTERVAL); return 0; +fail_init_adapter: fail_ready_state: iounmap(instance->reg_set); @@ -4105,10 +4105,13 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) instance->instancet->disable_intr(instance->reg_set); free_irq(instance->msi_flag ? instance->msixentry.vector : instance->pdev->irq, instance); +fail_irq: if (instance->msi_flag) pci_disable_msix(instance->pdev); - - fail_irq: + if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) + megasas_release_fusion(instance); + else + megasas_release_mfi(instance); fail_init_mfi: fail_alloc_dma_buf: if (instance->evt_detail) @@ -4116,13 +4119,9 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) instance->evt_detail, instance->evt_detail_h); - if (instance->producer) { + if (instance->producer) pci_free_consistent(pdev, sizeof(u32), instance->producer, instance->producer_h); - megasas_release_mfi(instance); - } else { - megasas_release_fusion(instance); - } if (instance->consumer) pci_free_consistent(pdev, sizeof(u32), instance->consumer, instance->consumer_h); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index c1e09d5a6196..26865290c22a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -984,13 +984,15 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) return 0; -fail_alloc_cmds: -fail_alloc_mfi_cmds: fail_map_info: if (i == 1) dma_free_coherent(&instance->pdev->dev, fusion->map_sz, fusion->ld_map[0], fusion->ld_map_phys[0]); fail_ioc_init: + megasas_free_cmds_fusion(instance); +fail_alloc_cmds: + megasas_free_cmds(instance); +fail_alloc_mfi_cmds: return 1; } -- cgit v1.2.1 From 53ef2bbd2068097ac453dff4a3d82858446be5bb Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:05 -0800 Subject: [SCSI] megaraid_sas: Add missing check_and_restore_queue_depth call Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 26865290c22a..eb4f4de19338 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -82,6 +82,10 @@ u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map); struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map); u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map); + +void +megasas_check_and_restore_queue_depth(struct megasas_instance *instance); + u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, struct LD_LOAD_BALANCE_INFO *lbInfo); u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo, @@ -1746,7 +1750,7 @@ complete_cmd_fusion(struct megasas_instance *instance) wmb(); writel(fusion->last_reply_idx, &instance->reg_set->reply_post_host_index); - + megasas_check_and_restore_queue_depth(instance); return IRQ_HANDLED; } -- cgit v1.2.1 From 0a77066acc78b4048b0afc9d70b7e91c06e63356 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:12 -0800 Subject: [SCSI] megaraid_sas: Enable MSI-X before calling megasas_init_fw Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c4ac4a5a075a..78c263337b0b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4039,12 +4039,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) else INIT_WORK(&instance->work_init, process_fw_state_change_wq); - /* - * Initialize MFI Firmware - */ - if (megasas_init_fw(instance)) - goto fail_init_mfi; - /* Try to enable MSI-X */ if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) && (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) && @@ -4053,6 +4047,12 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) &instance->msixentry, 1)) instance->msi_flag = 1; + /* + * Initialize MFI Firmware + */ + if (megasas_init_fw(instance)) + goto fail_init_mfi; + /* * Register IRQ */ @@ -4106,13 +4106,13 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) free_irq(instance->msi_flag ? instance->msixentry.vector : instance->pdev->irq, instance); fail_irq: - if (instance->msi_flag) - pci_disable_msix(instance->pdev); if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) megasas_release_fusion(instance); else megasas_release_mfi(instance); fail_init_mfi: + if (instance->msi_flag) + pci_disable_msix(instance->pdev); fail_alloc_dma_buf: if (instance->evt_detail) pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), @@ -4295,6 +4295,10 @@ megasas_resume(struct pci_dev *pdev) if (megasas_set_dma_mask(pdev)) goto fail_set_dma_mask; + /* Now re-enable MSI-X */ + if (instance->msi_flag) + pci_enable_msix(instance->pdev, &instance->msixentry, 1); + /* * Initialize MFI Firmware */ @@ -4331,10 +4335,6 @@ megasas_resume(struct pci_dev *pdev) tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, (unsigned long)instance); - /* Now re-enable MSI-X */ - if (instance->msi_flag) - pci_enable_msix(instance->pdev, &instance->msixentry, 1); - /* * Register IRQ */ -- cgit v1.2.1 From e1419191d8d38098fb6ef29e94aadd15dabff3da Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:21 -0800 Subject: [SCSI] megaraid_sas: Call tasklet_schedule for MSI-X The following patch for megaraid_sas calls tasklet_schedule() even if outbound_intr_status == 0 for MFI based boards in MSI-X mode. Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 78c263337b0b..050ec1694e68 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2503,7 +2503,9 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, if ((mfiStatus = instance->instancet->clear_intr( instance->reg_set) ) == 0) { - return IRQ_NONE; + /* Hardware may not set outbound_intr_status in MSI-X mode */ + if (!instance->msi_flag) + return IRQ_NONE; } instance->mfiStatus = mfiStatus; -- cgit v1.2.1 From 66192dfe1e74eae31a76cfc36092dabdba1324e6 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:28 -0800 Subject: [SCSI] megaraid_sas: Fix probe_one to clear MSI-X flags in kdump The following patch for megaraid_sas fixes megasas_probe_one() to clear MSI-X flags in kdump when the 'reset_devices' kernel parameter is passed in. Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 3 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 1b5e375732c0..e00ee4afdbc7 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1477,4 +1477,7 @@ struct megasas_mgmt_info { int max_index; }; +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 050ec1694e68..a521e1afd738 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3901,9 +3901,26 @@ fail_set_dma_mask: static int __devinit megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { - int rval; + int rval, pos; struct Scsi_Host *host; struct megasas_instance *instance; + u16 control = 0; + + /* Reset MSI-X in the kdump kernel */ + if (reset_devices) { + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), + &control); + if (control & PCI_MSIX_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI-X\n"); + pci_write_config_word(pdev, + msi_control_reg(pos), + control & + ~PCI_MSIX_FLAGS_ENABLE); + } + } + } /* * Announce PCI information -- cgit v1.2.1 From f512440589632c73e7c2f42d9d723994cd45958b Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:43 -0800 Subject: [SCSI] megaraid_sas: Fix megasas_build_dcdb_fusion to not filter by TYPE_DISK Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index eb4f4de19338..4ac1f6837532 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1438,8 +1438,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; /* Check if this is a system PD I/O */ - if ((instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) && - (instance->pd_list[pd_index].driveType == TYPE_DISK)) { + if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { io_request->Function = 0; io_request->DevHandle = local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; -- cgit v1.2.1 From eaa3c240de25c6e52ee1329e4acadfd99d7d104b Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:49 -0800 Subject: [SCSI] megaraid_sas: Fix megasas_build_dcdb_fusion to use correct LUN field Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 4ac1f6837532..905c1e9317b6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1461,7 +1461,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); } io_request->RaidContext.VirtualDiskTgtId = device_id; - io_request->LUN[0] = scmd->device->lun; + io_request->LUN[1] = scmd->device->lun; io_request->DataLength = scsi_bufflen(scmd); } @@ -1485,7 +1485,7 @@ megasas_build_io_fusion(struct megasas_instance *instance, device_id = MEGASAS_DEV_INDEX(instance, scp); /* Zero out some fields so they don't get reused */ - io_request->LUN[0] = 0; + io_request->LUN[1] = 0; io_request->CDB.EEDP32.PrimaryReferenceTag = 0; io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0; io_request->EEDPFlags = 0; -- cgit v1.2.1 From 4c598b23807a3bf0e4f7e65f7934965acc47e1b9 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:56:53 -0800 Subject: [SCSI] megaraid_sas: Add CFG_CLEARED AEN The following patch for megaraid_sas adds a missing check for MR_EVT_CFG_CLEARED in megasas_aen_polling(). Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index a521e1afd738..1789a1c13085 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5196,6 +5196,7 @@ megasas_aen_polling(struct work_struct *work) break; case MR_EVT_LD_OFFLINE: + case MR_EVT_CFG_CLEARED: case MR_EVT_LD_DELETED: megasas_get_ld_list(instance); for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { -- cgit v1.2.1 From f86c5424b02717a9eb9b1049a67ff3e7e9e92edf Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:57:00 -0800 Subject: [SCSI] megaraid_sas: Fix tasklet_init call The following patch fixes an incorrect tasklet_init() call in megasas_init_fw() to use instancet->tasklet. Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 1789a1c13085..22ec9f049181 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3544,7 +3544,7 @@ static int megasas_init_fw(struct megasas_instance *instance) * Setup tasklet for cmd completion */ - tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, + tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, (unsigned long)instance); /* Initialize the cmd completion timer */ -- cgit v1.2.1 From 1ac515ef3f2f7ab32498b0e4907933ff8b9b98c0 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:57:04 -0800 Subject: [SCSI] megaraid_sas: Fix fault state handling The following patch for megaraid_sas fixes fault state handling in megasas_transition_to_ready(). Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 22ec9f049181..c9d82b56c6d7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2613,7 +2613,9 @@ megasas_transition_to_ready(struct megasas_instance* instance) case MFI_STATE_FAULT: printk(KERN_DEBUG "megasas: FW in FAULT state!!\n"); - return -ENODEV; + max_wait = MEGASAS_RESET_WAIT_TIME; + cur_state = MFI_STATE_FAULT; + break; case MFI_STATE_WAIT_HANDSHAKE: /* -- cgit v1.2.1 From 42a8d2b34d107df34533ea4840daf8d62bdc90aa Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:57:09 -0800 Subject: [SCSI] megaraid_sas: Fix max_sectors for IEEE SGL Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index e00ee4afdbc7..c782bbc57cc8 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -723,6 +723,7 @@ struct megasas_ctrl_info { MEGASAS_MAX_DEV_PER_CHANNEL) #define MEGASAS_MAX_SECTORS (2*1024) +#define MEGASAS_MAX_SECTORS_IEEE (2*128) #define MEGASAS_DBG_LVL 1 #define MEGASAS_FW_BUSY 1 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c9d82b56c6d7..960b88cb4ff6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3824,6 +3824,10 @@ static int megasas_io_attach(struct megasas_instance *instance) instance->max_fw_cmds - MEGASAS_INT_CMDS; host->this_id = instance->init_id; host->sg_tablesize = instance->max_num_sge; + + if (instance->fw_support_ieee) + instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE; + /* * Check if the module parameter value for max_sectors can be used */ -- cgit v1.2.1 From ebf054b00b0a6dfa81dc4472d8b19301318b7f47 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:57:15 -0800 Subject: [SCSI] megaraid_sas: Fix iMR OCR support to work correctly Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas_base.c | 62 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 25 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 960b88cb4ff6..970d635574b3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -134,7 +134,11 @@ spinlock_t poll_aen_lock; void megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, u8 alt_status); - +static u32 +megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); +static int +megasas_adp_reset_gen2(struct megasas_instance *instance, + struct megasas_register_set __iomem *reg_set); static irqreturn_t megasas_isr(int irq, void *devp); static u32 megasas_init_adapter_mfi(struct megasas_instance *instance); @@ -554,6 +558,8 @@ static int megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) { u32 status; + u32 mfiStatus = 0; + /* * Check if it is our interrupt */ @@ -563,6 +569,15 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) return 0; } + /* + * Check if it is our interrupt + */ + if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) == + MFI_STATE_FAULT) { + mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; + } else + mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; + /* * Clear the interrupt by writing back the same value */ @@ -573,7 +588,7 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) */ readl(®s->outbound_intr_status); - return 1; + return mfiStatus; } /** @@ -596,17 +611,6 @@ megasas_fire_cmd_skinny(struct megasas_instance *instance, spin_unlock_irqrestore(&instance->hba_lock, flags); } -/** - * megasas_adp_reset_skinny - For controller reset - * @regs: MFI register set - */ -static int -megasas_adp_reset_skinny(struct megasas_instance *instance, - struct megasas_register_set __iomem *regs) -{ - return 0; -} - /** * megasas_check_reset_skinny - For controller reset check * @regs: MFI register set @@ -625,7 +629,7 @@ static struct megasas_instance_template megasas_instance_template_skinny = { .disable_intr = megasas_disable_intr_skinny, .clear_intr = megasas_clear_intr_skinny, .read_fw_status_reg = megasas_read_fw_status_reg_skinny, - .adp_reset = megasas_adp_reset_skinny, + .adp_reset = megasas_adp_reset_gen2, .check_reset = megasas_check_reset_skinny, .service_isr = megasas_isr, .tasklet = megasas_complete_cmd_dpc, @@ -740,20 +744,28 @@ megasas_adp_reset_gen2(struct megasas_instance *instance, { u32 retry = 0 ; u32 HostDiag; + u32 *seq_offset = ®_set->seq_offset; + u32 *hostdiag_offset = ®_set->host_diag; + + if (instance->instancet == &megasas_instance_template_skinny) { + seq_offset = ®_set->fusion_seq_offset; + hostdiag_offset = ®_set->fusion_host_diag; + } + + writel(0, seq_offset); + writel(4, seq_offset); + writel(0xb, seq_offset); + writel(2, seq_offset); + writel(7, seq_offset); + writel(0xd, seq_offset); - writel(0, ®_set->seq_offset); - writel(4, ®_set->seq_offset); - writel(0xb, ®_set->seq_offset); - writel(2, ®_set->seq_offset); - writel(7, ®_set->seq_offset); - writel(0xd, ®_set->seq_offset); msleep(1000); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { msleep(100); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", retry, HostDiag); @@ -764,14 +776,14 @@ megasas_adp_reset_gen2(struct megasas_instance *instance, printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); - writel((HostDiag | DIAG_RESET_ADAPTER), ®_set->host_diag); + writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset); ssleep(10); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { msleep(100); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", retry, HostDiag); -- cgit v1.2.1 From 00fa2b191b4bd74e9d22ac177e3d9e8ecd3582d3 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 24 Feb 2011 20:57:21 -0800 Subject: [SCSI] megaraid_sas: Version and Changelog update Signed-off-by: Adam Radford Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.h | 6 +++--- drivers/scsi/megaraid/megaraid_sas_base.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index c782bbc57cc8..635b228c3ead 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -33,9 +33,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.05.29-rc1" -#define MEGASAS_RELDATE "Dec. 7, 2010" -#define MEGASAS_EXT_VERSION "Tue. Dec. 7 17:00:00 PDT 2010" +#define MEGASAS_VERSION "00.00.05.34-rc1" +#define MEGASAS_RELDATE "Feb. 24, 2011" +#define MEGASAS_EXT_VERSION "Thu. Feb. 24 17:00:00 PDT 2011" /* * Device IDs diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 970d635574b3..f875e818905f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -18,12 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * FILE: megaraid_sas_base.c - * Version : v00.00.05.29-rc1 + * Version : v00.00.05.34-rc1 * * Authors: LSI Corporation * Sreenivas Bagalkote * Sumant Patro * Bo Yang + * Adam Radford * * Send feedback to: * -- cgit v1.2.1