diff options
author | Wayne Boyer <wayneb@linux.vnet.ibm.com> | 2010-02-19 16:24:26 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-03-03 05:35:03 -0500 |
commit | 214777ba125e2902c9b84c764be38099c94d0bd2 (patch) | |
tree | bc289ce7a58b8a0a67942f5bf35f027771009d89 /drivers/scsi/ipr.c | |
parent | f72919ec2bbbe1c42cdda7857a96c0c40e1d78aa (diff) |
[SCSI] ipr: add support for multiple stages of initialization
This patch adds support for using the new IOA initialization feedback register.
It also enables 64 bit support in the ipr_ioafp_identify_hrrq and
ipr_mask_and_clear_interrupts routines.
Signed-off-by: Wayne Boyer <wayneb@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r-- | drivers/scsi/ipr.c | 185 |
1 files changed, 155 insertions, 30 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index a64fb5085882..10b162d607ac 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -106,13 +106,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
106 | { | 106 | { |
107 | .set_interrupt_mask_reg = 0x0022C, | 107 | .set_interrupt_mask_reg = 0x0022C, |
108 | .clr_interrupt_mask_reg = 0x00230, | 108 | .clr_interrupt_mask_reg = 0x00230, |
109 | .clr_interrupt_mask_reg32 = 0x00230, | ||
109 | .sense_interrupt_mask_reg = 0x0022C, | 110 | .sense_interrupt_mask_reg = 0x0022C, |
111 | .sense_interrupt_mask_reg32 = 0x0022C, | ||
110 | .clr_interrupt_reg = 0x00228, | 112 | .clr_interrupt_reg = 0x00228, |
113 | .clr_interrupt_reg32 = 0x00228, | ||
111 | .sense_interrupt_reg = 0x00224, | 114 | .sense_interrupt_reg = 0x00224, |
115 | .sense_interrupt_reg32 = 0x00224, | ||
112 | .ioarrin_reg = 0x00404, | 116 | .ioarrin_reg = 0x00404, |
113 | .sense_uproc_interrupt_reg = 0x00214, | 117 | .sense_uproc_interrupt_reg = 0x00214, |
118 | .sense_uproc_interrupt_reg32 = 0x00214, | ||
114 | .set_uproc_interrupt_reg = 0x00214, | 119 | .set_uproc_interrupt_reg = 0x00214, |
115 | .clr_uproc_interrupt_reg = 0x00218 | 120 | .set_uproc_interrupt_reg32 = 0x00214, |
121 | .clr_uproc_interrupt_reg = 0x00218, | ||
122 | .clr_uproc_interrupt_reg32 = 0x00218 | ||
116 | } | 123 | } |
117 | }, | 124 | }, |
118 | { /* Snipe and Scamp */ | 125 | { /* Snipe and Scamp */ |
@@ -121,13 +128,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
121 | { | 128 | { |
122 | .set_interrupt_mask_reg = 0x00288, | 129 | .set_interrupt_mask_reg = 0x00288, |
123 | .clr_interrupt_mask_reg = 0x0028C, | 130 | .clr_interrupt_mask_reg = 0x0028C, |
131 | .clr_interrupt_mask_reg32 = 0x0028C, | ||
124 | .sense_interrupt_mask_reg = 0x00288, | 132 | .sense_interrupt_mask_reg = 0x00288, |
133 | .sense_interrupt_mask_reg32 = 0x00288, | ||
125 | .clr_interrupt_reg = 0x00284, | 134 | .clr_interrupt_reg = 0x00284, |
135 | .clr_interrupt_reg32 = 0x00284, | ||
126 | .sense_interrupt_reg = 0x00280, | 136 | .sense_interrupt_reg = 0x00280, |
137 | .sense_interrupt_reg32 = 0x00280, | ||
127 | .ioarrin_reg = 0x00504, | 138 | .ioarrin_reg = 0x00504, |
128 | .sense_uproc_interrupt_reg = 0x00290, | 139 | .sense_uproc_interrupt_reg = 0x00290, |
140 | .sense_uproc_interrupt_reg32 = 0x00290, | ||
129 | .set_uproc_interrupt_reg = 0x00290, | 141 | .set_uproc_interrupt_reg = 0x00290, |
130 | .clr_uproc_interrupt_reg = 0x00294 | 142 | .set_uproc_interrupt_reg32 = 0x00290, |
143 | .clr_uproc_interrupt_reg = 0x00294, | ||
144 | .clr_uproc_interrupt_reg32 = 0x00294 | ||
131 | } | 145 | } |
132 | }, | 146 | }, |
133 | { /* CRoC */ | 147 | { /* CRoC */ |
@@ -136,13 +150,21 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
136 | { | 150 | { |
137 | .set_interrupt_mask_reg = 0x00010, | 151 | .set_interrupt_mask_reg = 0x00010, |
138 | .clr_interrupt_mask_reg = 0x00018, | 152 | .clr_interrupt_mask_reg = 0x00018, |
153 | .clr_interrupt_mask_reg32 = 0x0001C, | ||
139 | .sense_interrupt_mask_reg = 0x00010, | 154 | .sense_interrupt_mask_reg = 0x00010, |
155 | .sense_interrupt_mask_reg32 = 0x00014, | ||
140 | .clr_interrupt_reg = 0x00008, | 156 | .clr_interrupt_reg = 0x00008, |
157 | .clr_interrupt_reg32 = 0x0000C, | ||
141 | .sense_interrupt_reg = 0x00000, | 158 | .sense_interrupt_reg = 0x00000, |
159 | .sense_interrupt_reg32 = 0x00004, | ||
142 | .ioarrin_reg = 0x00070, | 160 | .ioarrin_reg = 0x00070, |
143 | .sense_uproc_interrupt_reg = 0x00020, | 161 | .sense_uproc_interrupt_reg = 0x00020, |
162 | .sense_uproc_interrupt_reg32 = 0x00024, | ||
144 | .set_uproc_interrupt_reg = 0x00020, | 163 | .set_uproc_interrupt_reg = 0x00020, |
164 | .set_uproc_interrupt_reg32 = 0x00024, | ||
145 | .clr_uproc_interrupt_reg = 0x00028, | 165 | .clr_uproc_interrupt_reg = 0x00028, |
166 | .clr_uproc_interrupt_reg32 = 0x0002C, | ||
167 | .init_feedback_reg = 0x0005C, | ||
146 | .dump_addr_reg = 0x00064, | 168 | .dump_addr_reg = 0x00064, |
147 | .dump_data_reg = 0x00068 | 169 | .dump_data_reg = 0x00068 |
148 | } | 170 | } |
@@ -592,10 +614,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg, | |||
592 | ioa_cfg->allow_interrupts = 0; | 614 | ioa_cfg->allow_interrupts = 0; |
593 | 615 | ||
594 | /* Set interrupt mask to stop all new interrupts */ | 616 | /* Set interrupt mask to stop all new interrupts */ |
595 | writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); | 617 | if (ioa_cfg->sis64) |
618 | writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg); | ||
619 | else | ||
620 | writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); | ||
596 | 621 | ||
597 | /* Clear any pending interrupts */ | 622 | /* Clear any pending interrupts */ |
598 | writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg); | 623 | if (ioa_cfg->sis64) |
624 | writel(~0, ioa_cfg->regs.clr_interrupt_reg); | ||
625 | writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32); | ||
599 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); | 626 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
600 | } | 627 | } |
601 | 628 | ||
@@ -2561,7 +2588,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
2561 | 2588 | ||
2562 | /* Write IOA interrupt reg starting LDUMP state */ | 2589 | /* Write IOA interrupt reg starting LDUMP state */ |
2563 | writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), | 2590 | writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), |
2564 | ioa_cfg->regs.set_uproc_interrupt_reg); | 2591 | ioa_cfg->regs.set_uproc_interrupt_reg32); |
2565 | 2592 | ||
2566 | /* Wait for IO debug acknowledge */ | 2593 | /* Wait for IO debug acknowledge */ |
2567 | if (ipr_wait_iodbg_ack(ioa_cfg, | 2594 | if (ipr_wait_iodbg_ack(ioa_cfg, |
@@ -2580,7 +2607,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
2580 | 2607 | ||
2581 | /* Signal address valid - clear IOA Reset alert */ | 2608 | /* Signal address valid - clear IOA Reset alert */ |
2582 | writel(IPR_UPROCI_RESET_ALERT, | 2609 | writel(IPR_UPROCI_RESET_ALERT, |
2583 | ioa_cfg->regs.clr_uproc_interrupt_reg); | 2610 | ioa_cfg->regs.clr_uproc_interrupt_reg32); |
2584 | 2611 | ||
2585 | for (i = 0; i < length_in_words; i++) { | 2612 | for (i = 0; i < length_in_words; i++) { |
2586 | /* Wait for IO debug acknowledge */ | 2613 | /* Wait for IO debug acknowledge */ |
@@ -2605,10 +2632,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
2605 | 2632 | ||
2606 | /* Signal end of block transfer. Set reset alert then clear IO debug ack */ | 2633 | /* Signal end of block transfer. Set reset alert then clear IO debug ack */ |
2607 | writel(IPR_UPROCI_RESET_ALERT, | 2634 | writel(IPR_UPROCI_RESET_ALERT, |
2608 | ioa_cfg->regs.set_uproc_interrupt_reg); | 2635 | ioa_cfg->regs.set_uproc_interrupt_reg32); |
2609 | 2636 | ||
2610 | writel(IPR_UPROCI_IO_DEBUG_ALERT, | 2637 | writel(IPR_UPROCI_IO_DEBUG_ALERT, |
2611 | ioa_cfg->regs.clr_uproc_interrupt_reg); | 2638 | ioa_cfg->regs.clr_uproc_interrupt_reg32); |
2612 | 2639 | ||
2613 | /* Signal dump data received - Clear IO debug Ack */ | 2640 | /* Signal dump data received - Clear IO debug Ack */ |
2614 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, | 2641 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, |
@@ -2617,7 +2644,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
2617 | /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ | 2644 | /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ |
2618 | while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { | 2645 | while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { |
2619 | temp_pcii_reg = | 2646 | temp_pcii_reg = |
2620 | readl(ioa_cfg->regs.sense_uproc_interrupt_reg); | 2647 | readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); |
2621 | 2648 | ||
2622 | if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) | 2649 | if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) |
2623 | return 0; | 2650 | return 0; |
@@ -4831,11 +4858,29 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4831 | return IRQ_NONE; | 4858 | return IRQ_NONE; |
4832 | } | 4859 | } |
4833 | 4860 | ||
4834 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 4861 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); |
4835 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4862 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; |
4836 | 4863 | ||
4837 | /* If an interrupt on the adapter did not occur, ignore it */ | 4864 | /* If an interrupt on the adapter did not occur, ignore it. |
4865 | * Or in the case of SIS 64, check for a stage change interrupt. | ||
4866 | */ | ||
4838 | if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { | 4867 | if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { |
4868 | if (ioa_cfg->sis64) { | ||
4869 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
4870 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4871 | if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { | ||
4872 | |||
4873 | /* clear stage change */ | ||
4874 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); | ||
4875 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4876 | list_del(&ioa_cfg->reset_cmd->queue); | ||
4877 | del_timer(&ioa_cfg->reset_cmd->timer); | ||
4878 | ipr_reset_ioa_job(ioa_cfg->reset_cmd); | ||
4879 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4880 | return IRQ_HANDLED; | ||
4881 | } | ||
4882 | } | ||
4883 | |||
4839 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4884 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
4840 | return IRQ_NONE; | 4885 | return IRQ_NONE; |
4841 | } | 4886 | } |
@@ -4878,8 +4923,8 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4878 | if (ipr_cmd != NULL) { | 4923 | if (ipr_cmd != NULL) { |
4879 | /* Clear the PCI interrupt */ | 4924 | /* Clear the PCI interrupt */ |
4880 | do { | 4925 | do { |
4881 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); | 4926 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); |
4882 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4927 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; |
4883 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && | 4928 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && |
4884 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); | 4929 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); |
4885 | 4930 | ||
@@ -6887,7 +6932,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6887 | } | 6932 | } |
6888 | 6933 | ||
6889 | /** | 6934 | /** |
6890 | * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ. | 6935 | * ipr_ioafp_identify_hrrq - Send Identify Host RRQ. |
6891 | * @ipr_cmd: ipr command struct | 6936 | * @ipr_cmd: ipr command struct |
6892 | * | 6937 | * |
6893 | * This function send an Identify Host Request Response Queue | 6938 | * This function send an Identify Host Request Response Queue |
@@ -6896,7 +6941,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6896 | * Return value: | 6941 | * Return value: |
6897 | * IPR_RC_JOB_RETURN | 6942 | * IPR_RC_JOB_RETURN |
6898 | **/ | 6943 | **/ |
6899 | static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) | 6944 | static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd) |
6900 | { | 6945 | { |
6901 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6946 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6902 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6947 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
@@ -6908,19 +6953,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) | |||
6908 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6953 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
6909 | 6954 | ||
6910 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6955 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
6956 | if (ioa_cfg->sis64) | ||
6957 | ioarcb->cmd_pkt.cdb[1] = 0x1; | ||
6911 | ioarcb->cmd_pkt.cdb[2] = | 6958 | ioarcb->cmd_pkt.cdb[2] = |
6912 | ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff; | 6959 | ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff; |
6913 | ioarcb->cmd_pkt.cdb[3] = | 6960 | ioarcb->cmd_pkt.cdb[3] = |
6914 | ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff; | 6961 | ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff; |
6915 | ioarcb->cmd_pkt.cdb[4] = | 6962 | ioarcb->cmd_pkt.cdb[4] = |
6916 | ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff; | 6963 | ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff; |
6917 | ioarcb->cmd_pkt.cdb[5] = | 6964 | ioarcb->cmd_pkt.cdb[5] = |
6918 | ((u32) ioa_cfg->host_rrq_dma) & 0xff; | 6965 | ((u64) ioa_cfg->host_rrq_dma) & 0xff; |
6919 | ioarcb->cmd_pkt.cdb[7] = | 6966 | ioarcb->cmd_pkt.cdb[7] = |
6920 | ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; | 6967 | ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; |
6921 | ioarcb->cmd_pkt.cdb[8] = | 6968 | ioarcb->cmd_pkt.cdb[8] = |
6922 | (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; | 6969 | (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; |
6923 | 6970 | ||
6971 | if (ioa_cfg->sis64) { | ||
6972 | ioarcb->cmd_pkt.cdb[10] = | ||
6973 | ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff; | ||
6974 | ioarcb->cmd_pkt.cdb[11] = | ||
6975 | ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff; | ||
6976 | ioarcb->cmd_pkt.cdb[12] = | ||
6977 | ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff; | ||
6978 | ioarcb->cmd_pkt.cdb[13] = | ||
6979 | ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff; | ||
6980 | } | ||
6981 | |||
6924 | ipr_cmd->job_step = ipr_ioafp_std_inquiry; | 6982 | ipr_cmd->job_step = ipr_ioafp_std_inquiry; |
6925 | 6983 | ||
6926 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 6984 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
@@ -7005,6 +7063,57 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7005 | } | 7063 | } |
7006 | 7064 | ||
7007 | /** | 7065 | /** |
7066 | * ipr_reset_next_stage - Process IPL stage change based on feedback register. | ||
7067 | * @ipr_cmd: ipr command struct | ||
7068 | * | ||
7069 | * Return value: | ||
7070 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | ||
7071 | **/ | ||
7072 | static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) | ||
7073 | { | ||
7074 | unsigned long stage, stage_time; | ||
7075 | u32 feedback; | ||
7076 | volatile u32 int_reg; | ||
7077 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
7078 | u64 maskval = 0; | ||
7079 | |||
7080 | feedback = readl(ioa_cfg->regs.init_feedback_reg); | ||
7081 | stage = feedback & IPR_IPL_INIT_STAGE_MASK; | ||
7082 | stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK; | ||
7083 | |||
7084 | ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time); | ||
7085 | |||
7086 | /* sanity check the stage_time value */ | ||
7087 | if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) | ||
7088 | stage_time = IPR_IPL_INIT_MIN_STAGE_TIME; | ||
7089 | else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT) | ||
7090 | stage_time = IPR_LONG_OPERATIONAL_TIMEOUT; | ||
7091 | |||
7092 | if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) { | ||
7093 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg); | ||
7094 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
7095 | stage_time = ioa_cfg->transop_timeout; | ||
7096 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; | ||
7097 | } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) { | ||
7098 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; | ||
7099 | maskval = IPR_PCII_IPL_STAGE_CHANGE; | ||
7100 | maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER; | ||
7101 | writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg); | ||
7102 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
7103 | return IPR_RC_JOB_CONTINUE; | ||
7104 | } | ||
7105 | |||
7106 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; | ||
7107 | ipr_cmd->timer.expires = jiffies + stage_time * HZ; | ||
7108 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; | ||
7109 | ipr_cmd->done = ipr_reset_ioa_job; | ||
7110 | add_timer(&ipr_cmd->timer); | ||
7111 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); | ||
7112 | |||
7113 | return IPR_RC_JOB_RETURN; | ||
7114 | } | ||
7115 | |||
7116 | /** | ||
7008 | * ipr_reset_enable_ioa - Enable the IOA following a reset. | 7117 | * ipr_reset_enable_ioa - Enable the IOA following a reset. |
7009 | * @ipr_cmd: ipr command struct | 7118 | * @ipr_cmd: ipr command struct |
7010 | * | 7119 | * |
@@ -7020,7 +7129,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) | |||
7020 | volatile u32 int_reg; | 7129 | volatile u32 int_reg; |
7021 | 7130 | ||
7022 | ENTER; | 7131 | ENTER; |
7023 | ipr_cmd->job_step = ipr_ioafp_indentify_hrrq; | 7132 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; |
7024 | ipr_init_ioa_mem(ioa_cfg); | 7133 | ipr_init_ioa_mem(ioa_cfg); |
7025 | 7134 | ||
7026 | ioa_cfg->allow_interrupts = 1; | 7135 | ioa_cfg->allow_interrupts = 1; |
@@ -7028,19 +7137,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) | |||
7028 | 7137 | ||
7029 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { | 7138 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { |
7030 | writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), | 7139 | writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), |
7031 | ioa_cfg->regs.clr_interrupt_mask_reg); | 7140 | ioa_cfg->regs.clr_interrupt_mask_reg32); |
7032 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 7141 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
7033 | return IPR_RC_JOB_CONTINUE; | 7142 | return IPR_RC_JOB_CONTINUE; |
7034 | } | 7143 | } |
7035 | 7144 | ||
7036 | /* Enable destructive diagnostics on IOA */ | 7145 | /* Enable destructive diagnostics on IOA */ |
7037 | writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg); | 7146 | writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32); |
7147 | |||
7148 | writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); | ||
7149 | if (ioa_cfg->sis64) | ||
7150 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg); | ||
7038 | 7151 | ||
7039 | writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg); | ||
7040 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 7152 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
7041 | 7153 | ||
7042 | dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); | 7154 | dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); |
7043 | 7155 | ||
7156 | if (ioa_cfg->sis64) { | ||
7157 | ipr_cmd->job_step = ipr_reset_next_stage; | ||
7158 | return IPR_RC_JOB_CONTINUE; | ||
7159 | } | ||
7160 | |||
7044 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; | 7161 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; |
7045 | ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); | 7162 | ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); |
7046 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; | 7163 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; |
@@ -7374,7 +7491,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) | |||
7374 | 7491 | ||
7375 | if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { | 7492 | if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { |
7376 | ipr_mask_and_clear_interrupts(ioa_cfg, ~0); | 7493 | ipr_mask_and_clear_interrupts(ioa_cfg, ~0); |
7377 | writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg); | 7494 | writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32); |
7378 | ipr_cmd->job_step = ipr_reset_wait_to_start_bist; | 7495 | ipr_cmd->job_step = ipr_reset_wait_to_start_bist; |
7379 | } else { | 7496 | } else { |
7380 | ipr_cmd->job_step = ioa_cfg->reset; | 7497 | ipr_cmd->job_step = ioa_cfg->reset; |
@@ -8104,15 +8221,23 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, | |||
8104 | 8221 | ||
8105 | t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; | 8222 | t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; |
8106 | t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; | 8223 | t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; |
8224 | t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32; | ||
8107 | t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; | 8225 | t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; |
8226 | t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32; | ||
8108 | t->clr_interrupt_reg = base + p->clr_interrupt_reg; | 8227 | t->clr_interrupt_reg = base + p->clr_interrupt_reg; |
8228 | t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32; | ||
8109 | t->sense_interrupt_reg = base + p->sense_interrupt_reg; | 8229 | t->sense_interrupt_reg = base + p->sense_interrupt_reg; |
8230 | t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32; | ||
8110 | t->ioarrin_reg = base + p->ioarrin_reg; | 8231 | t->ioarrin_reg = base + p->ioarrin_reg; |
8111 | t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; | 8232 | t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; |
8233 | t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32; | ||
8112 | t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; | 8234 | t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; |
8235 | t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32; | ||
8113 | t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; | 8236 | t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; |
8237 | t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32; | ||
8114 | 8238 | ||
8115 | if (ioa_cfg->sis64) { | 8239 | if (ioa_cfg->sis64) { |
8240 | t->init_feedback_reg = base + p->init_feedback_reg; | ||
8116 | t->dump_addr_reg = base + p->dump_addr_reg; | 8241 | t->dump_addr_reg = base + p->dump_addr_reg; |
8117 | t->dump_data_reg = base + p->dump_data_reg; | 8242 | t->dump_data_reg = base + p->dump_data_reg; |
8118 | } | 8243 | } |
@@ -8187,7 +8312,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, | |||
8187 | init_waitqueue_head(&ioa_cfg->msi_wait_q); | 8312 | init_waitqueue_head(&ioa_cfg->msi_wait_q); |
8188 | ioa_cfg->msi_received = 0; | 8313 | ioa_cfg->msi_received = 0; |
8189 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | 8314 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); |
8190 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg); | 8315 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32); |
8191 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 8316 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
8192 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 8317 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
8193 | 8318 | ||
@@ -8198,7 +8323,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, | |||
8198 | } else if (ipr_debug) | 8323 | } else if (ipr_debug) |
8199 | dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); | 8324 | dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); |
8200 | 8325 | ||
8201 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg); | 8326 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32); |
8202 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); | 8327 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
8203 | wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); | 8328 | wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); |
8204 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | 8329 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); |
@@ -8378,9 +8503,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
8378 | * If HRRQ updated interrupt is not masked, or reset alert is set, | 8503 | * If HRRQ updated interrupt is not masked, or reset alert is set, |
8379 | * the card is in an unknown state and needs a hard reset | 8504 | * the card is in an unknown state and needs a hard reset |
8380 | */ | 8505 | */ |
8381 | mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 8506 | mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); |
8382 | interrupts = readl(ioa_cfg->regs.sense_interrupt_reg); | 8507 | interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32); |
8383 | uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); | 8508 | uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); |
8384 | if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) | 8509 | if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) |
8385 | ioa_cfg->needs_hard_reset = 1; | 8510 | ioa_cfg->needs_hard_reset = 1; |
8386 | if (interrupts & IPR_PCII_ERROR_INTERRUPTS) | 8511 | if (interrupts & IPR_PCII_ERROR_INTERRUPTS) |