diff options
-rw-r--r-- | drivers/scsi/qla2xxx/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 97 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 133 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 37 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dfs.c | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 256 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 26 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 47 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 124 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 65 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_tmpl.c | 909 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_tmpl.h | 205 |
20 files changed, 1812 insertions, 136 deletions
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index ff0fc7c7812f..44def6bb4bb0 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ | 1 | qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ |
2 | qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ | 2 | qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ |
3 | qla_nx.o qla_mr.o qla_nx2.o qla_target.o | 3 | qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o |
4 | 4 | ||
5 | obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o | 5 | obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o |
6 | obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o | 6 | obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index c2144412859b..f2d42b961e92 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -147,6 +147,92 @@ static struct bin_attribute sysfs_fw_dump_attr = { | |||
147 | }; | 147 | }; |
148 | 148 | ||
149 | static ssize_t | 149 | static ssize_t |
150 | qla2x00_sysfs_read_fw_dump_template(struct file *filp, struct kobject *kobj, | ||
151 | struct bin_attribute *bin_attr, | ||
152 | char *buf, loff_t off, size_t count) | ||
153 | { | ||
154 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | ||
155 | struct device, kobj))); | ||
156 | struct qla_hw_data *ha = vha->hw; | ||
157 | |||
158 | if (!ha->fw_dump_template || !ha->fw_dump_template_len) | ||
159 | return 0; | ||
160 | |||
161 | ql_dbg(ql_dbg_user, vha, 0x70e2, | ||
162 | "chunk <- off=%llx count=%lx\n", off, count); | ||
163 | return memory_read_from_buffer(buf, count, &off, | ||
164 | ha->fw_dump_template, ha->fw_dump_template_len); | ||
165 | } | ||
166 | |||
167 | static ssize_t | ||
168 | qla2x00_sysfs_write_fw_dump_template(struct file *filp, struct kobject *kobj, | ||
169 | struct bin_attribute *bin_attr, | ||
170 | char *buf, loff_t off, size_t count) | ||
171 | { | ||
172 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | ||
173 | struct device, kobj))); | ||
174 | struct qla_hw_data *ha = vha->hw; | ||
175 | uint32_t size; | ||
176 | |||
177 | if (off == 0) { | ||
178 | if (ha->fw_dump) | ||
179 | vfree(ha->fw_dump); | ||
180 | if (ha->fw_dump_template) | ||
181 | vfree(ha->fw_dump_template); | ||
182 | |||
183 | ha->fw_dump = NULL; | ||
184 | ha->fw_dump_len = 0; | ||
185 | ha->fw_dump_template = NULL; | ||
186 | ha->fw_dump_template_len = 0; | ||
187 | |||
188 | size = qla27xx_fwdt_template_size(buf); | ||
189 | ql_dbg(ql_dbg_user, vha, 0x70d1, | ||
190 | "-> allocating fwdt (%x bytes)...\n", size); | ||
191 | ha->fw_dump_template = vmalloc(size); | ||
192 | if (!ha->fw_dump_template) { | ||
193 | ql_log(ql_log_warn, vha, 0x70d2, | ||
194 | "Failed allocate fwdt (%x bytes).\n", size); | ||
195 | return -ENOMEM; | ||
196 | } | ||
197 | ha->fw_dump_template_len = size; | ||
198 | } | ||
199 | |||
200 | if (off + count > ha->fw_dump_template_len) { | ||
201 | count = ha->fw_dump_template_len - off; | ||
202 | ql_dbg(ql_dbg_user, vha, 0x70d3, | ||
203 | "chunk -> truncating to %lx bytes.\n", count); | ||
204 | } | ||
205 | |||
206 | ql_dbg(ql_dbg_user, vha, 0x70d4, | ||
207 | "chunk -> off=%llx count=%lx\n", off, count); | ||
208 | memcpy(ha->fw_dump_template + off, buf, count); | ||
209 | |||
210 | if (off + count == ha->fw_dump_template_len) { | ||
211 | size = qla27xx_fwdt_calculate_dump_size(vha); | ||
212 | ql_dbg(ql_dbg_user, vha, 0x70d5, | ||
213 | "-> allocating fwdump (%x bytes)...\n", size); | ||
214 | ha->fw_dump = vmalloc(size); | ||
215 | if (!ha->fw_dump) { | ||
216 | ql_log(ql_log_warn, vha, 0x70d6, | ||
217 | "Failed allocate fwdump (%x bytes).\n", size); | ||
218 | return -ENOMEM; | ||
219 | } | ||
220 | ha->fw_dump_len = size; | ||
221 | } | ||
222 | |||
223 | return count; | ||
224 | } | ||
225 | static struct bin_attribute sysfs_fw_dump_template_attr = { | ||
226 | .attr = { | ||
227 | .name = "fw_dump_template", | ||
228 | .mode = S_IRUSR | S_IWUSR, | ||
229 | }, | ||
230 | .size = 0, | ||
231 | .read = qla2x00_sysfs_read_fw_dump_template, | ||
232 | .write = qla2x00_sysfs_write_fw_dump_template, | ||
233 | }; | ||
234 | |||
235 | static ssize_t | ||
150 | qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, | 236 | qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, |
151 | struct bin_attribute *bin_attr, | 237 | struct bin_attribute *bin_attr, |
152 | char *buf, loff_t off, size_t count) | 238 | char *buf, loff_t off, size_t count) |
@@ -845,6 +931,7 @@ static struct sysfs_entry { | |||
845 | int is4GBp_only; | 931 | int is4GBp_only; |
846 | } bin_file_entries[] = { | 932 | } bin_file_entries[] = { |
847 | { "fw_dump", &sysfs_fw_dump_attr, }, | 933 | { "fw_dump", &sysfs_fw_dump_attr, }, |
934 | { "fw_dump_template", &sysfs_fw_dump_template_attr, 0x27 }, | ||
848 | { "nvram", &sysfs_nvram_attr, }, | 935 | { "nvram", &sysfs_nvram_attr, }, |
849 | { "optrom", &sysfs_optrom_attr, }, | 936 | { "optrom", &sysfs_optrom_attr, }, |
850 | { "optrom_ctl", &sysfs_optrom_ctl_attr, }, | 937 | { "optrom_ctl", &sysfs_optrom_ctl_attr, }, |
@@ -870,6 +957,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) | |||
870 | continue; | 957 | continue; |
871 | if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) | 958 | if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
872 | continue; | 959 | continue; |
960 | if (iter->is4GBp_only == 0x27 && !IS_QLA27XX(vha->hw)) | ||
961 | continue; | ||
873 | 962 | ||
874 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, | 963 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
875 | iter->attr); | 964 | iter->attr); |
@@ -1210,7 +1299,7 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev, | |||
1210 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1299 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1211 | struct qla_hw_data *ha = vha->hw; | 1300 | struct qla_hw_data *ha = vha->hw; |
1212 | 1301 | ||
1213 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) | 1302 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha)) |
1214 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1303 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1215 | 1304 | ||
1216 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", | 1305 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", |
@@ -1532,6 +1621,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
1532 | case PORT_SPEED_16GB: | 1621 | case PORT_SPEED_16GB: |
1533 | speed = FC_PORTSPEED_16GBIT; | 1622 | speed = FC_PORTSPEED_16GBIT; |
1534 | break; | 1623 | break; |
1624 | case PORT_SPEED_32GB: | ||
1625 | speed = FC_PORTSPEED_32GBIT; | ||
1626 | break; | ||
1535 | } | 1627 | } |
1536 | fc_host_speed(shost) = speed; | 1628 | fc_host_speed(shost) = speed; |
1537 | } | 1629 | } |
@@ -2183,6 +2275,9 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) | |||
2183 | else if (IS_QLAFX00(ha)) | 2275 | else if (IS_QLAFX00(ha)) |
2184 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | 2276 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | |
2185 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | 2277 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; |
2278 | else if (IS_QLA27XX(ha)) | ||
2279 | speed = FC_PORTSPEED_32GBIT | FC_PORTSPEED_16GBIT | | ||
2280 | FC_PORTSPEED_8GBIT; | ||
2186 | else | 2281 | else |
2187 | speed = FC_PORTSPEED_1GBIT; | 2282 | speed = FC_PORTSPEED_1GBIT; |
2188 | fc_host_supported_speeds(vha->host) = speed; | 2283 | fc_host_supported_speeds(vha->host) = speed; |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index f6103f553bb1..c68b60051dfb 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -11,13 +11,15 @@ | |||
11 | * ---------------------------------------------------------------------- | 11 | * ---------------------------------------------------------------------- |
12 | * | Level | Last Value Used | Holes | | 12 | * | Level | Last Value Used | Holes | |
13 | * ---------------------------------------------------------------------- | 13 | * ---------------------------------------------------------------------- |
14 | * | Module Init and Probe | 0x015b | 0x4b,0xba,0xfa | | 14 | * | Module Init and Probe | 0x017d | 0x004b,0x0141 | |
15 | * | | | 0x0x015a | | 15 | * | | | 0x0144,0x0146 | |
16 | * | Mailbox commands | 0x1187 | 0x111a-0x111b | | 16 | * | | | 0x015b-0x0160 | |
17 | * | | | 0x1155-0x1158 | | 17 | * | | | 0x016e-0x0170 | |
18 | * | | | 0x1018-0x1019 | | 18 | * | Mailbox commands | 0x1187 | 0x1018-0x1019 | |
19 | * | | | 0x10ca | | ||
19 | * | | | 0x1115-0x1116 | | 20 | * | | | 0x1115-0x1116 | |
20 | * | | | 0x10ca | | 21 | * | | | 0x111a-0x111b | |
22 | * | | | 0x1155-0x1158 | | ||
21 | * | Device Discovery | 0x2095 | 0x2020-0x2022, | | 23 | * | Device Discovery | 0x2095 | 0x2020-0x2022, | |
22 | * | | | 0x2011-0x2012, | | 24 | * | | | 0x2011-0x2012, | |
23 | * | | | 0x2016 | | 25 | * | | | 0x2016 | |
@@ -33,17 +35,15 @@ | |||
33 | * | | | 0x5084,0x5075 | | 35 | * | | | 0x5084,0x5075 | |
34 | * | | | 0x503d,0x5044 | | 36 | * | | | 0x503d,0x5044 | |
35 | * | Timer Routines | 0x6012 | | | 37 | * | Timer Routines | 0x6012 | | |
36 | * | User Space Interactions | 0x70e1 | 0x7018,0x702e, | | 38 | * | User Space Interactions | 0x70e2 | 0x7018,0x702e | |
37 | * | | | 0x7020,0x7024, | | 39 | * | | | 0x7020,0x7024 | |
38 | * | | | 0x7039,0x7045, | | 40 | * | | | 0x7039,0x7045 | |
39 | * | | | 0x7073-0x7075, | | 41 | * | | | 0x7073-0x7075 | |
40 | * | | | 0x707b,0x708c, | | 42 | * | | | 0x70a5-0x70a6 | |
41 | * | | | 0x70a5,0x70a6, | | 43 | * | | | 0x70a8,0x70ab | |
42 | * | | | 0x70a8,0x70ab, | | 44 | * | | | 0x70ad-0x70ae | |
43 | * | | | 0x70ad-0x70ae, | | 45 | * | | | 0x70d7-0x70db | |
44 | * | | | 0x70d1-0x70db, | | 46 | * | | | 0x70de-0x70df | |
45 | * | | | 0x7047,0x703b | | ||
46 | * | | | 0x70de-0x70df, | | ||
47 | * | Task Management | 0x803d | 0x8025-0x8026 | | 47 | * | Task Management | 0x803d | 0x8025-0x8026 | |
48 | * | | | 0x800b,0x8039 | | 48 | * | | | 0x800b,0x8039 | |
49 | * | AER/EEH | 0x9011 | | | 49 | * | AER/EEH | 0x9011 | | |
@@ -59,7 +59,11 @@ | |||
59 | * | | | 0xb13c-0xb140 | | 59 | * | | | 0xb13c-0xb140 | |
60 | * | | | 0xb149 | | 60 | * | | | 0xb149 | |
61 | * | MultiQ | 0xc00c | | | 61 | * | MultiQ | 0xc00c | | |
62 | * | Misc | 0xd010 | | | 62 | * | Misc | 0xd2ff | 0xd017-0xd019 | |
63 | * | | | 0xd020 | | ||
64 | * | | | 0xd02e-0xd0ff | | ||
65 | * | | | 0xd101-0xd1fe | | ||
66 | * | | | 0xd212-0xd2fe | | ||
63 | * | Target Mode | 0xe070 | 0xe021 | | 67 | * | Target Mode | 0xe070 | 0xe021 | |
64 | * | Target Mode Management | 0xf072 | 0xf002-0xf003 | | 68 | * | Target Mode Management | 0xf072 | 0xf002-0xf003 | |
65 | * | | | 0xf046-0xf049 | | 69 | * | | | 0xf046-0xf049 | |
@@ -104,7 +108,87 @@ qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr) | |||
104 | return ptr + (rsp->length * sizeof(response_t)); | 108 | return ptr + (rsp->length * sizeof(response_t)); |
105 | } | 109 | } |
106 | 110 | ||
107 | static int | 111 | int |
112 | qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | ||
113 | uint32_t ram_dwords, void **nxt) | ||
114 | { | ||
115 | int rval; | ||
116 | uint32_t cnt, stat, timer, dwords, idx; | ||
117 | uint16_t mb0, mb1; | ||
118 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
119 | dma_addr_t dump_dma = ha->gid_list_dma; | ||
120 | uint32_t *dump = (uint32_t *)ha->gid_list; | ||
121 | |||
122 | rval = QLA_SUCCESS; | ||
123 | mb0 = 0; | ||
124 | |||
125 | WRT_REG_WORD(®->mailbox0, MBC_LOAD_DUMP_MPI_RAM); | ||
126 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
127 | |||
128 | dwords = qla2x00_gid_list_size(ha) / 4; | ||
129 | for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS; | ||
130 | cnt += dwords, addr += dwords) { | ||
131 | if (cnt + dwords > ram_dwords) | ||
132 | dwords = ram_dwords - cnt; | ||
133 | |||
134 | WRT_REG_WORD(®->mailbox1, LSW(addr)); | ||
135 | WRT_REG_WORD(®->mailbox8, MSW(addr)); | ||
136 | |||
137 | WRT_REG_WORD(®->mailbox2, MSW(dump_dma)); | ||
138 | WRT_REG_WORD(®->mailbox3, LSW(dump_dma)); | ||
139 | WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); | ||
140 | WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); | ||
141 | |||
142 | WRT_REG_WORD(®->mailbox4, MSW(dwords)); | ||
143 | WRT_REG_WORD(®->mailbox5, LSW(dwords)); | ||
144 | |||
145 | WRT_REG_WORD(®->mailbox9, 0); | ||
146 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | ||
147 | |||
148 | ha->flags.mbox_int = 0; | ||
149 | for (timer = 6000000; timer; timer--) { | ||
150 | /* Check for pending interrupts. */ | ||
151 | stat = RD_REG_DWORD(®->host_status); | ||
152 | if (stat & HSRX_RISC_INT) { | ||
153 | stat &= 0xff; | ||
154 | |||
155 | if (stat == 0x1 || stat == 0x2 || | ||
156 | stat == 0x10 || stat == 0x11) { | ||
157 | set_bit(MBX_INTERRUPT, | ||
158 | &ha->mbx_cmd_flags); | ||
159 | |||
160 | mb0 = RD_REG_WORD(®->mailbox0); | ||
161 | mb1 = RD_REG_WORD(®->mailbox1); | ||
162 | |||
163 | WRT_REG_DWORD(®->hccr, | ||
164 | HCCRX_CLR_RISC_INT); | ||
165 | RD_REG_DWORD(®->hccr); | ||
166 | break; | ||
167 | } | ||
168 | |||
169 | /* Clear this intr; it wasn't a mailbox intr */ | ||
170 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
171 | RD_REG_DWORD(®->hccr); | ||
172 | } | ||
173 | udelay(5); | ||
174 | } | ||
175 | ha->flags.mbox_int = 1; | ||
176 | |||
177 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | ||
178 | rval = mb0 & MBS_MASK; | ||
179 | for (idx = 0; idx < dwords; idx++) | ||
180 | ram[cnt + idx] = IS_QLA27XX(ha) ? | ||
181 | le32_to_cpu(dump[idx]) : swab32(dump[idx]); | ||
182 | } else { | ||
183 | rval = QLA_FUNCTION_FAILED; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL; | ||
188 | return rval; | ||
189 | } | ||
190 | |||
191 | int | ||
108 | qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | 192 | qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, |
109 | uint32_t ram_dwords, void **nxt) | 193 | uint32_t ram_dwords, void **nxt) |
110 | { | 194 | { |
@@ -139,6 +223,7 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | |||
139 | WRT_REG_WORD(®->mailbox5, LSW(dwords)); | 223 | WRT_REG_WORD(®->mailbox5, LSW(dwords)); |
140 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | 224 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); |
141 | 225 | ||
226 | ha->flags.mbox_int = 0; | ||
142 | for (timer = 6000000; timer; timer--) { | 227 | for (timer = 6000000; timer; timer--) { |
143 | /* Check for pending interrupts. */ | 228 | /* Check for pending interrupts. */ |
144 | stat = RD_REG_DWORD(®->host_status); | 229 | stat = RD_REG_DWORD(®->host_status); |
@@ -164,11 +249,13 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | |||
164 | } | 249 | } |
165 | udelay(5); | 250 | udelay(5); |
166 | } | 251 | } |
252 | ha->flags.mbox_int = 1; | ||
167 | 253 | ||
168 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 254 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
169 | rval = mb0 & MBS_MASK; | 255 | rval = mb0 & MBS_MASK; |
170 | for (idx = 0; idx < dwords; idx++) | 256 | for (idx = 0; idx < dwords; idx++) |
171 | ram[cnt + idx] = swab32(dump[idx]); | 257 | ram[cnt + idx] = IS_QLA27XX(ha) ? |
258 | le32_to_cpu(dump[idx]) : swab32(dump[idx]); | ||
172 | } else { | 259 | } else { |
173 | rval = QLA_FUNCTION_FAILED; | 260 | rval = QLA_FUNCTION_FAILED; |
174 | } | 261 | } |
@@ -208,7 +295,7 @@ qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, | |||
208 | return buf; | 295 | return buf; |
209 | } | 296 | } |
210 | 297 | ||
211 | static inline int | 298 | int |
212 | qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) | 299 | qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) |
213 | { | 300 | { |
214 | int rval = QLA_SUCCESS; | 301 | int rval = QLA_SUCCESS; |
@@ -227,7 +314,7 @@ qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) | |||
227 | return rval; | 314 | return rval; |
228 | } | 315 | } |
229 | 316 | ||
230 | static int | 317 | int |
231 | qla24xx_soft_reset(struct qla_hw_data *ha) | 318 | qla24xx_soft_reset(struct qla_hw_data *ha) |
232 | { | 319 | { |
233 | int rval = QLA_SUCCESS; | 320 | int rval = QLA_SUCCESS; |
@@ -537,7 +624,7 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | |||
537 | struct qla2xxx_mq_chain *mq = ptr; | 624 | struct qla2xxx_mq_chain *mq = ptr; |
538 | device_reg_t __iomem *reg; | 625 | device_reg_t __iomem *reg; |
539 | 626 | ||
540 | if (!ha->mqenable || IS_QLA83XX(ha)) | 627 | if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
541 | return ptr; | 628 | return ptr; |
542 | 629 | ||
543 | mq = ptr; | 630 | mq = ptr; |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 35e20b4f8b6c..cc961040f8b1 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -348,3 +348,10 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); | |||
348 | #define ql_dbg_tgt 0x00004000 /* Target mode */ | 348 | #define ql_dbg_tgt 0x00004000 /* Target mode */ |
349 | #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ | 349 | #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ |
350 | #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ | 350 | #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ |
351 | |||
352 | extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, | ||
353 | uint32_t, void **); | ||
354 | extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *, | ||
355 | uint32_t, void **); | ||
356 | extern int qla24xx_pause_risc(struct device_reg_24xx __iomem *); | ||
357 | extern int qla24xx_soft_reset(struct qla_hw_data *); | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 638bdcca4552..400ef02e1610 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -654,7 +654,7 @@ typedef union { | |||
654 | struct device_reg_25xxmq isp25mq; | 654 | struct device_reg_25xxmq isp25mq; |
655 | struct device_reg_82xx isp82; | 655 | struct device_reg_82xx isp82; |
656 | struct device_reg_fx00 ispfx00; | 656 | struct device_reg_fx00 ispfx00; |
657 | } device_reg_t; | 657 | } __iomem device_reg_t; |
658 | 658 | ||
659 | #define ISP_REQ_Q_IN(ha, reg) \ | 659 | #define ISP_REQ_Q_IN(ha, reg) \ |
660 | (IS_QLA2100(ha) || IS_QLA2200(ha) ? \ | 660 | (IS_QLA2100(ha) || IS_QLA2200(ha) ? \ |
@@ -938,6 +938,7 @@ struct mbx_cmd_32 { | |||
938 | */ | 938 | */ |
939 | #define MBC_WRITE_SERDES 0x3 /* Write serdes word. */ | 939 | #define MBC_WRITE_SERDES 0x3 /* Write serdes word. */ |
940 | #define MBC_READ_SERDES 0x4 /* Read serdes word. */ | 940 | #define MBC_READ_SERDES 0x4 /* Read serdes word. */ |
941 | #define MBC_LOAD_DUMP_MPI_RAM 0x5 /* Load/Dump MPI RAM. */ | ||
941 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ | 942 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ |
942 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ | 943 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ |
943 | #define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */ | 944 | #define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */ |
@@ -2148,6 +2149,7 @@ struct ct_fdmi_hba_attributes { | |||
2148 | #define FDMI_PORT_SPEED_4GB 0x8 | 2149 | #define FDMI_PORT_SPEED_4GB 0x8 |
2149 | #define FDMI_PORT_SPEED_8GB 0x10 | 2150 | #define FDMI_PORT_SPEED_8GB 0x10 |
2150 | #define FDMI_PORT_SPEED_16GB 0x20 | 2151 | #define FDMI_PORT_SPEED_16GB 0x20 |
2152 | #define FDMI_PORT_SPEED_32GB 0x40 | ||
2151 | #define FDMI_PORT_SPEED_UNKNOWN 0x8000 | 2153 | #define FDMI_PORT_SPEED_UNKNOWN 0x8000 |
2152 | 2154 | ||
2153 | struct ct_fdmi_port_attr { | 2155 | struct ct_fdmi_port_attr { |
@@ -2656,7 +2658,7 @@ struct bidi_statistics { | |||
2656 | #define QLA_MQ_SIZE 32 | 2658 | #define QLA_MQ_SIZE 32 |
2657 | #define QLA_MAX_QUEUES 256 | 2659 | #define QLA_MAX_QUEUES 256 |
2658 | #define ISP_QUE_REG(ha, id) \ | 2660 | #define ISP_QUE_REG(ha, id) \ |
2659 | ((ha->mqenable || IS_QLA83XX(ha)) ? \ | 2661 | ((ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) ? \ |
2660 | ((void __iomem *)ha->mqiobase + (QLA_QUE_PAGE * id)) :\ | 2662 | ((void __iomem *)ha->mqiobase + (QLA_QUE_PAGE * id)) :\ |
2661 | ((void __iomem *)ha->iobase)) | 2663 | ((void __iomem *)ha->iobase)) |
2662 | #define QLA_REQ_QUE_ID(tag) \ | 2664 | #define QLA_REQ_QUE_ID(tag) \ |
@@ -2794,7 +2796,6 @@ struct qla_hw_data { | |||
2794 | uint32_t fac_supported :1; | 2796 | uint32_t fac_supported :1; |
2795 | 2797 | ||
2796 | uint32_t chip_reset_done :1; | 2798 | uint32_t chip_reset_done :1; |
2797 | uint32_t port0 :1; | ||
2798 | uint32_t running_gold_fw :1; | 2799 | uint32_t running_gold_fw :1; |
2799 | uint32_t eeh_busy :1; | 2800 | uint32_t eeh_busy :1; |
2800 | uint32_t cpu_affinity_enabled :1; | 2801 | uint32_t cpu_affinity_enabled :1; |
@@ -2825,7 +2826,7 @@ struct qla_hw_data { | |||
2825 | spinlock_t hardware_lock ____cacheline_aligned; | 2826 | spinlock_t hardware_lock ____cacheline_aligned; |
2826 | int bars; | 2827 | int bars; |
2827 | int mem_only; | 2828 | int mem_only; |
2828 | device_reg_t __iomem *iobase; /* Base I/O address */ | 2829 | device_reg_t *iobase; /* Base I/O address */ |
2829 | resource_size_t pio_address; | 2830 | resource_size_t pio_address; |
2830 | 2831 | ||
2831 | #define MIN_IOBASE_LEN 0x100 | 2832 | #define MIN_IOBASE_LEN 0x100 |
@@ -2844,8 +2845,8 @@ struct qla_hw_data { | |||
2844 | uint32_t rsp_que_off; | 2845 | uint32_t rsp_que_off; |
2845 | 2846 | ||
2846 | /* Multi queue data structs */ | 2847 | /* Multi queue data structs */ |
2847 | device_reg_t __iomem *mqiobase; | 2848 | device_reg_t *mqiobase; |
2848 | device_reg_t __iomem *msixbase; | 2849 | device_reg_t *msixbase; |
2849 | uint16_t msix_count; | 2850 | uint16_t msix_count; |
2850 | uint8_t mqenable; | 2851 | uint8_t mqenable; |
2851 | struct req_que **req_q_map; | 2852 | struct req_que **req_q_map; |
@@ -2881,6 +2882,7 @@ struct qla_hw_data { | |||
2881 | #define PORT_SPEED_4GB 0x03 | 2882 | #define PORT_SPEED_4GB 0x03 |
2882 | #define PORT_SPEED_8GB 0x04 | 2883 | #define PORT_SPEED_8GB 0x04 |
2883 | #define PORT_SPEED_16GB 0x05 | 2884 | #define PORT_SPEED_16GB 0x05 |
2885 | #define PORT_SPEED_32GB 0x06 | ||
2884 | #define PORT_SPEED_10GB 0x13 | 2886 | #define PORT_SPEED_10GB 0x13 |
2885 | uint16_t link_data_rate; /* F/W operating speed */ | 2887 | uint16_t link_data_rate; /* F/W operating speed */ |
2886 | 2888 | ||
@@ -2904,6 +2906,7 @@ struct qla_hw_data { | |||
2904 | #define PCI_DEVICE_ID_QLOGIC_ISP8001 0x8001 | 2906 | #define PCI_DEVICE_ID_QLOGIC_ISP8001 0x8001 |
2905 | #define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031 | 2907 | #define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031 |
2906 | #define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031 | 2908 | #define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031 |
2909 | #define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071 | ||
2907 | uint32_t device_type; | 2910 | uint32_t device_type; |
2908 | #define DT_ISP2100 BIT_0 | 2911 | #define DT_ISP2100 BIT_0 |
2909 | #define DT_ISP2200 BIT_1 | 2912 | #define DT_ISP2200 BIT_1 |
@@ -2924,7 +2927,8 @@ struct qla_hw_data { | |||
2924 | #define DT_ISP8031 BIT_16 | 2927 | #define DT_ISP8031 BIT_16 |
2925 | #define DT_ISPFX00 BIT_17 | 2928 | #define DT_ISPFX00 BIT_17 |
2926 | #define DT_ISP8044 BIT_18 | 2929 | #define DT_ISP8044 BIT_18 |
2927 | #define DT_ISP_LAST (DT_ISP8044 << 1) | 2930 | #define DT_ISP2071 BIT_19 |
2931 | #define DT_ISP_LAST (DT_ISP2071 << 1) | ||
2928 | 2932 | ||
2929 | #define DT_T10_PI BIT_25 | 2933 | #define DT_T10_PI BIT_25 |
2930 | #define DT_IIDMA BIT_26 | 2934 | #define DT_IIDMA BIT_26 |
@@ -2954,6 +2958,7 @@ struct qla_hw_data { | |||
2954 | #define IS_QLA2031(ha) (DT_MASK(ha) & DT_ISP2031) | 2958 | #define IS_QLA2031(ha) (DT_MASK(ha) & DT_ISP2031) |
2955 | #define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031) | 2959 | #define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031) |
2956 | #define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00) | 2960 | #define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00) |
2961 | #define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071) | ||
2957 | 2962 | ||
2958 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 2963 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
2959 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 2964 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
@@ -2962,6 +2967,7 @@ struct qla_hw_data { | |||
2962 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) | 2967 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) |
2963 | #define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha)) | 2968 | #define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha)) |
2964 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) | 2969 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) |
2970 | #define IS_QLA27XX(ha) (IS_QLA2071(ha)) | ||
2965 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ | 2971 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ |
2966 | IS_QLA84XX(ha)) | 2972 | IS_QLA84XX(ha)) |
2967 | #define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ | 2973 | #define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ |
@@ -2970,11 +2976,13 @@ struct qla_hw_data { | |||
2970 | #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ | 2976 | #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ |
2971 | IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ | 2977 | IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ |
2972 | IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ | 2978 | IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ |
2973 | IS_QLA8044(ha)) | 2979 | IS_QLA8044(ha) || IS_QLA27XX(ha)) |
2974 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 2980 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) |
2975 | #define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) | 2981 | #define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) |
2976 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 2982 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ |
2977 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 2983 | IS_QLA27XX(ha)) |
2984 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ | ||
2985 | IS_QLA27XX(ha)) | ||
2978 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) | 2986 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) |
2979 | 2987 | ||
2980 | #define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI) | 2988 | #define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI) |
@@ -2984,7 +2992,8 @@ struct qla_hw_data { | |||
2984 | #define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) | 2992 | #define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) |
2985 | #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) | 2993 | #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) |
2986 | #define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED) | 2994 | #define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED) |
2987 | #define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha)) | 2995 | #define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha) || \ |
2996 | IS_QLA27XX(ha)) | ||
2988 | #define IS_BIDI_CAPABLE(ha) ((IS_QLA25XX(ha) || IS_QLA2031(ha))) | 2997 | #define IS_BIDI_CAPABLE(ha) ((IS_QLA25XX(ha) || IS_QLA2031(ha))) |
2989 | /* Bit 21 of fw_attributes decides the MCTP capabilities */ | 2998 | /* Bit 21 of fw_attributes decides the MCTP capabilities */ |
2990 | #define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \ | 2999 | #define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \ |
@@ -3109,6 +3118,9 @@ struct qla_hw_data { | |||
3109 | uint16_t fw_xcb_count; | 3118 | uint16_t fw_xcb_count; |
3110 | uint16_t fw_iocb_count; | 3119 | uint16_t fw_iocb_count; |
3111 | 3120 | ||
3121 | uint32_t fw_shared_ram_start; | ||
3122 | uint32_t fw_shared_ram_end; | ||
3123 | |||
3112 | uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */ | 3124 | uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */ |
3113 | uint8_t fw_seriallink_options[4]; | 3125 | uint8_t fw_seriallink_options[4]; |
3114 | uint16_t fw_seriallink_options24[4]; | 3126 | uint16_t fw_seriallink_options24[4]; |
@@ -3117,6 +3129,9 @@ struct qla_hw_data { | |||
3117 | uint32_t mpi_capabilities; | 3129 | uint32_t mpi_capabilities; |
3118 | uint8_t phy_version[3]; | 3130 | uint8_t phy_version[3]; |
3119 | 3131 | ||
3132 | /* Firmware dump template */ | ||
3133 | void *fw_dump_template; | ||
3134 | uint32_t fw_dump_template_len; | ||
3120 | /* Firmware dump information. */ | 3135 | /* Firmware dump information. */ |
3121 | struct qla2xxx_fw_dump *fw_dump; | 3136 | struct qla2xxx_fw_dump *fw_dump; |
3122 | uint32_t fw_dump_len; | 3137 | uint32_t fw_dump_len; |
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 792a29294b62..32ab80957688 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -114,7 +114,8 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha) | |||
114 | { | 114 | { |
115 | struct qla_hw_data *ha = vha->hw; | 115 | struct qla_hw_data *ha = vha->hw; |
116 | 116 | ||
117 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) | 117 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
118 | !IS_QLA27XX(ha)) | ||
118 | goto out; | 119 | goto out; |
119 | if (!ha->fce) | 120 | if (!ha->fce) |
120 | goto out; | 121 | goto out; |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 610d3aa905a0..3a7353eaccbd 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1378,6 +1378,10 @@ struct qla_flt_header { | |||
1378 | #define FLT_REG_NVRAM_0 0x15 | 1378 | #define FLT_REG_NVRAM_0 0x15 |
1379 | #define FLT_REG_VPD_1 0x16 | 1379 | #define FLT_REG_VPD_1 0x16 |
1380 | #define FLT_REG_NVRAM_1 0x17 | 1380 | #define FLT_REG_NVRAM_1 0x17 |
1381 | #define FLT_REG_VPD_2 0xD4 | ||
1382 | #define FLT_REG_NVRAM_2 0xD5 | ||
1383 | #define FLT_REG_VPD_3 0xD6 | ||
1384 | #define FLT_REG_NVRAM_3 0xD7 | ||
1381 | #define FLT_REG_FDT 0x1a | 1385 | #define FLT_REG_FDT 0x1a |
1382 | #define FLT_REG_FLT 0x1c | 1386 | #define FLT_REG_FLT 0x1c |
1383 | #define FLT_REG_HW_EVENT_0 0x1d | 1387 | #define FLT_REG_HW_EVENT_0 0x1d |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 1f426628a0a5..19a06620b0e5 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -511,6 +511,14 @@ extern void qla2300_fw_dump(scsi_qla_host_t *, int); | |||
511 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | 511 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); |
512 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); | 512 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); |
513 | extern void qla81xx_fw_dump(scsi_qla_host_t *, int); | 513 | extern void qla81xx_fw_dump(scsi_qla_host_t *, int); |
514 | |||
515 | extern void qla27xx_fwdump(scsi_qla_host_t *, int); | ||
516 | extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *); | ||
517 | extern int qla27xx_fwdt_template_valid(void *); | ||
518 | extern ulong qla27xx_fwdt_template_size(void *); | ||
519 | extern const void *qla27xx_fwdt_template_default(void); | ||
520 | extern ulong qla27xx_fwdt_template_default_size(void); | ||
521 | |||
514 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 522 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
515 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 523 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
516 | extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); | 524 | extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index cd47f1b32d9a..e377f9d2f92a 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1532,6 +1532,10 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha) | |||
1532 | if (IS_CNA_CAPABLE(ha)) | 1532 | if (IS_CNA_CAPABLE(ha)) |
1533 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1533 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1534 | FDMI_PORT_SPEED_10GB); | 1534 | FDMI_PORT_SPEED_10GB); |
1535 | else if (IS_QLA27XX(ha)) | ||
1536 | eiter->a.sup_speed = __constant_cpu_to_be32( | ||
1537 | FDMI_PORT_SPEED_32GB|FDMI_PORT_SPEED_16GB| | ||
1538 | FDMI_PORT_SPEED_8GB); | ||
1535 | else if (IS_QLA25XX(ha)) | 1539 | else if (IS_QLA25XX(ha)) |
1536 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1540 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1537 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1541 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
@@ -1580,6 +1584,10 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha) | |||
1580 | eiter->a.cur_speed = | 1584 | eiter->a.cur_speed = |
1581 | __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB); | 1585 | __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB); |
1582 | break; | 1586 | break; |
1587 | case PORT_SPEED_32GB: | ||
1588 | eiter->a.cur_speed = | ||
1589 | __constant_cpu_to_be32(FDMI_PORT_SPEED_32GB); | ||
1590 | break; | ||
1583 | default: | 1591 | default: |
1584 | eiter->a.cur_speed = | 1592 | eiter->a.cur_speed = |
1585 | __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); | 1593 | __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); |
@@ -1889,6 +1897,9 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) | |||
1889 | case BIT_10: | 1897 | case BIT_10: |
1890 | list[i].fp_speed = PORT_SPEED_16GB; | 1898 | list[i].fp_speed = PORT_SPEED_16GB; |
1891 | break; | 1899 | break; |
1900 | case BIT_8: | ||
1901 | list[i].fp_speed = PORT_SPEED_32GB; | ||
1902 | break; | ||
1892 | } | 1903 | } |
1893 | 1904 | ||
1894 | ql_dbg(ql_dbg_disc, vha, 0x205b, | 1905 | ql_dbg(ql_dbg_disc, vha, 0x205b, |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9b271ccd3324..f75d19f497fe 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1379,7 +1379,12 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | ha->fw_dumped = 0; | 1381 | ha->fw_dumped = 0; |
1382 | fixed_size = mem_size = eft_size = fce_size = mq_size = 0; | 1382 | dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; |
1383 | req_q_size = rsp_q_size = 0; | ||
1384 | |||
1385 | if (IS_QLA27XX(ha)) | ||
1386 | goto try_fce; | ||
1387 | |||
1383 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 1388 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
1384 | fixed_size = sizeof(struct qla2100_fw_dump); | 1389 | fixed_size = sizeof(struct qla2100_fw_dump); |
1385 | } else if (IS_QLA23XX(ha)) { | 1390 | } else if (IS_QLA23XX(ha)) { |
@@ -1395,6 +1400,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
1395 | fixed_size = offsetof(struct qla25xx_fw_dump, ext_mem); | 1400 | fixed_size = offsetof(struct qla25xx_fw_dump, ext_mem); |
1396 | else | 1401 | else |
1397 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); | 1402 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); |
1403 | |||
1398 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 1404 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
1399 | sizeof(uint32_t); | 1405 | sizeof(uint32_t); |
1400 | if (ha->mqenable) { | 1406 | if (ha->mqenable) { |
@@ -1412,9 +1418,16 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
1412 | if (ha->tgt.atio_ring) | 1418 | if (ha->tgt.atio_ring) |
1413 | mq_size += ha->tgt.atio_q_length * sizeof(request_t); | 1419 | mq_size += ha->tgt.atio_q_length * sizeof(request_t); |
1414 | /* Allocate memory for Fibre Channel Event Buffer. */ | 1420 | /* Allocate memory for Fibre Channel Event Buffer. */ |
1415 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) | 1421 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
1422 | !IS_QLA27XX(ha)) | ||
1416 | goto try_eft; | 1423 | goto try_eft; |
1417 | 1424 | ||
1425 | try_fce: | ||
1426 | if (ha->fce) | ||
1427 | dma_free_coherent(&ha->pdev->dev, | ||
1428 | FCE_SIZE, ha->fce, ha->fce_dma); | ||
1429 | |||
1430 | /* Allocate memory for Fibre Channel Event Buffer. */ | ||
1418 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, | 1431 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, |
1419 | GFP_KERNEL); | 1432 | GFP_KERNEL); |
1420 | if (!tc) { | 1433 | if (!tc) { |
@@ -1442,7 +1455,12 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
1442 | ha->flags.fce_enabled = 1; | 1455 | ha->flags.fce_enabled = 1; |
1443 | ha->fce_dma = tc_dma; | 1456 | ha->fce_dma = tc_dma; |
1444 | ha->fce = tc; | 1457 | ha->fce = tc; |
1458 | |||
1445 | try_eft: | 1459 | try_eft: |
1460 | if (ha->eft) | ||
1461 | dma_free_coherent(&ha->pdev->dev, | ||
1462 | EFT_SIZE, ha->eft, ha->eft_dma); | ||
1463 | |||
1446 | /* Allocate memory for Extended Trace Buffer. */ | 1464 | /* Allocate memory for Extended Trace Buffer. */ |
1447 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, | 1465 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, |
1448 | GFP_KERNEL); | 1466 | GFP_KERNEL); |
@@ -1469,15 +1487,28 @@ try_eft: | |||
1469 | ha->eft_dma = tc_dma; | 1487 | ha->eft_dma = tc_dma; |
1470 | ha->eft = tc; | 1488 | ha->eft = tc; |
1471 | } | 1489 | } |
1490 | |||
1472 | cont_alloc: | 1491 | cont_alloc: |
1492 | if (IS_QLA27XX(ha)) { | ||
1493 | if (!ha->fw_dump_template) { | ||
1494 | ql_log(ql_log_warn, vha, 0x00ba, | ||
1495 | "Failed missing fwdump template\n"); | ||
1496 | return; | ||
1497 | } | ||
1498 | dump_size = qla27xx_fwdt_calculate_dump_size(vha); | ||
1499 | ql_dbg(ql_dbg_init, vha, 0x00fa, | ||
1500 | "-> allocating fwdump (%x bytes)...\n", dump_size); | ||
1501 | goto allocate; | ||
1502 | } | ||
1503 | |||
1473 | req_q_size = req->length * sizeof(request_t); | 1504 | req_q_size = req->length * sizeof(request_t); |
1474 | rsp_q_size = rsp->length * sizeof(response_t); | 1505 | rsp_q_size = rsp->length * sizeof(response_t); |
1475 | |||
1476 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | 1506 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
1477 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size; | 1507 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size; |
1478 | ha->chain_offset = dump_size; | 1508 | ha->chain_offset = dump_size; |
1479 | dump_size += mq_size + fce_size; | 1509 | dump_size += mq_size + fce_size; |
1480 | 1510 | ||
1511 | allocate: | ||
1481 | ha->fw_dump = vmalloc(dump_size); | 1512 | ha->fw_dump = vmalloc(dump_size); |
1482 | if (!ha->fw_dump) { | 1513 | if (!ha->fw_dump) { |
1483 | ql_log(ql_log_warn, vha, 0x00c4, | 1514 | ql_log(ql_log_warn, vha, 0x00c4, |
@@ -1499,10 +1530,13 @@ cont_alloc: | |||
1499 | } | 1530 | } |
1500 | return; | 1531 | return; |
1501 | } | 1532 | } |
1533 | ha->fw_dump_len = dump_size; | ||
1502 | ql_dbg(ql_dbg_init, vha, 0x00c5, | 1534 | ql_dbg(ql_dbg_init, vha, 0x00c5, |
1503 | "Allocated (%d KB) for firmware dump.\n", dump_size / 1024); | 1535 | "Allocated (%d KB) for firmware dump.\n", dump_size / 1024); |
1504 | 1536 | ||
1505 | ha->fw_dump_len = dump_size; | 1537 | if (IS_QLA27XX(ha)) |
1538 | return; | ||
1539 | |||
1506 | ha->fw_dump->signature[0] = 'Q'; | 1540 | ha->fw_dump->signature[0] = 'Q'; |
1507 | ha->fw_dump->signature[1] = 'L'; | 1541 | ha->fw_dump->signature[1] = 'L'; |
1508 | ha->fw_dump->signature[2] = 'G'; | 1542 | ha->fw_dump->signature[2] = 'G'; |
@@ -1731,7 +1765,7 @@ enable_82xx_npiv: | |||
1731 | ha->fw_major_version, ha->fw_minor_version, | 1765 | ha->fw_major_version, ha->fw_minor_version, |
1732 | ha->fw_subminor_version); | 1766 | ha->fw_subminor_version); |
1733 | 1767 | ||
1734 | if (IS_QLA83XX(ha)) { | 1768 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
1735 | ha->flags.fac_supported = 0; | 1769 | ha->flags.fac_supported = 0; |
1736 | rval = QLA_SUCCESS; | 1770 | rval = QLA_SUCCESS; |
1737 | } | 1771 | } |
@@ -1930,7 +1964,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
1930 | icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); | 1964 | icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); |
1931 | icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); | 1965 | icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); |
1932 | 1966 | ||
1933 | if (ha->mqenable || IS_QLA83XX(ha)) { | 1967 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
1934 | icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); | 1968 | icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); |
1935 | icb->rid = __constant_cpu_to_le16(rid); | 1969 | icb->rid = __constant_cpu_to_le16(rid); |
1936 | if (ha->flags.msix_enabled) { | 1970 | if (ha->flags.msix_enabled) { |
@@ -4789,13 +4823,14 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
4789 | nv = ha->nvram; | 4823 | nv = ha->nvram; |
4790 | 4824 | ||
4791 | /* Determine NVRAM starting address. */ | 4825 | /* Determine NVRAM starting address. */ |
4792 | if (ha->flags.port0) { | 4826 | if (ha->port_no == 0) { |
4793 | ha->nvram_base = FA_NVRAM_FUNC0_ADDR; | 4827 | ha->nvram_base = FA_NVRAM_FUNC0_ADDR; |
4794 | ha->vpd_base = FA_NVRAM_VPD0_ADDR; | 4828 | ha->vpd_base = FA_NVRAM_VPD0_ADDR; |
4795 | } else { | 4829 | } else { |
4796 | ha->nvram_base = FA_NVRAM_FUNC1_ADDR; | 4830 | ha->nvram_base = FA_NVRAM_FUNC1_ADDR; |
4797 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; | 4831 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; |
4798 | } | 4832 | } |
4833 | |||
4799 | ha->nvram_size = sizeof(struct nvram_24xx); | 4834 | ha->nvram_size = sizeof(struct nvram_24xx); |
4800 | ha->vpd_size = FA_NVRAM_VPD_SIZE; | 4835 | ha->vpd_size = FA_NVRAM_VPD_SIZE; |
4801 | 4836 | ||
@@ -4839,7 +4874,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
4839 | nv->exchange_count = __constant_cpu_to_le16(0); | 4874 | nv->exchange_count = __constant_cpu_to_le16(0); |
4840 | nv->hard_address = __constant_cpu_to_le16(124); | 4875 | nv->hard_address = __constant_cpu_to_le16(124); |
4841 | nv->port_name[0] = 0x21; | 4876 | nv->port_name[0] = 0x21; |
4842 | nv->port_name[1] = 0x00 + ha->port_no; | 4877 | nv->port_name[1] = 0x00 + ha->port_no + 1; |
4843 | nv->port_name[2] = 0x00; | 4878 | nv->port_name[2] = 0x00; |
4844 | nv->port_name[3] = 0xe0; | 4879 | nv->port_name[3] = 0xe0; |
4845 | nv->port_name[4] = 0x8b; | 4880 | nv->port_name[4] = 0x8b; |
@@ -5114,6 +5149,99 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, | |||
5114 | segments--; | 5149 | segments--; |
5115 | } | 5150 | } |
5116 | 5151 | ||
5152 | if (!IS_QLA27XX(ha)) | ||
5153 | return rval; | ||
5154 | |||
5155 | if (ha->fw_dump_template) | ||
5156 | vfree(ha->fw_dump_template); | ||
5157 | ha->fw_dump_template = NULL; | ||
5158 | ha->fw_dump_template_len = 0; | ||
5159 | |||
5160 | ql_dbg(ql_dbg_init, vha, 0x0161, | ||
5161 | "Loading fwdump template from %x\n", faddr); | ||
5162 | qla24xx_read_flash_data(vha, dcode, faddr, 7); | ||
5163 | risc_size = be32_to_cpu(dcode[2]); | ||
5164 | ql_dbg(ql_dbg_init, vha, 0x0162, | ||
5165 | "-> array size %x dwords\n", risc_size); | ||
5166 | if (risc_size == 0 || risc_size == ~0) | ||
5167 | goto default_template; | ||
5168 | |||
5169 | dlen = (risc_size - 8) * sizeof(*dcode); | ||
5170 | ql_dbg(ql_dbg_init, vha, 0x0163, | ||
5171 | "-> template allocating %x bytes...\n", dlen); | ||
5172 | ha->fw_dump_template = vmalloc(dlen); | ||
5173 | if (!ha->fw_dump_template) { | ||
5174 | ql_log(ql_log_warn, vha, 0x0164, | ||
5175 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
5176 | goto default_template; | ||
5177 | } | ||
5178 | |||
5179 | faddr += 7; | ||
5180 | risc_size -= 8; | ||
5181 | dcode = ha->fw_dump_template; | ||
5182 | qla24xx_read_flash_data(vha, dcode, faddr, risc_size); | ||
5183 | for (i = 0; i < risc_size; i++) | ||
5184 | dcode[i] = le32_to_cpu(dcode[i]); | ||
5185 | |||
5186 | if (!qla27xx_fwdt_template_valid(dcode)) { | ||
5187 | ql_log(ql_log_warn, vha, 0x0165, | ||
5188 | "Failed fwdump template validate\n"); | ||
5189 | goto default_template; | ||
5190 | } | ||
5191 | |||
5192 | dlen = qla27xx_fwdt_template_size(dcode); | ||
5193 | ql_dbg(ql_dbg_init, vha, 0x0166, | ||
5194 | "-> template size %x bytes\n", dlen); | ||
5195 | if (dlen > risc_size * sizeof(*dcode)) { | ||
5196 | ql_log(ql_log_warn, vha, 0x0167, | ||
5197 | "Failed fwdump template exceeds array by %lx bytes\n", | ||
5198 | dlen - risc_size * sizeof(*dcode)); | ||
5199 | goto default_template; | ||
5200 | } | ||
5201 | ha->fw_dump_template_len = dlen; | ||
5202 | return rval; | ||
5203 | |||
5204 | default_template: | ||
5205 | ql_log(ql_log_warn, vha, 0x0168, "Using default fwdump template\n"); | ||
5206 | if (ha->fw_dump_template) | ||
5207 | vfree(ha->fw_dump_template); | ||
5208 | ha->fw_dump_template = NULL; | ||
5209 | ha->fw_dump_template_len = 0; | ||
5210 | |||
5211 | dlen = qla27xx_fwdt_template_default_size(); | ||
5212 | ql_dbg(ql_dbg_init, vha, 0x0169, | ||
5213 | "-> template allocating %x bytes...\n", dlen); | ||
5214 | ha->fw_dump_template = vmalloc(dlen); | ||
5215 | if (!ha->fw_dump_template) { | ||
5216 | ql_log(ql_log_warn, vha, 0x016a, | ||
5217 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
5218 | goto failed_template; | ||
5219 | } | ||
5220 | |||
5221 | dcode = ha->fw_dump_template; | ||
5222 | risc_size = dlen / sizeof(*dcode); | ||
5223 | memcpy(dcode, qla27xx_fwdt_template_default(), dlen); | ||
5224 | for (i = 0; i < risc_size; i++) | ||
5225 | dcode[i] = be32_to_cpu(dcode[i]); | ||
5226 | |||
5227 | if (!qla27xx_fwdt_template_valid(ha->fw_dump_template)) { | ||
5228 | ql_log(ql_log_warn, vha, 0x016b, | ||
5229 | "Failed fwdump template validate\n"); | ||
5230 | goto failed_template; | ||
5231 | } | ||
5232 | |||
5233 | dlen = qla27xx_fwdt_template_size(ha->fw_dump_template); | ||
5234 | ql_dbg(ql_dbg_init, vha, 0x016c, | ||
5235 | "-> template size %x bytes\n", dlen); | ||
5236 | ha->fw_dump_template_len = dlen; | ||
5237 | return rval; | ||
5238 | |||
5239 | failed_template: | ||
5240 | ql_log(ql_log_warn, vha, 0x016d, "Failed default fwdump template\n"); | ||
5241 | if (ha->fw_dump_template) | ||
5242 | vfree(ha->fw_dump_template); | ||
5243 | ha->fw_dump_template = NULL; | ||
5244 | ha->fw_dump_template_len = 0; | ||
5117 | return rval; | 5245 | return rval; |
5118 | } | 5246 | } |
5119 | 5247 | ||
@@ -5228,7 +5356,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
5228 | uint32_t risc_size; | 5356 | uint32_t risc_size; |
5229 | uint32_t i; | 5357 | uint32_t i; |
5230 | struct fw_blob *blob; | 5358 | struct fw_blob *blob; |
5231 | uint32_t *fwcode, fwclen; | 5359 | const uint32_t *fwcode; |
5360 | uint32_t fwclen; | ||
5232 | struct qla_hw_data *ha = vha->hw; | 5361 | struct qla_hw_data *ha = vha->hw; |
5233 | struct req_que *req = ha->req_q_map[0]; | 5362 | struct req_que *req = ha->req_q_map[0]; |
5234 | 5363 | ||
@@ -5260,7 +5389,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
5260 | ql_log(ql_log_fatal, vha, 0x0093, | 5389 | ql_log(ql_log_fatal, vha, 0x0093, |
5261 | "Unable to verify integrity of firmware image (%Zd).\n", | 5390 | "Unable to verify integrity of firmware image (%Zd).\n", |
5262 | blob->fw->size); | 5391 | blob->fw->size); |
5263 | goto fail_fw_integrity; | 5392 | return QLA_FUNCTION_FAILED; |
5264 | } | 5393 | } |
5265 | for (i = 0; i < 4; i++) | 5394 | for (i = 0; i < 4; i++) |
5266 | dcode[i] = be32_to_cpu(fwcode[i + 4]); | 5395 | dcode[i] = be32_to_cpu(fwcode[i + 4]); |
@@ -5274,7 +5403,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
5274 | ql_log(ql_log_fatal, vha, 0x0095, | 5403 | ql_log(ql_log_fatal, vha, 0x0095, |
5275 | "Firmware data: %08x %08x %08x %08x.\n", | 5404 | "Firmware data: %08x %08x %08x %08x.\n", |
5276 | dcode[0], dcode[1], dcode[2], dcode[3]); | 5405 | dcode[0], dcode[1], dcode[2], dcode[3]); |
5277 | goto fail_fw_integrity; | 5406 | return QLA_FUNCTION_FAILED; |
5278 | } | 5407 | } |
5279 | 5408 | ||
5280 | while (segments && rval == QLA_SUCCESS) { | 5409 | while (segments && rval == QLA_SUCCESS) { |
@@ -5288,8 +5417,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
5288 | ql_log(ql_log_fatal, vha, 0x0096, | 5417 | ql_log(ql_log_fatal, vha, 0x0096, |
5289 | "Unable to verify integrity of firmware image " | 5418 | "Unable to verify integrity of firmware image " |
5290 | "(%Zd).\n", blob->fw->size); | 5419 | "(%Zd).\n", blob->fw->size); |
5291 | 5420 | return QLA_FUNCTION_FAILED; | |
5292 | goto fail_fw_integrity; | ||
5293 | } | 5421 | } |
5294 | 5422 | ||
5295 | fragment = 0; | 5423 | fragment = 0; |
@@ -5323,10 +5451,100 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
5323 | /* Next segment. */ | 5451 | /* Next segment. */ |
5324 | segments--; | 5452 | segments--; |
5325 | } | 5453 | } |
5454 | |||
5455 | if (!IS_QLA27XX(ha)) | ||
5456 | return rval; | ||
5457 | |||
5458 | if (ha->fw_dump_template) | ||
5459 | vfree(ha->fw_dump_template); | ||
5460 | ha->fw_dump_template = NULL; | ||
5461 | ha->fw_dump_template_len = 0; | ||
5462 | |||
5463 | ql_dbg(ql_dbg_init, vha, 0x171, | ||
5464 | "Loading fwdump template from %lx\n", | ||
5465 | (void *)fwcode - (void *)blob->fw->data); | ||
5466 | risc_size = be32_to_cpu(fwcode[2]); | ||
5467 | ql_dbg(ql_dbg_init, vha, 0x172, | ||
5468 | "-> array size %x dwords\n", risc_size); | ||
5469 | if (risc_size == 0 || risc_size == ~0) | ||
5470 | goto default_template; | ||
5471 | |||
5472 | dlen = (risc_size - 8) * sizeof(*fwcode); | ||
5473 | ql_dbg(ql_dbg_init, vha, 0x0173, | ||
5474 | "-> template allocating %x bytes...\n", dlen); | ||
5475 | ha->fw_dump_template = vmalloc(dlen); | ||
5476 | if (!ha->fw_dump_template) { | ||
5477 | ql_log(ql_log_warn, vha, 0x0174, | ||
5478 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
5479 | goto default_template; | ||
5480 | } | ||
5481 | |||
5482 | fwcode += 7; | ||
5483 | risc_size -= 8; | ||
5484 | dcode = ha->fw_dump_template; | ||
5485 | for (i = 0; i < risc_size; i++) | ||
5486 | dcode[i] = le32_to_cpu(fwcode[i]); | ||
5487 | |||
5488 | if (!qla27xx_fwdt_template_valid(dcode)) { | ||
5489 | ql_log(ql_log_warn, vha, 0x0175, | ||
5490 | "Failed fwdump template validate\n"); | ||
5491 | goto default_template; | ||
5492 | } | ||
5493 | |||
5494 | dlen = qla27xx_fwdt_template_size(dcode); | ||
5495 | ql_dbg(ql_dbg_init, vha, 0x0176, | ||
5496 | "-> template size %x bytes\n", dlen); | ||
5497 | if (dlen > risc_size * sizeof(*fwcode)) { | ||
5498 | ql_log(ql_log_warn, vha, 0x0177, | ||
5499 | "Failed fwdump template exceeds array by %lx bytes\n", | ||
5500 | dlen - risc_size * sizeof(*fwcode)); | ||
5501 | goto default_template; | ||
5502 | } | ||
5503 | ha->fw_dump_template_len = dlen; | ||
5326 | return rval; | 5504 | return rval; |
5327 | 5505 | ||
5328 | fail_fw_integrity: | 5506 | default_template: |
5329 | return QLA_FUNCTION_FAILED; | 5507 | ql_log(ql_log_warn, vha, 0x0178, "Using default fwdump template\n"); |
5508 | if (ha->fw_dump_template) | ||
5509 | vfree(ha->fw_dump_template); | ||
5510 | ha->fw_dump_template = NULL; | ||
5511 | ha->fw_dump_template_len = 0; | ||
5512 | |||
5513 | dlen = qla27xx_fwdt_template_default_size(); | ||
5514 | ql_dbg(ql_dbg_init, vha, 0x0179, | ||
5515 | "-> template allocating %x bytes...\n", dlen); | ||
5516 | ha->fw_dump_template = vmalloc(dlen); | ||
5517 | if (!ha->fw_dump_template) { | ||
5518 | ql_log(ql_log_warn, vha, 0x017a, | ||
5519 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
5520 | goto failed_template; | ||
5521 | } | ||
5522 | |||
5523 | dcode = ha->fw_dump_template; | ||
5524 | risc_size = dlen / sizeof(*fwcode); | ||
5525 | fwcode = qla27xx_fwdt_template_default(); | ||
5526 | for (i = 0; i < risc_size; i++) | ||
5527 | dcode[i] = be32_to_cpu(fwcode[i]); | ||
5528 | |||
5529 | if (!qla27xx_fwdt_template_valid(ha->fw_dump_template)) { | ||
5530 | ql_log(ql_log_warn, vha, 0x017b, | ||
5531 | "Failed fwdump template validate\n"); | ||
5532 | goto failed_template; | ||
5533 | } | ||
5534 | |||
5535 | dlen = qla27xx_fwdt_template_size(ha->fw_dump_template); | ||
5536 | ql_dbg(ql_dbg_init, vha, 0x017c, | ||
5537 | "-> template size %x bytes\n", dlen); | ||
5538 | ha->fw_dump_template_len = dlen; | ||
5539 | return rval; | ||
5540 | |||
5541 | failed_template: | ||
5542 | ql_log(ql_log_warn, vha, 0x017d, "Failed default fwdump template\n"); | ||
5543 | if (ha->fw_dump_template) | ||
5544 | vfree(ha->fw_dump_template); | ||
5545 | ha->fw_dump_template = NULL; | ||
5546 | ha->fw_dump_template_len = 0; | ||
5547 | return rval; | ||
5330 | } | 5548 | } |
5331 | 5549 | ||
5332 | int | 5550 | int |
@@ -5602,7 +5820,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
5602 | nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); | 5820 | nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); |
5603 | nv->exchange_count = __constant_cpu_to_le16(0); | 5821 | nv->exchange_count = __constant_cpu_to_le16(0); |
5604 | nv->port_name[0] = 0x21; | 5822 | nv->port_name[0] = 0x21; |
5605 | nv->port_name[1] = 0x00 + ha->port_no; | 5823 | nv->port_name[1] = 0x00 + ha->port_no + 1; |
5606 | nv->port_name[2] = 0x00; | 5824 | nv->port_name[2] = 0x00; |
5607 | nv->port_name[3] = 0xe0; | 5825 | nv->port_name[3] = 0xe0; |
5608 | nv->port_name[4] = 0x8b; | 5826 | nv->port_name[4] = 0x8b; |
@@ -5636,7 +5854,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
5636 | nv->enode_mac[2] = 0xDD; | 5854 | nv->enode_mac[2] = 0xDD; |
5637 | nv->enode_mac[3] = 0x04; | 5855 | nv->enode_mac[3] = 0x04; |
5638 | nv->enode_mac[4] = 0x05; | 5856 | nv->enode_mac[4] = 0x05; |
5639 | nv->enode_mac[5] = 0x06 + ha->port_no; | 5857 | nv->enode_mac[5] = 0x06 + ha->port_no + 1; |
5640 | 5858 | ||
5641 | rval = 1; | 5859 | rval = 1; |
5642 | } | 5860 | } |
@@ -5674,7 +5892,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
5674 | icb->enode_mac[2] = 0xDD; | 5892 | icb->enode_mac[2] = 0xDD; |
5675 | icb->enode_mac[3] = 0x04; | 5893 | icb->enode_mac[3] = 0x04; |
5676 | icb->enode_mac[4] = 0x05; | 5894 | icb->enode_mac[4] = 0x05; |
5677 | icb->enode_mac[5] = 0x06 + ha->port_no; | 5895 | icb->enode_mac[5] = 0x06 + ha->port_no + 1; |
5678 | } | 5896 | } |
5679 | 5897 | ||
5680 | /* Use extended-initialization control block. */ | 5898 | /* Use extended-initialization control block. */ |
@@ -5777,7 +5995,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
5777 | ha->login_retry_count = ql2xloginretrycount; | 5995 | ha->login_retry_count = ql2xloginretrycount; |
5778 | 5996 | ||
5779 | /* if not running MSI-X we need handshaking on interrupts */ | 5997 | /* if not running MSI-X we need handshaking on interrupts */ |
5780 | if (!vha->hw->flags.msix_enabled && IS_QLA83XX(ha)) | 5998 | if (!vha->hw->flags.msix_enabled && (IS_QLA83XX(ha) || IS_QLA27XX(ha))) |
5781 | icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22); | 5999 | icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22); |
5782 | 6000 | ||
5783 | /* Enable ZIO. */ | 6001 | /* Enable ZIO. */ |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 46b9307e8be4..5e6ac6c3186e 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -488,7 +488,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) | |||
488 | req->ring_ptr++; | 488 | req->ring_ptr++; |
489 | 489 | ||
490 | /* Set chip new ring index. */ | 490 | /* Set chip new ring index. */ |
491 | if (ha->mqenable || IS_QLA83XX(ha)) { | 491 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
492 | WRT_REG_DWORD(req->req_q_in, req->ring_index); | 492 | WRT_REG_DWORD(req->req_q_in, req->ring_index); |
493 | RD_REG_DWORD_RELAXED(&ha->iobase->isp24.hccr); | 493 | RD_REG_DWORD_RELAXED(&ha->iobase->isp24.hccr); |
494 | } else if (IS_QLAFX00(ha)) { | 494 | } else if (IS_QLAFX00(ha)) { |
@@ -1848,7 +1848,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) | |||
1848 | skip_cmd_array: | 1848 | skip_cmd_array: |
1849 | /* Check for room on request queue. */ | 1849 | /* Check for room on request queue. */ |
1850 | if (req->cnt < req_cnt) { | 1850 | if (req->cnt < req_cnt) { |
1851 | if (ha->mqenable || IS_QLA83XX(ha)) | 1851 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
1852 | cnt = RD_REG_DWORD(®->isp25mq.req_q_out); | 1852 | cnt = RD_REG_DWORD(®->isp25mq.req_q_out); |
1853 | else if (IS_P3P_TYPE(ha)) | 1853 | else if (IS_P3P_TYPE(ha)) |
1854 | cnt = RD_REG_DWORD(®->isp82.req_q_out); | 1854 | cnt = RD_REG_DWORD(®->isp82.req_q_out); |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 0a1dcb43d18b..c2aaf6a93cc1 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -356,15 +356,16 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr) | |||
356 | const char * | 356 | const char * |
357 | qla2x00_get_link_speed_str(struct qla_hw_data *ha, uint16_t speed) | 357 | qla2x00_get_link_speed_str(struct qla_hw_data *ha, uint16_t speed) |
358 | { | 358 | { |
359 | static const char * const link_speeds[] = { | 359 | static const char *const link_speeds[] = { |
360 | "1", "2", "?", "4", "8", "16", "10" | 360 | "1", "2", "?", "4", "8", "16", "32", "10" |
361 | }; | 361 | }; |
362 | #define QLA_LAST_SPEED 7 | ||
362 | 363 | ||
363 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 364 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
364 | return link_speeds[0]; | 365 | return link_speeds[0]; |
365 | else if (speed == 0x13) | 366 | else if (speed == 0x13) |
366 | return link_speeds[6]; | 367 | return link_speeds[QLA_LAST_SPEED]; |
367 | else if (speed < 6) | 368 | else if (speed < QLA_LAST_SPEED) |
368 | return link_speeds[speed]; | 369 | return link_speeds[speed]; |
369 | else | 370 | else |
370 | return link_speeds[LS_UNKNOWN]; | 371 | return link_speeds[LS_UNKNOWN]; |
@@ -649,7 +650,7 @@ skip_rio: | |||
649 | break; | 650 | break; |
650 | 651 | ||
651 | case MBA_SYSTEM_ERR: /* System Error */ | 652 | case MBA_SYSTEM_ERR: /* System Error */ |
652 | mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha)) ? | 653 | mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) ? |
653 | RD_REG_WORD(®24->mailbox7) : 0; | 654 | RD_REG_WORD(®24->mailbox7) : 0; |
654 | ql_log(ql_log_warn, vha, 0x5003, | 655 | ql_log(ql_log_warn, vha, 0x5003, |
655 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh " | 656 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh " |
@@ -666,7 +667,7 @@ skip_rio: | |||
666 | vha->device_flags |= DFLG_DEV_FAILED; | 667 | vha->device_flags |= DFLG_DEV_FAILED; |
667 | } else { | 668 | } else { |
668 | /* Check to see if MPI timeout occurred */ | 669 | /* Check to see if MPI timeout occurred */ |
669 | if ((mbx & MBX_3) && (ha->flags.port0)) | 670 | if ((mbx & MBX_3) && (ha->port_no == 0)) |
670 | set_bit(MPI_RESET_NEEDED, | 671 | set_bit(MPI_RESET_NEEDED, |
671 | &vha->dpc_flags); | 672 | &vha->dpc_flags); |
672 | 673 | ||
@@ -2525,7 +2526,8 @@ qla2xxx_check_risc_status(scsi_qla_host_t *vha) | |||
2525 | struct qla_hw_data *ha = vha->hw; | 2526 | struct qla_hw_data *ha = vha->hw; |
2526 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 2527 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
2527 | 2528 | ||
2528 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) | 2529 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
2530 | !IS_QLA27XX(ha)) | ||
2529 | return; | 2531 | return; |
2530 | 2532 | ||
2531 | rval = QLA_SUCCESS; | 2533 | rval = QLA_SUCCESS; |
@@ -2979,7 +2981,7 @@ msix_register_fail: | |||
2979 | } | 2981 | } |
2980 | 2982 | ||
2981 | /* Enable MSI-X vector for response queue update for queue 0 */ | 2983 | /* Enable MSI-X vector for response queue update for queue 0 */ |
2982 | if (IS_QLA83XX(ha)) { | 2984 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
2983 | if (ha->msixbase && ha->mqiobase && | 2985 | if (ha->msixbase && ha->mqiobase && |
2984 | (ha->max_rsp_queues > 1 || ha->max_req_queues > 1)) | 2986 | (ha->max_rsp_queues > 1 || ha->max_req_queues > 1)) |
2985 | ha->mqenable = 1; | 2987 | ha->mqenable = 1; |
@@ -3003,12 +3005,13 @@ int | |||
3003 | qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) | 3005 | qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) |
3004 | { | 3006 | { |
3005 | int ret = QLA_FUNCTION_FAILED; | 3007 | int ret = QLA_FUNCTION_FAILED; |
3006 | device_reg_t __iomem *reg = ha->iobase; | 3008 | device_reg_t *reg = ha->iobase; |
3007 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 3009 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
3008 | 3010 | ||
3009 | /* If possible, enable MSI-X. */ | 3011 | /* If possible, enable MSI-X. */ |
3010 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && | 3012 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && |
3011 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && !IS_QLAFX00(ha)) | 3013 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && !IS_QLAFX00(ha) && |
3014 | !IS_QLA27XX(ha)) | ||
3012 | goto skip_msi; | 3015 | goto skip_msi; |
3013 | 3016 | ||
3014 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && | 3017 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && |
@@ -3043,7 +3046,8 @@ skip_msix: | |||
3043 | "Falling back-to MSI mode -%d.\n", ret); | 3046 | "Falling back-to MSI mode -%d.\n", ret); |
3044 | 3047 | ||
3045 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && | 3048 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && |
3046 | !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha)) | 3049 | !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) && |
3050 | !IS_QLA27XX(ha)) | ||
3047 | goto skip_msi; | 3051 | goto skip_msi; |
3048 | 3052 | ||
3049 | ret = pci_enable_msi(ha->pdev); | 3053 | ret = pci_enable_msi(ha->pdev); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index b94511ae0051..b4f7cd5fa75c 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -35,7 +35,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
35 | { | 35 | { |
36 | int rval; | 36 | int rval; |
37 | unsigned long flags = 0; | 37 | unsigned long flags = 0; |
38 | device_reg_t __iomem *reg; | 38 | device_reg_t *reg; |
39 | uint8_t abort_active; | 39 | uint8_t abort_active; |
40 | uint8_t io_lock_on; | 40 | uint8_t io_lock_on; |
41 | uint16_t command = 0; | 41 | uint16_t command = 0; |
@@ -468,7 +468,8 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) | |||
468 | mcp->mb[1] = MSW(risc_addr); | 468 | mcp->mb[1] = MSW(risc_addr); |
469 | mcp->mb[2] = LSW(risc_addr); | 469 | mcp->mb[2] = LSW(risc_addr); |
470 | mcp->mb[3] = 0; | 470 | mcp->mb[3] = 0; |
471 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha)) { | 471 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || |
472 | IS_QLA27XX(ha)) { | ||
472 | struct nvram_81xx *nv = ha->nvram; | 473 | struct nvram_81xx *nv = ha->nvram; |
473 | mcp->mb[4] = (nv->enhanced_features & | 474 | mcp->mb[4] = (nv->enhanced_features & |
474 | EXTENDED_BB_CREDITS); | 475 | EXTENDED_BB_CREDITS); |
@@ -539,6 +540,8 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) | |||
539 | mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; | 540 | mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; |
540 | if (IS_FWI2_CAPABLE(ha)) | 541 | if (IS_FWI2_CAPABLE(ha)) |
541 | mcp->in_mb |= MBX_17|MBX_16|MBX_15; | 542 | mcp->in_mb |= MBX_17|MBX_16|MBX_15; |
543 | if (IS_QLA27XX(ha)) | ||
544 | mcp->in_mb |= MBX_21|MBX_20|MBX_19|MBX_18; | ||
542 | mcp->flags = 0; | 545 | mcp->flags = 0; |
543 | mcp->tov = MBX_TOV_SECONDS; | 546 | mcp->tov = MBX_TOV_SECONDS; |
544 | rval = qla2x00_mailbox_command(vha, mcp); | 547 | rval = qla2x00_mailbox_command(vha, mcp); |
@@ -574,6 +577,10 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) | |||
574 | "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n", | 577 | "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n", |
575 | __func__, mcp->mb[17], mcp->mb[16]); | 578 | __func__, mcp->mb[17], mcp->mb[16]); |
576 | } | 579 | } |
580 | if (IS_QLA27XX(ha)) { | ||
581 | ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18]; | ||
582 | ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20]; | ||
583 | } | ||
577 | 584 | ||
578 | failed: | 585 | failed: |
579 | if (rval != QLA_SUCCESS) { | 586 | if (rval != QLA_SUCCESS) { |
@@ -1225,7 +1232,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) | |||
1225 | } | 1232 | } |
1226 | /* 1 and 2 should normally be captured. */ | 1233 | /* 1 and 2 should normally be captured. */ |
1227 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 1234 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
1228 | if (IS_QLA83XX(ha)) | 1235 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
1229 | /* mb3 is additional info about the installed SFP. */ | 1236 | /* mb3 is additional info about the installed SFP. */ |
1230 | mcp->in_mb |= MBX_3; | 1237 | mcp->in_mb |= MBX_3; |
1231 | mcp->buf_size = size; | 1238 | mcp->buf_size = size; |
@@ -2349,7 +2356,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt, | |||
2349 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 2356 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
2350 | mcp->out_mb = MBX_0; | 2357 | mcp->out_mb = MBX_0; |
2351 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 2358 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
2352 | if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) | 2359 | if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw)) |
2353 | mcp->in_mb |= MBX_12; | 2360 | mcp->in_mb |= MBX_12; |
2354 | mcp->tov = MBX_TOV_SECONDS; | 2361 | mcp->tov = MBX_TOV_SECONDS; |
2355 | mcp->flags = 0; | 2362 | mcp->flags = 0; |
@@ -3032,7 +3039,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, | |||
3032 | "Entered %s.\n", __func__); | 3039 | "Entered %s.\n", __func__); |
3033 | 3040 | ||
3034 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && | 3041 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && |
3035 | !IS_QLA83XX(vha->hw)) | 3042 | !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw)) |
3036 | return QLA_FUNCTION_FAILED; | 3043 | return QLA_FUNCTION_FAILED; |
3037 | 3044 | ||
3038 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | 3045 | if (unlikely(pci_channel_offline(vha->hw->pdev))) |
@@ -3662,7 +3669,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3662 | mcp->mb[12] = req->qos; | 3669 | mcp->mb[12] = req->qos; |
3663 | mcp->mb[11] = req->vp_idx; | 3670 | mcp->mb[11] = req->vp_idx; |
3664 | mcp->mb[13] = req->rid; | 3671 | mcp->mb[13] = req->rid; |
3665 | if (IS_QLA83XX(ha)) | 3672 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
3666 | mcp->mb[15] = 0; | 3673 | mcp->mb[15] = 0; |
3667 | 3674 | ||
3668 | mcp->mb[4] = req->id; | 3675 | mcp->mb[4] = req->id; |
@@ -3676,9 +3683,9 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3676 | mcp->flags = MBX_DMA_OUT; | 3683 | mcp->flags = MBX_DMA_OUT; |
3677 | mcp->tov = MBX_TOV_SECONDS * 2; | 3684 | mcp->tov = MBX_TOV_SECONDS * 2; |
3678 | 3685 | ||
3679 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 3686 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
3680 | mcp->in_mb |= MBX_1; | 3687 | mcp->in_mb |= MBX_1; |
3681 | if (IS_QLA83XX(ha)) { | 3688 | if (IS_QLA83XX(ha) || !IS_QLA27XX(ha)) { |
3682 | mcp->out_mb |= MBX_15; | 3689 | mcp->out_mb |= MBX_15; |
3683 | /* debug q create issue in SR-IOV */ | 3690 | /* debug q create issue in SR-IOV */ |
3684 | mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; | 3691 | mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; |
@@ -3687,7 +3694,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3687 | spin_lock_irqsave(&ha->hardware_lock, flags); | 3694 | spin_lock_irqsave(&ha->hardware_lock, flags); |
3688 | if (!(req->options & BIT_0)) { | 3695 | if (!(req->options & BIT_0)) { |
3689 | WRT_REG_DWORD(req->req_q_in, 0); | 3696 | WRT_REG_DWORD(req->req_q_in, 0); |
3690 | if (!IS_QLA83XX(ha)) | 3697 | if (!IS_QLA83XX(ha) || !IS_QLA27XX(ha)) |
3691 | WRT_REG_DWORD(req->req_q_out, 0); | 3698 | WRT_REG_DWORD(req->req_q_out, 0); |
3692 | } | 3699 | } |
3693 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3700 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -3725,7 +3732,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
3725 | mcp->mb[5] = rsp->length; | 3732 | mcp->mb[5] = rsp->length; |
3726 | mcp->mb[14] = rsp->msix->entry; | 3733 | mcp->mb[14] = rsp->msix->entry; |
3727 | mcp->mb[13] = rsp->rid; | 3734 | mcp->mb[13] = rsp->rid; |
3728 | if (IS_QLA83XX(ha)) | 3735 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
3729 | mcp->mb[15] = 0; | 3736 | mcp->mb[15] = 0; |
3730 | 3737 | ||
3731 | mcp->mb[4] = rsp->id; | 3738 | mcp->mb[4] = rsp->id; |
@@ -3742,7 +3749,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
3742 | if (IS_QLA81XX(ha)) { | 3749 | if (IS_QLA81XX(ha)) { |
3743 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; | 3750 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; |
3744 | mcp->in_mb |= MBX_1; | 3751 | mcp->in_mb |= MBX_1; |
3745 | } else if (IS_QLA83XX(ha)) { | 3752 | } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
3746 | mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; | 3753 | mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; |
3747 | mcp->in_mb |= MBX_1; | 3754 | mcp->in_mb |= MBX_1; |
3748 | /* debug q create issue in SR-IOV */ | 3755 | /* debug q create issue in SR-IOV */ |
@@ -3809,7 +3816,8 @@ qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size) | |||
3809 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc, | 3816 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc, |
3810 | "Entered %s.\n", __func__); | 3817 | "Entered %s.\n", __func__); |
3811 | 3818 | ||
3812 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) | 3819 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && |
3820 | !IS_QLA27XX(vha->hw)) | ||
3813 | return QLA_FUNCTION_FAILED; | 3821 | return QLA_FUNCTION_FAILED; |
3814 | 3822 | ||
3815 | mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; | 3823 | mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; |
@@ -3840,7 +3848,8 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable) | |||
3840 | mbx_cmd_t mc; | 3848 | mbx_cmd_t mc; |
3841 | mbx_cmd_t *mcp = &mc; | 3849 | mbx_cmd_t *mcp = &mc; |
3842 | 3850 | ||
3843 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) | 3851 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && |
3852 | !IS_QLA27XX(vha->hw)) | ||
3844 | return QLA_FUNCTION_FAILED; | 3853 | return QLA_FUNCTION_FAILED; |
3845 | 3854 | ||
3846 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, | 3855 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, |
@@ -3874,7 +3883,8 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) | |||
3874 | mbx_cmd_t mc; | 3883 | mbx_cmd_t mc; |
3875 | mbx_cmd_t *mcp = &mc; | 3884 | mbx_cmd_t *mcp = &mc; |
3876 | 3885 | ||
3877 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) | 3886 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && |
3887 | !IS_QLA27XX(vha->hw)) | ||
3878 | return QLA_FUNCTION_FAILED; | 3888 | return QLA_FUNCTION_FAILED; |
3879 | 3889 | ||
3880 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, | 3890 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, |
@@ -4545,7 +4555,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha) | |||
4545 | mcp->mb[1] = 0; | 4555 | mcp->mb[1] = 0; |
4546 | mcp->out_mb = MBX_1|MBX_0; | 4556 | mcp->out_mb = MBX_1|MBX_0; |
4547 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 4557 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
4548 | if (IS_QLA83XX(ha)) | 4558 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
4549 | mcp->in_mb |= MBX_3; | 4559 | mcp->in_mb |= MBX_3; |
4550 | mcp->tov = MBX_TOV_SECONDS; | 4560 | mcp->tov = MBX_TOV_SECONDS; |
4551 | mcp->flags = 0; | 4561 | mcp->flags = 0; |
@@ -4574,7 +4584,8 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) | |||
4574 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, | 4584 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, |
4575 | "Entered %s.\n", __func__); | 4585 | "Entered %s.\n", __func__); |
4576 | 4586 | ||
4577 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha)) | 4587 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) && |
4588 | !IS_QLA27XX(ha)) | ||
4578 | return QLA_FUNCTION_FAILED; | 4589 | return QLA_FUNCTION_FAILED; |
4579 | mcp->mb[0] = MBC_GET_PORT_CONFIG; | 4590 | mcp->mb[0] = MBC_GET_PORT_CONFIG; |
4580 | mcp->out_mb = MBX_0; | 4591 | mcp->out_mb = MBX_0; |
@@ -5070,7 +5081,7 @@ qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) | |||
5070 | mbx_cmd_t mc; | 5081 | mbx_cmd_t mc; |
5071 | mbx_cmd_t *mcp = &mc; | 5082 | mbx_cmd_t *mcp = &mc; |
5072 | 5083 | ||
5073 | if (!IS_QLA83XX(ha)) | 5084 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) |
5074 | return QLA_FUNCTION_FAILED; | 5085 | return QLA_FUNCTION_FAILED; |
5075 | 5086 | ||
5076 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, | 5087 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, |
@@ -5145,7 +5156,7 @@ qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data) | |||
5145 | struct qla_hw_data *ha = vha->hw; | 5156 | struct qla_hw_data *ha = vha->hw; |
5146 | unsigned long retry_max_time = jiffies + (2 * HZ); | 5157 | unsigned long retry_max_time = jiffies + (2 * HZ); |
5147 | 5158 | ||
5148 | if (!IS_QLA83XX(ha)) | 5159 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) |
5149 | return QLA_FUNCTION_FAILED; | 5160 | return QLA_FUNCTION_FAILED; |
5150 | 5161 | ||
5151 | ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__); | 5162 | ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__); |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index a72df701fb38..f0a852257f99 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -630,7 +630,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, | |||
630 | struct req_que *req = NULL; | 630 | struct req_que *req = NULL; |
631 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | 631 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
632 | uint16_t que_id = 0; | 632 | uint16_t que_id = 0; |
633 | device_reg_t __iomem *reg; | 633 | device_reg_t *reg; |
634 | uint32_t cnt; | 634 | uint32_t cnt; |
635 | 635 | ||
636 | req = kzalloc(sizeof(struct req_que), GFP_KERNEL); | 636 | req = kzalloc(sizeof(struct req_que), GFP_KERNEL); |
@@ -754,7 +754,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, | |||
754 | struct rsp_que *rsp = NULL; | 754 | struct rsp_que *rsp = NULL; |
755 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | 755 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
756 | uint16_t que_id = 0; | 756 | uint16_t que_id = 0; |
757 | device_reg_t __iomem *reg; | 757 | device_reg_t *reg; |
758 | 758 | ||
759 | rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL); | 759 | rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL); |
760 | if (rsp == NULL) { | 760 | if (rsp == NULL) { |
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index ed44ec68c04d..a9b5cf4c710d 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c | |||
@@ -40,7 +40,7 @@ qlafx00_mailbox_command(scsi_qla_host_t *vha, struct mbx_cmd_32 *mcp) | |||
40 | { | 40 | { |
41 | int rval; | 41 | int rval; |
42 | unsigned long flags = 0; | 42 | unsigned long flags = 0; |
43 | device_reg_t __iomem *reg; | 43 | device_reg_t *reg; |
44 | uint8_t abort_active; | 44 | uint8_t abort_active; |
45 | uint8_t io_lock_on; | 45 | uint8_t io_lock_on; |
46 | uint16_t command = 0; | 46 | uint16_t command = 0; |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 1e6ba4a369e2..26326f336c59 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -1664,10 +1664,10 @@ qla82xx_iospace_config(struct qla_hw_data *ha) | |||
1664 | /* Mapping of IO base pointer */ | 1664 | /* Mapping of IO base pointer */ |
1665 | if (IS_QLA8044(ha)) { | 1665 | if (IS_QLA8044(ha)) { |
1666 | ha->iobase = | 1666 | ha->iobase = |
1667 | (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase); | 1667 | (device_reg_t *)((uint8_t *)ha->nx_pcibase); |
1668 | } else if (IS_QLA82XX(ha)) { | 1668 | } else if (IS_QLA82XX(ha)) { |
1669 | ha->iobase = | 1669 | ha->iobase = |
1670 | (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase + | 1670 | (device_reg_t *)((uint8_t *)ha->nx_pcibase + |
1671 | 0xbc000 + (ha->pdev->devfn << 11)); | 1671 | 0xbc000 + (ha->pdev->devfn << 11)); |
1672 | } | 1672 | } |
1673 | 1673 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 925d45c9bee0..c0c95c180188 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2102,6 +2102,44 @@ static struct isp_operations qlafx00_isp_ops = { | |||
2102 | .initialize_adapter = qlafx00_initialize_adapter, | 2102 | .initialize_adapter = qlafx00_initialize_adapter, |
2103 | }; | 2103 | }; |
2104 | 2104 | ||
2105 | static struct isp_operations qla27xx_isp_ops = { | ||
2106 | .pci_config = qla25xx_pci_config, | ||
2107 | .reset_chip = qla24xx_reset_chip, | ||
2108 | .chip_diag = qla24xx_chip_diag, | ||
2109 | .config_rings = qla24xx_config_rings, | ||
2110 | .reset_adapter = qla24xx_reset_adapter, | ||
2111 | .nvram_config = qla81xx_nvram_config, | ||
2112 | .update_fw_options = qla81xx_update_fw_options, | ||
2113 | .load_risc = qla81xx_load_risc, | ||
2114 | .pci_info_str = qla24xx_pci_info_str, | ||
2115 | .fw_version_str = qla24xx_fw_version_str, | ||
2116 | .intr_handler = qla24xx_intr_handler, | ||
2117 | .enable_intrs = qla24xx_enable_intrs, | ||
2118 | .disable_intrs = qla24xx_disable_intrs, | ||
2119 | .abort_command = qla24xx_abort_command, | ||
2120 | .target_reset = qla24xx_abort_target, | ||
2121 | .lun_reset = qla24xx_lun_reset, | ||
2122 | .fabric_login = qla24xx_login_fabric, | ||
2123 | .fabric_logout = qla24xx_fabric_logout, | ||
2124 | .calc_req_entries = NULL, | ||
2125 | .build_iocbs = NULL, | ||
2126 | .prep_ms_iocb = qla24xx_prep_ms_iocb, | ||
2127 | .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, | ||
2128 | .read_nvram = NULL, | ||
2129 | .write_nvram = NULL, | ||
2130 | .fw_dump = qla27xx_fwdump, | ||
2131 | .beacon_on = qla24xx_beacon_on, | ||
2132 | .beacon_off = qla24xx_beacon_off, | ||
2133 | .beacon_blink = qla83xx_beacon_blink, | ||
2134 | .read_optrom = qla25xx_read_optrom_data, | ||
2135 | .write_optrom = qla24xx_write_optrom_data, | ||
2136 | .get_flash_version = qla24xx_get_flash_version, | ||
2137 | .start_scsi = qla24xx_dif_start_scsi, | ||
2138 | .abort_isp = qla2x00_abort_isp, | ||
2139 | .iospace_config = qla83xx_iospace_config, | ||
2140 | .initialize_adapter = qla2x00_initialize_adapter, | ||
2141 | }; | ||
2142 | |||
2105 | static inline void | 2143 | static inline void |
2106 | qla2x00_set_isp_flags(struct qla_hw_data *ha) | 2144 | qla2x00_set_isp_flags(struct qla_hw_data *ha) |
2107 | { | 2145 | { |
@@ -2223,21 +2261,29 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) | |||
2223 | case PCI_DEVICE_ID_QLOGIC_ISPF001: | 2261 | case PCI_DEVICE_ID_QLOGIC_ISPF001: |
2224 | ha->device_type |= DT_ISPFX00; | 2262 | ha->device_type |= DT_ISPFX00; |
2225 | break; | 2263 | break; |
2264 | case PCI_DEVICE_ID_QLOGIC_ISP2071: | ||
2265 | ha->device_type |= DT_ISP2071; | ||
2266 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
2267 | ha->device_type |= DT_FWI2; | ||
2268 | ha->device_type |= DT_IIDMA; | ||
2269 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
2270 | break; | ||
2226 | } | 2271 | } |
2227 | 2272 | ||
2228 | if (IS_QLA82XX(ha)) | 2273 | if (IS_QLA82XX(ha)) |
2229 | ha->port_no = !(ha->portnum & 1); | 2274 | ha->port_no = !(ha->portnum & 1); |
2230 | else | 2275 | else { |
2231 | /* Get adapter physical port no from interrupt pin register. */ | 2276 | /* Get adapter physical port no from interrupt pin register. */ |
2232 | pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); | 2277 | pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); |
2278 | if (IS_QLA27XX(ha)) | ||
2279 | ha->port_no--; | ||
2280 | else | ||
2281 | ha->port_no = !(ha->port_no & 1); | ||
2282 | } | ||
2233 | 2283 | ||
2234 | if (ha->port_no & 1) | ||
2235 | ha->flags.port0 = 1; | ||
2236 | else | ||
2237 | ha->flags.port0 = 0; | ||
2238 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x000b, | 2284 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x000b, |
2239 | "device_type=0x%x port=%d fw_srisc_address=0x%x.\n", | 2285 | "device_type=0x%x port=%d fw_srisc_address=0x%x.\n", |
2240 | ha->device_type, ha->flags.port0, ha->fw_srisc_address); | 2286 | ha->device_type, ha->port_no, ha->fw_srisc_address); |
2241 | } | 2287 | } |
2242 | 2288 | ||
2243 | static void | 2289 | static void |
@@ -2297,7 +2343,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2297 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 || | 2343 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 || |
2298 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 || | 2344 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 || |
2299 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 || | 2345 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 || |
2300 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044) { | 2346 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || |
2347 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071) { | ||
2301 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 2348 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
2302 | mem_only = 1; | 2349 | mem_only = 1; |
2303 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, | 2350 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, |
@@ -2341,7 +2388,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2341 | 2388 | ||
2342 | /* Set EEH reset type to fundamental if required by hba */ | 2389 | /* Set EEH reset type to fundamental if required by hba */ |
2343 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || | 2390 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || |
2344 | IS_QLA83XX(ha)) | 2391 | IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
2345 | pdev->needs_freset = 1; | 2392 | pdev->needs_freset = 1; |
2346 | 2393 | ||
2347 | ha->prev_topology = 0; | 2394 | ha->prev_topology = 0; |
@@ -2497,6 +2544,22 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2497 | ha->mr.fw_hbt_en = 1; | 2544 | ha->mr.fw_hbt_en = 1; |
2498 | ha->mr.host_info_resend = false; | 2545 | ha->mr.host_info_resend = false; |
2499 | ha->mr.hinfo_resend_timer_tick = QLAFX00_HINFO_RESEND_INTERVAL; | 2546 | ha->mr.hinfo_resend_timer_tick = QLAFX00_HINFO_RESEND_INTERVAL; |
2547 | } else if (IS_QLA27XX(ha)) { | ||
2548 | ha->portnum = PCI_FUNC(ha->pdev->devfn); | ||
2549 | ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; | ||
2550 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | ||
2551 | req_length = REQUEST_ENTRY_CNT_24XX; | ||
2552 | rsp_length = RESPONSE_ENTRY_CNT_2300; | ||
2553 | ha->max_loop_id = SNS_LAST_LOOP_ID_2300; | ||
2554 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); | ||
2555 | ha->gid_list_info_size = 8; | ||
2556 | ha->optrom_size = OPTROM_SIZE_83XX; | ||
2557 | ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; | ||
2558 | ha->isp_ops = &qla27xx_isp_ops; | ||
2559 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX; | ||
2560 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX; | ||
2561 | ha->nvram_conf_off = ~0; | ||
2562 | ha->nvram_data_off = ~0; | ||
2500 | } | 2563 | } |
2501 | 2564 | ||
2502 | ql_dbg_pci(ql_dbg_init, pdev, 0x001e, | 2565 | ql_dbg_pci(ql_dbg_init, pdev, 0x001e, |
@@ -2637,7 +2700,7 @@ que_init: | |||
2637 | req->req_q_out = &ha->iobase->isp24.req_q_out; | 2700 | req->req_q_out = &ha->iobase->isp24.req_q_out; |
2638 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; | 2701 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; |
2639 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; | 2702 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; |
2640 | if (ha->mqenable || IS_QLA83XX(ha)) { | 2703 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
2641 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; | 2704 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; |
2642 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; | 2705 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; |
2643 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; | 2706 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; |
@@ -2888,9 +2951,9 @@ probe_hw_failed: | |||
2888 | iospace_config_failed: | 2951 | iospace_config_failed: |
2889 | if (IS_P3P_TYPE(ha)) { | 2952 | if (IS_P3P_TYPE(ha)) { |
2890 | if (!ha->nx_pcibase) | 2953 | if (!ha->nx_pcibase) |
2891 | iounmap((device_reg_t __iomem *)ha->nx_pcibase); | 2954 | iounmap((device_reg_t *)ha->nx_pcibase); |
2892 | if (!ql2xdbwr) | 2955 | if (!ql2xdbwr) |
2893 | iounmap((device_reg_t __iomem *)ha->nxdb_wr_ptr); | 2956 | iounmap((device_reg_t *)ha->nxdb_wr_ptr); |
2894 | } else { | 2957 | } else { |
2895 | if (ha->iobase) | 2958 | if (ha->iobase) |
2896 | iounmap(ha->iobase); | 2959 | iounmap(ha->iobase); |
@@ -3021,9 +3084,9 @@ qla2x00_unmap_iobases(struct qla_hw_data *ha) | |||
3021 | { | 3084 | { |
3022 | if (IS_QLA82XX(ha)) { | 3085 | if (IS_QLA82XX(ha)) { |
3023 | 3086 | ||
3024 | iounmap((device_reg_t __iomem *)ha->nx_pcibase); | 3087 | iounmap((device_reg_t *)ha->nx_pcibase); |
3025 | if (!ql2xdbwr) | 3088 | if (!ql2xdbwr) |
3026 | iounmap((device_reg_t __iomem *)ha->nxdb_wr_ptr); | 3089 | iounmap((device_reg_t *)ha->nxdb_wr_ptr); |
3027 | } else { | 3090 | } else { |
3028 | if (ha->iobase) | 3091 | if (ha->iobase) |
3029 | iounmap(ha->iobase); | 3092 | iounmap(ha->iobase); |
@@ -3034,7 +3097,7 @@ qla2x00_unmap_iobases(struct qla_hw_data *ha) | |||
3034 | if (ha->mqiobase) | 3097 | if (ha->mqiobase) |
3035 | iounmap(ha->mqiobase); | 3098 | iounmap(ha->mqiobase); |
3036 | 3099 | ||
3037 | if (IS_QLA83XX(ha) && ha->msixbase) | 3100 | if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && ha->msixbase) |
3038 | iounmap(ha->msixbase); | 3101 | iounmap(ha->msixbase); |
3039 | } | 3102 | } |
3040 | } | 3103 | } |
@@ -3448,7 +3511,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, | |||
3448 | ha->npiv_info = NULL; | 3511 | ha->npiv_info = NULL; |
3449 | 3512 | ||
3450 | /* Get consistent memory allocated for EX-INIT-CB. */ | 3513 | /* Get consistent memory allocated for EX-INIT-CB. */ |
3451 | if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)) { | 3514 | if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { |
3452 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | 3515 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
3453 | &ha->ex_init_cb_dma); | 3516 | &ha->ex_init_cb_dma); |
3454 | if (!ha->ex_init_cb) | 3517 | if (!ha->ex_init_cb) |
@@ -3563,22 +3626,28 @@ static void | |||
3563 | qla2x00_free_fw_dump(struct qla_hw_data *ha) | 3626 | qla2x00_free_fw_dump(struct qla_hw_data *ha) |
3564 | { | 3627 | { |
3565 | if (ha->fce) | 3628 | if (ha->fce) |
3566 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, | 3629 | dma_free_coherent(&ha->pdev->dev, |
3567 | ha->fce_dma); | 3630 | FCE_SIZE, ha->fce, ha->fce_dma); |
3568 | 3631 | ||
3569 | if (ha->fw_dump) { | 3632 | if (ha->eft) |
3570 | if (ha->eft) | 3633 | dma_free_coherent(&ha->pdev->dev, |
3571 | dma_free_coherent(&ha->pdev->dev, | 3634 | EFT_SIZE, ha->eft, ha->eft_dma); |
3572 | ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); | 3635 | |
3636 | if (ha->fw_dump) | ||
3573 | vfree(ha->fw_dump); | 3637 | vfree(ha->fw_dump); |
3574 | } | 3638 | if (ha->fw_dump_template) |
3639 | vfree(ha->fw_dump_template); | ||
3640 | |||
3575 | ha->fce = NULL; | 3641 | ha->fce = NULL; |
3576 | ha->fce_dma = 0; | 3642 | ha->fce_dma = 0; |
3577 | ha->eft = NULL; | 3643 | ha->eft = NULL; |
3578 | ha->eft_dma = 0; | 3644 | ha->eft_dma = 0; |
3579 | ha->fw_dump = NULL; | ||
3580 | ha->fw_dumped = 0; | 3645 | ha->fw_dumped = 0; |
3581 | ha->fw_dump_reading = 0; | 3646 | ha->fw_dump_reading = 0; |
3647 | ha->fw_dump = NULL; | ||
3648 | ha->fw_dump_len = 0; | ||
3649 | ha->fw_dump_template = NULL; | ||
3650 | ha->fw_dump_template_len = 0; | ||
3582 | } | 3651 | } |
3583 | 3652 | ||
3584 | /* | 3653 | /* |
@@ -5243,7 +5312,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
5243 | 5312 | ||
5244 | /* Firmware interface routines. */ | 5313 | /* Firmware interface routines. */ |
5245 | 5314 | ||
5246 | #define FW_BLOBS 10 | 5315 | #define FW_BLOBS 11 |
5247 | #define FW_ISP21XX 0 | 5316 | #define FW_ISP21XX 0 |
5248 | #define FW_ISP22XX 1 | 5317 | #define FW_ISP22XX 1 |
5249 | #define FW_ISP2300 2 | 5318 | #define FW_ISP2300 2 |
@@ -5254,6 +5323,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
5254 | #define FW_ISP82XX 7 | 5323 | #define FW_ISP82XX 7 |
5255 | #define FW_ISP2031 8 | 5324 | #define FW_ISP2031 8 |
5256 | #define FW_ISP8031 9 | 5325 | #define FW_ISP8031 9 |
5326 | #define FW_ISP2071 10 | ||
5257 | 5327 | ||
5258 | #define FW_FILE_ISP21XX "ql2100_fw.bin" | 5328 | #define FW_FILE_ISP21XX "ql2100_fw.bin" |
5259 | #define FW_FILE_ISP22XX "ql2200_fw.bin" | 5329 | #define FW_FILE_ISP22XX "ql2200_fw.bin" |
@@ -5265,6 +5335,8 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
5265 | #define FW_FILE_ISP82XX "ql8200_fw.bin" | 5335 | #define FW_FILE_ISP82XX "ql8200_fw.bin" |
5266 | #define FW_FILE_ISP2031 "ql2600_fw.bin" | 5336 | #define FW_FILE_ISP2031 "ql2600_fw.bin" |
5267 | #define FW_FILE_ISP8031 "ql8300_fw.bin" | 5337 | #define FW_FILE_ISP8031 "ql8300_fw.bin" |
5338 | #define FW_FILE_ISP2071 "ql2700_fw.bin" | ||
5339 | |||
5268 | 5340 | ||
5269 | static DEFINE_MUTEX(qla_fw_lock); | 5341 | static DEFINE_MUTEX(qla_fw_lock); |
5270 | 5342 | ||
@@ -5279,6 +5351,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | |||
5279 | { .name = FW_FILE_ISP82XX, }, | 5351 | { .name = FW_FILE_ISP82XX, }, |
5280 | { .name = FW_FILE_ISP2031, }, | 5352 | { .name = FW_FILE_ISP2031, }, |
5281 | { .name = FW_FILE_ISP8031, }, | 5353 | { .name = FW_FILE_ISP8031, }, |
5354 | { .name = FW_FILE_ISP2071, }, | ||
5282 | }; | 5355 | }; |
5283 | 5356 | ||
5284 | struct fw_blob * | 5357 | struct fw_blob * |
@@ -5307,6 +5380,8 @@ qla2x00_request_firmware(scsi_qla_host_t *vha) | |||
5307 | blob = &qla_fw_blobs[FW_ISP2031]; | 5380 | blob = &qla_fw_blobs[FW_ISP2031]; |
5308 | } else if (IS_QLA8031(ha)) { | 5381 | } else if (IS_QLA8031(ha)) { |
5309 | blob = &qla_fw_blobs[FW_ISP8031]; | 5382 | blob = &qla_fw_blobs[FW_ISP8031]; |
5383 | } else if (IS_QLA2071(ha)) { | ||
5384 | blob = &qla_fw_blobs[FW_ISP2071]; | ||
5310 | } else { | 5385 | } else { |
5311 | return NULL; | 5386 | return NULL; |
5312 | } | 5387 | } |
@@ -5636,6 +5711,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
5636 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) }, | 5711 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) }, |
5637 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) }, | 5712 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) }, |
5638 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) }, | 5713 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) }, |
5714 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, | ||
5639 | { 0 }, | 5715 | { 0 }, |
5640 | }; | 5716 | }; |
5641 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 5717 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index bd56cde795fc..f28123e8ed65 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -568,7 +568,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) | |||
568 | else if (IS_P3P_TYPE(ha)) { | 568 | else if (IS_P3P_TYPE(ha)) { |
569 | *start = FA_FLASH_LAYOUT_ADDR_82; | 569 | *start = FA_FLASH_LAYOUT_ADDR_82; |
570 | goto end; | 570 | goto end; |
571 | } else if (IS_QLA83XX(ha)) { | 571 | } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
572 | *start = FA_FLASH_LAYOUT_ADDR_83; | 572 | *start = FA_FLASH_LAYOUT_ADDR_83; |
573 | goto end; | 573 | goto end; |
574 | } | 574 | } |
@@ -682,7 +682,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
682 | /* Assign FCP prio region since older adapters may not have FLT, or | 682 | /* Assign FCP prio region since older adapters may not have FLT, or |
683 | FCP prio region in it's FLT. | 683 | FCP prio region in it's FLT. |
684 | */ | 684 | */ |
685 | ha->flt_region_fcp_prio = ha->flags.port0 ? | 685 | ha->flt_region_fcp_prio = (ha->port_no == 0) ? |
686 | fcp_prio_cfg0[def] : fcp_prio_cfg1[def]; | 686 | fcp_prio_cfg0[def] : fcp_prio_cfg1[def]; |
687 | 687 | ||
688 | ha->flt_region_flt = flt_addr; | 688 | ha->flt_region_flt = flt_addr; |
@@ -743,47 +743,71 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
743 | ha->flt_region_vpd_nvram = start; | 743 | ha->flt_region_vpd_nvram = start; |
744 | if (IS_P3P_TYPE(ha)) | 744 | if (IS_P3P_TYPE(ha)) |
745 | break; | 745 | break; |
746 | if (ha->flags.port0) | 746 | if (ha->port_no == 0) |
747 | ha->flt_region_vpd = start; | 747 | ha->flt_region_vpd = start; |
748 | break; | 748 | break; |
749 | case FLT_REG_VPD_1: | 749 | case FLT_REG_VPD_1: |
750 | if (IS_P3P_TYPE(ha) || IS_QLA8031(ha)) | 750 | if (IS_P3P_TYPE(ha) || IS_QLA8031(ha)) |
751 | break; | 751 | break; |
752 | if (!ha->flags.port0) | 752 | if (ha->port_no == 1) |
753 | ha->flt_region_vpd = start; | ||
754 | break; | ||
755 | case FLT_REG_VPD_2: | ||
756 | if (!IS_QLA27XX(ha)) | ||
757 | break; | ||
758 | if (ha->port_no == 2) | ||
759 | ha->flt_region_vpd = start; | ||
760 | break; | ||
761 | case FLT_REG_VPD_3: | ||
762 | if (!IS_QLA27XX(ha)) | ||
763 | break; | ||
764 | if (ha->port_no == 3) | ||
753 | ha->flt_region_vpd = start; | 765 | ha->flt_region_vpd = start; |
754 | break; | 766 | break; |
755 | case FLT_REG_NVRAM_0: | 767 | case FLT_REG_NVRAM_0: |
756 | if (IS_QLA8031(ha)) | 768 | if (IS_QLA8031(ha)) |
757 | break; | 769 | break; |
758 | if (ha->flags.port0) | 770 | if (ha->port_no == 0) |
759 | ha->flt_region_nvram = start; | 771 | ha->flt_region_nvram = start; |
760 | break; | 772 | break; |
761 | case FLT_REG_NVRAM_1: | 773 | case FLT_REG_NVRAM_1: |
762 | if (IS_QLA8031(ha)) | 774 | if (IS_QLA8031(ha)) |
763 | break; | 775 | break; |
764 | if (!ha->flags.port0) | 776 | if (ha->port_no == 1) |
777 | ha->flt_region_nvram = start; | ||
778 | break; | ||
779 | case FLT_REG_NVRAM_2: | ||
780 | if (!IS_QLA27XX(ha)) | ||
781 | break; | ||
782 | if (ha->port_no == 2) | ||
783 | ha->flt_region_nvram = start; | ||
784 | break; | ||
785 | case FLT_REG_NVRAM_3: | ||
786 | if (!IS_QLA27XX(ha)) | ||
787 | break; | ||
788 | if (ha->port_no == 3) | ||
765 | ha->flt_region_nvram = start; | 789 | ha->flt_region_nvram = start; |
766 | break; | 790 | break; |
767 | case FLT_REG_FDT: | 791 | case FLT_REG_FDT: |
768 | ha->flt_region_fdt = start; | 792 | ha->flt_region_fdt = start; |
769 | break; | 793 | break; |
770 | case FLT_REG_NPIV_CONF_0: | 794 | case FLT_REG_NPIV_CONF_0: |
771 | if (ha->flags.port0) | 795 | if (ha->port_no == 0) |
772 | ha->flt_region_npiv_conf = start; | 796 | ha->flt_region_npiv_conf = start; |
773 | break; | 797 | break; |
774 | case FLT_REG_NPIV_CONF_1: | 798 | case FLT_REG_NPIV_CONF_1: |
775 | if (!ha->flags.port0) | 799 | if (ha->port_no == 1) |
776 | ha->flt_region_npiv_conf = start; | 800 | ha->flt_region_npiv_conf = start; |
777 | break; | 801 | break; |
778 | case FLT_REG_GOLD_FW: | 802 | case FLT_REG_GOLD_FW: |
779 | ha->flt_region_gold_fw = start; | 803 | ha->flt_region_gold_fw = start; |
780 | break; | 804 | break; |
781 | case FLT_REG_FCP_PRIO_0: | 805 | case FLT_REG_FCP_PRIO_0: |
782 | if (ha->flags.port0) | 806 | if (ha->port_no == 0) |
783 | ha->flt_region_fcp_prio = start; | 807 | ha->flt_region_fcp_prio = start; |
784 | break; | 808 | break; |
785 | case FLT_REG_FCP_PRIO_1: | 809 | case FLT_REG_FCP_PRIO_1: |
786 | if (!ha->flags.port0) | 810 | if (ha->port_no == 1) |
787 | ha->flt_region_fcp_prio = start; | 811 | ha->flt_region_fcp_prio = start; |
788 | break; | 812 | break; |
789 | case FLT_REG_BOOT_CODE_82XX: | 813 | case FLT_REG_BOOT_CODE_82XX: |
@@ -813,13 +837,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
813 | case FLT_REG_FCOE_NVRAM_0: | 837 | case FLT_REG_FCOE_NVRAM_0: |
814 | if (!(IS_QLA8031(ha) || IS_QLA8044(ha))) | 838 | if (!(IS_QLA8031(ha) || IS_QLA8044(ha))) |
815 | break; | 839 | break; |
816 | if (ha->flags.port0) | 840 | if (ha->port_no == 0) |
817 | ha->flt_region_nvram = start; | 841 | ha->flt_region_nvram = start; |
818 | break; | 842 | break; |
819 | case FLT_REG_FCOE_NVRAM_1: | 843 | case FLT_REG_FCOE_NVRAM_1: |
820 | if (!(IS_QLA8031(ha) || IS_QLA8044(ha))) | 844 | if (!(IS_QLA8031(ha) || IS_QLA8044(ha))) |
821 | break; | 845 | break; |
822 | if (!ha->flags.port0) | 846 | if (ha->port_no == 1) |
823 | ha->flt_region_nvram = start; | 847 | ha->flt_region_nvram = start; |
824 | break; | 848 | break; |
825 | } | 849 | } |
@@ -832,12 +856,12 @@ no_flash_data: | |||
832 | ha->flt_region_fw = def_fw[def]; | 856 | ha->flt_region_fw = def_fw[def]; |
833 | ha->flt_region_boot = def_boot[def]; | 857 | ha->flt_region_boot = def_boot[def]; |
834 | ha->flt_region_vpd_nvram = def_vpd_nvram[def]; | 858 | ha->flt_region_vpd_nvram = def_vpd_nvram[def]; |
835 | ha->flt_region_vpd = ha->flags.port0 ? | 859 | ha->flt_region_vpd = (ha->port_no == 0) ? |
836 | def_vpd0[def] : def_vpd1[def]; | 860 | def_vpd0[def] : def_vpd1[def]; |
837 | ha->flt_region_nvram = ha->flags.port0 ? | 861 | ha->flt_region_nvram = (ha->port_no == 0) ? |
838 | def_nvram0[def] : def_nvram1[def]; | 862 | def_nvram0[def] : def_nvram1[def]; |
839 | ha->flt_region_fdt = def_fdt[def]; | 863 | ha->flt_region_fdt = def_fdt[def]; |
840 | ha->flt_region_npiv_conf = ha->flags.port0 ? | 864 | ha->flt_region_npiv_conf = (ha->port_no == 0) ? |
841 | def_npiv_conf0[def] : def_npiv_conf1[def]; | 865 | def_npiv_conf0[def] : def_npiv_conf1[def]; |
842 | done: | 866 | done: |
843 | ql_dbg(ql_dbg_init, vha, 0x004a, | 867 | ql_dbg(ql_dbg_init, vha, 0x004a, |
@@ -989,7 +1013,7 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha) | |||
989 | struct qla_hw_data *ha = vha->hw; | 1013 | struct qla_hw_data *ha = vha->hw; |
990 | 1014 | ||
991 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && | 1015 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && |
992 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha)) | 1016 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha)) |
993 | return QLA_SUCCESS; | 1017 | return QLA_SUCCESS; |
994 | 1018 | ||
995 | ret = qla2xxx_find_flt_start(vha, &flt_addr); | 1019 | ret = qla2xxx_find_flt_start(vha, &flt_addr); |
@@ -1192,7 +1216,8 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
1192 | struct qla_hw_data *ha = vha->hw; | 1216 | struct qla_hw_data *ha = vha->hw; |
1193 | 1217 | ||
1194 | /* Prepare burst-capable write on supported ISPs. */ | 1218 | /* Prepare burst-capable write on supported ISPs. */ |
1195 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha)) && | 1219 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || |
1220 | IS_QLA27XX(ha)) && | ||
1196 | !(faddr & 0xfff) && dwords > OPTROM_BURST_DWORDS) { | 1221 | !(faddr & 0xfff) && dwords > OPTROM_BURST_DWORDS) { |
1197 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 1222 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, |
1198 | &optrom_dma, GFP_KERNEL); | 1223 | &optrom_dma, GFP_KERNEL); |
@@ -1675,7 +1700,7 @@ qla83xx_select_led_port(struct qla_hw_data *ha) | |||
1675 | if (!IS_QLA83XX(ha)) | 1700 | if (!IS_QLA83XX(ha)) |
1676 | goto out; | 1701 | goto out; |
1677 | 1702 | ||
1678 | if (ha->flags.port0) | 1703 | if (ha->port_no == 0) |
1679 | led_select_value = QLA83XX_LED_PORT0; | 1704 | led_select_value = QLA83XX_LED_PORT0; |
1680 | else | 1705 | else |
1681 | led_select_value = QLA83XX_LED_PORT1; | 1706 | led_select_value = QLA83XX_LED_PORT1; |
@@ -2332,7 +2357,7 @@ qla2x00_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2332 | */ | 2357 | */ |
2333 | rest_addr = 0xffff; | 2358 | rest_addr = 0xffff; |
2334 | sec_mask = 0x10000; | 2359 | sec_mask = 0x10000; |
2335 | break; | 2360 | break; |
2336 | } | 2361 | } |
2337 | /* | 2362 | /* |
2338 | * ST m29w010b part - 16kb sector size | 2363 | * ST m29w010b part - 16kb sector size |
@@ -2558,7 +2583,7 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2558 | uint32_t faddr, left, burst; | 2583 | uint32_t faddr, left, burst; |
2559 | struct qla_hw_data *ha = vha->hw; | 2584 | struct qla_hw_data *ha = vha->hw; |
2560 | 2585 | ||
2561 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha)) | 2586 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA27XX(ha)) |
2562 | goto try_fast; | 2587 | goto try_fast; |
2563 | if (offset & 0xfff) | 2588 | if (offset & 0xfff) |
2564 | goto slow_read; | 2589 | goto slow_read; |
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c new file mode 100644 index 000000000000..a804e9b744bb --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_tmpl.c | |||
@@ -0,0 +1,909 @@ | |||
1 | /* | ||
2 | * QLogic Fibre Channel HBA Driver | ||
3 | * Copyright (c) 2003-2013 QLogic Corporation | ||
4 | * | ||
5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
6 | */ | ||
7 | #include "qla_def.h" | ||
8 | #include "qla_tmpl.h" | ||
9 | |||
10 | /* note default template is in big endian */ | ||
11 | static const uint32_t ql27xx_fwdt_default_template[] = { | ||
12 | 0x63000000, 0xa4000000, 0x7c050000, 0x00000000, | ||
13 | 0x30000000, 0x01000000, 0x00000000, 0xc0406eb4, | ||
14 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
15 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
16 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
17 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
18 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
19 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
20 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
21 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
22 | 0x00000000, 0x04010000, 0x14000000, 0x00000000, | ||
23 | 0x02000000, 0x44000000, 0x09010000, 0x10000000, | ||
24 | 0x00000000, 0x02000000, 0x01010000, 0x1c000000, | ||
25 | 0x00000000, 0x02000000, 0x00600000, 0x00000000, | ||
26 | 0xc0000000, 0x01010000, 0x1c000000, 0x00000000, | ||
27 | 0x02000000, 0x00600000, 0x00000000, 0xcc000000, | ||
28 | 0x01010000, 0x1c000000, 0x00000000, 0x02000000, | ||
29 | 0x10600000, 0x00000000, 0xd4000000, 0x01010000, | ||
30 | 0x1c000000, 0x00000000, 0x02000000, 0x700f0000, | ||
31 | 0x00000060, 0xf0000000, 0x00010000, 0x18000000, | ||
32 | 0x00000000, 0x02000000, 0x00700000, 0x041000c0, | ||
33 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
34 | 0x10700000, 0x041000c0, 0x00010000, 0x18000000, | ||
35 | 0x00000000, 0x02000000, 0x40700000, 0x041000c0, | ||
36 | 0x01010000, 0x1c000000, 0x00000000, 0x02000000, | ||
37 | 0x007c0000, 0x01000000, 0xc0000000, 0x00010000, | ||
38 | 0x18000000, 0x00000000, 0x02000000, 0x007c0000, | ||
39 | 0x040300c4, 0x00010000, 0x18000000, 0x00000000, | ||
40 | 0x02000000, 0x007c0000, 0x040100c0, 0x01010000, | ||
41 | 0x1c000000, 0x00000000, 0x02000000, 0x007c0000, | ||
42 | 0x00000000, 0xc0000000, 0x00010000, 0x18000000, | ||
43 | 0x00000000, 0x02000000, 0x007c0000, 0x04200000, | ||
44 | 0x0b010000, 0x18000000, 0x00000000, 0x02000000, | ||
45 | 0x0c000000, 0x00000000, 0x02010000, 0x20000000, | ||
46 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
47 | 0xf0000000, 0x000000b0, 0x02010000, 0x20000000, | ||
48 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
49 | 0xf0000000, 0x000010b0, 0x02010000, 0x20000000, | ||
50 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
51 | 0xf0000000, 0x000020b0, 0x02010000, 0x20000000, | ||
52 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
53 | 0xf0000000, 0x000030b0, 0x02010000, 0x20000000, | ||
54 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
55 | 0xf0000000, 0x000040b0, 0x02010000, 0x20000000, | ||
56 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
57 | 0xf0000000, 0x000050b0, 0x02010000, 0x20000000, | ||
58 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
59 | 0xf0000000, 0x000060b0, 0x02010000, 0x20000000, | ||
60 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
61 | 0xf0000000, 0x000070b0, 0x02010000, 0x20000000, | ||
62 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
63 | 0xf0000000, 0x000080b0, 0x02010000, 0x20000000, | ||
64 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
65 | 0xf0000000, 0x000090b0, 0x02010000, 0x20000000, | ||
66 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
67 | 0xf0000000, 0x0000a0b0, 0x00010000, 0x18000000, | ||
68 | 0x00000000, 0x02000000, 0x0a000000, 0x040100c0, | ||
69 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
70 | 0x0a000000, 0x04200080, 0x00010000, 0x18000000, | ||
71 | 0x00000000, 0x02000000, 0x00be0000, 0x041000c0, | ||
72 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
73 | 0x10be0000, 0x041000c0, 0x00010000, 0x18000000, | ||
74 | 0x00000000, 0x02000000, 0x20be0000, 0x041000c0, | ||
75 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
76 | 0x30be0000, 0x041000c0, 0x00010000, 0x18000000, | ||
77 | 0x00000000, 0x02000000, 0x00b00000, 0x041000c0, | ||
78 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
79 | 0x10b00000, 0x041000c0, 0x00010000, 0x18000000, | ||
80 | 0x00000000, 0x02000000, 0x20b00000, 0x041000c0, | ||
81 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
82 | 0x30b00000, 0x041000c0, 0x00010000, 0x18000000, | ||
83 | 0x00000000, 0x02000000, 0x00300000, 0x041000c0, | ||
84 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
85 | 0x10300000, 0x041000c0, 0x00010000, 0x18000000, | ||
86 | 0x00000000, 0x02000000, 0x20300000, 0x041000c0, | ||
87 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
88 | 0x30300000, 0x041000c0, 0x0a010000, 0x10000000, | ||
89 | 0x00000000, 0x02000000, 0x06010000, 0x1c000000, | ||
90 | 0x00000000, 0x02000000, 0x01000000, 0x00000200, | ||
91 | 0xff230200, 0x06010000, 0x1c000000, 0x00000000, | ||
92 | 0x02000000, 0x02000000, 0x00001000, 0x00000000, | ||
93 | 0x07010000, 0x18000000, 0x00000000, 0x02000000, | ||
94 | 0x00000000, 0x01000000, 0x07010000, 0x18000000, | ||
95 | 0x00000000, 0x02000000, 0x00000000, 0x02000000, | ||
96 | 0x07010000, 0x18000000, 0x00000000, 0x02000000, | ||
97 | 0x00000000, 0x03000000, 0x0d010000, 0x14000000, | ||
98 | 0x00000000, 0x02000000, 0x00000000, 0xff000000, | ||
99 | 0x10000000, 0x00000000, 0x00000080, | ||
100 | }; | ||
101 | |||
102 | static inline void __iomem * | ||
103 | qla27xx_isp_reg(struct scsi_qla_host *vha) | ||
104 | { | ||
105 | return &vha->hw->iobase->isp24; | ||
106 | } | ||
107 | |||
108 | static inline void | ||
109 | qla27xx_insert16(uint16_t value, void *buf, ulong *len) | ||
110 | { | ||
111 | if (buf) { | ||
112 | buf += *len; | ||
113 | *(__le16 *)buf = cpu_to_le16(value); | ||
114 | } | ||
115 | *len += sizeof(value); | ||
116 | } | ||
117 | |||
118 | static inline void | ||
119 | qla27xx_insert32(uint32_t value, void *buf, ulong *len) | ||
120 | { | ||
121 | if (buf) { | ||
122 | buf += *len; | ||
123 | *(__le32 *)buf = cpu_to_le32(value); | ||
124 | } | ||
125 | *len += sizeof(value); | ||
126 | } | ||
127 | |||
128 | static inline void | ||
129 | qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len) | ||
130 | { | ||
131 | ulong cnt = size; | ||
132 | |||
133 | if (buf && mem) { | ||
134 | buf += *len; | ||
135 | while (cnt >= sizeof(uint32_t)) { | ||
136 | *(__le32 *)buf = cpu_to_le32p(mem); | ||
137 | buf += sizeof(uint32_t); | ||
138 | mem += sizeof(uint32_t); | ||
139 | cnt -= sizeof(uint32_t); | ||
140 | } | ||
141 | if (cnt) | ||
142 | memcpy(buf, mem, cnt); | ||
143 | } | ||
144 | *len += size; | ||
145 | } | ||
146 | |||
147 | static inline void | ||
148 | qla27xx_read8(void *window, void *buf, ulong *len) | ||
149 | { | ||
150 | uint8_t value = ~0; | ||
151 | |||
152 | if (buf) { | ||
153 | value = RD_REG_BYTE((__iomem void *)window); | ||
154 | ql_dbg(ql_dbg_misc, NULL, 0xd011, | ||
155 | "%s: -> %x\n", __func__, value); | ||
156 | } | ||
157 | qla27xx_insert32(value, buf, len); | ||
158 | } | ||
159 | |||
160 | static inline void | ||
161 | qla27xx_read16(void *window, void *buf, ulong *len) | ||
162 | { | ||
163 | uint16_t value = ~0; | ||
164 | |||
165 | if (buf) { | ||
166 | value = RD_REG_WORD((__iomem void *)window); | ||
167 | ql_dbg(ql_dbg_misc, NULL, 0xd012, | ||
168 | "%s: -> %x\n", __func__, value); | ||
169 | } | ||
170 | qla27xx_insert32(value, buf, len); | ||
171 | } | ||
172 | |||
173 | static inline void | ||
174 | qla27xx_read32(void *window, void *buf, ulong *len) | ||
175 | { | ||
176 | uint32_t value = ~0; | ||
177 | |||
178 | if (buf) { | ||
179 | value = RD_REG_DWORD((__iomem void *)window); | ||
180 | ql_dbg(ql_dbg_misc, NULL, 0xd013, | ||
181 | "%s: -> %x\n", __func__, value); | ||
182 | } | ||
183 | qla27xx_insert32(value, buf, len); | ||
184 | } | ||
185 | |||
186 | static inline void (*qla27xx_read_vector(uint width))(void *, void *, ulong *) | ||
187 | { | ||
188 | return | ||
189 | (width == 1) ? qla27xx_read8 : | ||
190 | (width == 2) ? qla27xx_read16 : | ||
191 | qla27xx_read32; | ||
192 | } | ||
193 | |||
194 | static inline void | ||
195 | qla27xx_read_reg(__iomem struct device_reg_24xx *reg, | ||
196 | uint offset, void *buf, ulong *len) | ||
197 | { | ||
198 | void *window = (void *)reg + offset; | ||
199 | |||
200 | if (buf) { | ||
201 | ql_dbg(ql_dbg_misc, NULL, 0xd014, | ||
202 | "%s: @%x\n", __func__, offset); | ||
203 | } | ||
204 | qla27xx_insert32(offset, buf, len); | ||
205 | qla27xx_read32(window, buf, len); | ||
206 | } | ||
207 | |||
208 | static inline void | ||
209 | qla27xx_write_reg(__iomem struct device_reg_24xx *reg, | ||
210 | uint offset, uint32_t data, void *buf) | ||
211 | { | ||
212 | __iomem void *window = reg + offset; | ||
213 | |||
214 | if (buf) { | ||
215 | ql_dbg(ql_dbg_misc, NULL, 0xd015, | ||
216 | "%s: @%x <- %x\n", __func__, offset, data); | ||
217 | WRT_REG_DWORD(window, data); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static inline void | ||
222 | qla27xx_read_window(__iomem struct device_reg_24xx *reg, | ||
223 | uint32_t base, uint offset, uint count, uint width, void *buf, | ||
224 | ulong *len) | ||
225 | { | ||
226 | void *window = (void *)reg + offset; | ||
227 | void (*readn)(void *, void *, ulong *) = qla27xx_read_vector(width); | ||
228 | |||
229 | if (buf) { | ||
230 | ql_dbg(ql_dbg_misc, NULL, 0xd016, | ||
231 | "%s: base=%x offset=%x count=%x width=%x\n", | ||
232 | __func__, base, offset, count, width); | ||
233 | } | ||
234 | qla27xx_write_reg(reg, IOBASE_ADDR, base, buf); | ||
235 | while (count--) { | ||
236 | qla27xx_insert32(base, buf, len); | ||
237 | readn(window, buf, len); | ||
238 | window += width; | ||
239 | base += width; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static inline void | ||
244 | qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf) | ||
245 | { | ||
246 | if (buf) | ||
247 | ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY; | ||
248 | } | ||
249 | |||
250 | static int | ||
251 | qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha, | ||
252 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
253 | { | ||
254 | ql_dbg(ql_dbg_misc, vha, 0xd100, | ||
255 | "%s: nop [%lx]\n", __func__, *len); | ||
256 | qla27xx_skip_entry(ent, buf); | ||
257 | |||
258 | return false; | ||
259 | } | ||
260 | |||
261 | static int | ||
262 | qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha, | ||
263 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
264 | { | ||
265 | ql_dbg(ql_dbg_misc, vha, 0xd1ff, | ||
266 | "%s: end [%lx]\n", __func__, *len); | ||
267 | qla27xx_skip_entry(ent, buf); | ||
268 | |||
269 | /* terminate */ | ||
270 | return true; | ||
271 | } | ||
272 | |||
273 | static int | ||
274 | qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha, | ||
275 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
276 | { | ||
277 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
278 | |||
279 | ql_dbg(ql_dbg_misc, vha, 0xd200, | ||
280 | "%s: rdio t1 [%lx]\n", __func__, *len); | ||
281 | qla27xx_read_window(reg, ent->t256.base_addr, ent->t256.pci_offset, | ||
282 | ent->t256.reg_count, ent->t256.reg_width, buf, len); | ||
283 | |||
284 | return false; | ||
285 | } | ||
286 | |||
287 | static int | ||
288 | qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha, | ||
289 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
290 | { | ||
291 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
292 | |||
293 | ql_dbg(ql_dbg_misc, vha, 0xd201, | ||
294 | "%s: wrio t1 [%lx]\n", __func__, *len); | ||
295 | qla27xx_write_reg(reg, IOBASE_ADDR, ent->t257.base_addr, buf); | ||
296 | qla27xx_write_reg(reg, ent->t257.pci_offset, ent->t257.write_data, buf); | ||
297 | |||
298 | return false; | ||
299 | } | ||
300 | |||
301 | static int | ||
302 | qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha, | ||
303 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
304 | { | ||
305 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
306 | |||
307 | ql_dbg(ql_dbg_misc, vha, 0xd202, | ||
308 | "%s: rdio t2 [%lx]\n", __func__, *len); | ||
309 | qla27xx_write_reg(reg, ent->t258.banksel_offset, ent->t258.bank, buf); | ||
310 | qla27xx_read_window(reg, ent->t258.base_addr, ent->t258.pci_offset, | ||
311 | ent->t258.reg_count, ent->t258.reg_width, buf, len); | ||
312 | |||
313 | return false; | ||
314 | } | ||
315 | |||
316 | static int | ||
317 | qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha, | ||
318 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
319 | { | ||
320 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
321 | |||
322 | ql_dbg(ql_dbg_misc, vha, 0xd203, | ||
323 | "%s: wrio t2 [%lx]\n", __func__, *len); | ||
324 | qla27xx_write_reg(reg, IOBASE_ADDR, ent->t259.base_addr, buf); | ||
325 | qla27xx_write_reg(reg, ent->t259.banksel_offset, ent->t259.bank, buf); | ||
326 | qla27xx_write_reg(reg, ent->t259.pci_offset, ent->t259.write_data, buf); | ||
327 | |||
328 | return false; | ||
329 | } | ||
330 | |||
331 | static int | ||
332 | qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha, | ||
333 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
334 | { | ||
335 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
336 | |||
337 | ql_dbg(ql_dbg_misc, vha, 0xd204, | ||
338 | "%s: rdpci [%lx]\n", __func__, *len); | ||
339 | qla27xx_read_reg(reg, ent->t260.pci_addr, buf, len); | ||
340 | |||
341 | return false; | ||
342 | } | ||
343 | |||
344 | static int | ||
345 | qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha, | ||
346 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
347 | { | ||
348 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
349 | |||
350 | ql_dbg(ql_dbg_misc, vha, 0xd205, | ||
351 | "%s: wrpci [%lx]\n", __func__, *len); | ||
352 | qla27xx_write_reg(reg, ent->t261.pci_addr, ent->t261.write_data, buf); | ||
353 | |||
354 | return false; | ||
355 | } | ||
356 | |||
357 | static int | ||
358 | qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha, | ||
359 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
360 | { | ||
361 | ulong dwords; | ||
362 | ulong start; | ||
363 | ulong end; | ||
364 | |||
365 | ql_dbg(ql_dbg_misc, vha, 0xd206, | ||
366 | "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len); | ||
367 | start = ent->t262.start_addr; | ||
368 | end = ent->t262.end_addr; | ||
369 | |||
370 | if (ent->t262.ram_area == T262_RAM_AREA_CRITICAL_RAM) { | ||
371 | ; | ||
372 | } else if (ent->t262.ram_area == T262_RAM_AREA_EXTERNAL_RAM) { | ||
373 | end = vha->hw->fw_memory_size; | ||
374 | if (buf) | ||
375 | ent->t262.end_addr = end; | ||
376 | } else if (ent->t262.ram_area == T262_RAM_AREA_SHARED_RAM) { | ||
377 | start = vha->hw->fw_shared_ram_start; | ||
378 | end = vha->hw->fw_shared_ram_end; | ||
379 | if (buf) { | ||
380 | ent->t262.start_addr = start; | ||
381 | ent->t262.end_addr = end; | ||
382 | } | ||
383 | } else if (ent->t262.ram_area == T262_RAM_AREA_DDR_RAM) { | ||
384 | ql_dbg(ql_dbg_misc, vha, 0xd021, | ||
385 | "%s: unsupported ddr ram\n", __func__); | ||
386 | qla27xx_skip_entry(ent, buf); | ||
387 | goto done; | ||
388 | } else { | ||
389 | ql_dbg(ql_dbg_misc, vha, 0xd022, | ||
390 | "%s: unknown area %u\n", __func__, ent->t262.ram_area); | ||
391 | qla27xx_skip_entry(ent, buf); | ||
392 | goto done; | ||
393 | } | ||
394 | |||
395 | if (end < start) { | ||
396 | ql_dbg(ql_dbg_misc, vha, 0xd023, | ||
397 | "%s: bad range (start=%x end=%x)\n", __func__, | ||
398 | ent->t262.end_addr, ent->t262.start_addr); | ||
399 | qla27xx_skip_entry(ent, buf); | ||
400 | goto done; | ||
401 | } | ||
402 | |||
403 | dwords = end - start + 1; | ||
404 | if (buf) { | ||
405 | ql_dbg(ql_dbg_misc, vha, 0xd024, | ||
406 | "%s: @%lx -> (%lx dwords)\n", __func__, start, dwords); | ||
407 | buf += *len; | ||
408 | qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf); | ||
409 | } | ||
410 | *len += dwords * sizeof(uint32_t); | ||
411 | done: | ||
412 | return false; | ||
413 | } | ||
414 | |||
415 | static int | ||
416 | qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha, | ||
417 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
418 | { | ||
419 | uint count = 0; | ||
420 | uint i; | ||
421 | uint length; | ||
422 | |||
423 | ql_dbg(ql_dbg_misc, vha, 0xd207, | ||
424 | "%s: getq(%x) [%lx]\n", __func__, ent->t263.queue_type, *len); | ||
425 | if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) { | ||
426 | for (i = 0; i < vha->hw->max_req_queues; i++) { | ||
427 | struct req_que *req = vha->hw->req_q_map[i]; | ||
428 | if (req || !buf) { | ||
429 | length = req ? | ||
430 | req->length : REQUEST_ENTRY_CNT_24XX; | ||
431 | qla27xx_insert16(i, buf, len); | ||
432 | qla27xx_insert16(length, buf, len); | ||
433 | qla27xx_insertbuf(req ? req->ring : NULL, | ||
434 | length * sizeof(*req->ring), buf, len); | ||
435 | count++; | ||
436 | } | ||
437 | } | ||
438 | } else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) { | ||
439 | for (i = 0; i < vha->hw->max_rsp_queues; i++) { | ||
440 | struct rsp_que *rsp = vha->hw->rsp_q_map[i]; | ||
441 | if (rsp || !buf) { | ||
442 | length = rsp ? | ||
443 | rsp->length : RESPONSE_ENTRY_CNT_MQ; | ||
444 | qla27xx_insert16(i, buf, len); | ||
445 | qla27xx_insert16(length, buf, len); | ||
446 | qla27xx_insertbuf(rsp ? rsp->ring : NULL, | ||
447 | length * sizeof(*rsp->ring), buf, len); | ||
448 | count++; | ||
449 | } | ||
450 | } | ||
451 | } else if (ent->t263.queue_type == T263_QUEUE_TYPE_ATIO) { | ||
452 | ql_dbg(ql_dbg_misc, vha, 0xd025, | ||
453 | "%s: unsupported atio queue\n", __func__); | ||
454 | qla27xx_skip_entry(ent, buf); | ||
455 | goto done; | ||
456 | } else { | ||
457 | ql_dbg(ql_dbg_misc, vha, 0xd026, | ||
458 | "%s: unknown queue %u\n", __func__, ent->t263.queue_type); | ||
459 | qla27xx_skip_entry(ent, buf); | ||
460 | goto done; | ||
461 | } | ||
462 | |||
463 | if (buf) | ||
464 | ent->t263.num_queues = count; | ||
465 | done: | ||
466 | return false; | ||
467 | } | ||
468 | |||
469 | static int | ||
470 | qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha, | ||
471 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
472 | { | ||
473 | ql_dbg(ql_dbg_misc, vha, 0xd208, | ||
474 | "%s: getfce [%lx]\n", __func__, *len); | ||
475 | if (vha->hw->fce) { | ||
476 | if (buf) { | ||
477 | ent->t264.fce_trace_size = FCE_SIZE; | ||
478 | ent->t264.write_pointer = vha->hw->fce_wr; | ||
479 | ent->t264.base_pointer = vha->hw->fce_dma; | ||
480 | ent->t264.fce_enable_mb0 = vha->hw->fce_mb[0]; | ||
481 | ent->t264.fce_enable_mb2 = vha->hw->fce_mb[2]; | ||
482 | ent->t264.fce_enable_mb3 = vha->hw->fce_mb[3]; | ||
483 | ent->t264.fce_enable_mb4 = vha->hw->fce_mb[4]; | ||
484 | ent->t264.fce_enable_mb5 = vha->hw->fce_mb[5]; | ||
485 | ent->t264.fce_enable_mb6 = vha->hw->fce_mb[6]; | ||
486 | } | ||
487 | qla27xx_insertbuf(vha->hw->fce, FCE_SIZE, buf, len); | ||
488 | } else { | ||
489 | ql_dbg(ql_dbg_misc, vha, 0xd027, | ||
490 | "%s: missing fce\n", __func__); | ||
491 | qla27xx_skip_entry(ent, buf); | ||
492 | } | ||
493 | |||
494 | return false; | ||
495 | } | ||
496 | |||
497 | static int | ||
498 | qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha, | ||
499 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
500 | { | ||
501 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
502 | |||
503 | ql_dbg(ql_dbg_misc, vha, 0xd209, | ||
504 | "%s: pause risc [%lx]\n", __func__, *len); | ||
505 | if (buf) | ||
506 | qla24xx_pause_risc(reg); | ||
507 | |||
508 | return false; | ||
509 | } | ||
510 | |||
511 | static int | ||
512 | qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha, | ||
513 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
514 | { | ||
515 | ql_dbg(ql_dbg_misc, vha, 0xd20a, | ||
516 | "%s: reset risc [%lx]\n", __func__, *len); | ||
517 | if (buf) | ||
518 | qla24xx_soft_reset(vha->hw); | ||
519 | |||
520 | return false; | ||
521 | } | ||
522 | |||
523 | static int | ||
524 | qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha, | ||
525 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
526 | { | ||
527 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
528 | |||
529 | ql_dbg(ql_dbg_misc, vha, 0xd20b, | ||
530 | "%s: dis intr [%lx]\n", __func__, *len); | ||
531 | qla27xx_write_reg(reg, ent->t267.pci_offset, ent->t267.data, buf); | ||
532 | |||
533 | return false; | ||
534 | } | ||
535 | |||
536 | static int | ||
537 | qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha, | ||
538 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
539 | { | ||
540 | ql_dbg(ql_dbg_misc, vha, 0xd20c, | ||
541 | "%s: gethb(%x) [%lx]\n", __func__, ent->t268.buf_type, *len); | ||
542 | if (ent->t268.buf_type == T268_BUF_TYPE_EXTD_TRACE) { | ||
543 | if (vha->hw->eft) { | ||
544 | if (buf) { | ||
545 | ent->t268.buf_size = EFT_SIZE; | ||
546 | ent->t268.start_addr = vha->hw->eft_dma; | ||
547 | } | ||
548 | qla27xx_insertbuf(vha->hw->eft, EFT_SIZE, buf, len); | ||
549 | } else { | ||
550 | ql_dbg(ql_dbg_misc, vha, 0xd028, | ||
551 | "%s: missing eft\n", __func__); | ||
552 | qla27xx_skip_entry(ent, buf); | ||
553 | } | ||
554 | } else if (ent->t268.buf_type == T268_BUF_TYPE_EXCH_BUFOFF) { | ||
555 | ql_dbg(ql_dbg_misc, vha, 0xd029, | ||
556 | "%s: unsupported exchange offload buffer\n", __func__); | ||
557 | qla27xx_skip_entry(ent, buf); | ||
558 | } else if (ent->t268.buf_type == T268_BUF_TYPE_EXTD_LOGIN) { | ||
559 | ql_dbg(ql_dbg_misc, vha, 0xd02a, | ||
560 | "%s: unsupported extended login buffer\n", __func__); | ||
561 | qla27xx_skip_entry(ent, buf); | ||
562 | } else { | ||
563 | ql_dbg(ql_dbg_misc, vha, 0xd02b, | ||
564 | "%s: unknown buf %x\n", __func__, ent->t268.buf_type); | ||
565 | qla27xx_skip_entry(ent, buf); | ||
566 | } | ||
567 | |||
568 | return false; | ||
569 | } | ||
570 | |||
571 | static int | ||
572 | qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha, | ||
573 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
574 | { | ||
575 | ql_dbg(ql_dbg_misc, vha, 0xd20d, | ||
576 | "%s: scratch [%lx]\n", __func__, *len); | ||
577 | qla27xx_insert32(0xaaaaaaaa, buf, len); | ||
578 | qla27xx_insert32(0xbbbbbbbb, buf, len); | ||
579 | qla27xx_insert32(0xcccccccc, buf, len); | ||
580 | qla27xx_insert32(0xdddddddd, buf, len); | ||
581 | qla27xx_insert32(*len + sizeof(uint32_t), buf, len); | ||
582 | if (buf) | ||
583 | ent->t269.scratch_size = 5 * sizeof(uint32_t); | ||
584 | |||
585 | return false; | ||
586 | } | ||
587 | |||
588 | static int | ||
589 | qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha, | ||
590 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
591 | { | ||
592 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
593 | void *window = (void *)reg + 0xc4; | ||
594 | ulong dwords = ent->t270.count; | ||
595 | ulong addr = ent->t270.addr; | ||
596 | |||
597 | ql_dbg(ql_dbg_misc, vha, 0xd20e, | ||
598 | "%s: rdremreg [%lx]\n", __func__, *len); | ||
599 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); | ||
600 | while (dwords--) { | ||
601 | qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf); | ||
602 | qla27xx_read_reg(reg, 0xc4, buf, len); | ||
603 | qla27xx_insert32(addr, buf, len); | ||
604 | qla27xx_read32(window, buf, len); | ||
605 | addr++; | ||
606 | } | ||
607 | |||
608 | return false; | ||
609 | } | ||
610 | |||
611 | static int | ||
612 | qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha, | ||
613 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
614 | { | ||
615 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | ||
616 | ulong addr = ent->t271.addr; | ||
617 | |||
618 | ql_dbg(ql_dbg_misc, vha, 0xd20f, | ||
619 | "%s: wrremreg [%lx]\n", __func__, *len); | ||
620 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); | ||
621 | qla27xx_read_reg(reg, 0xc4, buf, len); | ||
622 | qla27xx_insert32(addr, buf, len); | ||
623 | qla27xx_write_reg(reg, 0xc0, addr, buf); | ||
624 | |||
625 | return false; | ||
626 | } | ||
627 | |||
628 | static int | ||
629 | qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha, | ||
630 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
631 | { | ||
632 | ulong dwords = ent->t272.count; | ||
633 | ulong start = ent->t272.addr; | ||
634 | |||
635 | ql_dbg(ql_dbg_misc, vha, 0xd210, | ||
636 | "%s: rdremram [%lx]\n", __func__, *len); | ||
637 | if (buf) { | ||
638 | ql_dbg(ql_dbg_misc, vha, 0xd02c, | ||
639 | "%s: @%lx -> (%lx dwords)\n", __func__, start, dwords); | ||
640 | buf += *len; | ||
641 | qla27xx_dump_mpi_ram(vha->hw, start, buf, dwords, &buf); | ||
642 | } | ||
643 | *len += dwords * sizeof(uint32_t); | ||
644 | |||
645 | return false; | ||
646 | } | ||
647 | |||
648 | static int | ||
649 | qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha, | ||
650 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
651 | { | ||
652 | ulong dwords = ent->t273.count; | ||
653 | ulong addr = ent->t273.addr; | ||
654 | uint32_t value; | ||
655 | |||
656 | ql_dbg(ql_dbg_misc, vha, 0xd211, | ||
657 | "%s: pcicfg [%lx]\n", __func__, *len); | ||
658 | while (dwords--) { | ||
659 | value = ~0; | ||
660 | if (pci_read_config_dword(vha->hw->pdev, addr, &value)) | ||
661 | ql_dbg(ql_dbg_misc, vha, 0xd02d, | ||
662 | "%s: failed pcicfg read at %lx\n", __func__, addr); | ||
663 | qla27xx_insert32(addr, buf, len); | ||
664 | qla27xx_insert32(value, buf, len); | ||
665 | addr += 4; | ||
666 | } | ||
667 | |||
668 | return false; | ||
669 | } | ||
670 | |||
671 | static int | ||
672 | qla27xx_fwdt_entry_other(struct scsi_qla_host *vha, | ||
673 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
674 | { | ||
675 | ql_dbg(ql_dbg_misc, vha, 0xd2ff, | ||
676 | "%s: type %x [%lx]\n", __func__, ent->hdr.entry_type, *len); | ||
677 | qla27xx_skip_entry(ent, buf); | ||
678 | |||
679 | return false; | ||
680 | } | ||
681 | |||
682 | struct qla27xx_fwdt_entry_call { | ||
683 | int type; | ||
684 | int (*call)( | ||
685 | struct scsi_qla_host *, | ||
686 | struct qla27xx_fwdt_entry *, | ||
687 | void *, | ||
688 | ulong *); | ||
689 | }; | ||
690 | |||
691 | static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = { | ||
692 | { ENTRY_TYPE_NOP , qla27xx_fwdt_entry_t0 } , | ||
693 | { ENTRY_TYPE_TMP_END , qla27xx_fwdt_entry_t255 } , | ||
694 | { ENTRY_TYPE_RD_IOB_T1 , qla27xx_fwdt_entry_t256 } , | ||
695 | { ENTRY_TYPE_WR_IOB_T1 , qla27xx_fwdt_entry_t257 } , | ||
696 | { ENTRY_TYPE_RD_IOB_T2 , qla27xx_fwdt_entry_t258 } , | ||
697 | { ENTRY_TYPE_WR_IOB_T2 , qla27xx_fwdt_entry_t259 } , | ||
698 | { ENTRY_TYPE_RD_PCI , qla27xx_fwdt_entry_t260 } , | ||
699 | { ENTRY_TYPE_WR_PCI , qla27xx_fwdt_entry_t261 } , | ||
700 | { ENTRY_TYPE_RD_RAM , qla27xx_fwdt_entry_t262 } , | ||
701 | { ENTRY_TYPE_GET_QUEUE , qla27xx_fwdt_entry_t263 } , | ||
702 | { ENTRY_TYPE_GET_FCE , qla27xx_fwdt_entry_t264 } , | ||
703 | { ENTRY_TYPE_PSE_RISC , qla27xx_fwdt_entry_t265 } , | ||
704 | { ENTRY_TYPE_RST_RISC , qla27xx_fwdt_entry_t266 } , | ||
705 | { ENTRY_TYPE_DIS_INTR , qla27xx_fwdt_entry_t267 } , | ||
706 | { ENTRY_TYPE_GET_HBUF , qla27xx_fwdt_entry_t268 } , | ||
707 | { ENTRY_TYPE_SCRATCH , qla27xx_fwdt_entry_t269 } , | ||
708 | { ENTRY_TYPE_RDREMREG , qla27xx_fwdt_entry_t270 } , | ||
709 | { ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } , | ||
710 | { ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } , | ||
711 | { ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } , | ||
712 | { -1 , qla27xx_fwdt_entry_other } | ||
713 | }; | ||
714 | |||
715 | static inline int (*qla27xx_find_entry(int type)) | ||
716 | (struct scsi_qla_host *, struct qla27xx_fwdt_entry *, void *, ulong *) | ||
717 | { | ||
718 | struct qla27xx_fwdt_entry_call *list = ql27xx_fwdt_entry_call_list; | ||
719 | |||
720 | while (list->type != -1 && list->type != type) | ||
721 | list++; | ||
722 | |||
723 | return list->call; | ||
724 | } | ||
725 | |||
726 | static inline void * | ||
727 | qla27xx_next_entry(void *p) | ||
728 | { | ||
729 | struct qla27xx_fwdt_entry *ent = p; | ||
730 | |||
731 | return p + ent->hdr.entry_size; | ||
732 | } | ||
733 | |||
734 | static void | ||
735 | qla27xx_walk_template(struct scsi_qla_host *vha, | ||
736 | struct qla27xx_fwdt_template *tmp, void *buf, ulong *len) | ||
737 | { | ||
738 | struct qla27xx_fwdt_entry *ent = (void *)tmp + tmp->entry_offset; | ||
739 | ulong count = tmp->entry_count; | ||
740 | |||
741 | ql_dbg(ql_dbg_misc, vha, 0xd01a, | ||
742 | "%s: entry count %lx\n", __func__, count); | ||
743 | while (count--) { | ||
744 | if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len)) | ||
745 | break; | ||
746 | ent = qla27xx_next_entry(ent); | ||
747 | } | ||
748 | ql_dbg(ql_dbg_misc, vha, 0xd01b, | ||
749 | "%s: len=%lx\n", __func__, *len); | ||
750 | } | ||
751 | |||
752 | static void | ||
753 | qla27xx_time_stamp(struct qla27xx_fwdt_template *tmp) | ||
754 | { | ||
755 | tmp->capture_timestamp = jiffies; | ||
756 | } | ||
757 | |||
758 | static void | ||
759 | qla27xx_driver_info(struct qla27xx_fwdt_template *tmp) | ||
760 | { | ||
761 | uint8_t v[] = { 0, 0, 0, 0, 0, 0 }; | ||
762 | int rval = 0; | ||
763 | |||
764 | rval = sscanf(qla2x00_version_str, "%hhu.%hhu.%hhu.%hhu.%hhu.%hhu", | ||
765 | v+0, v+1, v+2, v+3, v+4, v+5); | ||
766 | |||
767 | tmp->driver_info[0] = v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0]; | ||
768 | tmp->driver_info[1] = v[5] << 8 | v[4]; | ||
769 | tmp->driver_info[2] = 0x12345678; | ||
770 | } | ||
771 | |||
772 | static void | ||
773 | qla27xx_firmware_info(struct qla27xx_fwdt_template *tmp, | ||
774 | struct scsi_qla_host *vha) | ||
775 | { | ||
776 | tmp->firmware_version[0] = vha->hw->fw_major_version; | ||
777 | tmp->firmware_version[1] = vha->hw->fw_minor_version; | ||
778 | tmp->firmware_version[2] = vha->hw->fw_subminor_version; | ||
779 | tmp->firmware_version[3] = | ||
780 | vha->hw->fw_attributes_h << 16 | vha->hw->fw_attributes; | ||
781 | tmp->firmware_version[4] = | ||
782 | vha->hw->fw_attributes_ext[1] << 16 | vha->hw->fw_attributes_ext[0]; | ||
783 | } | ||
784 | |||
785 | static void | ||
786 | ql27xx_edit_template(struct scsi_qla_host *vha, | ||
787 | struct qla27xx_fwdt_template *tmp) | ||
788 | { | ||
789 | qla27xx_time_stamp(tmp); | ||
790 | qla27xx_driver_info(tmp); | ||
791 | qla27xx_firmware_info(tmp, vha); | ||
792 | } | ||
793 | |||
794 | static inline uint32_t | ||
795 | qla27xx_template_checksum(void *p, ulong size) | ||
796 | { | ||
797 | uint32_t *buf = p; | ||
798 | uint64_t sum = 0; | ||
799 | |||
800 | size /= sizeof(*buf); | ||
801 | |||
802 | while (size--) | ||
803 | sum += *buf++; | ||
804 | |||
805 | sum = (sum & 0xffffffff) + (sum >> 32); | ||
806 | |||
807 | return ~sum; | ||
808 | } | ||
809 | |||
810 | static inline int | ||
811 | qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp) | ||
812 | { | ||
813 | return qla27xx_template_checksum(tmp, tmp->template_size) == 0; | ||
814 | } | ||
815 | |||
816 | static inline int | ||
817 | qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp) | ||
818 | { | ||
819 | return tmp->template_type == TEMPLATE_TYPE_FWDUMP; | ||
820 | } | ||
821 | |||
822 | static void | ||
823 | qla27xx_execute_fwdt_template(struct scsi_qla_host *vha) | ||
824 | { | ||
825 | struct qla27xx_fwdt_template *tmp = vha->hw->fw_dump_template; | ||
826 | ulong len; | ||
827 | |||
828 | if (qla27xx_fwdt_template_valid(tmp)) { | ||
829 | len = tmp->template_size; | ||
830 | tmp = memcpy(vha->hw->fw_dump, tmp, len); | ||
831 | ql27xx_edit_template(vha, tmp); | ||
832 | qla27xx_walk_template(vha, tmp, tmp, &len); | ||
833 | vha->hw->fw_dump_len = len; | ||
834 | vha->hw->fw_dumped = 1; | ||
835 | } | ||
836 | } | ||
837 | |||
838 | ulong | ||
839 | qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha) | ||
840 | { | ||
841 | struct qla27xx_fwdt_template *tmp = vha->hw->fw_dump_template; | ||
842 | ulong len = 0; | ||
843 | |||
844 | if (qla27xx_fwdt_template_valid(tmp)) { | ||
845 | len = tmp->template_size; | ||
846 | qla27xx_walk_template(vha, tmp, NULL, &len); | ||
847 | } | ||
848 | |||
849 | return len; | ||
850 | } | ||
851 | |||
852 | ulong | ||
853 | qla27xx_fwdt_template_size(void *p) | ||
854 | { | ||
855 | struct qla27xx_fwdt_template *tmp = p; | ||
856 | |||
857 | return tmp->template_size; | ||
858 | } | ||
859 | |||
860 | ulong | ||
861 | qla27xx_fwdt_template_default_size(void) | ||
862 | { | ||
863 | return sizeof(ql27xx_fwdt_default_template); | ||
864 | } | ||
865 | |||
866 | const void * | ||
867 | qla27xx_fwdt_template_default(void) | ||
868 | { | ||
869 | return ql27xx_fwdt_default_template; | ||
870 | } | ||
871 | |||
872 | int | ||
873 | qla27xx_fwdt_template_valid(void *p) | ||
874 | { | ||
875 | struct qla27xx_fwdt_template *tmp = p; | ||
876 | |||
877 | if (!qla27xx_verify_template_header(tmp)) { | ||
878 | ql_log(ql_log_warn, NULL, 0xd01c, | ||
879 | "%s: template type %x\n", __func__, tmp->template_type); | ||
880 | return false; | ||
881 | } | ||
882 | |||
883 | if (!qla27xx_verify_template_checksum(tmp)) { | ||
884 | ql_log(ql_log_warn, NULL, 0xd01d, | ||
885 | "%s: failed template checksum\n", __func__); | ||
886 | return false; | ||
887 | } | ||
888 | |||
889 | return true; | ||
890 | } | ||
891 | |||
892 | void | ||
893 | qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) | ||
894 | { | ||
895 | ulong flags = 0; | ||
896 | |||
897 | if (!hardware_locked) | ||
898 | spin_lock_irqsave(&vha->hw->hardware_lock, flags); | ||
899 | |||
900 | if (!vha->hw->fw_dump) | ||
901 | ql_log(ql_log_warn, vha, 0xd01e, "fwdump buffer missing.\n"); | ||
902 | else if (!vha->hw->fw_dump_template) | ||
903 | ql_log(ql_log_warn, vha, 0xd01f, "fwdump template missing.\n"); | ||
904 | else | ||
905 | qla27xx_execute_fwdt_template(vha); | ||
906 | |||
907 | if (!hardware_locked) | ||
908 | spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); | ||
909 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.h b/drivers/scsi/qla2xxx/qla_tmpl.h new file mode 100644 index 000000000000..c9d2fff4d964 --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_tmpl.h | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * QLogic Fibre Channel HBA Driver | ||
3 | * Copyright (c) 2003-2013 QLogic Corporation | ||
4 | * | ||
5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
6 | */ | ||
7 | |||
8 | #ifndef __QLA_DMP27_H__ | ||
9 | #define __QLA_DMP27_H__ | ||
10 | |||
11 | #define IOBASE_ADDR offsetof(struct device_reg_24xx, iobase_addr) | ||
12 | |||
13 | struct __packed qla27xx_fwdt_template { | ||
14 | uint32_t template_type; | ||
15 | uint32_t entry_offset; | ||
16 | uint32_t template_size; | ||
17 | uint32_t reserved_1; | ||
18 | |||
19 | uint32_t entry_count; | ||
20 | uint32_t template_version; | ||
21 | uint32_t capture_timestamp; | ||
22 | uint32_t template_checksum; | ||
23 | |||
24 | uint32_t reserved_2; | ||
25 | uint32_t driver_info[3]; | ||
26 | |||
27 | uint32_t saved_state[16]; | ||
28 | |||
29 | uint32_t reserved_3[8]; | ||
30 | uint32_t firmware_version[5]; | ||
31 | }; | ||
32 | |||
33 | #define TEMPLATE_TYPE_FWDUMP 99 | ||
34 | |||
35 | #define ENTRY_TYPE_NOP 0 | ||
36 | #define ENTRY_TYPE_TMP_END 255 | ||
37 | #define ENTRY_TYPE_RD_IOB_T1 256 | ||
38 | #define ENTRY_TYPE_WR_IOB_T1 257 | ||
39 | #define ENTRY_TYPE_RD_IOB_T2 258 | ||
40 | #define ENTRY_TYPE_WR_IOB_T2 259 | ||
41 | #define ENTRY_TYPE_RD_PCI 260 | ||
42 | #define ENTRY_TYPE_WR_PCI 261 | ||
43 | #define ENTRY_TYPE_RD_RAM 262 | ||
44 | #define ENTRY_TYPE_GET_QUEUE 263 | ||
45 | #define ENTRY_TYPE_GET_FCE 264 | ||
46 | #define ENTRY_TYPE_PSE_RISC 265 | ||
47 | #define ENTRY_TYPE_RST_RISC 266 | ||
48 | #define ENTRY_TYPE_DIS_INTR 267 | ||
49 | #define ENTRY_TYPE_GET_HBUF 268 | ||
50 | #define ENTRY_TYPE_SCRATCH 269 | ||
51 | #define ENTRY_TYPE_RDREMREG 270 | ||
52 | #define ENTRY_TYPE_WRREMREG 271 | ||
53 | #define ENTRY_TYPE_RDREMRAM 272 | ||
54 | #define ENTRY_TYPE_PCICFG 273 | ||
55 | |||
56 | #define CAPTURE_FLAG_PHYS_ONLY BIT_0 | ||
57 | #define CAPTURE_FLAG_PHYS_VIRT BIT_1 | ||
58 | |||
59 | #define DRIVER_FLAG_SKIP_ENTRY BIT_7 | ||
60 | |||
61 | struct __packed qla27xx_fwdt_entry { | ||
62 | struct __packed { | ||
63 | uint32_t entry_type; | ||
64 | uint32_t entry_size; | ||
65 | uint32_t reserved_1; | ||
66 | |||
67 | uint8_t capture_flags; | ||
68 | uint8_t reserved_2[2]; | ||
69 | uint8_t driver_flags; | ||
70 | } hdr; | ||
71 | union __packed { | ||
72 | struct __packed { | ||
73 | } t0; | ||
74 | |||
75 | struct __packed { | ||
76 | } t255; | ||
77 | |||
78 | struct __packed { | ||
79 | uint32_t base_addr; | ||
80 | uint8_t reg_width; | ||
81 | uint16_t reg_count; | ||
82 | uint8_t pci_offset; | ||
83 | } t256; | ||
84 | |||
85 | struct __packed { | ||
86 | uint32_t base_addr; | ||
87 | uint32_t write_data; | ||
88 | uint8_t pci_offset; | ||
89 | uint8_t reserved[3]; | ||
90 | } t257; | ||
91 | |||
92 | struct __packed { | ||
93 | uint32_t base_addr; | ||
94 | uint8_t reg_width; | ||
95 | uint16_t reg_count; | ||
96 | uint8_t pci_offset; | ||
97 | uint8_t banksel_offset; | ||
98 | uint8_t reserved[3]; | ||
99 | uint32_t bank; | ||
100 | } t258; | ||
101 | |||
102 | struct __packed { | ||
103 | uint32_t base_addr; | ||
104 | uint32_t write_data; | ||
105 | uint8_t reserved[2]; | ||
106 | uint8_t pci_offset; | ||
107 | uint8_t banksel_offset; | ||
108 | uint32_t bank; | ||
109 | } t259; | ||
110 | |||
111 | struct __packed { | ||
112 | uint8_t pci_addr; | ||
113 | uint8_t reserved[3]; | ||
114 | } t260; | ||
115 | |||
116 | struct __packed { | ||
117 | uint8_t pci_addr; | ||
118 | uint8_t reserved[3]; | ||
119 | uint32_t write_data; | ||
120 | } t261; | ||
121 | |||
122 | struct __packed { | ||
123 | uint8_t ram_area; | ||
124 | uint8_t reserved[3]; | ||
125 | uint32_t start_addr; | ||
126 | uint32_t end_addr; | ||
127 | } t262; | ||
128 | |||
129 | struct __packed { | ||
130 | uint32_t num_queues; | ||
131 | uint8_t queue_type; | ||
132 | uint8_t reserved[3]; | ||
133 | } t263; | ||
134 | |||
135 | struct __packed { | ||
136 | uint32_t fce_trace_size; | ||
137 | uint64_t write_pointer; | ||
138 | uint64_t base_pointer; | ||
139 | uint32_t fce_enable_mb0; | ||
140 | uint32_t fce_enable_mb2; | ||
141 | uint32_t fce_enable_mb3; | ||
142 | uint32_t fce_enable_mb4; | ||
143 | uint32_t fce_enable_mb5; | ||
144 | uint32_t fce_enable_mb6; | ||
145 | } t264; | ||
146 | |||
147 | struct __packed { | ||
148 | } t265; | ||
149 | |||
150 | struct __packed { | ||
151 | } t266; | ||
152 | |||
153 | struct __packed { | ||
154 | uint8_t pci_offset; | ||
155 | uint8_t reserved[3]; | ||
156 | uint32_t data; | ||
157 | } t267; | ||
158 | |||
159 | struct __packed { | ||
160 | uint8_t buf_type; | ||
161 | uint8_t reserved[3]; | ||
162 | uint32_t buf_size; | ||
163 | uint64_t start_addr; | ||
164 | } t268; | ||
165 | |||
166 | struct __packed { | ||
167 | uint32_t scratch_size; | ||
168 | } t269; | ||
169 | |||
170 | struct __packed { | ||
171 | uint32_t addr; | ||
172 | uint32_t count; | ||
173 | } t270; | ||
174 | |||
175 | struct __packed { | ||
176 | uint32_t addr; | ||
177 | uint32_t data; | ||
178 | } t271; | ||
179 | |||
180 | struct __packed { | ||
181 | uint32_t addr; | ||
182 | uint32_t count; | ||
183 | } t272; | ||
184 | |||
185 | struct __packed { | ||
186 | uint32_t addr; | ||
187 | uint32_t count; | ||
188 | } t273; | ||
189 | }; | ||
190 | }; | ||
191 | |||
192 | #define T262_RAM_AREA_CRITICAL_RAM 1 | ||
193 | #define T262_RAM_AREA_EXTERNAL_RAM 2 | ||
194 | #define T262_RAM_AREA_SHARED_RAM 3 | ||
195 | #define T262_RAM_AREA_DDR_RAM 4 | ||
196 | |||
197 | #define T263_QUEUE_TYPE_REQ 1 | ||
198 | #define T263_QUEUE_TYPE_RSP 2 | ||
199 | #define T263_QUEUE_TYPE_ATIO 3 | ||
200 | |||
201 | #define T268_BUF_TYPE_EXTD_TRACE 1 | ||
202 | #define T268_BUF_TYPE_EXCH_BUFOFF 2 | ||
203 | #define T268_BUF_TYPE_EXTD_LOGIN 3 | ||
204 | |||
205 | #endif | ||