diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 82 |
1 files changed, 66 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 92b3e13e9061..fee0c493775b 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -50,7 +50,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
50 | ha->host_no); | 50 | ha->host_no); |
51 | 51 | ||
52 | vfree(ha->fw_dump_buffer); | 52 | vfree(ha->fw_dump_buffer); |
53 | if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) | 53 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) |
54 | free_pages((unsigned long)ha->fw_dump, | 54 | free_pages((unsigned long)ha->fw_dump, |
55 | ha->fw_dump_order); | 55 | ha->fw_dump_order); |
56 | 56 | ||
@@ -64,7 +64,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
64 | if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) { | 64 | if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) { |
65 | ha->fw_dump_reading = 1; | 65 | ha->fw_dump_reading = 1; |
66 | 66 | ||
67 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) | 67 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) |
68 | dump_size = FW_DUMP_SIZE_24XX; | 68 | dump_size = FW_DUMP_SIZE_24XX; |
69 | else { | 69 | else { |
70 | dump_size = FW_DUMP_SIZE_1M; | 70 | dump_size = FW_DUMP_SIZE_1M; |
@@ -138,7 +138,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off, | |||
138 | return 0; | 138 | return 0; |
139 | 139 | ||
140 | /* Checksum NVRAM. */ | 140 | /* Checksum NVRAM. */ |
141 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { | 141 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
142 | uint32_t *iter; | 142 | uint32_t *iter; |
143 | uint32_t chksum; | 143 | uint32_t chksum; |
144 | 144 | ||
@@ -308,6 +308,61 @@ static struct bin_attribute sysfs_optrom_ctl_attr = { | |||
308 | .write = qla2x00_sysfs_write_optrom_ctl, | 308 | .write = qla2x00_sysfs_write_optrom_ctl, |
309 | }; | 309 | }; |
310 | 310 | ||
311 | static ssize_t | ||
312 | qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, | ||
313 | size_t count) | ||
314 | { | ||
315 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
316 | struct device, kobj))); | ||
317 | unsigned long flags; | ||
318 | |||
319 | if (!capable(CAP_SYS_ADMIN) || off != 0) | ||
320 | return 0; | ||
321 | |||
322 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
323 | return -ENOTSUPP; | ||
324 | |||
325 | /* Read NVRAM. */ | ||
326 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
327 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); | ||
328 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
329 | |||
330 | return ha->vpd_size; | ||
331 | } | ||
332 | |||
333 | static ssize_t | ||
334 | qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, | ||
335 | size_t count) | ||
336 | { | ||
337 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
338 | struct device, kobj))); | ||
339 | unsigned long flags; | ||
340 | |||
341 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) | ||
342 | return 0; | ||
343 | |||
344 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
345 | return -ENOTSUPP; | ||
346 | |||
347 | /* Write NVRAM. */ | ||
348 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
349 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | ||
350 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
351 | |||
352 | return count; | ||
353 | } | ||
354 | |||
355 | static struct bin_attribute sysfs_vpd_attr = { | ||
356 | .attr = { | ||
357 | .name = "vpd", | ||
358 | .mode = S_IRUSR | S_IWUSR, | ||
359 | .owner = THIS_MODULE, | ||
360 | }, | ||
361 | .size = 0, | ||
362 | .read = qla2x00_sysfs_read_vpd, | ||
363 | .write = qla2x00_sysfs_write_vpd, | ||
364 | }; | ||
365 | |||
311 | void | 366 | void |
312 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 367 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) |
313 | { | 368 | { |
@@ -318,6 +373,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | |||
318 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 373 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
319 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 374 | sysfs_create_bin_file(&host->shost_gendev.kobj, |
320 | &sysfs_optrom_ctl_attr); | 375 | &sysfs_optrom_ctl_attr); |
376 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | ||
321 | } | 377 | } |
322 | 378 | ||
323 | void | 379 | void |
@@ -330,6 +386,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
330 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 386 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
331 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 387 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
332 | &sysfs_optrom_ctl_attr); | 388 | &sysfs_optrom_ctl_attr); |
389 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | ||
333 | 390 | ||
334 | if (ha->beacon_blink_led == 1) | 391 | if (ha->beacon_blink_led == 1) |
335 | ha->isp_ops.beacon_off(ha); | 392 | ha->isp_ops.beacon_off(ha); |
@@ -450,9 +507,6 @@ qla2x00_zio_show(struct class_device *cdev, char *buf) | |||
450 | int len = 0; | 507 | int len = 0; |
451 | 508 | ||
452 | switch (ha->zio_mode) { | 509 | switch (ha->zio_mode) { |
453 | case QLA_ZIO_MODE_5: | ||
454 | len += snprintf(buf + len, PAGE_SIZE-len, "Mode 5\n"); | ||
455 | break; | ||
456 | case QLA_ZIO_MODE_6: | 510 | case QLA_ZIO_MODE_6: |
457 | len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); | 511 | len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); |
458 | break; | 512 | break; |
@@ -470,20 +524,16 @@ qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) | |||
470 | int val = 0; | 524 | int val = 0; |
471 | uint16_t zio_mode; | 525 | uint16_t zio_mode; |
472 | 526 | ||
527 | if (!IS_ZIO_SUPPORTED(ha)) | ||
528 | return -ENOTSUPP; | ||
529 | |||
473 | if (sscanf(buf, "%d", &val) != 1) | 530 | if (sscanf(buf, "%d", &val) != 1) |
474 | return -EINVAL; | 531 | return -EINVAL; |
475 | 532 | ||
476 | switch (val) { | 533 | if (val) |
477 | case 1: | ||
478 | zio_mode = QLA_ZIO_MODE_5; | ||
479 | break; | ||
480 | case 2: | ||
481 | zio_mode = QLA_ZIO_MODE_6; | 534 | zio_mode = QLA_ZIO_MODE_6; |
482 | break; | 535 | else |
483 | default: | ||
484 | zio_mode = QLA_ZIO_DISABLED; | 536 | zio_mode = QLA_ZIO_DISABLED; |
485 | break; | ||
486 | } | ||
487 | 537 | ||
488 | /* Update per-hba values and queue a reset. */ | 538 | /* Update per-hba values and queue a reset. */ |
489 | if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { | 539 | if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { |
@@ -750,7 +800,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
750 | pfc_host_stat = &ha->fc_host_stat; | 800 | pfc_host_stat = &ha->fc_host_stat; |
751 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 801 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
752 | 802 | ||
753 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { | 803 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
754 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, | 804 | rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, |
755 | sizeof(stat_buf) / 4, mb_stat); | 805 | sizeof(stat_buf) / 4, mb_stat); |
756 | } else { | 806 | } else { |