aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 2b9e329a240c..488b3d16427b 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -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
311static ssize_t
312qla2x00_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
333static ssize_t
334qla2x00_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
355static 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
311void 366void
312qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) 367qla2x00_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
323void 379void
@@ -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);