1 // SPDX-License-Identifier: GPL-2.0-only
3 * QLogic iSCSI HBA Driver
4 * Copyright (c) 2003-2013 QLogic Corporation
12 qla4_8xxx_sysfs_read_fw_dump(struct file
*filep
, struct kobject
*kobj
,
13 struct bin_attribute
*ba
, char *buf
, loff_t off
,
16 struct scsi_qla_host
*ha
= to_qla_host(dev_to_shost(container_of(kobj
,
17 struct device
, kobj
)));
22 if (!test_bit(AF_82XX_DUMP_READING
, &ha
->flags
))
25 return memory_read_from_buffer(buf
, count
, &off
, ha
->fw_dump
,
30 qla4_8xxx_sysfs_write_fw_dump(struct file
*filep
, struct kobject
*kobj
,
31 struct bin_attribute
*ba
, char *buf
, loff_t off
,
34 struct scsi_qla_host
*ha
= to_qla_host(dev_to_shost(container_of(kobj
,
35 struct device
, kobj
)));
47 ret
= kstrtol(buf
, 10, &reading
);
49 ql4_printk(KERN_ERR
, ha
, "%s: Invalid input. Return err %d\n",
56 /* clear dump collection flags */
57 if (test_and_clear_bit(AF_82XX_DUMP_READING
, &ha
->flags
)) {
58 clear_bit(AF_82XX_FW_DUMPED
, &ha
->flags
);
59 /* Reload minidump template */
60 qla4xxx_alloc_fw_dump(ha
);
61 DEBUG2(ql4_printk(KERN_INFO
, ha
,
62 "Firmware template reloaded\n"));
66 /* Set flag to read dump */
67 if (test_bit(AF_82XX_FW_DUMPED
, &ha
->flags
) &&
68 !test_bit(AF_82XX_DUMP_READING
, &ha
->flags
)) {
69 set_bit(AF_82XX_DUMP_READING
, &ha
->flags
);
70 DEBUG2(ql4_printk(KERN_INFO
, ha
,
71 "Raw firmware dump ready for read on (%ld).\n",
76 /* Reset HBA and collect FW dump */
77 ha
->isp_ops
->idc_lock(ha
);
78 dev_state
= qla4_8xxx_rd_direct(ha
, QLA8XXX_CRB_DEV_STATE
);
79 if (dev_state
== QLA8XXX_DEV_READY
) {
80 ql4_printk(KERN_INFO
, ha
, "%s: Setting Need reset\n",
82 qla4_8xxx_wr_direct(ha
, QLA8XXX_CRB_DEV_STATE
,
83 QLA8XXX_DEV_NEED_RESET
);
85 ((is_qla8032(ha
) || is_qla8042(ha
)) &&
86 qla4_83xx_can_perform_reset(ha
))) {
87 set_bit(AF_8XXX_RST_OWNER
, &ha
->flags
);
88 set_bit(AF_FW_RECOVERY
, &ha
->flags
);
89 ql4_printk(KERN_INFO
, ha
, "%s: Reset owner is 0x%x\n",
90 __func__
, ha
->func_num
);
93 ql4_printk(KERN_INFO
, ha
,
94 "%s: Reset not performed as device state is 0x%x\n",
97 ha
->isp_ops
->idc_unlock(ha
);
107 static struct bin_attribute sysfs_fw_dump_attr
= {
110 .mode
= S_IRUSR
| S_IWUSR
,
113 .read
= qla4_8xxx_sysfs_read_fw_dump
,
114 .write
= qla4_8xxx_sysfs_write_fw_dump
,
117 static struct sysfs_entry
{
119 struct bin_attribute
*attr
;
120 } bin_file_entries
[] = {
121 { "fw_dump", &sysfs_fw_dump_attr
},
125 void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host
*ha
)
127 struct Scsi_Host
*host
= ha
->host
;
128 struct sysfs_entry
*iter
;
131 for (iter
= bin_file_entries
; iter
->name
; iter
++) {
132 ret
= sysfs_create_bin_file(&host
->shost_gendev
.kobj
,
135 ql4_printk(KERN_ERR
, ha
,
136 "Unable to create sysfs %s binary attribute (%d).\n",
141 void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host
*ha
)
143 struct Scsi_Host
*host
= ha
->host
;
144 struct sysfs_entry
*iter
;
146 for (iter
= bin_file_entries
; iter
->name
; iter
++)
147 sysfs_remove_bin_file(&host
->shost_gendev
.kobj
,
151 /* Scsi_Host attributes. */
153 qla4xxx_fw_version_show(struct device
*dev
,
154 struct device_attribute
*attr
, char *buf
)
156 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
159 return snprintf(buf
, PAGE_SIZE
, "%d.%02d.%02d (%x)\n",
160 ha
->fw_info
.fw_major
, ha
->fw_info
.fw_minor
,
161 ha
->fw_info
.fw_patch
, ha
->fw_info
.fw_build
);
163 return snprintf(buf
, PAGE_SIZE
, "%d.%02d.%02d.%02d\n",
164 ha
->fw_info
.fw_major
, ha
->fw_info
.fw_minor
,
165 ha
->fw_info
.fw_patch
, ha
->fw_info
.fw_build
);
169 qla4xxx_serial_num_show(struct device
*dev
, struct device_attribute
*attr
,
172 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
173 return snprintf(buf
, PAGE_SIZE
, "%s\n", ha
->serial_number
);
177 qla4xxx_iscsi_version_show(struct device
*dev
, struct device_attribute
*attr
,
180 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
181 return snprintf(buf
, PAGE_SIZE
, "%d.%02d\n", ha
->fw_info
.iscsi_major
,
182 ha
->fw_info
.iscsi_minor
);
186 qla4xxx_optrom_version_show(struct device
*dev
, struct device_attribute
*attr
,
189 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
190 return snprintf(buf
, PAGE_SIZE
, "%d.%02d.%02d.%02d\n",
191 ha
->fw_info
.bootload_major
, ha
->fw_info
.bootload_minor
,
192 ha
->fw_info
.bootload_patch
, ha
->fw_info
.bootload_build
);
196 qla4xxx_board_id_show(struct device
*dev
, struct device_attribute
*attr
,
199 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
200 return snprintf(buf
, PAGE_SIZE
, "0x%08X\n", ha
->board_id
);
204 qla4xxx_fw_state_show(struct device
*dev
, struct device_attribute
*attr
,
207 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
209 qla4xxx_get_firmware_state(ha
);
210 return snprintf(buf
, PAGE_SIZE
, "0x%08X%8X\n", ha
->firmware_state
,
215 qla4xxx_phy_port_cnt_show(struct device
*dev
, struct device_attribute
*attr
,
218 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
223 return snprintf(buf
, PAGE_SIZE
, "0x%04X\n", ha
->phy_port_cnt
);
227 qla4xxx_phy_port_num_show(struct device
*dev
, struct device_attribute
*attr
,
230 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
235 return snprintf(buf
, PAGE_SIZE
, "0x%04X\n", ha
->phy_port_num
);
239 qla4xxx_iscsi_func_cnt_show(struct device
*dev
, struct device_attribute
*attr
,
242 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
247 return snprintf(buf
, PAGE_SIZE
, "0x%04X\n", ha
->iscsi_pci_func_cnt
);
251 qla4xxx_hba_model_show(struct device
*dev
, struct device_attribute
*attr
,
254 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
256 return snprintf(buf
, PAGE_SIZE
, "%s\n", ha
->model_name
);
260 qla4xxx_fw_timestamp_show(struct device
*dev
, struct device_attribute
*attr
,
263 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
264 return snprintf(buf
, PAGE_SIZE
, "%s %s\n", ha
->fw_info
.fw_build_date
,
265 ha
->fw_info
.fw_build_time
);
269 qla4xxx_fw_build_user_show(struct device
*dev
, struct device_attribute
*attr
,
272 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
273 return snprintf(buf
, PAGE_SIZE
, "%s\n", ha
->fw_info
.fw_build_user
);
277 qla4xxx_fw_ext_timestamp_show(struct device
*dev
, struct device_attribute
*attr
,
280 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
281 return snprintf(buf
, PAGE_SIZE
, "%s\n", ha
->fw_info
.extended_timestamp
);
285 qla4xxx_fw_load_src_show(struct device
*dev
, struct device_attribute
*attr
,
288 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
289 char *load_src
= NULL
;
291 switch (ha
->fw_info
.fw_load_source
) {
293 load_src
= "Flash Primary";
296 load_src
= "Flash Secondary";
299 load_src
= "Host Download";
303 return snprintf(buf
, PAGE_SIZE
, "%s\n", load_src
);
307 qla4xxx_fw_uptime_show(struct device
*dev
, struct device_attribute
*attr
,
310 struct scsi_qla_host
*ha
= to_qla_host(class_to_shost(dev
));
311 qla4xxx_about_firmware(ha
);
312 return snprintf(buf
, PAGE_SIZE
, "%u.%u secs\n", ha
->fw_uptime_secs
,
313 ha
->fw_uptime_msecs
);
316 static DEVICE_ATTR(fw_version
, S_IRUGO
, qla4xxx_fw_version_show
, NULL
);
317 static DEVICE_ATTR(serial_num
, S_IRUGO
, qla4xxx_serial_num_show
, NULL
);
318 static DEVICE_ATTR(iscsi_version
, S_IRUGO
, qla4xxx_iscsi_version_show
, NULL
);
319 static DEVICE_ATTR(optrom_version
, S_IRUGO
, qla4xxx_optrom_version_show
, NULL
);
320 static DEVICE_ATTR(board_id
, S_IRUGO
, qla4xxx_board_id_show
, NULL
);
321 static DEVICE_ATTR(fw_state
, S_IRUGO
, qla4xxx_fw_state_show
, NULL
);
322 static DEVICE_ATTR(phy_port_cnt
, S_IRUGO
, qla4xxx_phy_port_cnt_show
, NULL
);
323 static DEVICE_ATTR(phy_port_num
, S_IRUGO
, qla4xxx_phy_port_num_show
, NULL
);
324 static DEVICE_ATTR(iscsi_func_cnt
, S_IRUGO
, qla4xxx_iscsi_func_cnt_show
, NULL
);
325 static DEVICE_ATTR(hba_model
, S_IRUGO
, qla4xxx_hba_model_show
, NULL
);
326 static DEVICE_ATTR(fw_timestamp
, S_IRUGO
, qla4xxx_fw_timestamp_show
, NULL
);
327 static DEVICE_ATTR(fw_build_user
, S_IRUGO
, qla4xxx_fw_build_user_show
, NULL
);
328 static DEVICE_ATTR(fw_ext_timestamp
, S_IRUGO
, qla4xxx_fw_ext_timestamp_show
,
330 static DEVICE_ATTR(fw_load_src
, S_IRUGO
, qla4xxx_fw_load_src_show
, NULL
);
331 static DEVICE_ATTR(fw_uptime
, S_IRUGO
, qla4xxx_fw_uptime_show
, NULL
);
333 static struct attribute
*qla4xxx_host_attrs
[] = {
334 &dev_attr_fw_version
.attr
,
335 &dev_attr_serial_num
.attr
,
336 &dev_attr_iscsi_version
.attr
,
337 &dev_attr_optrom_version
.attr
,
338 &dev_attr_board_id
.attr
,
339 &dev_attr_fw_state
.attr
,
340 &dev_attr_phy_port_cnt
.attr
,
341 &dev_attr_phy_port_num
.attr
,
342 &dev_attr_iscsi_func_cnt
.attr
,
343 &dev_attr_hba_model
.attr
,
344 &dev_attr_fw_timestamp
.attr
,
345 &dev_attr_fw_build_user
.attr
,
346 &dev_attr_fw_ext_timestamp
.attr
,
347 &dev_attr_fw_load_src
.attr
,
348 &dev_attr_fw_uptime
.attr
,
352 static const struct attribute_group qla4xxx_host_attr_group
= {
353 .attrs
= qla4xxx_host_attrs
356 const struct attribute_group
*qla4xxx_host_groups
[] = {
357 &qla4xxx_host_attr_group
,