mptfc.c (f0cd91a68acdc9b49d7f6738b514a426da627649) mptfc.c (80d3ac77a84987d5132726f3d7cef342a280f7d9)
1/*
2 * linux/drivers/message/fusion/mptfc.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 *
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
8 *

--- 582 unchanged lines hidden (view full) ---

591 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
592 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
593 SCpnt->device->id,SCpnt->device->lun));
594 }
595#endif
596 return err;
597}
598
1/*
2 * linux/drivers/message/fusion/mptfc.c
3 * For use with LSI Logic PCI chip/adapter(s)
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 *
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
8 *

--- 582 unchanged lines hidden (view full) ---

591 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
592 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
593 SCpnt->device->id,SCpnt->device->lun));
594 }
595#endif
596 return err;
597}
598
599/*
600 * mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
601 * @ioc: Pointer to MPT_ADAPTER structure
602 * @portnum: IOC Port number
603 *
604 * Return: 0 for success
605 * -ENOMEM if no memory available
606 * -EPERM if not allowed due to ISR context
607 * -EAGAIN if no msg frames currently available
608 * -EFAULT for non-successful reply or no reply (timeout)
609 * -EINVAL portnum arg out of range (hardwired to two elements)
610 */
611static int
612mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
613{
614 ConfigPageHeader_t hdr;
615 CONFIGPARMS cfg;
616 FCPortPage0_t *ppage0_alloc;
617 FCPortPage0_t *pp0dest;
618 dma_addr_t page0_dma;
619 int data_sz;
620 int copy_sz;
621 int rc;
622 int count = 400;
623
624 if (portnum > 1)
625 return -EINVAL;
626
627 /* Get FCPort Page 0 header */
628 hdr.PageVersion = 0;
629 hdr.PageLength = 0;
630 hdr.PageNumber = 0;
631 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
632 cfg.cfghdr.hdr = &hdr;
633 cfg.physAddr = -1;
634 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
635 cfg.dir = 0;
636 cfg.pageAddr = portnum;
637 cfg.timeout = 0;
638
639 if ((rc = mpt_config(ioc, &cfg)) != 0)
640 return rc;
641
642 if (hdr.PageLength == 0)
643 return 0;
644
645 data_sz = hdr.PageLength * 4;
646 rc = -ENOMEM;
647 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
648 if (ppage0_alloc) {
649
650 try_again:
651 memset((u8 *)ppage0_alloc, 0, data_sz);
652 cfg.physAddr = page0_dma;
653 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
654
655 if ((rc = mpt_config(ioc, &cfg)) == 0) {
656 /* save the data */
657 pp0dest = &ioc->fc_port_page0[portnum];
658 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
659 memcpy(pp0dest, ppage0_alloc, copy_sz);
660
661 /*
662 * Normalize endianness of structure data,
663 * by byte-swapping all > 1 byte fields!
664 */
665 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
666 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
667 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
668 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
669 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
670 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
671 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
672 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
673 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
674 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
675 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
676 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
677 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
678 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
679 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
680 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
681
682 /*
683 * if still doing discovery,
684 * hang loose a while until finished
685 */
686 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
687 if (count-- > 0) {
688 msleep_interruptible(100);
689 goto try_again;
690 }
691 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
692 " complete.\n",
693 ioc->name);
694 }
695 }
696
697 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
698 }
699
700 return rc;
701}
702
599static void
600mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
601{
602 unsigned class = 0, cos = 0;
603
604 /* don't know what to do as only one scsi (fc) host was allocated */
605 if (portnum != 0)
606 return;

--- 39 unchanged lines hidden (view full) ---

646 }
647 }
648
649 /*
650 * now rescan devices known to adapter,
651 * will reregister existing rports
652 */
653 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
703static void
704mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
705{
706 unsigned class = 0, cos = 0;
707
708 /* don't know what to do as only one scsi (fc) host was allocated */
709 if (portnum != 0)
710 return;

--- 39 unchanged lines hidden (view full) ---

750 }
751 }
752
753 /*
754 * now rescan devices known to adapter,
755 * will reregister existing rports
756 */
757 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
654 (void) mptbase_GetFcPortPage0(ioc, ii);
758 (void) mptfc_GetFcPortPage0(ioc, ii);
655 mptfc_init_host_attr(ioc,ii); /* refresh */
656 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
657 }
658
659 /* delete devices still missing */
660 list_for_each_entry(ri, &ioc->fc_rports, list) {
661 /* if newly missing, delete it */
662 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {

--- 85 unchanged lines hidden (view full) ---

748 if (!sh) {
749 printk(MYIOC_s_WARN_FMT
750 "Unable to register controller with SCSI subsystem\n",
751 ioc->name);
752 error = -1;
753 goto out_mptfc_probe;
754 }
755
759 mptfc_init_host_attr(ioc,ii); /* refresh */
760 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
761 }
762
763 /* delete devices still missing */
764 list_for_each_entry(ri, &ioc->fc_rports, list) {
765 /* if newly missing, delete it */
766 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {

--- 85 unchanged lines hidden (view full) ---

852 if (!sh) {
853 printk(MYIOC_s_WARN_FMT
854 "Unable to register controller with SCSI subsystem\n",
855 ioc->name);
856 error = -1;
857 goto out_mptfc_probe;
858 }
859
860 spin_lock_init(&ioc->fc_rescan_work_lock);
756 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
757
758 spin_lock_irqsave(&ioc->FreeQlock, flags);
759
760 /* Attach the SCSI Host to the IOC structure
761 */
762 ioc->sh = sh;
763

--- 120 unchanged lines hidden (view full) ---

884 snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
885 sh->host_no);
886 ioc->fc_rescan_work_q =
887 create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
888 if (!ioc->fc_rescan_work_q)
889 goto out_mptfc_probe;
890
891 /*
861 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
862
863 spin_lock_irqsave(&ioc->FreeQlock, flags);
864
865 /* Attach the SCSI Host to the IOC structure
866 */
867 ioc->sh = sh;
868

--- 120 unchanged lines hidden (view full) ---

989 snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
990 sh->host_no);
991 ioc->fc_rescan_work_q =
992 create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
993 if (!ioc->fc_rescan_work_q)
994 goto out_mptfc_probe;
995
996 /*
997 * Pre-fetch FC port WWN and stuff...
998 * (FCPortPage0_t stuff)
999 */
1000 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1001 (void) mptfc_GetFcPortPage0(ioc, ii);
1002 }
1003
1004 /*
892 * scan for rports -
893 * by doing it via the workqueue, some locking is eliminated
894 */
895
896 ioc->fc_rescan_work_count = 1;
897 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
898 flush_workqueue(ioc->fc_rescan_work_q);
899

--- 12 unchanged lines hidden (view full) ---

912 .remove = __devexit_p(mptfc_remove),
913 .shutdown = mptscsih_shutdown,
914#ifdef CONFIG_PM
915 .suspend = mptscsih_suspend,
916 .resume = mptscsih_resume,
917#endif
918};
919
1005 * scan for rports -
1006 * by doing it via the workqueue, some locking is eliminated
1007 */
1008
1009 ioc->fc_rescan_work_count = 1;
1010 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1011 flush_workqueue(ioc->fc_rescan_work_q);
1012

--- 12 unchanged lines hidden (view full) ---

1025 .remove = __devexit_p(mptfc_remove),
1026 .shutdown = mptscsih_shutdown,
1027#ifdef CONFIG_PM
1028 .suspend = mptscsih_suspend,
1029 .resume = mptscsih_resume,
1030#endif
1031};
1032
1033static int
1034mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1035{
1036 MPT_SCSI_HOST *hd;
1037 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1038 unsigned long flags;
1039 int rc=1;
1040
1041 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1042 ioc->name, event));
1043
1044 if (ioc->sh == NULL ||
1045 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
1046 return 1;
1047
1048 switch (event) {
1049 case MPI_EVENT_RESCAN:
1050 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1051 if (ioc->fc_rescan_work_q) {
1052 if (ioc->fc_rescan_work_count++ == 0) {
1053 queue_work(ioc->fc_rescan_work_q,
1054 &ioc->fc_rescan_work);
1055 }
1056 }
1057 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1058 break;
1059 default:
1060 rc = mptscsih_event_process(ioc,pEvReply);
1061 break;
1062 }
1063 return rc;
1064}
1065
1066static int
1067mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1068{
1069 int rc;
1070 unsigned long flags;
1071
1072 rc = mptscsih_ioc_reset(ioc,reset_phase);
1073 if (rc == 0)
1074 return rc;
1075
1076
1077 dtmprintk((KERN_WARNING MYNAM
1078 ": IOC %s_reset routed to FC host driver!\n",
1079 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1080 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1081
1082 if (reset_phase == MPT_IOC_SETUP_RESET) {
1083 }
1084
1085 else if (reset_phase == MPT_IOC_PRE_RESET) {
1086 }
1087
1088 else { /* MPT_IOC_POST_RESET */
1089 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1090 if (ioc->fc_rescan_work_q) {
1091 if (ioc->fc_rescan_work_count++ == 0) {
1092 queue_work(ioc->fc_rescan_work_q,
1093 &ioc->fc_rescan_work);
1094 }
1095 }
1096 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1097 }
1098 return 1;
1099}
1100
920/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
921/**
922 * mptfc_init - Register MPT adapter(s) as SCSI host(s) with
923 * linux scsi mid-layer.
924 *
925 * Returns 0 for success, non-zero for failure.
926 */
927static int __init

--- 12 unchanged lines hidden (view full) ---

940
941 if (!mptfc_transport_template)
942 return -ENODEV;
943
944 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
945 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
946 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
947
1101/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1102/**
1103 * mptfc_init - Register MPT adapter(s) as SCSI host(s) with
1104 * linux scsi mid-layer.
1105 *
1106 * Returns 0 for success, non-zero for failure.
1107 */
1108static int __init

--- 12 unchanged lines hidden (view full) ---

1121
1122 if (!mptfc_transport_template)
1123 return -ENODEV;
1124
1125 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
1126 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
1127 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
1128
948 if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
1129 if (mpt_event_register(mptfcDoneCtx, mptfc_event_process) == 0) {
949 devtverboseprintk((KERN_INFO MYNAM
950 ": Registered for IOC event notifications\n"));
951 }
952
1130 devtverboseprintk((KERN_INFO MYNAM
1131 ": Registered for IOC event notifications\n"));
1132 }
1133
953 if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
1134 if (mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset) == 0) {
954 dprintk((KERN_INFO MYNAM
955 ": Registered for IOC reset notifications\n"));
956 }
957
958 error = pci_register_driver(&mptfc_driver);
959 if (error)
960 fc_release_transport(mptfc_transport_template);
961

--- 62 unchanged lines hidden ---
1135 dprintk((KERN_INFO MYNAM
1136 ": Registered for IOC reset notifications\n"));
1137 }
1138
1139 error = pci_register_driver(&mptfc_driver);
1140 if (error)
1141 fc_release_transport(mptfc_transport_template);
1142

--- 62 unchanged lines hidden ---