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