aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/message/fusion/mptbase.c416
-rw-r--r--drivers/message/fusion/mptbase.h46
-rw-r--r--drivers/message/fusion/mptctl.c6
-rw-r--r--drivers/message/fusion/mptsas.c94
-rw-r--r--drivers/message/fusion/mptscsih.c174
-rw-r--r--drivers/message/fusion/mptscsih.h1
6 files changed, 443 insertions, 294 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index d67b26378a52..8f04d37fb359 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -207,7 +207,6 @@ static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
207#endif 207#endif
208static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); 208static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
209 209
210//int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
211static int ProcessEventNotification(MPT_ADAPTER *ioc, 210static int ProcessEventNotification(MPT_ADAPTER *ioc,
212 EventNotificationReply_t *evReply, int *evHandlers); 211 EventNotificationReply_t *evReply, int *evHandlers);
213static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 212static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
@@ -374,11 +373,11 @@ mpt_fault_reset_work(struct work_struct *work)
374 ioc = ioc->alt_ioc; 373 ioc = ioc->alt_ioc;
375 374
376 /* rearm the timer */ 375 /* rearm the timer */
377 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); 376 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
378 if (ioc->reset_work_q) 377 if (ioc->reset_work_q)
379 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 378 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
380 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 379 msecs_to_jiffies(MPT_POLLING_INTERVAL));
381 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); 380 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
382} 381}
383 382
384 383
@@ -972,11 +971,15 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
972 971
973 /* Put Request back on FreeQ! */ 972 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc->FreeQlock, flags); 973 spin_lock_irqsave(&ioc->FreeQlock, flags);
975 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */ 974 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
975 goto out;
976 /* signature to know if this mf is freed */
977 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
976 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 978 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
977#ifdef MFCNT 979#ifdef MFCNT
978 ioc->mfcnt--; 980 ioc->mfcnt--;
979#endif 981#endif
982 out:
980 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 983 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
981} 984}
982 985
@@ -1731,6 +1734,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1731 1734
1732 ioc->id = mpt_ids++; 1735 ioc->id = mpt_ids++;
1733 sprintf(ioc->name, "ioc%d", ioc->id); 1736 sprintf(ioc->name, "ioc%d", ioc->id);
1737 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1734 1738
1735 /* 1739 /*
1736 * set initial debug level 1740 * set initial debug level
@@ -1771,7 +1775,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1775 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1772 1776
1773 ioc->pcidev = pdev; 1777 ioc->pcidev = pdev;
1774 spin_lock_init(&ioc->initializing_hba_lock);
1775 1778
1776 spin_lock_init(&ioc->taskmgmt_lock); 1779 spin_lock_init(&ioc->taskmgmt_lock);
1777 mutex_init(&ioc->internal_cmds.mutex); 1780 mutex_init(&ioc->internal_cmds.mutex);
@@ -1792,6 +1795,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1792 ioc->mfcnt = 0; 1795 ioc->mfcnt = 0;
1793#endif 1796#endif
1794 1797
1798 ioc->sh = NULL;
1795 ioc->cached_fw = NULL; 1799 ioc->cached_fw = NULL;
1796 1800
1797 /* Initilize SCSI Config Data structure 1801 /* Initilize SCSI Config Data structure
@@ -1808,9 +1812,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1808 1812
1809 /* Initialize workqueue */ 1813 /* Initialize workqueue */
1810 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); 1814 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1811 spin_lock_init(&ioc->fault_reset_work_lock);
1812 1815
1813 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name), 1816 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1814 "mpt_poll_%d", ioc->id); 1817 "mpt_poll_%d", ioc->id);
1815 ioc->reset_work_q = 1818 ioc->reset_work_q =
1816 create_singlethread_workqueue(ioc->reset_work_q_name); 1819 create_singlethread_workqueue(ioc->reset_work_q_name);
@@ -1885,11 +1888,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1885 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1888 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1886 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1889 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1887 ioc->errata_flag_1064 = 1; 1890 ioc->errata_flag_1064 = 1;
1891 ioc->bus_type = SAS;
1892 break;
1888 1893
1889 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1894 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1890 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1895 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1896 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1892 ioc->bus_type = SAS; 1897 ioc->bus_type = SAS;
1898 break;
1893 } 1899 }
1894 1900
1895 1901
@@ -1933,7 +1939,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1933 1939
1934 INIT_LIST_HEAD(&ioc->fw_event_list); 1940 INIT_LIST_HEAD(&ioc->fw_event_list);
1935 spin_lock_init(&ioc->fw_event_lock); 1941 spin_lock_init(&ioc->fw_event_lock);
1936 snprintf(ioc->fw_event_q_name, 20, "mpt/%d", ioc->id); 1942 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1937 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name); 1943 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1938 1944
1939 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1945 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
@@ -2008,10 +2014,10 @@ mpt_detach(struct pci_dev *pdev)
2008 /* 2014 /*
2009 * Stop polling ioc for fault condition 2015 * Stop polling ioc for fault condition
2010 */ 2016 */
2011 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); 2017 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2012 wq = ioc->reset_work_q; 2018 wq = ioc->reset_work_q;
2013 ioc->reset_work_q = NULL; 2019 ioc->reset_work_q = NULL;
2014 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); 2020 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2015 cancel_delayed_work(&ioc->fault_reset_work); 2021 cancel_delayed_work(&ioc->fault_reset_work);
2016 destroy_workqueue(wq); 2022 destroy_workqueue(wq);
2017 2023
@@ -2234,12 +2240,16 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2234 ioc->active = 0; 2240 ioc->active = 0;
2235 2241
2236 if (ioc->alt_ioc) { 2242 if (ioc->alt_ioc) {
2237 if (ioc->alt_ioc->active) 2243 if (ioc->alt_ioc->active ||
2244 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2238 reset_alt_ioc_active = 1; 2245 reset_alt_ioc_active = 1;
2239 2246 /* Disable alt-IOC's reply interrupts
2240 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */ 2247 * (and FreeQ) for a bit
2241 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF); 2248 **/
2242 ioc->alt_ioc->active = 0; 2249 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2250 0xFFFFFFFF);
2251 ioc->alt_ioc->active = 0;
2252 }
2243 } 2253 }
2244 2254
2245 hard = 1; 2255 hard = 1;
@@ -2260,9 +2270,11 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2260 } 2270 }
2261 2271
2262 } else { 2272 } else {
2263 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name); 2273 printk(MYIOC_s_WARN_FMT
2274 "NOT READY WARNING!\n", ioc->name);
2264 } 2275 }
2265 return -1; 2276 ret = -1;
2277 goto out;
2266 } 2278 }
2267 2279
2268 /* hard_reset_done = 0 if a soft reset was performed 2280 /* hard_reset_done = 0 if a soft reset was performed
@@ -2272,7 +2284,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2272 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) 2284 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2273 alt_ioc_ready = 1; 2285 alt_ioc_ready = 1;
2274 else 2286 else
2275 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name); 2287 printk(MYIOC_s_WARN_FMT
2288 ": alt-ioc Not ready WARNING!\n",
2289 ioc->alt_ioc->name);
2276 } 2290 }
2277 2291
2278 for (ii=0; ii<5; ii++) { 2292 for (ii=0; ii<5; ii++) {
@@ -2293,7 +2307,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2293 if (alt_ioc_ready) { 2307 if (alt_ioc_ready) {
2294 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { 2308 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2295 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2309 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2296 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); 2310 "Initial Alt IocFacts failed rc=%x\n",
2311 ioc->name, rc));
2297 /* Retry - alt IOC was initialized once 2312 /* Retry - alt IOC was initialized once
2298 */ 2313 */
2299 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); 2314 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
@@ -2337,16 +2352,20 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2337 IRQF_SHARED, ioc->name, ioc); 2352 IRQF_SHARED, ioc->name, ioc);
2338 if (rc < 0) { 2353 if (rc < 0) {
2339 printk(MYIOC_s_ERR_FMT "Unable to allocate " 2354 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2340 "interrupt %d!\n", ioc->name, ioc->pcidev->irq); 2355 "interrupt %d!\n",
2356 ioc->name, ioc->pcidev->irq);
2341 if (ioc->msi_enable) 2357 if (ioc->msi_enable)
2342 pci_disable_msi(ioc->pcidev); 2358 pci_disable_msi(ioc->pcidev);
2343 return -EBUSY; 2359 ret = -EBUSY;
2360 goto out;
2344 } 2361 }
2345 irq_allocated = 1; 2362 irq_allocated = 1;
2346 ioc->pci_irq = ioc->pcidev->irq; 2363 ioc->pci_irq = ioc->pcidev->irq;
2347 pci_set_master(ioc->pcidev); /* ?? */ 2364 pci_set_master(ioc->pcidev); /* ?? */
2348 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt " 2365 pci_set_drvdata(ioc->pcidev, ioc);
2349 "%d\n", ioc->name, ioc->pcidev->irq)); 2366 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2367 "installed at interrupt %d\n", ioc->name,
2368 ioc->pcidev->irq));
2350 } 2369 }
2351 } 2370 }
2352 2371
@@ -2355,17 +2374,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2355 * init as upper addresses are needed for init. 2374 * init as upper addresses are needed for init.
2356 * If fails, continue with alt-ioc processing 2375 * If fails, continue with alt-ioc processing
2357 */ 2376 */
2377 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2378 ioc->name));
2358 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0)) 2379 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2359 ret = -3; 2380 ret = -3;
2360 2381
2361 /* May need to check/upload firmware & data here! 2382 /* May need to check/upload firmware & data here!
2362 * If fails, continue with alt-ioc processing 2383 * If fails, continue with alt-ioc processing
2363 */ 2384 */
2385 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2386 ioc->name));
2364 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0)) 2387 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2365 ret = -4; 2388 ret = -4;
2366// NEW! 2389// NEW!
2367 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) { 2390 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2368 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n", 2391 printk(MYIOC_s_WARN_FMT
2392 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2369 ioc->alt_ioc->name, rc); 2393 ioc->alt_ioc->name, rc);
2370 alt_ioc_ready = 0; 2394 alt_ioc_ready = 0;
2371 reset_alt_ioc_active = 0; 2395 reset_alt_ioc_active = 0;
@@ -2375,8 +2399,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2375 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { 2399 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2376 alt_ioc_ready = 0; 2400 alt_ioc_ready = 0;
2377 reset_alt_ioc_active = 0; 2401 reset_alt_ioc_active = 0;
2378 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n", 2402 printk(MYIOC_s_WARN_FMT
2379 ioc->alt_ioc->name, rc); 2403 ": alt-ioc: (%d) init failure WARNING!\n",
2404 ioc->alt_ioc->name, rc);
2380 } 2405 }
2381 } 2406 }
2382 2407
@@ -2457,8 +2482,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2457 mutex_init(&ioc->raid_data.inactive_list_mutex); 2482 mutex_init(&ioc->raid_data.inactive_list_mutex);
2458 INIT_LIST_HEAD(&ioc->raid_data.inactive_list); 2483 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2459 2484
2460 if (ioc->bus_type == SAS) { 2485 switch (ioc->bus_type) {
2461 2486
2487 case SAS:
2462 /* clear persistency table */ 2488 /* clear persistency table */
2463 if(ioc->facts.IOCExceptions & 2489 if(ioc->facts.IOCExceptions &
2464 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) { 2490 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
@@ -2472,8 +2498,15 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2472 */ 2498 */
2473 mpt_findImVolumes(ioc); 2499 mpt_findImVolumes(ioc);
2474 2500
2475 } else if (ioc->bus_type == FC) { 2501 /* Check, and possibly reset, the coalescing value
2476 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && 2502 */
2503 mpt_read_ioc_pg_1(ioc);
2504
2505 break;
2506
2507 case FC:
2508 if ((ioc->pfacts[0].ProtocolFlags &
2509 MPI_PORTFACTS_PROTOCOL_LAN) &&
2477 (ioc->lan_cnfg_page0.Header.PageLength == 0)) { 2510 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2478 /* 2511 /*
2479 * Pre-fetch the ports LAN MAC address! 2512 * Pre-fetch the ports LAN MAC address!
@@ -2482,11 +2515,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2482 (void) GetLanConfigPages(ioc); 2515 (void) GetLanConfigPages(ioc);
2483 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 2516 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2484 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2517 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2485 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 2518 "LanAddr = %02X:%02X:%02X"
2486 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0])); 2519 ":%02X:%02X:%02X\n",
2487 2520 ioc->name, a[5], a[4],
2521 a[3], a[2], a[1], a[0]));
2488 } 2522 }
2489 } else { 2523 break;
2524
2525 case SPI:
2490 /* Get NVRAM and adapter maximums from SPP 0 and 2 2526 /* Get NVRAM and adapter maximums from SPP 0 and 2
2491 */ 2527 */
2492 mpt_GetScsiPortSettings(ioc, 0); 2528 mpt_GetScsiPortSettings(ioc, 0);
@@ -2505,6 +2541,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2505 mpt_read_ioc_pg_1(ioc); 2541 mpt_read_ioc_pg_1(ioc);
2506 2542
2507 mpt_read_ioc_pg_4(ioc); 2543 mpt_read_ioc_pg_4(ioc);
2544
2545 break;
2508 } 2546 }
2509 2547
2510 GetIoUnitPage2(ioc); 2548 GetIoUnitPage2(ioc);
@@ -2586,16 +2624,20 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2586 if (_pcidev == peer) { 2624 if (_pcidev == peer) {
2587 /* Paranoia checks */ 2625 /* Paranoia checks */
2588 if (ioc->alt_ioc != NULL) { 2626 if (ioc->alt_ioc != NULL) {
2589 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", 2627 printk(MYIOC_s_WARN_FMT
2590 ioc->name, ioc->alt_ioc->name); 2628 "Oops, already bound (%s <==> %s)!\n",
2629 ioc->name, ioc->name, ioc->alt_ioc->name);
2591 break; 2630 break;
2592 } else if (ioc_srch->alt_ioc != NULL) { 2631 } else if (ioc_srch->alt_ioc != NULL) {
2593 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", 2632 printk(MYIOC_s_WARN_FMT
2594 ioc_srch->name, ioc_srch->alt_ioc->name); 2633 "Oops, already bound (%s <==> %s)!\n",
2634 ioc_srch->name, ioc_srch->name,
2635 ioc_srch->alt_ioc->name);
2595 break; 2636 break;
2596 } 2637 }
2597 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n", 2638 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2598 ioc->name, ioc_srch->name)); 2639 "FOUND! binding %s <==> %s\n",
2640 ioc->name, ioc->name, ioc_srch->name));
2599 ioc_srch->alt_ioc = ioc; 2641 ioc_srch->alt_ioc = ioc;
2600 ioc->alt_ioc = ioc_srch; 2642 ioc->alt_ioc = ioc_srch;
2601 } 2643 }
@@ -2615,8 +2657,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2615 int ret; 2657 int ret;
2616 2658
2617 if (ioc->cached_fw != NULL) { 2659 if (ioc->cached_fw != NULL) {
2618 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " 2660 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2619 "adapter\n", __func__, ioc->name)); 2661 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2620 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) 2662 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2621 ioc->cached_fw, CAN_SLEEP)) < 0) { 2663 ioc->cached_fw, CAN_SLEEP)) < 0) {
2622 printk(MYIOC_s_WARN_FMT 2664 printk(MYIOC_s_WARN_FMT
@@ -2626,10 +2668,13 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2626 } 2668 }
2627 2669
2628 /* Disable adapter interrupts! */ 2670 /* Disable adapter interrupts! */
2671 synchronize_irq(ioc->pcidev->irq);
2629 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2672 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2630 ioc->active = 0; 2673 ioc->active = 0;
2674
2631 /* Clear any lingering interrupt */ 2675 /* Clear any lingering interrupt */
2632 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2676 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2677 CHIPREG_READ32(&ioc->chip->IntStatus);
2633 2678
2634 if (ioc->alloc != NULL) { 2679 if (ioc->alloc != NULL) {
2635 sz = ioc->alloc_sz; 2680 sz = ioc->alloc_sz;
@@ -2689,19 +2734,22 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2689 if((ret = mpt_host_page_access_control(ioc, 2734 if((ret = mpt_host_page_access_control(ioc,
2690 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) { 2735 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2691 printk(MYIOC_s_ERR_FMT 2736 printk(MYIOC_s_ERR_FMT
2692 "host page buffers free failed (%d)!\n", 2737 ": %s: host page buffers free failed (%d)!\n",
2693 ioc->name, ret); 2738 ioc->name, __func__, ret);
2694 } 2739 }
2695 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n", 2740 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2696 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz)); 2741 "HostPageBuffer free @ %p, sz=%d bytes\n",
2742 ioc->name, ioc->HostPageBuffer,
2743 ioc->HostPageBuffer_sz));
2697 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, 2744 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2698 ioc->HostPageBuffer, ioc->HostPageBuffer_dma); 2745 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2699 ioc->HostPageBuffer = NULL; 2746 ioc->HostPageBuffer = NULL;
2700 ioc->HostPageBuffer_sz = 0; 2747 ioc->HostPageBuffer_sz = 0;
2701 ioc->alloc_total -= ioc->HostPageBuffer_sz; 2748 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2702 } 2749 }
2703}
2704 2750
2751 pci_set_drvdata(ioc->pcidev, NULL);
2752}
2705/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2753/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2706/** 2754/**
2707 * mpt_adapter_dispose - Free all resources associated with an MPT adapter 2755 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
@@ -2841,8 +2889,12 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2841 } 2889 }
2842 2890
2843 /* Is it already READY? */ 2891 /* Is it already READY? */
2844 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 2892 if (!statefault &&
2893 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2894 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2895 "IOC is in READY state\n", ioc->name));
2845 return 0; 2896 return 0;
2897 }
2846 2898
2847 /* 2899 /*
2848 * Check to see if IOC is in FAULT state. 2900 * Check to see if IOC is in FAULT state.
@@ -2915,8 +2967,9 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2915 2967
2916 ii++; cntdn--; 2968 ii++; cntdn--;
2917 if (!cntdn) { 2969 if (!cntdn) {
2918 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", 2970 printk(MYIOC_s_ERR_FMT
2919 ioc->name, (int)((ii+5)/HZ)); 2971 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2972 ioc->name, ioc_state, (int)((ii+5)/HZ));
2920 return -ETIME; 2973 return -ETIME;
2921 } 2974 }
2922 2975
@@ -2929,9 +2982,8 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2929 } 2982 }
2930 2983
2931 if (statefault < 3) { 2984 if (statefault < 3) {
2932 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", 2985 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2933 ioc->name, 2986 statefault == 1 ? "stuck handshake" : "IOC FAULT");
2934 statefault==1 ? "stuck handshake" : "IOC FAULT");
2935 } 2987 }
2936 2988
2937 return hard_reset_done; 2989 return hard_reset_done;
@@ -2984,8 +3036,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2984 3036
2985 /* IOC *must* NOT be in RESET state! */ 3037 /* IOC *must* NOT be in RESET state! */
2986 if (ioc->last_state == MPI_IOC_STATE_RESET) { 3038 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2987 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n", 3039 printk(KERN_ERR MYNAM
2988 ioc->name, ioc->last_state ); 3040 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3041 ioc->name, ioc->last_state);
2989 return -44; 3042 return -44;
2990 } 3043 }
2991 3044
@@ -3047,7 +3100,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3047 * Old: u16{Major(4),Minor(4),SubMinor(8)} 3100 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3048 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)} 3101 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3049 */ 3102 */
3050 if (facts->MsgVersion < 0x0102) { 3103 if (facts->MsgVersion < MPI_VERSION_01_02) {
3051 /* 3104 /*
3052 * Handle old FC f/w style, convert to new... 3105 * Handle old FC f/w style, convert to new...
3053 */ 3106 */
@@ -3059,9 +3112,11 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3059 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 3112 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3060 3113
3061 facts->ProductID = le16_to_cpu(facts->ProductID); 3114 facts->ProductID = le16_to_cpu(facts->ProductID);
3115
3062 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 3116 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3063 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) 3117 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3064 ioc->ir_firmware = 1; 3118 ioc->ir_firmware = 1;
3119
3065 facts->CurrentHostMfaHighAddr = 3120 facts->CurrentHostMfaHighAddr =
3066 le32_to_cpu(facts->CurrentHostMfaHighAddr); 3121 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3067 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 3122 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
@@ -3077,7 +3132,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3077 * to 14 in MPI-1.01.0x. 3132 * to 14 in MPI-1.01.0x.
3078 */ 3133 */
3079 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 && 3134 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3080 facts->MsgVersion > 0x0100) { 3135 facts->MsgVersion > MPI_VERSION_01_00) {
3081 facts->FWImageSize = le32_to_cpu(facts->FWImageSize); 3136 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3082 } 3137 }
3083 3138
@@ -3259,6 +3314,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3259 3314
3260 ioc_init.MaxDevices = (U8)ioc->devices_per_bus; 3315 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3261 ioc_init.MaxBuses = (U8)ioc->number_of_buses; 3316 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3317
3262 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n", 3318 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3263 ioc->name, ioc->facts.MsgVersion)); 3319 ioc->name, ioc->facts.MsgVersion));
3264 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { 3320 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
@@ -3273,7 +3329,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3273 } 3329 }
3274 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ 3330 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3275 3331
3276 if (sizeof(dma_addr_t) == sizeof(u64)) { 3332 if (ioc->sg_addr_size == sizeof(u64)) {
3277 /* Save the upper 32-bits of the request 3333 /* Save the upper 32-bits of the request
3278 * (reply) and sense buffers. 3334 * (reply) and sense buffers.
3279 */ 3335 */
@@ -3526,29 +3582,29 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3526 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest, 3582 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3527 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag); 3583 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3528 3584
3529 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii)); 3585 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3586 "rc=%x \n", ioc->name, ii));
3530 3587
3531 cmdStatus = -EFAULT; 3588 cmdStatus = -EFAULT;
3532 if (ii == 0) { 3589 if (ii == 0) {
3533 /* Handshake transfer was complete and successful. 3590 /* Handshake transfer was complete and successful.
3534 * Check the Reply Frame. 3591 * Check the Reply Frame.
3535 */ 3592 */
3536 int status, transfer_sz; 3593 int status;
3537 status = le16_to_cpu(preply->IOCStatus); 3594 status = le16_to_cpu(preply->IOCStatus) &
3538 if (status == MPI_IOCSTATUS_SUCCESS) { 3595 MPI_IOCSTATUS_MASK;
3539 transfer_sz = le32_to_cpu(preply->ActualImageSize); 3596 if (status == MPI_IOCSTATUS_SUCCESS &&
3540 if (transfer_sz == sz) 3597 ioc->facts.FWImageSize ==
3598 le32_to_cpu(preply->ActualImageSize))
3541 cmdStatus = 0; 3599 cmdStatus = 0;
3542 }
3543 } 3600 }
3544 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n", 3601 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3545 ioc->name, cmdStatus)); 3602 ioc->name, cmdStatus));
3546 3603
3547 3604
3548 if (cmdStatus) { 3605 if (cmdStatus) {
3549 3606 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3550 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n", 3607 "freeing image \n", ioc->name));
3551 ioc->name));
3552 mpt_free_fw_memory(ioc); 3608 mpt_free_fw_memory(ioc);
3553 } 3609 }
3554 kfree(prequest); 3610 kfree(prequest);
@@ -3872,6 +3928,10 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3872 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3928 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3873 3929
3874 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3930 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3931
3932 if (!ignore)
3933 return 0;
3934
3875 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3935 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3876 "address=%p\n", ioc->name, __func__, 3936 "address=%p\n", ioc->name, __func__,
3877 &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); 3937 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
@@ -3889,6 +3949,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3889 "looking for READY STATE: doorbell=%x" 3949 "looking for READY STATE: doorbell=%x"
3890 " count=%d\n", 3950 " count=%d\n",
3891 ioc->name, doorbell, count)); 3951 ioc->name, doorbell, count));
3952
3892 if (doorbell == MPI_IOC_STATE_READY) { 3953 if (doorbell == MPI_IOC_STATE_READY) {
3893 return 1; 3954 return 1;
3894 } 3955 }
@@ -4039,6 +4100,10 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
4039 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 4100 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4040 doorbell &= MPI_IOC_STATE_MASK; 4101 doorbell &= MPI_IOC_STATE_MASK;
4041 4102
4103 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4104 "looking for READY STATE: doorbell=%x"
4105 " count=%d\n", ioc->name, doorbell, count));
4106
4042 if (doorbell == MPI_IOC_STATE_READY) { 4107 if (doorbell == MPI_IOC_STATE_READY) {
4043 break; 4108 break;
4044 } 4109 }
@@ -4050,6 +4115,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
4050 mdelay (1000); 4115 mdelay (1000);
4051 } 4116 }
4052 } 4117 }
4118
4119 if (doorbell != MPI_IOC_STATE_READY)
4120 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4121 "after reset! IocState=%x", ioc->name,
4122 doorbell);
4053 } 4123 }
4054 } 4124 }
4055 4125
@@ -4168,8 +4238,9 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4168 if (sleepFlag != CAN_SLEEP) 4238 if (sleepFlag != CAN_SLEEP)
4169 count *= 10; 4239 count *= 10;
4170 4240
4171 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", 4241 printk(MYIOC_s_ERR_FMT
4172 ioc->name, (int)((count+5)/HZ)); 4242 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4243 ioc->name, state, (int)((count+5)/HZ));
4173 return -ETIME; 4244 return -ETIME;
4174 } 4245 }
4175 4246
@@ -4255,8 +4326,13 @@ initChainBuffers(MPT_ADAPTER *ioc)
4255 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n", 4326 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4256 ioc->name, num_sge, numSGE)); 4327 ioc->name, num_sge, numSGE));
4257 4328
4258 if ( numSGE > MPT_SCSI_SG_DEPTH ) 4329 if (ioc->bus_type == FC) {
4259 numSGE = MPT_SCSI_SG_DEPTH; 4330 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4331 numSGE = MPT_SCSI_FC_SG_DEPTH;
4332 } else {
4333 if (numSGE > MPT_SCSI_SG_DEPTH)
4334 numSGE = MPT_SCSI_SG_DEPTH;
4335 }
4260 4336
4261 num_chain = 1; 4337 num_chain = 1;
4262 while (numSGE - num_sge > 0) { 4338 while (numSGE - num_sge > 0) {
@@ -4493,6 +4569,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
4493 return 0; 4569 return 0;
4494 4570
4495out_fail: 4571out_fail:
4572
4496 if (ioc->alloc != NULL) { 4573 if (ioc->alloc != NULL) {
4497 sz = ioc->alloc_sz; 4574 sz = ioc->alloc_sz;
4498 pci_free_consistent(ioc->pcidev, 4575 pci_free_consistent(ioc->pcidev,
@@ -5610,17 +5687,20 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5610 * -ENOMEM if pci_alloc failed 5687 * -ENOMEM if pci_alloc failed
5611 **/ 5688 **/
5612int 5689int
5613mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk) 5690mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5691 RaidPhysDiskPage0_t *phys_disk)
5614{ 5692{
5615 CONFIGPARMS cfg; 5693 CONFIGPARMS cfg;
5616 ConfigPageHeader_t hdr; 5694 ConfigPageHeader_t hdr;
5617 dma_addr_t dma_handle; 5695 dma_addr_t dma_handle;
5618 pRaidPhysDiskPage0_t buffer = NULL; 5696 pRaidPhysDiskPage0_t buffer = NULL;
5619 int rc; 5697 int rc;
5620 5698
5621 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5699 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5622 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5700 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5701 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5623 5702
5703 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5624 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5704 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5625 cfg.cfghdr.hdr = &hdr; 5705 cfg.cfghdr.hdr = &hdr;
5626 cfg.physAddr = -1; 5706 cfg.physAddr = -1;
@@ -6074,7 +6154,8 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6074 int ret; 6154 int ret;
6075 u8 page_type = 0, extend_page; 6155 u8 page_type = 0, extend_page;
6076 unsigned long timeleft; 6156 unsigned long timeleft;
6077 int in_isr; 6157 unsigned long flags;
6158 int in_isr;
6078 u8 issue_hard_reset = 0; 6159 u8 issue_hard_reset = 0;
6079 u8 retry_count = 0; 6160 u8 retry_count = 0;
6080 6161
@@ -6086,7 +6167,17 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6086 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", 6167 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6087 ioc->name)); 6168 ioc->name));
6088 return -EPERM; 6169 return -EPERM;
6170 }
6171
6172 /* don't send a config page during diag reset */
6173 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6174 if (ioc->ioc_reset_in_progress) {
6175 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6176 "%s: busy with host reset\n", ioc->name, __func__));
6177 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6178 return -EBUSY;
6089 } 6179 }
6180 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6090 6181
6091 /* don't send if no chance of success */ 6182 /* don't send if no chance of success */
6092 if (!ioc->active || 6183 if (!ioc->active ||
@@ -6270,6 +6361,12 @@ mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6270 MPT_MGMT_STATUS_DID_IOCRESET; 6361 MPT_MGMT_STATUS_DID_IOCRESET;
6271 complete(&ioc->mptbase_cmds.done); 6362 complete(&ioc->mptbase_cmds.done);
6272 } 6363 }
6364/* wake up taskmgmt_cmds */
6365 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6366 ioc->taskmgmt_cmds.status |=
6367 MPT_MGMT_STATUS_DID_IOCRESET;
6368 complete(&ioc->taskmgmt_cmds.done);
6369 }
6273 break; 6370 break;
6274 default: 6371 default:
6275 break; 6372 break;
@@ -6690,7 +6787,9 @@ int
6690mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) 6787mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6691{ 6788{
6692 int rc; 6789 int rc;
6790 u8 cb_idx;
6693 unsigned long flags; 6791 unsigned long flags;
6792 unsigned long time_count;
6694 6793
6695 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name)); 6794 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6696#ifdef MFCNT 6795#ifdef MFCNT
@@ -6721,30 +6820,24 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6721 * Prevents timeouts occurring during a diagnostic reset...very bad. 6820 * Prevents timeouts occurring during a diagnostic reset...very bad.
6722 * For all other protocol drivers, this is a no-op. 6821 * For all other protocol drivers, this is a no-op.
6723 */ 6822 */
6724 { 6823 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6725 u8 cb_idx; 6824 if (MptResetHandlers[cb_idx]) {
6726 int r = 0; 6825 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6727 6826 if (ioc->alt_ioc)
6728 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6827 mpt_signal_reset(cb_idx, ioc->alt_ioc,
6729 if (MptResetHandlers[cb_idx]) { 6828 MPT_IOC_SETUP_RESET);
6730 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6731 ioc->name, cb_idx));
6732 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6733 if (ioc->alt_ioc) {
6734 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6735 ioc->name, ioc->alt_ioc->name, cb_idx));
6736 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6737 }
6738 }
6739 } 6829 }
6740 } 6830 }
6741 6831
6742 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) { 6832 time_count = jiffies;
6743 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc); 6833 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
6834 if (rc != 0) {
6835 printk(KERN_WARNING MYNAM
6836 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
6837 } else {
6838 if (ioc->hard_resets < -1)
6839 ioc->hard_resets++;
6744 } 6840 }
6745 ioc->reload_fw = 0;
6746 if (ioc->alt_ioc)
6747 ioc->alt_ioc->reload_fw = 0;
6748 6841
6749 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6842 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6750 ioc->ioc_reset_in_progress = 0; 6843 ioc->ioc_reset_in_progress = 0;
@@ -6757,16 +6850,27 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6757 } 6850 }
6758 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6851 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6759 6852
6760 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); 6853 dtmprintk(ioc,
6854 printk(MYIOC_s_DEBUG_FMT
6855 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
6856 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
6857 "SUCCESS" : "FAILED")));
6761 6858
6762 return rc; 6859 return rc;
6763} 6860}
6764 6861
6765/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6862#ifdef CONFIG_FUSION_LOGGING
6766static void 6863static void
6767EventDescriptionStr(u8 event, u32 evData0, char *evStr) 6864mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
6768{ 6865{
6769 char *ds = NULL; 6866 char *ds = NULL;
6867 u32 evData0;
6868 int ii;
6869 u8 event;
6870 char *evStr = ioc->evStr;
6871
6872 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6873 evData0 = le32_to_cpu(pEventReply->Data[0]);
6770 6874
6771 switch(event) { 6875 switch(event) {
6772 case MPI_EVENT_NONE: 6876 case MPI_EVENT_NONE:
@@ -6800,9 +6904,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6800 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) 6904 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6801 ds = "Loop State(LIP) Change"; 6905 ds = "Loop State(LIP) Change";
6802 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) 6906 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6803 ds = "Loop State(LPE) Change"; /* ??? */ 6907 ds = "Loop State(LPE) Change";
6804 else 6908 else
6805 ds = "Loop State(LPB) Change"; /* ??? */ 6909 ds = "Loop State(LPB) Change";
6806 break; 6910 break;
6807 case MPI_EVENT_LOGOUT: 6911 case MPI_EVENT_LOGOUT:
6808 ds = "Logout"; 6912 ds = "Logout";
@@ -7002,28 +7106,53 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
7002 } 7106 }
7003 case MPI_EVENT_IR2: 7107 case MPI_EVENT_IR2:
7004 { 7108 {
7109 u8 id = (u8)(evData0);
7110 u8 channel = (u8)(evData0 >> 8);
7111 u8 phys_num = (u8)(evData0 >> 24);
7005 u8 ReasonCode = (u8)(evData0 >> 16); 7112 u8 ReasonCode = (u8)(evData0 >> 16);
7113
7006 switch (ReasonCode) { 7114 switch (ReasonCode) {
7007 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED: 7115 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7008 ds = "IR2: LD State Changed"; 7116 snprintf(evStr, EVENT_DESCR_STR_SZ,
7117 "IR2: LD State Changed: "
7118 "id=%d channel=%d phys_num=%d",
7119 id, channel, phys_num);
7009 break; 7120 break;
7010 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED: 7121 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7011 ds = "IR2: PD State Changed"; 7122 snprintf(evStr, EVENT_DESCR_STR_SZ,
7123 "IR2: PD State Changed "
7124 "id=%d channel=%d phys_num=%d",
7125 id, channel, phys_num);
7012 break; 7126 break;
7013 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL: 7127 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7014 ds = "IR2: Bad Block Table Full"; 7128 snprintf(evStr, EVENT_DESCR_STR_SZ,
7129 "IR2: Bad Block Table Full: "
7130 "id=%d channel=%d phys_num=%d",
7131 id, channel, phys_num);
7015 break; 7132 break;
7016 case MPI_EVENT_IR2_RC_PD_INSERTED: 7133 case MPI_EVENT_IR2_RC_PD_INSERTED:
7017 ds = "IR2: PD Inserted"; 7134 snprintf(evStr, EVENT_DESCR_STR_SZ,
7135 "IR2: PD Inserted: "
7136 "id=%d channel=%d phys_num=%d",
7137 id, channel, phys_num);
7018 break; 7138 break;
7019 case MPI_EVENT_IR2_RC_PD_REMOVED: 7139 case MPI_EVENT_IR2_RC_PD_REMOVED:
7020 ds = "IR2: PD Removed"; 7140 snprintf(evStr, EVENT_DESCR_STR_SZ,
7141 "IR2: PD Removed: "
7142 "id=%d channel=%d phys_num=%d",
7143 id, channel, phys_num);
7021 break; 7144 break;
7022 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: 7145 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7023 ds = "IR2: Foreign CFG Detected"; 7146 snprintf(evStr, EVENT_DESCR_STR_SZ,
7147 "IR2: Foreign CFG Detected: "
7148 "id=%d channel=%d phys_num=%d",
7149 id, channel, phys_num);
7024 break; 7150 break;
7025 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR: 7151 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7026 ds = "IR2: Rebuild Medium Error"; 7152 snprintf(evStr, EVENT_DESCR_STR_SZ,
7153 "IR2: Rebuild Medium Error: "
7154 "id=%d channel=%d phys_num=%d",
7155 id, channel, phys_num);
7027 break; 7156 break;
7028 default: 7157 default:
7029 ds = "IR2"; 7158 ds = "IR2";
@@ -7059,13 +7188,18 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
7059 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 7188 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7060 { 7189 {
7061 u8 reason = (u8)(evData0); 7190 u8 reason = (u8)(evData0);
7062 u8 port_num = (u8)(evData0 >> 8);
7063 u16 handle = le16_to_cpu(evData0 >> 16);
7064 7191
7065 snprintf(evStr, EVENT_DESCR_STR_SZ, 7192 switch (reason) {
7066 "SAS Initiator Device Status Change: reason=0x%02x " 7193 case MPI_EVENT_SAS_INIT_RC_ADDED:
7067 "port=%d handle=0x%04x", 7194 ds = "SAS Initiator Status Change: Added";
7068 reason, port_num, handle); 7195 break;
7196 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7197 ds = "SAS Initiator Status Change: Deleted";
7198 break;
7199 default:
7200 ds = "SAS Initiator Status Change";
7201 break;
7202 }
7069 break; 7203 break;
7070 } 7204 }
7071 7205
@@ -7113,6 +7247,24 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
7113 break; 7247 break;
7114 } 7248 }
7115 7249
7250 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7251 {
7252 u8 reason = (u8)(evData0);
7253
7254 switch (reason) {
7255 case MPI_EVENT_SAS_EXP_RC_ADDED:
7256 ds = "Expander Status Change: Added";
7257 break;
7258 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7259 ds = "Expander Status Change: Deleted";
7260 break;
7261 default:
7262 ds = "Expander Status Change";
7263 break;
7264 }
7265 break;
7266 }
7267
7116 /* 7268 /*
7117 * MPT base "custom" events may be added here... 7269 * MPT base "custom" events may be added here...
7118 */ 7270 */
@@ -7122,8 +7274,20 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
7122 } 7274 }
7123 if (ds) 7275 if (ds)
7124 strncpy(evStr, ds, EVENT_DESCR_STR_SZ); 7276 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7125}
7126 7277
7278
7279 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7280 "MPT event:(%02Xh) : %s\n",
7281 ioc->name, event, evStr));
7282
7283 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7284 ": Event data:\n"));
7285 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7286 devtverboseprintk(ioc, printk(" %08x",
7287 le32_to_cpu(pEventReply->Data[ii])));
7288 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7289}
7290#endif
7127/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7291/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7128/** 7292/**
7129 * ProcessEventNotification - Route EventNotificationReply to all event handlers 7293 * ProcessEventNotification - Route EventNotificationReply to all event handlers
@@ -7140,37 +7304,24 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
7140{ 7304{
7141 u16 evDataLen; 7305 u16 evDataLen;
7142 u32 evData0 = 0; 7306 u32 evData0 = 0;
7143// u32 evCtx;
7144 int ii; 7307 int ii;
7145 u8 cb_idx; 7308 u8 cb_idx;
7146 int r = 0; 7309 int r = 0;
7147 int handlers = 0; 7310 int handlers = 0;
7148 char evStr[EVENT_DESCR_STR_SZ];
7149 u8 event; 7311 u8 event;
7150 7312
7151 /* 7313 /*
7152 * Do platform normalization of values 7314 * Do platform normalization of values
7153 */ 7315 */
7154 event = le32_to_cpu(pEventReply->Event) & 0xFF; 7316 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7155// evCtx = le32_to_cpu(pEventReply->EventContext);
7156 evDataLen = le16_to_cpu(pEventReply->EventDataLength); 7317 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7157 if (evDataLen) { 7318 if (evDataLen) {
7158 evData0 = le32_to_cpu(pEventReply->Data[0]); 7319 evData0 = le32_to_cpu(pEventReply->Data[0]);
7159 } 7320 }
7160 7321
7161 EventDescriptionStr(event, evData0, evStr);
7162 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
7163 ioc->name,
7164 event,
7165 evStr));
7166
7167#ifdef CONFIG_FUSION_LOGGING 7322#ifdef CONFIG_FUSION_LOGGING
7168 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7323 if (evDataLen)
7169 ": Event data:\n", ioc->name)); 7324 mpt_display_event_info(ioc, pEventReply);
7170 for (ii = 0; ii < evDataLen; ii++)
7171 devtverboseprintk(ioc, printk(" %08x",
7172 le32_to_cpu(pEventReply->Data[ii])));
7173 devtverboseprintk(ioc, printk("\n"));
7174#endif 7325#endif
7175 7326
7176 /* 7327 /*
@@ -7225,8 +7376,9 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
7225 */ 7376 */
7226 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7377 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7227 if (MptEvHandlers[cb_idx]) { 7378 if (MptEvHandlers[cb_idx]) {
7228 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n", 7379 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7229 ioc->name, cb_idx)); 7380 "Routing Event to event handler #%d\n",
7381 ioc->name, cb_idx));
7230 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply); 7382 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7231 handlers++; 7383 handlers++;
7232 } 7384 }
@@ -7310,8 +7462,6 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7310 switch (info) { 7462 switch (info) {
7311 case 0x00010000: 7463 case 0x00010000:
7312 desc = "bug! MID not found"; 7464 desc = "bug! MID not found";
7313 if (ioc->reload_fw == 0)
7314 ioc->reload_fw++;
7315 break; 7465 break;
7316 7466
7317 case 0x00020000: 7467 case 0x00020000:
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 11fc8f3960a6..91499d1275c4 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,7 +76,7 @@
76#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.04.09" 79#define MPT_LINUX_VERSION_COMMON "3.04.10"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.09" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.09"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
@@ -104,6 +104,7 @@
104#endif 104#endif
105 105
106#define MPT_NAME_LENGTH 32 106#define MPT_NAME_LENGTH 32
107#define MPT_KOBJ_NAME_LEN 20
107 108
108#define MPT_PROCFS_MPTBASEDIR "mpt" 109#define MPT_PROCFS_MPTBASEDIR "mpt"
109 /* chg it to "driver/fusion" ? */ 110 /* chg it to "driver/fusion" ? */
@@ -162,10 +163,10 @@
162/* 163/*
163 * Set the MAX_SGE value based on user input. 164 * Set the MAX_SGE value based on user input.
164 */ 165 */
165#ifdef CONFIG_FUSION_MAX_SGE 166#ifdef CONFIG_FUSION_MAX_SGE
166#if CONFIG_FUSION_MAX_SGE < 16 167#if CONFIG_FUSION_MAX_SGE < 16
167#define MPT_SCSI_SG_DEPTH 16 168#define MPT_SCSI_SG_DEPTH 16
168#elif CONFIG_FUSION_MAX_SGE > 128 169#elif CONFIG_FUSION_MAX_SGE > 128
169#define MPT_SCSI_SG_DEPTH 128 170#define MPT_SCSI_SG_DEPTH 128
170#else 171#else
171#define MPT_SCSI_SG_DEPTH CONFIG_FUSION_MAX_SGE 172#define MPT_SCSI_SG_DEPTH CONFIG_FUSION_MAX_SGE
@@ -174,6 +175,18 @@
174#define MPT_SCSI_SG_DEPTH 40 175#define MPT_SCSI_SG_DEPTH 40
175#endif 176#endif
176 177
178#ifdef CONFIG_FUSION_MAX_FC_SGE
179#if CONFIG_FUSION_MAX_FC_SGE < 16
180#define MPT_SCSI_FC_SG_DEPTH 16
181#elif CONFIG_FUSION_MAX_FC_SGE > 256
182#define MPT_SCSI_FC_SG_DEPTH 256
183#else
184#define MPT_SCSI_FC_SG_DEPTH CONFIG_FUSION_MAX_FC_SGE
185#endif
186#else
187#define MPT_SCSI_FC_SG_DEPTH 40
188#endif
189
177/* debug print string length used for events and iocstatus */ 190/* debug print string length used for events and iocstatus */
178# define EVENT_DESCR_STR_SZ 100 191# define EVENT_DESCR_STR_SZ 100
179 192
@@ -576,6 +589,10 @@ typedef struct _MPT_ADAPTER
576 int pci_irq; /* This irq */ 589 int pci_irq; /* This irq */
577 char name[MPT_NAME_LENGTH]; /* "iocN" */ 590 char name[MPT_NAME_LENGTH]; /* "iocN" */
578 char prod_name[MPT_NAME_LENGTH]; /* "LSIFC9x9" */ 591 char prod_name[MPT_NAME_LENGTH]; /* "LSIFC9x9" */
592#ifdef CONFIG_FUSION_LOGGING
593 /* used in mpt_display_event_info */
594 char evStr[EVENT_DESCR_STR_SZ];
595#endif
579 char board_name[16]; 596 char board_name[16];
580 char board_assembly[16]; 597 char board_assembly[16];
581 char board_tracer[16]; 598 char board_tracer[16];
@@ -682,14 +699,11 @@ typedef struct _MPT_ADAPTER
682 int aen_event_read_flag; /* flag to indicate event log was read*/ 699 int aen_event_read_flag; /* flag to indicate event log was read*/
683 u8 FirstWhoInit; 700 u8 FirstWhoInit;
684 u8 upload_fw; /* If set, do a fw upload */ 701 u8 upload_fw; /* If set, do a fw upload */
685 u8 reload_fw; /* Force a FW Reload on next reset */
686 u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */ 702 u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
687 u8 pad1[4]; 703 u8 pad1[4];
688 u8 DoneCtx; 704 u8 DoneCtx;
689 u8 TaskCtx; 705 u8 TaskCtx;
690 u8 InternalCtx; 706 u8 InternalCtx;
691 spinlock_t initializing_hba_lock;
692 int initializing_hba_lock_flag;
693 struct list_head list; 707 struct list_head list;
694 struct net_device *netdev; 708 struct net_device *netdev;
695 struct list_head sas_topology; 709 struct list_head sas_topology;
@@ -699,7 +713,7 @@ typedef struct _MPT_ADAPTER
699 struct list_head fw_event_list; 713 struct list_head fw_event_list;
700 spinlock_t fw_event_lock; 714 spinlock_t fw_event_lock;
701 u8 fw_events_off; /* if '1', then ignore events */ 715 u8 fw_events_off; /* if '1', then ignore events */
702 char fw_event_q_name[20]; 716 char fw_event_q_name[MPT_KOBJ_NAME_LEN];
703 717
704 struct mutex sas_discovery_mutex; 718 struct mutex sas_discovery_mutex;
705 u8 sas_discovery_runtime; 719 u8 sas_discovery_runtime;
@@ -731,15 +745,22 @@ typedef struct _MPT_ADAPTER
731 u8 fc_link_speed[2]; 745 u8 fc_link_speed[2];
732 spinlock_t fc_rescan_work_lock; 746 spinlock_t fc_rescan_work_lock;
733 struct work_struct fc_rescan_work; 747 struct work_struct fc_rescan_work;
734 char fc_rescan_work_q_name[20]; 748 char fc_rescan_work_q_name[MPT_KOBJ_NAME_LEN];
735 struct workqueue_struct *fc_rescan_work_q; 749 struct workqueue_struct *fc_rescan_work_q;
750
751 /* driver forced bus resets count */
752 unsigned long hard_resets;
753 /* fw/external bus resets count */
754 unsigned long soft_resets;
755 /* cmd timeouts */
756 unsigned long timeouts;
757
736 struct scsi_cmnd **ScsiLookup; 758 struct scsi_cmnd **ScsiLookup;
737 spinlock_t scsi_lookup_lock; 759 spinlock_t scsi_lookup_lock;
738 u64 dma_mask; 760 u64 dma_mask;
739 char reset_work_q_name[20]; 761 char reset_work_q_name[MPT_KOBJ_NAME_LEN];
740 struct workqueue_struct *reset_work_q; 762 struct workqueue_struct *reset_work_q;
741 struct delayed_work fault_reset_work; 763 struct delayed_work fault_reset_work;
742 spinlock_t fault_reset_work_lock;
743 764
744 u8 sg_addr_size; 765 u8 sg_addr_size;
745 u8 in_rescan; 766 u8 in_rescan;
@@ -870,9 +891,6 @@ typedef struct _MPT_SCSI_HOST {
870 MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */ 891 MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
871 struct scsi_cmnd *abortSCpnt; 892 struct scsi_cmnd *abortSCpnt;
872 MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */ 893 MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
873 unsigned long hard_resets; /* driver forced bus resets count */
874 unsigned long soft_resets; /* fw/external bus resets count */
875 unsigned long timeouts; /* cmd timeouts */
876 ushort sel_timeout[MPT_MAX_FC_DEVICES]; 894 ushort sel_timeout[MPT_MAX_FC_DEVICES];
877 char *info_kbuf; 895 char *info_kbuf;
878 long last_queue_full; 896 long last_queue_full;
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index ab620132d9a9..9b2e2198aee9 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -2534,9 +2534,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2534 MPT_SCSI_HOST *hd = shost_priv(ioc->sh); 2534 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
2535 2535
2536 if (hd && (cim_rev == 1)) { 2536 if (hd && (cim_rev == 1)) {
2537 karg.hard_resets = hd->hard_resets; 2537 karg.hard_resets = ioc->hard_resets;
2538 karg.soft_resets = hd->soft_resets; 2538 karg.soft_resets = ioc->soft_resets;
2539 karg.timeouts = hd->timeouts; 2539 karg.timeouts = ioc->timeouts;
2540 } 2540 }
2541 } 2541 }
2542 2542
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 6aa91268afe9..da22141152d7 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -724,8 +724,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
724 * Forming a port 724 * Forming a port
725 */ 725 */
726 if (!port_details) { 726 if (!port_details) {
727 port_details = kzalloc(sizeof(*port_details), 727 port_details = kzalloc(sizeof(struct
728 GFP_KERNEL); 728 mptsas_portinfo_details), GFP_KERNEL);
729 if (!port_details) 729 if (!port_details)
730 goto out; 730 goto out;
731 port_details->num_phys = 1; 731 port_details->num_phys = 1;
@@ -952,7 +952,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc,
952 952
953 vtarget->deleted = 1; /* block IO */ 953 vtarget->deleted = 1; /* block IO */
954 954
955 target_reset_list = kzalloc(sizeof(*target_reset_list), 955 target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
956 GFP_ATOMIC); 956 GFP_ATOMIC);
957 if (!target_reset_list) { 957 if (!target_reset_list) {
958 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT 958 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
@@ -1791,8 +1791,13 @@ static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1791 memcpy(ioc->sas_mgmt.reply, reply, 1791 memcpy(ioc->sas_mgmt.reply, reply,
1792 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength)); 1792 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1793 } 1793 }
1794 complete(&ioc->sas_mgmt.done); 1794
1795 return 1; 1795 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1796 ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
1797 complete(&ioc->sas_mgmt.done);
1798 return 1;
1799 }
1800 return 0;
1796} 1801}
1797 1802
1798static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) 1803static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
@@ -1831,6 +1836,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1831 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET; 1836 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1832 req->PhyNum = phy->identify.phy_identifier; 1837 req->PhyNum = phy->identify.phy_identifier;
1833 1838
1839 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
1834 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); 1840 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1835 1841
1836 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 1842 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
@@ -1862,6 +1868,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1862 error = 0; 1868 error = 0;
1863 1869
1864 out_unlock: 1870 out_unlock:
1871 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
1865 mutex_unlock(&ioc->sas_mgmt.mutex); 1872 mutex_unlock(&ioc->sas_mgmt.mutex);
1866 out: 1873 out:
1867 return error; 1874 return error;
@@ -1999,10 +2006,15 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1999 if (!dma_addr_out) 2006 if (!dma_addr_out)
2000 goto put_mf; 2007 goto put_mf;
2001 ioc->add_sge(psge, flagsLength, dma_addr_out); 2008 ioc->add_sge(psge, flagsLength, dma_addr_out);
2002 psge += (sizeof(u32) + sizeof(dma_addr_t)); 2009 psge += ioc->SGE_size;
2003 2010
2004 /* response */ 2011 /* response */
2005 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 2012 flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2013 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2014 MPI_SGE_FLAGS_IOC_TO_HOST |
2015 MPI_SGE_FLAGS_END_OF_BUFFER;
2016
2017 flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2006 flagsLength |= rsp->data_len + 4; 2018 flagsLength |= rsp->data_len + 4;
2007 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), 2019 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2008 rsp->data_len, PCI_DMA_BIDIRECTIONAL); 2020 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
@@ -2010,6 +2022,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2010 goto unmap; 2022 goto unmap;
2011 ioc->add_sge(psge, flagsLength, dma_addr_in); 2023 ioc->add_sge(psge, flagsLength, dma_addr_in);
2012 2024
2025 INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2013 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); 2026 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2014 2027
2015 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); 2028 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
@@ -2031,7 +2044,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2031 req->data_len = 0; 2044 req->data_len = 0;
2032 rsp->data_len -= smprep->ResponseDataLength; 2045 rsp->data_len -= smprep->ResponseDataLength;
2033 } else { 2046 } else {
2034 printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", 2047 printk(MYIOC_s_ERR_FMT
2048 "%s: smp passthru reply failed to be returned\n",
2035 ioc->name, __func__); 2049 ioc->name, __func__);
2036 ret = -ENXIO; 2050 ret = -ENXIO;
2037 } 2051 }
@@ -2046,6 +2060,7 @@ put_mf:
2046 if (mf) 2060 if (mf)
2047 mpt_free_msg_frame(ioc, mf); 2061 mpt_free_msg_frame(ioc, mf);
2048out_unlock: 2062out_unlock:
2063 CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2049 mutex_unlock(&ioc->sas_mgmt.mutex); 2064 mutex_unlock(&ioc->sas_mgmt.mutex);
2050out: 2065out:
2051 return ret; 2066 return ret;
@@ -2109,7 +2124,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2109 2124
2110 port_info->num_phys = buffer->NumPhys; 2125 port_info->num_phys = buffer->NumPhys;
2111 port_info->phy_info = kcalloc(port_info->num_phys, 2126 port_info->phy_info = kcalloc(port_info->num_phys,
2112 sizeof(*port_info->phy_info),GFP_KERNEL); 2127 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2113 if (!port_info->phy_info) { 2128 if (!port_info->phy_info) {
2114 error = -ENOMEM; 2129 error = -ENOMEM;
2115 goto out_free_consistent; 2130 goto out_free_consistent;
@@ -2271,10 +2286,6 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2271 __le64 sas_address; 2286 __le64 sas_address;
2272 int error=0; 2287 int error=0;
2273 2288
2274 if (ioc->sas_discovery_runtime &&
2275 mptsas_is_end_device(device_info))
2276 goto out;
2277
2278 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION; 2289 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2279 hdr.ExtPageLength = 0; 2290 hdr.ExtPageLength = 0;
2280 hdr.PageNumber = 0; 2291 hdr.PageNumber = 0;
@@ -2315,6 +2326,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2315 2326
2316 mptsas_print_device_pg0(ioc, buffer); 2327 mptsas_print_device_pg0(ioc, buffer);
2317 2328
2329 memset(device_info, 0, sizeof(struct mptsas_devinfo));
2318 device_info->handle = le16_to_cpu(buffer->DevHandle); 2330 device_info->handle = le16_to_cpu(buffer->DevHandle);
2319 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); 2331 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2320 device_info->handle_enclosure = 2332 device_info->handle_enclosure =
@@ -2346,7 +2358,9 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2346 SasExpanderPage0_t *buffer; 2358 SasExpanderPage0_t *buffer;
2347 dma_addr_t dma_handle; 2359 dma_addr_t dma_handle;
2348 int i, error; 2360 int i, error;
2361 __le64 sas_address;
2349 2362
2363 memset(port_info, 0, sizeof(struct mptsas_portinfo));
2350 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; 2364 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2351 hdr.ExtPageLength = 0; 2365 hdr.ExtPageLength = 0;
2352 hdr.PageNumber = 0; 2366 hdr.PageNumber = 0;
@@ -2392,18 +2406,23 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2392 } 2406 }
2393 2407
2394 /* save config data */ 2408 /* save config data */
2395 port_info->num_phys = buffer->NumPhys; 2409 port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2396 port_info->phy_info = kcalloc(port_info->num_phys, 2410 port_info->phy_info = kcalloc(port_info->num_phys,
2397 sizeof(*port_info->phy_info),GFP_KERNEL); 2411 sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2398 if (!port_info->phy_info) { 2412 if (!port_info->phy_info) {
2399 error = -ENOMEM; 2413 error = -ENOMEM;
2400 goto out_free_consistent; 2414 goto out_free_consistent;
2401 } 2415 }
2402 2416
2417 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2403 for (i = 0; i < port_info->num_phys; i++) { 2418 for (i = 0; i < port_info->num_phys; i++) {
2404 port_info->phy_info[i].portinfo = port_info; 2419 port_info->phy_info[i].portinfo = port_info;
2405 port_info->phy_info[i].handle = 2420 port_info->phy_info[i].handle =
2406 le16_to_cpu(buffer->DevHandle); 2421 le16_to_cpu(buffer->DevHandle);
2422 port_info->phy_info[i].identify.sas_address =
2423 le64_to_cpu(sas_address);
2424 port_info->phy_info[i].identify.handle_parent =
2425 le16_to_cpu(buffer->ParentDevHandle);
2407 } 2426 }
2408 2427
2409 out_free_consistent: 2428 out_free_consistent:
@@ -2423,11 +2442,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2423 dma_addr_t dma_handle; 2442 dma_addr_t dma_handle;
2424 int error=0; 2443 int error=0;
2425 2444
2426 if (ioc->sas_discovery_runtime && 2445 hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2427 mptsas_is_end_device(&phy_info->attached))
2428 goto out;
2429
2430 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2431 hdr.ExtPageLength = 0; 2446 hdr.ExtPageLength = 0;
2432 hdr.PageNumber = 1; 2447 hdr.PageNumber = 1;
2433 hdr.Reserved1 = 0; 2448 hdr.Reserved1 = 0;
@@ -2462,6 +2477,12 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2462 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 2477 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2463 2478
2464 error = mpt_config(ioc, &cfg); 2479 error = mpt_config(ioc, &cfg);
2480
2481 if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2482 error = -ENODEV;
2483 goto out;
2484 }
2485
2465 if (error) 2486 if (error)
2466 goto out_free_consistent; 2487 goto out_free_consistent;
2467 2488
@@ -2681,16 +2702,21 @@ static int mptsas_probe_one_phy(struct device *dev,
2681 goto out; 2702 goto out;
2682 } 2703 }
2683 mptsas_set_port(ioc, phy_info, port); 2704 mptsas_set_port(ioc, phy_info, port);
2684 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2705 devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
2685 "sas_port_alloc: port=%p dev=%p port_id=%d\n", 2706 MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
2686 ioc->name, port, dev, port->port_identifier)); 2707 ioc->name, port->port_identifier,
2708 (unsigned long long)phy_info->
2709 attached.sas_address));
2687 } 2710 }
2688 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n", 2711 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2689 ioc->name, phy_info->phy_id)); 2712 "sas_port_add_phy: phy_id=%d\n",
2713 ioc->name, phy_info->phy_id));
2690 sas_port_add_phy(port, phy_info->phy); 2714 sas_port_add_phy(port, phy_info->phy);
2691 phy_info->sas_port_add_phy = 0; 2715 phy_info->sas_port_add_phy = 0;
2716 devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
2717 MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
2718 phy_info->phy_id, phy_info->phy));
2692 } 2719 }
2693
2694 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) { 2720 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2695 2721
2696 struct sas_rphy *rphy; 2722 struct sas_rphy *rphy;
@@ -2703,9 +2729,10 @@ static int mptsas_probe_one_phy(struct device *dev,
2703 * the adding/removing of devices that occur 2729 * the adding/removing of devices that occur
2704 * after start of day. 2730 * after start of day.
2705 */ 2731 */
2706 if (ioc->sas_discovery_runtime && 2732 if (mptsas_is_end_device(&phy_info->attached) &&
2707 mptsas_is_end_device(&phy_info->attached)) 2733 phy_info->attached.handle_parent) {
2708 goto out; 2734 goto out;
2735 }
2709 2736
2710 mptsas_parse_device_info(&identify, &phy_info->attached); 2737 mptsas_parse_device_info(&identify, &phy_info->attached);
2711 if (scsi_is_host_device(parent)) { 2738 if (scsi_is_host_device(parent)) {
@@ -3420,9 +3447,12 @@ mptsas_probe_devices(MPT_ADAPTER *ioc)
3420 } 3447 }
3421} 3448}
3422 3449
3423/* 3450/**
3424 * Start of day discovery 3451 * mptsas_scan_sas_topology -
3425 */ 3452 * @ioc: Pointer to MPT_ADAPTER structure
3453 * @sas_address:
3454 *
3455 **/
3426static void 3456static void
3427mptsas_scan_sas_topology(MPT_ADAPTER *ioc) 3457mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3428{ 3458{
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 477f6f8251e5..6424dcbd5908 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -80,7 +80,6 @@ MODULE_VERSION(my_VERSION);
80/* 80/*
81 * Other private/forward protos... 81 * Other private/forward protos...
82 */ 82 */
83static struct scsi_cmnd * mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
84static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i); 83static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
85static void mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd); 84static void mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
86static int SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd); 85static int SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
@@ -236,7 +235,8 @@ nextSGEset:
236 for (ii=0; ii < (numSgeThisFrame-1); ii++) { 235 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
237 thisxfer = sg_dma_len(sg); 236 thisxfer = sg_dma_len(sg);
238 if (thisxfer == 0) { 237 if (thisxfer == 0) {
239 sg = sg_next(sg); /* Get next SG element from the OS */ 238 /* Get next SG element from the OS */
239 sg = sg_next(sg);
240 sg_done++; 240 sg_done++;
241 continue; 241 continue;
242 } 242 }
@@ -244,7 +244,8 @@ nextSGEset:
244 v2 = sg_dma_address(sg); 244 v2 = sg_dma_address(sg);
245 ioc->add_sge(psge, sgflags | thisxfer, v2); 245 ioc->add_sge(psge, sgflags | thisxfer, v2);
246 246
247 sg = sg_next(sg); /* Get next SG element from the OS */ 247 /* Get next SG element from the OS */
248 sg = sg_next(sg);
248 psge += ioc->SGE_size; 249 psge += ioc->SGE_size;
249 sgeOffset += ioc->SGE_size; 250 sgeOffset += ioc->SGE_size;
250 sg_done++; 251 sg_done++;
@@ -533,14 +534,15 @@ mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pSc
533 } 534 }
534 535
535 scsi_print_command(sc); 536 scsi_print_command(sc);
536 printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d\n", 537 printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %d\n",
537 ioc->name, pScsiReply->Bus, pScsiReply->TargetID); 538 ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
538 printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, " 539 printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
539 "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow, 540 "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
540 scsi_get_resid(sc)); 541 scsi_get_resid(sc));
541 printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, " 542 printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
542 "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag), 543 "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
543 le32_to_cpu(pScsiReply->TransferCount), sc->result); 544 le32_to_cpu(pScsiReply->TransferCount), sc->result);
545
544 printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), " 546 printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
545 "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n", 547 "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
546 ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus, 548 ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
@@ -595,16 +597,14 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
595 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 597 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
596 req_idx_MR = (mr != NULL) ? 598 req_idx_MR = (mr != NULL) ?
597 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx; 599 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
600
601 /* Special case, where already freed message frame is received from
602 * Firmware. It happens with Resetting IOC.
603 * Return immediately. Do not care
604 */
598 if ((req_idx != req_idx_MR) || 605 if ((req_idx != req_idx_MR) ||
599 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) { 606 (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
600 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
601 ioc->name);
602 printk (MYIOC_s_ERR_FMT
603 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
604 ioc->name, req_idx, req_idx_MR, mf, mr,
605 mptscsih_get_scsi_lookup(ioc, req_idx_MR));
606 return 0; 607 return 0;
607 }
608 608
609 sc = mptscsih_getclear_scsi_lookup(ioc, req_idx); 609 sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
610 if (sc == NULL) { 610 if (sc == NULL) {
@@ -751,12 +751,16 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
751 */ 751 */
752 752
753 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 753 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
754 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
755 /* Linux handles an unsolicited DID_RESET better 754 /* Linux handles an unsolicited DID_RESET better
756 * than an unsolicited DID_ABORT. 755 * than an unsolicited DID_ABORT.
757 */ 756 */
758 sc->result = DID_RESET << 16; 757 sc->result = DID_RESET << 16;
759 758
759 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
760 if (ioc->bus_type == FC)
761 sc->result = DID_ERROR << 16;
762 else
763 sc->result = DID_RESET << 16;
760 break; 764 break;
761 765
762 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 766 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
@@ -933,9 +937,9 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
933 scsi_dma_unmap(sc); 937 scsi_dma_unmap(sc);
934 sc->result = DID_RESET << 16; 938 sc->result = DID_RESET << 16;
935 sc->host_scribble = NULL; 939 sc->host_scribble = NULL;
936 sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT 940 dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
937 "completing cmds: fw_channel %d, fw_id %d, sc=%p," 941 "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
938 " mf = %p, idx=%x\n", ioc->name, channel, id, sc, mf, ii); 942 "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
939 sc->scsi_done(sc); 943 sc->scsi_done(sc);
940 } 944 }
941} 945}
@@ -994,9 +998,11 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
994 scsi_dma_unmap(sc); 998 scsi_dma_unmap(sc);
995 sc->host_scribble = NULL; 999 sc->host_scribble = NULL;
996 sc->result = DID_NO_CONNECT << 16; 1000 sc->result = DID_NO_CONNECT << 16;
997 sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT "completing cmds: fw_channel %d," 1001 dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
998 "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel, 1002 MYIOC_s_FMT "completing cmds: fw_channel %d, "
999 vdevice->vtarget->id, sc, mf, ii); 1003 "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
1004 vdevice->vtarget->channel, vdevice->vtarget->id,
1005 sc, mf, ii));
1000 sc->scsi_done(sc); 1006 sc->scsi_done(sc);
1001 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 1007 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1002 } 1008 }
@@ -1287,7 +1293,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1287 MPT_FRAME_HDR *mf; 1293 MPT_FRAME_HDR *mf;
1288 SCSIIORequest_t *pScsiReq; 1294 SCSIIORequest_t *pScsiReq;
1289 VirtDevice *vdevice = SCpnt->device->hostdata; 1295 VirtDevice *vdevice = SCpnt->device->hostdata;
1290 int lun;
1291 u32 datalen; 1296 u32 datalen;
1292 u32 scsictl; 1297 u32 scsictl;
1293 u32 scsidir; 1298 u32 scsidir;
@@ -1298,7 +1303,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1298 1303
1299 hd = shost_priv(SCpnt->device->host); 1304 hd = shost_priv(SCpnt->device->host);
1300 ioc = hd->ioc; 1305 ioc = hd->ioc;
1301 lun = SCpnt->device->lun;
1302 SCpnt->scsi_done = done; 1306 SCpnt->scsi_done = done;
1303 1307
1304 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n", 1308 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
@@ -1709,8 +1713,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1709 goto out; 1713 goto out;
1710 } 1714 }
1711 1715
1712 if (hd->timeouts < -1) 1716 if (ioc->timeouts < -1)
1713 hd->timeouts++; 1717 ioc->timeouts++;
1714 1718
1715 if (mpt_fwfault_debug) 1719 if (mpt_fwfault_debug)
1716 mpt_halt_firmware(ioc); 1720 mpt_halt_firmware(ioc);
@@ -1734,17 +1738,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1734 ctx2abort, mptscsih_get_tm_timeout(ioc)); 1738 ctx2abort, mptscsih_get_tm_timeout(ioc));
1735 1739
1736 if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx && 1740 if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx &&
1737 SCpnt->serial_number == sn) 1741 SCpnt->serial_number == sn) {
1742 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1743 "task abort: command still in active list! (sc=%p)\n",
1744 ioc->name, SCpnt));
1738 retval = FAILED; 1745 retval = FAILED;
1746 } else {
1747 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1748 "task abort: command cleared from active list! (sc=%p)\n",
1749 ioc->name, SCpnt));
1750 retval = SUCCESS;
1751 }
1739 1752
1740 out: 1753 out:
1741 printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n", 1754 printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
1742 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); 1755 ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt);
1743 1756
1744 if (retval == 0) 1757 return retval;
1745 return SUCCESS;
1746 else
1747 return FAILED;
1748} 1758}
1749 1759
1750/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1760/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1779,7 +1789,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1779 1789
1780 vdevice = SCpnt->device->hostdata; 1790 vdevice = SCpnt->device->hostdata;
1781 if (!vdevice || !vdevice->vtarget) { 1791 if (!vdevice || !vdevice->vtarget) {
1782 retval = 0; 1792 retval = SUCCESS;
1783 goto out; 1793 goto out;
1784 } 1794 }
1785 1795
@@ -1837,10 +1847,12 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1837 ioc->name, SCpnt); 1847 ioc->name, SCpnt);
1838 scsi_print_command(SCpnt); 1848 scsi_print_command(SCpnt);
1839 1849
1840 if (hd->timeouts < -1) 1850 if (ioc->timeouts < -1)
1841 hd->timeouts++; 1851 ioc->timeouts++;
1842 1852
1843 vdevice = SCpnt->device->hostdata; 1853 vdevice = SCpnt->device->hostdata;
1854 if (!vdevice || !vdevice->vtarget)
1855 return SUCCESS;
1844 retval = mptscsih_IssueTaskMgmt(hd, 1856 retval = mptscsih_IssueTaskMgmt(hd,
1845 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1857 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1846 vdevice->vtarget->channel, 0, 0, 0, 1858 vdevice->vtarget->channel, 0, 0, 0,
@@ -1868,8 +1880,9 @@ int
1868mptscsih_host_reset(struct scsi_cmnd *SCpnt) 1880mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1869{ 1881{
1870 MPT_SCSI_HOST * hd; 1882 MPT_SCSI_HOST * hd;
1871 int retval; 1883 int status = SUCCESS;
1872 MPT_ADAPTER *ioc; 1884 MPT_ADAPTER *ioc;
1885 int retval;
1873 1886
1874 /* If we can't locate the host to reset, then we failed. */ 1887 /* If we can't locate the host to reset, then we failed. */
1875 if ((hd = shost_priv(SCpnt->device->host)) == NULL){ 1888 if ((hd = shost_priv(SCpnt->device->host)) == NULL){
@@ -1888,19 +1901,16 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1888 /* If our attempts to reset the host failed, then return a failed 1901 /* If our attempts to reset the host failed, then return a failed
1889 * status. The host will be taken off line by the SCSI mid-layer. 1902 * status. The host will be taken off line by the SCSI mid-layer.
1890 */ 1903 */
1891 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) { 1904 retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
1892 retval = FAILED; 1905 if (retval < 0)
1893 } else { 1906 status = FAILED;
1894 /* Make sure TM pending is cleared and TM state is set to 1907 else
1895 * NONE. 1908 status = SUCCESS;
1896 */
1897 retval = 0;
1898 }
1899 1909
1900 printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n", 1910 printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1901 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); 1911 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1902 1912
1903 return retval; 1913 return status;
1904} 1914}
1905 1915
1906static int 1916static int
@@ -2244,7 +2254,6 @@ mptscsih_slave_configure(struct scsi_device *sdev)
2244 sdev->ppr, sdev->inquiry_len)); 2254 sdev->ppr, sdev->inquiry_len));
2245 2255
2246 vdevice->configured_lun = 1; 2256 vdevice->configured_lun = 1;
2247 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2248 2257
2249 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2258 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2250 "Queue depth=%d, tflags=%x\n", 2259 "Queue depth=%d, tflags=%x\n",
@@ -2256,6 +2265,7 @@ mptscsih_slave_configure(struct scsi_device *sdev)
2256 ioc->name, vtarget->negoFlags, vtarget->maxOffset, 2265 ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2257 vtarget->minSyncFactor)); 2266 vtarget->minSyncFactor));
2258 2267
2268 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2259 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2269 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2260 "tagged %d, simple %d, ordered %d\n", 2270 "tagged %d, simple %d, ordered %d\n",
2261 ioc->name,sdev->tagged_supported, sdev->simple_tags, 2271 ioc->name,sdev->tagged_supported, sdev->simple_tags,
@@ -2328,36 +2338,17 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
2328 } 2338 }
2329} 2339}
2330 2340
2331/**
2332 * mptscsih_get_scsi_lookup
2333 * @ioc: Pointer to MPT_ADAPTER structure
2334 * @i: index into the array
2335 *
2336 * retrieves scmd entry from ScsiLookup[] array list
2337 *
2338 * Returns the scsi_cmd pointer
2339 **/
2340static struct scsi_cmnd *
2341mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2342{
2343 unsigned long flags;
2344 struct scsi_cmnd *scmd;
2345
2346 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2347 scmd = ioc->ScsiLookup[i];
2348 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2349
2350 return scmd;
2351}
2352 2341
2353/** 2342/**
2354 * mptscsih_getclear_scsi_lookup 2343 * mptscsih_getclear_scsi_lookup
2355 * @ioc: Pointer to MPT_ADAPTER structure
2356 * @i: index into the array
2357 * 2344 *
2358 * retrieves and clears scmd entry from ScsiLookup[] array list 2345 * retrieves and clears scmd entry from ScsiLookup[] array list
2359 * 2346 *
2347 * @ioc: Pointer to MPT_ADAPTER structure
2348 * @i: index into the array
2349 *
2360 * Returns the scsi_cmd pointer 2350 * Returns the scsi_cmd pointer
2351 *
2361 **/ 2352 **/
2362static struct scsi_cmnd * 2353static struct scsi_cmnd *
2363mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i) 2354mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
@@ -2456,57 +2447,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2456int 2447int
2457mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) 2448mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2458{ 2449{
2459 MPT_SCSI_HOST *hd;
2460 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2450 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2461 2451
2462 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2452 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2463 "MPT event (=%02Xh) routed to SCSI host driver!\n", 2453 "MPT event (=%02Xh) routed to SCSI host driver!\n",
2464 ioc->name, event)); 2454 ioc->name, event));
2465 2455
2466 if (ioc->sh == NULL || 2456 if ((event == MPI_EVENT_IOC_BUS_RESET ||
2467 ((hd = shost_priv(ioc->sh)) == NULL)) 2457 event == MPI_EVENT_EXT_BUS_RESET) &&
2468 return 1; 2458 (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2469 2459 ioc->soft_resets++;
2470 switch (event) {
2471 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2472 /* FIXME! */
2473 break;
2474 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2475 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2476 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2477 hd->soft_resets++;
2478 break;
2479 case MPI_EVENT_LOGOUT: /* 09 */
2480 /* FIXME! */
2481 break;
2482
2483 case MPI_EVENT_RESCAN: /* 06 */
2484 break;
2485
2486 /*
2487 * CHECKME! Don't think we need to do
2488 * anything for these, but...
2489 */
2490 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2491 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2492 /*
2493 * CHECKME! Falling thru...
2494 */
2495 break;
2496
2497 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2498 break;
2499
2500 case MPI_EVENT_NONE: /* 00 */
2501 case MPI_EVENT_LOG_DATA: /* 01 */
2502 case MPI_EVENT_STATE_CHANGE: /* 02 */
2503 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2504 default:
2505 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2506 ": Ignoring event (=%02Xh)\n",
2507 ioc->name, event));
2508 break;
2509 }
2510 2460
2511 return 1; /* currently means nothing really */ 2461 return 1; /* currently means nothing really */
2512} 2462}
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 91e9e9fcd0e4..572739565f6a 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -90,6 +90,7 @@
90 90
91#endif 91#endif
92 92
93
93typedef struct _internal_cmd { 94typedef struct _internal_cmd {
94 char *data; /* data pointer */ 95 char *data; /* data pointer */
95 dma_addr_t data_dma; /* data dma address */ 96 dma_addr_t data_dma; /* data dma address */