Skip to content

Commit f73cb69

Browse files
Chad DupuisJames Bottomley
Chad Dupuis
authored and
James Bottomley
committed
[SCSI] qla2xxx: Add support for ISP2071.
Signed-off-by: Chad Dupuis <[email protected]> Signed-off-by: Armen Baloyan <[email protected]> Signed-off-by: Joe Carnuccio <[email protected]> Signed-off-by: Saurav Kashyap <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent 624f28b commit f73cb69

20 files changed

+1812
-136
lines changed

drivers/scsi/qla2xxx/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
22
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
44

55
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
66
obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o

drivers/scsi/qla2xxx/qla_attr.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,92 @@ static struct bin_attribute sysfs_fw_dump_attr = {
146146
.write = qla2x00_sysfs_write_fw_dump,
147147
};
148148

149+
static ssize_t
150+
qla2x00_sysfs_read_fw_dump_template(struct file *filp, struct kobject *kobj,
151+
struct bin_attribute *bin_attr,
152+
char *buf, loff_t off, size_t count)
153+
{
154+
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
155+
struct device, kobj)));
156+
struct qla_hw_data *ha = vha->hw;
157+
158+
if (!ha->fw_dump_template || !ha->fw_dump_template_len)
159+
return 0;
160+
161+
ql_dbg(ql_dbg_user, vha, 0x70e2,
162+
"chunk <- off=%llx count=%lx\n", off, count);
163+
return memory_read_from_buffer(buf, count, &off,
164+
ha->fw_dump_template, ha->fw_dump_template_len);
165+
}
166+
167+
static ssize_t
168+
qla2x00_sysfs_write_fw_dump_template(struct file *filp, struct kobject *kobj,
169+
struct bin_attribute *bin_attr,
170+
char *buf, loff_t off, size_t count)
171+
{
172+
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
173+
struct device, kobj)));
174+
struct qla_hw_data *ha = vha->hw;
175+
uint32_t size;
176+
177+
if (off == 0) {
178+
if (ha->fw_dump)
179+
vfree(ha->fw_dump);
180+
if (ha->fw_dump_template)
181+
vfree(ha->fw_dump_template);
182+
183+
ha->fw_dump = NULL;
184+
ha->fw_dump_len = 0;
185+
ha->fw_dump_template = NULL;
186+
ha->fw_dump_template_len = 0;
187+
188+
size = qla27xx_fwdt_template_size(buf);
189+
ql_dbg(ql_dbg_user, vha, 0x70d1,
190+
"-> allocating fwdt (%x bytes)...\n", size);
191+
ha->fw_dump_template = vmalloc(size);
192+
if (!ha->fw_dump_template) {
193+
ql_log(ql_log_warn, vha, 0x70d2,
194+
"Failed allocate fwdt (%x bytes).\n", size);
195+
return -ENOMEM;
196+
}
197+
ha->fw_dump_template_len = size;
198+
}
199+
200+
if (off + count > ha->fw_dump_template_len) {
201+
count = ha->fw_dump_template_len - off;
202+
ql_dbg(ql_dbg_user, vha, 0x70d3,
203+
"chunk -> truncating to %lx bytes.\n", count);
204+
}
205+
206+
ql_dbg(ql_dbg_user, vha, 0x70d4,
207+
"chunk -> off=%llx count=%lx\n", off, count);
208+
memcpy(ha->fw_dump_template + off, buf, count);
209+
210+
if (off + count == ha->fw_dump_template_len) {
211+
size = qla27xx_fwdt_calculate_dump_size(vha);
212+
ql_dbg(ql_dbg_user, vha, 0x70d5,
213+
"-> allocating fwdump (%x bytes)...\n", size);
214+
ha->fw_dump = vmalloc(size);
215+
if (!ha->fw_dump) {
216+
ql_log(ql_log_warn, vha, 0x70d6,
217+
"Failed allocate fwdump (%x bytes).\n", size);
218+
return -ENOMEM;
219+
}
220+
ha->fw_dump_len = size;
221+
}
222+
223+
return count;
224+
}
225+
static struct bin_attribute sysfs_fw_dump_template_attr = {
226+
.attr = {
227+
.name = "fw_dump_template",
228+
.mode = S_IRUSR | S_IWUSR,
229+
},
230+
.size = 0,
231+
.read = qla2x00_sysfs_read_fw_dump_template,
232+
.write = qla2x00_sysfs_write_fw_dump_template,
233+
};
234+
149235
static ssize_t
150236
qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj,
151237
struct bin_attribute *bin_attr,
@@ -845,6 +931,7 @@ static struct sysfs_entry {
845931
int is4GBp_only;
846932
} bin_file_entries[] = {
847933
{ "fw_dump", &sysfs_fw_dump_attr, },
934+
{ "fw_dump_template", &sysfs_fw_dump_template_attr, 0x27 },
848935
{ "nvram", &sysfs_nvram_attr, },
849936
{ "optrom", &sysfs_optrom_attr, },
850937
{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
@@ -870,6 +957,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
870957
continue;
871958
if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw)))
872959
continue;
960+
if (iter->is4GBp_only == 0x27 && !IS_QLA27XX(vha->hw))
961+
continue;
873962

874963
ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
875964
iter->attr);
@@ -1210,7 +1299,7 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev,
12101299
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12111300
struct qla_hw_data *ha = vha->hw;
12121301

1213-
if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
1302+
if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha))
12141303
return scnprintf(buf, PAGE_SIZE, "\n");
12151304

12161305
return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n",
@@ -1532,6 +1621,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
15321621
case PORT_SPEED_16GB:
15331622
speed = FC_PORTSPEED_16GBIT;
15341623
break;
1624+
case PORT_SPEED_32GB:
1625+
speed = FC_PORTSPEED_32GBIT;
1626+
break;
15351627
}
15361628
fc_host_speed(shost) = speed;
15371629
}
@@ -2183,6 +2275,9 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
21832275
else if (IS_QLAFX00(ha))
21842276
speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
21852277
FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
2278+
else if (IS_QLA27XX(ha))
2279+
speed = FC_PORTSPEED_32GBIT | FC_PORTSPEED_16GBIT |
2280+
FC_PORTSPEED_8GBIT;
21862281
else
21872282
speed = FC_PORTSPEED_1GBIT;
21882283
fc_host_supported_speeds(vha->host) = speed;

drivers/scsi/qla2xxx/qla_dbg.c

Lines changed: 110 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
* ----------------------------------------------------------------------
1212
* | Level | Last Value Used | Holes |
1313
* ----------------------------------------------------------------------
14-
* | Module Init and Probe | 0x015b | 0x4b,0xba,0xfa |
15-
* | | | 0x0x015a |
16-
* | Mailbox commands | 0x1187 | 0x111a-0x111b |
17-
* | | | 0x1155-0x1158 |
18-
* | | | 0x1018-0x1019 |
14+
* | Module Init and Probe | 0x017d | 0x004b,0x0141 |
15+
* | | | 0x0144,0x0146 |
16+
* | | | 0x015b-0x0160 |
17+
* | | | 0x016e-0x0170 |
18+
* | Mailbox commands | 0x1187 | 0x1018-0x1019 |
19+
* | | | 0x10ca |
1920
* | | | 0x1115-0x1116 |
20-
* | | | 0x10ca |
21+
* | | | 0x111a-0x111b |
22+
* | | | 0x1155-0x1158 |
2123
* | Device Discovery | 0x2095 | 0x2020-0x2022, |
2224
* | | | 0x2011-0x2012, |
2325
* | | | 0x2016 |
@@ -33,17 +35,15 @@
3335
* | | | 0x5084,0x5075 |
3436
* | | | 0x503d,0x5044 |
3537
* | Timer Routines | 0x6012 | |
36-
* | User Space Interactions | 0x70e1 | 0x7018,0x702e, |
37-
* | | | 0x7020,0x7024, |
38-
* | | | 0x7039,0x7045, |
39-
* | | | 0x7073-0x7075, |
40-
* | | | 0x707b,0x708c, |
41-
* | | | 0x70a5,0x70a6, |
42-
* | | | 0x70a8,0x70ab, |
43-
* | | | 0x70ad-0x70ae, |
44-
* | | | 0x70d1-0x70db, |
45-
* | | | 0x7047,0x703b |
46-
* | | | 0x70de-0x70df, |
38+
* | User Space Interactions | 0x70e2 | 0x7018,0x702e |
39+
* | | | 0x7020,0x7024 |
40+
* | | | 0x7039,0x7045 |
41+
* | | | 0x7073-0x7075 |
42+
* | | | 0x70a5-0x70a6 |
43+
* | | | 0x70a8,0x70ab |
44+
* | | | 0x70ad-0x70ae |
45+
* | | | 0x70d7-0x70db |
46+
* | | | 0x70de-0x70df |
4747
* | Task Management | 0x803d | 0x8025-0x8026 |
4848
* | | | 0x800b,0x8039 |
4949
* | AER/EEH | 0x9011 | |
@@ -59,7 +59,11 @@
5959
* | | | 0xb13c-0xb140 |
6060
* | | | 0xb149 |
6161
* | MultiQ | 0xc00c | |
62-
* | Misc | 0xd010 | |
62+
* | Misc | 0xd2ff | 0xd017-0xd019 |
63+
* | | | 0xd020 |
64+
* | | | 0xd02e-0xd0ff |
65+
* | | | 0xd101-0xd1fe |
66+
* | | | 0xd212-0xd2fe |
6367
* | Target Mode | 0xe070 | 0xe021 |
6468
* | Target Mode Management | 0xf072 | 0xf002-0xf003 |
6569
* | | | 0xf046-0xf049 |
@@ -104,7 +108,87 @@ qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
104108
return ptr + (rsp->length * sizeof(response_t));
105109
}
106110

107-
static int
111+
int
112+
qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
113+
uint32_t ram_dwords, void **nxt)
114+
{
115+
int rval;
116+
uint32_t cnt, stat, timer, dwords, idx;
117+
uint16_t mb0, mb1;
118+
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
119+
dma_addr_t dump_dma = ha->gid_list_dma;
120+
uint32_t *dump = (uint32_t *)ha->gid_list;
121+
122+
rval = QLA_SUCCESS;
123+
mb0 = 0;
124+
125+
WRT_REG_WORD(&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+
191+
int
108192
qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
109193
uint32_t ram_dwords, void **nxt)
110194
{
@@ -139,6 +223,7 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
139223
WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
140224
WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
141225

226+
ha->flags.mbox_int = 0;
142227
for (timer = 6000000; timer; timer--) {
143228
/* Check for pending interrupts. */
144229
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,
164249
}
165250
udelay(5);
166251
}
252+
ha->flags.mbox_int = 1;
167253

168254
if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
169255
rval = mb0 & MBS_MASK;
170256
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]);
172259
} else {
173260
rval = QLA_FUNCTION_FAILED;
174261
}
@@ -208,7 +295,7 @@ qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
208295
return buf;
209296
}
210297

211-
static inline int
298+
int
212299
qla24xx_pause_risc(struct device_reg_24xx __iomem *reg)
213300
{
214301
int rval = QLA_SUCCESS;
@@ -227,7 +314,7 @@ qla24xx_pause_risc(struct device_reg_24xx __iomem *reg)
227314
return rval;
228315
}
229316

230-
static int
317+
int
231318
qla24xx_soft_reset(struct qla_hw_data *ha)
232319
{
233320
int rval = QLA_SUCCESS;
@@ -537,7 +624,7 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
537624
struct qla2xxx_mq_chain *mq = ptr;
538625
device_reg_t __iomem *reg;
539626

540-
if (!ha->mqenable || IS_QLA83XX(ha))
627+
if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
541628
return ptr;
542629

543630
mq = ptr;

drivers/scsi/qla2xxx/qla_dbg.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,10 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
348348
#define ql_dbg_tgt 0x00004000 /* Target mode */
349349
#define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */
350350
#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
351+
352+
extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
353+
uint32_t, void **);
354+
extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
355+
uint32_t, void **);
356+
extern int qla24xx_pause_risc(struct device_reg_24xx __iomem *);
357+
extern int qla24xx_soft_reset(struct qla_hw_data *);

0 commit comments

Comments
 (0)