1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49#include <linux/kernel.h>
50#include <linux/module.h>
51#include <linux/errno.h>
52#include <linux/init.h>
53#include <linux/seq_file.h>
54#include <linux/slab.h>
55#include <linux/types.h>
56#include <linux/pci.h>
57#include <linux/kdev_t.h>
58#include <linux/blkdev.h>
59#include <linux/delay.h>
60#include <linux/interrupt.h>
61#include <linux/dma-mapping.h>
62#include <linux/kthread.h>
63#include <scsi/scsi_host.h>
64
65#include "mptbase.h"
66#include "lsi/mpi_log_fc.h"
67
68
69#define my_NAME "Fusion MPT base driver"
70#define my_VERSION MPT_LINUX_VERSION_COMMON
71#define MYNAM "mptbase"
72
73MODULE_AUTHOR(MODULEAUTHOR);
74MODULE_DESCRIPTION(my_NAME);
75MODULE_LICENSE("GPL");
76MODULE_VERSION(my_VERSION);
77
78
79
80
81
82static int mpt_msi_enable_spi;
83module_param(mpt_msi_enable_spi, int, 0);
84MODULE_PARM_DESC(mpt_msi_enable_spi,
85 " Enable MSI Support for SPI controllers (default=0)");
86
87static int mpt_msi_enable_fc;
88module_param(mpt_msi_enable_fc, int, 0);
89MODULE_PARM_DESC(mpt_msi_enable_fc,
90 " Enable MSI Support for FC controllers (default=0)");
91
92static int mpt_msi_enable_sas;
93module_param(mpt_msi_enable_sas, int, 0);
94MODULE_PARM_DESC(mpt_msi_enable_sas,
95 " Enable MSI Support for SAS controllers (default=0)");
96
97static int mpt_channel_mapping;
98module_param(mpt_channel_mapping, int, 0);
99MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
100
101static int mpt_debug_level;
102static int mpt_set_debug_level(const char *val, const struct kernel_param *kp);
103module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
104 &mpt_debug_level, 0600);
105MODULE_PARM_DESC(mpt_debug_level,
106 " debug level - refer to mptdebug.h - (default=0)");
107
108int mpt_fwfault_debug;
109EXPORT_SYMBOL(mpt_fwfault_debug);
110module_param(mpt_fwfault_debug, int, 0600);
111MODULE_PARM_DESC(mpt_fwfault_debug,
112 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
113
114static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS]
115 [MPT_MAX_CALLBACKNAME_LEN+1];
116
117#ifdef MFCNT
118static int mfcounter = 0;
119#define PRINT_MF_COUNT 20000
120#endif
121
122
123
124
125
126
127#define WHOINIT_UNKNOWN 0xAA
128
129
130
131
132
133
134LIST_HEAD(ioc_list);
135
136static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
137
138static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
139
140static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
141
142static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
143static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
144
145#ifdef CONFIG_PROC_FS
146static struct proc_dir_entry *mpt_proc_root_dir;
147#endif
148
149
150
151
152static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
153static u8 last_drv_idx;
154
155
156
157
158
159static irqreturn_t mpt_interrupt(int irq, void *bus_id);
160static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
161 MPT_FRAME_HDR *reply);
162static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
163 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
164 int sleepFlag);
165static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
166static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
167static void mpt_adapter_disable(MPT_ADAPTER *ioc);
168static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
169
170static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
171static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
172static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
173static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
174static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
175static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
176static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
177static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
178static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
179static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
180static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
181static int PrimeIocFifos(MPT_ADAPTER *ioc);
182static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
183static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
184static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185static int GetLanConfigPages(MPT_ADAPTER *ioc);
186static int GetIoUnitPage2(MPT_ADAPTER *ioc);
187int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
188static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
189static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
190static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
191static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
192static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
193static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
194 int sleepFlag);
195static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
196static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
197static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
198
199#ifdef CONFIG_PROC_FS
200static int mpt_summary_proc_show(struct seq_file *m, void *v);
201static int mpt_version_proc_show(struct seq_file *m, void *v);
202static int mpt_iocinfo_proc_show(struct seq_file *m, void *v);
203#endif
204static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
205
206static int ProcessEventNotification(MPT_ADAPTER *ioc,
207 EventNotificationReply_t *evReply, int *evHandlers);
208static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
209static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
210static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
211static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
212static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
213static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
214
215
216static int __init fusion_init (void);
217static void __exit fusion_exit (void);
218
219#define CHIPREG_READ32(addr) readl_relaxed(addr)
220#define CHIPREG_READ32_dmasync(addr) readl(addr)
221#define CHIPREG_WRITE32(addr,val) writel(val, addr)
222#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
223#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
224
225static void
226pci_disable_io_access(struct pci_dev *pdev)
227{
228 u16 command_reg;
229
230 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
231 command_reg &= ~1;
232 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
233}
234
235static void
236pci_enable_io_access(struct pci_dev *pdev)
237{
238 u16 command_reg;
239
240 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
241 command_reg |= 1;
242 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
243}
244
245static int mpt_set_debug_level(const char *val, const struct kernel_param *kp)
246{
247 int ret = param_set_int(val, kp);
248 MPT_ADAPTER *ioc;
249
250 if (ret)
251 return ret;
252
253 list_for_each_entry(ioc, &ioc_list, list)
254 ioc->debug_level = mpt_debug_level;
255 return 0;
256}
257
258
259
260
261
262
263
264static u8
265mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
266{
267 u8 cb_idx;
268
269 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
270 if (MptDriverClass[cb_idx] == dclass)
271 return cb_idx;
272 return 0;
273}
274
275
276
277
278
279
280
281static int
282mpt_is_discovery_complete(MPT_ADAPTER *ioc)
283{
284 ConfigExtendedPageHeader_t hdr;
285 CONFIGPARMS cfg;
286 SasIOUnitPage0_t *buffer;
287 dma_addr_t dma_handle;
288 int rc = 0;
289
290 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
291 memset(&cfg, 0, sizeof(CONFIGPARMS));
292 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
293 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
294 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
295 cfg.cfghdr.ehdr = &hdr;
296 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
297
298 if ((mpt_config(ioc, &cfg)))
299 goto out;
300 if (!hdr.ExtPageLength)
301 goto out;
302
303 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
304 &dma_handle);
305 if (!buffer)
306 goto out;
307
308 cfg.physAddr = dma_handle;
309 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
310
311 if ((mpt_config(ioc, &cfg)))
312 goto out_free_consistent;
313
314 if (!(buffer->PhyData[0].PortFlags &
315 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
316 rc = 1;
317
318 out_free_consistent:
319 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
320 buffer, dma_handle);
321 out:
322 return rc;
323}
324
325
326
327
328
329
330
331
332
333static int mpt_remove_dead_ioc_func(void *arg)
334{
335 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
336 struct pci_dev *pdev;
337
338 if (!ioc)
339 return -1;
340
341 pdev = ioc->pcidev;
342 if (!pdev)
343 return -1;
344
345 pci_stop_and_remove_bus_device_locked(pdev);
346 return 0;
347}
348
349
350
351
352
353
354
355
356static void
357mpt_fault_reset_work(struct work_struct *work)
358{
359 MPT_ADAPTER *ioc =
360 container_of(work, MPT_ADAPTER, fault_reset_work.work);
361 u32 ioc_raw_state;
362 int rc;
363 unsigned long flags;
364 MPT_SCSI_HOST *hd;
365 struct task_struct *p;
366
367 if (ioc->ioc_reset_in_progress || !ioc->active)
368 goto out;
369
370
371 ioc_raw_state = mpt_GetIocState(ioc, 0);
372 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
373 printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
374 ioc->name, __func__);
375
376
377
378
379
380
381
382
383 hd = shost_priv(ioc->sh);
384 ioc->schedule_dead_ioc_flush_running_cmds(hd);
385
386
387 p = kthread_run(mpt_remove_dead_ioc_func, ioc,
388 "mpt_dead_ioc_%d", ioc->id);
389 if (IS_ERR(p)) {
390 printk(MYIOC_s_ERR_FMT
391 "%s: Running mpt_dead_ioc thread failed !\n",
392 ioc->name, __func__);
393 } else {
394 printk(MYIOC_s_WARN_FMT
395 "%s: Running mpt_dead_ioc thread success !\n",
396 ioc->name, __func__);
397 }
398 return;
399 }
400
401 if ((ioc_raw_state & MPI_IOC_STATE_MASK)
402 == MPI_IOC_STATE_FAULT) {
403 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
404 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
405 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
406 ioc->name, __func__);
407 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
408 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
409 __func__, (rc == 0) ? "success" : "failed");
410 ioc_raw_state = mpt_GetIocState(ioc, 0);
411 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
412 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
413 "reset (%04xh)\n", ioc->name, ioc_raw_state &
414 MPI_DOORBELL_DATA_MASK);
415 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
416 if ((mpt_is_discovery_complete(ioc))) {
417 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
418 "discovery_quiesce_io flag\n", ioc->name));
419 ioc->sas_discovery_quiesce_io = 0;
420 }
421 }
422
423 out:
424
425
426
427 if (ioc->alt_ioc)
428 ioc = ioc->alt_ioc;
429
430
431 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
432 if (ioc->reset_work_q)
433 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
434 msecs_to_jiffies(MPT_POLLING_INTERVAL));
435 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
436}
437
438
439
440
441
442static void
443mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
444{
445 MPT_FRAME_HDR *mf = NULL;
446 MPT_FRAME_HDR *mr = NULL;
447 u16 req_idx = 0;
448 u8 cb_idx;
449
450 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
451 ioc->name, pa));
452
453 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
454 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
455 req_idx = pa & 0x0000FFFF;
456 cb_idx = (pa & 0x00FF0000) >> 16;
457 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
458 break;
459 case MPI_CONTEXT_REPLY_TYPE_LAN:
460 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
461
462
463
464
465
466
467
468
469
470 if ((pa & 0x58000000) == 0x58000000) {
471 req_idx = pa & 0x0000FFFF;
472 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
473 mpt_free_msg_frame(ioc, mf);
474 mb();
475 return;
476 }
477 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
478 break;
479 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
480 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
481 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
482 break;
483 default:
484 cb_idx = 0;
485 BUG();
486 }
487
488
489 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
490 MptCallbacks[cb_idx] == NULL) {
491 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
492 __func__, ioc->name, cb_idx);
493 goto out;
494 }
495
496 if (MptCallbacks[cb_idx](ioc, mf, mr))
497 mpt_free_msg_frame(ioc, mf);
498 out:
499 mb();
500}
501
502static void
503mpt_reply(MPT_ADAPTER *ioc, u32 pa)
504{
505 MPT_FRAME_HDR *mf;
506 MPT_FRAME_HDR *mr;
507 u16 req_idx;
508 u8 cb_idx;
509 int freeme;
510
511 u32 reply_dma_low;
512 u16 ioc_stat;
513
514
515
516
517
518
519
520
521
522
523
524 reply_dma_low = (pa <<= 1);
525 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
526 (reply_dma_low - ioc->reply_frames_low_dma));
527
528 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
529 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
530 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
531
532 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
533 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
534 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
535
536
537
538 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
539 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
540 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
541 if (ioc->bus_type == FC)
542 mpt_fc_log_info(ioc, log_info);
543 else if (ioc->bus_type == SPI)
544 mpt_spi_log_info(ioc, log_info);
545 else if (ioc->bus_type == SAS)
546 mpt_sas_log_info(ioc, log_info, cb_idx);
547 }
548
549 if (ioc_stat & MPI_IOCSTATUS_MASK)
550 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
551
552
553 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
554 MptCallbacks[cb_idx] == NULL) {
555 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
556 __func__, ioc->name, cb_idx);
557 freeme = 0;
558 goto out;
559 }
560
561 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
562
563 out:
564
565 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
566
567 if (freeme)
568 mpt_free_msg_frame(ioc, mf);
569 mb();
570}
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589static irqreturn_t
590mpt_interrupt(int irq, void *bus_id)
591{
592 MPT_ADAPTER *ioc = bus_id;
593 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
594
595 if (pa == 0xFFFFFFFF)
596 return IRQ_NONE;
597
598
599
600
601 do {
602 if (pa & MPI_ADDRESS_REPLY_A_BIT)
603 mpt_reply(ioc, pa);
604 else
605 mpt_turbo_reply(ioc, pa);
606 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
607 } while (pa != 0xFFFFFFFF);
608
609 return IRQ_HANDLED;
610}
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626static int
627mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
628{
629 EventNotificationReply_t *pEventReply;
630 u8 event;
631 int evHandlers;
632 int freereq = 1;
633
634 switch (reply->u.hdr.Function) {
635 case MPI_FUNCTION_EVENT_NOTIFICATION:
636 pEventReply = (EventNotificationReply_t *)reply;
637 evHandlers = 0;
638 ProcessEventNotification(ioc, pEventReply, &evHandlers);
639 event = le32_to_cpu(pEventReply->Event) & 0xFF;
640 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
641 freereq = 0;
642 if (event != MPI_EVENT_EVENT_CHANGE)
643 break;
644 fallthrough;
645 case MPI_FUNCTION_CONFIG:
646 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
647 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
648 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
649 memcpy(ioc->mptbase_cmds.reply, reply,
650 min(MPT_DEFAULT_FRAME_SIZE,
651 4 * reply->u.reply.MsgLength));
652 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
653 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
654 complete(&ioc->mptbase_cmds.done);
655 } else
656 freereq = 0;
657 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
658 freereq = 1;
659 break;
660 case MPI_FUNCTION_EVENT_ACK:
661 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
662 "EventAck reply received\n", ioc->name));
663 break;
664 default:
665 printk(MYIOC_s_ERR_FMT
666 "Unexpected msg function (=%02Xh) reply received!\n",
667 ioc->name, reply->u.hdr.Function);
668 break;
669 }
670
671
672
673
674
675 return freereq;
676}
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699u8
700mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
701{
702 u8 cb_idx;
703 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
704
705
706
707
708
709 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
710 if (MptCallbacks[cb_idx] == NULL) {
711 MptCallbacks[cb_idx] = cbfunc;
712 MptDriverClass[cb_idx] = dclass;
713 MptEvHandlers[cb_idx] = NULL;
714 last_drv_idx = cb_idx;
715 strlcpy(MptCallbacksName[cb_idx], func_name,
716 MPT_MAX_CALLBACKNAME_LEN+1);
717 break;
718 }
719 }
720
721 return last_drv_idx;
722}
723
724
725
726
727
728
729
730
731
732void
733mpt_deregister(u8 cb_idx)
734{
735 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
736 MptCallbacks[cb_idx] = NULL;
737 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
738 MptEvHandlers[cb_idx] = NULL;
739
740 last_drv_idx++;
741 }
742}
743
744
745
746
747
748
749
750
751
752
753
754
755int
756mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
757{
758 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
759 return -1;
760
761 MptEvHandlers[cb_idx] = ev_cbfunc;
762 return 0;
763}
764
765
766
767
768
769
770
771
772
773
774void
775mpt_event_deregister(u8 cb_idx)
776{
777 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
778 return;
779
780 MptEvHandlers[cb_idx] = NULL;
781}
782
783
784
785
786
787
788
789
790
791
792
793
794int
795mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
796{
797 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
798 return -1;
799
800 MptResetHandlers[cb_idx] = reset_func;
801 return 0;
802}
803
804
805
806
807
808
809
810
811
812
813void
814mpt_reset_deregister(u8 cb_idx)
815{
816 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
817 return;
818
819 MptResetHandlers[cb_idx] = NULL;
820}
821
822
823
824
825
826
827
828int
829mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
830{
831 MPT_ADAPTER *ioc;
832
833 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
834 return -EINVAL;
835
836 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
837
838
839 list_for_each_entry(ioc, &ioc_list, list) {
840 if (dd_cbfunc->probe)
841 dd_cbfunc->probe(ioc->pcidev);
842 }
843
844 return 0;
845}
846
847
848
849
850
851
852void
853mpt_device_driver_deregister(u8 cb_idx)
854{
855 struct mpt_pci_driver *dd_cbfunc;
856 MPT_ADAPTER *ioc;
857
858 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
859 return;
860
861 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
862
863 list_for_each_entry(ioc, &ioc_list, list) {
864 if (dd_cbfunc->remove)
865 dd_cbfunc->remove(ioc->pcidev);
866 }
867
868 MptDeviceDriverHandlers[cb_idx] = NULL;
869}
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884MPT_FRAME_HDR*
885mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
886{
887 MPT_FRAME_HDR *mf;
888 unsigned long flags;
889 u16 req_idx;
890
891
892
893#ifdef MFCNT
894 if (!ioc->active)
895 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
896 "returning NULL!\n", ioc->name);
897#endif
898
899
900 if (!ioc->active)
901 return NULL;
902
903 spin_lock_irqsave(&ioc->FreeQlock, flags);
904 if (!list_empty(&ioc->FreeQ)) {
905 int req_offset;
906
907 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
908 u.frame.linkage.list);
909 list_del(&mf->u.frame.linkage.list);
910 mf->u.frame.linkage.arg1 = 0;
911 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
912 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
913
914 req_idx = req_offset / ioc->req_sz;
915 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
916 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
917
918 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
919#ifdef MFCNT
920 ioc->mfcnt++;
921#endif
922 }
923 else
924 mf = NULL;
925 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
926
927#ifdef MFCNT
928 if (mf == NULL)
929 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
930 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
931 ioc->req_depth);
932 mfcounter++;
933 if (mfcounter == PRINT_MF_COUNT)
934 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
935 ioc->mfcnt, ioc->req_depth);
936#endif
937
938 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
939 ioc->name, cb_idx, ioc->id, mf));
940 return mf;
941}
942
943
944
945
946
947
948
949
950
951
952
953void
954mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
955{
956 u32 mf_dma_addr;
957 int req_offset;
958 u16 req_idx;
959
960
961 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
962 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
963
964 req_idx = req_offset / ioc->req_sz;
965 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
966 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
967
968 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
969
970 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
971 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
972 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
973 ioc->RequestNB[req_idx]));
974 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
975}
976
977
978
979
980
981
982
983
984
985
986
987
988
989void
990mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
991{
992 u32 mf_dma_addr;
993 int req_offset;
994 u16 req_idx;
995
996
997 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
998 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
999 req_idx = req_offset / ioc->req_sz;
1000 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1001 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1002
1003 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1004
1005 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1006 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1007 ioc->name, mf_dma_addr, req_idx));
1008 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1009}
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020void
1021mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1022{
1023 unsigned long flags;
1024
1025
1026 spin_lock_irqsave(&ioc->FreeQlock, flags);
1027 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
1028 goto out;
1029
1030 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
1031 list_add(&mf->u.frame.linkage.list, &ioc->FreeQ);
1032#ifdef MFCNT
1033 ioc->mfcnt--;
1034#endif
1035 out:
1036 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1037}
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049static void
1050mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1051{
1052 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1053 pSge->FlagsLength = cpu_to_le32(flagslength);
1054 pSge->Address = cpu_to_le32(dma_addr);
1055}
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066static void
1067mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1068{
1069 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1070 pSge->Address.Low = cpu_to_le32
1071 (lower_32_bits(dma_addr));
1072 pSge->Address.High = cpu_to_le32
1073 (upper_32_bits(dma_addr));
1074 pSge->FlagsLength = cpu_to_le32
1075 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1076}
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087static void
1088mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1089{
1090 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1091 u32 tmp;
1092
1093 pSge->Address.Low = cpu_to_le32
1094 (lower_32_bits(dma_addr));
1095 tmp = (u32)(upper_32_bits(dma_addr));
1096
1097
1098
1099
1100 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1101 flagslength |=
1102 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1103 tmp |= (1<<31);
1104 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1105 printk(KERN_DEBUG "1078 P0M2 addressing for "
1106 "addr = 0x%llx len = %d\n",
1107 (unsigned long long)dma_addr,
1108 MPI_SGE_LENGTH(flagslength));
1109 }
1110
1111 pSge->Address.High = cpu_to_le32(tmp);
1112 pSge->FlagsLength = cpu_to_le32(
1113 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1114}
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125static void
1126mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1127{
1128 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1129
1130 pChain->Length = cpu_to_le16(length);
1131 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1132 pChain->NextChainOffset = next;
1133 pChain->Address = cpu_to_le32(dma_addr);
1134}
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145static void
1146mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1147{
1148 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1149 u32 tmp = dma_addr & 0xFFFFFFFF;
1150
1151 pChain->Length = cpu_to_le16(length);
1152 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1153 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1154
1155 pChain->NextChainOffset = next;
1156
1157 pChain->Address.Low = cpu_to_le32(tmp);
1158 tmp = (u32)(upper_32_bits(dma_addr));
1159 pChain->Address.High = cpu_to_le32(tmp);
1160}
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179int
1180mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1181{
1182 int r = 0;
1183 u8 *req_as_bytes;
1184 int ii;
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1197 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1198 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1199 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1200 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1201 }
1202
1203
1204 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1205
1206 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1207 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1208 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1209
1210
1211 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1212 return ii;
1213 }
1214
1215
1216 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1217 return -5;
1218
1219 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1220 ioc->name, ii));
1221
1222 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1223
1224 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1225 return -2;
1226 }
1227
1228
1229 req_as_bytes = (u8 *) req;
1230 for (ii = 0; ii < reqBytes/4; ii++) {
1231 u32 word;
1232
1233 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1234 (req_as_bytes[(ii*4) + 1] << 8) |
1235 (req_as_bytes[(ii*4) + 2] << 16) |
1236 (req_as_bytes[(ii*4) + 3] << 24));
1237 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1238 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1239 r = -3;
1240 break;
1241 }
1242 }
1243
1244 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1245 r = 0;
1246 else
1247 r = -4;
1248
1249
1250 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1251
1252 return r;
1253}
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274static int
1275mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1276{
1277 int r = 0;
1278
1279
1280 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1281 & MPI_DOORBELL_ACTIVE)
1282 return -1;
1283
1284 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1285
1286 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1287 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1288 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1289 (access_control_value<<12)));
1290
1291
1292 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1293 return -2;
1294 }else
1295 return 0;
1296}
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307static int
1308mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1309{
1310 char *psge;
1311 int flags_length;
1312 u32 host_page_buffer_sz=0;
1313
1314 if(!ioc->HostPageBuffer) {
1315
1316 host_page_buffer_sz =
1317 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1318
1319 if(!host_page_buffer_sz)
1320 return 0;
1321
1322
1323 while (host_page_buffer_sz > 0) {
1324 ioc->HostPageBuffer =
1325 dma_alloc_coherent(&ioc->pcidev->dev,
1326 host_page_buffer_sz,
1327 &ioc->HostPageBuffer_dma,
1328 GFP_KERNEL);
1329 if (ioc->HostPageBuffer) {
1330 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1331 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1332 ioc->name, ioc->HostPageBuffer,
1333 (u32)ioc->HostPageBuffer_dma,
1334 host_page_buffer_sz));
1335 ioc->alloc_total += host_page_buffer_sz;
1336 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1337 break;
1338 }
1339
1340 host_page_buffer_sz -= (4*1024);
1341 }
1342 }
1343
1344 if(!ioc->HostPageBuffer) {
1345 printk(MYIOC_s_ERR_FMT
1346 "Failed to alloc memory for host_page_buffer!\n",
1347 ioc->name);
1348 return -999;
1349 }
1350
1351 psge = (char *)&ioc_init->HostPageBufferSGE;
1352 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1353 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1354 MPI_SGE_FLAGS_HOST_TO_IOC |
1355 MPI_SGE_FLAGS_END_OF_BUFFER;
1356 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1357 flags_length |= ioc->HostPageBuffer_sz;
1358 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1359 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1360
1361 return 0;
1362}
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376int
1377mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1378{
1379 MPT_ADAPTER *ioc;
1380
1381 list_for_each_entry(ioc,&ioc_list,list) {
1382 if (ioc->id == iocid) {
1383 *iocpp =ioc;
1384 return iocid;
1385 }
1386 }
1387
1388 *iocpp = NULL;
1389 return -1;
1390}
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402static const char*
1403mpt_get_product_name(u16 vendor, u16 device, u8 revision)
1404{
1405 char *product_str = NULL;
1406
1407 if (vendor == PCI_VENDOR_ID_BROCADE) {
1408 switch (device)
1409 {
1410 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1411 switch (revision)
1412 {
1413 case 0x00:
1414 product_str = "BRE040 A0";
1415 break;
1416 case 0x01:
1417 product_str = "BRE040 A1";
1418 break;
1419 default:
1420 product_str = "BRE040";
1421 break;
1422 }
1423 break;
1424 }
1425 goto out;
1426 }
1427
1428 switch (device)
1429 {
1430 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1431 product_str = "LSIFC909 B1";
1432 break;
1433 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1434 product_str = "LSIFC919 B0";
1435 break;
1436 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1437 product_str = "LSIFC929 B0";
1438 break;
1439 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1440 if (revision < 0x80)
1441 product_str = "LSIFC919X A0";
1442 else
1443 product_str = "LSIFC919XL A1";
1444 break;
1445 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1446 if (revision < 0x80)
1447 product_str = "LSIFC929X A0";
1448 else
1449 product_str = "LSIFC929XL A1";
1450 break;
1451 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1452 product_str = "LSIFC939X A1";
1453 break;
1454 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1455 product_str = "LSIFC949X A1";
1456 break;
1457 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1458 switch (revision)
1459 {
1460 case 0x00:
1461 product_str = "LSIFC949E A0";
1462 break;
1463 case 0x01:
1464 product_str = "LSIFC949E A1";
1465 break;
1466 default:
1467 product_str = "LSIFC949E";
1468 break;
1469 }
1470 break;
1471 case MPI_MANUFACTPAGE_DEVID_53C1030:
1472 switch (revision)
1473 {
1474 case 0x00:
1475 product_str = "LSI53C1030 A0";
1476 break;
1477 case 0x01:
1478 product_str = "LSI53C1030 B0";
1479 break;
1480 case 0x03:
1481 product_str = "LSI53C1030 B1";
1482 break;
1483 case 0x07:
1484 product_str = "LSI53C1030 B2";
1485 break;
1486 case 0x08:
1487 product_str = "LSI53C1030 C0";
1488 break;
1489 case 0x80:
1490 product_str = "LSI53C1030T A0";
1491 break;
1492 case 0x83:
1493 product_str = "LSI53C1030T A2";
1494 break;
1495 case 0x87:
1496 product_str = "LSI53C1030T A3";
1497 break;
1498 case 0xc1:
1499 product_str = "LSI53C1020A A1";
1500 break;
1501 default:
1502 product_str = "LSI53C1030";
1503 break;
1504 }
1505 break;
1506 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1507 switch (revision)
1508 {
1509 case 0x03:
1510 product_str = "LSI53C1035 A2";
1511 break;
1512 case 0x04:
1513 product_str = "LSI53C1035 B0";
1514 break;
1515 default:
1516 product_str = "LSI53C1035";
1517 break;
1518 }
1519 break;
1520 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1521 switch (revision)
1522 {
1523 case 0x00:
1524 product_str = "LSISAS1064 A1";
1525 break;
1526 case 0x01:
1527 product_str = "LSISAS1064 A2";
1528 break;
1529 case 0x02:
1530 product_str = "LSISAS1064 A3";
1531 break;
1532 case 0x03:
1533 product_str = "LSISAS1064 A4";
1534 break;
1535 default:
1536 product_str = "LSISAS1064";
1537 break;
1538 }
1539 break;
1540 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1541 switch (revision)
1542 {
1543 case 0x00:
1544 product_str = "LSISAS1064E A0";
1545 break;
1546 case 0x01:
1547 product_str = "LSISAS1064E B0";
1548 break;
1549 case 0x02:
1550 product_str = "LSISAS1064E B1";
1551 break;
1552 case 0x04:
1553 product_str = "LSISAS1064E B2";
1554 break;
1555 case 0x08:
1556 product_str = "LSISAS1064E B3";
1557 break;
1558 default:
1559 product_str = "LSISAS1064E";
1560 break;
1561 }
1562 break;
1563 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1564 switch (revision)
1565 {
1566 case 0x00:
1567 product_str = "LSISAS1068 A0";
1568 break;
1569 case 0x01:
1570 product_str = "LSISAS1068 B0";
1571 break;
1572 case 0x02:
1573 product_str = "LSISAS1068 B1";
1574 break;
1575 default:
1576 product_str = "LSISAS1068";
1577 break;
1578 }
1579 break;
1580 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1581 switch (revision)
1582 {
1583 case 0x00:
1584 product_str = "LSISAS1068E A0";
1585 break;
1586 case 0x01:
1587 product_str = "LSISAS1068E B0";
1588 break;
1589 case 0x02:
1590 product_str = "LSISAS1068E B1";
1591 break;
1592 case 0x04:
1593 product_str = "LSISAS1068E B2";
1594 break;
1595 case 0x08:
1596 product_str = "LSISAS1068E B3";
1597 break;
1598 default:
1599 product_str = "LSISAS1068E";
1600 break;
1601 }
1602 break;
1603 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1604 switch (revision)
1605 {
1606 case 0x00:
1607 product_str = "LSISAS1078 A0";
1608 break;
1609 case 0x01:
1610 product_str = "LSISAS1078 B0";
1611 break;
1612 case 0x02:
1613 product_str = "LSISAS1078 C0";
1614 break;
1615 case 0x03:
1616 product_str = "LSISAS1078 C1";
1617 break;
1618 case 0x04:
1619 product_str = "LSISAS1078 C2";
1620 break;
1621 default:
1622 product_str = "LSISAS1078";
1623 break;
1624 }
1625 break;
1626 }
1627
1628 out:
1629 return product_str;
1630}
1631
1632
1633
1634
1635
1636
1637static int
1638mpt_mapresources(MPT_ADAPTER *ioc)
1639{
1640 u8 __iomem *mem;
1641 int ii;
1642 resource_size_t mem_phys;
1643 unsigned long port;
1644 u32 msize;
1645 u32 psize;
1646 int r = -ENODEV;
1647 struct pci_dev *pdev;
1648
1649 pdev = ioc->pcidev;
1650 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1651 if (pci_enable_device_mem(pdev)) {
1652 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1653 "failed\n", ioc->name);
1654 return r;
1655 }
1656 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1657 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1658 "MEM failed\n", ioc->name);
1659 goto out_pci_disable_device;
1660 }
1661
1662 if (sizeof(dma_addr_t) > 4) {
1663 const uint64_t required_mask = dma_get_required_mask
1664 (&pdev->dev);
1665 if (required_mask > DMA_BIT_MASK(32)
1666 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1667 && !pci_set_consistent_dma_mask(pdev,
1668 DMA_BIT_MASK(64))) {
1669 ioc->dma_mask = DMA_BIT_MASK(64);
1670 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1671 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1672 ioc->name));
1673 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1674 && !pci_set_consistent_dma_mask(pdev,
1675 DMA_BIT_MASK(32))) {
1676 ioc->dma_mask = DMA_BIT_MASK(32);
1677 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1678 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1679 ioc->name));
1680 } else {
1681 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1682 ioc->name, pci_name(pdev));
1683 goto out_pci_release_region;
1684 }
1685 } else {
1686 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1687 && !pci_set_consistent_dma_mask(pdev,
1688 DMA_BIT_MASK(32))) {
1689 ioc->dma_mask = DMA_BIT_MASK(32);
1690 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1691 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1692 ioc->name));
1693 } else {
1694 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1695 ioc->name, pci_name(pdev));
1696 goto out_pci_release_region;
1697 }
1698 }
1699
1700 mem_phys = msize = 0;
1701 port = psize = 0;
1702 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1703 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1704 if (psize)
1705 continue;
1706
1707 port = pci_resource_start(pdev, ii);
1708 psize = pci_resource_len(pdev, ii);
1709 } else {
1710 if (msize)
1711 continue;
1712
1713 mem_phys = pci_resource_start(pdev, ii);
1714 msize = pci_resource_len(pdev, ii);
1715 }
1716 }
1717 ioc->mem_size = msize;
1718
1719 mem = NULL;
1720
1721
1722 mem = ioremap(mem_phys, msize);
1723 if (mem == NULL) {
1724 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1725 " memory!\n", ioc->name);
1726 r = -EINVAL;
1727 goto out_pci_release_region;
1728 }
1729 ioc->memmap = mem;
1730 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1731 ioc->name, mem, (unsigned long long)mem_phys));
1732
1733 ioc->mem_phys = mem_phys;
1734 ioc->chip = (SYSIF_REGS __iomem *)mem;
1735
1736
1737 ioc->pio_mem_phys = port;
1738 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1739
1740 return 0;
1741
1742out_pci_release_region:
1743 pci_release_selected_regions(pdev, ioc->bars);
1744out_pci_disable_device:
1745 pci_disable_device(pdev);
1746 return r;
1747}
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767int
1768mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1769{
1770 MPT_ADAPTER *ioc;
1771 u8 cb_idx;
1772 int r = -ENODEV;
1773 u8 pcixcmd;
1774 static int mpt_ids = 0;
1775#ifdef CONFIG_PROC_FS
1776 struct proc_dir_entry *dent;
1777#endif
1778
1779 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
1780 if (ioc == NULL) {
1781 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1782 return -ENOMEM;
1783 }
1784
1785 ioc->id = mpt_ids++;
1786 sprintf(ioc->name, "ioc%d", ioc->id);
1787 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1788
1789
1790
1791
1792
1793
1794 ioc->debug_level = mpt_debug_level;
1795 if (mpt_debug_level)
1796 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1797
1798 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1799
1800 ioc->pcidev = pdev;
1801 if (mpt_mapresources(ioc)) {
1802 goto out_free_ioc;
1803 }
1804
1805
1806
1807
1808 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1809 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1810 ioc->add_sge = &mpt_add_sge_64bit_1078;
1811 else
1812 ioc->add_sge = &mpt_add_sge_64bit;
1813 ioc->add_chain = &mpt_add_chain_64bit;
1814 ioc->sg_addr_size = 8;
1815 } else {
1816 ioc->add_sge = &mpt_add_sge;
1817 ioc->add_chain = &mpt_add_chain;
1818 ioc->sg_addr_size = 4;
1819 }
1820 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1821
1822 ioc->alloc_total = sizeof(MPT_ADAPTER);
1823 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;
1824 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1825
1826
1827 spin_lock_init(&ioc->taskmgmt_lock);
1828 mutex_init(&ioc->internal_cmds.mutex);
1829 init_completion(&ioc->internal_cmds.done);
1830 mutex_init(&ioc->mptbase_cmds.mutex);
1831 init_completion(&ioc->mptbase_cmds.done);
1832 mutex_init(&ioc->taskmgmt_cmds.mutex);
1833 init_completion(&ioc->taskmgmt_cmds.done);
1834
1835
1836
1837 ioc->eventTypes = 0;
1838 ioc->eventContext = 0;
1839 ioc->eventLogSize = 0;
1840 ioc->events = NULL;
1841
1842#ifdef MFCNT
1843 ioc->mfcnt = 0;
1844#endif
1845
1846 ioc->sh = NULL;
1847 ioc->cached_fw = NULL;
1848
1849
1850
1851 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1852
1853
1854
1855 INIT_LIST_HEAD(&ioc->fc_rports);
1856
1857
1858 INIT_LIST_HEAD(&ioc->list);
1859
1860
1861
1862 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1863
1864 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1865 "mpt_poll_%d", ioc->id);
1866 ioc->reset_work_q = alloc_workqueue(ioc->reset_work_q_name,
1867 WQ_MEM_RECLAIM, 0);
1868 if (!ioc->reset_work_q) {
1869 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1870 ioc->name);
1871 r = -ENOMEM;
1872 goto out_unmap_resources;
1873 }
1874
1875 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1876 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1877
1878 ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
1879 pdev->revision);
1880
1881 switch (pdev->device)
1882 {
1883 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1884 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1885 ioc->errata_flag_1064 = 1;
1886 fallthrough;
1887 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1888 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1889 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1890 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1891 ioc->bus_type = FC;
1892 break;
1893
1894 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1895 if (pdev->revision < XL_929) {
1896
1897
1898
1899 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1900 pcixcmd &= 0x8F;
1901 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1902 } else {
1903
1904
1905 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1906 pcixcmd |= 0x08;
1907 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1908 }
1909 ioc->bus_type = FC;
1910 break;
1911
1912 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1913
1914
1915
1916 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1917 pcixcmd &= 0x8F;
1918 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1919 ioc->bus_type = FC;
1920 break;
1921
1922 case MPI_MANUFACTPAGE_DEVID_53C1030:
1923
1924
1925
1926 if (pdev->revision < C0_1030) {
1927 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1928 pcixcmd &= 0x8F;
1929 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1930 }
1931 fallthrough;
1932
1933 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1934 ioc->bus_type = SPI;
1935 break;
1936
1937 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1938 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1939 ioc->errata_flag_1064 = 1;
1940 ioc->bus_type = SAS;
1941 break;
1942
1943 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1944 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1945 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1946 ioc->bus_type = SAS;
1947 break;
1948 }
1949
1950
1951 switch (ioc->bus_type) {
1952
1953 case SAS:
1954 ioc->msi_enable = mpt_msi_enable_sas;
1955 break;
1956
1957 case SPI:
1958 ioc->msi_enable = mpt_msi_enable_spi;
1959 break;
1960
1961 case FC:
1962 ioc->msi_enable = mpt_msi_enable_fc;
1963 break;
1964
1965 default:
1966 ioc->msi_enable = 0;
1967 break;
1968 }
1969
1970 ioc->fw_events_off = 1;
1971
1972 if (ioc->errata_flag_1064)
1973 pci_disable_io_access(pdev);
1974
1975 spin_lock_init(&ioc->FreeQlock);
1976
1977
1978 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1979 ioc->active = 0;
1980 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1981
1982
1983 pci_set_drvdata(ioc->pcidev, ioc);
1984
1985
1986 list_add_tail(&ioc->list, &ioc_list);
1987
1988
1989
1990 mpt_detect_bound_ports(ioc, pdev);
1991
1992 INIT_LIST_HEAD(&ioc->fw_event_list);
1993 spin_lock_init(&ioc->fw_event_lock);
1994 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1995 ioc->fw_event_q = alloc_workqueue(ioc->fw_event_q_name,
1996 WQ_MEM_RECLAIM, 0);
1997 if (!ioc->fw_event_q) {
1998 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1999 ioc->name);
2000 r = -ENOMEM;
2001 goto out_remove_ioc;
2002 }
2003
2004 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2005 CAN_SLEEP)) != 0){
2006 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2007 ioc->name, r);
2008
2009 destroy_workqueue(ioc->fw_event_q);
2010 ioc->fw_event_q = NULL;
2011
2012 list_del(&ioc->list);
2013 if (ioc->alt_ioc)
2014 ioc->alt_ioc->alt_ioc = NULL;
2015 iounmap(ioc->memmap);
2016 if (pci_is_enabled(pdev))
2017 pci_disable_device(pdev);
2018 if (r != -5)
2019 pci_release_selected_regions(pdev, ioc->bars);
2020
2021 destroy_workqueue(ioc->reset_work_q);
2022 ioc->reset_work_q = NULL;
2023
2024 kfree(ioc);
2025 return r;
2026 }
2027
2028
2029 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2030 if(MptDeviceDriverHandlers[cb_idx] &&
2031 MptDeviceDriverHandlers[cb_idx]->probe) {
2032 MptDeviceDriverHandlers[cb_idx]->probe(pdev);
2033 }
2034 }
2035
2036#ifdef CONFIG_PROC_FS
2037
2038
2039
2040 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2041 if (dent) {
2042 proc_create_single_data("info", S_IRUGO, dent,
2043 mpt_iocinfo_proc_show, ioc);
2044 proc_create_single_data("summary", S_IRUGO, dent,
2045 mpt_summary_proc_show, ioc);
2046 }
2047#endif
2048
2049 if (!ioc->alt_ioc)
2050 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2051 msecs_to_jiffies(MPT_POLLING_INTERVAL));
2052
2053 return 0;
2054
2055out_remove_ioc:
2056 list_del(&ioc->list);
2057 if (ioc->alt_ioc)
2058 ioc->alt_ioc->alt_ioc = NULL;
2059
2060 destroy_workqueue(ioc->reset_work_q);
2061 ioc->reset_work_q = NULL;
2062
2063out_unmap_resources:
2064 iounmap(ioc->memmap);
2065 pci_disable_device(pdev);
2066 pci_release_selected_regions(pdev, ioc->bars);
2067
2068out_free_ioc:
2069 kfree(ioc);
2070
2071 return r;
2072}
2073
2074
2075
2076
2077
2078
2079
2080void
2081mpt_detach(struct pci_dev *pdev)
2082{
2083 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2084 char pname[64];
2085 u8 cb_idx;
2086 unsigned long flags;
2087 struct workqueue_struct *wq;
2088
2089
2090
2091
2092 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2093 wq = ioc->reset_work_q;
2094 ioc->reset_work_q = NULL;
2095 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2096 cancel_delayed_work(&ioc->fault_reset_work);
2097 destroy_workqueue(wq);
2098
2099 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2100 wq = ioc->fw_event_q;
2101 ioc->fw_event_q = NULL;
2102 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2103 destroy_workqueue(wq);
2104
2105 snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2106 remove_proc_entry(pname, NULL);
2107 snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2108 remove_proc_entry(pname, NULL);
2109 snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2110 remove_proc_entry(pname, NULL);
2111
2112
2113 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2114 if(MptDeviceDriverHandlers[cb_idx] &&
2115 MptDeviceDriverHandlers[cb_idx]->remove) {
2116 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2117 }
2118 }
2119
2120
2121 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2122
2123 ioc->active = 0;
2124 synchronize_irq(pdev->irq);
2125
2126
2127 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2128
2129 CHIPREG_READ32(&ioc->chip->IntStatus);
2130
2131 mpt_adapter_dispose(ioc);
2132
2133}
2134
2135
2136
2137
2138#ifdef CONFIG_PM
2139
2140
2141
2142
2143
2144
2145int
2146mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2147{
2148 u32 device_state;
2149 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2150
2151 device_state = pci_choose_state(pdev, state);
2152 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2153 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2154 device_state);
2155
2156
2157 if (SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2158 printk(MYIOC_s_ERR_FMT
2159 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2160 }
2161
2162
2163 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2164 ioc->active = 0;
2165
2166
2167 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2168
2169 free_irq(ioc->pci_irq, ioc);
2170 if (ioc->msi_enable)
2171 pci_disable_msi(ioc->pcidev);
2172 ioc->pci_irq = -1;
2173 pci_save_state(pdev);
2174 pci_disable_device(pdev);
2175 pci_release_selected_regions(pdev, ioc->bars);
2176 pci_set_power_state(pdev, device_state);
2177 return 0;
2178}
2179
2180
2181
2182
2183
2184
2185int
2186mpt_resume(struct pci_dev *pdev)
2187{
2188 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2189 u32 device_state = pdev->current_state;
2190 int recovery_state;
2191 int err;
2192
2193 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2194 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2195 device_state);
2196
2197 pci_set_power_state(pdev, PCI_D0);
2198 pci_enable_wake(pdev, PCI_D0, 0);
2199 pci_restore_state(pdev);
2200 ioc->pcidev = pdev;
2201 err = mpt_mapresources(ioc);
2202 if (err)
2203 return err;
2204
2205 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2206 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2207 ioc->add_sge = &mpt_add_sge_64bit_1078;
2208 else
2209 ioc->add_sge = &mpt_add_sge_64bit;
2210 ioc->add_chain = &mpt_add_chain_64bit;
2211 ioc->sg_addr_size = 8;
2212 } else {
2213
2214 ioc->add_sge = &mpt_add_sge;
2215 ioc->add_chain = &mpt_add_chain;
2216 ioc->sg_addr_size = 4;
2217 }
2218 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2219
2220 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2221 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2222 CHIPREG_READ32(&ioc->chip->Doorbell));
2223
2224
2225
2226
2227
2228
2229
2230
2231 if (ioc->bus_type == SAS && (pdev->device ==
2232 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2233 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2234 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2235 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2236 ioc->name);
2237 goto out;
2238 }
2239 }
2240
2241
2242 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2243 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2244 CAN_SLEEP);
2245 if (recovery_state != 0)
2246 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2247 "error:[%x]\n", ioc->name, recovery_state);
2248 else
2249 printk(MYIOC_s_INFO_FMT
2250 "pci-resume: success\n", ioc->name);
2251 out:
2252 return 0;
2253
2254}
2255#endif
2256
2257static int
2258mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2259{
2260 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2261 ioc->bus_type != SPI) ||
2262 (MptDriverClass[index] == MPTFC_DRIVER &&
2263 ioc->bus_type != FC) ||
2264 (MptDriverClass[index] == MPTSAS_DRIVER &&
2265 ioc->bus_type != SAS))
2266
2267
2268 return 0;
2269 return (MptResetHandlers[index])(ioc, reset_phase);
2270}
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294static int
2295mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2296{
2297 int hard_reset_done = 0;
2298 int alt_ioc_ready = 0;
2299 int hard;
2300 int rc=0;
2301 int ii;
2302 int ret = 0;
2303 int reset_alt_ioc_active = 0;
2304 int irq_allocated = 0;
2305 u8 *a;
2306
2307 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2308 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2309
2310
2311 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2312 ioc->active = 0;
2313
2314 if (ioc->alt_ioc) {
2315 if (ioc->alt_ioc->active ||
2316 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2317 reset_alt_ioc_active = 1;
2318
2319
2320
2321 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2322 0xFFFFFFFF);
2323 ioc->alt_ioc->active = 0;
2324 }
2325 }
2326
2327 hard = 1;
2328 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2329 hard = 0;
2330
2331 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2332 if (hard_reset_done == -4) {
2333 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2334 ioc->name);
2335
2336 if (reset_alt_ioc_active && ioc->alt_ioc) {
2337
2338 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2339 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2340 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2341 ioc->alt_ioc->active = 1;
2342 }
2343
2344 } else {
2345 printk(MYIOC_s_WARN_FMT
2346 "NOT READY WARNING!\n", ioc->name);
2347 }
2348 ret = -1;
2349 goto out;
2350 }
2351
2352
2353
2354
2355 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2356 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2357 alt_ioc_ready = 1;
2358 else
2359 printk(MYIOC_s_WARN_FMT
2360 ": alt-ioc Not ready WARNING!\n",
2361 ioc->alt_ioc->name);
2362 }
2363
2364 for (ii=0; ii<5; ii++) {
2365
2366 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2367 break;
2368 }
2369
2370
2371 if (ii == 5) {
2372 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2373 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2374 ret = -2;
2375 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2376 MptDisplayIocCapabilities(ioc);
2377 }
2378
2379 if (alt_ioc_ready) {
2380 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2381 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2382 "Initial Alt IocFacts failed rc=%x\n",
2383 ioc->name, rc));
2384
2385
2386 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2387 }
2388 if (rc) {
2389 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2390 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2391 alt_ioc_ready = 0;
2392 reset_alt_ioc_active = 0;
2393 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2394 MptDisplayIocCapabilities(ioc->alt_ioc);
2395 }
2396 }
2397
2398 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2399 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2400 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2401 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2402 IORESOURCE_IO);
2403 if (pci_enable_device(ioc->pcidev))
2404 return -5;
2405 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2406 "mpt"))
2407 return -5;
2408 }
2409
2410
2411
2412
2413
2414
2415 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2416 ioc->pci_irq = -1;
2417 if (ioc->pcidev->irq) {
2418 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2419 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2420 ioc->name);
2421 else
2422 ioc->msi_enable = 0;
2423 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2424 IRQF_SHARED, ioc->name, ioc);
2425 if (rc < 0) {
2426 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2427 "interrupt %d!\n",
2428 ioc->name, ioc->pcidev->irq);
2429 if (ioc->msi_enable)
2430 pci_disable_msi(ioc->pcidev);
2431 ret = -EBUSY;
2432 goto out;
2433 }
2434 irq_allocated = 1;
2435 ioc->pci_irq = ioc->pcidev->irq;
2436 pci_set_master(ioc->pcidev);
2437 pci_set_drvdata(ioc->pcidev, ioc);
2438 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2439 "installed at interrupt %d\n", ioc->name,
2440 ioc->pcidev->irq));
2441 }
2442 }
2443
2444
2445
2446
2447
2448
2449 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2450 ioc->name));
2451 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2452 ret = -3;
2453
2454
2455
2456
2457 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2458 ioc->name));
2459 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2460 ret = -4;
2461
2462 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2463 printk(MYIOC_s_WARN_FMT
2464 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2465 ioc->alt_ioc->name, rc);
2466 alt_ioc_ready = 0;
2467 reset_alt_ioc_active = 0;
2468 }
2469
2470 if (alt_ioc_ready) {
2471 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2472 alt_ioc_ready = 0;
2473 reset_alt_ioc_active = 0;
2474 printk(MYIOC_s_WARN_FMT
2475 ": alt-ioc: (%d) init failure WARNING!\n",
2476 ioc->alt_ioc->name, rc);
2477 }
2478 }
2479
2480 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2481 if (ioc->upload_fw) {
2482 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2483 "firmware upload required!\n", ioc->name));
2484
2485
2486
2487 if (ret == 0) {
2488 rc = mpt_do_upload(ioc, sleepFlag);
2489 if (rc == 0) {
2490 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2491
2492
2493
2494
2495
2496
2497
2498 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2499 "mpt_upload: alt_%s has cached_fw=%p \n",
2500 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2501 ioc->cached_fw = NULL;
2502 }
2503 } else {
2504 printk(MYIOC_s_WARN_FMT
2505 "firmware upload failure!\n", ioc->name);
2506 ret = -6;
2507 }
2508 }
2509 }
2510 }
2511
2512
2513
2514
2515 if ((ret == 0) && (!ioc->facts.EventState)) {
2516 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2517 "SendEventNotification\n",
2518 ioc->name));
2519 ret = SendEventNotification(ioc, 1, sleepFlag);
2520 }
2521
2522 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2523 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2524
2525 if (ret == 0) {
2526
2527 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2528 ioc->active = 1;
2529 }
2530 if (rc == 0) {
2531 if (reset_alt_ioc_active && ioc->alt_ioc) {
2532
2533 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2534 "reply irq re-enabled\n",
2535 ioc->alt_ioc->name));
2536 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2537 MPI_HIM_DIM);
2538 ioc->alt_ioc->active = 1;
2539 }
2540 }
2541
2542
2543
2544
2545
2546
2547
2548
2549 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2550
2551
2552
2553
2554 mutex_init(&ioc->raid_data.inactive_list_mutex);
2555 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2556
2557 switch (ioc->bus_type) {
2558
2559 case SAS:
2560
2561 if(ioc->facts.IOCExceptions &
2562 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2563 ret = mptbase_sas_persist_operation(ioc,
2564 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2565 if(ret != 0)
2566 goto out;
2567 }
2568
2569
2570
2571 mpt_findImVolumes(ioc);
2572
2573
2574
2575 mpt_read_ioc_pg_1(ioc);
2576
2577 break;
2578
2579 case FC:
2580 if ((ioc->pfacts[0].ProtocolFlags &
2581 MPI_PORTFACTS_PROTOCOL_LAN) &&
2582 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2583
2584
2585
2586
2587 (void) GetLanConfigPages(ioc);
2588 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2589 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2590 "LanAddr = %pMR\n", ioc->name, a));
2591 }
2592 break;
2593
2594 case SPI:
2595
2596
2597 mpt_GetScsiPortSettings(ioc, 0);
2598
2599
2600
2601 mpt_readScsiDevicePageHeaders(ioc, 0);
2602
2603
2604
2605 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2606 mpt_findImVolumes(ioc);
2607
2608
2609
2610 mpt_read_ioc_pg_1(ioc);
2611
2612 mpt_read_ioc_pg_4(ioc);
2613
2614 break;
2615 }
2616
2617 GetIoUnitPage2(ioc);
2618 mpt_get_manufacturing_pg_0(ioc);
2619 }
2620
2621 out:
2622 if ((ret != 0) && irq_allocated) {
2623 free_irq(ioc->pci_irq, ioc);
2624 if (ioc->msi_enable)
2625 pci_disable_msi(ioc->pcidev);
2626 }
2627 return ret;
2628}
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643static void
2644mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2645{
2646 struct pci_dev *peer=NULL;
2647 unsigned int slot = PCI_SLOT(pdev->devfn);
2648 unsigned int func = PCI_FUNC(pdev->devfn);
2649 MPT_ADAPTER *ioc_srch;
2650
2651 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2652 " searching for devfn match on %x or %x\n",
2653 ioc->name, pci_name(pdev), pdev->bus->number,
2654 pdev->devfn, func-1, func+1));
2655
2656 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2657 if (!peer) {
2658 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2659 if (!peer)
2660 return;
2661 }
2662
2663 list_for_each_entry(ioc_srch, &ioc_list, list) {
2664 struct pci_dev *_pcidev = ioc_srch->pcidev;
2665 if (_pcidev == peer) {
2666
2667 if (ioc->alt_ioc != NULL) {
2668 printk(MYIOC_s_WARN_FMT
2669 "Oops, already bound (%s <==> %s)!\n",
2670 ioc->name, ioc->name, ioc->alt_ioc->name);
2671 break;
2672 } else if (ioc_srch->alt_ioc != NULL) {
2673 printk(MYIOC_s_WARN_FMT
2674 "Oops, already bound (%s <==> %s)!\n",
2675 ioc_srch->name, ioc_srch->name,
2676 ioc_srch->alt_ioc->name);
2677 break;
2678 }
2679 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2680 "FOUND! binding %s <==> %s\n",
2681 ioc->name, ioc->name, ioc_srch->name));
2682 ioc_srch->alt_ioc = ioc;
2683 ioc->alt_ioc = ioc_srch;
2684 }
2685 }
2686 pci_dev_put(peer);
2687}
2688
2689
2690
2691
2692
2693
2694static void
2695mpt_adapter_disable(MPT_ADAPTER *ioc)
2696{
2697 int sz;
2698 int ret;
2699
2700 if (ioc->cached_fw != NULL) {
2701 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2702 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2703 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2704 ioc->cached_fw, CAN_SLEEP)) < 0) {
2705 printk(MYIOC_s_WARN_FMT
2706 ": firmware downloadboot failure (%d)!\n",
2707 ioc->name, ret);
2708 }
2709 }
2710
2711
2712
2713
2714 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2715 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2716 CAN_SLEEP)) {
2717 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2718 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2719 "reset failed to put ioc in ready state!\n",
2720 ioc->name, __func__);
2721 } else
2722 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2723 "failed!\n", ioc->name, __func__);
2724 }
2725
2726
2727
2728 synchronize_irq(ioc->pcidev->irq);
2729 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2730 ioc->active = 0;
2731
2732
2733 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2734 CHIPREG_READ32(&ioc->chip->IntStatus);
2735
2736 if (ioc->alloc != NULL) {
2737 sz = ioc->alloc_sz;
2738 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2739 ioc->name, ioc->alloc, ioc->alloc_sz));
2740 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
2741 ioc->alloc_dma);
2742 ioc->reply_frames = NULL;
2743 ioc->req_frames = NULL;
2744 ioc->alloc = NULL;
2745 ioc->alloc_total -= sz;
2746 }
2747
2748 if (ioc->sense_buf_pool != NULL) {
2749 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2750 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
2751 ioc->sense_buf_pool_dma);
2752 ioc->sense_buf_pool = NULL;
2753 ioc->alloc_total -= sz;
2754 }
2755
2756 if (ioc->events != NULL){
2757 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2758 kfree(ioc->events);
2759 ioc->events = NULL;
2760 ioc->alloc_total -= sz;
2761 }
2762
2763 mpt_free_fw_memory(ioc);
2764
2765 kfree(ioc->spi_data.nvram);
2766 mpt_inactive_raid_list_free(ioc);
2767 kfree(ioc->raid_data.pIocPg2);
2768 kfree(ioc->raid_data.pIocPg3);
2769 ioc->spi_data.nvram = NULL;
2770 ioc->raid_data.pIocPg3 = NULL;
2771
2772 if (ioc->spi_data.pIocPg4 != NULL) {
2773 sz = ioc->spi_data.IocPg4Sz;
2774 pci_free_consistent(ioc->pcidev, sz,
2775 ioc->spi_data.pIocPg4,
2776 ioc->spi_data.IocPg4_dma);
2777 ioc->spi_data.pIocPg4 = NULL;
2778 ioc->alloc_total -= sz;
2779 }
2780
2781 if (ioc->ReqToChain != NULL) {
2782 kfree(ioc->ReqToChain);
2783 kfree(ioc->RequestNB);
2784 ioc->ReqToChain = NULL;
2785 }
2786
2787 kfree(ioc->ChainToChain);
2788 ioc->ChainToChain = NULL;
2789
2790 if (ioc->HostPageBuffer != NULL) {
2791 if((ret = mpt_host_page_access_control(ioc,
2792 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2793 printk(MYIOC_s_ERR_FMT
2794 ": %s: host page buffers free failed (%d)!\n",
2795 ioc->name, __func__, ret);
2796 }
2797 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2798 "HostPageBuffer free @ %p, sz=%d bytes\n",
2799 ioc->name, ioc->HostPageBuffer,
2800 ioc->HostPageBuffer_sz));
2801 dma_free_coherent(&ioc->pcidev->dev, ioc->HostPageBuffer_sz,
2802 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2803 ioc->HostPageBuffer = NULL;
2804 ioc->HostPageBuffer_sz = 0;
2805 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2806 }
2807
2808 pci_set_drvdata(ioc->pcidev, NULL);
2809}
2810
2811
2812
2813
2814
2815
2816
2817
2818static void
2819mpt_adapter_dispose(MPT_ADAPTER *ioc)
2820{
2821 int sz_first, sz_last;
2822
2823 if (ioc == NULL)
2824 return;
2825
2826 sz_first = ioc->alloc_total;
2827
2828 mpt_adapter_disable(ioc);
2829
2830 if (ioc->pci_irq != -1) {
2831 free_irq(ioc->pci_irq, ioc);
2832 if (ioc->msi_enable)
2833 pci_disable_msi(ioc->pcidev);
2834 ioc->pci_irq = -1;
2835 }
2836
2837 if (ioc->memmap != NULL) {
2838 iounmap(ioc->memmap);
2839 ioc->memmap = NULL;
2840 }
2841
2842 pci_disable_device(ioc->pcidev);
2843 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2844
2845
2846 list_del(&ioc->list);
2847
2848 sz_last = ioc->alloc_total;
2849 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2850 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2851
2852 if (ioc->alt_ioc)
2853 ioc->alt_ioc->alt_ioc = NULL;
2854
2855 kfree(ioc);
2856}
2857
2858
2859
2860
2861
2862
2863static void
2864MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2865{
2866 int i = 0;
2867
2868 printk(KERN_INFO "%s: ", ioc->name);
2869 if (ioc->prod_name)
2870 pr_cont("%s: ", ioc->prod_name);
2871 pr_cont("Capabilities={");
2872
2873 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2874 pr_cont("Initiator");
2875 i++;
2876 }
2877
2878 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2879 pr_cont("%sTarget", i ? "," : "");
2880 i++;
2881 }
2882
2883 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2884 pr_cont("%sLAN", i ? "," : "");
2885 i++;
2886 }
2887
2888#if 0
2889
2890
2891
2892 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2893 pr_cont("%sLogBusAddr", i ? "," : "");
2894 i++;
2895 }
2896#endif
2897
2898 pr_cont("}\n");
2899}
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916static int
2917MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2918{
2919 u32 ioc_state;
2920 int statefault = 0;
2921 int cntdn;
2922 int hard_reset_done = 0;
2923 int r;
2924 int ii;
2925 int whoinit;
2926
2927
2928 ioc_state = mpt_GetIocState(ioc, 0);
2929 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2930
2931
2932
2933
2934
2935 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2936 statefault = 1;
2937 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2938 ioc->name);
2939 }
2940
2941
2942 if (!statefault &&
2943 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2944 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2945 "IOC is in READY state\n", ioc->name));
2946 return 0;
2947 }
2948
2949
2950
2951
2952 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2953 statefault = 2;
2954 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2955 ioc->name);
2956 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2957 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2958 }
2959
2960
2961
2962
2963 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2964 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2965 ioc->name));
2966
2967
2968
2969
2970
2971
2972 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2973 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2974 "whoinit 0x%x statefault %d force %d\n",
2975 ioc->name, whoinit, statefault, force));
2976 if (whoinit == MPI_WHOINIT_PCI_PEER)
2977 return -4;
2978 else {
2979 if ((statefault == 0 ) && (force == 0)) {
2980 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2981 return 0;
2982 }
2983 statefault = 3;
2984 }
2985 }
2986
2987 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2988 if (hard_reset_done < 0)
2989 return -1;
2990
2991
2992
2993
2994 ii = 0;
2995 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;
2996
2997 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2998 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2999
3000
3001
3002
3003 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
3004 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
3005 return -2;
3006 }
3007 } else if (ioc_state == MPI_IOC_STATE_RESET) {
3008
3009
3010
3011
3012 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
3013 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3014 return -3;
3015 }
3016 }
3017
3018 ii++; cntdn--;
3019 if (!cntdn) {
3020 printk(MYIOC_s_ERR_FMT
3021 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
3022 ioc->name, ioc_state, (int)((ii+5)/HZ));
3023 return -ETIME;
3024 }
3025
3026 if (sleepFlag == CAN_SLEEP) {
3027 msleep(1);
3028 } else {
3029 mdelay (1);
3030 }
3031
3032 }
3033
3034 if (statefault < 3) {
3035 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3036 statefault == 1 ? "stuck handshake" : "IOC FAULT");
3037 }
3038
3039 return hard_reset_done;
3040}
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051u32
3052mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3053{
3054 u32 s, sc;
3055
3056
3057 s = CHIPREG_READ32(&ioc->chip->Doorbell);
3058 sc = s & MPI_IOC_STATE_MASK;
3059
3060
3061 ioc->last_state = sc;
3062
3063 return cooked ? sc : s;
3064}
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075static int
3076GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3077{
3078 IOCFacts_t get_facts;
3079 IOCFactsReply_t *facts;
3080 int r;
3081 int req_sz;
3082 int reply_sz;
3083 int sz;
3084 u32 vv;
3085 u8 shiftFactor=1;
3086
3087
3088 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3089 printk(KERN_ERR MYNAM
3090 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3091 ioc->name, ioc->last_state);
3092 return -44;
3093 }
3094
3095 facts = &ioc->facts;
3096
3097
3098 reply_sz = sizeof(*facts);
3099 memset(facts, 0, reply_sz);
3100
3101
3102 req_sz = sizeof(get_facts);
3103 memset(&get_facts, 0, req_sz);
3104
3105 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3106
3107
3108 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3109 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3110 ioc->name, req_sz, reply_sz));
3111
3112
3113
3114
3115 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3116 reply_sz, (u16*)facts, 5 , sleepFlag);
3117 if (r != 0)
3118 return r;
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3129 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3130
3131
3132
3133 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3134 ioc->FirstWhoInit = facts->WhoInit;
3135 }
3136
3137 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3138 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3139 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3140 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3141 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3142
3143
3144 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3145 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3146
3147
3148
3149
3150
3151
3152 if (facts->MsgVersion < MPI_VERSION_01_02) {
3153
3154
3155
3156 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3157 facts->FWVersion.Word =
3158 ((oldv<<12) & 0xFF000000) |
3159 ((oldv<<8) & 0x000FFF00);
3160 } else
3161 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3162
3163 facts->ProductID = le16_to_cpu(facts->ProductID);
3164
3165 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3166 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3167 ioc->ir_firmware = 1;
3168
3169 facts->CurrentHostMfaHighAddr =
3170 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3171 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3172 facts->CurrentSenseBufferHighAddr =
3173 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3174 facts->CurReplyFrameSize =
3175 le16_to_cpu(facts->CurReplyFrameSize);
3176 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3177
3178
3179
3180
3181
3182
3183 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3184 facts->MsgVersion > MPI_VERSION_01_00) {
3185 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3186 }
3187
3188 facts->FWImageSize = ALIGN(facts->FWImageSize, 4);
3189
3190 if (!facts->RequestFrameSize) {
3191
3192 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3193 ioc->name);
3194 return -55;
3195 }
3196
3197 r = sz = facts->BlockSize;
3198 vv = ((63 / (sz * 4)) + 1) & 0x03;
3199 ioc->NB_for_64_byte_frame = vv;
3200 while ( sz )
3201 {
3202 shiftFactor++;
3203 sz = sz >> 1;
3204 }
3205 ioc->NBShiftFactor = shiftFactor;
3206 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3207 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3208 ioc->name, vv, shiftFactor, r));
3209
3210 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3211
3212
3213
3214
3215 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3216 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3217 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3218 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3219
3220 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3221 ioc->name, ioc->reply_sz, ioc->reply_depth));
3222 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3223 ioc->name, ioc->req_sz, ioc->req_depth));
3224
3225
3226 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3227 return r;
3228 }
3229 } else {
3230 printk(MYIOC_s_ERR_FMT
3231 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3232 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3233 RequestFrameSize)/sizeof(u32)));
3234 return -66;
3235 }
3236
3237 return 0;
3238}
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249static int
3250GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3251{
3252 PortFacts_t get_pfacts;
3253 PortFactsReply_t *pfacts;
3254 int ii;
3255 int req_sz;
3256 int reply_sz;
3257 int max_id;
3258
3259
3260 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3261 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3262 ioc->name, ioc->last_state );
3263 return -4;
3264 }
3265
3266 pfacts = &ioc->pfacts[portnum];
3267
3268
3269 reply_sz = sizeof(*pfacts);
3270 memset(pfacts, 0, reply_sz);
3271
3272
3273 req_sz = sizeof(get_pfacts);
3274 memset(&get_pfacts, 0, req_sz);
3275
3276 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3277 get_pfacts.PortNumber = portnum;
3278
3279
3280 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3281 ioc->name, portnum));
3282
3283
3284
3285
3286 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3287 reply_sz, (u16*)pfacts, 5 , sleepFlag);
3288 if (ii != 0)
3289 return ii;
3290
3291
3292
3293
3294 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3295 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3296 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3297 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3298 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3299 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3300 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3301 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3302 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3303
3304 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3305 pfacts->MaxDevices;
3306 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3307 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3308
3309
3310
3311
3312
3313
3314 if (mpt_channel_mapping) {
3315 ioc->devices_per_bus = 1;
3316 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3317 }
3318
3319 return 0;
3320}
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332static int
3333SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3334{
3335 IOCInit_t ioc_init;
3336 MPIDefaultReply_t init_reply;
3337 u32 state;
3338 int r;
3339 int count;
3340 int cntdn;
3341
3342 memset(&ioc_init, 0, sizeof(ioc_init));
3343 memset(&init_reply, 0, sizeof(init_reply));
3344
3345 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3346 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3347
3348
3349
3350
3351
3352 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3353 ioc->upload_fw = 1;
3354 else
3355 ioc->upload_fw = 0;
3356 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3357 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3358
3359 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3360 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3361
3362 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3363 ioc->name, ioc->facts.MsgVersion));
3364 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3365
3366 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3367 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3368
3369 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3370 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3371 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3372 return -99;
3373 }
3374 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);
3375
3376 if (ioc->sg_addr_size == sizeof(u64)) {
3377
3378
3379
3380 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3381 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3382 } else {
3383
3384 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3385 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3386 }
3387
3388 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3389 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3390 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3391 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3392
3393 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3394 ioc->name, &ioc_init));
3395
3396 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3397 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 , sleepFlag);
3398 if (r != 0) {
3399 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3400 return r;
3401 }
3402
3403
3404
3405
3406
3407 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3408 ioc->name, &ioc_init));
3409
3410 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3411 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3412 return r;
3413 }
3414
3415
3416
3417
3418
3419 count = 0;
3420 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;
3421 state = mpt_GetIocState(ioc, 1);
3422 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3423 if (sleepFlag == CAN_SLEEP) {
3424 msleep(1);
3425 } else {
3426 mdelay(1);
3427 }
3428
3429 if (!cntdn) {
3430 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3431 ioc->name, (int)((count+5)/HZ));
3432 return -9;
3433 }
3434
3435 state = mpt_GetIocState(ioc, 1);
3436 count++;
3437 }
3438 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3439 ioc->name, count));
3440
3441 ioc->aen_event_read_flag=0;
3442 return r;
3443}
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456static int
3457SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3458{
3459 PortEnable_t port_enable;
3460 MPIDefaultReply_t reply_buf;
3461 int rc;
3462 int req_sz;
3463 int reply_sz;
3464
3465
3466 reply_sz = sizeof(MPIDefaultReply_t);
3467 memset(&reply_buf, 0, reply_sz);
3468
3469 req_sz = sizeof(PortEnable_t);
3470 memset(&port_enable, 0, req_sz);
3471
3472 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3473 port_enable.PortNumber = portnum;
3474
3475
3476
3477
3478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3479 ioc->name, portnum, &port_enable));
3480
3481
3482
3483 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3484 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3485 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3486 300 , sleepFlag);
3487 } else {
3488 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3489 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3490 30 , sleepFlag);
3491 }
3492 return rc;
3493}
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505int
3506mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3507{
3508 int rc;
3509
3510 if (ioc->cached_fw) {
3511 rc = 0;
3512 goto out;
3513 }
3514 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3515 ioc->cached_fw = ioc->alt_ioc->cached_fw;
3516 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3517 rc = 0;
3518 goto out;
3519 }
3520 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3521 if (!ioc->cached_fw) {
3522 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3523 ioc->name);
3524 rc = -1;
3525 } else {
3526 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3527 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3528 ioc->alloc_total += size;
3529 rc = 0;
3530 }
3531 out:
3532 return rc;
3533}
3534
3535
3536
3537
3538
3539
3540
3541
3542void
3543mpt_free_fw_memory(MPT_ADAPTER *ioc)
3544{
3545 int sz;
3546
3547 if (!ioc->cached_fw)
3548 return;
3549
3550 sz = ioc->facts.FWImageSize;
3551 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3552 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3553 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3554 ioc->alloc_total -= sz;
3555 ioc->cached_fw = NULL;
3556}
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572static int
3573mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3574{
3575 u8 reply[sizeof(FWUploadReply_t)];
3576 FWUpload_t *prequest;
3577 FWUploadReply_t *preply;
3578 FWUploadTCSGE_t *ptcsge;
3579 u32 flagsLength;
3580 int ii, sz, reply_sz;
3581 int cmdStatus;
3582 int request_size;
3583
3584
3585 if ((sz = ioc->facts.FWImageSize) == 0)
3586 return 0;
3587
3588 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3589 return -ENOMEM;
3590
3591 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3592 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3593
3594 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3595 kzalloc(ioc->req_sz, GFP_KERNEL);
3596 if (!prequest) {
3597 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3598 "while allocating memory \n", ioc->name));
3599 mpt_free_fw_memory(ioc);
3600 return -ENOMEM;
3601 }
3602
3603 preply = (FWUploadReply_t *)&reply;
3604
3605 reply_sz = sizeof(reply);
3606 memset(preply, 0, reply_sz);
3607
3608 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3609 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3610
3611 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3612 ptcsge->DetailsLength = 12;
3613 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3614 ptcsge->ImageSize = cpu_to_le32(sz);
3615 ptcsge++;
3616
3617 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3618 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3619 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3620 ioc->SGE_size;
3621 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3622 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3623 ioc->facts.FWImageSize, request_size));
3624 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3625
3626 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3627 reply_sz, (u16 *)preply, 65 , sleepFlag);
3628
3629 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3630 "rc=%x \n", ioc->name, ii));
3631
3632 cmdStatus = -EFAULT;
3633 if (ii == 0) {
3634
3635
3636
3637 int status;
3638 status = le16_to_cpu(preply->IOCStatus) &
3639 MPI_IOCSTATUS_MASK;
3640 if (status == MPI_IOCSTATUS_SUCCESS &&
3641 ioc->facts.FWImageSize ==
3642 le32_to_cpu(preply->ActualImageSize))
3643 cmdStatus = 0;
3644 }
3645 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3646 ioc->name, cmdStatus));
3647
3648
3649 if (cmdStatus) {
3650 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3651 "freeing image \n", ioc->name));
3652 mpt_free_fw_memory(ioc);
3653 }
3654 kfree(prequest);
3655
3656 return cmdStatus;
3657}
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673static int
3674mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3675{
3676 MpiExtImageHeader_t *pExtImage;
3677 u32 fwSize;
3678 u32 diag0val;
3679 int count;
3680 u32 *ptrFw;
3681 u32 diagRwData;
3682 u32 nextImage;
3683 u32 load_addr;
3684 u32 ioc_state=0;
3685
3686 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3687 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3688
3689 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3690 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3691 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3692 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3693 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3694 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3695
3696 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3697
3698
3699 if (sleepFlag == CAN_SLEEP) {
3700 msleep(1);
3701 } else {
3702 mdelay (1);
3703 }
3704
3705 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3706 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3707
3708 for (count = 0; count < 30; count ++) {
3709 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3710 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3711 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3712 ioc->name, count));
3713 break;
3714 }
3715
3716 if (sleepFlag == CAN_SLEEP) {
3717 msleep (100);
3718 } else {
3719 mdelay (100);
3720 }
3721 }
3722
3723 if ( count == 30 ) {
3724 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3725 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3726 ioc->name, diag0val));
3727 return -3;
3728 }
3729
3730 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3731 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3732 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3733 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3734 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3735 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3736
3737
3738 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3739
3740 fwSize = (pFwHeader->ImageSize + 3)/4;
3741 ptrFw = (u32 *) pFwHeader;
3742
3743
3744
3745
3746 if (ioc->errata_flag_1064)
3747 pci_enable_io_access(ioc->pcidev);
3748
3749 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3750 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3751 ioc->name, pFwHeader->LoadStartAddress));
3752
3753 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3754 ioc->name, fwSize*4, ptrFw));
3755 while (fwSize--) {
3756 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3757 }
3758
3759 nextImage = pFwHeader->NextImageHeaderOffset;
3760 while (nextImage) {
3761 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3762
3763 load_addr = pExtImage->LoadStartAddress;
3764
3765 fwSize = (pExtImage->ImageSize + 3) >> 2;
3766 ptrFw = (u32 *)pExtImage;
3767
3768 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3769 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3770 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3771
3772 while (fwSize--) {
3773 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3774 }
3775 nextImage = pExtImage->NextImageHeaderOffset;
3776 }
3777
3778
3779 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3780 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3781
3782
3783 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3784 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3785
3786
3787
3788
3789 if (ioc->bus_type == SPI) {
3790
3791
3792
3793
3794 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3795 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3796 diagRwData |= 0x40000000;
3797 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3798 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3799
3800 } else {
3801 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3802 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3803 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3804
3805
3806 if (sleepFlag == CAN_SLEEP) {
3807 msleep (1);
3808 } else {
3809 mdelay (1);
3810 }
3811 }
3812
3813 if (ioc->errata_flag_1064)
3814 pci_disable_io_access(ioc->pcidev);
3815
3816 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3817 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3818 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3819 ioc->name, diag0val));
3820 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3821 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3822 ioc->name, diag0val));
3823 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3824
3825
3826 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3827
3828 if (ioc->bus_type == SAS) {
3829 ioc_state = mpt_GetIocState(ioc, 0);
3830 if ( (GetIocFacts(ioc, sleepFlag,
3831 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3832 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3833 ioc->name, ioc_state));
3834 return -EFAULT;
3835 }
3836 }
3837
3838 for (count=0; count<HZ*20; count++) {
3839 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3840 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3841 "downloadboot successful! (count=%d) IocState=%x\n",
3842 ioc->name, count, ioc_state));
3843 if (ioc->bus_type == SAS) {
3844 return 0;
3845 }
3846 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3847 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3848 "downloadboot: SendIocInit failed\n",
3849 ioc->name));
3850 return -EFAULT;
3851 }
3852 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3853 "downloadboot: SendIocInit successful\n",
3854 ioc->name));
3855 return 0;
3856 }
3857 if (sleepFlag == CAN_SLEEP) {
3858 msleep (10);
3859 } else {
3860 mdelay (10);
3861 }
3862 }
3863 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3864 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3865 return -EFAULT;
3866}
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894static int
3895KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3896{
3897 int hard_reset_done = 0;
3898 u32 ioc_state=0;
3899 int cnt,cntdn;
3900
3901 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3902 if (ioc->bus_type == SPI) {
3903
3904
3905
3906 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3907
3908 if (sleepFlag == CAN_SLEEP) {
3909 msleep (1000);
3910 } else {
3911 mdelay (1000);
3912 }
3913 }
3914
3915 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3916 if (hard_reset_done < 0)
3917 return hard_reset_done;
3918
3919 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3920 ioc->name));
3921
3922 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;
3923 for (cnt=0; cnt<cntdn; cnt++) {
3924 ioc_state = mpt_GetIocState(ioc, 1);
3925 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3926 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3927 ioc->name, cnt));
3928 return hard_reset_done;
3929 }
3930 if (sleepFlag == CAN_SLEEP) {
3931 msleep (10);
3932 } else {
3933 mdelay (10);
3934 }
3935 }
3936
3937 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3938 ioc->name, mpt_GetIocState(ioc, 0)));
3939 return -1;
3940}
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961static int
3962mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3963{
3964 u32 diag0val;
3965 u32 doorbell;
3966 int hard_reset_done = 0;
3967 int count = 0;
3968 u32 diag1val = 0;
3969 MpiFwHeader_t *cached_fw;
3970 u8 cb_idx;
3971
3972
3973 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3974
3975 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3976
3977 if (!ignore)
3978 return 0;
3979
3980 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3981 "address=%p\n", ioc->name, __func__,
3982 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3983 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3984 if (sleepFlag == CAN_SLEEP)
3985 msleep(1);
3986 else
3987 mdelay(1);
3988
3989
3990
3991
3992
3993
3994
3995 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3996 if (MptResetHandlers[cb_idx])
3997 (*(MptResetHandlers[cb_idx]))(ioc,
3998 MPT_IOC_PRE_RESET);
3999 }
4000
4001 for (count = 0; count < 60; count ++) {
4002 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4003 doorbell &= MPI_IOC_STATE_MASK;
4004
4005 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4006 "looking for READY STATE: doorbell=%x"
4007 " count=%d\n",
4008 ioc->name, doorbell, count));
4009
4010 if (doorbell == MPI_IOC_STATE_READY) {
4011 return 1;
4012 }
4013
4014
4015 if (sleepFlag == CAN_SLEEP)
4016 msleep(1000);
4017 else
4018 mdelay(1000);
4019 }
4020 return -1;
4021 }
4022
4023
4024 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4025
4026 if (ioc->debug_level & MPT_DEBUG) {
4027 if (ioc->alt_ioc)
4028 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4029 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4030 ioc->name, diag0val, diag1val));
4031 }
4032
4033
4034
4035
4036 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4037 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4038
4039
4040
4041 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4042 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4043 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4044 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4045 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4046 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4047
4048
4049 if (sleepFlag == CAN_SLEEP) {
4050 msleep (100);
4051 } else {
4052 mdelay (100);
4053 }
4054
4055 count++;
4056 if (count > 20) {
4057 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4058 ioc->name, diag0val);
4059 return -2;
4060
4061 }
4062
4063 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4064
4065 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4066 ioc->name, diag0val));
4067 }
4068
4069 if (ioc->debug_level & MPT_DEBUG) {
4070 if (ioc->alt_ioc)
4071 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4072 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4073 ioc->name, diag0val, diag1val));
4074 }
4075
4076
4077
4078
4079 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4080 mdelay(1);
4081
4082
4083
4084
4085
4086 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4087 hard_reset_done = 1;
4088 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4089 ioc->name));
4090
4091
4092
4093
4094
4095
4096
4097 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4098 if (MptResetHandlers[cb_idx]) {
4099 mpt_signal_reset(cb_idx,
4100 ioc, MPT_IOC_PRE_RESET);
4101 if (ioc->alt_ioc) {
4102 mpt_signal_reset(cb_idx,
4103 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4104 }
4105 }
4106 }
4107
4108 if (ioc->cached_fw)
4109 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4110 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4111 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4112 else
4113 cached_fw = NULL;
4114 if (cached_fw) {
4115
4116
4117
4118
4119 for (count = 0; count < 30; count ++) {
4120 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4121 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4122 break;
4123 }
4124
4125 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4126 ioc->name, diag0val, count));
4127
4128 if (sleepFlag == CAN_SLEEP) {
4129 msleep (1000);
4130 } else {
4131 mdelay (1000);
4132 }
4133 }
4134 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4135 printk(MYIOC_s_WARN_FMT
4136 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4137 }
4138
4139 } else {
4140
4141
4142
4143
4144
4145
4146 for (count = 0; count < 60; count ++) {
4147 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4148 doorbell &= MPI_IOC_STATE_MASK;
4149
4150 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4151 "looking for READY STATE: doorbell=%x"
4152 " count=%d\n", ioc->name, doorbell, count));
4153
4154 if (doorbell == MPI_IOC_STATE_READY) {
4155 break;
4156 }
4157
4158
4159 if (sleepFlag == CAN_SLEEP) {
4160 msleep (1000);
4161 } else {
4162 mdelay (1000);
4163 }
4164 }
4165
4166 if (doorbell != MPI_IOC_STATE_READY)
4167 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4168 "after reset! IocState=%x", ioc->name,
4169 doorbell);
4170 }
4171 }
4172
4173 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4174 if (ioc->debug_level & MPT_DEBUG) {
4175 if (ioc->alt_ioc)
4176 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4177 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4178 ioc->name, diag0val, diag1val));
4179 }
4180
4181
4182
4183
4184 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4185 count = 0;
4186 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4187
4188
4189
4190 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4191 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4192 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4193 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4194 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4195 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4196
4197
4198 if (sleepFlag == CAN_SLEEP) {
4199 msleep (100);
4200 } else {
4201 mdelay (100);
4202 }
4203
4204 count++;
4205 if (count > 20) {
4206 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4207 ioc->name, diag0val);
4208 break;
4209 }
4210 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4211 }
4212 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4213 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4214 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4215 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4216 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4217 ioc->name);
4218 }
4219
4220
4221
4222 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4223
4224
4225
4226 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4227 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4228 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4229 ioc->name, diag0val);
4230 return -3;
4231 }
4232
4233 if (ioc->debug_level & MPT_DEBUG) {
4234 if (ioc->alt_ioc)
4235 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4236 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4237 ioc->name, diag0val, diag1val));
4238 }
4239
4240
4241
4242
4243 ioc->facts.EventState = 0;
4244
4245 if (ioc->alt_ioc)
4246 ioc->alt_ioc->facts.EventState = 0;
4247
4248 return hard_reset_done;
4249}
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263static int
4264SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4265{
4266 int r;
4267 u32 state;
4268 int cntdn, count;
4269
4270 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4271 ioc->name, reset_type));
4272 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4273 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4274 return r;
4275
4276
4277
4278 count = 0;
4279 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;
4280
4281 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4282 cntdn--;
4283 count++;
4284 if (!cntdn) {
4285 if (sleepFlag != CAN_SLEEP)
4286 count *= 10;
4287
4288 printk(MYIOC_s_ERR_FMT
4289 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4290 ioc->name, state, (int)((count+5)/HZ));
4291 return -ETIME;
4292 }
4293
4294 if (sleepFlag == CAN_SLEEP) {
4295 msleep(1);
4296 } else {
4297 mdelay (1);
4298 }
4299 }
4300
4301
4302
4303
4304
4305 if (ioc->facts.Function)
4306 ioc->facts.EventState = 0;
4307
4308 return 0;
4309}
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319static int
4320initChainBuffers(MPT_ADAPTER *ioc)
4321{
4322 u8 *mem;
4323 int sz, ii, num_chain;
4324 int scale, num_sge, numSGE;
4325
4326
4327
4328
4329 if (ioc->ReqToChain == NULL) {
4330 sz = ioc->req_depth * sizeof(int);
4331 mem = kmalloc(sz, GFP_ATOMIC);
4332 if (mem == NULL)
4333 return -1;
4334
4335 ioc->ReqToChain = (int *) mem;
4336 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4337 ioc->name, mem, sz));
4338 mem = kmalloc(sz, GFP_ATOMIC);
4339 if (mem == NULL)
4340 return -1;
4341
4342 ioc->RequestNB = (int *) mem;
4343 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4344 ioc->name, mem, sz));
4345 }
4346 for (ii = 0; ii < ioc->req_depth; ii++) {
4347 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4348 }
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360 scale = ioc->req_sz / ioc->SGE_size;
4361 if (ioc->sg_addr_size == sizeof(u64))
4362 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4363 else
4364 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4365
4366 if (ioc->sg_addr_size == sizeof(u64)) {
4367 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4368 (ioc->req_sz - 60) / ioc->SGE_size;
4369 } else {
4370 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4371 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4372 }
4373 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4374 ioc->name, num_sge, numSGE));
4375
4376 if (ioc->bus_type == FC) {
4377 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4378 numSGE = MPT_SCSI_FC_SG_DEPTH;
4379 } else {
4380 if (numSGE > MPT_SCSI_SG_DEPTH)
4381 numSGE = MPT_SCSI_SG_DEPTH;
4382 }
4383
4384 num_chain = 1;
4385 while (numSGE - num_sge > 0) {
4386 num_chain++;
4387 num_sge += (scale - 1);
4388 }
4389 num_chain++;
4390
4391 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4392 ioc->name, numSGE, num_sge, num_chain));
4393
4394 if (ioc->bus_type == SPI)
4395 num_chain *= MPT_SCSI_CAN_QUEUE;
4396 else if (ioc->bus_type == SAS)
4397 num_chain *= MPT_SAS_CAN_QUEUE;
4398 else
4399 num_chain *= MPT_FC_CAN_QUEUE;
4400
4401 ioc->num_chain = num_chain;
4402
4403 sz = num_chain * sizeof(int);
4404 if (ioc->ChainToChain == NULL) {
4405 mem = kmalloc(sz, GFP_ATOMIC);
4406 if (mem == NULL)
4407 return -1;
4408
4409 ioc->ChainToChain = (int *) mem;
4410 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4411 ioc->name, mem, sz));
4412 } else {
4413 mem = (u8 *) ioc->ChainToChain;
4414 }
4415 memset(mem, 0xFF, sz);
4416 return num_chain;
4417}
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430static int
4431PrimeIocFifos(MPT_ADAPTER *ioc)
4432{
4433 MPT_FRAME_HDR *mf;
4434 unsigned long flags;
4435 dma_addr_t alloc_dma;
4436 u8 *mem;
4437 int i, reply_sz, sz, total_size, num_chain;
4438 u64 dma_mask;
4439
4440 dma_mask = 0;
4441
4442
4443
4444 if (ioc->reply_frames == NULL) {
4445 if ( (num_chain = initChainBuffers(ioc)) < 0)
4446 return -1;
4447
4448
4449
4450 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4451 ioc->dma_mask > DMA_BIT_MASK(35)) {
4452 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4453 && !pci_set_consistent_dma_mask(ioc->pcidev,
4454 DMA_BIT_MASK(32))) {
4455 dma_mask = DMA_BIT_MASK(35);
4456 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4457 "setting 35 bit addressing for "
4458 "Request/Reply/Chain and Sense Buffers\n",
4459 ioc->name));
4460 } else {
4461
4462 pci_set_dma_mask(ioc->pcidev,
4463 DMA_BIT_MASK(64));
4464 pci_set_consistent_dma_mask(ioc->pcidev,
4465 DMA_BIT_MASK(64));
4466
4467 printk(MYIOC_s_ERR_FMT
4468 "failed setting 35 bit addressing for "
4469 "Request/Reply/Chain and Sense Buffers\n",
4470 ioc->name);
4471 return -1;
4472 }
4473 }
4474
4475 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4476 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4477 ioc->name, ioc->reply_sz, ioc->reply_depth));
4478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4479 ioc->name, reply_sz, reply_sz));
4480
4481 sz = (ioc->req_sz * ioc->req_depth);
4482 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4483 ioc->name, ioc->req_sz, ioc->req_depth));
4484 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4485 ioc->name, sz, sz));
4486 total_size += sz;
4487
4488 sz = num_chain * ioc->req_sz;
4489 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4490 ioc->name, ioc->req_sz, num_chain));
4491 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4492 ioc->name, sz, sz, num_chain));
4493
4494 total_size += sz;
4495 mem = dma_alloc_coherent(&ioc->pcidev->dev, total_size,
4496 &alloc_dma, GFP_KERNEL);
4497 if (mem == NULL) {
4498 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4499 ioc->name);
4500 goto out_fail;
4501 }
4502
4503 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4504 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4505
4506 memset(mem, 0, total_size);
4507 ioc->alloc_total += total_size;
4508 ioc->alloc = mem;
4509 ioc->alloc_dma = alloc_dma;
4510 ioc->alloc_sz = total_size;
4511 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4512 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4513
4514 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4515 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4516
4517 alloc_dma += reply_sz;
4518 mem += reply_sz;
4519
4520
4521
4522 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4523 ioc->req_frames_dma = alloc_dma;
4524
4525 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4526 ioc->name, mem, (void *)(ulong)alloc_dma));
4527
4528 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4529
4530 for (i = 0; i < ioc->req_depth; i++) {
4531 alloc_dma += ioc->req_sz;
4532 mem += ioc->req_sz;
4533 }
4534
4535 ioc->ChainBuffer = mem;
4536 ioc->ChainBufferDMA = alloc_dma;
4537
4538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4539 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4540
4541
4542
4543
4544 INIT_LIST_HEAD(&ioc->FreeChainQ);
4545
4546
4547
4548 mem = (u8 *)ioc->ChainBuffer;
4549 for (i=0; i < num_chain; i++) {
4550 mf = (MPT_FRAME_HDR *) mem;
4551 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4552 mem += ioc->req_sz;
4553 }
4554
4555
4556
4557 alloc_dma = ioc->req_frames_dma;
4558 mem = (u8 *) ioc->req_frames;
4559
4560 spin_lock_irqsave(&ioc->FreeQlock, flags);
4561 INIT_LIST_HEAD(&ioc->FreeQ);
4562 for (i = 0; i < ioc->req_depth; i++) {
4563 mf = (MPT_FRAME_HDR *) mem;
4564
4565
4566 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4567
4568 mem += ioc->req_sz;
4569 }
4570 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4571
4572 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4573 ioc->sense_buf_pool = dma_alloc_coherent(&ioc->pcidev->dev, sz,
4574 &ioc->sense_buf_pool_dma, GFP_KERNEL);
4575 if (ioc->sense_buf_pool == NULL) {
4576 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4577 ioc->name);
4578 goto out_fail;
4579 }
4580
4581 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4582 ioc->alloc_total += sz;
4583 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4584 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4585
4586 }
4587
4588
4589
4590 alloc_dma = ioc->alloc_dma;
4591 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4592 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4593
4594 for (i = 0; i < ioc->reply_depth; i++) {
4595
4596 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4597 alloc_dma += ioc->reply_sz;
4598 }
4599
4600 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4601 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4602 ioc->dma_mask))
4603 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4604 "restoring 64 bit addressing\n", ioc->name));
4605
4606 return 0;
4607
4608out_fail:
4609
4610 if (ioc->alloc != NULL) {
4611 sz = ioc->alloc_sz;
4612 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
4613 ioc->alloc_dma);
4614 ioc->reply_frames = NULL;
4615 ioc->req_frames = NULL;
4616 ioc->alloc_total -= sz;
4617 }
4618 if (ioc->sense_buf_pool != NULL) {
4619 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4620 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
4621 ioc->sense_buf_pool_dma);
4622 ioc->sense_buf_pool = NULL;
4623 }
4624
4625 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4626 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4627 DMA_BIT_MASK(64)))
4628 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4629 "restoring 64 bit addressing\n", ioc->name));
4630
4631 return -1;
4632}
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653static int
4654mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4655 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4656{
4657 MPIDefaultReply_t *mptReply;
4658 int failcnt = 0;
4659 int t;
4660
4661
4662
4663
4664 ioc->hs_reply_idx = 0;
4665 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4666 mptReply->MsgLength = 0;
4667
4668
4669
4670
4671
4672
4673 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4674 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4675 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4676 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4677
4678
4679
4680
4681 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4682 failcnt++;
4683
4684 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4685 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4686
4687
4688 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4689 return -1;
4690
4691
4692
4693
4694
4695
4696 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4697 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4698 failcnt++;
4699
4700 if (!failcnt) {
4701 int ii;
4702 u8 *req_as_bytes = (u8 *) req;
4703
4704
4705
4706
4707
4708 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4709 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4710 (req_as_bytes[(ii*4) + 1] << 8) |
4711 (req_as_bytes[(ii*4) + 2] << 16) |
4712 (req_as_bytes[(ii*4) + 3] << 24));
4713
4714 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4715 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4716 failcnt++;
4717 }
4718
4719 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4720 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4721
4722 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4723 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4724
4725
4726
4727
4728 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4729 failcnt++;
4730
4731 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4732 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4733
4734
4735
4736
4737 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4738 u16reply[ii] = ioc->hs_reply[ii];
4739 } else {
4740 return -99;
4741 }
4742
4743 return -failcnt;
4744}
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759static int
4760WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4761{
4762 int cntdn;
4763 int count = 0;
4764 u32 intstat=0;
4765
4766 cntdn = 1000 * howlong;
4767
4768 if (sleepFlag == CAN_SLEEP) {
4769 while (--cntdn) {
4770 msleep (1);
4771 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4772 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4773 break;
4774 count++;
4775 }
4776 } else {
4777 while (--cntdn) {
4778 udelay (1000);
4779 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4780 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4781 break;
4782 count++;
4783 }
4784 }
4785
4786 if (cntdn) {
4787 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4788 ioc->name, count));
4789 return count;
4790 }
4791
4792 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4793 ioc->name, count, intstat);
4794 return -1;
4795}
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809static int
4810WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4811{
4812 int cntdn;
4813 int count = 0;
4814 u32 intstat=0;
4815
4816 cntdn = 1000 * howlong;
4817 if (sleepFlag == CAN_SLEEP) {
4818 while (--cntdn) {
4819 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4820 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4821 break;
4822 msleep(1);
4823 count++;
4824 }
4825 } else {
4826 while (--cntdn) {
4827 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4828 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4829 break;
4830 udelay (1000);
4831 count++;
4832 }
4833 }
4834
4835 if (cntdn) {
4836 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4837 ioc->name, count, howlong));
4838 return count;
4839 }
4840
4841 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4842 ioc->name, count, intstat);
4843 return -1;
4844}
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859static int
4860WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4861{
4862 int u16cnt = 0;
4863 int failcnt = 0;
4864 int t;
4865 u16 *hs_reply = ioc->hs_reply;
4866 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4867 u16 hword;
4868
4869 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4870
4871
4872
4873
4874 u16cnt=0;
4875 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4876 failcnt++;
4877 } else {
4878 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4879 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4880 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4881 failcnt++;
4882 else {
4883 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4884 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4885 }
4886 }
4887
4888 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4889 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4890 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4891
4892
4893
4894
4895
4896 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4897 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4898 failcnt++;
4899 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4900
4901 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4902 hs_reply[u16cnt] = hword;
4903 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4904 }
4905
4906 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4907 failcnt++;
4908 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4909
4910 if (failcnt) {
4911 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4912 ioc->name);
4913 return -failcnt;
4914 }
4915#if 0
4916 else if (u16cnt != (2 * mptReply->MsgLength)) {
4917 return -101;
4918 }
4919 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4920 return -102;
4921 }
4922#endif
4923
4924 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4925 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4926
4927 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4928 ioc->name, t, u16cnt/2));
4929 return u16cnt/2;
4930}
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943static int
4944GetLanConfigPages(MPT_ADAPTER *ioc)
4945{
4946 ConfigPageHeader_t hdr;
4947 CONFIGPARMS cfg;
4948 LANPage0_t *ppage0_alloc;
4949 dma_addr_t page0_dma;
4950 LANPage1_t *ppage1_alloc;
4951 dma_addr_t page1_dma;
4952 int rc = 0;
4953 int data_sz;
4954 int copy_sz;
4955
4956
4957 hdr.PageVersion = 0;
4958 hdr.PageLength = 0;
4959 hdr.PageNumber = 0;
4960 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4961 cfg.cfghdr.hdr = &hdr;
4962 cfg.physAddr = -1;
4963 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4964 cfg.dir = 0;
4965 cfg.pageAddr = 0;
4966 cfg.timeout = 0;
4967
4968 if ((rc = mpt_config(ioc, &cfg)) != 0)
4969 return rc;
4970
4971 if (hdr.PageLength > 0) {
4972 data_sz = hdr.PageLength * 4;
4973 ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4974 rc = -ENOMEM;
4975 if (ppage0_alloc) {
4976 memset((u8 *)ppage0_alloc, 0, data_sz);
4977 cfg.physAddr = page0_dma;
4978 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4979
4980 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4981
4982 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4983 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4984
4985 }
4986
4987 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4988
4989
4990
4991
4992
4993
4994 }
4995
4996 if (rc)
4997 return rc;
4998 }
4999
5000
5001 hdr.PageVersion = 0;
5002 hdr.PageLength = 0;
5003 hdr.PageNumber = 1;
5004 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5005 cfg.cfghdr.hdr = &hdr;
5006 cfg.physAddr = -1;
5007 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5008 cfg.dir = 0;
5009 cfg.pageAddr = 0;
5010
5011 if ((rc = mpt_config(ioc, &cfg)) != 0)
5012 return rc;
5013
5014 if (hdr.PageLength == 0)
5015 return 0;
5016
5017 data_sz = hdr.PageLength * 4;
5018 rc = -ENOMEM;
5019 ppage1_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
5020 if (ppage1_alloc) {
5021 memset((u8 *)ppage1_alloc, 0, data_sz);
5022 cfg.physAddr = page1_dma;
5023 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5024
5025 if ((rc = mpt_config(ioc, &cfg)) == 0) {
5026
5027 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5028 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5029 }
5030
5031 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
5032
5033
5034
5035
5036
5037
5038 }
5039
5040 return rc;
5041}
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061int
5062mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5063{
5064 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5065 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5066 MPT_FRAME_HDR *mf = NULL;
5067 MPIHeader_t *mpi_hdr;
5068 int ret = 0;
5069 unsigned long timeleft;
5070
5071 mutex_lock(&ioc->mptbase_cmds.mutex);
5072
5073
5074 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5075 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5076
5077
5078 switch(persist_opcode) {
5079
5080 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5081 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5082 break;
5083
5084 default:
5085 ret = -1;
5086 goto out;
5087 }
5088
5089 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5090 __func__, persist_opcode);
5091
5092
5093
5094 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5095 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5096 ret = -1;
5097 goto out;
5098 }
5099
5100 mpi_hdr = (MPIHeader_t *) mf;
5101 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5102 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5103 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5104 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5105 sasIoUnitCntrReq->Operation = persist_opcode;
5106
5107 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5108 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5109 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5110 ret = -ETIME;
5111 printk(KERN_DEBUG "%s: failed\n", __func__);
5112 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5113 goto out;
5114 if (!timeleft) {
5115 printk(MYIOC_s_WARN_FMT
5116 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5117 ioc->name, __func__, mpt_GetIocState(ioc, 0));
5118 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5119 mpt_free_msg_frame(ioc, mf);
5120 }
5121 goto out;
5122 }
5123
5124 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5125 ret = -1;
5126 goto out;
5127 }
5128
5129 sasIoUnitCntrReply =
5130 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5131 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5132 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5133 __func__, sasIoUnitCntrReply->IOCStatus,
5134 sasIoUnitCntrReply->IOCLogInfo);
5135 printk(KERN_DEBUG "%s: failed\n", __func__);
5136 ret = -1;
5137 } else
5138 printk(KERN_DEBUG "%s: success\n", __func__);
5139 out:
5140
5141 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5142 mutex_unlock(&ioc->mptbase_cmds.mutex);
5143 return ret;
5144}
5145
5146
5147
5148static void
5149mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5150 MpiEventDataRaid_t * pRaidEventData)
5151{
5152 int volume;
5153 int reason;
5154 int disk;
5155 int status;
5156 int flags;
5157 int state;
5158
5159 volume = pRaidEventData->VolumeID;
5160 reason = pRaidEventData->ReasonCode;
5161 disk = pRaidEventData->PhysDiskNum;
5162 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5163 flags = (status >> 0) & 0xff;
5164 state = (status >> 8) & 0xff;
5165
5166 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5167 return;
5168 }
5169
5170 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5171 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5172 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5173 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5174 ioc->name, disk, volume);
5175 } else {
5176 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5177 ioc->name, volume);
5178 }
5179
5180 switch(reason) {
5181 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5182 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5183 ioc->name);
5184 break;
5185
5186 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5187
5188 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5189 ioc->name);
5190 break;
5191
5192 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5193 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5194 ioc->name);
5195 break;
5196
5197 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5198 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5199 ioc->name,
5200 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5201 ? "optimal"
5202 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5203 ? "degraded"
5204 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5205 ? "failed"
5206 : "state unknown",
5207 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5208 ? ", enabled" : "",
5209 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5210 ? ", quiesced" : "",
5211 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5212 ? ", resync in progress" : "" );
5213 break;
5214
5215 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5216 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5217 ioc->name, disk);
5218 break;
5219
5220 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5221 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5222 ioc->name);
5223 break;
5224
5225 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5226 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5227 ioc->name);
5228 break;
5229
5230 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5231 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5232 ioc->name);
5233 break;
5234
5235 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5236 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5237 ioc->name,
5238 state == MPI_PHYSDISK0_STATUS_ONLINE
5239 ? "online"
5240 : state == MPI_PHYSDISK0_STATUS_MISSING
5241 ? "missing"
5242 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5243 ? "not compatible"
5244 : state == MPI_PHYSDISK0_STATUS_FAILED
5245 ? "failed"
5246 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5247 ? "initializing"
5248 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5249 ? "offline requested"
5250 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5251 ? "failed requested"
5252 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5253 ? "offline"
5254 : "state unknown",
5255 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5256 ? ", out of sync" : "",
5257 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5258 ? ", quiesced" : "" );
5259 break;
5260
5261 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5262 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5263 ioc->name, disk);
5264 break;
5265
5266 case MPI_EVENT_RAID_RC_SMART_DATA:
5267 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5268 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5269 break;
5270
5271 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5272 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5273 ioc->name, disk);
5274 break;
5275 }
5276}
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289static int
5290GetIoUnitPage2(MPT_ADAPTER *ioc)
5291{
5292 ConfigPageHeader_t hdr;
5293 CONFIGPARMS cfg;
5294 IOUnitPage2_t *ppage_alloc;
5295 dma_addr_t page_dma;
5296 int data_sz;
5297 int rc;
5298
5299
5300 hdr.PageVersion = 0;
5301 hdr.PageLength = 0;
5302 hdr.PageNumber = 2;
5303 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5304 cfg.cfghdr.hdr = &hdr;
5305 cfg.physAddr = -1;
5306 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5307 cfg.dir = 0;
5308 cfg.pageAddr = 0;
5309 cfg.timeout = 0;
5310
5311 if ((rc = mpt_config(ioc, &cfg)) != 0)
5312 return rc;
5313
5314 if (hdr.PageLength == 0)
5315 return 0;
5316
5317
5318 data_sz = hdr.PageLength * 4;
5319 rc = -ENOMEM;
5320 ppage_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5321 if (ppage_alloc) {
5322 memset((u8 *)ppage_alloc, 0, data_sz);
5323 cfg.physAddr = page_dma;
5324 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5325
5326
5327 if ((rc = mpt_config(ioc, &cfg)) == 0)
5328 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5329
5330 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5331 }
5332
5333 return rc;
5334}
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357static int
5358mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5359{
5360 u8 *pbuf;
5361 dma_addr_t buf_dma;
5362 CONFIGPARMS cfg;
5363 ConfigPageHeader_t header;
5364 int ii;
5365 int data, rc = 0;
5366
5367
5368
5369 if (!ioc->spi_data.nvram) {
5370 int sz;
5371 u8 *mem;
5372 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5373 mem = kmalloc(sz, GFP_ATOMIC);
5374 if (mem == NULL)
5375 return -EFAULT;
5376
5377 ioc->spi_data.nvram = (int *) mem;
5378
5379 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5380 ioc->name, ioc->spi_data.nvram, sz));
5381 }
5382
5383
5384
5385 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5386 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5387 }
5388
5389
5390
5391 header.PageVersion = 0;
5392 header.PageLength = 0;
5393 header.PageNumber = 0;
5394 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5395 cfg.cfghdr.hdr = &header;
5396 cfg.physAddr = -1;
5397 cfg.pageAddr = portnum;
5398 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5399 cfg.dir = 0;
5400 cfg.timeout = 0;
5401 if (mpt_config(ioc, &cfg) != 0)
5402 return -EFAULT;
5403
5404 if (header.PageLength > 0) {
5405 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5406 if (pbuf) {
5407 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5408 cfg.physAddr = buf_dma;
5409 if (mpt_config(ioc, &cfg) != 0) {
5410 ioc->spi_data.maxBusWidth = MPT_NARROW;
5411 ioc->spi_data.maxSyncOffset = 0;
5412 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5413 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5414 rc = 1;
5415 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5416 "Unable to read PortPage0 minSyncFactor=%x\n",
5417 ioc->name, ioc->spi_data.minSyncFactor));
5418 } else {
5419
5420
5421 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5422 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5423 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5424
5425 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5426 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5427 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5428 "noQas due to Capabilities=%x\n",
5429 ioc->name, pPP0->Capabilities));
5430 }
5431 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5432 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5433 if (data) {
5434 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5435 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5436 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5437 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5438 "PortPage0 minSyncFactor=%x\n",
5439 ioc->name, ioc->spi_data.minSyncFactor));
5440 } else {
5441 ioc->spi_data.maxSyncOffset = 0;
5442 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5443 }
5444
5445 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5446
5447
5448
5449 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5450 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5451
5452 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5453 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5454 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5455 "HVD or SE detected, minSyncFactor=%x\n",
5456 ioc->name, ioc->spi_data.minSyncFactor));
5457 }
5458 }
5459 }
5460 if (pbuf) {
5461 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5462 }
5463 }
5464 }
5465
5466
5467
5468 header.PageVersion = 0;
5469 header.PageLength = 0;
5470 header.PageNumber = 2;
5471 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5472 cfg.cfghdr.hdr = &header;
5473 cfg.physAddr = -1;
5474 cfg.pageAddr = portnum;
5475 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5476 cfg.dir = 0;
5477 if (mpt_config(ioc, &cfg) != 0)
5478 return -EFAULT;
5479
5480 if (header.PageLength > 0) {
5481
5482
5483 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5484 if (pbuf) {
5485 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5486 cfg.physAddr = buf_dma;
5487 if (mpt_config(ioc, &cfg) != 0) {
5488
5489
5490 rc = 1;
5491 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5492
5493
5494
5495 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5496 ATTODeviceInfo_t *pdevice = NULL;
5497 u16 ATTOFlags;
5498
5499
5500
5501
5502 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5503 pdevice = &pPP2->DeviceSettings[ii];
5504 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5505 data = 0;
5506
5507
5508
5509 if (ATTOFlags & ATTOFLAG_DISC)
5510 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5511 if (ATTOFlags & ATTOFLAG_ID_ENB)
5512 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5513 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5514 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5515 if (ATTOFlags & ATTOFLAG_TAGGED)
5516 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5517 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5518 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5519
5520 data = (data << 16) | (pdevice->Period << 8) | 10;
5521 ioc->spi_data.nvram[ii] = data;
5522 }
5523 } else {
5524 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5525 MpiDeviceInfo_t *pdevice = NULL;
5526
5527
5528
5529
5530 ioc->spi_data.bus_reset =
5531 (le32_to_cpu(pPP2->PortFlags) &
5532 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5533 0 : 1 ;
5534
5535
5536
5537
5538 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5539 ioc->spi_data.PortFlags = data;
5540 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5541 pdevice = &pPP2->DeviceSettings[ii];
5542 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5543 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5544 ioc->spi_data.nvram[ii] = data;
5545 }
5546 }
5547
5548 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5549 }
5550 }
5551
5552
5553
5554
5555
5556
5557 return rc;
5558}
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569static int
5570mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5571{
5572 CONFIGPARMS cfg;
5573 ConfigPageHeader_t header;
5574
5575
5576
5577 header.PageVersion = 0;
5578 header.PageLength = 0;
5579 header.PageNumber = 1;
5580 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5581 cfg.cfghdr.hdr = &header;
5582 cfg.physAddr = -1;
5583 cfg.pageAddr = portnum;
5584 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5585 cfg.dir = 0;
5586 cfg.timeout = 0;
5587 if (mpt_config(ioc, &cfg) != 0)
5588 return -EFAULT;
5589
5590 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5591 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5592
5593 header.PageVersion = 0;
5594 header.PageLength = 0;
5595 header.PageNumber = 0;
5596 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5597 if (mpt_config(ioc, &cfg) != 0)
5598 return -EFAULT;
5599
5600 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5601 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5602
5603 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5604 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5605
5606 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5607 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5608 return 0;
5609}
5610
5611
5612
5613
5614
5615static void
5616mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5617{
5618 struct inactive_raid_component_info *component_info, *pNext;
5619
5620 if (list_empty(&ioc->raid_data.inactive_list))
5621 return;
5622
5623 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5624 list_for_each_entry_safe(component_info, pNext,
5625 &ioc->raid_data.inactive_list, list) {
5626 list_del(&component_info->list);
5627 kfree(component_info);
5628 }
5629 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5630}
5631
5632
5633
5634
5635
5636
5637
5638
5639static void
5640mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5641{
5642 CONFIGPARMS cfg;
5643 ConfigPageHeader_t hdr;
5644 dma_addr_t dma_handle;
5645 pRaidVolumePage0_t buffer = NULL;
5646 int i;
5647 RaidPhysDiskPage0_t phys_disk;
5648 struct inactive_raid_component_info *component_info;
5649 int handle_inactive_volumes;
5650
5651 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5652 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5653 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5654 cfg.pageAddr = (channel << 8) + id;
5655 cfg.cfghdr.hdr = &hdr;
5656 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5657
5658 if (mpt_config(ioc, &cfg) != 0)
5659 goto out;
5660
5661 if (!hdr.PageLength)
5662 goto out;
5663
5664 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5665 &dma_handle);
5666
5667 if (!buffer)
5668 goto out;
5669
5670 cfg.physAddr = dma_handle;
5671 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5672
5673 if (mpt_config(ioc, &cfg) != 0)
5674 goto out;
5675
5676 if (!buffer->NumPhysDisks)
5677 goto out;
5678
5679 handle_inactive_volumes =
5680 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5681 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5682 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5683 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5684
5685 if (!handle_inactive_volumes)
5686 goto out;
5687
5688 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5689 for (i = 0; i < buffer->NumPhysDisks; i++) {
5690 if(mpt_raid_phys_disk_pg0(ioc,
5691 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5692 continue;
5693
5694 if ((component_info = kmalloc(sizeof (*component_info),
5695 GFP_KERNEL)) == NULL)
5696 continue;
5697
5698 component_info->volumeID = id;
5699 component_info->volumeBus = channel;
5700 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5701 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5702 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5703 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5704
5705 list_add_tail(&component_info->list,
5706 &ioc->raid_data.inactive_list);
5707 }
5708 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5709
5710 out:
5711 if (buffer)
5712 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5713 dma_handle);
5714}
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727int
5728mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5729 RaidPhysDiskPage0_t *phys_disk)
5730{
5731 CONFIGPARMS cfg;
5732 ConfigPageHeader_t hdr;
5733 dma_addr_t dma_handle;
5734 pRaidPhysDiskPage0_t buffer = NULL;
5735 int rc;
5736
5737 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5738 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5739 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5740
5741 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5742 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5743 cfg.cfghdr.hdr = &hdr;
5744 cfg.physAddr = -1;
5745 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5746
5747 if (mpt_config(ioc, &cfg) != 0) {
5748 rc = -EFAULT;
5749 goto out;
5750 }
5751
5752 if (!hdr.PageLength) {
5753 rc = -EFAULT;
5754 goto out;
5755 }
5756
5757 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5758 &dma_handle);
5759
5760 if (!buffer) {
5761 rc = -ENOMEM;
5762 goto out;
5763 }
5764
5765 cfg.physAddr = dma_handle;
5766 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5767 cfg.pageAddr = phys_disk_num;
5768
5769 if (mpt_config(ioc, &cfg) != 0) {
5770 rc = -EFAULT;
5771 goto out;
5772 }
5773
5774 rc = 0;
5775 memcpy(phys_disk, buffer, sizeof(*buffer));
5776 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5777
5778 out:
5779
5780 if (buffer)
5781 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5782 dma_handle);
5783
5784 return rc;
5785}
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795int
5796mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5797{
5798 CONFIGPARMS cfg;
5799 ConfigPageHeader_t hdr;
5800 dma_addr_t dma_handle;
5801 pRaidPhysDiskPage1_t buffer = NULL;
5802 int rc;
5803
5804 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5805 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5806
5807 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5808 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5809 hdr.PageNumber = 1;
5810 cfg.cfghdr.hdr = &hdr;
5811 cfg.physAddr = -1;
5812 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5813
5814 if (mpt_config(ioc, &cfg) != 0) {
5815 rc = 0;
5816 goto out;
5817 }
5818
5819 if (!hdr.PageLength) {
5820 rc = 0;
5821 goto out;
5822 }
5823
5824 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5825 &dma_handle);
5826
5827 if (!buffer) {
5828 rc = 0;
5829 goto out;
5830 }
5831
5832 cfg.physAddr = dma_handle;
5833 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5834 cfg.pageAddr = phys_disk_num;
5835
5836 if (mpt_config(ioc, &cfg) != 0) {
5837 rc = 0;
5838 goto out;
5839 }
5840
5841 rc = buffer->NumPhysDiskPaths;
5842 out:
5843
5844 if (buffer)
5845 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5846 dma_handle);
5847
5848 return rc;
5849}
5850EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863int
5864mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5865 RaidPhysDiskPage1_t *phys_disk)
5866{
5867 CONFIGPARMS cfg;
5868 ConfigPageHeader_t hdr;
5869 dma_addr_t dma_handle;
5870 pRaidPhysDiskPage1_t buffer = NULL;
5871 int rc;
5872 int i;
5873 __le64 sas_address;
5874
5875 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5876 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5877 rc = 0;
5878
5879 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5880 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5881 hdr.PageNumber = 1;
5882 cfg.cfghdr.hdr = &hdr;
5883 cfg.physAddr = -1;
5884 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5885
5886 if (mpt_config(ioc, &cfg) != 0) {
5887 rc = -EFAULT;
5888 goto out;
5889 }
5890
5891 if (!hdr.PageLength) {
5892 rc = -EFAULT;
5893 goto out;
5894 }
5895
5896 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5897 &dma_handle);
5898
5899 if (!buffer) {
5900 rc = -ENOMEM;
5901 goto out;
5902 }
5903
5904 cfg.physAddr = dma_handle;
5905 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5906 cfg.pageAddr = phys_disk_num;
5907
5908 if (mpt_config(ioc, &cfg) != 0) {
5909 rc = -EFAULT;
5910 goto out;
5911 }
5912
5913 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5914 phys_disk->PhysDiskNum = phys_disk_num;
5915 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5916 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5917 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5918 phys_disk->Path[i].OwnerIdentifier =
5919 buffer->Path[i].OwnerIdentifier;
5920 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5921 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5922 sas_address = le64_to_cpu(sas_address);
5923 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5924 memcpy(&sas_address,
5925 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5926 sas_address = le64_to_cpu(sas_address);
5927 memcpy(&phys_disk->Path[i].OwnerWWID,
5928 &sas_address, sizeof(__le64));
5929 }
5930
5931 out:
5932
5933 if (buffer)
5934 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5935 dma_handle);
5936
5937 return rc;
5938}
5939EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951int
5952mpt_findImVolumes(MPT_ADAPTER *ioc)
5953{
5954 IOCPage2_t *pIoc2;
5955 u8 *mem;
5956 dma_addr_t ioc2_dma;
5957 CONFIGPARMS cfg;
5958 ConfigPageHeader_t header;
5959 int rc = 0;
5960 int iocpage2sz;
5961 int i;
5962
5963 if (!ioc->ir_firmware)
5964 return 0;
5965
5966
5967
5968 kfree(ioc->raid_data.pIocPg2);
5969 ioc->raid_data.pIocPg2 = NULL;
5970 mpt_inactive_raid_list_free(ioc);
5971
5972
5973
5974 header.PageVersion = 0;
5975 header.PageLength = 0;
5976 header.PageNumber = 2;
5977 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5978 cfg.cfghdr.hdr = &header;
5979 cfg.physAddr = -1;
5980 cfg.pageAddr = 0;
5981 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5982 cfg.dir = 0;
5983 cfg.timeout = 0;
5984 if (mpt_config(ioc, &cfg) != 0)
5985 return -EFAULT;
5986
5987 if (header.PageLength == 0)
5988 return -EFAULT;
5989
5990 iocpage2sz = header.PageLength * 4;
5991 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5992 if (!pIoc2)
5993 return -ENOMEM;
5994
5995 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5996 cfg.physAddr = ioc2_dma;
5997 if (mpt_config(ioc, &cfg) != 0)
5998 goto out;
5999
6000 mem = kmemdup(pIoc2, iocpage2sz, GFP_KERNEL);
6001 if (!mem) {
6002 rc = -ENOMEM;
6003 goto out;
6004 }
6005
6006 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6007
6008 mpt_read_ioc_pg_3(ioc);
6009
6010 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6011 mpt_inactive_raid_volumes(ioc,
6012 pIoc2->RaidVolume[i].VolumeBus,
6013 pIoc2->RaidVolume[i].VolumeID);
6014
6015 out:
6016 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
6017
6018 return rc;
6019}
6020
6021static int
6022mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6023{
6024 IOCPage3_t *pIoc3;
6025 u8 *mem;
6026 CONFIGPARMS cfg;
6027 ConfigPageHeader_t header;
6028 dma_addr_t ioc3_dma;
6029 int iocpage3sz = 0;
6030
6031
6032
6033 kfree(ioc->raid_data.pIocPg3);
6034 ioc->raid_data.pIocPg3 = NULL;
6035
6036
6037
6038
6039 header.PageVersion = 0;
6040 header.PageLength = 0;
6041 header.PageNumber = 3;
6042 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6043 cfg.cfghdr.hdr = &header;
6044 cfg.physAddr = -1;
6045 cfg.pageAddr = 0;
6046 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6047 cfg.dir = 0;
6048 cfg.timeout = 0;
6049 if (mpt_config(ioc, &cfg) != 0)
6050 return 0;
6051
6052 if (header.PageLength == 0)
6053 return 0;
6054
6055
6056
6057 iocpage3sz = header.PageLength * 4;
6058 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6059 if (!pIoc3)
6060 return 0;
6061
6062
6063
6064
6065 cfg.physAddr = ioc3_dma;
6066 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6067 if (mpt_config(ioc, &cfg) == 0) {
6068 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6069 if (mem) {
6070 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6071 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6072 }
6073 }
6074
6075 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6076
6077 return 0;
6078}
6079
6080static void
6081mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6082{
6083 IOCPage4_t *pIoc4;
6084 CONFIGPARMS cfg;
6085 ConfigPageHeader_t header;
6086 dma_addr_t ioc4_dma;
6087 int iocpage4sz;
6088
6089
6090
6091 header.PageVersion = 0;
6092 header.PageLength = 0;
6093 header.PageNumber = 4;
6094 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6095 cfg.cfghdr.hdr = &header;
6096 cfg.physAddr = -1;
6097 cfg.pageAddr = 0;
6098 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6099 cfg.dir = 0;
6100 cfg.timeout = 0;
6101 if (mpt_config(ioc, &cfg) != 0)
6102 return;
6103
6104 if (header.PageLength == 0)
6105 return;
6106
6107 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6108 iocpage4sz = (header.PageLength + 4) * 4;
6109 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6110 if (!pIoc4)
6111 return;
6112 ioc->alloc_total += iocpage4sz;
6113 } else {
6114 ioc4_dma = ioc->spi_data.IocPg4_dma;
6115 iocpage4sz = ioc->spi_data.IocPg4Sz;
6116 }
6117
6118
6119
6120 cfg.physAddr = ioc4_dma;
6121 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6122 if (mpt_config(ioc, &cfg) == 0) {
6123 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6124 ioc->spi_data.IocPg4_dma = ioc4_dma;
6125 ioc->spi_data.IocPg4Sz = iocpage4sz;
6126 } else {
6127 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6128 ioc->spi_data.pIocPg4 = NULL;
6129 ioc->alloc_total -= iocpage4sz;
6130 }
6131}
6132
6133static void
6134mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6135{
6136 IOCPage1_t *pIoc1;
6137 CONFIGPARMS cfg;
6138 ConfigPageHeader_t header;
6139 dma_addr_t ioc1_dma;
6140 int iocpage1sz = 0;
6141 u32 tmp;
6142
6143
6144
6145 header.PageVersion = 0;
6146 header.PageLength = 0;
6147 header.PageNumber = 1;
6148 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6149 cfg.cfghdr.hdr = &header;
6150 cfg.physAddr = -1;
6151 cfg.pageAddr = 0;
6152 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6153 cfg.dir = 0;
6154 cfg.timeout = 0;
6155 if (mpt_config(ioc, &cfg) != 0)
6156 return;
6157
6158 if (header.PageLength == 0)
6159 return;
6160
6161
6162
6163 iocpage1sz = header.PageLength * 4;
6164 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6165 if (!pIoc1)
6166 return;
6167
6168
6169
6170 cfg.physAddr = ioc1_dma;
6171 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6172 if (mpt_config(ioc, &cfg) == 0) {
6173
6174 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6175 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6176 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6177
6178 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6179 ioc->name, tmp));
6180
6181 if (tmp > MPT_COALESCING_TIMEOUT) {
6182 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6183
6184
6185
6186 cfg.dir = 1;
6187 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6188 if (mpt_config(ioc, &cfg) == 0) {
6189 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6190 ioc->name, MPT_COALESCING_TIMEOUT));
6191
6192 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6193 if (mpt_config(ioc, &cfg) == 0) {
6194 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6195 "Reset NVRAM Coalescing Timeout to = %d\n",
6196 ioc->name, MPT_COALESCING_TIMEOUT));
6197 } else {
6198 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6199 "Reset NVRAM Coalescing Timeout Failed\n",
6200 ioc->name));
6201 }
6202
6203 } else {
6204 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6205 "Reset of Current Coalescing Timeout Failed!\n",
6206 ioc->name));
6207 }
6208 }
6209
6210 } else {
6211 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6212 }
6213 }
6214
6215 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6216
6217 return;
6218}
6219
6220static void
6221mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6222{
6223 CONFIGPARMS cfg;
6224 ConfigPageHeader_t hdr;
6225 dma_addr_t buf_dma;
6226 ManufacturingPage0_t *pbuf = NULL;
6227
6228 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6229 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6230
6231 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6232 cfg.cfghdr.hdr = &hdr;
6233 cfg.physAddr = -1;
6234 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6235 cfg.timeout = 10;
6236
6237 if (mpt_config(ioc, &cfg) != 0)
6238 goto out;
6239
6240 if (!cfg.cfghdr.hdr->PageLength)
6241 goto out;
6242
6243 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6244 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6245 if (!pbuf)
6246 goto out;
6247
6248 cfg.physAddr = buf_dma;
6249
6250 if (mpt_config(ioc, &cfg) != 0)
6251 goto out;
6252
6253 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6254 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6255 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6256
6257out:
6258
6259 if (pbuf)
6260 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6261}
6262
6263
6264
6265
6266
6267
6268
6269
6270static int
6271SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6272{
6273 EventNotification_t evn;
6274 MPIDefaultReply_t reply_buf;
6275
6276 memset(&evn, 0, sizeof(EventNotification_t));
6277 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6278
6279 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6280 evn.Switch = EvSwitch;
6281 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6282
6283 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6284 "Sending EventNotification (%d) request %p\n",
6285 ioc->name, EvSwitch, &evn));
6286
6287 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6288 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6289 sleepFlag);
6290}
6291
6292
6293
6294
6295
6296
6297
6298static int
6299SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6300{
6301 EventAck_t *pAck;
6302
6303 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6304 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6305 ioc->name, __func__));
6306 return -1;
6307 }
6308
6309 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6310
6311 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6312 pAck->ChainOffset = 0;
6313 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6314 pAck->MsgFlags = 0;
6315 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6316 pAck->Event = evnp->Event;
6317 pAck->EventContext = evnp->EventContext;
6318
6319 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6320
6321 return 0;
6322}
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337int
6338mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6339{
6340 Config_t *pReq;
6341 ConfigReply_t *pReply;
6342 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6343 MPT_FRAME_HDR *mf;
6344 int ii;
6345 int flagsLength;
6346 long timeout;
6347 int ret;
6348 u8 page_type = 0, extend_page;
6349 unsigned long timeleft;
6350 unsigned long flags;
6351 u8 issue_hard_reset = 0;
6352 u8 retry_count = 0;
6353
6354 might_sleep();
6355
6356
6357 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6358 if (ioc->ioc_reset_in_progress) {
6359 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6360 "%s: busy with host reset\n", ioc->name, __func__));
6361 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6362 return -EBUSY;
6363 }
6364 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6365
6366
6367 if (!ioc->active ||
6368 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6369 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6370 "%s: ioc not operational, %d, %xh\n",
6371 ioc->name, __func__, ioc->active,
6372 mpt_GetIocState(ioc, 0)));
6373 return -EFAULT;
6374 }
6375
6376 retry_config:
6377 mutex_lock(&ioc->mptbase_cmds.mutex);
6378
6379 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6380 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6381
6382
6383
6384 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6385 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6386 "mpt_config: no msg frames!\n", ioc->name));
6387 ret = -EAGAIN;
6388 goto out;
6389 }
6390
6391 pReq = (Config_t *)mf;
6392 pReq->Action = pCfg->action;
6393 pReq->Reserved = 0;
6394 pReq->ChainOffset = 0;
6395 pReq->Function = MPI_FUNCTION_CONFIG;
6396
6397
6398 pReq->ExtPageLength = 0;
6399 pReq->ExtPageType = 0;
6400 pReq->MsgFlags = 0;
6401
6402 for (ii=0; ii < 8; ii++)
6403 pReq->Reserved2[ii] = 0;
6404
6405 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6406 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6407 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6408 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6409
6410 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6411 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6412 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6413 pReq->ExtPageType = pExtHdr->ExtPageType;
6414 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6415
6416
6417
6418
6419 pReq->Header.PageLength = 0;
6420 }
6421
6422 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6423
6424
6425
6426 if (pCfg->dir)
6427 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6428 else
6429 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6430
6431 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6432 MPI_CONFIG_PAGETYPE_EXTENDED) {
6433 flagsLength |= pExtHdr->ExtPageLength * 4;
6434 page_type = pReq->ExtPageType;
6435 extend_page = 1;
6436 } else {
6437 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6438 page_type = pReq->Header.PageType;
6439 extend_page = 0;
6440 }
6441
6442 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6443 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6444 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6445
6446 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6447 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6448 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6449 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6450 timeout);
6451 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6452 ret = -ETIME;
6453 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6454 "Failed Sending Config request type 0x%x, page 0x%x,"
6455 " action %d, status %xh, time left %ld\n\n",
6456 ioc->name, page_type, pReq->Header.PageNumber,
6457 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6458 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6459 goto out;
6460 if (!timeleft) {
6461 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6462 if (ioc->ioc_reset_in_progress) {
6463 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6464 flags);
6465 printk(MYIOC_s_INFO_FMT "%s: host reset in"
6466 " progress mpt_config timed out.!!\n",
6467 __func__, ioc->name);
6468 mutex_unlock(&ioc->mptbase_cmds.mutex);
6469 return -EFAULT;
6470 }
6471 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6472 issue_hard_reset = 1;
6473 }
6474 goto out;
6475 }
6476
6477 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6478 ret = -1;
6479 goto out;
6480 }
6481 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6482 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6483 if (ret == MPI_IOCSTATUS_SUCCESS) {
6484 if (extend_page) {
6485 pCfg->cfghdr.ehdr->ExtPageLength =
6486 le16_to_cpu(pReply->ExtPageLength);
6487 pCfg->cfghdr.ehdr->ExtPageType =
6488 pReply->ExtPageType;
6489 }
6490 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6491 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6492 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6493 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6494
6495 }
6496
6497 if (retry_count)
6498 printk(MYIOC_s_INFO_FMT "Retry completed "
6499 "ret=0x%x timeleft=%ld\n",
6500 ioc->name, ret, timeleft);
6501
6502 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6503 ret, le32_to_cpu(pReply->IOCLogInfo)));
6504
6505out:
6506
6507 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6508 mutex_unlock(&ioc->mptbase_cmds.mutex);
6509 if (issue_hard_reset) {
6510 issue_hard_reset = 0;
6511 printk(MYIOC_s_WARN_FMT
6512 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6513 ioc->name, __func__, mpt_GetIocState(ioc, 0));
6514 if (retry_count == 0) {
6515 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6516 retry_count++;
6517 } else
6518 mpt_HardResetHandler(ioc, CAN_SLEEP);
6519
6520 mpt_free_msg_frame(ioc, mf);
6521
6522 if (retry_count < 2) {
6523 printk(MYIOC_s_INFO_FMT
6524 "Attempting Retry Config request"
6525 " type 0x%x, page 0x%x,"
6526 " action %d\n", ioc->name, page_type,
6527 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6528 retry_count++;
6529 goto retry_config;
6530 }
6531 }
6532 return ret;
6533
6534}
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544static int
6545mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6546{
6547 switch (reset_phase) {
6548 case MPT_IOC_SETUP_RESET:
6549 ioc->taskmgmt_quiesce_io = 1;
6550 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6551 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6552 break;
6553 case MPT_IOC_PRE_RESET:
6554 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6555 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6556 break;
6557 case MPT_IOC_POST_RESET:
6558 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6559 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6560
6561 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6562 ioc->mptbase_cmds.status |=
6563 MPT_MGMT_STATUS_DID_IOCRESET;
6564 complete(&ioc->mptbase_cmds.done);
6565 }
6566
6567 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6568 ioc->taskmgmt_cmds.status |=
6569 MPT_MGMT_STATUS_DID_IOCRESET;
6570 complete(&ioc->taskmgmt_cmds.done);
6571 }
6572 break;
6573 default:
6574 break;
6575 }
6576
6577 return 1;
6578}
6579
6580
6581#ifdef CONFIG_PROC_FS
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592static int
6593procmpt_create(void)
6594{
6595 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6596 if (mpt_proc_root_dir == NULL)
6597 return -ENOTDIR;
6598
6599 proc_create_single("summary", S_IRUGO, mpt_proc_root_dir,
6600 mpt_summary_proc_show);
6601 proc_create_single("version", S_IRUGO, mpt_proc_root_dir,
6602 mpt_version_proc_show);
6603 return 0;
6604}
6605
6606
6607
6608
6609
6610
6611
6612static void
6613procmpt_destroy(void)
6614{
6615 remove_proc_entry("version", mpt_proc_root_dir);
6616 remove_proc_entry("summary", mpt_proc_root_dir);
6617 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6618}
6619
6620
6621
6622
6623
6624static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6625
6626static int mpt_summary_proc_show(struct seq_file *m, void *v)
6627{
6628 MPT_ADAPTER *ioc = m->private;
6629
6630 if (ioc) {
6631 seq_mpt_print_ioc_summary(ioc, m, 1);
6632 } else {
6633 list_for_each_entry(ioc, &ioc_list, list) {
6634 seq_mpt_print_ioc_summary(ioc, m, 1);
6635 }
6636 }
6637
6638 return 0;
6639}
6640
6641static int mpt_version_proc_show(struct seq_file *m, void *v)
6642{
6643 u8 cb_idx;
6644 int scsi, fc, sas, lan, ctl, targ, dmp;
6645 char *drvname;
6646
6647 seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6648 seq_printf(m, " Fusion MPT base driver\n");
6649
6650 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6651 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6652 drvname = NULL;
6653 if (MptCallbacks[cb_idx]) {
6654 switch (MptDriverClass[cb_idx]) {
6655 case MPTSPI_DRIVER:
6656 if (!scsi++) drvname = "SPI host";
6657 break;
6658 case MPTFC_DRIVER:
6659 if (!fc++) drvname = "FC host";
6660 break;
6661 case MPTSAS_DRIVER:
6662 if (!sas++) drvname = "SAS host";
6663 break;
6664 case MPTLAN_DRIVER:
6665 if (!lan++) drvname = "LAN";
6666 break;
6667 case MPTSTM_DRIVER:
6668 if (!targ++) drvname = "SCSI target";
6669 break;
6670 case MPTCTL_DRIVER:
6671 if (!ctl++) drvname = "ioctl";
6672 break;
6673 }
6674
6675 if (drvname)
6676 seq_printf(m, " Fusion MPT %s driver\n", drvname);
6677 }
6678 }
6679
6680 return 0;
6681}
6682
6683static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6684{
6685 MPT_ADAPTER *ioc = m->private;
6686 char expVer[32];
6687 int sz;
6688 int p;
6689
6690 mpt_get_fw_exp_ver(expVer, ioc);
6691
6692 seq_printf(m, "%s:", ioc->name);
6693 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6694 seq_printf(m, " (f/w download boot flag set)");
6695
6696
6697
6698 seq_printf(m, "\n ProductID = 0x%04x (%s)\n",
6699 ioc->facts.ProductID,
6700 ioc->prod_name);
6701 seq_printf(m, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6702 if (ioc->facts.FWImageSize)
6703 seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6704 seq_printf(m, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6705 seq_printf(m, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6706 seq_printf(m, " EventState = 0x%02x\n", ioc->facts.EventState);
6707
6708 seq_printf(m, " CurrentHostMfaHighAddr = 0x%08x\n",
6709 ioc->facts.CurrentHostMfaHighAddr);
6710 seq_printf(m, " CurrentSenseBufferHighAddr = 0x%08x\n",
6711 ioc->facts.CurrentSenseBufferHighAddr);
6712
6713 seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6714 seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6715
6716 seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6717 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6718
6719
6720
6721 sz = (ioc->req_sz * ioc->req_depth) + 128;
6722 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6723 seq_printf(m, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6724 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6725 seq_printf(m, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6726 4*ioc->facts.RequestFrameSize,
6727 ioc->facts.GlobalCredits);
6728
6729 seq_printf(m, " Frames @ 0x%p (Dma @ 0x%p)\n",
6730 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6731 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6732 seq_printf(m, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6733 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6734 seq_printf(m, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6735 ioc->facts.CurReplyFrameSize,
6736 ioc->facts.ReplyQueueDepth);
6737
6738 seq_printf(m, " MaxDevices = %d\n",
6739 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6740 seq_printf(m, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6741
6742
6743 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6744 seq_printf(m, " PortNumber = %d (of %d)\n",
6745 p+1,
6746 ioc->facts.NumberOfPorts);
6747 if (ioc->bus_type == FC) {
6748 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6749 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6750 seq_printf(m, " LanAddr = %pMR\n", a);
6751 }
6752 seq_printf(m, " WWN = %08X%08X:%08X%08X\n",
6753 ioc->fc_port_page0[p].WWNN.High,
6754 ioc->fc_port_page0[p].WWNN.Low,
6755 ioc->fc_port_page0[p].WWPN.High,
6756 ioc->fc_port_page0[p].WWPN.Low);
6757 }
6758 }
6759
6760 return 0;
6761}
6762#endif
6763
6764
6765static void
6766mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6767{
6768 buf[0] ='\0';
6769 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6770 sprintf(buf, " (Exp %02d%02d)",
6771 (ioc->facts.FWVersion.Word >> 16) & 0x00FF,
6772 (ioc->facts.FWVersion.Word >> 8) & 0x1F);
6773
6774
6775 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6776 strcat(buf, " [MDBG]");
6777 }
6778}
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792void
6793mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6794{
6795 char expVer[32];
6796 int y;
6797
6798 mpt_get_fw_exp_ver(expVer, ioc);
6799
6800
6801
6802
6803 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6804 ioc->name,
6805 ioc->prod_name,
6806 MPT_FW_REV_MAGIC_ID_STRING,
6807 ioc->facts.FWVersion.Word,
6808 expVer,
6809 ioc->facts.NumberOfPorts,
6810 ioc->req_depth);
6811
6812 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6813 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6814 y += sprintf(buffer+len+y, ", LanAddr=%pMR", a);
6815 }
6816
6817 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6818
6819 if (!ioc->active)
6820 y += sprintf(buffer+len+y, " (disabled)");
6821
6822 y += sprintf(buffer+len+y, "\n");
6823
6824 *size = y;
6825}
6826
6827#ifdef CONFIG_PROC_FS
6828static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6829{
6830 char expVer[32];
6831
6832 mpt_get_fw_exp_ver(expVer, ioc);
6833
6834
6835
6836
6837 seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6838 ioc->name,
6839 ioc->prod_name,
6840 MPT_FW_REV_MAGIC_ID_STRING,
6841 ioc->facts.FWVersion.Word,
6842 expVer,
6843 ioc->facts.NumberOfPorts,
6844 ioc->req_depth);
6845
6846 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6847 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6848 seq_printf(m, ", LanAddr=%pMR", a);
6849 }
6850
6851 seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6852
6853 if (!ioc->active)
6854 seq_printf(m, " (disabled)");
6855
6856 seq_putc(m, '\n');
6857}
6858#endif
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868int
6869mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6870{
6871 unsigned long flags;
6872 int retval;
6873
6874 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6875 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6876 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6877 retval = -1;
6878 goto out;
6879 }
6880 retval = 0;
6881 ioc->taskmgmt_in_progress = 1;
6882 ioc->taskmgmt_quiesce_io = 1;
6883 if (ioc->alt_ioc) {
6884 ioc->alt_ioc->taskmgmt_in_progress = 1;
6885 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6886 }
6887 out:
6888 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6889 return retval;
6890}
6891EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6892
6893
6894
6895
6896
6897
6898void
6899mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6900{
6901 unsigned long flags;
6902
6903 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6904 ioc->taskmgmt_in_progress = 0;
6905 ioc->taskmgmt_quiesce_io = 0;
6906 if (ioc->alt_ioc) {
6907 ioc->alt_ioc->taskmgmt_in_progress = 0;
6908 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6909 }
6910 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6911}
6912EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6913
6914
6915
6916
6917
6918
6919
6920
6921void
6922mpt_halt_firmware(MPT_ADAPTER *ioc)
6923{
6924 u32 ioc_raw_state;
6925
6926 ioc_raw_state = mpt_GetIocState(ioc, 0);
6927
6928 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6929 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6930 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6931 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6932 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6933 } else {
6934 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6935 panic("%s: Firmware is halted due to command timeout\n",
6936 ioc->name);
6937 }
6938}
6939EXPORT_SYMBOL(mpt_halt_firmware);
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954static int
6955mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6956{
6957 int rc;
6958 int ii;
6959 u8 cb_idx;
6960 unsigned long flags;
6961 u32 ioc_state;
6962 unsigned long time_count;
6963
6964 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6965 ioc->name));
6966
6967 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6968
6969 if (mpt_fwfault_debug)
6970 mpt_halt_firmware(ioc);
6971
6972 if (ioc_state == MPI_IOC_STATE_FAULT ||
6973 ioc_state == MPI_IOC_STATE_RESET) {
6974 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6975 "skipping, either in FAULT or RESET state!\n", ioc->name));
6976 return -1;
6977 }
6978
6979 if (ioc->bus_type == FC) {
6980 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6981 "skipping, because the bus type is FC!\n", ioc->name));
6982 return -1;
6983 }
6984
6985 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6986 if (ioc->ioc_reset_in_progress) {
6987 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6988 return -1;
6989 }
6990 ioc->ioc_reset_in_progress = 1;
6991 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6992
6993 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6994 if (MptResetHandlers[cb_idx])
6995 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6996 }
6997
6998 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6999 if (ioc->taskmgmt_in_progress) {
7000 ioc->ioc_reset_in_progress = 0;
7001 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7002 return -1;
7003 }
7004 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7005
7006 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7007 ioc->active = 0;
7008 time_count = jiffies;
7009
7010 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7011
7012 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7013 if (MptResetHandlers[cb_idx])
7014 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7015 }
7016
7017 if (rc)
7018 goto out;
7019
7020 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7021 if (ioc_state != MPI_IOC_STATE_READY)
7022 goto out;
7023
7024 for (ii = 0; ii < 5; ii++) {
7025
7026 rc = GetIocFacts(ioc, sleepFlag,
7027 MPT_HOSTEVENT_IOC_RECOVER);
7028 if (rc == 0)
7029 break;
7030 if (sleepFlag == CAN_SLEEP)
7031 msleep(100);
7032 else
7033 mdelay(100);
7034 }
7035 if (ii == 5)
7036 goto out;
7037
7038 rc = PrimeIocFifos(ioc);
7039 if (rc != 0)
7040 goto out;
7041
7042 rc = SendIocInit(ioc, sleepFlag);
7043 if (rc != 0)
7044 goto out;
7045
7046 rc = SendEventNotification(ioc, 1, sleepFlag);
7047 if (rc != 0)
7048 goto out;
7049
7050 if (ioc->hard_resets < -1)
7051 ioc->hard_resets++;
7052
7053
7054
7055
7056
7057 ioc->active = 1;
7058 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7059
7060 out:
7061 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7062 ioc->ioc_reset_in_progress = 0;
7063 ioc->taskmgmt_quiesce_io = 0;
7064 ioc->taskmgmt_in_progress = 0;
7065 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7066
7067 if (ioc->active) {
7068 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7069 if (MptResetHandlers[cb_idx])
7070 mpt_signal_reset(cb_idx, ioc,
7071 MPT_IOC_POST_RESET);
7072 }
7073 }
7074
7075 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7076 "SoftResetHandler: completed (%d seconds): %s\n",
7077 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7078 ((rc == 0) ? "SUCCESS" : "FAILED")));
7079
7080 return rc;
7081}
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092int
7093mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7094 int ret = -1;
7095
7096 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7097 if (ret == 0)
7098 return ret;
7099 ret = mpt_HardResetHandler(ioc, sleepFlag);
7100 return ret;
7101}
7102EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125int
7126mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7127{
7128 int rc;
7129 u8 cb_idx;
7130 unsigned long flags;
7131 unsigned long time_count;
7132
7133 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7134#ifdef MFCNT
7135 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7136 printk("MF count 0x%x !\n", ioc->mfcnt);
7137#endif
7138 if (mpt_fwfault_debug)
7139 mpt_halt_firmware(ioc);
7140
7141
7142
7143
7144 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7145 if (ioc->ioc_reset_in_progress) {
7146 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7147 ioc->wait_on_reset_completion = 1;
7148 do {
7149 ssleep(1);
7150 } while (ioc->ioc_reset_in_progress == 1);
7151 ioc->wait_on_reset_completion = 0;
7152 return ioc->reset_status;
7153 }
7154 if (ioc->wait_on_reset_completion) {
7155 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7156 rc = 0;
7157 time_count = jiffies;
7158 goto exit;
7159 }
7160 ioc->ioc_reset_in_progress = 1;
7161 if (ioc->alt_ioc)
7162 ioc->alt_ioc->ioc_reset_in_progress = 1;
7163 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7164
7165
7166
7167
7168
7169
7170
7171 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7172 if (MptResetHandlers[cb_idx]) {
7173 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7174 if (ioc->alt_ioc)
7175 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7176 MPT_IOC_SETUP_RESET);
7177 }
7178 }
7179
7180 time_count = jiffies;
7181 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7182 if (rc != 0) {
7183 printk(KERN_WARNING MYNAM
7184 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7185 rc, ioc->name, mpt_GetIocState(ioc, 0));
7186 } else {
7187 if (ioc->hard_resets < -1)
7188 ioc->hard_resets++;
7189 }
7190
7191 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7192 ioc->ioc_reset_in_progress = 0;
7193 ioc->taskmgmt_quiesce_io = 0;
7194 ioc->taskmgmt_in_progress = 0;
7195 ioc->reset_status = rc;
7196 if (ioc->alt_ioc) {
7197 ioc->alt_ioc->ioc_reset_in_progress = 0;
7198 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7199 ioc->alt_ioc->taskmgmt_in_progress = 0;
7200 }
7201 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7202
7203 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7204 if (MptResetHandlers[cb_idx]) {
7205 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7206 if (ioc->alt_ioc)
7207 mpt_signal_reset(cb_idx,
7208 ioc->alt_ioc, MPT_IOC_POST_RESET);
7209 }
7210 }
7211exit:
7212 dtmprintk(ioc,
7213 printk(MYIOC_s_DEBUG_FMT
7214 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7215 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7216 "SUCCESS" : "FAILED")));
7217
7218 return rc;
7219}
7220
7221#ifdef CONFIG_FUSION_LOGGING
7222static void
7223mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7224{
7225 char *ds = NULL;
7226 u32 evData0;
7227 int ii;
7228 u8 event;
7229 char *evStr = ioc->evStr;
7230
7231 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7232 evData0 = le32_to_cpu(pEventReply->Data[0]);
7233
7234 switch(event) {
7235 case MPI_EVENT_NONE:
7236 ds = "None";
7237 break;
7238 case MPI_EVENT_LOG_DATA:
7239 ds = "Log Data";
7240 break;
7241 case MPI_EVENT_STATE_CHANGE:
7242 ds = "State Change";
7243 break;
7244 case MPI_EVENT_UNIT_ATTENTION:
7245 ds = "Unit Attention";
7246 break;
7247 case MPI_EVENT_IOC_BUS_RESET:
7248 ds = "IOC Bus Reset";
7249 break;
7250 case MPI_EVENT_EXT_BUS_RESET:
7251 ds = "External Bus Reset";
7252 break;
7253 case MPI_EVENT_RESCAN:
7254 ds = "Bus Rescan Event";
7255 break;
7256 case MPI_EVENT_LINK_STATUS_CHANGE:
7257 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7258 ds = "Link Status(FAILURE) Change";
7259 else
7260 ds = "Link Status(ACTIVE) Change";
7261 break;
7262 case MPI_EVENT_LOOP_STATE_CHANGE:
7263 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7264 ds = "Loop State(LIP) Change";
7265 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7266 ds = "Loop State(LPE) Change";
7267 else
7268 ds = "Loop State(LPB) Change";
7269 break;
7270 case MPI_EVENT_LOGOUT:
7271 ds = "Logout";
7272 break;
7273 case MPI_EVENT_EVENT_CHANGE:
7274 if (evData0)
7275 ds = "Events ON";
7276 else
7277 ds = "Events OFF";
7278 break;
7279 case MPI_EVENT_INTEGRATED_RAID:
7280 {
7281 u8 ReasonCode = (u8)(evData0 >> 16);
7282 switch (ReasonCode) {
7283 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7284 ds = "Integrated Raid: Volume Created";
7285 break;
7286 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7287 ds = "Integrated Raid: Volume Deleted";
7288 break;
7289 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7290 ds = "Integrated Raid: Volume Settings Changed";
7291 break;
7292 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7293 ds = "Integrated Raid: Volume Status Changed";
7294 break;
7295 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7296 ds = "Integrated Raid: Volume Physdisk Changed";
7297 break;
7298 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7299 ds = "Integrated Raid: Physdisk Created";
7300 break;
7301 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7302 ds = "Integrated Raid: Physdisk Deleted";
7303 break;
7304 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7305 ds = "Integrated Raid: Physdisk Settings Changed";
7306 break;
7307 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7308 ds = "Integrated Raid: Physdisk Status Changed";
7309 break;
7310 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7311 ds = "Integrated Raid: Domain Validation Needed";
7312 break;
7313 case MPI_EVENT_RAID_RC_SMART_DATA :
7314 ds = "Integrated Raid; Smart Data";
7315 break;
7316 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7317 ds = "Integrated Raid: Replace Action Started";
7318 break;
7319 default:
7320 ds = "Integrated Raid";
7321 break;
7322 }
7323 break;
7324 }
7325 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7326 ds = "SCSI Device Status Change";
7327 break;
7328 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7329 {
7330 u8 id = (u8)(evData0);
7331 u8 channel = (u8)(evData0 >> 8);
7332 u8 ReasonCode = (u8)(evData0 >> 16);
7333 switch (ReasonCode) {
7334 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7335 snprintf(evStr, EVENT_DESCR_STR_SZ,
7336 "SAS Device Status Change: Added: "
7337 "id=%d channel=%d", id, channel);
7338 break;
7339 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7340 snprintf(evStr, EVENT_DESCR_STR_SZ,
7341 "SAS Device Status Change: Deleted: "
7342 "id=%d channel=%d", id, channel);
7343 break;
7344 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7345 snprintf(evStr, EVENT_DESCR_STR_SZ,
7346 "SAS Device Status Change: SMART Data: "
7347 "id=%d channel=%d", id, channel);
7348 break;
7349 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7350 snprintf(evStr, EVENT_DESCR_STR_SZ,
7351 "SAS Device Status Change: No Persistency: "
7352 "id=%d channel=%d", id, channel);
7353 break;
7354 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7355 snprintf(evStr, EVENT_DESCR_STR_SZ,
7356 "SAS Device Status Change: Unsupported Device "
7357 "Discovered : id=%d channel=%d", id, channel);
7358 break;
7359 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7360 snprintf(evStr, EVENT_DESCR_STR_SZ,
7361 "SAS Device Status Change: Internal Device "
7362 "Reset : id=%d channel=%d", id, channel);
7363 break;
7364 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7365 snprintf(evStr, EVENT_DESCR_STR_SZ,
7366 "SAS Device Status Change: Internal Task "
7367 "Abort : id=%d channel=%d", id, channel);
7368 break;
7369 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7370 snprintf(evStr, EVENT_DESCR_STR_SZ,
7371 "SAS Device Status Change: Internal Abort "
7372 "Task Set : id=%d channel=%d", id, channel);
7373 break;
7374 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7375 snprintf(evStr, EVENT_DESCR_STR_SZ,
7376 "SAS Device Status Change: Internal Clear "
7377 "Task Set : id=%d channel=%d", id, channel);
7378 break;
7379 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7380 snprintf(evStr, EVENT_DESCR_STR_SZ,
7381 "SAS Device Status Change: Internal Query "
7382 "Task : id=%d channel=%d", id, channel);
7383 break;
7384 default:
7385 snprintf(evStr, EVENT_DESCR_STR_SZ,
7386 "SAS Device Status Change: Unknown: "
7387 "id=%d channel=%d", id, channel);
7388 break;
7389 }
7390 break;
7391 }
7392 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7393 ds = "Bus Timer Expired";
7394 break;
7395 case MPI_EVENT_QUEUE_FULL:
7396 {
7397 u16 curr_depth = (u16)(evData0 >> 16);
7398 u8 channel = (u8)(evData0 >> 8);
7399 u8 id = (u8)(evData0);
7400
7401 snprintf(evStr, EVENT_DESCR_STR_SZ,
7402 "Queue Full: channel=%d id=%d depth=%d",
7403 channel, id, curr_depth);
7404 break;
7405 }
7406 case MPI_EVENT_SAS_SES:
7407 ds = "SAS SES Event";
7408 break;
7409 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7410 ds = "Persistent Table Full";
7411 break;
7412 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7413 {
7414 u8 LinkRates = (u8)(evData0 >> 8);
7415 u8 PhyNumber = (u8)(evData0);
7416 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7417 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7418 switch (LinkRates) {
7419 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7420 snprintf(evStr, EVENT_DESCR_STR_SZ,
7421 "SAS PHY Link Status: Phy=%d:"
7422 " Rate Unknown",PhyNumber);
7423 break;
7424 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7425 snprintf(evStr, EVENT_DESCR_STR_SZ,
7426 "SAS PHY Link Status: Phy=%d:"
7427 " Phy Disabled",PhyNumber);
7428 break;
7429 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7430 snprintf(evStr, EVENT_DESCR_STR_SZ,
7431 "SAS PHY Link Status: Phy=%d:"
7432 " Failed Speed Nego",PhyNumber);
7433 break;
7434 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7435 snprintf(evStr, EVENT_DESCR_STR_SZ,
7436 "SAS PHY Link Status: Phy=%d:"
7437 " Sata OOB Completed",PhyNumber);
7438 break;
7439 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7440 snprintf(evStr, EVENT_DESCR_STR_SZ,
7441 "SAS PHY Link Status: Phy=%d:"
7442 " Rate 1.5 Gbps",PhyNumber);
7443 break;
7444 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7445 snprintf(evStr, EVENT_DESCR_STR_SZ,
7446 "SAS PHY Link Status: Phy=%d:"
7447 " Rate 3.0 Gbps", PhyNumber);
7448 break;
7449 case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7450 snprintf(evStr, EVENT_DESCR_STR_SZ,
7451 "SAS PHY Link Status: Phy=%d:"
7452 " Rate 6.0 Gbps", PhyNumber);
7453 break;
7454 default:
7455 snprintf(evStr, EVENT_DESCR_STR_SZ,
7456 "SAS PHY Link Status: Phy=%d", PhyNumber);
7457 break;
7458 }
7459 break;
7460 }
7461 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7462 ds = "SAS Discovery Error";
7463 break;
7464 case MPI_EVENT_IR_RESYNC_UPDATE:
7465 {
7466 u8 resync_complete = (u8)(evData0 >> 16);
7467 snprintf(evStr, EVENT_DESCR_STR_SZ,
7468 "IR Resync Update: Complete = %d:",resync_complete);
7469 break;
7470 }
7471 case MPI_EVENT_IR2:
7472 {
7473 u8 id = (u8)(evData0);
7474 u8 channel = (u8)(evData0 >> 8);
7475 u8 phys_num = (u8)(evData0 >> 24);
7476 u8 ReasonCode = (u8)(evData0 >> 16);
7477
7478 switch (ReasonCode) {
7479 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7480 snprintf(evStr, EVENT_DESCR_STR_SZ,
7481 "IR2: LD State Changed: "
7482 "id=%d channel=%d phys_num=%d",
7483 id, channel, phys_num);
7484 break;
7485 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7486 snprintf(evStr, EVENT_DESCR_STR_SZ,
7487 "IR2: PD State Changed "
7488 "id=%d channel=%d phys_num=%d",
7489 id, channel, phys_num);
7490 break;
7491 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7492 snprintf(evStr, EVENT_DESCR_STR_SZ,
7493 "IR2: Bad Block Table Full: "
7494 "id=%d channel=%d phys_num=%d",
7495 id, channel, phys_num);
7496 break;
7497 case MPI_EVENT_IR2_RC_PD_INSERTED:
7498 snprintf(evStr, EVENT_DESCR_STR_SZ,
7499 "IR2: PD Inserted: "
7500 "id=%d channel=%d phys_num=%d",
7501 id, channel, phys_num);
7502 break;
7503 case MPI_EVENT_IR2_RC_PD_REMOVED:
7504 snprintf(evStr, EVENT_DESCR_STR_SZ,
7505 "IR2: PD Removed: "
7506 "id=%d channel=%d phys_num=%d",
7507 id, channel, phys_num);
7508 break;
7509 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7510 snprintf(evStr, EVENT_DESCR_STR_SZ,
7511 "IR2: Foreign CFG Detected: "
7512 "id=%d channel=%d phys_num=%d",
7513 id, channel, phys_num);
7514 break;
7515 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7516 snprintf(evStr, EVENT_DESCR_STR_SZ,
7517 "IR2: Rebuild Medium Error: "
7518 "id=%d channel=%d phys_num=%d",
7519 id, channel, phys_num);
7520 break;
7521 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7522 snprintf(evStr, EVENT_DESCR_STR_SZ,
7523 "IR2: Dual Port Added: "
7524 "id=%d channel=%d phys_num=%d",
7525 id, channel, phys_num);
7526 break;
7527 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7528 snprintf(evStr, EVENT_DESCR_STR_SZ,
7529 "IR2: Dual Port Removed: "
7530 "id=%d channel=%d phys_num=%d",
7531 id, channel, phys_num);
7532 break;
7533 default:
7534 ds = "IR2";
7535 break;
7536 }
7537 break;
7538 }
7539 case MPI_EVENT_SAS_DISCOVERY:
7540 {
7541 if (evData0)
7542 ds = "SAS Discovery: Start";
7543 else
7544 ds = "SAS Discovery: Stop";
7545 break;
7546 }
7547 case MPI_EVENT_LOG_ENTRY_ADDED:
7548 ds = "SAS Log Entry Added";
7549 break;
7550
7551 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7552 {
7553 u8 phy_num = (u8)(evData0);
7554 u8 port_num = (u8)(evData0 >> 8);
7555 u8 port_width = (u8)(evData0 >> 16);
7556 u8 primitive = (u8)(evData0 >> 24);
7557 snprintf(evStr, EVENT_DESCR_STR_SZ,
7558 "SAS Broadcast Primitive: phy=%d port=%d "
7559 "width=%d primitive=0x%02x",
7560 phy_num, port_num, port_width, primitive);
7561 break;
7562 }
7563
7564 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7565 {
7566 u8 reason = (u8)(evData0);
7567
7568 switch (reason) {
7569 case MPI_EVENT_SAS_INIT_RC_ADDED:
7570 ds = "SAS Initiator Status Change: Added";
7571 break;
7572 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7573 ds = "SAS Initiator Status Change: Deleted";
7574 break;
7575 default:
7576 ds = "SAS Initiator Status Change";
7577 break;
7578 }
7579 break;
7580 }
7581
7582 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7583 {
7584 u8 max_init = (u8)(evData0);
7585 u8 current_init = (u8)(evData0 >> 8);
7586
7587 snprintf(evStr, EVENT_DESCR_STR_SZ,
7588 "SAS Initiator Device Table Overflow: max initiators=%02d "
7589 "current initiators=%02d",
7590 max_init, current_init);
7591 break;
7592 }
7593 case MPI_EVENT_SAS_SMP_ERROR:
7594 {
7595 u8 status = (u8)(evData0);
7596 u8 port_num = (u8)(evData0 >> 8);
7597 u8 result = (u8)(evData0 >> 16);
7598
7599 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7600 snprintf(evStr, EVENT_DESCR_STR_SZ,
7601 "SAS SMP Error: port=%d result=0x%02x",
7602 port_num, result);
7603 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7604 snprintf(evStr, EVENT_DESCR_STR_SZ,
7605 "SAS SMP Error: port=%d : CRC Error",
7606 port_num);
7607 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7608 snprintf(evStr, EVENT_DESCR_STR_SZ,
7609 "SAS SMP Error: port=%d : Timeout",
7610 port_num);
7611 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7612 snprintf(evStr, EVENT_DESCR_STR_SZ,
7613 "SAS SMP Error: port=%d : No Destination",
7614 port_num);
7615 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7616 snprintf(evStr, EVENT_DESCR_STR_SZ,
7617 "SAS SMP Error: port=%d : Bad Destination",
7618 port_num);
7619 else
7620 snprintf(evStr, EVENT_DESCR_STR_SZ,
7621 "SAS SMP Error: port=%d : status=0x%02x",
7622 port_num, status);
7623 break;
7624 }
7625
7626 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7627 {
7628 u8 reason = (u8)(evData0);
7629
7630 switch (reason) {
7631 case MPI_EVENT_SAS_EXP_RC_ADDED:
7632 ds = "Expander Status Change: Added";
7633 break;
7634 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7635 ds = "Expander Status Change: Deleted";
7636 break;
7637 default:
7638 ds = "Expander Status Change";
7639 break;
7640 }
7641 break;
7642 }
7643
7644
7645
7646
7647 default:
7648 ds = "Unknown";
7649 break;
7650 }
7651 if (ds)
7652 strlcpy(evStr, ds, EVENT_DESCR_STR_SZ);
7653
7654
7655 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7656 "MPT event:(%02Xh) : %s\n",
7657 ioc->name, event, evStr));
7658
7659 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7660 ": Event data:\n"));
7661 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7662 devtverboseprintk(ioc, printk(" %08x",
7663 le32_to_cpu(pEventReply->Data[ii])));
7664 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7665}
7666#endif
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678static int
7679ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7680{
7681 u16 evDataLen;
7682 u32 evData0 = 0;
7683 int ii;
7684 u8 cb_idx;
7685 int r = 0;
7686 int handlers = 0;
7687 u8 event;
7688
7689
7690
7691
7692 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7693 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7694 if (evDataLen) {
7695 evData0 = le32_to_cpu(pEventReply->Data[0]);
7696 }
7697
7698#ifdef CONFIG_FUSION_LOGGING
7699 if (evDataLen)
7700 mpt_display_event_info(ioc, pEventReply);
7701#endif
7702
7703
7704
7705
7706 switch(event) {
7707 case MPI_EVENT_EVENT_CHANGE:
7708 if (evDataLen) {
7709 u8 evState = evData0 & 0xFF;
7710
7711
7712
7713
7714 if (ioc->facts.Function) {
7715 ioc->facts.EventState = evState;
7716 }
7717 }
7718 break;
7719 case MPI_EVENT_INTEGRATED_RAID:
7720 mptbase_raid_process_event_data(ioc,
7721 (MpiEventDataRaid_t *)pEventReply->Data);
7722 break;
7723 default:
7724 break;
7725 }
7726
7727
7728
7729
7730
7731 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7732 int idx;
7733
7734 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7735
7736 ioc->events[idx].event = event;
7737 ioc->events[idx].eventContext = ioc->eventContext;
7738
7739 for (ii = 0; ii < 2; ii++) {
7740 if (ii < evDataLen)
7741 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7742 else
7743 ioc->events[idx].data[ii] = 0;
7744 }
7745
7746 ioc->eventContext++;
7747 }
7748
7749
7750
7751
7752
7753 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7754 if (MptEvHandlers[cb_idx]) {
7755 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7756 "Routing Event to event handler #%d\n",
7757 ioc->name, cb_idx));
7758 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7759 handlers++;
7760 }
7761 }
7762
7763
7764
7765
7766
7767 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7768 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7769 "EventAck required\n",ioc->name));
7770 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7771 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7772 ioc->name, ii));
7773 }
7774 }
7775
7776 *evHandlers = handlers;
7777 return r;
7778}
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788static void
7789mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7790{
7791 char *desc = "unknown";
7792
7793 switch (log_info & 0xFF000000) {
7794 case MPI_IOCLOGINFO_FC_INIT_BASE:
7795 desc = "FCP Initiator";
7796 break;
7797 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7798 desc = "FCP Target";
7799 break;
7800 case MPI_IOCLOGINFO_FC_LAN_BASE:
7801 desc = "LAN";
7802 break;
7803 case MPI_IOCLOGINFO_FC_MSG_BASE:
7804 desc = "MPI Message Layer";
7805 break;
7806 case MPI_IOCLOGINFO_FC_LINK_BASE:
7807 desc = "FC Link";
7808 break;
7809 case MPI_IOCLOGINFO_FC_CTX_BASE:
7810 desc = "Context Manager";
7811 break;
7812 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7813 desc = "Invalid Field Offset";
7814 break;
7815 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7816 desc = "State Change Info";
7817 break;
7818 }
7819
7820 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7821 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7822}
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832static void
7833mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7834{
7835 u32 info = log_info & 0x00FF0000;
7836 char *desc = "unknown";
7837
7838 switch (info) {
7839 case 0x00010000:
7840 desc = "bug! MID not found";
7841 break;
7842
7843 case 0x00020000:
7844 desc = "Parity Error";
7845 break;
7846
7847 case 0x00030000:
7848 desc = "ASYNC Outbound Overrun";
7849 break;
7850
7851 case 0x00040000:
7852 desc = "SYNC Offset Error";
7853 break;
7854
7855 case 0x00050000:
7856 desc = "BM Change";
7857 break;
7858
7859 case 0x00060000:
7860 desc = "Msg In Overflow";
7861 break;
7862
7863 case 0x00070000:
7864 desc = "DMA Error";
7865 break;
7866
7867 case 0x00080000:
7868 desc = "Outbound DMA Overrun";
7869 break;
7870
7871 case 0x00090000:
7872 desc = "Task Management";
7873 break;
7874
7875 case 0x000A0000:
7876 desc = "Device Problem";
7877 break;
7878
7879 case 0x000B0000:
7880 desc = "Invalid Phase Change";
7881 break;
7882
7883 case 0x000C0000:
7884 desc = "Untagged Table Size";
7885 break;
7886
7887 }
7888
7889 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7890}
7891
7892
7893 static char *originator_str[] = {
7894 "IOP",
7895 "PL",
7896 "IR"
7897 };
7898 static char *iop_code_str[] = {
7899 NULL,
7900 "Invalid SAS Address",
7901 NULL,
7902 "Invalid Page",
7903 "Diag Message Error",
7904 "Task Terminated",
7905 "Enclosure Management",
7906 "Target Mode"
7907 };
7908 static char *pl_code_str[] = {
7909 NULL,
7910 "Open Failure",
7911 "Invalid Scatter Gather List",
7912 "Wrong Relative Offset or Frame Length",
7913 "Frame Transfer Error",
7914 "Transmit Frame Connected Low",
7915 "SATA Non-NCQ RW Error Bit Set",
7916 "SATA Read Log Receive Data Error",
7917 "SATA NCQ Fail All Commands After Error",
7918 "SATA Error in Receive Set Device Bit FIS",
7919 "Receive Frame Invalid Message",
7920 "Receive Context Message Valid Error",
7921 "Receive Frame Current Frame Error",
7922 "SATA Link Down",
7923 "Discovery SATA Init W IOS",
7924 "Config Invalid Page",
7925 "Discovery SATA Init Timeout",
7926 "Reset",
7927 "Abort",
7928 "IO Not Yet Executed",
7929 "IO Executed",
7930 "Persistent Reservation Out Not Affiliation "
7931 "Owner",
7932 "Open Transmit DMA Abort",
7933 "IO Device Missing Delay Retry",
7934 "IO Cancelled Due to Receive Error",
7935 NULL,
7936 NULL,
7937 NULL,
7938 NULL,
7939 NULL,
7940 NULL,
7941 NULL,
7942 "Enclosure Management"
7943 };
7944 static char *ir_code_str[] = {
7945 "Raid Action Error",
7946 NULL,
7947 NULL,
7948 NULL,
7949 NULL,
7950 NULL,
7951 NULL,
7952 NULL,
7953 NULL
7954 };
7955 static char *raid_sub_code_str[] = {
7956 NULL,
7957 "Volume Creation Failed: Data Passed too "
7958 "Large",
7959 "Volume Creation Failed: Duplicate Volumes "
7960 "Attempted",
7961 "Volume Creation Failed: Max Number "
7962 "Supported Volumes Exceeded",
7963 "Volume Creation Failed: DMA Error",
7964 "Volume Creation Failed: Invalid Volume Type",
7965 "Volume Creation Failed: Error Reading "
7966 "MFG Page 4",
7967 "Volume Creation Failed: Creating Internal "
7968 "Structures",
7969 NULL,
7970 NULL,
7971 NULL,
7972 NULL,
7973 NULL,
7974 NULL,
7975 NULL,
7976 NULL,
7977 "Activation failed: Already Active Volume",
7978 "Activation failed: Unsupported Volume Type",
7979 "Activation failed: Too Many Active Volumes",
7980 "Activation failed: Volume ID in Use",
7981 "Activation failed: Reported Failure",
7982 "Activation failed: Importing a Volume",
7983 NULL,
7984 NULL,
7985 NULL,
7986 NULL,
7987 NULL,
7988 NULL,
7989 NULL,
7990 NULL,
7991 NULL,
7992 NULL,
7993 "Phys Disk failed: Too Many Phys Disks",
7994 "Phys Disk failed: Data Passed too Large",
7995 "Phys Disk failed: DMA Error",
7996 "Phys Disk failed: Invalid <channel:id>",
7997 "Phys Disk failed: Creating Phys Disk Config "
7998 "Page",
7999 NULL,
8000 NULL,
8001 NULL,
8002 NULL,
8003 NULL,
8004 NULL,
8005 NULL,
8006 NULL,
8007 NULL,
8008 NULL,
8009 NULL,
8010 "Compatibility Error: IR Disabled",
8011 "Compatibility Error: Inquiry Command Failed",
8012 "Compatibility Error: Device not Direct Access "
8013 "Device ",
8014 "Compatibility Error: Removable Device Found",
8015 "Compatibility Error: Device SCSI Version not "
8016 "2 or Higher",
8017 "Compatibility Error: SATA Device, 48 BIT LBA "
8018 "not Supported",
8019 "Compatibility Error: Device doesn't have "
8020 "512 Byte Block Sizes",
8021 "Compatibility Error: Volume Type Check Failed",
8022 "Compatibility Error: Volume Type is "
8023 "Unsupported by FW",
8024 "Compatibility Error: Disk Drive too Small for "
8025 "use in Volume",
8026 "Compatibility Error: Phys Disk for Create "
8027 "Volume not Found",
8028 "Compatibility Error: Too Many or too Few "
8029 "Disks for Volume Type",
8030 "Compatibility Error: Disk stripe Sizes "
8031 "Must be 64KB",
8032 "Compatibility Error: IME Size Limited to < 2TB",
8033 };
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044static void
8045mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8046{
8047 union loginfo_type {
8048 u32 loginfo;
8049 struct {
8050 u32 subcode:16;
8051 u32 code:8;
8052 u32 originator:4;
8053 u32 bus_type:4;
8054 } dw;
8055 };
8056 union loginfo_type sas_loginfo;
8057 char *originator_desc = NULL;
8058 char *code_desc = NULL;
8059 char *sub_code_desc = NULL;
8060
8061 sas_loginfo.loginfo = log_info;
8062 if ((sas_loginfo.dw.bus_type != 3 ) &&
8063 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8064 return;
8065
8066 originator_desc = originator_str[sas_loginfo.dw.originator];
8067
8068 switch (sas_loginfo.dw.originator) {
8069
8070 case 0:
8071 if (sas_loginfo.dw.code <
8072 ARRAY_SIZE(iop_code_str))
8073 code_desc = iop_code_str[sas_loginfo.dw.code];
8074 break;
8075 case 1:
8076 if (sas_loginfo.dw.code <
8077 ARRAY_SIZE(pl_code_str))
8078 code_desc = pl_code_str[sas_loginfo.dw.code];
8079 break;
8080 case 2:
8081 if (sas_loginfo.dw.code >=
8082 ARRAY_SIZE(ir_code_str))
8083 break;
8084 code_desc = ir_code_str[sas_loginfo.dw.code];
8085 if (sas_loginfo.dw.subcode >=
8086 ARRAY_SIZE(raid_sub_code_str))
8087 break;
8088 if (sas_loginfo.dw.code == 0)
8089 sub_code_desc =
8090 raid_sub_code_str[sas_loginfo.dw.subcode];
8091 break;
8092 default:
8093 return;
8094 }
8095
8096 if (sub_code_desc != NULL)
8097 printk(MYIOC_s_INFO_FMT
8098 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8099 " SubCode={%s} cb_idx %s\n",
8100 ioc->name, log_info, originator_desc, code_desc,
8101 sub_code_desc, MptCallbacksName[cb_idx]);
8102 else if (code_desc != NULL)
8103 printk(MYIOC_s_INFO_FMT
8104 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8105 " SubCode(0x%04x) cb_idx %s\n",
8106 ioc->name, log_info, originator_desc, code_desc,
8107 sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8108 else
8109 printk(MYIOC_s_INFO_FMT
8110 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8111 " SubCode(0x%04x) cb_idx %s\n",
8112 ioc->name, log_info, originator_desc,
8113 sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8114 MptCallbacksName[cb_idx]);
8115}
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126static void
8127mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8128{
8129 Config_t *pReq = (Config_t *)mf;
8130 char extend_desc[EVENT_DESCR_STR_SZ];
8131 char *desc = NULL;
8132 u32 form;
8133 u8 page_type;
8134
8135 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8136 page_type = pReq->ExtPageType;
8137 else
8138 page_type = pReq->Header.PageType;
8139
8140
8141
8142
8143 form = le32_to_cpu(pReq->PageAddress);
8144 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8145 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8146 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8147 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8148 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8149 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8150 return;
8151 }
8152 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8153 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8154 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8155 return;
8156 }
8157
8158 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8159 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8160 page_type, pReq->Header.PageNumber, pReq->Action, form);
8161
8162 switch (ioc_status) {
8163
8164 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION:
8165 desc = "Config Page Invalid Action";
8166 break;
8167
8168 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:
8169 desc = "Config Page Invalid Type";
8170 break;
8171
8172 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:
8173 desc = "Config Page Invalid Page";
8174 break;
8175
8176 case MPI_IOCSTATUS_CONFIG_INVALID_DATA:
8177 desc = "Config Page Invalid Data";
8178 break;
8179
8180 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:
8181 desc = "Config Page No Defaults";
8182 break;
8183
8184 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:
8185 desc = "Config Page Can't Commit";
8186 break;
8187 }
8188
8189 if (!desc)
8190 return;
8191
8192 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8193 ioc->name, ioc_status, desc, extend_desc));
8194}
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204static void
8205mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8206{
8207 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8208 char *desc = NULL;
8209
8210 switch (status) {
8211
8212
8213
8214
8215
8216 case MPI_IOCSTATUS_INVALID_FUNCTION:
8217 desc = "Invalid Function";
8218 break;
8219
8220 case MPI_IOCSTATUS_BUSY:
8221 desc = "Busy";
8222 break;
8223
8224 case MPI_IOCSTATUS_INVALID_SGL:
8225 desc = "Invalid SGL";
8226 break;
8227
8228 case MPI_IOCSTATUS_INTERNAL_ERROR:
8229 desc = "Internal Error";
8230 break;
8231
8232 case MPI_IOCSTATUS_RESERVED:
8233 desc = "Reserved";
8234 break;
8235
8236 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
8237 desc = "Insufficient Resources";
8238 break;
8239
8240 case MPI_IOCSTATUS_INVALID_FIELD:
8241 desc = "Invalid Field";
8242 break;
8243
8244 case MPI_IOCSTATUS_INVALID_STATE:
8245 desc = "Invalid State";
8246 break;
8247
8248
8249
8250
8251
8252 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION:
8253 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:
8254 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:
8255 case MPI_IOCSTATUS_CONFIG_INVALID_DATA:
8256 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:
8257 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:
8258 mpt_iocstatus_info_config(ioc, status, mf);
8259 break;
8260
8261
8262
8263
8264
8265
8266
8267
8268 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:
8269 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
8270 case MPI_IOCSTATUS_SCSI_INVALID_BUS:
8271 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
8272 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
8273 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
8274 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
8275 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
8276 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
8277 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
8278 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
8279 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
8280 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
8281 break;
8282
8283
8284
8285
8286
8287 case MPI_IOCSTATUS_TARGET_PRIORITY_IO:
8288 desc = "Target: Priority IO";
8289 break;
8290
8291 case MPI_IOCSTATUS_TARGET_INVALID_PORT:
8292 desc = "Target: Invalid Port";
8293 break;
8294
8295 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX:
8296 desc = "Target Invalid IO Index:";
8297 break;
8298
8299 case MPI_IOCSTATUS_TARGET_ABORTED:
8300 desc = "Target: Aborted";
8301 break;
8302
8303 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE:
8304 desc = "Target: No Conn Retryable";
8305 break;
8306
8307 case MPI_IOCSTATUS_TARGET_NO_CONNECTION:
8308 desc = "Target: No Connection";
8309 break;
8310
8311 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH:
8312 desc = "Target: Transfer Count Mismatch";
8313 break;
8314
8315 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT:
8316 desc = "Target: STS Data not Sent";
8317 break;
8318
8319 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR:
8320 desc = "Target: Data Offset Error";
8321 break;
8322
8323 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA:
8324 desc = "Target: Too Much Write Data";
8325 break;
8326
8327 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT:
8328 desc = "Target: IU Too Short";
8329 break;
8330
8331 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT:
8332 desc = "Target: ACK NAK Timeout";
8333 break;
8334
8335 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED:
8336 desc = "Target: Nak Received";
8337 break;
8338
8339
8340
8341
8342
8343 case MPI_IOCSTATUS_FC_ABORTED:
8344 desc = "FC: Aborted";
8345 break;
8346
8347 case MPI_IOCSTATUS_FC_RX_ID_INVALID:
8348 desc = "FC: RX ID Invalid";
8349 break;
8350
8351 case MPI_IOCSTATUS_FC_DID_INVALID:
8352 desc = "FC: DID Invalid";
8353 break;
8354
8355 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT:
8356 desc = "FC: Node Logged Out";
8357 break;
8358
8359 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED:
8360 desc = "FC: Exchange Canceled";
8361 break;
8362
8363
8364
8365
8366
8367 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND:
8368 desc = "LAN: Device not Found";
8369 break;
8370
8371 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE:
8372 desc = "LAN: Device Failure";
8373 break;
8374
8375 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR:
8376 desc = "LAN: Transmit Error";
8377 break;
8378
8379 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED:
8380 desc = "LAN: Transmit Aborted";
8381 break;
8382
8383 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR:
8384 desc = "LAN: Receive Error";
8385 break;
8386
8387 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED:
8388 desc = "LAN: Receive Aborted";
8389 break;
8390
8391 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET:
8392 desc = "LAN: Partial Packet";
8393 break;
8394
8395 case MPI_IOCSTATUS_LAN_CANCELED:
8396 desc = "LAN: Canceled";
8397 break;
8398
8399
8400
8401
8402
8403 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
8404 desc = "SAS: SMP Request Failed";
8405 break;
8406
8407 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
8408 desc = "SAS: SMP Data Overrun";
8409 break;
8410
8411 default:
8412 desc = "Others";
8413 break;
8414 }
8415
8416 if (!desc)
8417 return;
8418
8419 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8420 ioc->name, status, desc));
8421}
8422
8423
8424EXPORT_SYMBOL(mpt_attach);
8425EXPORT_SYMBOL(mpt_detach);
8426#ifdef CONFIG_PM
8427EXPORT_SYMBOL(mpt_resume);
8428EXPORT_SYMBOL(mpt_suspend);
8429#endif
8430EXPORT_SYMBOL(ioc_list);
8431EXPORT_SYMBOL(mpt_register);
8432EXPORT_SYMBOL(mpt_deregister);
8433EXPORT_SYMBOL(mpt_event_register);
8434EXPORT_SYMBOL(mpt_event_deregister);
8435EXPORT_SYMBOL(mpt_reset_register);
8436EXPORT_SYMBOL(mpt_reset_deregister);
8437EXPORT_SYMBOL(mpt_device_driver_register);
8438EXPORT_SYMBOL(mpt_device_driver_deregister);
8439EXPORT_SYMBOL(mpt_get_msg_frame);
8440EXPORT_SYMBOL(mpt_put_msg_frame);
8441EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8442EXPORT_SYMBOL(mpt_free_msg_frame);
8443EXPORT_SYMBOL(mpt_send_handshake_request);
8444EXPORT_SYMBOL(mpt_verify_adapter);
8445EXPORT_SYMBOL(mpt_GetIocState);
8446EXPORT_SYMBOL(mpt_print_ioc_summary);
8447EXPORT_SYMBOL(mpt_HardResetHandler);
8448EXPORT_SYMBOL(mpt_config);
8449EXPORT_SYMBOL(mpt_findImVolumes);
8450EXPORT_SYMBOL(mpt_alloc_fw_memory);
8451EXPORT_SYMBOL(mpt_free_fw_memory);
8452EXPORT_SYMBOL(mptbase_sas_persist_operation);
8453EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8454
8455
8456
8457
8458
8459
8460
8461static int __init
8462fusion_init(void)
8463{
8464 u8 cb_idx;
8465
8466 show_mptmod_ver(my_NAME, my_VERSION);
8467 printk(KERN_INFO COPYRIGHT "\n");
8468
8469 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8470 MptCallbacks[cb_idx] = NULL;
8471 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8472 MptEvHandlers[cb_idx] = NULL;
8473 MptResetHandlers[cb_idx] = NULL;
8474 }
8475
8476
8477
8478
8479 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8480 "mptbase_reply");
8481
8482
8483
8484 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8485
8486#ifdef CONFIG_PROC_FS
8487 (void) procmpt_create();
8488#endif
8489 return 0;
8490}
8491
8492
8493
8494
8495
8496
8497
8498
8499static void __exit
8500fusion_exit(void)
8501{
8502
8503 mpt_reset_deregister(mpt_base_index);
8504
8505#ifdef CONFIG_PROC_FS
8506 procmpt_destroy();
8507#endif
8508}
8509
8510module_init(fusion_init);
8511module_exit(fusion_exit);
8512