aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/Makefile2
-rw-r--r--drivers/message/fusion/mptbase.c299
-rw-r--r--drivers/message/fusion/mptbase.h18
-rw-r--r--drivers/message/fusion/mptctl.c241
-rw-r--r--drivers/message/fusion/mptctl.h4
-rw-r--r--drivers/message/fusion/mptfc.c203
-rw-r--r--drivers/message/fusion/mptsas.c241
-rw-r--r--drivers/message/fusion/mptscsih.c118
-rw-r--r--drivers/message/fusion/mptscsih.h1
-rw-r--r--drivers/message/fusion/mptspi.c10
10 files changed, 843 insertions, 294 deletions
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 8a2e2657f4c2..33ace373241c 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -29,6 +29,8 @@
29# For mptctl: 29# For mptctl:
30#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL 30#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
31# 31#
32# For mptfc:
33#CFLAGS_mptfc.o += -DMPT_DEBUG_FC
32 34
33#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC 35#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
34 36
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index d890b2b8a93e..642a61b6d0a4 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 */
84static int mpt_msi_enable;
85module_param(mpt_msi_enable, int, 0);
86MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
87
84#ifdef MFCNT 88#ifdef MFCNT
85static int mfcounter = 0; 89static 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);
174static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); 178static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
175static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 179static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
176static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 180static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
177static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); 181static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
178static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 182static 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 }
@@ -448,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
448 } else if (func == MPI_FUNCTION_EVENT_ACK) { 452 } else if (func == MPI_FUNCTION_EVENT_ACK) {
449 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", 453 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
450 ioc->name)); 454 ioc->name));
451 } else if (func == MPI_FUNCTION_CONFIG || 455 } else if (func == MPI_FUNCTION_CONFIG) {
452 func == MPI_FUNCTION_TOOLBOX) {
453 CONFIGPARMS *pCfg; 456 CONFIGPARMS *pCfg;
454 unsigned long flags; 457 unsigned long flags;
455 458
@@ -1444,6 +1447,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1444 1447
1445 ioc->pci_irq = -1; 1448 ioc->pci_irq = -1;
1446 if (pdev->irq) { 1449 if (pdev->irq) {
1450 if (mpt_msi_enable && !pci_enable_msi(pdev))
1451 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name);
1452
1447 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); 1453 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1448 1454
1449 if (r < 0) { 1455 if (r < 0) {
@@ -1483,6 +1489,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1483 1489
1484 list_del(&ioc->list); 1490 list_del(&ioc->list);
1485 free_irq(ioc->pci_irq, ioc); 1491 free_irq(ioc->pci_irq, ioc);
1492 if (mpt_msi_enable)
1493 pci_disable_msi(pdev);
1494 if (ioc->alt_ioc)
1495 ioc->alt_ioc->alt_ioc = NULL;
1486 iounmap(mem); 1496 iounmap(mem);
1487 kfree(ioc); 1497 kfree(ioc);
1488 pci_set_drvdata(pdev, NULL); 1498 pci_set_drvdata(pdev, NULL);
@@ -2136,6 +2146,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
2136 2146
2137 if (ioc->pci_irq != -1) { 2147 if (ioc->pci_irq != -1) {
2138 free_irq(ioc->pci_irq, ioc); 2148 free_irq(ioc->pci_irq, ioc);
2149 if (mpt_msi_enable)
2150 pci_disable_msi(ioc->pcidev);
2139 ioc->pci_irq = -1; 2151 ioc->pci_irq = -1;
2140 } 2152 }
2141 2153
@@ -2157,6 +2169,10 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
2157 sz_last = ioc->alloc_total; 2169 sz_last = ioc->alloc_total;
2158 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", 2170 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2159 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); 2171 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2172
2173 if (ioc->alt_ioc)
2174 ioc->alt_ioc->alt_ioc = NULL;
2175
2160 kfree(ioc); 2176 kfree(ioc);
2161} 2177}
2162 2178
@@ -2770,13 +2786,16 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2770 2786
2771 /* RAID FW may take a long time to enable 2787 /* RAID FW may take a long time to enable
2772 */ 2788 */
2773 if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 2789 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2774 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) { 2790 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2775 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, 2791 (ioc->bus_type == SAS)) {
2776 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); 2792 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2793 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2794 300 /*seconds*/, sleepFlag);
2777 } else { 2795 } else {
2778 rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, 2796 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2779 reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag); 2797 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2798 30 /*seconds*/, sleepFlag);
2780 } 2799 }
2781 return rc; 2800 return rc;
2782} 2801}
@@ -4387,6 +4406,138 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4387} 4406}
4388 4407
4389/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4408/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4409
4410static void
4411mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4412 MpiEventDataRaid_t * pRaidEventData)
4413{
4414 int volume;
4415 int reason;
4416 int disk;
4417 int status;
4418 int flags;
4419 int state;
4420
4421 volume = pRaidEventData->VolumeID;
4422 reason = pRaidEventData->ReasonCode;
4423 disk = pRaidEventData->PhysDiskNum;
4424 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4425 flags = (status >> 0) & 0xff;
4426 state = (status >> 8) & 0xff;
4427
4428 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4429 return;
4430 }
4431
4432 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4433 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4434 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4435 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4436 ioc->name, disk);
4437 } else {
4438 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4439 ioc->name, volume);
4440 }
4441
4442 switch(reason) {
4443 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4444 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4445 ioc->name);
4446 break;
4447
4448 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4449
4450 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4451 ioc->name);
4452 break;
4453
4454 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4455 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4456 ioc->name);
4457 break;
4458
4459 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4460 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4461 ioc->name,
4462 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4463 ? "optimal"
4464 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4465 ? "degraded"
4466 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4467 ? "failed"
4468 : "state unknown",
4469 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4470 ? ", enabled" : "",
4471 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4472 ? ", quiesced" : "",
4473 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4474 ? ", resync in progress" : "" );
4475 break;
4476
4477 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4478 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4479 ioc->name, disk);
4480 break;
4481
4482 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4483 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4484 ioc->name);
4485 break;
4486
4487 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4488 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4489 ioc->name);
4490 break;
4491
4492 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4493 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4494 ioc->name);
4495 break;
4496
4497 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4498 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4499 ioc->name,
4500 state == MPI_PHYSDISK0_STATUS_ONLINE
4501 ? "online"
4502 : state == MPI_PHYSDISK0_STATUS_MISSING
4503 ? "missing"
4504 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4505 ? "not compatible"
4506 : state == MPI_PHYSDISK0_STATUS_FAILED
4507 ? "failed"
4508 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4509 ? "initializing"
4510 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4511 ? "offline requested"
4512 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4513 ? "failed requested"
4514 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4515 ? "offline"
4516 : "state unknown",
4517 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4518 ? ", out of sync" : "",
4519 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4520 ? ", quiesced" : "" );
4521 break;
4522
4523 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4524 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4525 ioc->name, disk);
4526 break;
4527
4528 case MPI_EVENT_RAID_RC_SMART_DATA:
4529 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4530 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4531 break;
4532
4533 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4534 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4535 ioc->name, disk);
4536 break;
4537 }
4538}
4539
4540/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4390/* 4541/*
4391 * GetIoUnitPage2 - Retrieve BIOS version and boot order information. 4542 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4392 * @ioc: Pointer to MPT_ADAPTER structure 4543 * @ioc: Pointer to MPT_ADAPTER structure
@@ -4598,6 +4749,14 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4598 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; 4749 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4599 MpiDeviceInfo_t *pdevice = NULL; 4750 MpiDeviceInfo_t *pdevice = NULL;
4600 4751
4752 /*
4753 * Save "Set to Avoid SCSI Bus Resets" flag
4754 */
4755 ioc->spi_data.bus_reset =
4756 (le32_to_cpu(pPP2->PortFlags) &
4757 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4758 0 : 1 ;
4759
4601 /* Save the Port Page 2 data 4760 /* Save the Port Page 2 data
4602 * (reformat into a 32bit quantity) 4761 * (reformat into a 32bit quantity)
4603 */ 4762 */
@@ -5167,115 +5326,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5167} 5326}
5168 5327
5169/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5328/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5170/**
5171 * mpt_toolbox - Generic function to issue toolbox message
5172 * @ioc - Pointer to an adapter structure
5173 * @cfg - Pointer to a toolbox structure. Struct contains
5174 * action, page address, direction, physical address
5175 * and pointer to a configuration page header
5176 * Page header is updated.
5177 *
5178 * Returns 0 for success
5179 * -EPERM if not allowed due to ISR context
5180 * -EAGAIN if no msg frames currently available
5181 * -EFAULT for non-successful reply or no reply (timeout)
5182 */
5183int
5184mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5185{
5186 ToolboxIstwiReadWriteRequest_t *pReq;
5187 MPT_FRAME_HDR *mf;
5188 struct pci_dev *pdev;
5189 unsigned long flags;
5190 int rc;
5191 u32 flagsLength;
5192 int in_isr;
5193
5194 /* Prevent calling wait_event() (below), if caller happens
5195 * to be in ISR context, because that is fatal!
5196 */
5197 in_isr = in_interrupt();
5198 if (in_isr) {
5199 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5200 ioc->name));
5201 return -EPERM;
5202 }
5203
5204 /* Get and Populate a free Frame
5205 */
5206 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5207 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5208 ioc->name));
5209 return -EAGAIN;
5210 }
5211 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5212 pReq->Tool = pCfg->action;
5213 pReq->Reserved = 0;
5214 pReq->ChainOffset = 0;
5215 pReq->Function = MPI_FUNCTION_TOOLBOX;
5216 pReq->Reserved1 = 0;
5217 pReq->Reserved2 = 0;
5218 pReq->MsgFlags = 0;
5219 pReq->Flags = pCfg->dir;
5220 pReq->BusNum = 0;
5221 pReq->Reserved3 = 0;
5222 pReq->NumAddressBytes = 0x01;
5223 pReq->Reserved4 = 0;
5224 pReq->DataLength = cpu_to_le16(0x04);
5225 pdev = ioc->pcidev;
5226 if (pdev->devfn & 1)
5227 pReq->DeviceAddr = 0xB2;
5228 else
5229 pReq->DeviceAddr = 0xB0;
5230 pReq->Addr1 = 0;
5231 pReq->Addr2 = 0;
5232 pReq->Addr3 = 0;
5233 pReq->Reserved5 = 0;
5234
5235 /* Add a SGE to the config request.
5236 */
5237
5238 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5239
5240 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5241
5242 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5243 ioc->name, pReq->Tool));
5244
5245 /* Append pCfg pointer to end of mf
5246 */
5247 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5248
5249 /* Initalize the timer
5250 */
5251 init_timer(&pCfg->timer);
5252 pCfg->timer.data = (unsigned long) ioc;
5253 pCfg->timer.function = mpt_timer_expired;
5254 pCfg->wait_done = 0;
5255
5256 /* Set the timer; ensure 10 second minimum */
5257 if (pCfg->timeout < 10)
5258 pCfg->timer.expires = jiffies + HZ*10;
5259 else
5260 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5261
5262 /* Add to end of Q, set timer and then issue this command */
5263 spin_lock_irqsave(&ioc->FreeQlock, flags);
5264 list_add_tail(&pCfg->linkage, &ioc->configQ);
5265 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5266
5267 add_timer(&pCfg->timer);
5268 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5269 wait_event(mpt_waitq, pCfg->wait_done);
5270
5271 /* mf has been freed - do not access */
5272
5273 rc = pCfg->status;
5274
5275 return rc;
5276}
5277
5278/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5279/* 5329/*
5280 * mpt_timer_expired - Call back for timer process. 5330 * mpt_timer_expired - Call back for timer process.
5281 * Used only internal config functionality. 5331 * Used only internal config functionality.
@@ -5967,6 +6017,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5967 } 6017 }
5968 } 6018 }
5969 break; 6019 break;
6020 case MPI_EVENT_INTEGRATED_RAID:
6021 mptbase_raid_process_event_data(ioc,
6022 (MpiEventDataRaid_t *)pEventReply->Data);
6023 break;
5970 default: 6024 default:
5971 break; 6025 break;
5972 } 6026 }
@@ -5978,7 +6032,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5978 if (ioc->events && (ioc->eventTypes & ( 1 << event))) { 6032 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5979 int idx; 6033 int idx;
5980 6034
5981 idx = ioc->eventContext % ioc->eventLogSize; 6035 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
5982 6036
5983 ioc->events[idx].event = event; 6037 ioc->events[idx].event = event;
5984 ioc->events[idx].eventContext = ioc->eventContext; 6038 ioc->events[idx].eventContext = ioc->eventContext;
@@ -6046,7 +6100,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6046 6100
6047/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6101/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6048/* 6102/*
6049 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC. 6103 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6050 * @ioc: Pointer to MPT_ADAPTER structure 6104 * @ioc: Pointer to MPT_ADAPTER structure
6051 * @mr: Pointer to MPT reply frame 6105 * @mr: Pointer to MPT reply frame
6052 * @log_info: U32 LogInfo word from the IOC 6106 * @log_info: U32 LogInfo word from the IOC
@@ -6054,7 +6108,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6054 * Refer to lsi/sp_log.h. 6108 * Refer to lsi/sp_log.h.
6055 */ 6109 */
6056static void 6110static void
6057mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) 6111mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6058{ 6112{
6059 u32 info = log_info & 0x00FF0000; 6113 u32 info = log_info & 0x00FF0000;
6060 char *desc = "unknown"; 6114 char *desc = "unknown";
@@ -6376,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index);
6376EXPORT_SYMBOL(mpt_stm_index); 6430EXPORT_SYMBOL(mpt_stm_index);
6377EXPORT_SYMBOL(mpt_HardResetHandler); 6431EXPORT_SYMBOL(mpt_HardResetHandler);
6378EXPORT_SYMBOL(mpt_config); 6432EXPORT_SYMBOL(mpt_config);
6379EXPORT_SYMBOL(mpt_toolbox);
6380EXPORT_SYMBOL(mpt_findImVolumes); 6433EXPORT_SYMBOL(mpt_findImVolumes);
6381EXPORT_SYMBOL(mpt_read_ioc_pg_3); 6434EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6382EXPORT_SYMBOL(mpt_alloc_fw_memory); 6435EXPORT_SYMBOL(mpt_alloc_fw_memory);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 47053ac65068..723d54300953 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.06" 79#define MPT_LINUX_VERSION_COMMON "3.03.07"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.07"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -123,7 +123,7 @@
123#define MPT_MAX_FRAME_SIZE 128 123#define MPT_MAX_FRAME_SIZE 128
124#define MPT_DEFAULT_FRAME_SIZE 128 124#define MPT_DEFAULT_FRAME_SIZE 128
125 125
126#define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */ 126#define MPT_REPLY_FRAME_SIZE 0x50 /* Must be a multiple of 8 */
127 127
128#define MPT_SG_REQ_128_SCALE 1 128#define MPT_SG_REQ_128_SCALE 1
129#define MPT_SG_REQ_96_SCALE 2 129#define MPT_SG_REQ_96_SCALE 2
@@ -510,9 +510,10 @@ struct mptfc_rport_info
510{ 510{
511 struct list_head list; 511 struct list_head list;
512 struct fc_rport *rport; 512 struct fc_rport *rport;
513 VirtDevice *vdev; 513 struct scsi_target *starget;
514 FCDevicePage0_t pg0; 514 FCDevicePage0_t pg0;
515 u8 flags; 515 u8 flags;
516 u8 remap_needed;
516}; 517};
517 518
518/* 519/*
@@ -615,6 +616,7 @@ typedef struct _MPT_ADAPTER
615 * increments by 32 bytes 616 * increments by 32 bytes
616 */ 617 */
617 int errata_flag_1064; 618 int errata_flag_1064;
619 int aen_event_read_flag; /* flag to indicate event log was read*/
618 u8 FirstWhoInit; 620 u8 FirstWhoInit;
619 u8 upload_fw; /* If set, do a fw upload */ 621 u8 upload_fw; /* If set, do a fw upload */
620 u8 reload_fw; /* Force a FW Reload on next reset */ 622 u8 reload_fw; /* Force a FW Reload on next reset */
@@ -631,6 +633,7 @@ typedef struct _MPT_ADAPTER
631 struct mutex sas_topology_mutex; 633 struct mutex sas_topology_mutex;
632 MPT_SAS_MGMT sas_mgmt; 634 MPT_SAS_MGMT sas_mgmt;
633 int num_ports; 635 int num_ports;
636 struct work_struct mptscsih_persistTask;
634 637
635 struct list_head fc_rports; 638 struct list_head fc_rports;
636 spinlock_t fc_rport_lock; /* list and ri flags */ 639 spinlock_t fc_rport_lock; /* list and ri flags */
@@ -803,6 +806,12 @@ typedef struct _mpt_sge {
803#define dreplyprintk(x) 806#define dreplyprintk(x)
804#endif 807#endif
805 808
809#ifdef DMPT_DEBUG_FC
810#define dfcprintk(x) printk x
811#else
812#define dfcprintk(x)
813#endif
814
806#ifdef MPT_DEBUG_TM 815#ifdef MPT_DEBUG_TM
807#define dtmprintk(x) printk x 816#define dtmprintk(x) printk x
808#define DBG_DUMP_TM_REQUEST_FRAME(mfp) \ 817#define DBG_DUMP_TM_REQUEST_FRAME(mfp) \
@@ -1018,7 +1027,6 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
1018extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); 1027extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
1019extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 1028extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
1020extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); 1029extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
1021extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
1022extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); 1030extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
1023extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 1031extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1024extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1032extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index bdf709987982..9b64e07400da 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -136,6 +136,12 @@ static void mptctl_free_tm_flags(MPT_ADAPTER *ioc);
136 */ 136 */
137static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); 137static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
138 138
139/*
140 * Event Handler function
141 */
142static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
143struct fasync_struct *async_queue=NULL;
144
139/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
140/* 146/*
141 * Scatter gather list (SGL) sizes and limits... 147 * Scatter gather list (SGL) sizes and limits...
@@ -385,18 +391,18 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
385 } 391 }
386 392
387 /* Now wait for the command to complete */ 393 /* Now wait for the command to complete */
388 ii = wait_event_interruptible_timeout(mptctl_wait, 394 ii = wait_event_timeout(mptctl_wait,
389 ioctl->wait_done == 1, 395 ioctl->wait_done == 1,
390 HZ*5 /* 5 second timeout */); 396 HZ*5 /* 5 second timeout */);
391 397
392 if(ii <=0 && (ioctl->wait_done != 1 )) { 398 if(ii <=0 && (ioctl->wait_done != 1 )) {
399 mpt_free_msg_frame(hd->ioc, mf);
393 ioctl->wait_done = 0; 400 ioctl->wait_done = 0;
394 retval = -1; /* return failure */ 401 retval = -1; /* return failure */
395 } 402 }
396 403
397mptctl_bus_reset_done: 404mptctl_bus_reset_done:
398 405
399 mpt_free_msg_frame(hd->ioc, mf);
400 mptctl_free_tm_flags(ioctl->ioc); 406 mptctl_free_tm_flags(ioctl->ioc);
401 return retval; 407 return retval;
402} 408}
@@ -472,6 +478,69 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
472} 478}
473 479
474/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 480/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
481/* ASYNC Event Notification Support */
482static int
483mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
484{
485 u8 event;
486
487 event = le32_to_cpu(pEvReply->Event) & 0xFF;
488
489 dctlprintk(("%s() called\n", __FUNCTION__));
490 if(async_queue == NULL)
491 return 1;
492
493 /* Raise SIGIO for persistent events.
494 * TODO - this define is not in MPI spec yet,
495 * but they plan to set it to 0x21
496 */
497 if (event == 0x21 ) {
498 ioc->aen_event_read_flag=1;
499 dctlprintk(("Raised SIGIO to application\n"));
500 devtprintk(("Raised SIGIO to application\n"));
501 kill_fasync(&async_queue, SIGIO, POLL_IN);
502 return 1;
503 }
504
505 /* This flag is set after SIGIO was raised, and
506 * remains set until the application has read
507 * the event log via ioctl=MPTEVENTREPORT
508 */
509 if(ioc->aen_event_read_flag)
510 return 1;
511
512 /* Signal only for the events that are
513 * requested for by the application
514 */
515 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
516 ioc->aen_event_read_flag=1;
517 dctlprintk(("Raised SIGIO to application\n"));
518 devtprintk(("Raised SIGIO to application\n"));
519 kill_fasync(&async_queue, SIGIO, POLL_IN);
520 }
521 return 1;
522}
523
524static int
525mptctl_fasync(int fd, struct file *filep, int mode)
526{
527 MPT_ADAPTER *ioc;
528
529 list_for_each_entry(ioc, &ioc_list, list)
530 ioc->aen_event_read_flag=0;
531
532 dctlprintk(("%s() called\n", __FUNCTION__));
533 return fasync_helper(fd, filep, mode, &async_queue);
534}
535
536static int
537mptctl_release(struct inode *inode, struct file *filep)
538{
539 dctlprintk(("%s() called\n", __FUNCTION__));
540 return fasync_helper(-1, filep, 0, &async_queue);
541}
542
543/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
475/* 544/*
476 * MPT ioctl handler 545 * MPT ioctl handler
477 * cmd - specify the particular IOCTL command to be issued 546 * cmd - specify the particular IOCTL command to be issued
@@ -674,22 +743,23 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
674 u16 iocstat; 743 u16 iocstat;
675 pFWDownloadReply_t ReplyMsg = NULL; 744 pFWDownloadReply_t ReplyMsg = NULL;
676 745
677 dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); 746 dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
678 747
679 dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf)); 748 dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf));
680 dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen)); 749 dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen));
681 dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc)); 750 dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc));
682 751
683 if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) { 752 if (mpt_verify_adapter(ioc, &iocp) < 0) {
684 dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n", 753 dctlprintk(("ioctl_fwdl - ioc%d not found!\n",
685 __FILE__, __LINE__, ioc)); 754 ioc));
686 return -ENODEV; /* (-6) No such device or address */ 755 return -ENODEV; /* (-6) No such device or address */
687 } 756 } else {
688 757
689 /* Valid device. Get a message frame and construct the FW download message. 758 /* Valid device. Get a message frame and construct the FW download message.
690 */ 759 */
691 if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) 760 if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
692 return -EAGAIN; 761 return -EAGAIN;
762 }
693 dlmsg = (FWDownload_t*) mf; 763 dlmsg = (FWDownload_t*) mf;
694 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; 764 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
695 sgOut = (char *) (ptsge + 1); 765 sgOut = (char *) (ptsge + 1);
@@ -702,7 +772,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
702 dlmsg->ChainOffset = 0; 772 dlmsg->ChainOffset = 0;
703 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; 773 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
704 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; 774 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
705 dlmsg->MsgFlags = 0; 775 if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
776 dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
777 else
778 dlmsg->MsgFlags = 0;
779
706 780
707 /* Set up the Transaction SGE. 781 /* Set up the Transaction SGE.
708 */ 782 */
@@ -754,7 +828,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
754 goto fwdl_out; 828 goto fwdl_out;
755 } 829 }
756 830
757 dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); 831 dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags));
758 832
759 /* 833 /*
760 * Parse SG list, copying sgl itself, 834 * Parse SG list, copying sgl itself,
@@ -803,11 +877,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
803 /* 877 /*
804 * Finally, perform firmware download. 878 * Finally, perform firmware download.
805 */ 879 */
806 iocp->ioctl->wait_done = 0; 880 ReplyMsg = NULL;
807 mpt_put_msg_frame(mptctl_id, iocp, mf); 881 mpt_put_msg_frame(mptctl_id, iocp, mf);
808 882
809 /* Now wait for the command to complete */ 883 /* Now wait for the command to complete */
810 ret = wait_event_interruptible_timeout(mptctl_wait, 884 ret = wait_event_timeout(mptctl_wait,
811 iocp->ioctl->wait_done == 1, 885 iocp->ioctl->wait_done == 1,
812 HZ*60); 886 HZ*60);
813 887
@@ -1145,7 +1219,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1145 /* Fill in the data and return the structure to the calling 1219 /* Fill in the data and return the structure to the calling
1146 * program 1220 * program
1147 */ 1221 */
1148 if (ioc->bus_type == FC) 1222 if (ioc->bus_type == SAS)
1223 karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1224 else if (ioc->bus_type == FC)
1149 karg->adapterType = MPT_IOCTL_INTERFACE_FC; 1225 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1150 else 1226 else
1151 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; 1227 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
@@ -1170,12 +1246,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1170 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); 1246 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1171 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); 1247 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1172 } else if (cim_rev == 2) { 1248 } else if (cim_rev == 2) {
1173 /* Get the PCI bus, device, function and segment ID numbers 1249 /* Get the PCI bus, device, function and segment ID numbers
1174 for the IOC */ 1250 for the IOC */
1175 karg->pciInfo.u.bits.busNumber = pdev->bus->number; 1251 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1176 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); 1252 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1177 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); 1253 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1178 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1179 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); 1254 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1180 } 1255 }
1181 1256
@@ -1500,7 +1575,7 @@ mptctl_eventquery (unsigned long arg)
1500 return -ENODEV; 1575 return -ENODEV;
1501 } 1576 }
1502 1577
1503 karg.eventEntries = ioc->eventLogSize; 1578 karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1504 karg.eventTypes = ioc->eventTypes; 1579 karg.eventTypes = ioc->eventTypes;
1505 1580
1506 /* Copy the data from kernel memory to user memory 1581 /* Copy the data from kernel memory to user memory
@@ -1550,7 +1625,6 @@ mptctl_eventenable (unsigned long arg)
1550 memset(ioc->events, 0, sz); 1625 memset(ioc->events, 0, sz);
1551 ioc->alloc_total += sz; 1626 ioc->alloc_total += sz;
1552 1627
1553 ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;
1554 ioc->eventContext = 0; 1628 ioc->eventContext = 0;
1555 } 1629 }
1556 1630
@@ -1590,7 +1664,7 @@ mptctl_eventreport (unsigned long arg)
1590 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); 1664 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1591 1665
1592 1666
1593 max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents; 1667 max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1594 1668
1595 /* If fewer than 1 event is requested, there must have 1669 /* If fewer than 1 event is requested, there must have
1596 * been some type of error. 1670 * been some type of error.
@@ -1598,6 +1672,9 @@ mptctl_eventreport (unsigned long arg)
1598 if ((max < 1) || !ioc->events) 1672 if ((max < 1) || !ioc->events)
1599 return -ENODATA; 1673 return -ENODATA;
1600 1674
1675 /* reset this flag so SIGIO can restart */
1676 ioc->aen_event_read_flag=0;
1677
1601 /* Copy the data from kernel memory to user memory 1678 /* Copy the data from kernel memory to user memory
1602 */ 1679 */
1603 numBytes = max * sizeof(MPT_IOCTL_EVENTS); 1680 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
@@ -1817,6 +1894,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1817 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: 1894 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1818 case MPI_FUNCTION_FW_DOWNLOAD: 1895 case MPI_FUNCTION_FW_DOWNLOAD:
1819 case MPI_FUNCTION_FC_PRIMITIVE_SEND: 1896 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1897 case MPI_FUNCTION_TOOLBOX:
1898 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1820 break; 1899 break;
1821 1900
1822 case MPI_FUNCTION_SCSI_IO_REQUEST: 1901 case MPI_FUNCTION_SCSI_IO_REQUEST:
@@ -1837,7 +1916,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1837 goto done_free_mem; 1916 goto done_free_mem;
1838 } 1917 }
1839 1918
1840 pScsiReq->MsgFlags = mpt_msg_flags(); 1919 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1920 pScsiReq->MsgFlags |= mpt_msg_flags();
1921
1841 1922
1842 /* verify that app has not requested 1923 /* verify that app has not requested
1843 * more sense data than driver 1924 * more sense data than driver
@@ -1888,6 +1969,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1888 } 1969 }
1889 break; 1970 break;
1890 1971
1972 case MPI_FUNCTION_SMP_PASSTHROUGH:
1973 /* Check mf->PassthruFlags to determine if
1974 * transfer is ImmediateMode or not.
1975 * Immediate mode returns data in the ReplyFrame.
1976 * Else, we are sending request and response data
1977 * in two SGLs at the end of the mf.
1978 */
1979 break;
1980
1981 case MPI_FUNCTION_SATA_PASSTHROUGH:
1982 if (!ioc->sh) {
1983 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1984 "SCSI driver is not loaded. \n",
1985 __FILE__, __LINE__);
1986 rc = -EFAULT;
1987 goto done_free_mem;
1988 }
1989 break;
1990
1891 case MPI_FUNCTION_RAID_ACTION: 1991 case MPI_FUNCTION_RAID_ACTION:
1892 /* Just add a SGE 1992 /* Just add a SGE
1893 */ 1993 */
@@ -1900,7 +2000,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1900 int scsidir = MPI_SCSIIO_CONTROL_READ; 2000 int scsidir = MPI_SCSIIO_CONTROL_READ;
1901 int dataSize; 2001 int dataSize;
1902 2002
1903 pScsiReq->MsgFlags = mpt_msg_flags(); 2003 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
2004 pScsiReq->MsgFlags |= mpt_msg_flags();
2005
1904 2006
1905 /* verify that app has not requested 2007 /* verify that app has not requested
1906 * more sense data than driver 2008 * more sense data than driver
@@ -2130,7 +2232,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
2130 2232
2131 /* Now wait for the command to complete */ 2233 /* Now wait for the command to complete */
2132 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; 2234 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2133 timeout = wait_event_interruptible_timeout(mptctl_wait, 2235 timeout = wait_event_timeout(mptctl_wait,
2134 ioc->ioctl->wait_done == 1, 2236 ioc->ioctl->wait_done == 1,
2135 HZ*timeout); 2237 HZ*timeout);
2136 2238
@@ -2246,13 +2348,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2246 hp_host_info_t __user *uarg = (void __user *) arg; 2348 hp_host_info_t __user *uarg = (void __user *) arg;
2247 MPT_ADAPTER *ioc; 2349 MPT_ADAPTER *ioc;
2248 struct pci_dev *pdev; 2350 struct pci_dev *pdev;
2249 char *pbuf; 2351 char *pbuf=NULL;
2250 dma_addr_t buf_dma; 2352 dma_addr_t buf_dma;
2251 hp_host_info_t karg; 2353 hp_host_info_t karg;
2252 CONFIGPARMS cfg; 2354 CONFIGPARMS cfg;
2253 ConfigPageHeader_t hdr; 2355 ConfigPageHeader_t hdr;
2254 int iocnum; 2356 int iocnum;
2255 int rc, cim_rev; 2357 int rc, cim_rev;
2358 ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
2359 MPT_FRAME_HDR *mf = NULL;
2360 MPIHeader_t *mpi_hdr;
2256 2361
2257 dctlprintk((": mptctl_hp_hostinfo called.\n")); 2362 dctlprintk((": mptctl_hp_hostinfo called.\n"));
2258 /* Reset long to int. Should affect IA64 and SPARC only 2363 /* Reset long to int. Should affect IA64 and SPARC only
@@ -2370,7 +2475,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2370 2475
2371 karg.base_io_addr = pci_resource_start(pdev, 0); 2476 karg.base_io_addr = pci_resource_start(pdev, 0);
2372 2477
2373 if (ioc->bus_type == FC) 2478 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2374 karg.bus_phys_width = HP_BUS_WIDTH_UNK; 2479 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2375 else 2480 else
2376 karg.bus_phys_width = HP_BUS_WIDTH_16; 2481 karg.bus_phys_width = HP_BUS_WIDTH_16;
@@ -2388,20 +2493,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2388 } 2493 }
2389 } 2494 }
2390 2495
2391 cfg.pageAddr = 0; 2496 /*
2392 cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; 2497 * Gather ISTWI(Industry Standard Two Wire Interface) Data
2393 cfg.dir = MPI_TB_ISTWI_FLAGS_READ; 2498 */
2394 cfg.timeout = 10; 2499 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2500 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
2501 ioc->name,__FUNCTION__));
2502 goto out;
2503 }
2504
2505 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2506 mpi_hdr = (MPIHeader_t *) mf;
2507 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2508 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2509 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2510 IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
2511 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2512 IstwiRWRequest->NumAddressBytes = 0x01;
2513 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2514 if (pdev->devfn & 1)
2515 IstwiRWRequest->DeviceAddr = 0xB2;
2516 else
2517 IstwiRWRequest->DeviceAddr = 0xB0;
2518
2395 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); 2519 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2396 if (pbuf) { 2520 if (!pbuf)
2397 cfg.physAddr = buf_dma; 2521 goto out;
2398 if ((mpt_toolbox(ioc, &cfg)) == 0) { 2522 mpt_add_sge((char *)&IstwiRWRequest->SGL,
2399 karg.rsvd = *(u32 *)pbuf; 2523 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2400 } 2524
2401 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); 2525 ioc->ioctl->wait_done = 0;
2402 pbuf = NULL; 2526 mpt_put_msg_frame(mptctl_id, ioc, mf);
2527
2528 rc = wait_event_timeout(mptctl_wait,
2529 ioc->ioctl->wait_done == 1,
2530 HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */);
2531
2532 if(rc <=0 && (ioc->ioctl->wait_done != 1 )) {
2533 /*
2534 * Now we need to reset the board
2535 */
2536 mpt_free_msg_frame(ioc, mf);
2537 mptctl_timeout_expired(ioc->ioctl);
2538 goto out;
2403 } 2539 }
2404 2540
2541 /*
2542 *ISTWI Data Definition
2543 * pbuf[0] = FW_VERSION = 0x4
2544 * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
2545 * the config, you should be seeing one out of these three values
2546 * pbuf[2] = Drive Installed Map = bit pattern depend on which
2547 * bays have drives in them
2548 * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
2549 */
2550 if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID)
2551 karg.rsvd = *(u32 *)pbuf;
2552
2553 out:
2554 if (pbuf)
2555 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2556
2405 /* Copy the data from kernel memory to user memory 2557 /* Copy the data from kernel memory to user memory
2406 */ 2558 */
2407 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { 2559 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
@@ -2459,7 +2611,7 @@ mptctl_hp_targetinfo(unsigned long arg)
2459 2611
2460 /* There is nothing to do for FCP parts. 2612 /* There is nothing to do for FCP parts.
2461 */ 2613 */
2462 if (ioc->bus_type == FC) 2614 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2463 return 0; 2615 return 0;
2464 2616
2465 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) 2617 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
@@ -2569,6 +2721,8 @@ mptctl_hp_targetinfo(unsigned long arg)
2569static struct file_operations mptctl_fops = { 2721static struct file_operations mptctl_fops = {
2570 .owner = THIS_MODULE, 2722 .owner = THIS_MODULE,
2571 .llseek = no_llseek, 2723 .llseek = no_llseek,
2724 .release = mptctl_release,
2725 .fasync = mptctl_fasync,
2572 .unlocked_ioctl = mptctl_ioctl, 2726 .unlocked_ioctl = mptctl_ioctl,
2573#ifdef CONFIG_COMPAT 2727#ifdef CONFIG_COMPAT
2574 .compat_ioctl = compat_mpctl_ioctl, 2728 .compat_ioctl = compat_mpctl_ioctl,
@@ -2813,6 +2967,11 @@ static int __init mptctl_init(void)
2813 /* FIXME! */ 2967 /* FIXME! */
2814 } 2968 }
2815 2969
2970 if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {
2971 devtprintk((KERN_INFO MYNAM
2972 ": Registered for IOC event notifications\n"));
2973 }
2974
2816 return 0; 2975 return 0;
2817 2976
2818out_fail: 2977out_fail:
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 518996e03481..a2f8a97992e6 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -169,8 +169,10 @@ struct mpt_ioctl_pci_info2 {
169 * Read only. 169 * Read only.
170 * Data starts at offset 0xC 170 * Data starts at offset 0xC
171 */ 171 */
172#define MPT_IOCTL_INTERFACE_FC (0x01)
173#define MPT_IOCTL_INTERFACE_SCSI (0x00) 172#define MPT_IOCTL_INTERFACE_SCSI (0x00)
173#define MPT_IOCTL_INTERFACE_FC (0x01)
174#define MPT_IOCTL_INTERFACE_FC_IP (0x02)
175#define MPT_IOCTL_INTERFACE_SAS (0x03)
174#define MPT_IOCTL_VERSION_LENGTH (32) 176#define MPT_IOCTL_VERSION_LENGTH (32)
175 177
176struct mpt_ioctl_iocinfo { 178struct mpt_ioctl_iocinfo {
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index b102c7666d0e..c3a3499bce2a 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -93,10 +93,11 @@ static int mptfcDoneCtx = -1;
93static int mptfcTaskCtx = -1; 93static int mptfcTaskCtx = -1;
94static int mptfcInternalCtx = -1; /* Used only for internal commands */ 94static int mptfcInternalCtx = -1; /* Used only for internal commands */
95 95
96int mptfc_slave_alloc(struct scsi_device *device); 96static int mptfc_target_alloc(struct scsi_target *starget);
97static int mptfc_slave_alloc(struct scsi_device *sdev);
97static int mptfc_qcmd(struct scsi_cmnd *SCpnt, 98static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
98 void (*done)(struct scsi_cmnd *)); 99 void (*done)(struct scsi_cmnd *));
99 100static void mptfc_target_destroy(struct scsi_target *starget);
100static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); 101static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
101static void __devexit mptfc_remove(struct pci_dev *pdev); 102static void __devexit mptfc_remove(struct pci_dev *pdev);
102 103
@@ -107,10 +108,10 @@ static struct scsi_host_template mptfc_driver_template = {
107 .name = "MPT FC Host", 108 .name = "MPT FC Host",
108 .info = mptscsih_info, 109 .info = mptscsih_info,
109 .queuecommand = mptfc_qcmd, 110 .queuecommand = mptfc_qcmd,
110 .target_alloc = mptscsih_target_alloc, 111 .target_alloc = mptfc_target_alloc,
111 .slave_alloc = mptfc_slave_alloc, 112 .slave_alloc = mptfc_slave_alloc,
112 .slave_configure = mptscsih_slave_configure, 113 .slave_configure = mptscsih_slave_configure,
113 .target_destroy = mptscsih_target_destroy, 114 .target_destroy = mptfc_target_destroy,
114 .slave_destroy = mptscsih_slave_destroy, 115 .slave_destroy = mptscsih_slave_destroy,
115 .change_queue_depth = mptscsih_change_queue_depth, 116 .change_queue_depth = mptscsih_change_queue_depth,
116 .eh_abort_handler = mptscsih_abort, 117 .eh_abort_handler = mptscsih_abort,
@@ -348,14 +349,33 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
348} 349}
349 350
350static void 351static void
352mptfc_remap_sdev(struct scsi_device *sdev, void *arg)
353{
354 VirtDevice *vdev;
355 VirtTarget *vtarget;
356 struct scsi_target *starget;
357
358 starget = scsi_target(sdev);
359 if (starget->hostdata == arg) {
360 vtarget = arg;
361 vdev = sdev->hostdata;
362 if (vdev) {
363 vdev->bus_id = vtarget->bus_id;
364 vdev->target_id = vtarget->target_id;
365 }
366 }
367}
368
369static void
351mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) 370mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
352{ 371{
353 struct fc_rport_identifiers rport_ids; 372 struct fc_rport_identifiers rport_ids;
354 struct fc_rport *rport; 373 struct fc_rport *rport;
355 struct mptfc_rport_info *ri; 374 struct mptfc_rport_info *ri;
356 int match = 0; 375 int new_ri = 1;
357 u64 port_name; 376 u64 pn;
358 unsigned long flags; 377 unsigned long flags;
378 VirtTarget *vtarget;
359 379
360 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) 380 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
361 return; 381 return;
@@ -363,14 +383,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
363 /* scan list looking for a match */ 383 /* scan list looking for a match */
364 spin_lock_irqsave(&ioc->fc_rport_lock, flags); 384 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
365 list_for_each_entry(ri, &ioc->fc_rports, list) { 385 list_for_each_entry(ri, &ioc->fc_rports, list) {
366 port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; 386 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
367 if (port_name == rport_ids.port_name) { /* match */ 387 if (pn == rport_ids.port_name) { /* match */
368 list_move_tail(&ri->list, &ioc->fc_rports); 388 list_move_tail(&ri->list, &ioc->fc_rports);
369 match = 1; 389 new_ri = 0;
370 break; 390 break;
371 } 391 }
372 } 392 }
373 if (!match) { /* allocate one */ 393 if (new_ri) { /* allocate one */
374 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); 394 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
375 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); 395 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
376 if (!ri) 396 if (!ri)
@@ -382,40 +402,43 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
382 ri->pg0 = *pg0; /* add/update pg0 data */ 402 ri->pg0 = *pg0; /* add/update pg0 data */
383 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING; 403 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
384 404
405 /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
385 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { 406 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
386 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; 407 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
387 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); 408 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
388 rport = fc_remote_port_add(ioc->sh,channel, &rport_ids); 409 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
389 spin_lock_irqsave(&ioc->fc_rport_lock, flags); 410 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
390 if (rport) { 411 if (rport) {
391 if (*((struct mptfc_rport_info **)rport->dd_data) != ri) { 412 ri->rport = rport;
392 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV; 413 if (new_ri) /* may have been reset by user */
393 ri->vdev = NULL; 414 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
394 ri->rport = rport; 415 *((struct mptfc_rport_info **)rport->dd_data) = ri;
395 *((struct mptfc_rport_info **)rport->dd_data) = ri;
396 }
397 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
398 /* 416 /*
399 * if already mapped, remap here. If not mapped, 417 * if already mapped, remap here. If not mapped,
400 * slave_alloc will allocate vdev and map 418 * target_alloc will allocate vtarget and map,
419 * slave_alloc will fill in vdev from vtarget.
401 */ 420 */
402 if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) { 421 if (ri->starget) {
403 ri->vdev->target_id = ri->pg0.CurrentTargetID; 422 vtarget = ri->starget->hostdata;
404 ri->vdev->bus_id = ri->pg0.CurrentBus; 423 if (vtarget) {
405 ri->vdev->vtarget->target_id = ri->vdev->target_id; 424 vtarget->target_id = pg0->CurrentTargetID;
406 ri->vdev->vtarget->bus_id = ri->vdev->bus_id; 425 vtarget->bus_id = pg0->CurrentBus;
426 starget_for_each_device(ri->starget,
427 vtarget,mptfc_remap_sdev);
428 }
429 ri->remap_needed = 0;
407 } 430 }
408 #ifdef MPT_DEBUG 431 dfcprintk ((MYIOC_s_INFO_FMT
409 printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " 432 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
410 "rport tid %d, tmo %d\n", 433 "rport tid %d, tmo %d\n",
411 ioc->sh->host_no, 434 ioc->name,
435 oc->sh->host_no,
412 pg0->PortIdentifier, 436 pg0->PortIdentifier,
413 pg0->WWNN, 437 pg0->WWNN,
414 pg0->WWPN, 438 pg0->WWPN,
415 pg0->CurrentTargetID, 439 pg0->CurrentTargetID,
416 ri->rport->scsi_target_id, 440 ri->rport->scsi_target_id,
417 ri->rport->dev_loss_tmo); 441 ri->rport->dev_loss_tmo));
418 #endif
419 } else { 442 } else {
420 list_del(&ri->list); 443 list_del(&ri->list);
421 kfree(ri); 444 kfree(ri);
@@ -427,6 +450,65 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
427} 450}
428 451
429/* 452/*
453 * OS entry point to allow for host driver to free allocated memory
454 * Called if no device present or device being unloaded
455 */
456static void
457mptfc_target_destroy(struct scsi_target *starget)
458{
459 struct fc_rport *rport;
460 struct mptfc_rport_info *ri;
461
462 rport = starget_to_rport(starget);
463 if (rport) {
464 ri = *((struct mptfc_rport_info **)rport->dd_data);
465 if (ri) /* better be! */
466 ri->starget = NULL;
467 }
468 if (starget->hostdata)
469 kfree(starget->hostdata);
470 starget->hostdata = NULL;
471}
472
473/*
474 * OS entry point to allow host driver to alloc memory
475 * for each scsi target. Called once per device the bus scan.
476 * Return non-zero if allocation fails.
477 */
478static int
479mptfc_target_alloc(struct scsi_target *starget)
480{
481 VirtTarget *vtarget;
482 struct fc_rport *rport;
483 struct mptfc_rport_info *ri;
484 int rc;
485
486 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
487 if (!vtarget)
488 return -ENOMEM;
489 starget->hostdata = vtarget;
490
491 rc = -ENODEV;
492 rport = starget_to_rport(starget);
493 if (rport) {
494 ri = *((struct mptfc_rport_info **)rport->dd_data);
495 if (ri) { /* better be! */
496 vtarget->target_id = ri->pg0.CurrentTargetID;
497 vtarget->bus_id = ri->pg0.CurrentBus;
498 ri->starget = starget;
499 ri->remap_needed = 0;
500 rc = 0;
501 }
502 }
503 if (rc != 0) {
504 kfree(vtarget);
505 starget->hostdata = NULL;
506 }
507
508 return rc;
509}
510
511/*
430 * OS entry point to allow host driver to alloc memory 512 * OS entry point to allow host driver to alloc memory
431 * for each scsi device. Called once per device the bus scan. 513 * for each scsi device. Called once per device the bus scan.
432 * Return non-zero if allocation fails. 514 * Return non-zero if allocation fails.
@@ -440,7 +522,6 @@ mptfc_slave_alloc(struct scsi_device *sdev)
440 VirtDevice *vdev; 522 VirtDevice *vdev;
441 struct scsi_target *starget; 523 struct scsi_target *starget;
442 struct fc_rport *rport; 524 struct fc_rport *rport;
443 struct mptfc_rport_info *ri;
444 unsigned long flags; 525 unsigned long flags;
445 526
446 527
@@ -451,55 +532,44 @@ mptfc_slave_alloc(struct scsi_device *sdev)
451 532
452 hd = (MPT_SCSI_HOST *)sdev->host->hostdata; 533 hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
453 534
454 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); 535 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
455 if (!vdev) { 536 if (!vdev) {
456 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 537 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
457 hd->ioc->name, sizeof(VirtDevice)); 538 hd->ioc->name, sizeof(VirtDevice));
458 return -ENOMEM; 539 return -ENOMEM;
459 } 540 }
460 memset(vdev, 0, sizeof(VirtDevice));
461 541
462 spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags); 542 spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
463 543
464 if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {
465 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
466 kfree(vdev);
467 return -ENODEV;
468 }
469
470 sdev->hostdata = vdev; 544 sdev->hostdata = vdev;
471 starget = scsi_target(sdev); 545 starget = scsi_target(sdev);
472 vtarget = starget->hostdata; 546 vtarget = starget->hostdata;
547
473 if (vtarget->num_luns == 0) { 548 if (vtarget->num_luns == 0) {
549 vtarget->ioc_id = hd->ioc->id;
474 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | 550 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
475 MPT_TARGET_FLAGS_VALID_INQUIRY; 551 MPT_TARGET_FLAGS_VALID_INQUIRY;
476 hd->Targets[sdev->id] = vtarget; 552 hd->Targets[sdev->id] = vtarget;
477 } 553 }
478 554
479 vtarget->target_id = vdev->target_id;
480 vtarget->bus_id = vdev->bus_id;
481
482 vdev->vtarget = vtarget; 555 vdev->vtarget = vtarget;
483 vdev->ioc_id = hd->ioc->id; 556 vdev->ioc_id = hd->ioc->id;
484 vdev->lun = sdev->lun; 557 vdev->lun = sdev->lun;
485 vdev->target_id = ri->pg0.CurrentTargetID; 558 vdev->target_id = vtarget->target_id;
486 vdev->bus_id = ri->pg0.CurrentBus; 559 vdev->bus_id = vtarget->bus_id;
487
488 ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
489 ri->vdev = vdev;
490 560
491 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); 561 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
492 562
493 vtarget->num_luns++; 563 vtarget->num_luns++;
494 564
495#ifdef MPT_DEBUG 565 dfcprintk ((MYIOC_s_INFO_FMT
496 printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " 566 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
497 "CurrentTargetID %d, %x %llx %llx\n", 567 "CurrentTargetID %d, %x %llx %llx\n",
498 sdev->host->host_no, 568 ioc->name,
499 vtarget->num_luns, 569 sdev->host->host_no,
500 sdev->id, ri->pg0.CurrentTargetID, 570 vtarget->num_luns,
501 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN); 571 sdev->id, ri->pg0.CurrentTargetID,
502#endif 572 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
503 573
504 return 0; 574 return 0;
505} 575}
@@ -507,6 +577,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
507static int 577static int
508mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) 578mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
509{ 579{
580 struct mptfc_rport_info *ri;
510 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); 581 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
511 int err; 582 int err;
512 583
@@ -516,6 +587,10 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
516 done(SCpnt); 587 done(SCpnt);
517 return 0; 588 return 0;
518 } 589 }
590 ri = *((struct mptfc_rport_info **)rport->dd_data);
591 if (unlikely(ri->remap_needed))
592 return SCSI_MLQUEUE_HOST_BUSY;
593
519 return mptscsih_qcmd(SCpnt,done); 594 return mptscsih_qcmd(SCpnt,done);
520} 595}
521 596
@@ -591,16 +666,20 @@ mptfc_rescan_devices(void *arg)
591 666
592 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| 667 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
593 MPT_RPORT_INFO_FLAGS_MISSING); 668 MPT_RPORT_INFO_FLAGS_MISSING);
669 ri->remap_needed = 1;
594 fc_remote_port_delete(ri->rport); 670 fc_remote_port_delete(ri->rport);
595 /* 671 /*
596 * remote port not really deleted 'cause 672 * remote port not really deleted 'cause
597 * binding is by WWPN and driver only 673 * binding is by WWPN and driver only
598 * registers FCP_TARGETs 674 * registers FCP_TARGETs but cannot trust
675 * data structures.
599 */ 676 */
600 #ifdef MPT_DEBUG 677 ri->rport = NULL;
601 printk ("mptfc_rescan.%d: %llx deleted\n", 678 dfcprintk ((MYIOC_s_INFO_FMT
602 ioc->sh->host_no, ri->pg0.WWPN); 679 "mptfc_rescan.%d: %llx deleted\n",
603 #endif 680 ioc->name,
681 ioc->sh->host_no,
682 ri->pg0.WWPN));
604 } 683 }
605 } 684 }
606 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); 685 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
@@ -872,9 +951,8 @@ mptfc_init(void)
872 } 951 }
873 952
874 error = pci_register_driver(&mptfc_driver); 953 error = pci_register_driver(&mptfc_driver);
875 if (error) { 954 if (error)
876 fc_release_transport(mptfc_transport_template); 955 fc_release_transport(mptfc_transport_template);
877 }
878 956
879 return error; 957 return error;
880} 958}
@@ -885,7 +963,8 @@ mptfc_init(void)
885 * @pdev: Pointer to pci_dev structure 963 * @pdev: Pointer to pci_dev structure
886 * 964 *
887 */ 965 */
888static void __devexit mptfc_remove(struct pci_dev *pdev) 966static void __devexit
967mptfc_remove(struct pci_dev *pdev)
889{ 968{
890 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 969 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
891 struct mptfc_rport_info *p, *n; 970 struct mptfc_rport_info *p, *n;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 5a06d8d8694e..2512d0e6155e 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -89,6 +89,8 @@ static int mptsasMgmtCtx = -1;
89enum mptsas_hotplug_action { 89enum mptsas_hotplug_action {
90 MPTSAS_ADD_DEVICE, 90 MPTSAS_ADD_DEVICE,
91 MPTSAS_DEL_DEVICE, 91 MPTSAS_DEL_DEVICE,
92 MPTSAS_ADD_RAID,
93 MPTSAS_DEL_RAID,
92}; 94};
93 95
94struct mptsas_hotplug_event { 96struct mptsas_hotplug_event {
@@ -114,6 +116,7 @@ struct mptsas_hotplug_event {
114 116
115struct mptsas_devinfo { 117struct mptsas_devinfo {
116 u16 handle; /* unique id to address this device */ 118 u16 handle; /* unique id to address this device */
119 u16 handle_parent; /* unique id to address parent device */
117 u8 phy_id; /* phy number of parent device */ 120 u8 phy_id; /* phy number of parent device */
118 u8 port_id; /* sas physical port this device 121 u8 port_id; /* sas physical port this device
119 is assoc'd with */ 122 is assoc'd with */
@@ -301,9 +304,8 @@ mptsas_slave_alloc(struct scsi_device *sdev)
301 } 304 }
302 mutex_unlock(&hd->ioc->sas_topology_mutex); 305 mutex_unlock(&hd->ioc->sas_topology_mutex);
303 306
304 printk("No matching SAS device found!!\n");
305 kfree(vdev); 307 kfree(vdev);
306 return -ENODEV; 308 return -ENXIO;
307 309
308 out: 310 out:
309 vtarget->ioc_id = vdev->ioc_id; 311 vtarget->ioc_id = vdev->ioc_id;
@@ -321,6 +323,7 @@ mptsas_slave_destroy(struct scsi_device *sdev)
321 struct sas_rphy *rphy; 323 struct sas_rphy *rphy;
322 struct mptsas_portinfo *p; 324 struct mptsas_portinfo *p;
323 int i; 325 int i;
326 VirtDevice *vdev;
324 327
325 /* 328 /*
326 * Handle hotplug removal case. 329 * Handle hotplug removal case.
@@ -344,8 +347,29 @@ mptsas_slave_destroy(struct scsi_device *sdev)
344 out: 347 out:
345 mutex_unlock(&hd->ioc->sas_topology_mutex); 348 mutex_unlock(&hd->ioc->sas_topology_mutex);
346 /* 349 /*
347 * TODO: Issue target reset to flush firmware outstanding commands. 350 * Issue target reset to flush firmware outstanding commands.
348 */ 351 */
352 vdev = sdev->hostdata;
353 if (vdev->configured_lun){
354 if (mptscsih_TMHandler(hd,
355 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
356 vdev->bus_id,
357 vdev->target_id,
358 0, 0, 5 /* 5 second timeout */)
359 < 0){
360
361 /* The TM request failed!
362 * Fatal error case.
363 */
364 printk(MYIOC_s_WARN_FMT
365 "Error processing TaskMgmt id=%d TARGET_RESET\n",
366 hd->ioc->name,
367 vdev->target_id);
368
369 hd->tmPending = 0;
370 hd->tmState = TM_STATE_NONE;
371 }
372 }
349 mptscsih_slave_destroy(sdev); 373 mptscsih_slave_destroy(sdev);
350} 374}
351 375
@@ -714,6 +738,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
714 mptsas_print_device_pg0(buffer); 738 mptsas_print_device_pg0(buffer);
715 739
716 device_info->handle = le16_to_cpu(buffer->DevHandle); 740 device_info->handle = le16_to_cpu(buffer->DevHandle);
741 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
717 device_info->phy_id = buffer->PhyNum; 742 device_info->phy_id = buffer->PhyNum;
718 device_info->port_id = buffer->PhysicalPort; 743 device_info->port_id = buffer->PhysicalPort;
719 device_info->id = buffer->TargetID; 744 device_info->id = buffer->TargetID;
@@ -863,6 +888,26 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
863 return error; 888 return error;
864} 889}
865 890
891/*
892 * Returns true if there is a scsi end device
893 */
894static inline int
895mptsas_is_end_device(struct mptsas_devinfo * attached)
896{
897 if ((attached->handle) &&
898 (attached->device_info &
899 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
900 ((attached->device_info &
901 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
902 (attached->device_info &
903 MPI_SAS_DEVICE_INFO_STP_TARGET) |
904 (attached->device_info &
905 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
906 return 1;
907 else
908 return 0;
909}
910
866static void 911static void
867mptsas_parse_device_info(struct sas_identify *identify, 912mptsas_parse_device_info(struct sas_identify *identify,
868 struct mptsas_devinfo *device_info) 913 struct mptsas_devinfo *device_info)
@@ -1227,7 +1272,7 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1227} 1272}
1228 1273
1229static struct mptsas_phyinfo * 1274static struct mptsas_phyinfo *
1230mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) 1275mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
1231{ 1276{
1232 struct mptsas_portinfo *port_info; 1277 struct mptsas_portinfo *port_info;
1233 struct mptsas_phyinfo *phy_info = NULL; 1278 struct mptsas_phyinfo *phy_info = NULL;
@@ -1239,12 +1284,12 @@ mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
1239 */ 1284 */
1240 mutex_lock(&ioc->sas_topology_mutex); 1285 mutex_lock(&ioc->sas_topology_mutex);
1241 list_for_each_entry(port_info, &ioc->sas_topology, list) { 1286 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1242 for (i = 0; i < port_info->num_phys; i++) { 1287 for (i = 0; i < port_info->num_phys; i++)
1243 if (port_info->phy_info[i].attached.handle == handle) { 1288 if (mptsas_is_end_device(&port_info->phy_info[i].attached))
1244 phy_info = &port_info->phy_info[i]; 1289 if (port_info->phy_info[i].attached.id == id) {
1245 break; 1290 phy_info = &port_info->phy_info[i];
1246 } 1291 break;
1247 } 1292 }
1248 } 1293 }
1249 mutex_unlock(&ioc->sas_topology_mutex); 1294 mutex_unlock(&ioc->sas_topology_mutex);
1250 1295
@@ -1258,36 +1303,58 @@ mptsas_hotplug_work(void *arg)
1258 MPT_ADAPTER *ioc = ev->ioc; 1303 MPT_ADAPTER *ioc = ev->ioc;
1259 struct mptsas_phyinfo *phy_info; 1304 struct mptsas_phyinfo *phy_info;
1260 struct sas_rphy *rphy; 1305 struct sas_rphy *rphy;
1306 struct scsi_device *sdev;
1261 char *ds = NULL; 1307 char *ds = NULL;
1262 1308 struct mptsas_devinfo sas_device;
1263 if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1264 ds = "ssp";
1265 if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1266 ds = "stp";
1267 if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1268 ds = "sata";
1269 1309
1270 switch (ev->event_type) { 1310 switch (ev->event_type) {
1271 case MPTSAS_DEL_DEVICE: 1311 case MPTSAS_DEL_DEVICE:
1272 printk(MYIOC_s_INFO_FMT
1273 "removing %s device, channel %d, id %d, phy %d\n",
1274 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1275 1312
1276 phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle); 1313 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
1277 if (!phy_info) { 1314 if (!phy_info) {
1278 printk("mptsas: remove event for non-existant PHY.\n"); 1315 printk("mptsas: remove event for non-existant PHY.\n");
1279 break; 1316 break;
1280 } 1317 }
1281 1318
1319 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1320 ds = "ssp";
1321 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1322 ds = "stp";
1323 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1324 ds = "sata";
1325
1326 printk(MYIOC_s_INFO_FMT
1327 "removing %s device, channel %d, id %d, phy %d\n",
1328 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
1329
1282 if (phy_info->rphy) { 1330 if (phy_info->rphy) {
1283 sas_rphy_delete(phy_info->rphy); 1331 sas_rphy_delete(phy_info->rphy);
1284 phy_info->rphy = NULL; 1332 phy_info->rphy = NULL;
1285 } 1333 }
1286 break; 1334 break;
1287 case MPTSAS_ADD_DEVICE: 1335 case MPTSAS_ADD_DEVICE:
1288 printk(MYIOC_s_INFO_FMT 1336
1289 "attaching %s device, channel %d, id %d, phy %d\n", 1337 /*
1290 ioc->name, ds, ev->channel, ev->id, ev->phy_id); 1338 * When there is no sas address,
1339 * RAID volumes are being deleted,
1340 * and hidden phy disk are being added.
1341 * We don't know the SAS data yet,
1342 * so lookup sas device page to get
1343 * pertaining info
1344 */
1345 if (!ev->sas_address) {
1346 if (mptsas_sas_device_pg0(ioc,
1347 &sas_device, ev->id,
1348 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
1349 MPI_SAS_DEVICE_PGAD_FORM_SHIFT)))
1350 break;
1351 ev->handle = sas_device.handle;
1352 ev->parent_handle = sas_device.handle_parent;
1353 ev->channel = sas_device.channel;
1354 ev->phy_id = sas_device.phy_id;
1355 ev->sas_address = sas_device.sas_address;
1356 ev->device_info = sas_device.device_info;
1357 }
1291 1358
1292 phy_info = mptsas_find_phyinfo_by_parent(ioc, 1359 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1293 ev->parent_handle, ev->phy_id); 1360 ev->parent_handle, ev->phy_id);
@@ -1310,10 +1377,23 @@ mptsas_hotplug_work(void *arg)
1310 phy_info->attached.sas_address = ev->sas_address; 1377 phy_info->attached.sas_address = ev->sas_address;
1311 phy_info->attached.device_info = ev->device_info; 1378 phy_info->attached.device_info = ev->device_info;
1312 1379
1380 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1381 ds = "ssp";
1382 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1383 ds = "stp";
1384 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1385 ds = "sata";
1386
1387 printk(MYIOC_s_INFO_FMT
1388 "attaching %s device, channel %d, id %d, phy %d\n",
1389 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1390
1391
1313 rphy = sas_rphy_alloc(phy_info->phy); 1392 rphy = sas_rphy_alloc(phy_info->phy);
1314 if (!rphy) 1393 if (!rphy)
1315 break; /* non-fatal: an rphy can be added later */ 1394 break; /* non-fatal: an rphy can be added later */
1316 1395
1396 rphy->scsi_target_id = phy_info->attached.id;
1317 mptsas_parse_device_info(&rphy->identify, &phy_info->attached); 1397 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1318 if (sas_rphy_add(rphy)) { 1398 if (sas_rphy_add(rphy)) {
1319 sas_rphy_free(rphy); 1399 sas_rphy_free(rphy);
@@ -1322,6 +1402,40 @@ mptsas_hotplug_work(void *arg)
1322 1402
1323 phy_info->rphy = rphy; 1403 phy_info->rphy = rphy;
1324 break; 1404 break;
1405 case MPTSAS_ADD_RAID:
1406 sdev = scsi_device_lookup(
1407 ioc->sh,
1408 ioc->num_ports,
1409 ev->id,
1410 0);
1411 if (sdev) {
1412 scsi_device_put(sdev);
1413 break;
1414 }
1415 printk(MYIOC_s_INFO_FMT
1416 "attaching device, channel %d, id %d\n",
1417 ioc->name, ioc->num_ports, ev->id);
1418 scsi_add_device(ioc->sh,
1419 ioc->num_ports,
1420 ev->id,
1421 0);
1422 mpt_findImVolumes(ioc);
1423 break;
1424 case MPTSAS_DEL_RAID:
1425 sdev = scsi_device_lookup(
1426 ioc->sh,
1427 ioc->num_ports,
1428 ev->id,
1429 0);
1430 if (!sdev)
1431 break;
1432 printk(MYIOC_s_INFO_FMT
1433 "removing device, channel %d, id %d\n",
1434 ioc->name, ioc->num_ports, ev->id);
1435 scsi_remove_device(sdev);
1436 scsi_device_put(sdev);
1437 mpt_findImVolumes(ioc);
1438 break;
1325 } 1439 }
1326 1440
1327 kfree(ev); 1441 kfree(ev);
@@ -1372,23 +1486,94 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1372 schedule_work(&ev->work); 1486 schedule_work(&ev->work);
1373} 1487}
1374 1488
1489static void
1490mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1491 EVENT_DATA_RAID *raid_event_data)
1492{
1493 struct mptsas_hotplug_event *ev;
1494 RAID_VOL0_STATUS * volumeStatus;
1495
1496 if (ioc->bus_type != SAS)
1497 return;
1498
1499 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1500 if (!ev) {
1501 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1502 return;
1503 }
1504
1505 memset(ev,0,sizeof(struct mptsas_hotplug_event));
1506 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1507 ev->ioc = ioc;
1508 ev->id = raid_event_data->VolumeID;
1509
1510 switch (raid_event_data->ReasonCode) {
1511 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
1512 ev->event_type = MPTSAS_ADD_DEVICE;
1513 break;
1514 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
1515 ev->event_type = MPTSAS_DEL_DEVICE;
1516 break;
1517 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
1518 ev->event_type = MPTSAS_DEL_RAID;
1519 break;
1520 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
1521 ev->event_type = MPTSAS_ADD_RAID;
1522 break;
1523 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
1524 volumeStatus = (RAID_VOL0_STATUS *) &
1525 raid_event_data->SettingsStatus;
1526 ev->event_type = (volumeStatus->State ==
1527 MPI_RAIDVOL0_STATUS_STATE_FAILED) ?
1528 MPTSAS_DEL_RAID : MPTSAS_ADD_RAID;
1529 break;
1530 default:
1531 break;
1532 }
1533 schedule_work(&ev->work);
1534}
1535
1536/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1537/* work queue thread to clear the persitency table */
1538static void
1539mptscsih_sas_persist_clear_table(void * arg)
1540{
1541 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
1542
1543 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
1544}
1545
1375static int 1546static int
1376mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) 1547mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1377{ 1548{
1549 int rc=1;
1378 u8 event = le32_to_cpu(reply->Event) & 0xFF; 1550 u8 event = le32_to_cpu(reply->Event) & 0xFF;
1379 1551
1380 if (!ioc->sh) 1552 if (!ioc->sh)
1381 return 1; 1553 goto out;
1382 1554
1383 switch (event) { 1555 switch (event) {
1384 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 1556 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1385 mptscsih_send_sas_event(ioc, 1557 mptscsih_send_sas_event(ioc,
1386 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); 1558 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
1387 return 1; /* currently means nothing really */ 1559 break;
1388 1560 case MPI_EVENT_INTEGRATED_RAID:
1561 mptscsih_send_raid_event(ioc,
1562 (EVENT_DATA_RAID *)reply->Data);
1563 break;
1564 case MPI_EVENT_PERSISTENT_TABLE_FULL:
1565 INIT_WORK(&ioc->mptscsih_persistTask,
1566 mptscsih_sas_persist_clear_table,
1567 (void *)ioc);
1568 schedule_work(&ioc->mptscsih_persistTask);
1569 break;
1389 default: 1570 default:
1390 return mptscsih_event_process(ioc, reply); 1571 rc = mptscsih_event_process(ioc, reply);
1572 break;
1391 } 1573 }
1574 out:
1575
1576 return rc;
1392} 1577}
1393 1578
1394static int 1579static int
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index cdac5578fdf2..4fee6befc93d 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -144,7 +144,6 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
144static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); 144static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
145static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); 145static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
146 146
147static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
148static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 147static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
149 148
150int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 149int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
@@ -159,11 +158,9 @@ static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
159int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 158int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
160static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 159static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
161static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 160static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
162static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget); 161static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
163static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); 162static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
164 163
165static struct work_struct mptscsih_persistTask;
166
167#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 164#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
168static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); 165static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
169static void mptscsih_domainValidation(void *hd); 166static void mptscsih_domainValidation(void *hd);
@@ -563,11 +560,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
563 MPT_SCSI_HOST *hd; 560 MPT_SCSI_HOST *hd;
564 SCSIIORequest_t *pScsiReq; 561 SCSIIORequest_t *pScsiReq;
565 SCSIIOReply_t *pScsiReply; 562 SCSIIOReply_t *pScsiReply;
566 u16 req_idx; 563 u16 req_idx, req_idx_MR;
567 564
568 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; 565 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
569 566
570 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 567 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
568 req_idx_MR = (mr != NULL) ?
569 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
570 if ((req_idx != req_idx_MR) ||
571 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
572 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
573 ioc->name);
574 printk (MYIOC_s_ERR_FMT
575 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
576 ioc->name, req_idx, req_idx_MR, mf, mr,
577 hd->ScsiLookup[req_idx_MR]);
578 return 0;
579 }
580
571 sc = hd->ScsiLookup[req_idx]; 581 sc = hd->ScsiLookup[req_idx];
572 if (sc == NULL) { 582 if (sc == NULL) {
573 MPIHeader_t *hdr = (MPIHeader_t *)mf; 583 MPIHeader_t *hdr = (MPIHeader_t *)mf;
@@ -730,6 +740,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
730 740
731 break; 741 break;
732 742
743 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
744 sc->resid=0;
733 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 745 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
734 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ 746 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
735 if (scsi_status == MPI_SCSI_STATUS_BUSY) 747 if (scsi_status == MPI_SCSI_STATUS_BUSY)
@@ -789,7 +801,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
789 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ 801 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
790 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ 802 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
791 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ 803 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
792 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
793 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 804 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
794 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ 805 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
795 default: 806 default:
@@ -1530,7 +1541,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1530 * 1541 *
1531 * Returns 0 for SUCCESS or -1 if FAILED. 1542 * Returns 0 for SUCCESS or -1 if FAILED.
1532 */ 1543 */
1533static int 1544int
1534mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1545mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1535{ 1546{
1536 MPT_ADAPTER *ioc; 1547 MPT_ADAPTER *ioc;
@@ -1721,6 +1732,20 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
1721 return retval; 1732 return retval;
1722} 1733}
1723 1734
1735static int
1736mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1737{
1738 switch (ioc->bus_type) {
1739 case FC:
1740 return 40;
1741 case SAS:
1742 return 10;
1743 case SPI:
1744 default:
1745 return 2;
1746 }
1747}
1748
1724/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1749/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1725/** 1750/**
1726 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant 1751 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
@@ -1792,7 +1817,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1792 vdev = SCpnt->device->hostdata; 1817 vdev = SCpnt->device->hostdata;
1793 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1818 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1794 vdev->bus_id, vdev->target_id, vdev->lun, 1819 vdev->bus_id, vdev->target_id, vdev->lun,
1795 ctx2abort, 2 /* 2 second timeout */); 1820 ctx2abort, mptscsih_get_tm_timeout(ioc));
1796 1821
1797 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1822 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1798 hd->ioc->name, 1823 hd->ioc->name,
@@ -1843,7 +1868,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1843 vdev = SCpnt->device->hostdata; 1868 vdev = SCpnt->device->hostdata;
1844 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1869 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1845 vdev->bus_id, vdev->target_id, 1870 vdev->bus_id, vdev->target_id,
1846 0, 0, 5 /* 5 second timeout */); 1871 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1847 1872
1848 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", 1873 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1849 hd->ioc->name, 1874 hd->ioc->name,
@@ -1893,7 +1918,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1893 1918
1894 vdev = SCpnt->device->hostdata; 1919 vdev = SCpnt->device->hostdata;
1895 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1920 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1896 vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */); 1921 vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1897 1922
1898 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", 1923 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1899 hd->ioc->name, 1924 hd->ioc->name,
@@ -2016,6 +2041,42 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2016} 2041}
2017 2042
2018/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2043/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2044static void
2045mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2046{
2047 char *desc;
2048
2049 switch (response_code) {
2050 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2051 desc = "The task completed.";
2052 break;
2053 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2054 desc = "The IOC received an invalid frame status.";
2055 break;
2056 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2057 desc = "The task type is not supported.";
2058 break;
2059 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2060 desc = "The requested task failed.";
2061 break;
2062 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2063 desc = "The task completed successfully.";
2064 break;
2065 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2066 desc = "The LUN request is invalid.";
2067 break;
2068 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2069 desc = "The task is in the IOC queue and has not been sent to target.";
2070 break;
2071 default:
2072 desc = "unknown";
2073 break;
2074 }
2075 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2076 ioc->name, response_code, desc);
2077}
2078
2079/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2019/** 2080/**
2020 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver 2081 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2021 * @ioc: Pointer to MPT_ADAPTER structure 2082 * @ioc: Pointer to MPT_ADAPTER structure
@@ -2064,6 +2125,11 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
2064 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ 2125 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2065 tmType = pScsiTmReq->TaskType; 2126 tmType = pScsiTmReq->TaskType;
2066 2127
2128 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2129 pScsiTmReply->ResponseCode)
2130 mptscsih_taskmgmt_response_code(ioc,
2131 pScsiTmReply->ResponseCode);
2132
2067 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", 2133 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2068 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); 2134 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2069 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); 2135 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
@@ -2255,7 +2321,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
2255 vtarget->luns[0] &= ~(1 << vdevice->lun); 2321 vtarget->luns[0] &= ~(1 << vdevice->lun);
2256 vtarget->num_luns--; 2322 vtarget->num_luns--;
2257 if (vtarget->num_luns == 0) { 2323 if (vtarget->num_luns == 0) {
2258 mptscsih_negotiate_to_asyn_narrow(hd, vtarget); 2324 mptscsih_negotiate_to_asyn_narrow(hd, vdevice);
2259 if (hd->ioc->bus_type == SPI) { 2325 if (hd->ioc->bus_type == SPI) {
2260 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { 2326 if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
2261 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; 2327 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
@@ -2423,7 +2489,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
2423 int idx; 2489 int idx;
2424 MPT_ADAPTER *ioc = hd->ioc; 2490 MPT_ADAPTER *ioc = hd->ioc;
2425 2491
2426 idx = ioc->eventContext % ioc->eventLogSize; 2492 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2427 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; 2493 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2428 ioc->events[idx].eventContext = ioc->eventContext; 2494 ioc->events[idx].eventContext = ioc->eventContext;
2429 2495
@@ -2585,16 +2651,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2585} 2651}
2586 2652
2587/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2653/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2588/* work queue thread to clear the persitency table */
2589static void
2590mptscsih_sas_persist_clear_table(void * arg)
2591{
2592 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2593
2594 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2595}
2596
2597/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2598int 2654int
2599mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) 2655mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2600{ 2656{
@@ -2656,13 +2712,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2656 break; 2712 break;
2657 } 2713 }
2658 2714
2659 /* Persistent table is full. */
2660 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2661 INIT_WORK(&mptscsih_persistTask,
2662 mptscsih_sas_persist_clear_table,(void *)ioc);
2663 schedule_work(&mptscsih_persistTask);
2664 break;
2665
2666 case MPI_EVENT_NONE: /* 00 */ 2715 case MPI_EVENT_NONE: /* 00 */
2667 case MPI_EVENT_LOG_DATA: /* 01 */ 2716 case MPI_EVENT_LOG_DATA: /* 01 */
2668 case MPI_EVENT_STATE_CHANGE: /* 02 */ 2717 case MPI_EVENT_STATE_CHANGE: /* 02 */
@@ -3863,8 +3912,9 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3863 * 3912 *
3864 */ 3913 */
3865static void 3914static void
3866mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) 3915mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3867{ 3916{
3917 VirtTarget *vtarget = vdevice->vtarget;
3868 MPT_ADAPTER *ioc= hd->ioc; 3918 MPT_ADAPTER *ioc= hd->ioc;
3869 SCSIDevicePage1_t *pcfg1Data; 3919 SCSIDevicePage1_t *pcfg1Data;
3870 CONFIGPARMS cfg; 3920 CONFIGPARMS cfg;
@@ -3874,7 +3924,8 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3874 int requested, configuration, data,i; 3924 int requested, configuration, data,i;
3875 u8 flags, factor; 3925 u8 flags, factor;
3876 3926
3877 if (ioc->bus_type != SPI) 3927 if ((ioc->bus_type != SPI) ||
3928 (!vdevice->configured_lun))
3878 return; 3929 return;
3879 3930
3880 if (!ioc->spi_data.sdp1length) 3931 if (!ioc->spi_data.sdp1length)
@@ -3910,7 +3961,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3910 } 3961 }
3911 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, 3962 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3912 &configuration, flags); 3963 &configuration, flags);
3913 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " 3964 dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
3914 "offset=0 negoFlags=%x request=%x config=%x\n", 3965 "offset=0 negoFlags=%x request=%x config=%x\n",
3915 id, flags, requested, configuration)); 3966 id, flags, requested, configuration));
3916 pcfg1Data->RequestedParameters = cpu_to_le32(requested); 3967 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
@@ -3923,7 +3974,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
3923 flags = vtarget->negoFlags; 3974 flags = vtarget->negoFlags;
3924 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, 3975 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
3925 &configuration, flags); 3976 &configuration, flags);
3926 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " 3977 dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
3927 "offset=0 negoFlags=%x request=%x config=%x\n", 3978 "offset=0 negoFlags=%x request=%x config=%x\n",
3928 vtarget->target_id, flags, requested, configuration)); 3979 vtarget->target_id, flags, requested, configuration));
3929 pcfg1Data->RequestedParameters = cpu_to_le32(requested); 3980 pcfg1Data->RequestedParameters = cpu_to_le32(requested);
@@ -5620,5 +5671,6 @@ EXPORT_SYMBOL(mptscsih_event_process);
5620EXPORT_SYMBOL(mptscsih_ioc_reset); 5671EXPORT_SYMBOL(mptscsih_ioc_reset);
5621EXPORT_SYMBOL(mptscsih_change_queue_depth); 5672EXPORT_SYMBOL(mptscsih_change_queue_depth);
5622EXPORT_SYMBOL(mptscsih_timer_expired); 5673EXPORT_SYMBOL(mptscsih_timer_expired);
5674EXPORT_SYMBOL(mptscsih_TMHandler);
5623 5675
5624/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5676/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index d3cba12f4bd9..44b248d51ea3 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -108,3 +108,4 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE
108extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 108extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
109extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); 109extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
110extern void mptscsih_timer_expired(unsigned long data); 110extern void mptscsih_timer_expired(unsigned long data);
111extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 7dce29277cb7..f148dfa39117 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -384,6 +384,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
384 goto out_mptspi_probe; 384 goto out_mptspi_probe;
385 } 385 }
386 386
387 /*
388 * issue internal bus reset
389 */
390 if (ioc->spi_data.bus_reset)
391 mptscsih_TMHandler(hd,
392 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
393 0, 0, 0, 0, 5);
394
387 scsi_scan_host(sh); 395 scsi_scan_host(sh);
388 return 0; 396 return 0;
389 397
@@ -445,7 +453,7 @@ static void __exit
445mptspi_exit(void) 453mptspi_exit(void)
446{ 454{
447 pci_unregister_driver(&mptspi_driver); 455 pci_unregister_driver(&mptspi_driver);
448 456
449 mpt_reset_deregister(mptspiDoneCtx); 457 mpt_reset_deregister(mptspiDoneCtx);
450 dprintk((KERN_INFO MYNAM 458 dprintk((KERN_INFO MYNAM
451 ": Deregistered for IOC reset notifications\n")); 459 ": Deregistered for IOC reset notifications\n"));