1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * QLogic iSCSI HBA Driver 4 * Copyright (c) 2003-2013 QLogic Corporation 5 */ 6 7 #include "ql4_def.h" 8 #include "ql4_glbl.h" 9 #include "ql4_dbg.h" 10 11 static ssize_t 12 qla4_8xxx_sysfs_read_fw_dump(struct file *filep, struct kobject *kobj, 13 struct bin_attribute *ba, char *buf, loff_t off, 14 size_t count) 15 { 16 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 17 struct device, kobj))); 18 19 if (is_qla40XX(ha)) 20 return -EINVAL; 21 22 if (!test_bit(AF_82XX_DUMP_READING, &ha->flags)) 23 return 0; 24 25 return memory_read_from_buffer(buf, count, &off, ha->fw_dump, 26 ha->fw_dump_size); 27 } 28 29 static ssize_t 30 qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj, 31 struct bin_attribute *ba, char *buf, loff_t off, 32 size_t count) 33 { 34 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 35 struct device, kobj))); 36 uint32_t dev_state; 37 long reading; 38 int ret = 0; 39 40 if (is_qla40XX(ha)) 41 return -EINVAL; 42 43 if (off != 0) 44 return ret; 45 46 buf[1] = 0; 47 ret = kstrtol(buf, 10, &reading); 48 if (ret) { 49 ql4_printk(KERN_ERR, ha, "%s: Invalid input. Return err %d\n", 50 __func__, ret); 51 return ret; 52 } 53 54 switch (reading) { 55 case 0: 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")); 63 } 64 break; 65 case 1: 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", 72 ha->host_no)); 73 } 74 break; 75 case 2: 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", 81 __func__); 82 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, 83 QLA8XXX_DEV_NEED_RESET); 84 if (is_qla8022(ha) || 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); 91 } 92 } else 93 ql4_printk(KERN_INFO, ha, 94 "%s: Reset not performed as device state is 0x%x\n", 95 __func__, dev_state); 96 97 ha->isp_ops->idc_unlock(ha); 98 break; 99 default: 100 /* do nothing */ 101 break; 102 } 103 104 return count; 105 } 106 107 static struct bin_attribute sysfs_fw_dump_attr = { 108 .attr = { 109 .name = "fw_dump", 110 .mode = S_IRUSR | S_IWUSR, 111 }, 112 .size = 0, 113 .read = qla4_8xxx_sysfs_read_fw_dump, 114 .write = qla4_8xxx_sysfs_write_fw_dump, 115 }; 116 117 static struct sysfs_entry { 118 char *name; 119 struct bin_attribute *attr; 120 } bin_file_entries[] = { 121 { "fw_dump", &sysfs_fw_dump_attr }, 122 { NULL }, 123 }; 124 125 void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha) 126 { 127 struct Scsi_Host *host = ha->host; 128 struct sysfs_entry *iter; 129 int ret; 130 131 for (iter = bin_file_entries; iter->name; iter++) { 132 ret = sysfs_create_bin_file(&host->shost_gendev.kobj, 133 iter->attr); 134 if (ret) 135 ql4_printk(KERN_ERR, ha, 136 "Unable to create sysfs %s binary attribute (%d).\n", 137 iter->name, ret); 138 } 139 } 140 141 void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha) 142 { 143 struct Scsi_Host *host = ha->host; 144 struct sysfs_entry *iter; 145 146 for (iter = bin_file_entries; iter->name; iter++) 147 sysfs_remove_bin_file(&host->shost_gendev.kobj, 148 iter->attr); 149 } 150 151 /* Scsi_Host attributes. */ 152 static ssize_t 153 qla4xxx_fw_version_show(struct device *dev, 154 struct device_attribute *attr, char *buf) 155 { 156 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 157 158 if (is_qla80XX(ha)) 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); 162 else 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); 166 } 167 168 static ssize_t 169 qla4xxx_serial_num_show(struct device *dev, struct device_attribute *attr, 170 char *buf) 171 { 172 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 173 return snprintf(buf, PAGE_SIZE, "%s\n", ha->serial_number); 174 } 175 176 static ssize_t 177 qla4xxx_iscsi_version_show(struct device *dev, struct device_attribute *attr, 178 char *buf) 179 { 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); 183 } 184 185 static ssize_t 186 qla4xxx_optrom_version_show(struct device *dev, struct device_attribute *attr, 187 char *buf) 188 { 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); 193 } 194 195 static ssize_t 196 qla4xxx_board_id_show(struct device *dev, struct device_attribute *attr, 197 char *buf) 198 { 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); 201 } 202 203 static ssize_t 204 qla4xxx_fw_state_show(struct device *dev, struct device_attribute *attr, 205 char *buf) 206 { 207 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 208 209 qla4xxx_get_firmware_state(ha); 210 return snprintf(buf, PAGE_SIZE, "0x%08X%8X\n", ha->firmware_state, 211 ha->addl_fw_state); 212 } 213 214 static ssize_t 215 qla4xxx_phy_port_cnt_show(struct device *dev, struct device_attribute *attr, 216 char *buf) 217 { 218 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 219 220 if (is_qla40XX(ha)) 221 return -ENOSYS; 222 223 return snprintf(buf, PAGE_SIZE, "0x%04X\n", ha->phy_port_cnt); 224 } 225 226 static ssize_t 227 qla4xxx_phy_port_num_show(struct device *dev, struct device_attribute *attr, 228 char *buf) 229 { 230 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 231 232 if (is_qla40XX(ha)) 233 return -ENOSYS; 234 235 return snprintf(buf, PAGE_SIZE, "0x%04X\n", ha->phy_port_num); 236 } 237 238 static ssize_t 239 qla4xxx_iscsi_func_cnt_show(struct device *dev, struct device_attribute *attr, 240 char *buf) 241 { 242 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 243 244 if (is_qla40XX(ha)) 245 return -ENOSYS; 246 247 return snprintf(buf, PAGE_SIZE, "0x%04X\n", ha->iscsi_pci_func_cnt); 248 } 249 250 static ssize_t 251 qla4xxx_hba_model_show(struct device *dev, struct device_attribute *attr, 252 char *buf) 253 { 254 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 255 256 return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_name); 257 } 258 259 static ssize_t 260 qla4xxx_fw_timestamp_show(struct device *dev, struct device_attribute *attr, 261 char *buf) 262 { 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); 266 } 267 268 static ssize_t 269 qla4xxx_fw_build_user_show(struct device *dev, struct device_attribute *attr, 270 char *buf) 271 { 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); 274 } 275 276 static ssize_t 277 qla4xxx_fw_ext_timestamp_show(struct device *dev, struct device_attribute *attr, 278 char *buf) 279 { 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); 282 } 283 284 static ssize_t 285 qla4xxx_fw_load_src_show(struct device *dev, struct device_attribute *attr, 286 char *buf) 287 { 288 struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); 289 char *load_src = NULL; 290 291 switch (ha->fw_info.fw_load_source) { 292 case 1: 293 load_src = "Flash Primary"; 294 break; 295 case 2: 296 load_src = "Flash Secondary"; 297 break; 298 case 3: 299 load_src = "Host Download"; 300 break; 301 } 302 303 return snprintf(buf, PAGE_SIZE, "%s\n", load_src); 304 } 305 306 static ssize_t 307 qla4xxx_fw_uptime_show(struct device *dev, struct device_attribute *attr, 308 char *buf) 309 { 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); 314 } 315 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, 329 NULL); 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); 332 333 struct device_attribute *qla4xxx_host_attrs[] = { 334 &dev_attr_fw_version, 335 &dev_attr_serial_num, 336 &dev_attr_iscsi_version, 337 &dev_attr_optrom_version, 338 &dev_attr_board_id, 339 &dev_attr_fw_state, 340 &dev_attr_phy_port_cnt, 341 &dev_attr_phy_port_num, 342 &dev_attr_iscsi_func_cnt, 343 &dev_attr_hba_model, 344 &dev_attr_fw_timestamp, 345 &dev_attr_fw_build_user, 346 &dev_attr_fw_ext_timestamp, 347 &dev_attr_fw_load_src, 348 &dev_attr_fw_uptime, 349 NULL, 350 }; 351