summaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/mptbase.c303
-rw-r--r--drivers/message/fusion/mptbase.h5
-rw-r--r--drivers/message/fusion/mptsas.c22
-rw-r--r--drivers/message/fusion/mptscsih.c141
-rw-r--r--drivers/message/fusion/mptscsih.h2
5 files changed, 276 insertions, 197 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 6b6df867958..db3c892f87f 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -79,7 +79,7 @@ MODULE_VERSION(my_VERSION);
/*
* cmd line parameters
*/
-static int mpt_msi_enable;
+static int mpt_msi_enable = -1;
module_param(mpt_msi_enable, int, 0);
MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
@@ -1430,6 +1430,98 @@ mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
sprintf(prod_name, "%s", product_str);
}
+/**
+ * mpt_mapresources - map in memory mapped io
+ * @ioc: Pointer to pointer to IOC adapter
+ *
+ **/
+static int
+mpt_mapresources(MPT_ADAPTER *ioc)
+{
+ u8 __iomem *mem;
+ int ii;
+ unsigned long mem_phys;
+ unsigned long port;
+ u32 msize;
+ u32 psize;
+ u8 revision;
+ int r = -ENODEV;
+ struct pci_dev *pdev;
+
+ pdev = ioc->pcidev;
+ ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ if (pci_enable_device_mem(pdev)) {
+ printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
+ "failed\n", ioc->name);
+ return r;
+ }
+ if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
+ printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
+ "MEM failed\n", ioc->name);
+ return r;
+ }
+
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
+ && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
+ ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
+ ioc->name));
+ } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
+ && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
+ ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
+ ioc->name));
+ } else {
+ printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
+ ioc->name, pci_name(pdev));
+ pci_release_selected_regions(pdev, ioc->bars);
+ return r;
+ }
+
+ mem_phys = msize = 0;
+ port = psize = 0;
+ for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
+ if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
+ if (psize)
+ continue;
+ /* Get I/O space! */
+ port = pci_resource_start(pdev, ii);
+ psize = pci_resource_len(pdev, ii);
+ } else {
+ if (msize)
+ continue;
+ /* Get memmap */
+ mem_phys = pci_resource_start(pdev, ii);
+ msize = pci_resource_len(pdev, ii);
+ }
+ }
+ ioc->mem_size = msize;
+
+ mem = NULL;
+ /* Get logical ptr for PciMem0 space */
+ /*mem = ioremap(mem_phys, msize);*/
+ mem = ioremap(mem_phys, msize);
+ if (mem == NULL) {
+ printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
+ " memory!\n", ioc->name);
+ return -EINVAL;
+ }
+ ioc->memmap = mem;
+ dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
+ ioc->name, mem, mem_phys));
+
+ ioc->mem_phys = mem_phys;
+ ioc->chip = (SYSIF_REGS __iomem *)mem;
+
+ /* Save Port IO values in case we need to do downloadboot */
+ ioc->pio_mem_phys = port;
+ ioc->pio_chip = (SYSIF_REGS __iomem *)port;
+
+ return 0;
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1452,13 +1544,6 @@ int
mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
{
MPT_ADAPTER *ioc;
- u8 __iomem *mem;
- u8 __iomem *pmem;
- unsigned long mem_phys;
- unsigned long port;
- u32 msize;
- u32 psize;
- int ii;
u8 cb_idx;
int r = -ENODEV;
u8 revision;
@@ -1468,52 +1553,32 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
struct proc_dir_entry *dent, *ent;
#endif
- if (mpt_debug_level)
- printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
-
ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
if (ioc == NULL) {
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
return -ENOMEM;
}
- ioc->debug_level = mpt_debug_level;
+
ioc->id = mpt_ids++;
sprintf(ioc->name, "ioc%d", ioc->id);
- ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
- if (pci_enable_device_mem(pdev)) {
- printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
- "failed\n", ioc->name);
- kfree(ioc);
- return r;
- }
- if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
- printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
- "MEM failed\n", ioc->name);
- kfree(ioc);
- return r;
- }
+ /*
+ * set initial debug level
+ * (refer to mptdebug.h)
+ *
+ */
+ ioc->debug_level = mpt_debug_level;
+ if (mpt_debug_level)
+ printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- dprintk(ioc, printk(MYIOC_s_INFO_FMT
- ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
- printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",
- ioc->name);
+ ioc->pcidev = pdev;
+ if (mpt_mapresources(ioc)) {
kfree(ioc);
return r;
}
- if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
- dprintk(ioc, printk(MYIOC_s_INFO_FMT
- ": Using 64 bit consistent mask\n", ioc->name));
- } else {
- dprintk(ioc, printk(MYIOC_s_INFO_FMT
- ": Not using 64 bit consistent mask\n", ioc->name));
- }
-
ioc->alloc_total = sizeof(MPT_ADAPTER);
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
@@ -1551,48 +1616,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Find lookup slot. */
INIT_LIST_HEAD(&ioc->list);
- mem_phys = msize = 0;
- port = psize = 0;
- for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
- if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
- if (psize)
- continue;
- /* Get I/O space! */
- port = pci_resource_start(pdev, ii);
- psize = pci_resource_len(pdev,ii);
- } else {
- if (msize)
- continue;
- /* Get memmap */
- mem_phys = pci_resource_start(pdev, ii);
- msize = pci_resource_len(pdev,ii);
- }
- }
- ioc->mem_size = msize;
-
- mem = NULL;
- /* Get logical ptr for PciMem0 space */
- /*mem = ioremap(mem_phys, msize);*/
- mem = ioremap(mem_phys, msize);
- if (mem == NULL) {
- printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);
- kfree(ioc);
- return -EINVAL;
- }
- ioc->memmap = mem;
- dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));
-
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
ioc->name, &ioc->facts, &ioc->pfacts[0]));
- ioc->mem_phys = mem_phys;
- ioc->chip = (SYSIF_REGS __iomem *)mem;
-
- /* Save Port IO values in case we need to do downloadboot */
- ioc->pio_mem_phys = port;
- pmem = (u8 __iomem *)port;
- ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
-
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
@@ -1660,6 +1686,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->bus_type = SAS;
}
+ if (ioc->bus_type == SAS && mpt_msi_enable == -1)
+ ioc->msi_enable = 1;
+ else
+ ioc->msi_enable = mpt_msi_enable;
+
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -1688,7 +1719,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
- iounmap(mem);
+ iounmap(ioc->memmap);
+ if (r != -5)
+ pci_release_selected_regions(pdev, ioc->bars);
kfree(ioc);
pci_set_drvdata(pdev, NULL);
return r;
@@ -1784,13 +1817,10 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
u32 device_state;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
- device_state=pci_choose_state(pdev, state);
-
- printk(MYIOC_s_INFO_FMT
- "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
- ioc->name, pdev, pci_name(pdev), device_state);
-
- pci_save_state(pdev);
+ device_state = pci_choose_state(pdev, state);
+ printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
+ "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
+ device_state);
/* put ioc into READY_STATE */
if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
@@ -1805,10 +1835,14 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ free_irq(ioc->pci_irq, ioc);
+ if (ioc->msi_enable)
+ pci_disable_msi(ioc->pcidev);
+ ioc->pci_irq = -1;
+ pci_save_state(pdev);
pci_disable_device(pdev);
pci_release_selected_regions(pdev, ioc->bars);
pci_set_power_state(pdev, device_state);
-
return 0;
}
@@ -1823,48 +1857,54 @@ mpt_resume(struct pci_dev *pdev)
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
u32 device_state = pdev->current_state;
int recovery_state;
+ int err;
- printk(MYIOC_s_INFO_FMT
- "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
- ioc->name, pdev, pci_name(pdev), device_state);
+ printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
+ "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
+ device_state);
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_enable_wake(pdev, PCI_D0, 0);
pci_restore_state(pdev);
- if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
- ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
- IORESOURCE_IO);
- if (pci_enable_device(pdev))
- return 0;
- } else {
- ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
- if (pci_enable_device_mem(pdev))
- return 0;
- }
- if (pci_request_selected_regions(pdev, ioc->bars, "mpt"))
- return 0;
+ ioc->pcidev = pdev;
+ err = mpt_mapresources(ioc);
+ if (err)
+ return err;
- /* enable interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
- ioc->active = 1;
+ printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
+ ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
+ CHIPREG_READ32(&ioc->chip->Doorbell));
- printk(MYIOC_s_INFO_FMT
- "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
- ioc->name,
- (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
- CHIPREG_READ32(&ioc->chip->Doorbell));
+ /*
+ * Errata workaround for SAS pci express:
+ * Upon returning to the D0 state, the contents of the doorbell will be
+ * stale data, and this will incorrectly signal to the host driver that
+ * the firmware is ready to process mpt commands. The workaround is
+ * to issue a diagnostic reset.
+ */
+ if (ioc->bus_type == SAS && (pdev->device ==
+ MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
+ MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
+ if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
+ printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
+ ioc->name);
+ goto out;
+ }
+ }
/* bring ioc to operational state */
- if ((recovery_state = mpt_do_ioc_recovery(ioc,
- MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
- printk(MYIOC_s_INFO_FMT
- "pci-resume: Cannot recover, error:[%x]\n",
- ioc->name, recovery_state);
- } else {
+ printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
+ recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
+ CAN_SLEEP);
+ if (recovery_state != 0)
+ printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
+ "error:[%x]\n", ioc->name, recovery_state);
+ else
printk(MYIOC_s_INFO_FMT
- "pci-resume: success\n", ioc->name);
- }
-
+ "pci-resume: success\n", ioc->name);
+ out:
return 0;
+
}
#endif
@@ -1903,6 +1943,7 @@ mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
* -3 if READY but PrimeIOCFifos Failed
* -4 if READY but IOCInit Failed
* -5 if failed to enable_device and/or request_selected_regions
+ * -6 if failed to upload firmware
*/
static int
mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
@@ -2021,15 +2062,17 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
ioc->pci_irq = -1;
if (ioc->pcidev->irq) {
- if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
+ if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
ioc->name);
+ else
+ ioc->msi_enable = 0;
rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
IRQF_SHARED, ioc->name, ioc);
if (rc < 0) {
printk(MYIOC_s_ERR_FMT "Unable to allocate "
"interrupt %d!\n", ioc->name, ioc->pcidev->irq);
- if (mpt_msi_enable)
+ if (ioc->msi_enable)
pci_disable_msi(ioc->pcidev);
return -EBUSY;
}
@@ -2097,7 +2140,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
} else {
printk(MYIOC_s_WARN_FMT
"firmware upload failure!\n", ioc->name);
- ret = -5;
+ ret = -6;
}
}
}
@@ -2137,7 +2180,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/*
* Initalize link list for inactive raid volumes.
*/
- init_MUTEX(&ioc->raid_data.inactive_list_mutex);
+ mutex_init(&ioc->raid_data.inactive_list_mutex);
INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
if (ioc->bus_type == SAS) {
@@ -2225,7 +2268,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
out:
if ((ret != 0) && irq_allocated) {
free_irq(ioc->pci_irq, ioc);
- if (mpt_msi_enable)
+ if (ioc->msi_enable)
pci_disable_msi(ioc->pcidev);
}
return ret;
@@ -2407,7 +2450,7 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
if (ioc->pci_irq != -1) {
free_irq(ioc->pci_irq, ioc);
- if (mpt_msi_enable)
+ if (ioc->msi_enable)
pci_disable_msi(ioc->pcidev);
ioc->pci_irq = -1;
}
@@ -5123,13 +5166,13 @@ mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
if (list_empty(&ioc->raid_data.inactive_list))
return;
- down(&ioc->raid_data.inactive_list_mutex);
+ mutex_lock(&ioc->raid_data.inactive_list_mutex);
list_for_each_entry_safe(component_info, pNext,
&ioc->raid_data.inactive_list, list) {
list_del(&component_info->list);
kfree(component_info);
}
- up(&ioc->raid_data.inactive_list_mutex);
+ mutex_unlock(&ioc->raid_data.inactive_list_mutex);
}
/**
@@ -5188,7 +5231,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
if (!handle_inactive_volumes)
goto out;
- down(&ioc->raid_data.inactive_list_mutex);
+ mutex_lock(&ioc->raid_data.inactive_list_mutex);
for (i = 0; i < buffer->NumPhysDisks; i++) {
if(mpt_raid_phys_disk_pg0(ioc,
buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
@@ -5208,7 +5251,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
list_add_tail(&component_info->list,
&ioc->raid_data.inactive_list);
}
- up(&ioc->raid_data.inactive_list_mutex);
+ mutex_unlock(&ioc->raid_data.inactive_list_mutex);
out:
if (buffer)
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index caadc68c300..a8f617447d2 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -51,6 +51,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/mutex.h>
#include "lsi/mpi_type.h"
#include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */
@@ -531,7 +532,7 @@ struct inactive_raid_component_info {
typedef struct _RaidCfgData {
IOCPage2_t *pIocPg2; /* table of Raid Volumes */
IOCPage3_t *pIocPg3; /* table of physical disks */
- struct semaphore inactive_list_mutex;
+ struct mutex inactive_list_mutex;
struct list_head inactive_list; /* link list for physical
disk that belong in
inactive volumes */
@@ -630,6 +631,7 @@ typedef struct _MPT_ADAPTER
int mtrr_reg;
struct pci_dev *pcidev; /* struct pci_dev pointer */
int bars; /* bitmask of BAR's that must be configured */
+ int msi_enable;
u8 __iomem *memmap; /* mmap address */
struct Scsi_Host *sh; /* Scsi Host pointer */
SpiCfgData spi_data; /* Scsi config. data */
@@ -693,7 +695,6 @@ typedef struct _MPT_ADAPTER
struct mutex sas_discovery_mutex;
u8 sas_discovery_runtime;
u8 sas_discovery_ignore_events;
- u16 handle;
int sas_index; /* index refrencing */
MPT_SAS_MGMT sas_mgmt;
struct work_struct sas_persist_task;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 78734e25edd..468480771f1 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -230,6 +230,20 @@ static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
}
+static struct mptsas_portinfo *
+mptsas_get_hba_portinfo(MPT_ADAPTER *ioc)
+{
+ struct list_head *head = &ioc->sas_topology;
+ struct mptsas_portinfo *pi = NULL;
+
+ /* always the first entry on sas_topology list */
+
+ if (!list_empty(head))
+ pi = list_entry(head->next, struct mptsas_portinfo, list);
+
+ return pi;
+}
+
/*
* mptsas_find_portinfo_by_handle
*
@@ -1290,7 +1304,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct mptsas_portinfo *port_info;
mutex_lock(&ioc->sas_topology_mutex);
- port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+ port_info = mptsas_get_hba_portinfo(ioc);
if (port_info && port_info->phy_info)
sas_address =
port_info->phy_info[0].phy->identify.sas_address;
@@ -2028,8 +2042,7 @@ static int mptsas_probe_one_phy(struct device *dev,
int i;
mutex_lock(&ioc->sas_topology_mutex);
- port_info = mptsas_find_portinfo_by_handle(ioc,
- ioc->handle);
+ port_info = mptsas_get_hba_portinfo(ioc);
mutex_unlock(&ioc->sas_topology_mutex);
for (i = 0; i < port_info->num_phys; i++)
@@ -2099,8 +2112,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
mptsas_sas_io_unit_pg1(ioc);
mutex_lock(&ioc->sas_topology_mutex);
- ioc->handle = hba->phy_info[0].handle;
- port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+ port_info = mptsas_get_hba_portinfo(ioc);
if (!port_info) {
port_info = hba;
list_add_tail(&port_info->list, &ioc->sas_topology);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 0c252f60c4c..b109bd8a4d1 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1170,6 +1170,10 @@ mptscsih_shutdown(struct pci_dev *pdev)
int
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
{
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+
+ scsi_block_requests(ioc->sh);
+ flush_scheduled_work();
mptscsih_shutdown(pdev);
return mpt_suspend(pdev,state);
}
@@ -1183,7 +1187,12 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
int
mptscsih_resume(struct pci_dev *pdev)
{
- return mpt_resume(pdev);
+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+ int rc;
+
+ rc = mpt_resume(pdev);
+ scsi_unblock_requests(ioc->sh);
+ return rc;
}
#endif
@@ -2295,14 +2304,14 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
if (list_empty(&ioc->raid_data.inactive_list))
goto out;
- down(&ioc->raid_data.inactive_list_mutex);
+ mutex_lock(&ioc->raid_data.inactive_list_mutex);
list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
list) {
if ((component_info->d.PhysDiskID == id) &&
(component_info->d.PhysDiskBus == channel))
rc = 1;
}
- up(&ioc->raid_data.inactive_list_mutex);
+ mutex_unlock(&ioc->raid_data.inactive_list_mutex);
out:
return rc;
@@ -2332,14 +2341,14 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
if (list_empty(&ioc->raid_data.inactive_list))
goto out;
- down(&ioc->raid_data.inactive_list_mutex);
+ mutex_lock(&ioc->raid_data.inactive_list_mutex);
list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
list) {
if ((component_info->d.PhysDiskID == id) &&
(component_info->d.PhysDiskBus == channel))
rc = component_info->d.PhysDiskNum;
}
- up(&ioc->raid_data.inactive_list_mutex);
+ mutex_unlock(&ioc->raid_data.inactive_list_mutex);
out:
return rc;
@@ -3291,9 +3300,10 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
}
static ssize_t
-mptscsih_version_fw_show(struct class_device *cdev, char *buf)
+mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
@@ -3303,12 +3313,13 @@ mptscsih_version_fw_show(struct class_device *cdev, char *buf)
(ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
ioc->facts.FWVersion.Word & 0x000000FF);
}
-static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
+static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
static ssize_t
-mptscsih_version_bios_show(struct class_device *cdev, char *buf)
+mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
@@ -3318,129 +3329,141 @@ mptscsih_version_bios_show(struct class_device *cdev, char *buf)
(ioc->biosVersion & 0x0000FF00) >> 8,
ioc->biosVersion & 0x000000FF);
}
-static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
+static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
static ssize_t
-mptscsih_version_mpi_show(struct class_device *cdev, char *buf)
+mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
}
-static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
+static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
static ssize_t
-mptscsih_version_product_show(struct class_device *cdev, char *buf)
+mptscsih_version_product_show(struct device *dev,
+ struct device_attribute *attr,
+char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
}
-static CLASS_DEVICE_ATTR(version_product, S_IRUGO,
+static DEVICE_ATTR(version_product, S_IRUGO,
mptscsih_version_product_show, NULL);
static ssize_t
-mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf)
+mptscsih_version_nvdata_persistent_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%02xh\n",
ioc->nvdata_version_persistent);
}
-static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
+static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
mptscsih_version_nvdata_persistent_show, NULL);
static ssize_t
-mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf)
+mptscsih_version_nvdata_default_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
}
-static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO,
+static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
mptscsih_version_nvdata_default_show, NULL);
static ssize_t
-mptscsih_board_name_show(struct class_device *cdev, char *buf)
+mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
}
-static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
+static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
static ssize_t
-mptscsih_board_assembly_show(struct class_device *cdev, char *buf)
+mptscsih_board_assembly_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
}
-static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO,
+static DEVICE_ATTR(board_assembly, S_IRUGO,
mptscsih_board_assembly_show, NULL);
static ssize_t
-mptscsih_board_tracer_show(struct class_device *cdev, char *buf)
+mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
}
-static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO,
+static DEVICE_ATTR(board_tracer, S_IRUGO,
mptscsih_board_tracer_show, NULL);
static ssize_t
-mptscsih_io_delay_show(struct class_device *cdev, char *buf)
+mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
}
-static CLASS_DEVICE_ATTR(io_delay, S_IRUGO,
+static DEVICE_ATTR(io_delay, S_IRUGO,
mptscsih_io_delay_show, NULL);
static ssize_t
-mptscsih_device_delay_show(struct class_device *cdev, char *buf)
+mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
}
-static CLASS_DEVICE_ATTR(device_delay, S_IRUGO,
+static DEVICE_ATTR(device_delay, S_IRUGO,
mptscsih_device_delay_show, NULL);
static ssize_t
-mptscsih_debug_level_show(struct class_device *cdev, char *buf)
+mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
}
static ssize_t
-mptscsih_debug_level_store(struct class_device *cdev, const char *buf,
- size_t count)
+mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct Scsi_Host *host = class_to_shost(cdev);
+ struct Scsi_Host *host = class_to_shost(dev);
MPT_SCSI_HOST *hd = shost_priv(host);
MPT_ADAPTER *ioc = hd->ioc;
int val = 0;
@@ -3453,22 +3476,22 @@ mptscsih_debug_level_store(struct class_device *cdev, const char *buf,
ioc->name, ioc->debug_level);
return strlen(buf);
}
-static CLASS_DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
- mptscsih_debug_level_show, mptscsih_debug_level_store);
-
-struct class_device_attribute *mptscsih_host_attrs[] = {
- &class_device_attr_version_fw,
- &class_device_attr_version_bios,
- &class_device_attr_version_mpi,
- &class_device_attr_version_product,
- &class_device_attr_version_nvdata_persistent,
- &class_device_attr_version_nvdata_default,
- &class_device_attr_board_name,
- &class_device_attr_board_assembly,
- &class_device_attr_board_tracer,
- &class_device_attr_io_delay,
- &class_device_attr_device_delay,
- &class_device_attr_debug_level,
+static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
+ mptscsih_debug_level_show, mptscsih_debug_level_store);
+
+struct device_attribute *mptscsih_host_attrs[] = {
+ &dev_attr_version_fw,
+ &dev_attr_version_bios,
+ &dev_attr_version_mpi,
+ &dev_attr_version_product,
+ &dev_attr_version_nvdata_persistent,
+ &dev_attr_version_nvdata_default,
+ &dev_attr_board_name,
+ &dev_attr_board_assembly,
+ &dev_attr_board_tracer,
+ &dev_attr_io_delay,
+ &dev_attr_device_delay,
+ &dev_attr_debug_level,
NULL,
};
EXPORT_SYMBOL(mptscsih_host_attrs);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index d289e97cfe8..7ea7da0e090 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -129,4 +129,4 @@ extern void mptscsih_timer_expired(unsigned long data);
extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
-extern struct class_device_attribute *mptscsih_host_attrs[];
+extern struct device_attribute *mptscsih_host_attrs[];