aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 88e6eebc315..b830d61684d 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
6 * Copyright (C) 2007-2009 LSI Corporation 6 * Copyright (C) 2007-2010 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -58,6 +58,7 @@
58#include <linux/sort.h> 58#include <linux/sort.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/time.h> 60#include <linux/time.h>
61#include <linux/aer.h>
61 62
62#include "mpt2sas_base.h" 63#include "mpt2sas_base.h"
63 64
@@ -285,6 +286,9 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
285 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION) 286 request_hdr->Function == MPI2_FUNCTION_EVENT_NOTIFICATION)
286 return; 287 return;
287 288
289 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
290 return;
291
288 switch (ioc_status) { 292 switch (ioc_status) {
289 293
290/**************************************************************************** 294/****************************************************************************
@@ -517,8 +521,18 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
517 desc = "IR Operation Status"; 521 desc = "IR Operation Status";
518 break; 522 break;
519 case MPI2_EVENT_SAS_DISCOVERY: 523 case MPI2_EVENT_SAS_DISCOVERY:
520 desc = "Discovery"; 524 {
521 break; 525 Mpi2EventDataSasDiscovery_t *event_data =
526 (Mpi2EventDataSasDiscovery_t *)mpi_reply->EventData;
527 printk(MPT2SAS_INFO_FMT "Discovery: (%s)", ioc->name,
528 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
529 "start" : "stop");
530 if (event_data->DiscoveryStatus)
531 printk("discovery_status(0x%08x)",
532 le32_to_cpu(event_data->DiscoveryStatus));
533 printk("\n");
534 return;
535 }
522 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 536 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
523 desc = "SAS Broadcast Primitive"; 537 desc = "SAS Broadcast Primitive";
524 break; 538 break;
@@ -1243,6 +1257,9 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1243 goto out_fail; 1257 goto out_fail;
1244 } 1258 }
1245 1259
1260 /* AER (Advanced Error Reporting) hooks */
1261 pci_enable_pcie_error_reporting(pdev);
1262
1246 pci_set_master(pdev); 1263 pci_set_master(pdev);
1247 1264
1248 if (_base_config_dma_addressing(ioc, pdev) != 0) { 1265 if (_base_config_dma_addressing(ioc, pdev) != 0) {
@@ -1253,7 +1270,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1253 } 1270 }
1254 1271
1255 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) { 1272 for (i = 0, memap_sz = 0, pio_sz = 0 ; i < DEVICE_COUNT_RESOURCE; i++) {
1256 if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { 1273 if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
1257 if (pio_sz) 1274 if (pio_sz)
1258 continue; 1275 continue;
1259 pio_chip = (u64)pci_resource_start(pdev, i); 1276 pio_chip = (u64)pci_resource_start(pdev, i);
@@ -1261,15 +1278,18 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1261 } else { 1278 } else {
1262 if (memap_sz) 1279 if (memap_sz)
1263 continue; 1280 continue;
1264 ioc->chip_phys = pci_resource_start(pdev, i); 1281 /* verify memory resource is valid before using */
1265 chip_phys = (u64)ioc->chip_phys; 1282 if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
1266 memap_sz = pci_resource_len(pdev, i); 1283 ioc->chip_phys = pci_resource_start(pdev, i);
1267 ioc->chip = ioremap(ioc->chip_phys, memap_sz); 1284 chip_phys = (u64)ioc->chip_phys;
1268 if (ioc->chip == NULL) { 1285 memap_sz = pci_resource_len(pdev, i);
1269 printk(MPT2SAS_ERR_FMT "unable to map adapter " 1286 ioc->chip = ioremap(ioc->chip_phys, memap_sz);
1270 "memory!\n", ioc->name); 1287 if (ioc->chip == NULL) {
1271 r = -EINVAL; 1288 printk(MPT2SAS_ERR_FMT "unable to map "
1272 goto out_fail; 1289 "adapter memory!\n", ioc->name);
1290 r = -EINVAL;
1291 goto out_fail;
1292 }
1273 } 1293 }
1274 } 1294 }
1275 } 1295 }
@@ -1295,6 +1315,7 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1295 ioc->chip_phys = 0; 1315 ioc->chip_phys = 0;
1296 ioc->pci_irq = -1; 1316 ioc->pci_irq = -1;
1297 pci_release_selected_regions(ioc->pdev, ioc->bars); 1317 pci_release_selected_regions(ioc->pdev, ioc->bars);
1318 pci_disable_pcie_error_reporting(pdev);
1298 pci_disable_device(pdev); 1319 pci_disable_device(pdev);
1299 return r; 1320 return r;
1300} 1321}
@@ -1898,7 +1919,10 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1898 ioc->config_page, ioc->config_page_dma); 1919 ioc->config_page, ioc->config_page_dma);
1899 } 1920 }
1900 1921
1901 kfree(ioc->scsi_lookup); 1922 if (ioc->scsi_lookup) {
1923 free_pages((ulong)ioc->scsi_lookup, ioc->scsi_lookup_pages);
1924 ioc->scsi_lookup = NULL;
1925 }
1902 kfree(ioc->hpr_lookup); 1926 kfree(ioc->hpr_lookup);
1903 kfree(ioc->internal_lookup); 1927 kfree(ioc->internal_lookup);
1904} 1928}
@@ -2110,11 +2134,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2110 ioc->name, (unsigned long long) ioc->request_dma)); 2134 ioc->name, (unsigned long long) ioc->request_dma));
2111 total_sz += sz; 2135 total_sz += sz;
2112 2136
2113 ioc->scsi_lookup = kcalloc(ioc->scsiio_depth, 2137 sz = ioc->scsiio_depth * sizeof(struct request_tracker);
2114 sizeof(struct request_tracker), GFP_KERNEL); 2138 ioc->scsi_lookup_pages = get_order(sz);
2139 ioc->scsi_lookup = (struct request_tracker *)__get_free_pages(
2140 GFP_KERNEL, ioc->scsi_lookup_pages);
2115 if (!ioc->scsi_lookup) { 2141 if (!ioc->scsi_lookup) {
2116 printk(MPT2SAS_ERR_FMT "scsi_lookup: kcalloc failed\n", 2142 printk(MPT2SAS_ERR_FMT "scsi_lookup: get_free_pages failed, "
2117 ioc->name); 2143 "sz(%d)\n", ioc->name, (int)sz);
2118 goto out; 2144 goto out;
2119 } 2145 }
2120 2146
@@ -3006,8 +3032,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3006 * since epoch ~ midnight January 1, 1970. 3032 * since epoch ~ midnight January 1, 1970.
3007 */ 3033 */
3008 do_gettimeofday(&current_time); 3034 do_gettimeofday(&current_time);
3009 mpi_request.TimeStamp = (current_time.tv_sec * 1000) + 3035 mpi_request.TimeStamp = cpu_to_le64((u64)current_time.tv_sec * 1000 +
3010 (current_time.tv_usec >> 3); 3036 (current_time.tv_usec / 1000));
3011 3037
3012 if (ioc->logging_level & MPT_DEBUG_INIT) { 3038 if (ioc->logging_level & MPT_DEBUG_INIT) {
3013 u32 *mfp; 3039 u32 *mfp;
@@ -3179,7 +3205,7 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3179 mpi_request->VP_ID = 0; 3205 mpi_request->VP_ID = 0;
3180 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3206 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3181 mpi_request->EventMasks[i] = 3207 mpi_request->EventMasks[i] =
3182 le32_to_cpu(ioc->event_masks[i]); 3208 cpu_to_le32(ioc->event_masks[i]);
3183 mpt2sas_base_put_smid_default(ioc, smid); 3209 mpt2sas_base_put_smid_default(ioc, smid);
3184 init_completion(&ioc->base_cmds.done); 3210 init_completion(&ioc->base_cmds.done);
3185 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); 3211 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
@@ -3516,7 +3542,9 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3516 __func__)); 3542 __func__));
3517 3543
3518 _base_mask_interrupts(ioc); 3544 _base_mask_interrupts(ioc);
3545 ioc->shost_recovery = 1;
3519 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 3546 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
3547 ioc->shost_recovery = 0;
3520 if (ioc->pci_irq) { 3548 if (ioc->pci_irq) {
3521 synchronize_irq(pdev->irq); 3549 synchronize_irq(pdev->irq);
3522 free_irq(ioc->pci_irq, ioc); 3550 free_irq(ioc->pci_irq, ioc);
@@ -3527,6 +3555,7 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
3527 ioc->pci_irq = -1; 3555 ioc->pci_irq = -1;
3528 ioc->chip_phys = 0; 3556 ioc->chip_phys = 0;
3529 pci_release_selected_regions(ioc->pdev, ioc->bars); 3557 pci_release_selected_regions(ioc->pdev, ioc->bars);
3558 pci_disable_pcie_error_reporting(pdev);
3530 pci_disable_device(pdev); 3559 pci_disable_device(pdev);
3531 return; 3560 return;
3532} 3561}
@@ -3560,8 +3589,10 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3560 3589
3561 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, 3590 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
3562 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL); 3591 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
3563 if (!ioc->pfacts) 3592 if (!ioc->pfacts) {
3593 r = -ENOMEM;
3564 goto out_free_resources; 3594 goto out_free_resources;
3595 }
3565 3596
3566 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) { 3597 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
3567 r = _base_get_port_facts(ioc, i, CAN_SLEEP); 3598 r = _base_get_port_facts(ioc, i, CAN_SLEEP);
@@ -3607,6 +3638,15 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3607 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 3638 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
3608 mutex_init(&ioc->ctl_cmds.mutex); 3639 mutex_init(&ioc->ctl_cmds.mutex);
3609 3640
3641 if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
3642 !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
3643 !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) {
3644 r = -ENOMEM;
3645 goto out_free_resources;
3646 }
3647
3648 init_completion(&ioc->shost_recovery_done);
3649
3610 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3650 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3611 ioc->event_masks[i] = -1; 3651 ioc->event_masks[i] = -1;
3612 3652
@@ -3639,6 +3679,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3639 pci_set_drvdata(ioc->pdev, NULL); 3679 pci_set_drvdata(ioc->pdev, NULL);
3640 kfree(ioc->tm_cmds.reply); 3680 kfree(ioc->tm_cmds.reply);
3641 kfree(ioc->transport_cmds.reply); 3681 kfree(ioc->transport_cmds.reply);
3682 kfree(ioc->scsih_cmds.reply);
3642 kfree(ioc->config_cmds.reply); 3683 kfree(ioc->config_cmds.reply);
3643 kfree(ioc->base_cmds.reply); 3684 kfree(ioc->base_cmds.reply);
3644 kfree(ioc->ctl_cmds.reply); 3685 kfree(ioc->ctl_cmds.reply);
@@ -3646,6 +3687,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3646 ioc->ctl_cmds.reply = NULL; 3687 ioc->ctl_cmds.reply = NULL;
3647 ioc->base_cmds.reply = NULL; 3688 ioc->base_cmds.reply = NULL;
3648 ioc->tm_cmds.reply = NULL; 3689 ioc->tm_cmds.reply = NULL;
3690 ioc->scsih_cmds.reply = NULL;
3649 ioc->transport_cmds.reply = NULL; 3691 ioc->transport_cmds.reply = NULL;
3650 ioc->config_cmds.reply = NULL; 3692 ioc->config_cmds.reply = NULL;
3651 ioc->pfacts = NULL; 3693 ioc->pfacts = NULL;
@@ -3675,6 +3717,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3675 kfree(ioc->base_cmds.reply); 3717 kfree(ioc->base_cmds.reply);
3676 kfree(ioc->tm_cmds.reply); 3718 kfree(ioc->tm_cmds.reply);
3677 kfree(ioc->transport_cmds.reply); 3719 kfree(ioc->transport_cmds.reply);
3720 kfree(ioc->scsih_cmds.reply);
3678 kfree(ioc->config_cmds.reply); 3721 kfree(ioc->config_cmds.reply);
3679} 3722}
3680 3723
@@ -3811,9 +3854,8 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3811 3854
3812 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); 3855 spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
3813 ioc->shost_recovery = 0; 3856 ioc->shost_recovery = 0;
3857 complete(&ioc->shost_recovery_done);
3814 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); 3858 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
3815 3859
3816 if (!r)
3817 _base_reset_handler(ioc, MPT2_IOC_RUNNING);
3818 return r; 3860 return r;
3819} 3861}