diff options
| author | Michael Reed <mdr@sgi.com> | 2006-05-24 16:07:24 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-10 16:59:19 -0400 |
| commit | ca2f938efe71ca48cbc689db4df8d4f04b5d8f07 (patch) | |
| tree | 044df117f00aa7838d83a78aa40ed41c1f0baf31 /drivers/message | |
| parent | 80d3ac77a84987d5132726f3d7cef342a280f7d9 (diff) | |
[SCSI] mptfc: set fibre channel fw target missing timers to one second
The fibre channel firmware provides a timer which is similar in purpose
to the fibre channel transport's device loss timer. The effect of this
timer is to extend the total time that a target will be missing beyond
the value associated with the transport's timer. This patch changes
the firmware timer to a default of one second which significantly reduces
the lag between when a target goes missing and the notification of the
fibre channel transport.
Signed-off-by: Michael Reed <mdr@sgi.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message')
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 10 | ||||
| -rw-r--r-- | drivers/message/fusion/mptfc.c | 171 |
2 files changed, 172 insertions, 9 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 693c95c9034a..29f6b986946f 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
| @@ -487,6 +487,15 @@ typedef struct _RaidCfgData { | |||
| 487 | int isRaid; /* bit field, 1 if RAID */ | 487 | int isRaid; /* bit field, 1 if RAID */ |
| 488 | }RaidCfgData; | 488 | }RaidCfgData; |
| 489 | 489 | ||
| 490 | typedef struct _FcCfgData { | ||
| 491 | /* will ultimately hold fc_port_page0 also */ | ||
| 492 | struct { | ||
| 493 | FCPortPage1_t *data; | ||
| 494 | dma_addr_t dma; | ||
| 495 | int pg_sz; | ||
| 496 | } fc_port_page1[2]; | ||
| 497 | } FcCfgData; | ||
| 498 | |||
| 490 | #define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ | 499 | #define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ |
| 491 | #define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ | 500 | #define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ |
| 492 | 501 | ||
| @@ -565,6 +574,7 @@ typedef struct _MPT_ADAPTER | |||
| 565 | SpiCfgData spi_data; /* Scsi config. data */ | 574 | SpiCfgData spi_data; /* Scsi config. data */ |
| 566 | RaidCfgData raid_data; /* Raid config. data */ | 575 | RaidCfgData raid_data; /* Raid config. data */ |
| 567 | SasCfgData sas_data; /* Sas config. data */ | 576 | SasCfgData sas_data; /* Sas config. data */ |
| 577 | FcCfgData fc_data; /* Fc config. data */ | ||
| 568 | MPT_IOCTL *ioctl; /* ioctl data pointer */ | 578 | MPT_IOCTL *ioctl; /* ioctl data pointer */ |
| 569 | struct proc_dir_entry *ioc_dentry; | 579 | struct proc_dir_entry *ioc_dentry; |
| 570 | struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ | 580 | struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */ |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index e518bc97f8ce..918aca0146ff 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
| @@ -169,13 +169,6 @@ static struct fc_function_template mptfc_transport_functions = { | |||
| 169 | 169 | ||
| 170 | }; | 170 | }; |
| 171 | 171 | ||
| 172 | /* FIXME! values controlling firmware RESCAN event | ||
| 173 | * need to be set low to allow dev_loss_tmo to | ||
| 174 | * work as expected. Currently, firmware doesn't | ||
| 175 | * notify driver of RESCAN event until some number | ||
| 176 | * of seconds elapse. This value can be set via | ||
| 177 | * lsiutil. | ||
| 178 | */ | ||
| 179 | static void | 172 | static void |
| 180 | mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | 173 | mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
| 181 | { | 174 | { |
| @@ -700,6 +693,153 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) | |||
| 700 | return rc; | 693 | return rc; |
| 701 | } | 694 | } |
| 702 | 695 | ||
| 696 | static int | ||
| 697 | mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum) | ||
| 698 | { | ||
| 699 | ConfigPageHeader_t hdr; | ||
| 700 | CONFIGPARMS cfg; | ||
| 701 | int rc; | ||
| 702 | |||
| 703 | if (portnum > 1) | ||
| 704 | return -EINVAL; | ||
| 705 | |||
| 706 | if (!(ioc->fc_data.fc_port_page1[portnum].data)) | ||
| 707 | return -EINVAL; | ||
| 708 | |||
| 709 | /* get fcport page 1 header */ | ||
| 710 | hdr.PageVersion = 0; | ||
| 711 | hdr.PageLength = 0; | ||
| 712 | hdr.PageNumber = 1; | ||
| 713 | hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; | ||
| 714 | cfg.cfghdr.hdr = &hdr; | ||
| 715 | cfg.physAddr = -1; | ||
| 716 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
| 717 | cfg.dir = 0; | ||
| 718 | cfg.pageAddr = portnum; | ||
| 719 | cfg.timeout = 0; | ||
| 720 | |||
| 721 | if ((rc = mpt_config(ioc, &cfg)) != 0) | ||
| 722 | return rc; | ||
| 723 | |||
| 724 | if (hdr.PageLength == 0) | ||
| 725 | return -ENODEV; | ||
| 726 | |||
| 727 | if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz) | ||
| 728 | return -EINVAL; | ||
| 729 | |||
| 730 | cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma; | ||
| 731 | cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
| 732 | cfg.dir = 1; | ||
| 733 | |||
| 734 | rc = mpt_config(ioc, &cfg); | ||
| 735 | |||
| 736 | return rc; | ||
| 737 | } | ||
| 738 | |||
| 739 | static int | ||
| 740 | mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum) | ||
| 741 | { | ||
| 742 | ConfigPageHeader_t hdr; | ||
| 743 | CONFIGPARMS cfg; | ||
| 744 | FCPortPage1_t *page1_alloc; | ||
| 745 | dma_addr_t page1_dma; | ||
| 746 | int data_sz; | ||
| 747 | int rc; | ||
| 748 | |||
| 749 | if (portnum > 1) | ||
| 750 | return -EINVAL; | ||
| 751 | |||
| 752 | /* get fcport page 1 header */ | ||
| 753 | hdr.PageVersion = 0; | ||
| 754 | hdr.PageLength = 0; | ||
| 755 | hdr.PageNumber = 1; | ||
| 756 | hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT; | ||
| 757 | cfg.cfghdr.hdr = &hdr; | ||
| 758 | cfg.physAddr = -1; | ||
| 759 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
| 760 | cfg.dir = 0; | ||
| 761 | cfg.pageAddr = portnum; | ||
| 762 | cfg.timeout = 0; | ||
| 763 | |||
| 764 | if ((rc = mpt_config(ioc, &cfg)) != 0) | ||
| 765 | return rc; | ||
| 766 | |||
| 767 | if (hdr.PageLength == 0) | ||
| 768 | return -ENODEV; | ||
| 769 | |||
| 770 | start_over: | ||
| 771 | |||
| 772 | if (ioc->fc_data.fc_port_page1[portnum].data == NULL) { | ||
| 773 | data_sz = hdr.PageLength * 4; | ||
| 774 | if (data_sz < sizeof(FCPortPage1_t)) | ||
| 775 | data_sz = sizeof(FCPortPage1_t); | ||
| 776 | |||
| 777 | page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev, | ||
| 778 | data_sz, | ||
| 779 | &page1_dma); | ||
| 780 | if (!page1_alloc) | ||
| 781 | return -ENOMEM; | ||
| 782 | } | ||
| 783 | else { | ||
| 784 | page1_alloc = ioc->fc_data.fc_port_page1[portnum].data; | ||
| 785 | page1_dma = ioc->fc_data.fc_port_page1[portnum].dma; | ||
| 786 | data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz; | ||
| 787 | if (hdr.PageLength * 4 > data_sz) { | ||
| 788 | ioc->fc_data.fc_port_page1[portnum].data = NULL; | ||
| 789 | pci_free_consistent(ioc->pcidev, data_sz, (u8 *) | ||
| 790 | page1_alloc, page1_dma); | ||
| 791 | goto start_over; | ||
| 792 | } | ||
| 793 | } | ||
| 794 | |||
| 795 | memset(page1_alloc,0,data_sz); | ||
| 796 | |||
| 797 | cfg.physAddr = page1_dma; | ||
| 798 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
| 799 | |||
| 800 | if ((rc = mpt_config(ioc, &cfg)) == 0) { | ||
| 801 | ioc->fc_data.fc_port_page1[portnum].data = page1_alloc; | ||
| 802 | ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz; | ||
| 803 | ioc->fc_data.fc_port_page1[portnum].dma = page1_dma; | ||
| 804 | } | ||
| 805 | else { | ||
| 806 | ioc->fc_data.fc_port_page1[portnum].data = NULL; | ||
| 807 | pci_free_consistent(ioc->pcidev, data_sz, (u8 *) | ||
| 808 | page1_alloc, page1_dma); | ||
| 809 | } | ||
| 810 | |||
| 811 | return rc; | ||
| 812 | } | ||
| 813 | |||
| 814 | static void | ||
| 815 | mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc) | ||
| 816 | { | ||
| 817 | int ii; | ||
| 818 | FCPortPage1_t *pp1; | ||
| 819 | |||
| 820 | #define MPTFC_FW_DEVICE_TIMEOUT (1) | ||
| 821 | #define MPTFC_FW_IO_PEND_TIMEOUT (1) | ||
| 822 | #define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY) | ||
| 823 | #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS) | ||
| 824 | |||
| 825 | for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) { | ||
| 826 | if (mptfc_GetFcPortPage1(ioc, ii) != 0) | ||
| 827 | continue; | ||
| 828 | pp1 = ioc->fc_data.fc_port_page1[ii].data; | ||
| 829 | if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT) | ||
| 830 | && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT) | ||
| 831 | && ((pp1->Flags & ON_FLAGS) == ON_FLAGS) | ||
| 832 | && ((pp1->Flags & OFF_FLAGS) == 0)) | ||
| 833 | continue; | ||
| 834 | pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT; | ||
| 835 | pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT; | ||
| 836 | pp1->Flags &= ~OFF_FLAGS; | ||
| 837 | pp1->Flags |= ON_FLAGS; | ||
| 838 | mptfc_WriteFcPortPage1(ioc, ii); | ||
| 839 | } | ||
| 840 | } | ||
| 841 | |||
| 842 | |||
| 703 | static void | 843 | static void |
| 704 | mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) | 844 | mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) |
| 705 | { | 845 | { |
| @@ -1000,6 +1140,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1000 | for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { | 1140 | for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { |
| 1001 | (void) mptfc_GetFcPortPage0(ioc, ii); | 1141 | (void) mptfc_GetFcPortPage0(ioc, ii); |
| 1002 | } | 1142 | } |
| 1143 | mptfc_SetFcPortPage1_defaults(ioc); | ||
| 1003 | 1144 | ||
| 1004 | /* | 1145 | /* |
| 1005 | * scan for rports - | 1146 | * scan for rports - |
| @@ -1086,6 +1227,7 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
| 1086 | } | 1227 | } |
| 1087 | 1228 | ||
| 1088 | else { /* MPT_IOC_POST_RESET */ | 1229 | else { /* MPT_IOC_POST_RESET */ |
| 1230 | mptfc_SetFcPortPage1_defaults(ioc); | ||
| 1089 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); | 1231 | spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); |
| 1090 | if (ioc->fc_rescan_work_q) { | 1232 | if (ioc->fc_rescan_work_q) { |
| 1091 | if (ioc->fc_rescan_work_count++ == 0) { | 1233 | if (ioc->fc_rescan_work_count++ == 0) { |
| @@ -1112,8 +1254,8 @@ mptfc_init(void) | |||
| 1112 | 1254 | ||
| 1113 | show_mptmod_ver(my_NAME, my_VERSION); | 1255 | show_mptmod_ver(my_NAME, my_VERSION); |
| 1114 | 1256 | ||
| 1115 | /* sanity check module parameter */ | 1257 | /* sanity check module parameters */ |
| 1116 | if (mptfc_dev_loss_tmo == 0) | 1258 | if (mptfc_dev_loss_tmo <= 0) |
| 1117 | mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; | 1259 | mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; |
| 1118 | 1260 | ||
| 1119 | mptfc_transport_template = | 1261 | mptfc_transport_template = |
| @@ -1156,6 +1298,7 @@ mptfc_remove(struct pci_dev *pdev) | |||
| 1156 | struct mptfc_rport_info *p, *n; | 1298 | struct mptfc_rport_info *p, *n; |
| 1157 | struct workqueue_struct *work_q; | 1299 | struct workqueue_struct *work_q; |
| 1158 | unsigned long flags; | 1300 | unsigned long flags; |
| 1301 | int ii; | ||
| 1159 | 1302 | ||
| 1160 | /* destroy workqueue */ | 1303 | /* destroy workqueue */ |
| 1161 | if ((work_q=ioc->fc_rescan_work_q)) { | 1304 | if ((work_q=ioc->fc_rescan_work_q)) { |
| @@ -1172,6 +1315,16 @@ mptfc_remove(struct pci_dev *pdev) | |||
| 1172 | kfree(p); | 1315 | kfree(p); |
| 1173 | } | 1316 | } |
| 1174 | 1317 | ||
| 1318 | for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) { | ||
| 1319 | if (ioc->fc_data.fc_port_page1[ii].data) { | ||
| 1320 | pci_free_consistent(ioc->pcidev, | ||
| 1321 | ioc->fc_data.fc_port_page1[ii].pg_sz, | ||
| 1322 | (u8 *) ioc->fc_data.fc_port_page1[ii].data, | ||
| 1323 | ioc->fc_data.fc_port_page1[ii].dma); | ||
| 1324 | ioc->fc_data.fc_port_page1[ii].data = NULL; | ||
| 1325 | } | ||
| 1326 | } | ||
| 1327 | |||
| 1175 | mptscsih_remove(pdev); | 1328 | mptscsih_remove(pdev); |
| 1176 | } | 1329 | } |
| 1177 | 1330 | ||
