diff options
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 184 |
1 files changed, 174 insertions, 10 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index d890b2b8a93e..9a2c7605d49c 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -81,6 +81,10 @@ MODULE_LICENSE("GPL"); | |||
81 | /* | 81 | /* |
82 | * cmd line parameters | 82 | * cmd line parameters |
83 | */ | 83 | */ |
84 | static int mpt_msi_enable; | ||
85 | module_param(mpt_msi_enable, int, 0); | ||
86 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); | ||
87 | |||
84 | #ifdef MFCNT | 88 | #ifdef MFCNT |
85 | static int mfcounter = 0; | 89 | static int mfcounter = 0; |
86 | #define PRINT_MF_COUNT 20000 | 90 | #define PRINT_MF_COUNT 20000 |
@@ -174,7 +178,7 @@ static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); | |||
174 | static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); | 178 | static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); |
175 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); | 179 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); |
176 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); | 180 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); |
177 | static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); | 181 | static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); |
178 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); | 182 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); |
179 | 183 | ||
180 | /* module entry point */ | 184 | /* module entry point */ |
@@ -313,7 +317,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) | |||
313 | if (ioc->bus_type == FC) | 317 | if (ioc->bus_type == FC) |
314 | mpt_fc_log_info(ioc, log_info); | 318 | mpt_fc_log_info(ioc, log_info); |
315 | else if (ioc->bus_type == SPI) | 319 | else if (ioc->bus_type == SPI) |
316 | mpt_sp_log_info(ioc, log_info); | 320 | mpt_spi_log_info(ioc, log_info); |
317 | else if (ioc->bus_type == SAS) | 321 | else if (ioc->bus_type == SAS) |
318 | mpt_sas_log_info(ioc, log_info); | 322 | mpt_sas_log_info(ioc, log_info); |
319 | } | 323 | } |
@@ -1444,6 +1448,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1444 | 1448 | ||
1445 | ioc->pci_irq = -1; | 1449 | ioc->pci_irq = -1; |
1446 | if (pdev->irq) { | 1450 | if (pdev->irq) { |
1451 | if (mpt_msi_enable && !pci_enable_msi(pdev)) | ||
1452 | printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name); | ||
1453 | |||
1447 | r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); | 1454 | r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); |
1448 | 1455 | ||
1449 | if (r < 0) { | 1456 | if (r < 0) { |
@@ -1483,6 +1490,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1483 | 1490 | ||
1484 | list_del(&ioc->list); | 1491 | list_del(&ioc->list); |
1485 | free_irq(ioc->pci_irq, ioc); | 1492 | free_irq(ioc->pci_irq, ioc); |
1493 | if (mpt_msi_enable) | ||
1494 | pci_disable_msi(pdev); | ||
1495 | if (ioc->alt_ioc) | ||
1496 | ioc->alt_ioc->alt_ioc = NULL; | ||
1486 | iounmap(mem); | 1497 | iounmap(mem); |
1487 | kfree(ioc); | 1498 | kfree(ioc); |
1488 | pci_set_drvdata(pdev, NULL); | 1499 | pci_set_drvdata(pdev, NULL); |
@@ -2136,6 +2147,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2136 | 2147 | ||
2137 | if (ioc->pci_irq != -1) { | 2148 | if (ioc->pci_irq != -1) { |
2138 | free_irq(ioc->pci_irq, ioc); | 2149 | free_irq(ioc->pci_irq, ioc); |
2150 | if (mpt_msi_enable) | ||
2151 | pci_disable_msi(ioc->pcidev); | ||
2139 | ioc->pci_irq = -1; | 2152 | ioc->pci_irq = -1; |
2140 | } | 2153 | } |
2141 | 2154 | ||
@@ -2157,6 +2170,10 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2157 | sz_last = ioc->alloc_total; | 2170 | sz_last = ioc->alloc_total; |
2158 | dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", | 2171 | dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", |
2159 | ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); | 2172 | ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); |
2173 | |||
2174 | if (ioc->alt_ioc) | ||
2175 | ioc->alt_ioc->alt_ioc = NULL; | ||
2176 | |||
2160 | kfree(ioc); | 2177 | kfree(ioc); |
2161 | } | 2178 | } |
2162 | 2179 | ||
@@ -2770,13 +2787,16 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2770 | 2787 | ||
2771 | /* RAID FW may take a long time to enable | 2788 | /* RAID FW may take a long time to enable |
2772 | */ | 2789 | */ |
2773 | if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) | 2790 | if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) |
2774 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) { | 2791 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) || |
2775 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, | 2792 | (ioc->bus_type == SAS)) { |
2776 | reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); | 2793 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
2794 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, | ||
2795 | 300 /*seconds*/, sleepFlag); | ||
2777 | } else { | 2796 | } else { |
2778 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, | 2797 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
2779 | reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag); | 2798 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, |
2799 | 30 /*seconds*/, sleepFlag); | ||
2780 | } | 2800 | } |
2781 | return rc; | 2801 | return rc; |
2782 | } | 2802 | } |
@@ -4387,6 +4407,138 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
4387 | } | 4407 | } |
4388 | 4408 | ||
4389 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 4409 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
4410 | |||
4411 | static void | ||
4412 | mptbase_raid_process_event_data(MPT_ADAPTER *ioc, | ||
4413 | MpiEventDataRaid_t * pRaidEventData) | ||
4414 | { | ||
4415 | int volume; | ||
4416 | int reason; | ||
4417 | int disk; | ||
4418 | int status; | ||
4419 | int flags; | ||
4420 | int state; | ||
4421 | |||
4422 | volume = pRaidEventData->VolumeID; | ||
4423 | reason = pRaidEventData->ReasonCode; | ||
4424 | disk = pRaidEventData->PhysDiskNum; | ||
4425 | status = le32_to_cpu(pRaidEventData->SettingsStatus); | ||
4426 | flags = (status >> 0) & 0xff; | ||
4427 | state = (status >> 8) & 0xff; | ||
4428 | |||
4429 | if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { | ||
4430 | return; | ||
4431 | } | ||
4432 | |||
4433 | if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && | ||
4434 | reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || | ||
4435 | (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { | ||
4436 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", | ||
4437 | ioc->name, disk); | ||
4438 | } else { | ||
4439 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", | ||
4440 | ioc->name, volume); | ||
4441 | } | ||
4442 | |||
4443 | switch(reason) { | ||
4444 | case MPI_EVENT_RAID_RC_VOLUME_CREATED: | ||
4445 | printk(MYIOC_s_INFO_FMT " volume has been created\n", | ||
4446 | ioc->name); | ||
4447 | break; | ||
4448 | |||
4449 | case MPI_EVENT_RAID_RC_VOLUME_DELETED: | ||
4450 | |||
4451 | printk(MYIOC_s_INFO_FMT " volume has been deleted\n", | ||
4452 | ioc->name); | ||
4453 | break; | ||
4454 | |||
4455 | case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: | ||
4456 | printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", | ||
4457 | ioc->name); | ||
4458 | break; | ||
4459 | |||
4460 | case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: | ||
4461 | printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", | ||
4462 | ioc->name, | ||
4463 | state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL | ||
4464 | ? "optimal" | ||
4465 | : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED | ||
4466 | ? "degraded" | ||
4467 | : state == MPI_RAIDVOL0_STATUS_STATE_FAILED | ||
4468 | ? "failed" | ||
4469 | : "state unknown", | ||
4470 | flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED | ||
4471 | ? ", enabled" : "", | ||
4472 | flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED | ||
4473 | ? ", quiesced" : "", | ||
4474 | flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS | ||
4475 | ? ", resync in progress" : "" ); | ||
4476 | break; | ||
4477 | |||
4478 | case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: | ||
4479 | printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", | ||
4480 | ioc->name, disk); | ||
4481 | break; | ||
4482 | |||
4483 | case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: | ||
4484 | printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", | ||
4485 | ioc->name); | ||
4486 | break; | ||
4487 | |||
4488 | case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: | ||
4489 | printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", | ||
4490 | ioc->name); | ||
4491 | break; | ||
4492 | |||
4493 | case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: | ||
4494 | printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", | ||
4495 | ioc->name); | ||
4496 | break; | ||
4497 | |||
4498 | case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: | ||
4499 | printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", | ||
4500 | ioc->name, | ||
4501 | state == MPI_PHYSDISK0_STATUS_ONLINE | ||
4502 | ? "online" | ||
4503 | : state == MPI_PHYSDISK0_STATUS_MISSING | ||
4504 | ? "missing" | ||
4505 | : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE | ||
4506 | ? "not compatible" | ||
4507 | : state == MPI_PHYSDISK0_STATUS_FAILED | ||
4508 | ? "failed" | ||
4509 | : state == MPI_PHYSDISK0_STATUS_INITIALIZING | ||
4510 | ? "initializing" | ||
4511 | : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED | ||
4512 | ? "offline requested" | ||
4513 | : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED | ||
4514 | ? "failed requested" | ||
4515 | : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE | ||
4516 | ? "offline" | ||
4517 | : "state unknown", | ||
4518 | flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC | ||
4519 | ? ", out of sync" : "", | ||
4520 | flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED | ||
4521 | ? ", quiesced" : "" ); | ||
4522 | break; | ||
4523 | |||
4524 | case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: | ||
4525 | printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", | ||
4526 | ioc->name, disk); | ||
4527 | break; | ||
4528 | |||
4529 | case MPI_EVENT_RAID_RC_SMART_DATA: | ||
4530 | printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", | ||
4531 | ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); | ||
4532 | break; | ||
4533 | |||
4534 | case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: | ||
4535 | printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", | ||
4536 | ioc->name, disk); | ||
4537 | break; | ||
4538 | } | ||
4539 | } | ||
4540 | |||
4541 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
4390 | /* | 4542 | /* |
4391 | * GetIoUnitPage2 - Retrieve BIOS version and boot order information. | 4543 | * GetIoUnitPage2 - Retrieve BIOS version and boot order information. |
4392 | * @ioc: Pointer to MPT_ADAPTER structure | 4544 | * @ioc: Pointer to MPT_ADAPTER structure |
@@ -4598,6 +4750,14 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) | |||
4598 | SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; | 4750 | SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; |
4599 | MpiDeviceInfo_t *pdevice = NULL; | 4751 | MpiDeviceInfo_t *pdevice = NULL; |
4600 | 4752 | ||
4753 | /* | ||
4754 | * Save "Set to Avoid SCSI Bus Resets" flag | ||
4755 | */ | ||
4756 | ioc->spi_data.bus_reset = | ||
4757 | (le32_to_cpu(pPP2->PortFlags) & | ||
4758 | MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? | ||
4759 | 0 : 1 ; | ||
4760 | |||
4601 | /* Save the Port Page 2 data | 4761 | /* Save the Port Page 2 data |
4602 | * (reformat into a 32bit quantity) | 4762 | * (reformat into a 32bit quantity) |
4603 | */ | 4763 | */ |
@@ -5967,6 +6127,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply | |||
5967 | } | 6127 | } |
5968 | } | 6128 | } |
5969 | break; | 6129 | break; |
6130 | case MPI_EVENT_INTEGRATED_RAID: | ||
6131 | mptbase_raid_process_event_data(ioc, | ||
6132 | (MpiEventDataRaid_t *)pEventReply->Data); | ||
6133 | break; | ||
5970 | default: | 6134 | default: |
5971 | break; | 6135 | break; |
5972 | } | 6136 | } |
@@ -6046,7 +6210,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6046 | 6210 | ||
6047 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6211 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6048 | /* | 6212 | /* |
6049 | * mpt_sp_log_info - Log information returned from SCSI Parallel IOC. | 6213 | * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. |
6050 | * @ioc: Pointer to MPT_ADAPTER structure | 6214 | * @ioc: Pointer to MPT_ADAPTER structure |
6051 | * @mr: Pointer to MPT reply frame | 6215 | * @mr: Pointer to MPT reply frame |
6052 | * @log_info: U32 LogInfo word from the IOC | 6216 | * @log_info: U32 LogInfo word from the IOC |
@@ -6054,7 +6218,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6054 | * Refer to lsi/sp_log.h. | 6218 | * Refer to lsi/sp_log.h. |
6055 | */ | 6219 | */ |
6056 | static void | 6220 | static void |
6057 | mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) | 6221 | mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) |
6058 | { | 6222 | { |
6059 | u32 info = log_info & 0x00FF0000; | 6223 | u32 info = log_info & 0x00FF0000; |
6060 | char *desc = "unknown"; | 6224 | char *desc = "unknown"; |