aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/qla2xxx/Makefile2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c97
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c133
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h37
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h8
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c11
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c256
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c26
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c47
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c124
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c65
-rw-r--r--drivers/scsi/qla2xxx/qla_tmpl.c909
-rw-r--r--drivers/scsi/qla2xxx/qla_tmpl.h205
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 @@
1qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ 1qla2xxx-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
5obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o 5obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
6obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o 6obj-$(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
149static ssize_t 149static ssize_t
150qla2x00_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
167static ssize_t
168qla2x00_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}
225static 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
235static ssize_t
150qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, 236qla2x00_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
107static int 111int
112qla27xx_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(&reg->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(&reg->mailbox1, LSW(addr));
135 WRT_REG_WORD(&reg->mailbox8, MSW(addr));
136
137 WRT_REG_WORD(&reg->mailbox2, MSW(dump_dma));
138 WRT_REG_WORD(&reg->mailbox3, LSW(dump_dma));
139 WRT_REG_WORD(&reg->mailbox6, MSW(MSD(dump_dma)));
140 WRT_REG_WORD(&reg->mailbox7, LSW(MSD(dump_dma)));
141
142 WRT_REG_WORD(&reg->mailbox4, MSW(dwords));
143 WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
144
145 WRT_REG_WORD(&reg->mailbox9, 0);
146 WRT_REG_DWORD(&reg->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(&reg->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(&reg->mailbox0);
161 mb1 = RD_REG_WORD(&reg->mailbox1);
162
163 WRT_REG_DWORD(&reg->hccr,
164 HCCRX_CLR_RISC_INT);
165 RD_REG_DWORD(&reg->hccr);
166 break;
167 }
168
169 /* Clear this intr; it wasn't a mailbox intr */
170 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
171 RD_REG_DWORD(&reg->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
191int
108qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, 192qla24xx_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(&reg->mailbox5, LSW(dwords)); 223 WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
140 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT); 224 WRT_REG_DWORD(&reg->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(&reg->host_status); 229 stat = RD_REG_DWORD(&reg->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
211static inline int 298int
212qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) 299qla24xx_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
230static int 317int
231qla24xx_soft_reset(struct qla_hw_data *ha) 318qla24xx_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
352extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
353 uint32_t, void **);
354extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
355 uint32_t, void **);
356extern int qla24xx_pause_risc(struct device_reg_24xx __iomem *);
357extern 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
2153struct ct_fdmi_port_attr { 2155struct 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);
511extern void qla24xx_fw_dump(scsi_qla_host_t *, int); 511extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
512extern void qla25xx_fw_dump(scsi_qla_host_t *, int); 512extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
513extern void qla81xx_fw_dump(scsi_qla_host_t *, int); 513extern void qla81xx_fw_dump(scsi_qla_host_t *, int);
514
515extern void qla27xx_fwdump(scsi_qla_host_t *, int);
516extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *);
517extern int qla27xx_fwdt_template_valid(void *);
518extern ulong qla27xx_fwdt_template_size(void *);
519extern const void *qla27xx_fwdt_template_default(void);
520extern ulong qla27xx_fwdt_template_default_size(void);
521
514extern void qla2x00_dump_regs(scsi_qla_host_t *); 522extern void qla2x00_dump_regs(scsi_qla_host_t *);
515extern void qla2x00_dump_buffer(uint8_t *, uint32_t); 523extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
516extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); 524extern 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
1425try_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
1445try_eft: 1459try_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
1472cont_alloc: 1491cont_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
1511allocate:
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
5204default_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
5239failed_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
5328fail_fw_integrity: 5506default_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
5541failed_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
5332int 5550int
@@ -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)
1848skip_cmd_array: 1848skip_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(&reg->isp25mq.req_q_out); 1852 cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
1853 else if (IS_P3P_TYPE(ha)) 1853 else if (IS_P3P_TYPE(ha))
1854 cnt = RD_REG_DWORD(&reg->isp82.req_q_out); 1854 cnt = RD_REG_DWORD(&reg->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)
356const char * 356const char *
357qla2x00_get_link_speed_str(struct qla_hw_data *ha, uint16_t speed) 357qla2x00_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(&reg24->mailbox7) : 0; 654 RD_REG_WORD(&reg24->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
3003qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) 3005qla2x00_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
578failed: 585failed:
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
2105static 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
2105static inline void 2143static inline void
2106qla2x00_set_isp_flags(struct qla_hw_data *ha) 2144qla2x00_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
2243static void 2289static 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:
2888iospace_config_failed: 2951iospace_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
3563qla2x00_free_fw_dump(struct qla_hw_data *ha) 3626qla2x00_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
5269static DEFINE_MUTEX(qla_fw_lock); 5341static 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
5284struct fw_blob * 5357struct 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};
5641MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); 5717MODULE_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];
842done: 866done:
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 */
11static 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
102static inline void __iomem *
103qla27xx_isp_reg(struct scsi_qla_host *vha)
104{
105 return &vha->hw->iobase->isp24;
106}
107
108static inline void
109qla27xx_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
118static inline void
119qla27xx_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
128static inline void
129qla27xx_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
147static inline void
148qla27xx_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
160static inline void
161qla27xx_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
173static inline void
174qla27xx_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
186static 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
194static inline void
195qla27xx_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
208static inline void
209qla27xx_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
221static inline void
222qla27xx_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
243static inline void
244qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf)
245{
246 if (buf)
247 ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
248}
249
250static int
251qla27xx_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
261static int
262qla27xx_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
273static int
274qla27xx_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
287static int
288qla27xx_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
301static int
302qla27xx_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
316static int
317qla27xx_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
331static int
332qla27xx_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
344static int
345qla27xx_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
357static int
358qla27xx_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);
411done:
412 return false;
413}
414
415static int
416qla27xx_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;
465done:
466 return false;
467}
468
469static int
470qla27xx_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
497static int
498qla27xx_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
511static int
512qla27xx_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
523static int
524qla27xx_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
536static int
537qla27xx_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
571static int
572qla27xx_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
588static int
589qla27xx_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
611static int
612qla27xx_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
628static int
629qla27xx_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
648static int
649qla27xx_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
671static int
672qla27xx_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
682struct 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
691static 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
715static 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
726static inline void *
727qla27xx_next_entry(void *p)
728{
729 struct qla27xx_fwdt_entry *ent = p;
730
731 return p + ent->hdr.entry_size;
732}
733
734static void
735qla27xx_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
752static void
753qla27xx_time_stamp(struct qla27xx_fwdt_template *tmp)
754{
755 tmp->capture_timestamp = jiffies;
756}
757
758static void
759qla27xx_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
772static void
773qla27xx_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
785static void
786ql27xx_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
794static inline uint32_t
795qla27xx_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
810static inline int
811qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp)
812{
813 return qla27xx_template_checksum(tmp, tmp->template_size) == 0;
814}
815
816static inline int
817qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp)
818{
819 return tmp->template_type == TEMPLATE_TYPE_FWDUMP;
820}
821
822static void
823qla27xx_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
838ulong
839qla27xx_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
852ulong
853qla27xx_fwdt_template_size(void *p)
854{
855 struct qla27xx_fwdt_template *tmp = p;
856
857 return tmp->template_size;
858}
859
860ulong
861qla27xx_fwdt_template_default_size(void)
862{
863 return sizeof(ql27xx_fwdt_default_template);
864}
865
866const void *
867qla27xx_fwdt_template_default(void)
868{
869 return ql27xx_fwdt_default_template;
870}
871
872int
873qla27xx_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
892void
893qla27xx_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
13struct __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
61struct __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