diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 171 |
1 files changed, 136 insertions, 35 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 670241efa4b5..88e6eebc3159 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/dma-mapping.h> | 57 | #include <linux/dma-mapping.h> |
58 | #include <linux/sort.h> | 58 | #include <linux/sort.h> |
59 | #include <linux/io.h> | 59 | #include <linux/io.h> |
60 | #include <linux/time.h> | ||
60 | 61 | ||
61 | #include "mpt2sas_base.h" | 62 | #include "mpt2sas_base.h" |
62 | 63 | ||
@@ -77,6 +78,43 @@ static int msix_disable = -1; | |||
77 | module_param(msix_disable, int, 0); | 78 | module_param(msix_disable, int, 0); |
78 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); | 79 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); |
79 | 80 | ||
81 | /* diag_buffer_enable is bitwise | ||
82 | * bit 0 set = TRACE | ||
83 | * bit 1 set = SNAPSHOT | ||
84 | * bit 2 set = EXTENDED | ||
85 | * | ||
86 | * Either bit can be set, or both | ||
87 | */ | ||
88 | static int diag_buffer_enable; | ||
89 | module_param(diag_buffer_enable, int, 0); | ||
90 | MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " | ||
91 | "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); | ||
92 | |||
93 | int mpt2sas_fwfault_debug; | ||
94 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " | ||
95 | "and halt firmware - (default=0)"); | ||
96 | |||
97 | /** | ||
98 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. | ||
99 | * | ||
100 | */ | ||
101 | static int | ||
102 | _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp) | ||
103 | { | ||
104 | int ret = param_set_int(val, kp); | ||
105 | struct MPT2SAS_ADAPTER *ioc; | ||
106 | |||
107 | if (ret) | ||
108 | return ret; | ||
109 | |||
110 | printk(KERN_INFO "setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug); | ||
111 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) | ||
112 | ioc->fwfault_debug = mpt2sas_fwfault_debug; | ||
113 | return 0; | ||
114 | } | ||
115 | module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug, | ||
116 | param_get_int, &mpt2sas_fwfault_debug, 0644); | ||
117 | |||
80 | /** | 118 | /** |
81 | * _base_fault_reset_work - workq handling ioc fault conditions | 119 | * _base_fault_reset_work - workq handling ioc fault conditions |
82 | * @work: input argument, used to derive ioc | 120 | * @work: input argument, used to derive ioc |
@@ -121,7 +159,7 @@ _base_fault_reset_work(struct work_struct *work) | |||
121 | 159 | ||
122 | /** | 160 | /** |
123 | * mpt2sas_base_start_watchdog - start the fault_reset_work_q | 161 | * mpt2sas_base_start_watchdog - start the fault_reset_work_q |
124 | * @ioc: pointer to scsi command object | 162 | * @ioc: per adapter object |
125 | * Context: sleep. | 163 | * Context: sleep. |
126 | * | 164 | * |
127 | * Return nothing. | 165 | * Return nothing. |
@@ -155,7 +193,7 @@ mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc) | |||
155 | 193 | ||
156 | /** | 194 | /** |
157 | * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q | 195 | * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q |
158 | * @ioc: pointer to scsi command object | 196 | * @ioc: per adapter object |
159 | * Context: sleep. | 197 | * Context: sleep. |
160 | * | 198 | * |
161 | * Return nothing. | 199 | * Return nothing. |
@@ -177,10 +215,55 @@ mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc) | |||
177 | } | 215 | } |
178 | } | 216 | } |
179 | 217 | ||
218 | /** | ||
219 | * mpt2sas_base_fault_info - verbose translation of firmware FAULT code | ||
220 | * @ioc: per adapter object | ||
221 | * @fault_code: fault code | ||
222 | * | ||
223 | * Return nothing. | ||
224 | */ | ||
225 | void | ||
226 | mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code) | ||
227 | { | ||
228 | printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n", | ||
229 | ioc->name, fault_code); | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * mpt2sas_halt_firmware - halt's mpt controller firmware | ||
234 | * @ioc: per adapter object | ||
235 | * | ||
236 | * For debugging timeout related issues. Writing 0xCOFFEE00 | ||
237 | * to the doorbell register will halt controller firmware. With | ||
238 | * the purpose to stop both driver and firmware, the enduser can | ||
239 | * obtain a ring buffer from controller UART. | ||
240 | */ | ||
241 | void | ||
242 | mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc) | ||
243 | { | ||
244 | u32 doorbell; | ||
245 | |||
246 | if (!ioc->fwfault_debug) | ||
247 | return; | ||
248 | |||
249 | dump_stack(); | ||
250 | |||
251 | doorbell = readl(&ioc->chip->Doorbell); | ||
252 | if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) | ||
253 | mpt2sas_base_fault_info(ioc , doorbell); | ||
254 | else { | ||
255 | writel(0xC0FFEE00, &ioc->chip->Doorbell); | ||
256 | printk(MPT2SAS_ERR_FMT "Firmware is halted due to command " | ||
257 | "timeout\n", ioc->name); | ||
258 | } | ||
259 | |||
260 | panic("panic in %s\n", __func__); | ||
261 | } | ||
262 | |||
180 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 263 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
181 | /** | 264 | /** |
182 | * _base_sas_ioc_info - verbose translation of the ioc status | 265 | * _base_sas_ioc_info - verbose translation of the ioc status |
183 | * @ioc: pointer to scsi command object | 266 | * @ioc: per adapter object |
184 | * @mpi_reply: reply mf payload returned from firmware | 267 | * @mpi_reply: reply mf payload returned from firmware |
185 | * @request_hdr: request mf | 268 | * @request_hdr: request mf |
186 | * | 269 | * |
@@ -394,7 +477,7 @@ _base_sas_ioc_info(struct MPT2SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply, | |||
394 | 477 | ||
395 | /** | 478 | /** |
396 | * _base_display_event_data - verbose translation of firmware asyn events | 479 | * _base_display_event_data - verbose translation of firmware asyn events |
397 | * @ioc: pointer to scsi command object | 480 | * @ioc: per adapter object |
398 | * @mpi_reply: reply mf payload returned from firmware | 481 | * @mpi_reply: reply mf payload returned from firmware |
399 | * | 482 | * |
400 | * Return nothing. | 483 | * Return nothing. |
@@ -474,7 +557,7 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, | |||
474 | 557 | ||
475 | /** | 558 | /** |
476 | * _base_sas_log_info - verbose translation of firmware log info | 559 | * _base_sas_log_info - verbose translation of firmware log info |
477 | * @ioc: pointer to scsi command object | 560 | * @ioc: per adapter object |
478 | * @log_info: log info | 561 | * @log_info: log info |
479 | * | 562 | * |
480 | * Return nothing. | 563 | * Return nothing. |
@@ -526,22 +609,8 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) | |||
526 | } | 609 | } |
527 | 610 | ||
528 | /** | 611 | /** |
529 | * mpt2sas_base_fault_info - verbose translation of firmware FAULT code | ||
530 | * @ioc: pointer to scsi command object | ||
531 | * @fault_code: fault code | ||
532 | * | ||
533 | * Return nothing. | ||
534 | */ | ||
535 | void | ||
536 | mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code) | ||
537 | { | ||
538 | printk(MPT2SAS_ERR_FMT "fault_state(0x%04x)!\n", | ||
539 | ioc->name, fault_code); | ||
540 | } | ||
541 | |||
542 | /** | ||
543 | * _base_display_reply_info - | 612 | * _base_display_reply_info - |
544 | * @ioc: pointer to scsi command object | 613 | * @ioc: per adapter object |
545 | * @smid: system request message index | 614 | * @smid: system request message index |
546 | * @msix_index: MSIX table index supplied by the OS | 615 | * @msix_index: MSIX table index supplied by the OS |
547 | * @reply: reply message frame(lower 32bit addr) | 616 | * @reply: reply message frame(lower 32bit addr) |
@@ -570,7 +639,7 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
570 | 639 | ||
571 | /** | 640 | /** |
572 | * mpt2sas_base_done - base internal command completion routine | 641 | * mpt2sas_base_done - base internal command completion routine |
573 | * @ioc: pointer to scsi command object | 642 | * @ioc: per adapter object |
574 | * @smid: system request message index | 643 | * @smid: system request message index |
575 | * @msix_index: MSIX table index supplied by the OS | 644 | * @msix_index: MSIX table index supplied by the OS |
576 | * @reply: reply message frame(lower 32bit addr) | 645 | * @reply: reply message frame(lower 32bit addr) |
@@ -603,7 +672,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
603 | 672 | ||
604 | /** | 673 | /** |
605 | * _base_async_event - main callback handler for firmware asyn events | 674 | * _base_async_event - main callback handler for firmware asyn events |
606 | * @ioc: pointer to scsi command object | 675 | * @ioc: per adapter object |
607 | * @msix_index: MSIX table index supplied by the OS | 676 | * @msix_index: MSIX table index supplied by the OS |
608 | * @reply: reply message frame(lower 32bit addr) | 677 | * @reply: reply message frame(lower 32bit addr) |
609 | * | 678 | * |
@@ -684,7 +753,7 @@ _base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
684 | 753 | ||
685 | /** | 754 | /** |
686 | * _base_mask_interrupts - disable interrupts | 755 | * _base_mask_interrupts - disable interrupts |
687 | * @ioc: pointer to scsi command object | 756 | * @ioc: per adapter object |
688 | * | 757 | * |
689 | * Disabling ResetIRQ, Reply and Doorbell Interrupts | 758 | * Disabling ResetIRQ, Reply and Doorbell Interrupts |
690 | * | 759 | * |
@@ -704,7 +773,7 @@ _base_mask_interrupts(struct MPT2SAS_ADAPTER *ioc) | |||
704 | 773 | ||
705 | /** | 774 | /** |
706 | * _base_unmask_interrupts - enable interrupts | 775 | * _base_unmask_interrupts - enable interrupts |
707 | * @ioc: pointer to scsi command object | 776 | * @ioc: per adapter object |
708 | * | 777 | * |
709 | * Enabling only Reply Interrupts | 778 | * Enabling only Reply Interrupts |
710 | * | 779 | * |
@@ -1152,6 +1221,8 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1152 | u32 memap_sz; | 1221 | u32 memap_sz; |
1153 | u32 pio_sz; | 1222 | u32 pio_sz; |
1154 | int i, r = 0; | 1223 | int i, r = 0; |
1224 | u64 pio_chip = 0; | ||
1225 | u64 chip_phys = 0; | ||
1155 | 1226 | ||
1156 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", | 1227 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", |
1157 | ioc->name, __func__)); | 1228 | ioc->name, __func__)); |
@@ -1185,12 +1256,13 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1185 | if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { | 1256 | if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) { |
1186 | if (pio_sz) | 1257 | if (pio_sz) |
1187 | continue; | 1258 | continue; |
1188 | ioc->pio_chip = pci_resource_start(pdev, i); | 1259 | pio_chip = (u64)pci_resource_start(pdev, i); |
1189 | pio_sz = pci_resource_len(pdev, i); | 1260 | pio_sz = pci_resource_len(pdev, i); |
1190 | } else { | 1261 | } else { |
1191 | if (memap_sz) | 1262 | if (memap_sz) |
1192 | continue; | 1263 | continue; |
1193 | ioc->chip_phys = pci_resource_start(pdev, i); | 1264 | ioc->chip_phys = pci_resource_start(pdev, i); |
1265 | chip_phys = (u64)ioc->chip_phys; | ||
1194 | memap_sz = pci_resource_len(pdev, i); | 1266 | memap_sz = pci_resource_len(pdev, i); |
1195 | ioc->chip = ioremap(ioc->chip_phys, memap_sz); | 1267 | ioc->chip = ioremap(ioc->chip_phys, memap_sz); |
1196 | if (ioc->chip == NULL) { | 1268 | if (ioc->chip == NULL) { |
@@ -1210,10 +1282,10 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc) | |||
1210 | printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n", | 1282 | printk(MPT2SAS_INFO_FMT "%s: IRQ %d\n", |
1211 | ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : | 1283 | ioc->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : |
1212 | "IO-APIC enabled"), ioc->pci_irq); | 1284 | "IO-APIC enabled"), ioc->pci_irq); |
1213 | printk(MPT2SAS_INFO_FMT "iomem(0x%lx), mapped(0x%p), size(%d)\n", | 1285 | printk(MPT2SAS_INFO_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n", |
1214 | ioc->name, ioc->chip_phys, ioc->chip, memap_sz); | 1286 | ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz); |
1215 | printk(MPT2SAS_INFO_FMT "ioport(0x%lx), size(%d)\n", | 1287 | printk(MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n", |
1216 | ioc->name, ioc->pio_chip, pio_sz); | 1288 | ioc->name, (unsigned long long)pio_chip, pio_sz); |
1217 | 1289 | ||
1218 | return 0; | 1290 | return 0; |
1219 | 1291 | ||
@@ -1258,12 +1330,13 @@ mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid) | |||
1258 | * @ioc: per adapter object | 1330 | * @ioc: per adapter object |
1259 | * @smid: system request message index | 1331 | * @smid: system request message index |
1260 | * | 1332 | * |
1261 | * Returns phys pointer to sense buffer. | 1333 | * Returns phys pointer to the low 32bit address of the sense buffer. |
1262 | */ | 1334 | */ |
1263 | dma_addr_t | 1335 | __le32 |
1264 | mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) | 1336 | mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid) |
1265 | { | 1337 | { |
1266 | return ioc->sense_dma + ((smid - 1) * SCSI_SENSE_BUFFERSIZE); | 1338 | return cpu_to_le32(ioc->sense_dma + |
1339 | ((smid - 1) * SCSI_SENSE_BUFFERSIZE)); | ||
1267 | } | 1340 | } |
1268 | 1341 | ||
1269 | /** | 1342 | /** |
@@ -1697,6 +1770,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) | |||
1697 | } | 1770 | } |
1698 | 1771 | ||
1699 | if (ioc->facts.IOCCapabilities & | 1772 | if (ioc->facts.IOCCapabilities & |
1773 | MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) { | ||
1774 | printk(KERN_INFO "%sDiag Extended Buffer", i ? "," : ""); | ||
1775 | i++; | ||
1776 | } | ||
1777 | |||
1778 | if (ioc->facts.IOCCapabilities & | ||
1700 | MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { | 1779 | MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING) { |
1701 | printk("%sTask Set Full", i ? "," : ""); | 1780 | printk("%sTask Set Full", i ? "," : ""); |
1702 | i++; | 1781 | i++; |
@@ -2871,6 +2950,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2871 | Mpi2IOCInitRequest_t mpi_request; | 2950 | Mpi2IOCInitRequest_t mpi_request; |
2872 | Mpi2IOCInitReply_t mpi_reply; | 2951 | Mpi2IOCInitReply_t mpi_reply; |
2873 | int r; | 2952 | int r; |
2953 | struct timeval current_time; | ||
2954 | u16 ioc_status; | ||
2874 | 2955 | ||
2875 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 2956 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
2876 | __func__)); | 2957 | __func__)); |
@@ -2921,6 +3002,13 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2921 | cpu_to_le32(ioc->reply_post_free_dma); | 3002 | cpu_to_le32(ioc->reply_post_free_dma); |
2922 | #endif | 3003 | #endif |
2923 | 3004 | ||
3005 | /* This time stamp specifies number of milliseconds | ||
3006 | * since epoch ~ midnight January 1, 1970. | ||
3007 | */ | ||
3008 | do_gettimeofday(¤t_time); | ||
3009 | mpi_request.TimeStamp = (current_time.tv_sec * 1000) + | ||
3010 | (current_time.tv_usec >> 3); | ||
3011 | |||
2924 | if (ioc->logging_level & MPT_DEBUG_INIT) { | 3012 | if (ioc->logging_level & MPT_DEBUG_INIT) { |
2925 | u32 *mfp; | 3013 | u32 *mfp; |
2926 | int i; | 3014 | int i; |
@@ -2943,7 +3031,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2943 | return r; | 3031 | return r; |
2944 | } | 3032 | } |
2945 | 3033 | ||
2946 | if (mpi_reply.IOCStatus != MPI2_IOCSTATUS_SUCCESS || | 3034 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; |
3035 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS || | ||
2947 | mpi_reply.IOCLogInfo) { | 3036 | mpi_reply.IOCLogInfo) { |
2948 | printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__); | 3037 | printk(MPT2SAS_ERR_FMT "%s: failed\n", ioc->name, __func__); |
2949 | r = -EIO; | 3038 | r = -EIO; |
@@ -3461,11 +3550,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3461 | return r; | 3550 | return r; |
3462 | 3551 | ||
3463 | pci_set_drvdata(ioc->pdev, ioc->shost); | 3552 | pci_set_drvdata(ioc->pdev, ioc->shost); |
3464 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); | 3553 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); |
3465 | if (r) | 3554 | if (r) |
3466 | goto out_free_resources; | 3555 | goto out_free_resources; |
3467 | 3556 | ||
3468 | r = _base_get_ioc_facts(ioc, CAN_SLEEP); | 3557 | r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); |
3469 | if (r) | 3558 | if (r) |
3470 | goto out_free_resources; | 3559 | goto out_free_resources; |
3471 | 3560 | ||
@@ -3486,6 +3575,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3486 | 3575 | ||
3487 | init_waitqueue_head(&ioc->reset_wq); | 3576 | init_waitqueue_head(&ioc->reset_wq); |
3488 | 3577 | ||
3578 | ioc->fwfault_debug = mpt2sas_fwfault_debug; | ||
3579 | |||
3489 | /* base internal command bits */ | 3580 | /* base internal command bits */ |
3490 | mutex_init(&ioc->base_cmds.mutex); | 3581 | mutex_init(&ioc->base_cmds.mutex); |
3491 | ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3582 | ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
@@ -3496,6 +3587,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3496 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; | 3587 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; |
3497 | mutex_init(&ioc->transport_cmds.mutex); | 3588 | mutex_init(&ioc->transport_cmds.mutex); |
3498 | 3589 | ||
3590 | /* scsih internal command bits */ | ||
3591 | ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | ||
3592 | ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; | ||
3593 | mutex_init(&ioc->scsih_cmds.mutex); | ||
3594 | |||
3499 | /* task management internal command bits */ | 3595 | /* task management internal command bits */ |
3500 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3596 | ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
3501 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | 3597 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; |
@@ -3531,6 +3627,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3531 | goto out_free_resources; | 3627 | goto out_free_resources; |
3532 | 3628 | ||
3533 | mpt2sas_base_start_watchdog(ioc); | 3629 | mpt2sas_base_start_watchdog(ioc); |
3630 | if (diag_buffer_enable != 0) | ||
3631 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | ||
3534 | return 0; | 3632 | return 0; |
3535 | 3633 | ||
3536 | out_free_resources: | 3634 | out_free_resources: |
@@ -3684,6 +3782,9 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
3684 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, | 3782 | dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, |
3685 | __func__)); | 3783 | __func__)); |
3686 | 3784 | ||
3785 | if (mpt2sas_fwfault_debug) | ||
3786 | mpt2sas_halt_firmware(ioc); | ||
3787 | |||
3687 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 3788 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); |
3688 | if (ioc->shost_recovery) { | 3789 | if (ioc->shost_recovery) { |
3689 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 3790 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |