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 --- |