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