diff options
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); | ||