diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-01-09 02:38:23 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-01-09 02:38:23 -0500 |
| commit | da733563be5a9da26fe81d9f007262d00b846e22 (patch) | |
| tree | db28291df94a2043af2123911984c5c173da4e6f /drivers/message/fusion | |
| parent | 6ccbcf2cb41131f8d56ef0723bf3f7c1f8486076 (diff) | |
| parent | dab78d7924598ea4031663dd10db814e2e324928 (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/message/fusion')
| -rw-r--r-- | drivers/message/fusion/mptbase.c | 92 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 72 | ||||
| -rw-r--r-- | drivers/message/fusion/mptsas.c | 47 | ||||
| -rw-r--r-- | drivers/message/fusion/mptscsih.c | 18 | ||||
| -rw-r--r-- | drivers/message/fusion/mptscsih.h | 1 |
5 files changed, 185 insertions, 45 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 7956a10f9488..e9c6a6047a00 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
| @@ -63,6 +63,8 @@ | |||
| 63 | #ifdef CONFIG_MTRR | 63 | #ifdef CONFIG_MTRR |
| 64 | #include <asm/mtrr.h> | 64 | #include <asm/mtrr.h> |
| 65 | #endif | 65 | #endif |
| 66 | #include <linux/kthread.h> | ||
| 67 | #include <scsi/scsi_host.h> | ||
| 66 | 68 | ||
| 67 | #include "mptbase.h" | 69 | #include "mptbase.h" |
| 68 | #include "lsi/mpi_log_fc.h" | 70 | #include "lsi/mpi_log_fc.h" |
| @@ -323,6 +325,32 @@ mpt_is_discovery_complete(MPT_ADAPTER *ioc) | |||
| 323 | return rc; | 325 | return rc; |
| 324 | } | 326 | } |
| 325 | 327 | ||
| 328 | |||
| 329 | /** | ||
| 330 | * mpt_remove_dead_ioc_func - kthread context to remove dead ioc | ||
| 331 | * @arg: input argument, used to derive ioc | ||
| 332 | * | ||
| 333 | * Return 0 if controller is removed from pci subsystem. | ||
| 334 | * Return -1 for other case. | ||
| 335 | */ | ||
| 336 | static int mpt_remove_dead_ioc_func(void *arg) | ||
| 337 | { | ||
| 338 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | ||
| 339 | struct pci_dev *pdev; | ||
| 340 | |||
| 341 | if ((ioc == NULL)) | ||
| 342 | return -1; | ||
| 343 | |||
| 344 | pdev = ioc->pcidev; | ||
| 345 | if ((pdev == NULL)) | ||
| 346 | return -1; | ||
| 347 | |||
| 348 | pci_remove_bus_device(pdev); | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 352 | |||
| 353 | |||
| 326 | /** | 354 | /** |
| 327 | * mpt_fault_reset_work - work performed on workq after ioc fault | 355 | * mpt_fault_reset_work - work performed on workq after ioc fault |
| 328 | * @work: input argument, used to derive ioc | 356 | * @work: input argument, used to derive ioc |
| @@ -336,12 +364,45 @@ mpt_fault_reset_work(struct work_struct *work) | |||
| 336 | u32 ioc_raw_state; | 364 | u32 ioc_raw_state; |
| 337 | int rc; | 365 | int rc; |
| 338 | unsigned long flags; | 366 | unsigned long flags; |
| 367 | MPT_SCSI_HOST *hd; | ||
| 368 | struct task_struct *p; | ||
| 339 | 369 | ||
| 340 | if (ioc->ioc_reset_in_progress || !ioc->active) | 370 | if (ioc->ioc_reset_in_progress || !ioc->active) |
| 341 | goto out; | 371 | goto out; |
| 342 | 372 | ||
| 373 | |||
| 343 | ioc_raw_state = mpt_GetIocState(ioc, 0); | 374 | ioc_raw_state = mpt_GetIocState(ioc, 0); |
| 344 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { | 375 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) { |
| 376 | printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n", | ||
| 377 | ioc->name, __func__); | ||
| 378 | |||
| 379 | /* | ||
| 380 | * Call mptscsih_flush_pending_cmds callback so that we | ||
| 381 | * flush all pending commands back to OS. | ||
| 382 | * This call is required to aovid deadlock at block layer. | ||
| 383 | * Dead IOC will fail to do diag reset,and this call is safe | ||
| 384 | * since dead ioc will never return any command back from HW. | ||
| 385 | */ | ||
| 386 | hd = shost_priv(ioc->sh); | ||
| 387 | ioc->schedule_dead_ioc_flush_running_cmds(hd); | ||
| 388 | |||
| 389 | /*Remove the Dead Host */ | ||
| 390 | p = kthread_run(mpt_remove_dead_ioc_func, ioc, | ||
| 391 | "mpt_dead_ioc_%d", ioc->id); | ||
| 392 | if (IS_ERR(p)) { | ||
| 393 | printk(MYIOC_s_ERR_FMT | ||
| 394 | "%s: Running mpt_dead_ioc thread failed !\n", | ||
| 395 | ioc->name, __func__); | ||
| 396 | } else { | ||
| 397 | printk(MYIOC_s_WARN_FMT | ||
| 398 | "%s: Running mpt_dead_ioc thread success !\n", | ||
| 399 | ioc->name, __func__); | ||
| 400 | } | ||
| 401 | return; /* don't rearm timer */ | ||
| 402 | } | ||
| 403 | |||
| 404 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) | ||
| 405 | == MPI_IOC_STATE_FAULT) { | ||
| 345 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", | 406 | printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", |
| 346 | ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); | 407 | ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); |
| 347 | printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", | 408 | printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", |
| @@ -6413,8 +6474,19 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) | |||
| 6413 | pReq->Action, ioc->mptbase_cmds.status, timeleft)); | 6474 | pReq->Action, ioc->mptbase_cmds.status, timeleft)); |
| 6414 | if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) | 6475 | if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) |
| 6415 | goto out; | 6476 | goto out; |
| 6416 | if (!timeleft) | 6477 | if (!timeleft) { |
| 6478 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | ||
| 6479 | if (ioc->ioc_reset_in_progress) { | ||
| 6480 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, | ||
| 6481 | flags); | ||
| 6482 | printk(MYIOC_s_INFO_FMT "%s: host reset in" | ||
| 6483 | " progress mpt_config timed out.!!\n", | ||
| 6484 | __func__, ioc->name); | ||
| 6485 | return -EFAULT; | ||
| 6486 | } | ||
| 6487 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
| 6417 | issue_hard_reset = 1; | 6488 | issue_hard_reset = 1; |
| 6489 | } | ||
| 6418 | goto out; | 6490 | goto out; |
| 6419 | } | 6491 | } |
| 6420 | 6492 | ||
| @@ -7128,7 +7200,18 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
| 7128 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | 7200 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); |
| 7129 | if (ioc->ioc_reset_in_progress) { | 7201 | if (ioc->ioc_reset_in_progress) { |
| 7130 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | 7202 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); |
| 7131 | return 0; | 7203 | ioc->wait_on_reset_completion = 1; |
| 7204 | do { | ||
| 7205 | ssleep(1); | ||
| 7206 | } while (ioc->ioc_reset_in_progress == 1); | ||
| 7207 | ioc->wait_on_reset_completion = 0; | ||
| 7208 | return ioc->reset_status; | ||
| 7209 | } | ||
| 7210 | if (ioc->wait_on_reset_completion) { | ||
| 7211 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
| 7212 | rc = 0; | ||
| 7213 | time_count = jiffies; | ||
| 7214 | goto exit; | ||
| 7132 | } | 7215 | } |
| 7133 | ioc->ioc_reset_in_progress = 1; | 7216 | ioc->ioc_reset_in_progress = 1; |
| 7134 | if (ioc->alt_ioc) | 7217 | if (ioc->alt_ioc) |
| @@ -7165,6 +7248,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
| 7165 | ioc->ioc_reset_in_progress = 0; | 7248 | ioc->ioc_reset_in_progress = 0; |
| 7166 | ioc->taskmgmt_quiesce_io = 0; | 7249 | ioc->taskmgmt_quiesce_io = 0; |
| 7167 | ioc->taskmgmt_in_progress = 0; | 7250 | ioc->taskmgmt_in_progress = 0; |
| 7251 | ioc->reset_status = rc; | ||
| 7168 | if (ioc->alt_ioc) { | 7252 | if (ioc->alt_ioc) { |
| 7169 | ioc->alt_ioc->ioc_reset_in_progress = 0; | 7253 | ioc->alt_ioc->ioc_reset_in_progress = 0; |
| 7170 | ioc->alt_ioc->taskmgmt_quiesce_io = 0; | 7254 | ioc->alt_ioc->taskmgmt_quiesce_io = 0; |
| @@ -7180,7 +7264,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | |||
| 7180 | ioc->alt_ioc, MPT_IOC_POST_RESET); | 7264 | ioc->alt_ioc, MPT_IOC_POST_RESET); |
| 7181 | } | 7265 | } |
| 7182 | } | 7266 | } |
| 7183 | 7267 | exit: | |
| 7184 | dtmprintk(ioc, | 7268 | dtmprintk(ioc, |
| 7185 | printk(MYIOC_s_DEBUG_FMT | 7269 | printk(MYIOC_s_DEBUG_FMT |
| 7186 | "HardResetHandler: completed (%d seconds): %s\n", ioc->name, | 7270 | "HardResetHandler: completed (%d seconds): %s\n", ioc->name, |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index fe902338539b..b4d24dc081ae 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
| @@ -76,8 +76,8 @@ | |||
| 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.19" | 79 | #define MPT_LINUX_VERSION_COMMON "3.04.20" |
| 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.19" | 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.20" |
| 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) \ |
| @@ -554,10 +554,47 @@ struct mptfc_rport_info | |||
| 554 | u8 flags; | 554 | u8 flags; |
| 555 | }; | 555 | }; |
| 556 | 556 | ||
| 557 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
| 558 | |||
| 559 | /* | ||
| 560 | * MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers | ||
| 561 | * Private to the driver. | ||
| 562 | */ | ||
| 563 | |||
| 564 | #define MPT_HOST_BUS_UNKNOWN (0xFF) | ||
| 565 | #define MPT_HOST_TOO_MANY_TM (0x05) | ||
| 566 | #define MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) | ||
| 567 | #define MPT_HOST_NO_CHAIN (0xFFFFFFFF) | ||
| 568 | #define MPT_NVRAM_MASK_TIMEOUT (0x000000FF) | ||
| 569 | #define MPT_NVRAM_SYNC_MASK (0x0000FF00) | ||
| 570 | #define MPT_NVRAM_SYNC_SHIFT (8) | ||
| 571 | #define MPT_NVRAM_DISCONNECT_ENABLE (0x00010000) | ||
| 572 | #define MPT_NVRAM_ID_SCAN_ENABLE (0x00020000) | ||
| 573 | #define MPT_NVRAM_LUN_SCAN_ENABLE (0x00040000) | ||
| 574 | #define MPT_NVRAM_TAG_QUEUE_ENABLE (0x00080000) | ||
| 575 | #define MPT_NVRAM_WIDE_DISABLE (0x00100000) | ||
| 576 | #define MPT_NVRAM_BOOT_CHOICE (0x00200000) | ||
| 577 | |||
| 578 | typedef enum { | ||
| 579 | FC, | ||
| 580 | SPI, | ||
| 581 | SAS | ||
| 582 | } BUS_TYPE; | ||
| 583 | |||
| 584 | typedef struct _MPT_SCSI_HOST { | ||
| 585 | struct _MPT_ADAPTER *ioc; | ||
| 586 | ushort sel_timeout[MPT_MAX_FC_DEVICES]; | ||
| 587 | char *info_kbuf; | ||
| 588 | long last_queue_full; | ||
| 589 | u16 spi_pending; | ||
| 590 | struct list_head target_reset_list; | ||
| 591 | } MPT_SCSI_HOST; | ||
| 592 | |||
| 557 | typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); | 593 | typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); |
| 558 | typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, | 594 | typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, |
| 559 | dma_addr_t dma_addr); | 595 | dma_addr_t dma_addr); |
| 560 | typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc); | 596 | typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc); |
| 597 | typedef void (*MPT_FLUSH_RUNNING_CMDS)(MPT_SCSI_HOST *hd); | ||
| 561 | 598 | ||
| 562 | /* | 599 | /* |
| 563 | * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS | 600 | * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS |
| @@ -716,7 +753,10 @@ typedef struct _MPT_ADAPTER | |||
| 716 | int taskmgmt_in_progress; | 753 | int taskmgmt_in_progress; |
| 717 | u8 taskmgmt_quiesce_io; | 754 | u8 taskmgmt_quiesce_io; |
| 718 | u8 ioc_reset_in_progress; | 755 | u8 ioc_reset_in_progress; |
| 756 | u8 reset_status; | ||
| 757 | u8 wait_on_reset_completion; | ||
| 719 | MPT_SCHEDULE_TARGET_RESET schedule_target_reset; | 758 | MPT_SCHEDULE_TARGET_RESET schedule_target_reset; |
| 759 | MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; | ||
| 720 | struct work_struct sas_persist_task; | 760 | struct work_struct sas_persist_task; |
| 721 | 761 | ||
| 722 | struct work_struct fc_setup_reset_work; | 762 | struct work_struct fc_setup_reset_work; |
| @@ -830,19 +870,6 @@ typedef struct _MPT_LOCAL_REPLY { | |||
| 830 | u32 pad; | 870 | u32 pad; |
| 831 | } MPT_LOCAL_REPLY; | 871 | } MPT_LOCAL_REPLY; |
| 832 | 872 | ||
| 833 | #define MPT_HOST_BUS_UNKNOWN (0xFF) | ||
| 834 | #define MPT_HOST_TOO_MANY_TM (0x05) | ||
| 835 | #define MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) | ||
| 836 | #define MPT_HOST_NO_CHAIN (0xFFFFFFFF) | ||
| 837 | #define MPT_NVRAM_MASK_TIMEOUT (0x000000FF) | ||
| 838 | #define MPT_NVRAM_SYNC_MASK (0x0000FF00) | ||
| 839 | #define MPT_NVRAM_SYNC_SHIFT (8) | ||
| 840 | #define MPT_NVRAM_DISCONNECT_ENABLE (0x00010000) | ||
| 841 | #define MPT_NVRAM_ID_SCAN_ENABLE (0x00020000) | ||
| 842 | #define MPT_NVRAM_LUN_SCAN_ENABLE (0x00040000) | ||
| 843 | #define MPT_NVRAM_TAG_QUEUE_ENABLE (0x00080000) | ||
| 844 | #define MPT_NVRAM_WIDE_DISABLE (0x00100000) | ||
| 845 | #define MPT_NVRAM_BOOT_CHOICE (0x00200000) | ||
| 846 | 873 | ||
| 847 | /* The TM_STATE variable is used to provide strict single threading of TM | 874 | /* The TM_STATE variable is used to provide strict single threading of TM |
| 848 | * requests as well as communicate TM error conditions. | 875 | * requests as well as communicate TM error conditions. |
| @@ -851,21 +878,6 @@ typedef struct _MPT_LOCAL_REPLY { | |||
| 851 | #define TM_STATE_IN_PROGRESS (1) | 878 | #define TM_STATE_IN_PROGRESS (1) |
| 852 | #define TM_STATE_ERROR (2) | 879 | #define TM_STATE_ERROR (2) |
| 853 | 880 | ||
| 854 | typedef enum { | ||
| 855 | FC, | ||
| 856 | SPI, | ||
| 857 | SAS | ||
| 858 | } BUS_TYPE; | ||
| 859 | |||
| 860 | typedef struct _MPT_SCSI_HOST { | ||
| 861 | MPT_ADAPTER *ioc; | ||
| 862 | ushort sel_timeout[MPT_MAX_FC_DEVICES]; | ||
| 863 | char *info_kbuf; | ||
| 864 | long last_queue_full; | ||
| 865 | u16 spi_pending; | ||
| 866 | struct list_head target_reset_list; | ||
| 867 | } MPT_SCSI_HOST; | ||
| 868 | |||
| 869 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 881 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 870 | /* | 882 | /* |
| 871 | * More Dynamic Multi-Pathing stuff... | 883 | * More Dynamic Multi-Pathing stuff... |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 7596aecd5072..9d9504298549 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
| @@ -92,6 +92,11 @@ static int max_lun = MPTSAS_MAX_LUN; | |||
| 92 | module_param(max_lun, int, 0); | 92 | module_param(max_lun, int, 0); |
| 93 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | 93 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); |
| 94 | 94 | ||
| 95 | static int mpt_loadtime_max_sectors = 8192; | ||
| 96 | module_param(mpt_loadtime_max_sectors, int, 0); | ||
| 97 | MODULE_PARM_DESC(mpt_loadtime_max_sectors, | ||
| 98 | " Maximum sector define for Host Bus Adaptor.Range 64 to 8192 default=8192"); | ||
| 99 | |||
| 95 | static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS; | 100 | static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS; |
| 96 | static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS; | 101 | static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS; |
| 97 | static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */ | 102 | static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */ |
| @@ -285,10 +290,11 @@ mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
| 285 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 290 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
| 286 | list_add_tail(&fw_event->list, &ioc->fw_event_list); | 291 | list_add_tail(&fw_event->list, &ioc->fw_event_list); |
| 287 | INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work); | 292 | INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work); |
| 288 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)\n", | 293 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)" |
| 289 | ioc->name, __func__, fw_event)); | 294 | "on cpuid %d\n", ioc->name, __func__, |
| 290 | queue_delayed_work(ioc->fw_event_q, &fw_event->work, | 295 | fw_event, smp_processor_id())); |
| 291 | delay); | 296 | queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q, |
| 297 | &fw_event->work, delay); | ||
| 292 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 298 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
| 293 | } | 299 | } |
| 294 | 300 | ||
| @@ -300,10 +306,11 @@ mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
| 300 | unsigned long flags; | 306 | unsigned long flags; |
| 301 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 307 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
| 302 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task " | 308 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task " |
| 303 | "(fw_event=0x%p)\n", ioc->name, __func__, fw_event)); | 309 | "(fw_event=0x%p)on cpuid %d\n", ioc->name, __func__, |
| 310 | fw_event, smp_processor_id())); | ||
| 304 | fw_event->retries++; | 311 | fw_event->retries++; |
| 305 | queue_delayed_work(ioc->fw_event_q, &fw_event->work, | 312 | queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q, |
| 306 | msecs_to_jiffies(delay)); | 313 | &fw_event->work, msecs_to_jiffies(delay)); |
| 307 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 314 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
| 308 | } | 315 | } |
| 309 | 316 | ||
| @@ -1943,6 +1950,15 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc) | |||
| 1943 | goto done; | 1950 | goto done; |
| 1944 | } | 1951 | } |
| 1945 | 1952 | ||
| 1953 | /* In case if IOC is in reset from internal context. | ||
| 1954 | * Do not execute EEH for the same IOC. SML should to reset timer. | ||
| 1955 | */ | ||
| 1956 | if (ioc->ioc_reset_in_progress) { | ||
| 1957 | dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset," | ||
| 1958 | "SML need to reset the timer (sc=%p)\n", | ||
| 1959 | ioc->name, __func__, sc)); | ||
| 1960 | rc = BLK_EH_RESET_TIMER; | ||
| 1961 | } | ||
| 1946 | vdevice = sc->device->hostdata; | 1962 | vdevice = sc->device->hostdata; |
| 1947 | if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD | 1963 | if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD |
| 1948 | || vdevice->vtarget->deleted)) { | 1964 | || vdevice->vtarget->deleted)) { |
| @@ -5142,6 +5158,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 5142 | ioc->TaskCtx = mptsasTaskCtx; | 5158 | ioc->TaskCtx = mptsasTaskCtx; |
| 5143 | ioc->InternalCtx = mptsasInternalCtx; | 5159 | ioc->InternalCtx = mptsasInternalCtx; |
| 5144 | ioc->schedule_target_reset = &mptsas_schedule_target_reset; | 5160 | ioc->schedule_target_reset = &mptsas_schedule_target_reset; |
| 5161 | ioc->schedule_dead_ioc_flush_running_cmds = | ||
| 5162 | &mptscsih_flush_running_cmds; | ||
| 5145 | /* Added sanity check on readiness of the MPT adapter. | 5163 | /* Added sanity check on readiness of the MPT adapter. |
| 5146 | */ | 5164 | */ |
| 5147 | if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { | 5165 | if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { |
| @@ -5239,6 +5257,21 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 5239 | sh->sg_tablesize = numSGE; | 5257 | sh->sg_tablesize = numSGE; |
| 5240 | } | 5258 | } |
| 5241 | 5259 | ||
| 5260 | if (mpt_loadtime_max_sectors) { | ||
| 5261 | if (mpt_loadtime_max_sectors < 64 || | ||
| 5262 | mpt_loadtime_max_sectors > 8192) { | ||
| 5263 | printk(MYIOC_s_INFO_FMT "Invalid value passed for" | ||
| 5264 | "mpt_loadtime_max_sectors %d." | ||
| 5265 | "Range from 64 to 8192\n", ioc->name, | ||
| 5266 | mpt_loadtime_max_sectors); | ||
| 5267 | } | ||
| 5268 | mpt_loadtime_max_sectors &= 0xFFFFFFFE; | ||
| 5269 | dprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
| 5270 | "Resetting max sector to %d from %d\n", | ||
| 5271 | ioc->name, mpt_loadtime_max_sectors, sh->max_sectors)); | ||
| 5272 | sh->max_sectors = mpt_loadtime_max_sectors; | ||
| 5273 | } | ||
| 5274 | |||
| 5242 | hd = shost_priv(sh); | 5275 | hd = shost_priv(sh); |
| 5243 | hd->ioc = ioc; | 5276 | hd->ioc = ioc; |
| 5244 | 5277 | ||
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index ce61a5769765..0c3ced70707b 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
| @@ -830,7 +830,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
| 830 | if ((pScsiReq->CDB[0] == READ_6 && ((pScsiReq->CDB[1] & 0x02) == 0)) || | 830 | if ((pScsiReq->CDB[0] == READ_6 && ((pScsiReq->CDB[1] & 0x02) == 0)) || |
| 831 | pScsiReq->CDB[0] == READ_10 || | 831 | pScsiReq->CDB[0] == READ_10 || |
| 832 | pScsiReq->CDB[0] == READ_12 || | 832 | pScsiReq->CDB[0] == READ_12 || |
| 833 | pScsiReq->CDB[0] == READ_16 || | 833 | (pScsiReq->CDB[0] == READ_16 && |
| 834 | ((pScsiReq->CDB[1] & 0x02) == 0)) || | ||
| 834 | pScsiReq->CDB[0] == VERIFY || | 835 | pScsiReq->CDB[0] == VERIFY || |
| 835 | pScsiReq->CDB[0] == VERIFY_16) { | 836 | pScsiReq->CDB[0] == VERIFY_16) { |
| 836 | if (scsi_bufflen(sc) != | 837 | if (scsi_bufflen(sc) != |
| @@ -1024,7 +1025,7 @@ out: | |||
| 1024 | * | 1025 | * |
| 1025 | * Must be called while new I/Os are being queued. | 1026 | * Must be called while new I/Os are being queued. |
| 1026 | */ | 1027 | */ |
| 1027 | static void | 1028 | void |
| 1028 | mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) | 1029 | mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) |
| 1029 | { | 1030 | { |
| 1030 | MPT_ADAPTER *ioc = hd->ioc; | 1031 | MPT_ADAPTER *ioc = hd->ioc; |
| @@ -1055,6 +1056,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) | |||
| 1055 | sc->scsi_done(sc); | 1056 | sc->scsi_done(sc); |
| 1056 | } | 1057 | } |
| 1057 | } | 1058 | } |
| 1059 | EXPORT_SYMBOL(mptscsih_flush_running_cmds); | ||
| 1058 | 1060 | ||
| 1059 | /* | 1061 | /* |
| 1060 | * mptscsih_search_running_cmds - Delete any commands associated | 1062 | * mptscsih_search_running_cmds - Delete any commands associated |
| @@ -1629,7 +1631,13 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, | |||
| 1629 | return 0; | 1631 | return 0; |
| 1630 | } | 1632 | } |
| 1631 | 1633 | ||
| 1632 | if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { | 1634 | /* DOORBELL ACTIVE check is not required if |
| 1635 | * MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported. | ||
| 1636 | */ | ||
| 1637 | |||
| 1638 | if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) | ||
| 1639 | && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) && | ||
| 1640 | (ioc_raw_state & MPI_DOORBELL_ACTIVE)) { | ||
| 1633 | printk(MYIOC_s_WARN_FMT | 1641 | printk(MYIOC_s_WARN_FMT |
| 1634 | "TaskMgmt type=%x: ioc_state: " | 1642 | "TaskMgmt type=%x: ioc_state: " |
| 1635 | "DOORBELL_ACTIVE (0x%x)!\n", | 1643 | "DOORBELL_ACTIVE (0x%x)!\n", |
| @@ -1728,7 +1736,9 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, | |||
| 1728 | printk(MYIOC_s_WARN_FMT | 1736 | printk(MYIOC_s_WARN_FMT |
| 1729 | "Issuing Reset from %s!! doorbell=0x%08x\n", | 1737 | "Issuing Reset from %s!! doorbell=0x%08x\n", |
| 1730 | ioc->name, __func__, mpt_GetIocState(ioc, 0)); | 1738 | ioc->name, __func__, mpt_GetIocState(ioc, 0)); |
| 1731 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 1739 | retval = (ioc->bus_type == SAS) ? |
| 1740 | mpt_HardResetHandler(ioc, CAN_SLEEP) : | ||
| 1741 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | ||
| 1732 | mpt_free_msg_frame(ioc, mf); | 1742 | mpt_free_msg_frame(ioc, mf); |
| 1733 | } | 1743 | } |
| 1734 | 1744 | ||
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 45a5ff3eff61..43e75ff39921 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
| @@ -135,3 +135,4 @@ extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); | |||
| 135 | extern struct device_attribute *mptscsih_host_attrs[]; | 135 | extern struct device_attribute *mptscsih_host_attrs[]; |
| 136 | extern struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i); | 136 | extern struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i); |
| 137 | extern void mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code); | 137 | extern void mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code); |
| 138 | extern void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd); | ||
