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