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 <asm/io.h>
63#ifdef CONFIG_MTRR
64#include <asm/mtrr.h>
65#endif
66#include <linux/kthread.h>
67#include <scsi/scsi_host.h>
68
69#include "mptbase.h"
70#include "lsi/mpi_log_fc.h"
71
72
73#define my_NAME "Fusion MPT base driver"
74#define my_VERSION MPT_LINUX_VERSION_COMMON
75#define MYNAM "mptbase"
76
77MODULE_AUTHOR(MODULEAUTHOR);
78MODULE_DESCRIPTION(my_NAME);
79MODULE_LICENSE("GPL");
80MODULE_VERSION(my_VERSION);
81
82
83
84
85
86static int mpt_msi_enable_spi;
87module_param(mpt_msi_enable_spi, int, 0);
88MODULE_PARM_DESC(mpt_msi_enable_spi,
89 " Enable MSI Support for SPI controllers (default=0)");
90
91static int mpt_msi_enable_fc;
92module_param(mpt_msi_enable_fc, int, 0);
93MODULE_PARM_DESC(mpt_msi_enable_fc,
94 " Enable MSI Support for FC controllers (default=0)");
95
96static int mpt_msi_enable_sas;
97module_param(mpt_msi_enable_sas, int, 0);
98MODULE_PARM_DESC(mpt_msi_enable_sas,
99 " Enable MSI Support for SAS controllers (default=0)");
100
101static int mpt_channel_mapping;
102module_param(mpt_channel_mapping, int, 0);
103MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
104
105static int mpt_debug_level;
106static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
107module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
108 &mpt_debug_level, 0600);
109MODULE_PARM_DESC(mpt_debug_level,
110 " debug level - refer to mptdebug.h - (default=0)");
111
112int mpt_fwfault_debug;
113EXPORT_SYMBOL(mpt_fwfault_debug);
114module_param(mpt_fwfault_debug, int, 0600);
115MODULE_PARM_DESC(mpt_fwfault_debug,
116 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
117
118static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
119
120#ifdef MFCNT
121static int mfcounter = 0;
122#define PRINT_MF_COUNT 20000
123#endif
124
125
126
127
128
129
130#define WHOINIT_UNKNOWN 0xAA
131
132
133
134
135
136
137LIST_HEAD(ioc_list);
138
139static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
140
141static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
142
143static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
144
145static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147
148#ifdef CONFIG_PROC_FS
149static struct proc_dir_entry *mpt_proc_root_dir;
150#endif
151
152
153
154
155static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
156static u8 last_drv_idx;
157
158
159
160
161
162static irqreturn_t mpt_interrupt(int irq, void *bus_id);
163static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
164 MPT_FRAME_HDR *reply);
165static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
166 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
167 int sleepFlag);
168static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
169static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
170static void mpt_adapter_disable(MPT_ADAPTER *ioc);
171static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
172
173static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
174static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
175static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
176static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
178static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
179static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
180static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
181static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
182static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
183static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
184static int PrimeIocFifos(MPT_ADAPTER *ioc);
185static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
188static int GetLanConfigPages(MPT_ADAPTER *ioc);
189static int GetIoUnitPage2(MPT_ADAPTER *ioc);
190int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
191static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
192static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
193static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
194static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
195static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
196static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
197 int sleepFlag);
198static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
199static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
200static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
201
202#ifdef CONFIG_PROC_FS
203static const struct file_operations mpt_summary_proc_fops;
204static const struct file_operations mpt_version_proc_fops;
205static const struct file_operations mpt_iocinfo_proc_fops;
206#endif
207static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
208
209static int ProcessEventNotification(MPT_ADAPTER *ioc,
210 EventNotificationReply_t *evReply, int *evHandlers);
211static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
212static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
213static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
214static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
215static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
216static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
217
218
219static int __init fusion_init (void);
220static void __exit fusion_exit (void);
221
222#define CHIPREG_READ32(addr) readl_relaxed(addr)
223#define CHIPREG_READ32_dmasync(addr) readl(addr)
224#define CHIPREG_WRITE32(addr,val) writel(val, addr)
225#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
226#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
227
228static void
229pci_disable_io_access(struct pci_dev *pdev)
230{
231 u16 command_reg;
232
233 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
234 command_reg &= ~1;
235 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
236}
237
238static void
239pci_enable_io_access(struct pci_dev *pdev)
240{
241 u16 command_reg;
242
243 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
244 command_reg |= 1;
245 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
246}
247
248static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
249{
250 int ret = param_set_int(val, kp);
251 MPT_ADAPTER *ioc;
252
253 if (ret)
254 return ret;
255
256 list_for_each_entry(ioc, &ioc_list, list)
257 ioc->debug_level = mpt_debug_level;
258 return 0;
259}
260
261
262
263
264
265
266
267static u8
268mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
269{
270 u8 cb_idx;
271
272 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
273 if (MptDriverClass[cb_idx] == dclass)
274 return cb_idx;
275 return 0;
276}
277
278
279
280
281
282
283
284static int
285mpt_is_discovery_complete(MPT_ADAPTER *ioc)
286{
287 ConfigExtendedPageHeader_t hdr;
288 CONFIGPARMS cfg;
289 SasIOUnitPage0_t *buffer;
290 dma_addr_t dma_handle;
291 int rc = 0;
292
293 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
294 memset(&cfg, 0, sizeof(CONFIGPARMS));
295 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
296 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
297 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
298 cfg.cfghdr.ehdr = &hdr;
299 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
300
301 if ((mpt_config(ioc, &cfg)))
302 goto out;
303 if (!hdr.ExtPageLength)
304 goto out;
305
306 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
307 &dma_handle);
308 if (!buffer)
309 goto out;
310
311 cfg.physAddr = dma_handle;
312 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
313
314 if ((mpt_config(ioc, &cfg)))
315 goto out_free_consistent;
316
317 if (!(buffer->PhyData[0].PortFlags &
318 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
319 rc = 1;
320
321 out_free_consistent:
322 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
323 buffer, dma_handle);
324 out:
325 return rc;
326}
327
328
329
330
331
332
333
334
335
336static int mpt_remove_dead_ioc_func(void *arg)
337{
338 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
339 struct pci_dev *pdev;
340
341 if ((ioc == NULL))
342 return -1;
343
344 pdev = ioc->pcidev;
345 if ((pdev == NULL))
346 return -1;
347
348 pci_remove_bus_device(pdev);
349 return 0;
350}
351
352
353
354
355
356
357
358
359static void
360mpt_fault_reset_work(struct work_struct *work)
361{
362 MPT_ADAPTER *ioc =
363 container_of(work, MPT_ADAPTER, fault_reset_work.work);
364 u32 ioc_raw_state;
365 int rc;
366 unsigned long flags;
367 MPT_SCSI_HOST *hd;
368 struct task_struct *p;
369
370 if (ioc->ioc_reset_in_progress || !ioc->active)
371 goto out;
372
373
374 ioc_raw_state = mpt_GetIocState(ioc, 0);
375 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
376 printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
377 ioc->name, __func__);
378
379
380
381
382
383
384
385
386 hd = shost_priv(ioc->sh);
387 ioc->schedule_dead_ioc_flush_running_cmds(hd);
388
389
390 p = kthread_run(mpt_remove_dead_ioc_func, ioc,
391 "mpt_dead_ioc_%d", ioc->id);
392 if (IS_ERR(p)) {
393 printk(MYIOC_s_ERR_FMT
394 "%s: Running mpt_dead_ioc thread failed !\n",
395 ioc->name, __func__);
396 } else {
397 printk(MYIOC_s_WARN_FMT
398 "%s: Running mpt_dead_ioc thread success !\n",
399 ioc->name, __func__);
400 }
401 return;
402 }
403
404 if ((ioc_raw_state & MPI_IOC_STATE_MASK)
405 == MPI_IOC_STATE_FAULT) {
406 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
407 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
408 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
409 ioc->name, __func__);
410 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
411 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
412 __func__, (rc == 0) ? "success" : "failed");
413 ioc_raw_state = mpt_GetIocState(ioc, 0);
414 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
415 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
416 "reset (%04xh)\n", ioc->name, ioc_raw_state &
417 MPI_DOORBELL_DATA_MASK);
418 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
419 if ((mpt_is_discovery_complete(ioc))) {
420 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
421 "discovery_quiesce_io flag\n", ioc->name));
422 ioc->sas_discovery_quiesce_io = 0;
423 }
424 }
425
426 out:
427
428
429
430 if (ioc->alt_ioc)
431 ioc = ioc->alt_ioc;
432
433
434 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
435 if (ioc->reset_work_q)
436 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
437 msecs_to_jiffies(MPT_POLLING_INTERVAL));
438 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
439}
440
441
442
443
444
445static void
446mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
447{
448 MPT_FRAME_HDR *mf = NULL;
449 MPT_FRAME_HDR *mr = NULL;
450 u16 req_idx = 0;
451 u8 cb_idx;
452
453 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
454 ioc->name, pa));
455
456 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
457 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
458 req_idx = pa & 0x0000FFFF;
459 cb_idx = (pa & 0x00FF0000) >> 16;
460 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
461 break;
462 case MPI_CONTEXT_REPLY_TYPE_LAN:
463 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
464
465
466
467
468
469
470
471
472
473 if ((pa & 0x58000000) == 0x58000000) {
474 req_idx = pa & 0x0000FFFF;
475 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
476 mpt_free_msg_frame(ioc, mf);
477 mb();
478 return;
479 break;
480 }
481 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
482 break;
483 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
484 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
485 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
486 break;
487 default:
488 cb_idx = 0;
489 BUG();
490 }
491
492
493 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
494 MptCallbacks[cb_idx] == NULL) {
495 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
496 __func__, ioc->name, cb_idx);
497 goto out;
498 }
499
500 if (MptCallbacks[cb_idx](ioc, mf, mr))
501 mpt_free_msg_frame(ioc, mf);
502 out:
503 mb();
504}
505
506static void
507mpt_reply(MPT_ADAPTER *ioc, u32 pa)
508{
509 MPT_FRAME_HDR *mf;
510 MPT_FRAME_HDR *mr;
511 u16 req_idx;
512 u8 cb_idx;
513 int freeme;
514
515 u32 reply_dma_low;
516 u16 ioc_stat;
517
518
519
520
521
522
523
524
525
526
527
528 reply_dma_low = (pa <<= 1);
529 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
530 (reply_dma_low - ioc->reply_frames_low_dma));
531
532 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
533 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
534 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
535
536 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
537 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
538 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
539
540
541
542 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
543 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
544 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
545 if (ioc->bus_type == FC)
546 mpt_fc_log_info(ioc, log_info);
547 else if (ioc->bus_type == SPI)
548 mpt_spi_log_info(ioc, log_info);
549 else if (ioc->bus_type == SAS)
550 mpt_sas_log_info(ioc, log_info, cb_idx);
551 }
552
553 if (ioc_stat & MPI_IOCSTATUS_MASK)
554 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
555
556
557 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
558 MptCallbacks[cb_idx] == NULL) {
559 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
560 __func__, ioc->name, cb_idx);
561 freeme = 0;
562 goto out;
563 }
564
565 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
566
567 out:
568
569 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
570
571 if (freeme)
572 mpt_free_msg_frame(ioc, mf);
573 mb();
574}
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593static irqreturn_t
594mpt_interrupt(int irq, void *bus_id)
595{
596 MPT_ADAPTER *ioc = bus_id;
597 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
598
599 if (pa == 0xFFFFFFFF)
600 return IRQ_NONE;
601
602
603
604
605 do {
606 if (pa & MPI_ADDRESS_REPLY_A_BIT)
607 mpt_reply(ioc, pa);
608 else
609 mpt_turbo_reply(ioc, pa);
610 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
611 } while (pa != 0xFFFFFFFF);
612
613 return IRQ_HANDLED;
614}
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630static int
631mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
632{
633 EventNotificationReply_t *pEventReply;
634 u8 event;
635 int evHandlers;
636 int freereq = 1;
637
638 switch (reply->u.hdr.Function) {
639 case MPI_FUNCTION_EVENT_NOTIFICATION:
640 pEventReply = (EventNotificationReply_t *)reply;
641 evHandlers = 0;
642 ProcessEventNotification(ioc, pEventReply, &evHandlers);
643 event = le32_to_cpu(pEventReply->Event) & 0xFF;
644 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
645 freereq = 0;
646 if (event != MPI_EVENT_EVENT_CHANGE)
647 break;
648 case MPI_FUNCTION_CONFIG:
649 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
650 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
651 if (reply) {
652 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
653 memcpy(ioc->mptbase_cmds.reply, reply,
654 min(MPT_DEFAULT_FRAME_SIZE,
655 4 * reply->u.reply.MsgLength));
656 }
657 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
658 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
659 complete(&ioc->mptbase_cmds.done);
660 } else
661 freereq = 0;
662 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
663 freereq = 1;
664 break;
665 case MPI_FUNCTION_EVENT_ACK:
666 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
667 "EventAck reply received\n", ioc->name));
668 break;
669 default:
670 printk(MYIOC_s_ERR_FMT
671 "Unexpected msg function (=%02Xh) reply received!\n",
672 ioc->name, reply->u.hdr.Function);
673 break;
674 }
675
676
677
678
679
680 return freereq;
681}
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704u8
705mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
706{
707 u8 cb_idx;
708 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
709
710
711
712
713
714 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
715 if (MptCallbacks[cb_idx] == NULL) {
716 MptCallbacks[cb_idx] = cbfunc;
717 MptDriverClass[cb_idx] = dclass;
718 MptEvHandlers[cb_idx] = NULL;
719 last_drv_idx = cb_idx;
720 memcpy(MptCallbacksName[cb_idx], func_name,
721 strlen(func_name) > 50 ? 50 : strlen(func_name));
722 break;
723 }
724 }
725
726 return last_drv_idx;
727}
728
729
730
731
732
733
734
735
736
737void
738mpt_deregister(u8 cb_idx)
739{
740 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
741 MptCallbacks[cb_idx] = NULL;
742 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
743 MptEvHandlers[cb_idx] = NULL;
744
745 last_drv_idx++;
746 }
747}
748
749
750
751
752
753
754
755
756
757
758
759
760int
761mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
762{
763 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
764 return -1;
765
766 MptEvHandlers[cb_idx] = ev_cbfunc;
767 return 0;
768}
769
770
771
772
773
774
775
776
777
778
779void
780mpt_event_deregister(u8 cb_idx)
781{
782 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
783 return;
784
785 MptEvHandlers[cb_idx] = NULL;
786}
787
788
789
790
791
792
793
794
795
796
797
798
799int
800mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
801{
802 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
803 return -1;
804
805 MptResetHandlers[cb_idx] = reset_func;
806 return 0;
807}
808
809
810
811
812
813
814
815
816
817
818void
819mpt_reset_deregister(u8 cb_idx)
820{
821 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
822 return;
823
824 MptResetHandlers[cb_idx] = NULL;
825}
826
827
828
829
830
831
832
833int
834mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
835{
836 MPT_ADAPTER *ioc;
837 const struct pci_device_id *id;
838
839 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
840 return -EINVAL;
841
842 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
843
844
845 list_for_each_entry(ioc, &ioc_list, list) {
846 id = ioc->pcidev->driver ?
847 ioc->pcidev->driver->id_table : NULL;
848 if (dd_cbfunc->probe)
849 dd_cbfunc->probe(ioc->pcidev, id);
850 }
851
852 return 0;
853}
854
855
856
857
858
859
860void
861mpt_device_driver_deregister(u8 cb_idx)
862{
863 struct mpt_pci_driver *dd_cbfunc;
864 MPT_ADAPTER *ioc;
865
866 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
867 return;
868
869 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
870
871 list_for_each_entry(ioc, &ioc_list, list) {
872 if (dd_cbfunc->remove)
873 dd_cbfunc->remove(ioc->pcidev);
874 }
875
876 MptDeviceDriverHandlers[cb_idx] = NULL;
877}
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892MPT_FRAME_HDR*
893mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
894{
895 MPT_FRAME_HDR *mf;
896 unsigned long flags;
897 u16 req_idx;
898
899
900
901#ifdef MFCNT
902 if (!ioc->active)
903 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
904 "returning NULL!\n", ioc->name);
905#endif
906
907
908 if (!ioc->active)
909 return NULL;
910
911 spin_lock_irqsave(&ioc->FreeQlock, flags);
912 if (!list_empty(&ioc->FreeQ)) {
913 int req_offset;
914
915 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
916 u.frame.linkage.list);
917 list_del(&mf->u.frame.linkage.list);
918 mf->u.frame.linkage.arg1 = 0;
919 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
920 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
921
922 req_idx = req_offset / ioc->req_sz;
923 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
924 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
925
926 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
927#ifdef MFCNT
928 ioc->mfcnt++;
929#endif
930 }
931 else
932 mf = NULL;
933 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
934
935#ifdef MFCNT
936 if (mf == NULL)
937 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
938 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
939 ioc->req_depth);
940 mfcounter++;
941 if (mfcounter == PRINT_MF_COUNT)
942 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
943 ioc->mfcnt, ioc->req_depth);
944#endif
945
946 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
947 ioc->name, cb_idx, ioc->id, mf));
948 return mf;
949}
950
951
952
953
954
955
956
957
958
959
960
961void
962mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
963{
964 u32 mf_dma_addr;
965 int req_offset;
966 u16 req_idx;
967
968
969 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
970 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
971
972 req_idx = req_offset / ioc->req_sz;
973 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
974 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
975
976 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
977
978 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
979 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
980 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
981 ioc->RequestNB[req_idx]));
982 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
983}
984
985
986
987
988
989
990
991
992
993
994
995
996
997void
998mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
999{
1000 u32 mf_dma_addr;
1001 int req_offset;
1002 u16 req_idx;
1003
1004
1005 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1006 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
1007 req_idx = req_offset / ioc->req_sz;
1008 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1009 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1010
1011 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1012
1013 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1014 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1015 ioc->name, mf_dma_addr, req_idx));
1016 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1017}
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028void
1029mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1030{
1031 unsigned long flags;
1032
1033
1034 spin_lock_irqsave(&ioc->FreeQlock, flags);
1035 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
1036 goto out;
1037
1038 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
1039 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
1040#ifdef MFCNT
1041 ioc->mfcnt--;
1042#endif
1043 out:
1044 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1045}
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057static void
1058mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1059{
1060 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1061 pSge->FlagsLength = cpu_to_le32(flagslength);
1062 pSge->Address = cpu_to_le32(dma_addr);
1063}
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074static void
1075mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1076{
1077 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1078 pSge->Address.Low = cpu_to_le32
1079 (lower_32_bits(dma_addr));
1080 pSge->Address.High = cpu_to_le32
1081 (upper_32_bits(dma_addr));
1082 pSge->FlagsLength = cpu_to_le32
1083 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1084}
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095static void
1096mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1097{
1098 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1099 u32 tmp;
1100
1101 pSge->Address.Low = cpu_to_le32
1102 (lower_32_bits(dma_addr));
1103 tmp = (u32)(upper_32_bits(dma_addr));
1104
1105
1106
1107
1108 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1109 flagslength |=
1110 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1111 tmp |= (1<<31);
1112 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1113 printk(KERN_DEBUG "1078 P0M2 addressing for "
1114 "addr = 0x%llx len = %d\n",
1115 (unsigned long long)dma_addr,
1116 MPI_SGE_LENGTH(flagslength));
1117 }
1118
1119 pSge->Address.High = cpu_to_le32(tmp);
1120 pSge->FlagsLength = cpu_to_le32(
1121 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1122}
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133static void
1134mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1135{
1136 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1137 pChain->Length = cpu_to_le16(length);
1138 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1139 pChain->NextChainOffset = next;
1140 pChain->Address = cpu_to_le32(dma_addr);
1141}
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152static void
1153mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1154{
1155 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1156 u32 tmp = dma_addr & 0xFFFFFFFF;
1157
1158 pChain->Length = cpu_to_le16(length);
1159 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1160 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1161
1162 pChain->NextChainOffset = next;
1163
1164 pChain->Address.Low = cpu_to_le32(tmp);
1165 tmp = (u32)(upper_32_bits(dma_addr));
1166 pChain->Address.High = cpu_to_le32(tmp);
1167}
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186int
1187mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1188{
1189 int r = 0;
1190 u8 *req_as_bytes;
1191 int ii;
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1204 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1205 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1206 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1207 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1208 }
1209
1210
1211 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1212
1213 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1214 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1215 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1216
1217
1218 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1219 return ii;
1220 }
1221
1222
1223 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1224 return -5;
1225
1226 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1227 ioc->name, ii));
1228
1229 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1230
1231 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1232 return -2;
1233 }
1234
1235
1236 req_as_bytes = (u8 *) req;
1237 for (ii = 0; ii < reqBytes/4; ii++) {
1238 u32 word;
1239
1240 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1241 (req_as_bytes[(ii*4) + 1] << 8) |
1242 (req_as_bytes[(ii*4) + 2] << 16) |
1243 (req_as_bytes[(ii*4) + 3] << 24));
1244 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1245 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1246 r = -3;
1247 break;
1248 }
1249 }
1250
1251 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1252 r = 0;
1253 else
1254 r = -4;
1255
1256
1257 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1258
1259 return r;
1260}
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281static int
1282mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1283{
1284 int r = 0;
1285
1286
1287 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1288 & MPI_DOORBELL_ACTIVE)
1289 return -1;
1290
1291 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1292
1293 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1294 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1295 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1296 (access_control_value<<12)));
1297
1298
1299 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1300 return -2;
1301 }else
1302 return 0;
1303}
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314static int
1315mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1316{
1317 char *psge;
1318 int flags_length;
1319 u32 host_page_buffer_sz=0;
1320
1321 if(!ioc->HostPageBuffer) {
1322
1323 host_page_buffer_sz =
1324 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1325
1326 if(!host_page_buffer_sz)
1327 return 0;
1328
1329
1330 while(host_page_buffer_sz > 0) {
1331
1332 if((ioc->HostPageBuffer = pci_alloc_consistent(
1333 ioc->pcidev,
1334 host_page_buffer_sz,
1335 &ioc->HostPageBuffer_dma)) != NULL) {
1336
1337 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1338 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1339 ioc->name, ioc->HostPageBuffer,
1340 (u32)ioc->HostPageBuffer_dma,
1341 host_page_buffer_sz));
1342 ioc->alloc_total += host_page_buffer_sz;
1343 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1344 break;
1345 }
1346
1347 host_page_buffer_sz -= (4*1024);
1348 }
1349 }
1350
1351 if(!ioc->HostPageBuffer) {
1352 printk(MYIOC_s_ERR_FMT
1353 "Failed to alloc memory for host_page_buffer!\n",
1354 ioc->name);
1355 return -999;
1356 }
1357
1358 psge = (char *)&ioc_init->HostPageBufferSGE;
1359 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1360 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1361 MPI_SGE_FLAGS_HOST_TO_IOC |
1362 MPI_SGE_FLAGS_END_OF_BUFFER;
1363 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1364 flags_length |= ioc->HostPageBuffer_sz;
1365 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1366 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1367
1368return 0;
1369}
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383int
1384mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1385{
1386 MPT_ADAPTER *ioc;
1387
1388 list_for_each_entry(ioc,&ioc_list,list) {
1389 if (ioc->id == iocid) {
1390 *iocpp =ioc;
1391 return iocid;
1392 }
1393 }
1394
1395 *iocpp = NULL;
1396 return -1;
1397}
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410static void
1411mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1412{
1413 char *product_str = NULL;
1414
1415 if (vendor == PCI_VENDOR_ID_BROCADE) {
1416 switch (device)
1417 {
1418 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1419 switch (revision)
1420 {
1421 case 0x00:
1422 product_str = "BRE040 A0";
1423 break;
1424 case 0x01:
1425 product_str = "BRE040 A1";
1426 break;
1427 default:
1428 product_str = "BRE040";
1429 break;
1430 }
1431 break;
1432 }
1433 goto out;
1434 }
1435
1436 switch (device)
1437 {
1438 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1439 product_str = "LSIFC909 B1";
1440 break;
1441 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1442 product_str = "LSIFC919 B0";
1443 break;
1444 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1445 product_str = "LSIFC929 B0";
1446 break;
1447 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1448 if (revision < 0x80)
1449 product_str = "LSIFC919X A0";
1450 else
1451 product_str = "LSIFC919XL A1";
1452 break;
1453 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1454 if (revision < 0x80)
1455 product_str = "LSIFC929X A0";
1456 else
1457 product_str = "LSIFC929XL A1";
1458 break;
1459 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1460 product_str = "LSIFC939X A1";
1461 break;
1462 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1463 product_str = "LSIFC949X A1";
1464 break;
1465 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1466 switch (revision)
1467 {
1468 case 0x00:
1469 product_str = "LSIFC949E A0";
1470 break;
1471 case 0x01:
1472 product_str = "LSIFC949E A1";
1473 break;
1474 default:
1475 product_str = "LSIFC949E";
1476 break;
1477 }
1478 break;
1479 case MPI_MANUFACTPAGE_DEVID_53C1030:
1480 switch (revision)
1481 {
1482 case 0x00:
1483 product_str = "LSI53C1030 A0";
1484 break;
1485 case 0x01:
1486 product_str = "LSI53C1030 B0";
1487 break;
1488 case 0x03:
1489 product_str = "LSI53C1030 B1";
1490 break;
1491 case 0x07:
1492 product_str = "LSI53C1030 B2";
1493 break;
1494 case 0x08:
1495 product_str = "LSI53C1030 C0";
1496 break;
1497 case 0x80:
1498 product_str = "LSI53C1030T A0";
1499 break;
1500 case 0x83:
1501 product_str = "LSI53C1030T A2";
1502 break;
1503 case 0x87:
1504 product_str = "LSI53C1030T A3";
1505 break;
1506 case 0xc1:
1507 product_str = "LSI53C1020A A1";
1508 break;
1509 default:
1510 product_str = "LSI53C1030";
1511 break;
1512 }
1513 break;
1514 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1515 switch (revision)
1516 {
1517 case 0x03:
1518 product_str = "LSI53C1035 A2";
1519 break;
1520 case 0x04:
1521 product_str = "LSI53C1035 B0";
1522 break;
1523 default:
1524 product_str = "LSI53C1035";
1525 break;
1526 }
1527 break;
1528 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1529 switch (revision)
1530 {
1531 case 0x00:
1532 product_str = "LSISAS1064 A1";
1533 break;
1534 case 0x01:
1535 product_str = "LSISAS1064 A2";
1536 break;
1537 case 0x02:
1538 product_str = "LSISAS1064 A3";
1539 break;
1540 case 0x03:
1541 product_str = "LSISAS1064 A4";
1542 break;
1543 default:
1544 product_str = "LSISAS1064";
1545 break;
1546 }
1547 break;
1548 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1549 switch (revision)
1550 {
1551 case 0x00:
1552 product_str = "LSISAS1064E A0";
1553 break;
1554 case 0x01:
1555 product_str = "LSISAS1064E B0";
1556 break;
1557 case 0x02:
1558 product_str = "LSISAS1064E B1";
1559 break;
1560 case 0x04:
1561 product_str = "LSISAS1064E B2";
1562 break;
1563 case 0x08:
1564 product_str = "LSISAS1064E B3";
1565 break;
1566 default:
1567 product_str = "LSISAS1064E";
1568 break;
1569 }
1570 break;
1571 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1572 switch (revision)
1573 {
1574 case 0x00:
1575 product_str = "LSISAS1068 A0";
1576 break;
1577 case 0x01:
1578 product_str = "LSISAS1068 B0";
1579 break;
1580 case 0x02:
1581 product_str = "LSISAS1068 B1";
1582 break;
1583 default:
1584 product_str = "LSISAS1068";
1585 break;
1586 }
1587 break;
1588 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1589 switch (revision)
1590 {
1591 case 0x00:
1592 product_str = "LSISAS1068E A0";
1593 break;
1594 case 0x01:
1595 product_str = "LSISAS1068E B0";
1596 break;
1597 case 0x02:
1598 product_str = "LSISAS1068E B1";
1599 break;
1600 case 0x04:
1601 product_str = "LSISAS1068E B2";
1602 break;
1603 case 0x08:
1604 product_str = "LSISAS1068E B3";
1605 break;
1606 default:
1607 product_str = "LSISAS1068E";
1608 break;
1609 }
1610 break;
1611 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1612 switch (revision)
1613 {
1614 case 0x00:
1615 product_str = "LSISAS1078 A0";
1616 break;
1617 case 0x01:
1618 product_str = "LSISAS1078 B0";
1619 break;
1620 case 0x02:
1621 product_str = "LSISAS1078 C0";
1622 break;
1623 case 0x03:
1624 product_str = "LSISAS1078 C1";
1625 break;
1626 case 0x04:
1627 product_str = "LSISAS1078 C2";
1628 break;
1629 default:
1630 product_str = "LSISAS1078";
1631 break;
1632 }
1633 break;
1634 }
1635
1636 out:
1637 if (product_str)
1638 sprintf(prod_name, "%s", product_str);
1639}
1640
1641
1642
1643
1644
1645
1646static int
1647mpt_mapresources(MPT_ADAPTER *ioc)
1648{
1649 u8 __iomem *mem;
1650 int ii;
1651 resource_size_t mem_phys;
1652 unsigned long port;
1653 u32 msize;
1654 u32 psize;
1655 u8 revision;
1656 int r = -ENODEV;
1657 struct pci_dev *pdev;
1658
1659 pdev = ioc->pcidev;
1660 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1661 if (pci_enable_device_mem(pdev)) {
1662 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1663 "failed\n", ioc->name);
1664 return r;
1665 }
1666 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1667 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1668 "MEM failed\n", ioc->name);
1669 return r;
1670 }
1671
1672 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1673
1674 if (sizeof(dma_addr_t) > 4) {
1675 const uint64_t required_mask = dma_get_required_mask
1676 (&pdev->dev);
1677 if (required_mask > DMA_BIT_MASK(32)
1678 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1679 && !pci_set_consistent_dma_mask(pdev,
1680 DMA_BIT_MASK(64))) {
1681 ioc->dma_mask = DMA_BIT_MASK(64);
1682 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1683 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1684 ioc->name));
1685 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1686 && !pci_set_consistent_dma_mask(pdev,
1687 DMA_BIT_MASK(32))) {
1688 ioc->dma_mask = DMA_BIT_MASK(32);
1689 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1690 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1691 ioc->name));
1692 } else {
1693 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1694 ioc->name, pci_name(pdev));
1695 pci_release_selected_regions(pdev, ioc->bars);
1696 return r;
1697 }
1698 } else {
1699 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1700 && !pci_set_consistent_dma_mask(pdev,
1701 DMA_BIT_MASK(32))) {
1702 ioc->dma_mask = DMA_BIT_MASK(32);
1703 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1704 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1705 ioc->name));
1706 } else {
1707 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1708 ioc->name, pci_name(pdev));
1709 pci_release_selected_regions(pdev, ioc->bars);
1710 return r;
1711 }
1712 }
1713
1714 mem_phys = msize = 0;
1715 port = psize = 0;
1716 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1717 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1718 if (psize)
1719 continue;
1720
1721 port = pci_resource_start(pdev, ii);
1722 psize = pci_resource_len(pdev, ii);
1723 } else {
1724 if (msize)
1725 continue;
1726
1727 mem_phys = pci_resource_start(pdev, ii);
1728 msize = pci_resource_len(pdev, ii);
1729 }
1730 }
1731 ioc->mem_size = msize;
1732
1733 mem = NULL;
1734
1735
1736 mem = ioremap(mem_phys, msize);
1737 if (mem == NULL) {
1738 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1739 " memory!\n", ioc->name);
1740 pci_release_selected_regions(pdev, ioc->bars);
1741 return -EINVAL;
1742 }
1743 ioc->memmap = mem;
1744 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1745 ioc->name, mem, (unsigned long long)mem_phys));
1746
1747 ioc->mem_phys = mem_phys;
1748 ioc->chip = (SYSIF_REGS __iomem *)mem;
1749
1750
1751 ioc->pio_mem_phys = port;
1752 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1753
1754 return 0;
1755}
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775int
1776mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1777{
1778 MPT_ADAPTER *ioc;
1779 u8 cb_idx;
1780 int r = -ENODEV;
1781 u8 revision;
1782 u8 pcixcmd;
1783 static int mpt_ids = 0;
1784#ifdef CONFIG_PROC_FS
1785 struct proc_dir_entry *dent;
1786#endif
1787
1788 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1789 if (ioc == NULL) {
1790 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1791 return -ENOMEM;
1792 }
1793
1794 ioc->id = mpt_ids++;
1795 sprintf(ioc->name, "ioc%d", ioc->id);
1796 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1797
1798
1799
1800
1801
1802
1803 ioc->debug_level = mpt_debug_level;
1804 if (mpt_debug_level)
1805 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1806
1807 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1808
1809 ioc->pcidev = pdev;
1810 if (mpt_mapresources(ioc)) {
1811 kfree(ioc);
1812 return r;
1813 }
1814
1815
1816
1817
1818 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1819 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1820 ioc->add_sge = &mpt_add_sge_64bit_1078;
1821 else
1822 ioc->add_sge = &mpt_add_sge_64bit;
1823 ioc->add_chain = &mpt_add_chain_64bit;
1824 ioc->sg_addr_size = 8;
1825 } else {
1826 ioc->add_sge = &mpt_add_sge;
1827 ioc->add_chain = &mpt_add_chain;
1828 ioc->sg_addr_size = 4;
1829 }
1830 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1831
1832 ioc->alloc_total = sizeof(MPT_ADAPTER);
1833 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;
1834 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1835
1836
1837 spin_lock_init(&ioc->taskmgmt_lock);
1838 mutex_init(&ioc->internal_cmds.mutex);
1839 init_completion(&ioc->internal_cmds.done);
1840 mutex_init(&ioc->mptbase_cmds.mutex);
1841 init_completion(&ioc->mptbase_cmds.done);
1842 mutex_init(&ioc->taskmgmt_cmds.mutex);
1843 init_completion(&ioc->taskmgmt_cmds.done);
1844
1845
1846
1847 ioc->eventTypes = 0;
1848 ioc->eventContext = 0;
1849 ioc->eventLogSize = 0;
1850 ioc->events = NULL;
1851
1852#ifdef MFCNT
1853 ioc->mfcnt = 0;
1854#endif
1855
1856 ioc->sh = NULL;
1857 ioc->cached_fw = NULL;
1858
1859
1860
1861 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1862
1863
1864
1865 INIT_LIST_HEAD(&ioc->fc_rports);
1866
1867
1868 INIT_LIST_HEAD(&ioc->list);
1869
1870
1871
1872 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1873
1874 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1875 "mpt_poll_%d", ioc->id);
1876 ioc->reset_work_q =
1877 create_singlethread_workqueue(ioc->reset_work_q_name);
1878 if (!ioc->reset_work_q) {
1879 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1880 ioc->name);
1881 pci_release_selected_regions(pdev, ioc->bars);
1882 kfree(ioc);
1883 return -ENOMEM;
1884 }
1885
1886 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1887 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1888
1889 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1890 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1891
1892 switch (pdev->device)
1893 {
1894 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1895 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1896 ioc->errata_flag_1064 = 1;
1897 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1898 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1899 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1900 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1901 ioc->bus_type = FC;
1902 break;
1903
1904 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1905 if (revision < XL_929) {
1906
1907
1908
1909 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1910 pcixcmd &= 0x8F;
1911 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1912 } else {
1913
1914
1915 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1916 pcixcmd |= 0x08;
1917 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1918 }
1919 ioc->bus_type = FC;
1920 break;
1921
1922 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1923
1924
1925
1926 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1927 pcixcmd &= 0x8F;
1928 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1929 ioc->bus_type = FC;
1930 break;
1931
1932 case MPI_MANUFACTPAGE_DEVID_53C1030:
1933
1934
1935
1936 if (revision < C0_1030) {
1937 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1938 pcixcmd &= 0x8F;
1939 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1940 }
1941
1942 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1943 ioc->bus_type = SPI;
1944 break;
1945
1946 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1947 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1948 ioc->errata_flag_1064 = 1;
1949 ioc->bus_type = SAS;
1950 break;
1951
1952 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1953 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1954 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1955 ioc->bus_type = SAS;
1956 break;
1957 }
1958
1959
1960 switch (ioc->bus_type) {
1961
1962 case SAS:
1963 ioc->msi_enable = mpt_msi_enable_sas;
1964 break;
1965
1966 case SPI:
1967 ioc->msi_enable = mpt_msi_enable_spi;
1968 break;
1969
1970 case FC:
1971 ioc->msi_enable = mpt_msi_enable_fc;
1972 break;
1973
1974 default:
1975 ioc->msi_enable = 0;
1976 break;
1977 }
1978
1979 ioc->fw_events_off = 1;
1980
1981 if (ioc->errata_flag_1064)
1982 pci_disable_io_access(pdev);
1983
1984 spin_lock_init(&ioc->FreeQlock);
1985
1986
1987 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1988 ioc->active = 0;
1989 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1990
1991
1992 pci_set_drvdata(ioc->pcidev, ioc);
1993
1994
1995 list_add_tail(&ioc->list, &ioc_list);
1996
1997
1998
1999 mpt_detect_bound_ports(ioc, pdev);
2000
2001 INIT_LIST_HEAD(&ioc->fw_event_list);
2002 spin_lock_init(&ioc->fw_event_lock);
2003 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
2004 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
2005
2006 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2007 CAN_SLEEP)) != 0){
2008 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2009 ioc->name, r);
2010
2011 list_del(&ioc->list);
2012 if (ioc->alt_ioc)
2013 ioc->alt_ioc->alt_ioc = NULL;
2014 iounmap(ioc->memmap);
2015 if (r != -5)
2016 pci_release_selected_regions(pdev, ioc->bars);
2017
2018 destroy_workqueue(ioc->reset_work_q);
2019 ioc->reset_work_q = NULL;
2020
2021 kfree(ioc);
2022 pci_set_drvdata(pdev, NULL);
2023 return r;
2024 }
2025
2026
2027 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2028 if(MptDeviceDriverHandlers[cb_idx] &&
2029 MptDeviceDriverHandlers[cb_idx]->probe) {
2030 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
2031 }
2032 }
2033
2034#ifdef CONFIG_PROC_FS
2035
2036
2037
2038 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2039 if (dent) {
2040 proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
2041 proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
2042 }
2043#endif
2044
2045 if (!ioc->alt_ioc)
2046 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2047 msecs_to_jiffies(MPT_POLLING_INTERVAL));
2048
2049 return 0;
2050}
2051
2052
2053
2054
2055
2056
2057
2058void
2059mpt_detach(struct pci_dev *pdev)
2060{
2061 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2062 char pname[32];
2063 u8 cb_idx;
2064 unsigned long flags;
2065 struct workqueue_struct *wq;
2066
2067
2068
2069
2070 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2071 wq = ioc->reset_work_q;
2072 ioc->reset_work_q = NULL;
2073 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2074 cancel_delayed_work(&ioc->fault_reset_work);
2075 destroy_workqueue(wq);
2076
2077 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2078 wq = ioc->fw_event_q;
2079 ioc->fw_event_q = NULL;
2080 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2081 destroy_workqueue(wq);
2082
2083 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2084 remove_proc_entry(pname, NULL);
2085 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2086 remove_proc_entry(pname, NULL);
2087 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2088 remove_proc_entry(pname, NULL);
2089
2090
2091 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2092 if(MptDeviceDriverHandlers[cb_idx] &&
2093 MptDeviceDriverHandlers[cb_idx]->remove) {
2094 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2095 }
2096 }
2097
2098
2099 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2100
2101 ioc->active = 0;
2102 synchronize_irq(pdev->irq);
2103
2104
2105 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2106
2107 CHIPREG_READ32(&ioc->chip->IntStatus);
2108
2109 mpt_adapter_dispose(ioc);
2110
2111}
2112
2113
2114
2115
2116#ifdef CONFIG_PM
2117
2118
2119
2120
2121
2122
2123int
2124mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2125{
2126 u32 device_state;
2127 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2128
2129 device_state = pci_choose_state(pdev, state);
2130 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2131 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2132 device_state);
2133
2134
2135 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2136 printk(MYIOC_s_ERR_FMT
2137 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2138 }
2139
2140
2141 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2142 ioc->active = 0;
2143
2144
2145 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2146
2147 free_irq(ioc->pci_irq, ioc);
2148 if (ioc->msi_enable)
2149 pci_disable_msi(ioc->pcidev);
2150 ioc->pci_irq = -1;
2151 pci_save_state(pdev);
2152 pci_disable_device(pdev);
2153 pci_release_selected_regions(pdev, ioc->bars);
2154 pci_set_power_state(pdev, device_state);
2155 return 0;
2156}
2157
2158
2159
2160
2161
2162
2163int
2164mpt_resume(struct pci_dev *pdev)
2165{
2166 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2167 u32 device_state = pdev->current_state;
2168 int recovery_state;
2169 int err;
2170
2171 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2172 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2173 device_state);
2174
2175 pci_set_power_state(pdev, PCI_D0);
2176 pci_enable_wake(pdev, PCI_D0, 0);
2177 pci_restore_state(pdev);
2178 ioc->pcidev = pdev;
2179 err = mpt_mapresources(ioc);
2180 if (err)
2181 return err;
2182
2183 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2184 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2185 ioc->add_sge = &mpt_add_sge_64bit_1078;
2186 else
2187 ioc->add_sge = &mpt_add_sge_64bit;
2188 ioc->add_chain = &mpt_add_chain_64bit;
2189 ioc->sg_addr_size = 8;
2190 } else {
2191
2192 ioc->add_sge = &mpt_add_sge;
2193 ioc->add_chain = &mpt_add_chain;
2194 ioc->sg_addr_size = 4;
2195 }
2196 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2197
2198 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2199 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2200 CHIPREG_READ32(&ioc->chip->Doorbell));
2201
2202
2203
2204
2205
2206
2207
2208
2209 if (ioc->bus_type == SAS && (pdev->device ==
2210 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2211 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2212 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2213 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2214 ioc->name);
2215 goto out;
2216 }
2217 }
2218
2219
2220 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2221 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2222 CAN_SLEEP);
2223 if (recovery_state != 0)
2224 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2225 "error:[%x]\n", ioc->name, recovery_state);
2226 else
2227 printk(MYIOC_s_INFO_FMT
2228 "pci-resume: success\n", ioc->name);
2229 out:
2230 return 0;
2231
2232}
2233#endif
2234
2235static int
2236mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2237{
2238 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2239 ioc->bus_type != SPI) ||
2240 (MptDriverClass[index] == MPTFC_DRIVER &&
2241 ioc->bus_type != FC) ||
2242 (MptDriverClass[index] == MPTSAS_DRIVER &&
2243 ioc->bus_type != SAS))
2244
2245
2246 return 0;
2247 return (MptResetHandlers[index])(ioc, reset_phase);
2248}
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272static int
2273mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2274{
2275 int hard_reset_done = 0;
2276 int alt_ioc_ready = 0;
2277 int hard;
2278 int rc=0;
2279 int ii;
2280 int ret = 0;
2281 int reset_alt_ioc_active = 0;
2282 int irq_allocated = 0;
2283 u8 *a;
2284
2285 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2286 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2287
2288
2289 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2290 ioc->active = 0;
2291
2292 if (ioc->alt_ioc) {
2293 if (ioc->alt_ioc->active ||
2294 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2295 reset_alt_ioc_active = 1;
2296
2297
2298
2299 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2300 0xFFFFFFFF);
2301 ioc->alt_ioc->active = 0;
2302 }
2303 }
2304
2305 hard = 1;
2306 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2307 hard = 0;
2308
2309 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2310 if (hard_reset_done == -4) {
2311 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2312 ioc->name);
2313
2314 if (reset_alt_ioc_active && ioc->alt_ioc) {
2315
2316 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2317 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2318 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2319 ioc->alt_ioc->active = 1;
2320 }
2321
2322 } else {
2323 printk(MYIOC_s_WARN_FMT
2324 "NOT READY WARNING!\n", ioc->name);
2325 }
2326 ret = -1;
2327 goto out;
2328 }
2329
2330
2331
2332
2333 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2334 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2335 alt_ioc_ready = 1;
2336 else
2337 printk(MYIOC_s_WARN_FMT
2338 ": alt-ioc Not ready WARNING!\n",
2339 ioc->alt_ioc->name);
2340 }
2341
2342 for (ii=0; ii<5; ii++) {
2343
2344 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2345 break;
2346 }
2347
2348
2349 if (ii == 5) {
2350 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2351 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2352 ret = -2;
2353 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2354 MptDisplayIocCapabilities(ioc);
2355 }
2356
2357 if (alt_ioc_ready) {
2358 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2359 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2360 "Initial Alt IocFacts failed rc=%x\n",
2361 ioc->name, rc));
2362
2363
2364 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2365 }
2366 if (rc) {
2367 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2368 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2369 alt_ioc_ready = 0;
2370 reset_alt_ioc_active = 0;
2371 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2372 MptDisplayIocCapabilities(ioc->alt_ioc);
2373 }
2374 }
2375
2376 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2377 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2378 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2379 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2380 IORESOURCE_IO);
2381 if (pci_enable_device(ioc->pcidev))
2382 return -5;
2383 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2384 "mpt"))
2385 return -5;
2386 }
2387
2388
2389
2390
2391
2392
2393 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2394 ioc->pci_irq = -1;
2395 if (ioc->pcidev->irq) {
2396 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2397 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2398 ioc->name);
2399 else
2400 ioc->msi_enable = 0;
2401 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2402 IRQF_SHARED, ioc->name, ioc);
2403 if (rc < 0) {
2404 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2405 "interrupt %d!\n",
2406 ioc->name, ioc->pcidev->irq);
2407 if (ioc->msi_enable)
2408 pci_disable_msi(ioc->pcidev);
2409 ret = -EBUSY;
2410 goto out;
2411 }
2412 irq_allocated = 1;
2413 ioc->pci_irq = ioc->pcidev->irq;
2414 pci_set_master(ioc->pcidev);
2415 pci_set_drvdata(ioc->pcidev, ioc);
2416 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2417 "installed at interrupt %d\n", ioc->name,
2418 ioc->pcidev->irq));
2419 }
2420 }
2421
2422
2423
2424
2425
2426
2427 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2428 ioc->name));
2429 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2430 ret = -3;
2431
2432
2433
2434
2435 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2436 ioc->name));
2437 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2438 ret = -4;
2439
2440 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2441 printk(MYIOC_s_WARN_FMT
2442 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2443 ioc->alt_ioc->name, rc);
2444 alt_ioc_ready = 0;
2445 reset_alt_ioc_active = 0;
2446 }
2447
2448 if (alt_ioc_ready) {
2449 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2450 alt_ioc_ready = 0;
2451 reset_alt_ioc_active = 0;
2452 printk(MYIOC_s_WARN_FMT
2453 ": alt-ioc: (%d) init failure WARNING!\n",
2454 ioc->alt_ioc->name, rc);
2455 }
2456 }
2457
2458 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2459 if (ioc->upload_fw) {
2460 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2461 "firmware upload required!\n", ioc->name));
2462
2463
2464
2465 if (ret == 0) {
2466 rc = mpt_do_upload(ioc, sleepFlag);
2467 if (rc == 0) {
2468 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2469
2470
2471
2472
2473
2474
2475
2476 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2477 "mpt_upload: alt_%s has cached_fw=%p \n",
2478 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2479 ioc->cached_fw = NULL;
2480 }
2481 } else {
2482 printk(MYIOC_s_WARN_FMT
2483 "firmware upload failure!\n", ioc->name);
2484 ret = -6;
2485 }
2486 }
2487 }
2488 }
2489
2490
2491
2492
2493 if ((ret == 0) && (!ioc->facts.EventState)) {
2494 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2495 "SendEventNotification\n",
2496 ioc->name));
2497 ret = SendEventNotification(ioc, 1, sleepFlag);
2498 }
2499
2500 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2501 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2502
2503 if (ret == 0) {
2504
2505 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2506 ioc->active = 1;
2507 }
2508 if (rc == 0) {
2509 if (reset_alt_ioc_active && ioc->alt_ioc) {
2510
2511 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2512 "reply irq re-enabled\n",
2513 ioc->alt_ioc->name));
2514 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2515 MPI_HIM_DIM);
2516 ioc->alt_ioc->active = 1;
2517 }
2518 }
2519
2520
2521
2522
2523
2524
2525
2526
2527 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2528
2529
2530
2531
2532 mutex_init(&ioc->raid_data.inactive_list_mutex);
2533 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2534
2535 switch (ioc->bus_type) {
2536
2537 case SAS:
2538
2539 if(ioc->facts.IOCExceptions &
2540 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2541 ret = mptbase_sas_persist_operation(ioc,
2542 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2543 if(ret != 0)
2544 goto out;
2545 }
2546
2547
2548
2549 mpt_findImVolumes(ioc);
2550
2551
2552
2553 mpt_read_ioc_pg_1(ioc);
2554
2555 break;
2556
2557 case FC:
2558 if ((ioc->pfacts[0].ProtocolFlags &
2559 MPI_PORTFACTS_PROTOCOL_LAN) &&
2560 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2561
2562
2563
2564
2565 (void) GetLanConfigPages(ioc);
2566 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2567 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2568 "LanAddr = %02X:%02X:%02X"
2569 ":%02X:%02X:%02X\n",
2570 ioc->name, a[5], a[4],
2571 a[3], a[2], a[1], a[0]));
2572 }
2573 break;
2574
2575 case SPI:
2576
2577
2578 mpt_GetScsiPortSettings(ioc, 0);
2579
2580
2581
2582 mpt_readScsiDevicePageHeaders(ioc, 0);
2583
2584
2585
2586 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2587 mpt_findImVolumes(ioc);
2588
2589
2590
2591 mpt_read_ioc_pg_1(ioc);
2592
2593 mpt_read_ioc_pg_4(ioc);
2594
2595 break;
2596 }
2597
2598 GetIoUnitPage2(ioc);
2599 mpt_get_manufacturing_pg_0(ioc);
2600 }
2601
2602 out:
2603 if ((ret != 0) && irq_allocated) {
2604 free_irq(ioc->pci_irq, ioc);
2605 if (ioc->msi_enable)
2606 pci_disable_msi(ioc->pcidev);
2607 }
2608 return ret;
2609}
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624static void
2625mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2626{
2627 struct pci_dev *peer=NULL;
2628 unsigned int slot = PCI_SLOT(pdev->devfn);
2629 unsigned int func = PCI_FUNC(pdev->devfn);
2630 MPT_ADAPTER *ioc_srch;
2631
2632 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2633 " searching for devfn match on %x or %x\n",
2634 ioc->name, pci_name(pdev), pdev->bus->number,
2635 pdev->devfn, func-1, func+1));
2636
2637 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2638 if (!peer) {
2639 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2640 if (!peer)
2641 return;
2642 }
2643
2644 list_for_each_entry(ioc_srch, &ioc_list, list) {
2645 struct pci_dev *_pcidev = ioc_srch->pcidev;
2646 if (_pcidev == peer) {
2647
2648 if (ioc->alt_ioc != NULL) {
2649 printk(MYIOC_s_WARN_FMT
2650 "Oops, already bound (%s <==> %s)!\n",
2651 ioc->name, ioc->name, ioc->alt_ioc->name);
2652 break;
2653 } else if (ioc_srch->alt_ioc != NULL) {
2654 printk(MYIOC_s_WARN_FMT
2655 "Oops, already bound (%s <==> %s)!\n",
2656 ioc_srch->name, ioc_srch->name,
2657 ioc_srch->alt_ioc->name);
2658 break;
2659 }
2660 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2661 "FOUND! binding %s <==> %s\n",
2662 ioc->name, ioc->name, ioc_srch->name));
2663 ioc_srch->alt_ioc = ioc;
2664 ioc->alt_ioc = ioc_srch;
2665 }
2666 }
2667 pci_dev_put(peer);
2668}
2669
2670
2671
2672
2673
2674
2675static void
2676mpt_adapter_disable(MPT_ADAPTER *ioc)
2677{
2678 int sz;
2679 int ret;
2680
2681 if (ioc->cached_fw != NULL) {
2682 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2683 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2684 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2685 ioc->cached_fw, CAN_SLEEP)) < 0) {
2686 printk(MYIOC_s_WARN_FMT
2687 ": firmware downloadboot failure (%d)!\n",
2688 ioc->name, ret);
2689 }
2690 }
2691
2692
2693
2694
2695 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2696 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2697 CAN_SLEEP)) {
2698 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2699 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2700 "reset failed to put ioc in ready state!\n",
2701 ioc->name, __func__);
2702 } else
2703 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2704 "failed!\n", ioc->name, __func__);
2705 }
2706
2707
2708
2709 synchronize_irq(ioc->pcidev->irq);
2710 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2711 ioc->active = 0;
2712
2713
2714 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2715 CHIPREG_READ32(&ioc->chip->IntStatus);
2716
2717 if (ioc->alloc != NULL) {
2718 sz = ioc->alloc_sz;
2719 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2720 ioc->name, ioc->alloc, ioc->alloc_sz));
2721 pci_free_consistent(ioc->pcidev, sz,
2722 ioc->alloc, ioc->alloc_dma);
2723 ioc->reply_frames = NULL;
2724 ioc->req_frames = NULL;
2725 ioc->alloc = NULL;
2726 ioc->alloc_total -= sz;
2727 }
2728
2729 if (ioc->sense_buf_pool != NULL) {
2730 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2731 pci_free_consistent(ioc->pcidev, sz,
2732 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2733 ioc->sense_buf_pool = NULL;
2734 ioc->alloc_total -= sz;
2735 }
2736
2737 if (ioc->events != NULL){
2738 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2739 kfree(ioc->events);
2740 ioc->events = NULL;
2741 ioc->alloc_total -= sz;
2742 }
2743
2744 mpt_free_fw_memory(ioc);
2745
2746 kfree(ioc->spi_data.nvram);
2747 mpt_inactive_raid_list_free(ioc);
2748 kfree(ioc->raid_data.pIocPg2);
2749 kfree(ioc->raid_data.pIocPg3);
2750 ioc->spi_data.nvram = NULL;
2751 ioc->raid_data.pIocPg3 = NULL;
2752
2753 if (ioc->spi_data.pIocPg4 != NULL) {
2754 sz = ioc->spi_data.IocPg4Sz;
2755 pci_free_consistent(ioc->pcidev, sz,
2756 ioc->spi_data.pIocPg4,
2757 ioc->spi_data.IocPg4_dma);
2758 ioc->spi_data.pIocPg4 = NULL;
2759 ioc->alloc_total -= sz;
2760 }
2761
2762 if (ioc->ReqToChain != NULL) {
2763 kfree(ioc->ReqToChain);
2764 kfree(ioc->RequestNB);
2765 ioc->ReqToChain = NULL;
2766 }
2767
2768 kfree(ioc->ChainToChain);
2769 ioc->ChainToChain = NULL;
2770
2771 if (ioc->HostPageBuffer != NULL) {
2772 if((ret = mpt_host_page_access_control(ioc,
2773 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2774 printk(MYIOC_s_ERR_FMT
2775 ": %s: host page buffers free failed (%d)!\n",
2776 ioc->name, __func__, ret);
2777 }
2778 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2779 "HostPageBuffer free @ %p, sz=%d bytes\n",
2780 ioc->name, ioc->HostPageBuffer,
2781 ioc->HostPageBuffer_sz));
2782 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2783 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2784 ioc->HostPageBuffer = NULL;
2785 ioc->HostPageBuffer_sz = 0;
2786 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2787 }
2788
2789 pci_set_drvdata(ioc->pcidev, NULL);
2790}
2791
2792
2793
2794
2795
2796
2797
2798
2799static void
2800mpt_adapter_dispose(MPT_ADAPTER *ioc)
2801{
2802 int sz_first, sz_last;
2803
2804 if (ioc == NULL)
2805 return;
2806
2807 sz_first = ioc->alloc_total;
2808
2809 mpt_adapter_disable(ioc);
2810
2811 if (ioc->pci_irq != -1) {
2812 free_irq(ioc->pci_irq, ioc);
2813 if (ioc->msi_enable)
2814 pci_disable_msi(ioc->pcidev);
2815 ioc->pci_irq = -1;
2816 }
2817
2818 if (ioc->memmap != NULL) {
2819 iounmap(ioc->memmap);
2820 ioc->memmap = NULL;
2821 }
2822
2823 pci_disable_device(ioc->pcidev);
2824 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2825
2826#if defined(CONFIG_MTRR) && 0
2827 if (ioc->mtrr_reg > 0) {
2828 mtrr_del(ioc->mtrr_reg, 0, 0);
2829 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2830 }
2831#endif
2832
2833
2834 list_del(&ioc->list);
2835
2836 sz_last = ioc->alloc_total;
2837 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2838 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2839
2840 if (ioc->alt_ioc)
2841 ioc->alt_ioc->alt_ioc = NULL;
2842
2843 kfree(ioc);
2844}
2845
2846
2847
2848
2849
2850
2851static void
2852MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2853{
2854 int i = 0;
2855
2856 printk(KERN_INFO "%s: ", ioc->name);
2857 if (ioc->prod_name)
2858 printk("%s: ", ioc->prod_name);
2859 printk("Capabilities={");
2860
2861 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2862 printk("Initiator");
2863 i++;
2864 }
2865
2866 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2867 printk("%sTarget", i ? "," : "");
2868 i++;
2869 }
2870
2871 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2872 printk("%sLAN", i ? "," : "");
2873 i++;
2874 }
2875
2876#if 0
2877
2878
2879
2880 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2881 printk("%sLogBusAddr", i ? "," : "");
2882 i++;
2883 }
2884#endif
2885
2886 printk("}\n");
2887}
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904static int
2905MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2906{
2907 u32 ioc_state;
2908 int statefault = 0;
2909 int cntdn;
2910 int hard_reset_done = 0;
2911 int r;
2912 int ii;
2913 int whoinit;
2914
2915
2916 ioc_state = mpt_GetIocState(ioc, 0);
2917 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2918
2919
2920
2921
2922
2923 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2924 statefault = 1;
2925 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2926 ioc->name);
2927 }
2928
2929
2930 if (!statefault &&
2931 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2932 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2933 "IOC is in READY state\n", ioc->name));
2934 return 0;
2935 }
2936
2937
2938
2939
2940 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2941 statefault = 2;
2942 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2943 ioc->name);
2944 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2945 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2946 }
2947
2948
2949
2950
2951 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2952 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2953 ioc->name));
2954
2955
2956
2957
2958
2959
2960 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2961 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2962 "whoinit 0x%x statefault %d force %d\n",
2963 ioc->name, whoinit, statefault, force));
2964 if (whoinit == MPI_WHOINIT_PCI_PEER)
2965 return -4;
2966 else {
2967 if ((statefault == 0 ) && (force == 0)) {
2968 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2969 return 0;
2970 }
2971 statefault = 3;
2972 }
2973 }
2974
2975 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2976 if (hard_reset_done < 0)
2977 return -1;
2978
2979
2980
2981
2982 ii = 0;
2983 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;
2984
2985 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2986 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2987
2988
2989
2990
2991 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2992 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2993 return -2;
2994 }
2995 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2996
2997
2998
2999
3000 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
3001 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3002 return -3;
3003 }
3004 }
3005
3006 ii++; cntdn--;
3007 if (!cntdn) {
3008 printk(MYIOC_s_ERR_FMT
3009 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
3010 ioc->name, ioc_state, (int)((ii+5)/HZ));
3011 return -ETIME;
3012 }
3013
3014 if (sleepFlag == CAN_SLEEP) {
3015 msleep(1);
3016 } else {
3017 mdelay (1);
3018 }
3019
3020 }
3021
3022 if (statefault < 3) {
3023 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3024 statefault == 1 ? "stuck handshake" : "IOC FAULT");
3025 }
3026
3027 return hard_reset_done;
3028}
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039u32
3040mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3041{
3042 u32 s, sc;
3043
3044
3045 s = CHIPREG_READ32(&ioc->chip->Doorbell);
3046 sc = s & MPI_IOC_STATE_MASK;
3047
3048
3049 ioc->last_state = sc;
3050
3051 return cooked ? sc : s;
3052}
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063static int
3064GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3065{
3066 IOCFacts_t get_facts;
3067 IOCFactsReply_t *facts;
3068 int r;
3069 int req_sz;
3070 int reply_sz;
3071 int sz;
3072 u32 status, vv;
3073 u8 shiftFactor=1;
3074
3075
3076 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3077 printk(KERN_ERR MYNAM
3078 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3079 ioc->name, ioc->last_state);
3080 return -44;
3081 }
3082
3083 facts = &ioc->facts;
3084
3085
3086 reply_sz = sizeof(*facts);
3087 memset(facts, 0, reply_sz);
3088
3089
3090 req_sz = sizeof(get_facts);
3091 memset(&get_facts, 0, req_sz);
3092
3093 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3094
3095
3096 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3097 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3098 ioc->name, req_sz, reply_sz));
3099
3100
3101
3102
3103 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3104 reply_sz, (u16*)facts, 5 , sleepFlag);
3105 if (r != 0)
3106 return r;
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3117 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3118
3119
3120
3121 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3122 ioc->FirstWhoInit = facts->WhoInit;
3123 }
3124
3125 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3126 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3127 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3128 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3129 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3130 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3131
3132
3133 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3134 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3135
3136
3137
3138
3139
3140
3141 if (facts->MsgVersion < MPI_VERSION_01_02) {
3142
3143
3144
3145 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3146 facts->FWVersion.Word =
3147 ((oldv<<12) & 0xFF000000) |
3148 ((oldv<<8) & 0x000FFF00);
3149 } else
3150 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3151
3152 facts->ProductID = le16_to_cpu(facts->ProductID);
3153
3154 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3155 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3156 ioc->ir_firmware = 1;
3157
3158 facts->CurrentHostMfaHighAddr =
3159 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3160 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3161 facts->CurrentSenseBufferHighAddr =
3162 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3163 facts->CurReplyFrameSize =
3164 le16_to_cpu(facts->CurReplyFrameSize);
3165 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3166
3167
3168
3169
3170
3171
3172 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3173 facts->MsgVersion > MPI_VERSION_01_00) {
3174 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3175 }
3176
3177 sz = facts->FWImageSize;
3178 if ( sz & 0x01 )
3179 sz += 1;
3180 if ( sz & 0x02 )
3181 sz += 2;
3182 facts->FWImageSize = sz;
3183
3184 if (!facts->RequestFrameSize) {
3185
3186 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3187 ioc->name);
3188 return -55;
3189 }
3190
3191 r = sz = facts->BlockSize;
3192 vv = ((63 / (sz * 4)) + 1) & 0x03;
3193 ioc->NB_for_64_byte_frame = vv;
3194 while ( sz )
3195 {
3196 shiftFactor++;
3197 sz = sz >> 1;
3198 }
3199 ioc->NBShiftFactor = shiftFactor;
3200 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3201 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3202 ioc->name, vv, shiftFactor, r));
3203
3204 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3205
3206
3207
3208
3209 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3210 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3211 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3212 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3213
3214 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3215 ioc->name, ioc->reply_sz, ioc->reply_depth));
3216 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3217 ioc->name, ioc->req_sz, ioc->req_depth));
3218
3219
3220 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3221 return r;
3222 }
3223 } else {
3224 printk(MYIOC_s_ERR_FMT
3225 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3226 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3227 RequestFrameSize)/sizeof(u32)));
3228 return -66;
3229 }
3230
3231 return 0;
3232}
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243static int
3244GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3245{
3246 PortFacts_t get_pfacts;
3247 PortFactsReply_t *pfacts;
3248 int ii;
3249 int req_sz;
3250 int reply_sz;
3251 int max_id;
3252
3253
3254 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3255 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3256 ioc->name, ioc->last_state );
3257 return -4;
3258 }
3259
3260 pfacts = &ioc->pfacts[portnum];
3261
3262
3263 reply_sz = sizeof(*pfacts);
3264 memset(pfacts, 0, reply_sz);
3265
3266
3267 req_sz = sizeof(get_pfacts);
3268 memset(&get_pfacts, 0, req_sz);
3269
3270 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3271 get_pfacts.PortNumber = portnum;
3272
3273
3274 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3275 ioc->name, portnum));
3276
3277
3278
3279
3280 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3281 reply_sz, (u16*)pfacts, 5 , sleepFlag);
3282 if (ii != 0)
3283 return ii;
3284
3285
3286
3287
3288 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3289 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3290 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3291 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3292 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3293 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3294 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3295 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3296 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3297
3298 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3299 pfacts->MaxDevices;
3300 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3301 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3302
3303
3304
3305
3306
3307
3308 if (mpt_channel_mapping) {
3309 ioc->devices_per_bus = 1;
3310 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3311 }
3312
3313 return 0;
3314}
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326static int
3327SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3328{
3329 IOCInit_t ioc_init;
3330 MPIDefaultReply_t init_reply;
3331 u32 state;
3332 int r;
3333 int count;
3334 int cntdn;
3335
3336 memset(&ioc_init, 0, sizeof(ioc_init));
3337 memset(&init_reply, 0, sizeof(init_reply));
3338
3339 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3340 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3341
3342
3343
3344
3345
3346 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3347 ioc->upload_fw = 1;
3348 else
3349 ioc->upload_fw = 0;
3350 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3351 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3352
3353 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3354 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3355
3356 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3357 ioc->name, ioc->facts.MsgVersion));
3358 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3359
3360 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3361 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3362
3363 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3364 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3365 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3366 return -99;
3367 }
3368 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);
3369
3370 if (ioc->sg_addr_size == sizeof(u64)) {
3371
3372
3373
3374 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3375 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3376 } else {
3377
3378 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3379 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3380 }
3381
3382 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3383 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3384 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3385 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3386
3387 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3388 ioc->name, &ioc_init));
3389
3390 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3391 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 , sleepFlag);
3392 if (r != 0) {
3393 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3394 return r;
3395 }
3396
3397
3398
3399
3400
3401 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3402 ioc->name, &ioc_init));
3403
3404 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3405 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3406 return r;
3407 }
3408
3409
3410
3411
3412
3413 count = 0;
3414 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;
3415 state = mpt_GetIocState(ioc, 1);
3416 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3417 if (sleepFlag == CAN_SLEEP) {
3418 msleep(1);
3419 } else {
3420 mdelay(1);
3421 }
3422
3423 if (!cntdn) {
3424 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3425 ioc->name, (int)((count+5)/HZ));
3426 return -9;
3427 }
3428
3429 state = mpt_GetIocState(ioc, 1);
3430 count++;
3431 }
3432 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3433 ioc->name, count));
3434
3435 ioc->aen_event_read_flag=0;
3436 return r;
3437}
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450static int
3451SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3452{
3453 PortEnable_t port_enable;
3454 MPIDefaultReply_t reply_buf;
3455 int rc;
3456 int req_sz;
3457 int reply_sz;
3458
3459
3460 reply_sz = sizeof(MPIDefaultReply_t);
3461 memset(&reply_buf, 0, reply_sz);
3462
3463 req_sz = sizeof(PortEnable_t);
3464 memset(&port_enable, 0, req_sz);
3465
3466 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3467 port_enable.PortNumber = portnum;
3468
3469
3470
3471
3472 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3473 ioc->name, portnum, &port_enable));
3474
3475
3476
3477 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3478 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3479 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3480 300 , sleepFlag);
3481 } else {
3482 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3483 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3484 30 , sleepFlag);
3485 }
3486 return rc;
3487}
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499int
3500mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3501{
3502 int rc;
3503
3504 if (ioc->cached_fw) {
3505 rc = 0;
3506 goto out;
3507 }
3508 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3509 ioc->cached_fw = ioc->alt_ioc->cached_fw;
3510 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3511 rc = 0;
3512 goto out;
3513 }
3514 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3515 if (!ioc->cached_fw) {
3516 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3517 ioc->name);
3518 rc = -1;
3519 } else {
3520 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3521 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3522 ioc->alloc_total += size;
3523 rc = 0;
3524 }
3525 out:
3526 return rc;
3527}
3528
3529
3530
3531
3532
3533
3534
3535
3536void
3537mpt_free_fw_memory(MPT_ADAPTER *ioc)
3538{
3539 int sz;
3540
3541 if (!ioc->cached_fw)
3542 return;
3543
3544 sz = ioc->facts.FWImageSize;
3545 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3546 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3547 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3548 ioc->alloc_total -= sz;
3549 ioc->cached_fw = NULL;
3550}
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566static int
3567mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3568{
3569 u8 reply[sizeof(FWUploadReply_t)];
3570 FWUpload_t *prequest;
3571 FWUploadReply_t *preply;
3572 FWUploadTCSGE_t *ptcsge;
3573 u32 flagsLength;
3574 int ii, sz, reply_sz;
3575 int cmdStatus;
3576 int request_size;
3577
3578
3579 if ((sz = ioc->facts.FWImageSize) == 0)
3580 return 0;
3581
3582 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3583 return -ENOMEM;
3584
3585 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3586 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3587
3588 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3589 kzalloc(ioc->req_sz, GFP_KERNEL);
3590 if (!prequest) {
3591 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3592 "while allocating memory \n", ioc->name));
3593 mpt_free_fw_memory(ioc);
3594 return -ENOMEM;
3595 }
3596
3597 preply = (FWUploadReply_t *)&reply;
3598
3599 reply_sz = sizeof(reply);
3600 memset(preply, 0, reply_sz);
3601
3602 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3603 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3604
3605 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3606 ptcsge->DetailsLength = 12;
3607 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3608 ptcsge->ImageSize = cpu_to_le32(sz);
3609 ptcsge++;
3610
3611 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3612 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3613 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3614 ioc->SGE_size;
3615 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3616 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3617 ioc->facts.FWImageSize, request_size));
3618 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3619
3620 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3621 reply_sz, (u16 *)preply, 65 , sleepFlag);
3622
3623 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3624 "rc=%x \n", ioc->name, ii));
3625
3626 cmdStatus = -EFAULT;
3627 if (ii == 0) {
3628
3629
3630
3631 int status;
3632 status = le16_to_cpu(preply->IOCStatus) &
3633 MPI_IOCSTATUS_MASK;
3634 if (status == MPI_IOCSTATUS_SUCCESS &&
3635 ioc->facts.FWImageSize ==
3636 le32_to_cpu(preply->ActualImageSize))
3637 cmdStatus = 0;
3638 }
3639 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3640 ioc->name, cmdStatus));
3641
3642
3643 if (cmdStatus) {
3644 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3645 "freeing image \n", ioc->name));
3646 mpt_free_fw_memory(ioc);
3647 }
3648 kfree(prequest);
3649
3650 return cmdStatus;
3651}
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667static int
3668mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3669{
3670 MpiExtImageHeader_t *pExtImage;
3671 u32 fwSize;
3672 u32 diag0val;
3673 int count;
3674 u32 *ptrFw;
3675 u32 diagRwData;
3676 u32 nextImage;
3677 u32 load_addr;
3678 u32 ioc_state=0;
3679
3680 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3681 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3682
3683 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3684 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3685 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3686 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3687 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3688 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3689
3690 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3691
3692
3693 if (sleepFlag == CAN_SLEEP) {
3694 msleep(1);
3695 } else {
3696 mdelay (1);
3697 }
3698
3699 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3700 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3701
3702 for (count = 0; count < 30; count ++) {
3703 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3704 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3705 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3706 ioc->name, count));
3707 break;
3708 }
3709
3710 if (sleepFlag == CAN_SLEEP) {
3711 msleep (100);
3712 } else {
3713 mdelay (100);
3714 }
3715 }
3716
3717 if ( count == 30 ) {
3718 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3719 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3720 ioc->name, diag0val));
3721 return -3;
3722 }
3723
3724 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3725 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3726 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3727 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3728 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3729 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3730
3731
3732 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3733
3734 fwSize = (pFwHeader->ImageSize + 3)/4;
3735 ptrFw = (u32 *) pFwHeader;
3736
3737
3738
3739
3740 if (ioc->errata_flag_1064)
3741 pci_enable_io_access(ioc->pcidev);
3742
3743 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3744 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3745 ioc->name, pFwHeader->LoadStartAddress));
3746
3747 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3748 ioc->name, fwSize*4, ptrFw));
3749 while (fwSize--) {
3750 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3751 }
3752
3753 nextImage = pFwHeader->NextImageHeaderOffset;
3754 while (nextImage) {
3755 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3756
3757 load_addr = pExtImage->LoadStartAddress;
3758
3759 fwSize = (pExtImage->ImageSize + 3) >> 2;
3760 ptrFw = (u32 *)pExtImage;
3761
3762 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3763 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3764 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3765
3766 while (fwSize--) {
3767 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3768 }
3769 nextImage = pExtImage->NextImageHeaderOffset;
3770 }
3771
3772
3773 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3774 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3775
3776
3777 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3778 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3779
3780
3781
3782
3783 if (ioc->bus_type == SPI) {
3784
3785
3786
3787
3788 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3789 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3790 diagRwData |= 0x40000000;
3791 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3792 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3793
3794 } else {
3795 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3796 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3797 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3798
3799
3800 if (sleepFlag == CAN_SLEEP) {
3801 msleep (1);
3802 } else {
3803 mdelay (1);
3804 }
3805 }
3806
3807 if (ioc->errata_flag_1064)
3808 pci_disable_io_access(ioc->pcidev);
3809
3810 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3811 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3812 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3813 ioc->name, diag0val));
3814 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3815 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3816 ioc->name, diag0val));
3817 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3818
3819
3820 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3821
3822 if (ioc->bus_type == SAS) {
3823 ioc_state = mpt_GetIocState(ioc, 0);
3824 if ( (GetIocFacts(ioc, sleepFlag,
3825 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3826 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3827 ioc->name, ioc_state));
3828 return -EFAULT;
3829 }
3830 }
3831
3832 for (count=0; count<HZ*20; count++) {
3833 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3834 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3835 "downloadboot successful! (count=%d) IocState=%x\n",
3836 ioc->name, count, ioc_state));
3837 if (ioc->bus_type == SAS) {
3838 return 0;
3839 }
3840 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3841 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3842 "downloadboot: SendIocInit failed\n",
3843 ioc->name));
3844 return -EFAULT;
3845 }
3846 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3847 "downloadboot: SendIocInit successful\n",
3848 ioc->name));
3849 return 0;
3850 }
3851 if (sleepFlag == CAN_SLEEP) {
3852 msleep (10);
3853 } else {
3854 mdelay (10);
3855 }
3856 }
3857 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3858 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3859 return -EFAULT;
3860}
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888static int
3889KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3890{
3891 int hard_reset_done = 0;
3892 u32 ioc_state=0;
3893 int cnt,cntdn;
3894
3895 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3896 if (ioc->bus_type == SPI) {
3897
3898
3899
3900 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3901
3902 if (sleepFlag == CAN_SLEEP) {
3903 msleep (1000);
3904 } else {
3905 mdelay (1000);
3906 }
3907 }
3908
3909 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3910 if (hard_reset_done < 0)
3911 return hard_reset_done;
3912
3913 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3914 ioc->name));
3915
3916 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;
3917 for (cnt=0; cnt<cntdn; cnt++) {
3918 ioc_state = mpt_GetIocState(ioc, 1);
3919 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3920 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3921 ioc->name, cnt));
3922 return hard_reset_done;
3923 }
3924 if (sleepFlag == CAN_SLEEP) {
3925 msleep (10);
3926 } else {
3927 mdelay (10);
3928 }
3929 }
3930
3931 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3932 ioc->name, mpt_GetIocState(ioc, 0)));
3933 return -1;
3934}
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955static int
3956mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3957{
3958 u32 diag0val;
3959 u32 doorbell;
3960 int hard_reset_done = 0;
3961 int count = 0;
3962 u32 diag1val = 0;
3963 MpiFwHeader_t *cached_fw;
3964 u8 cb_idx;
3965
3966
3967 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3968
3969 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3970
3971 if (!ignore)
3972 return 0;
3973
3974 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3975 "address=%p\n", ioc->name, __func__,
3976 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3977 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3978 if (sleepFlag == CAN_SLEEP)
3979 msleep(1);
3980 else
3981 mdelay(1);
3982
3983
3984
3985
3986
3987
3988
3989 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3990 if (MptResetHandlers[cb_idx])
3991 (*(MptResetHandlers[cb_idx]))(ioc,
3992 MPT_IOC_PRE_RESET);
3993 }
3994
3995 for (count = 0; count < 60; count ++) {
3996 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3997 doorbell &= MPI_IOC_STATE_MASK;
3998
3999 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4000 "looking for READY STATE: doorbell=%x"
4001 " count=%d\n",
4002 ioc->name, doorbell, count));
4003
4004 if (doorbell == MPI_IOC_STATE_READY) {
4005 return 1;
4006 }
4007
4008
4009 if (sleepFlag == CAN_SLEEP)
4010 msleep(1000);
4011 else
4012 mdelay(1000);
4013 }
4014 return -1;
4015 }
4016
4017
4018 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4019
4020 if (ioc->debug_level & MPT_DEBUG) {
4021 if (ioc->alt_ioc)
4022 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4023 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4024 ioc->name, diag0val, diag1val));
4025 }
4026
4027
4028
4029
4030 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4031 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4032
4033
4034
4035 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4036 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4037 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4038 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4039 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4040 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4041
4042
4043 if (sleepFlag == CAN_SLEEP) {
4044 msleep (100);
4045 } else {
4046 mdelay (100);
4047 }
4048
4049 count++;
4050 if (count > 20) {
4051 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4052 ioc->name, diag0val);
4053 return -2;
4054
4055 }
4056
4057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4058
4059 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4060 ioc->name, diag0val));
4061 }
4062
4063 if (ioc->debug_level & MPT_DEBUG) {
4064 if (ioc->alt_ioc)
4065 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4066 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4067 ioc->name, diag0val, diag1val));
4068 }
4069
4070
4071
4072
4073 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4074 mdelay(1);
4075
4076
4077
4078
4079
4080 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4081 hard_reset_done = 1;
4082 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4083 ioc->name));
4084
4085
4086
4087
4088
4089
4090
4091 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4092 if (MptResetHandlers[cb_idx]) {
4093 mpt_signal_reset(cb_idx,
4094 ioc, MPT_IOC_PRE_RESET);
4095 if (ioc->alt_ioc) {
4096 mpt_signal_reset(cb_idx,
4097 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4098 }
4099 }
4100 }
4101
4102 if (ioc->cached_fw)
4103 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4104 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4105 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4106 else
4107 cached_fw = NULL;
4108 if (cached_fw) {
4109
4110
4111
4112
4113 for (count = 0; count < 30; count ++) {
4114 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4115 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4116 break;
4117 }
4118
4119 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4120 ioc->name, diag0val, count));
4121
4122 if (sleepFlag == CAN_SLEEP) {
4123 msleep (1000);
4124 } else {
4125 mdelay (1000);
4126 }
4127 }
4128 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4129 printk(MYIOC_s_WARN_FMT
4130 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4131 }
4132
4133 } else {
4134
4135
4136
4137
4138
4139
4140 for (count = 0; count < 60; count ++) {
4141 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4142 doorbell &= MPI_IOC_STATE_MASK;
4143
4144 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4145 "looking for READY STATE: doorbell=%x"
4146 " count=%d\n", ioc->name, doorbell, count));
4147
4148 if (doorbell == MPI_IOC_STATE_READY) {
4149 break;
4150 }
4151
4152
4153 if (sleepFlag == CAN_SLEEP) {
4154 msleep (1000);
4155 } else {
4156 mdelay (1000);
4157 }
4158 }
4159
4160 if (doorbell != MPI_IOC_STATE_READY)
4161 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4162 "after reset! IocState=%x", ioc->name,
4163 doorbell);
4164 }
4165 }
4166
4167 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4168 if (ioc->debug_level & MPT_DEBUG) {
4169 if (ioc->alt_ioc)
4170 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4171 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4172 ioc->name, diag0val, diag1val));
4173 }
4174
4175
4176
4177
4178 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4179 count = 0;
4180 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4181
4182
4183
4184 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4185 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4186 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4187 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4188 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4189 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4190
4191
4192 if (sleepFlag == CAN_SLEEP) {
4193 msleep (100);
4194 } else {
4195 mdelay (100);
4196 }
4197
4198 count++;
4199 if (count > 20) {
4200 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4201 ioc->name, diag0val);
4202 break;
4203 }
4204 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4205 }
4206 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4207 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4208 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4209 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4210 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4211 ioc->name);
4212 }
4213
4214
4215
4216 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4217
4218
4219
4220 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4221 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4222 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4223 ioc->name, diag0val);
4224 return -3;
4225 }
4226
4227 if (ioc->debug_level & MPT_DEBUG) {
4228 if (ioc->alt_ioc)
4229 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4230 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4231 ioc->name, diag0val, diag1val));
4232 }
4233
4234
4235
4236
4237 ioc->facts.EventState = 0;
4238
4239 if (ioc->alt_ioc)
4240 ioc->alt_ioc->facts.EventState = 0;
4241
4242 return hard_reset_done;
4243}
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257static int
4258SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4259{
4260 int r;
4261 u32 state;
4262 int cntdn, count;
4263
4264 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4265 ioc->name, reset_type));
4266 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4267 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4268 return r;
4269
4270
4271
4272 count = 0;
4273 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;
4274
4275 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4276 cntdn--;
4277 count++;
4278 if (!cntdn) {
4279 if (sleepFlag != CAN_SLEEP)
4280 count *= 10;
4281
4282 printk(MYIOC_s_ERR_FMT
4283 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4284 ioc->name, state, (int)((count+5)/HZ));
4285 return -ETIME;
4286 }
4287
4288 if (sleepFlag == CAN_SLEEP) {
4289 msleep(1);
4290 } else {
4291 mdelay (1);
4292 }
4293 }
4294
4295
4296
4297
4298
4299 if (ioc->facts.Function)
4300 ioc->facts.EventState = 0;
4301
4302 return 0;
4303}
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313static int
4314initChainBuffers(MPT_ADAPTER *ioc)
4315{
4316 u8 *mem;
4317 int sz, ii, num_chain;
4318 int scale, num_sge, numSGE;
4319
4320
4321
4322
4323 if (ioc->ReqToChain == NULL) {
4324 sz = ioc->req_depth * sizeof(int);
4325 mem = kmalloc(sz, GFP_ATOMIC);
4326 if (mem == NULL)
4327 return -1;
4328
4329 ioc->ReqToChain = (int *) mem;
4330 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4331 ioc->name, mem, sz));
4332 mem = kmalloc(sz, GFP_ATOMIC);
4333 if (mem == NULL)
4334 return -1;
4335
4336 ioc->RequestNB = (int *) mem;
4337 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4338 ioc->name, mem, sz));
4339 }
4340 for (ii = 0; ii < ioc->req_depth; ii++) {
4341 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4342 }
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354 scale = ioc->req_sz / ioc->SGE_size;
4355 if (ioc->sg_addr_size == sizeof(u64))
4356 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4357 else
4358 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4359
4360 if (ioc->sg_addr_size == sizeof(u64)) {
4361 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4362 (ioc->req_sz - 60) / ioc->SGE_size;
4363 } else {
4364 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4365 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4366 }
4367 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4368 ioc->name, num_sge, numSGE));
4369
4370 if (ioc->bus_type == FC) {
4371 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4372 numSGE = MPT_SCSI_FC_SG_DEPTH;
4373 } else {
4374 if (numSGE > MPT_SCSI_SG_DEPTH)
4375 numSGE = MPT_SCSI_SG_DEPTH;
4376 }
4377
4378 num_chain = 1;
4379 while (numSGE - num_sge > 0) {
4380 num_chain++;
4381 num_sge += (scale - 1);
4382 }
4383 num_chain++;
4384
4385 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4386 ioc->name, numSGE, num_sge, num_chain));
4387
4388 if (ioc->bus_type == SPI)
4389 num_chain *= MPT_SCSI_CAN_QUEUE;
4390 else if (ioc->bus_type == SAS)
4391 num_chain *= MPT_SAS_CAN_QUEUE;
4392 else
4393 num_chain *= MPT_FC_CAN_QUEUE;
4394
4395 ioc->num_chain = num_chain;
4396
4397 sz = num_chain * sizeof(int);
4398 if (ioc->ChainToChain == NULL) {
4399 mem = kmalloc(sz, GFP_ATOMIC);
4400 if (mem == NULL)
4401 return -1;
4402
4403 ioc->ChainToChain = (int *) mem;
4404 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4405 ioc->name, mem, sz));
4406 } else {
4407 mem = (u8 *) ioc->ChainToChain;
4408 }
4409 memset(mem, 0xFF, sz);
4410 return num_chain;
4411}
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424static int
4425PrimeIocFifos(MPT_ADAPTER *ioc)
4426{
4427 MPT_FRAME_HDR *mf;
4428 unsigned long flags;
4429 dma_addr_t alloc_dma;
4430 u8 *mem;
4431 int i, reply_sz, sz, total_size, num_chain;
4432 u64 dma_mask;
4433
4434 dma_mask = 0;
4435
4436
4437
4438 if (ioc->reply_frames == NULL) {
4439 if ( (num_chain = initChainBuffers(ioc)) < 0)
4440 return -1;
4441
4442
4443
4444 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4445 ioc->dma_mask > DMA_BIT_MASK(35)) {
4446 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4447 && !pci_set_consistent_dma_mask(ioc->pcidev,
4448 DMA_BIT_MASK(32))) {
4449 dma_mask = DMA_BIT_MASK(35);
4450 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4451 "setting 35 bit addressing for "
4452 "Request/Reply/Chain and Sense Buffers\n",
4453 ioc->name));
4454 } else {
4455
4456 pci_set_dma_mask(ioc->pcidev,
4457 DMA_BIT_MASK(64));
4458 pci_set_consistent_dma_mask(ioc->pcidev,
4459 DMA_BIT_MASK(64));
4460
4461 printk(MYIOC_s_ERR_FMT
4462 "failed setting 35 bit addressing for "
4463 "Request/Reply/Chain and Sense Buffers\n",
4464 ioc->name);
4465 return -1;
4466 }
4467 }
4468
4469 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4470 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4471 ioc->name, ioc->reply_sz, ioc->reply_depth));
4472 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4473 ioc->name, reply_sz, reply_sz));
4474
4475 sz = (ioc->req_sz * ioc->req_depth);
4476 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4477 ioc->name, ioc->req_sz, ioc->req_depth));
4478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4479 ioc->name, sz, sz));
4480 total_size += sz;
4481
4482 sz = num_chain * ioc->req_sz;
4483 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4484 ioc->name, ioc->req_sz, num_chain));
4485 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4486 ioc->name, sz, sz, num_chain));
4487
4488 total_size += sz;
4489 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4490 if (mem == NULL) {
4491 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4492 ioc->name);
4493 goto out_fail;
4494 }
4495
4496 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4497 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4498
4499 memset(mem, 0, total_size);
4500 ioc->alloc_total += total_size;
4501 ioc->alloc = mem;
4502 ioc->alloc_dma = alloc_dma;
4503 ioc->alloc_sz = total_size;
4504 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4505 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4506
4507 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4508 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4509
4510 alloc_dma += reply_sz;
4511 mem += reply_sz;
4512
4513
4514
4515 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4516 ioc->req_frames_dma = alloc_dma;
4517
4518 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4519 ioc->name, mem, (void *)(ulong)alloc_dma));
4520
4521 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4522
4523#if defined(CONFIG_MTRR) && 0
4524
4525
4526
4527
4528
4529 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4530 sz,
4531 MTRR_TYPE_WRCOMB, 1);
4532 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4533 ioc->name, ioc->req_frames_dma, sz));
4534#endif
4535
4536 for (i = 0; i < ioc->req_depth; i++) {
4537 alloc_dma += ioc->req_sz;
4538 mem += ioc->req_sz;
4539 }
4540
4541 ioc->ChainBuffer = mem;
4542 ioc->ChainBufferDMA = alloc_dma;
4543
4544 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4545 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4546
4547
4548
4549
4550 INIT_LIST_HEAD(&ioc->FreeChainQ);
4551
4552
4553
4554 mem = (u8 *)ioc->ChainBuffer;
4555 for (i=0; i < num_chain; i++) {
4556 mf = (MPT_FRAME_HDR *) mem;
4557 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4558 mem += ioc->req_sz;
4559 }
4560
4561
4562
4563 alloc_dma = ioc->req_frames_dma;
4564 mem = (u8 *) ioc->req_frames;
4565
4566 spin_lock_irqsave(&ioc->FreeQlock, flags);
4567 INIT_LIST_HEAD(&ioc->FreeQ);
4568 for (i = 0; i < ioc->req_depth; i++) {
4569 mf = (MPT_FRAME_HDR *) mem;
4570
4571
4572 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4573
4574 mem += ioc->req_sz;
4575 }
4576 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4577
4578 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4579 ioc->sense_buf_pool =
4580 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4581 if (ioc->sense_buf_pool == NULL) {
4582 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4583 ioc->name);
4584 goto out_fail;
4585 }
4586
4587 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4588 ioc->alloc_total += sz;
4589 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4590 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4591
4592 }
4593
4594
4595
4596 alloc_dma = ioc->alloc_dma;
4597 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4598 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4599
4600 for (i = 0; i < ioc->reply_depth; i++) {
4601
4602 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4603 alloc_dma += ioc->reply_sz;
4604 }
4605
4606 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4607 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4608 ioc->dma_mask))
4609 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4610 "restoring 64 bit addressing\n", ioc->name));
4611
4612 return 0;
4613
4614out_fail:
4615
4616 if (ioc->alloc != NULL) {
4617 sz = ioc->alloc_sz;
4618 pci_free_consistent(ioc->pcidev,
4619 sz,
4620 ioc->alloc, ioc->alloc_dma);
4621 ioc->reply_frames = NULL;
4622 ioc->req_frames = NULL;
4623 ioc->alloc_total -= sz;
4624 }
4625 if (ioc->sense_buf_pool != NULL) {
4626 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4627 pci_free_consistent(ioc->pcidev,
4628 sz,
4629 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4630 ioc->sense_buf_pool = NULL;
4631 }
4632
4633 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4634 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4635 DMA_BIT_MASK(64)))
4636 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4637 "restoring 64 bit addressing\n", ioc->name));
4638
4639 return -1;
4640}
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661static int
4662mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4663 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4664{
4665 MPIDefaultReply_t *mptReply;
4666 int failcnt = 0;
4667 int t;
4668
4669
4670
4671
4672 ioc->hs_reply_idx = 0;
4673 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4674 mptReply->MsgLength = 0;
4675
4676
4677
4678
4679
4680
4681 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4682 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4683 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4684 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4685
4686
4687
4688
4689 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4690 failcnt++;
4691
4692 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4693 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4694
4695
4696 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4697 return -1;
4698
4699
4700
4701
4702
4703
4704 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4705 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4706 failcnt++;
4707
4708 if (!failcnt) {
4709 int ii;
4710 u8 *req_as_bytes = (u8 *) req;
4711
4712
4713
4714
4715
4716 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4717 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4718 (req_as_bytes[(ii*4) + 1] << 8) |
4719 (req_as_bytes[(ii*4) + 2] << 16) |
4720 (req_as_bytes[(ii*4) + 3] << 24));
4721
4722 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4723 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4724 failcnt++;
4725 }
4726
4727 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4728 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4729
4730 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4731 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4732
4733
4734
4735
4736 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4737 failcnt++;
4738
4739 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4740 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4741
4742
4743
4744
4745 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4746 u16reply[ii] = ioc->hs_reply[ii];
4747 } else {
4748 return -99;
4749 }
4750
4751 return -failcnt;
4752}
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767static int
4768WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4769{
4770 int cntdn;
4771 int count = 0;
4772 u32 intstat=0;
4773
4774 cntdn = 1000 * howlong;
4775
4776 if (sleepFlag == CAN_SLEEP) {
4777 while (--cntdn) {
4778 msleep (1);
4779 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4780 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4781 break;
4782 count++;
4783 }
4784 } else {
4785 while (--cntdn) {
4786 udelay (1000);
4787 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4788 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4789 break;
4790 count++;
4791 }
4792 }
4793
4794 if (cntdn) {
4795 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4796 ioc->name, count));
4797 return count;
4798 }
4799
4800 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4801 ioc->name, count, intstat);
4802 return -1;
4803}
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817static int
4818WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4819{
4820 int cntdn;
4821 int count = 0;
4822 u32 intstat=0;
4823
4824 cntdn = 1000 * howlong;
4825 if (sleepFlag == CAN_SLEEP) {
4826 while (--cntdn) {
4827 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4828 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4829 break;
4830 msleep(1);
4831 count++;
4832 }
4833 } else {
4834 while (--cntdn) {
4835 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4836 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4837 break;
4838 udelay (1000);
4839 count++;
4840 }
4841 }
4842
4843 if (cntdn) {
4844 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4845 ioc->name, count, howlong));
4846 return count;
4847 }
4848
4849 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4850 ioc->name, count, intstat);
4851 return -1;
4852}
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867static int
4868WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4869{
4870 int u16cnt = 0;
4871 int failcnt = 0;
4872 int t;
4873 u16 *hs_reply = ioc->hs_reply;
4874 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4875 u16 hword;
4876
4877 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4878
4879
4880
4881
4882 u16cnt=0;
4883 if ((t = WaitForDoorbellInt(ioc, howlong, 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 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4889 failcnt++;
4890 else {
4891 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4892 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4893 }
4894 }
4895
4896 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4897 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4898 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4899
4900
4901
4902
4903
4904 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4905 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4906 failcnt++;
4907 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4908
4909 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4910 hs_reply[u16cnt] = hword;
4911 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4912 }
4913
4914 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4915 failcnt++;
4916 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4917
4918 if (failcnt) {
4919 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4920 ioc->name);
4921 return -failcnt;
4922 }
4923#if 0
4924 else if (u16cnt != (2 * mptReply->MsgLength)) {
4925 return -101;
4926 }
4927 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4928 return -102;
4929 }
4930#endif
4931
4932 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4933 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4934
4935 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4936 i