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