diff options
author | Harish Zunjarrao <harish.zunjarrao@qlogic.com> | 2011-05-18 02:17:11 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-24 12:40:23 -0400 |
commit | 7ad633c06b6f1498cf26922b165837b121f27519 (patch) | |
tree | ede1e79f40c30cd65021dce68f8c906da2165144 | |
parent | 8f0722cae6a799e0cd5f1eb5ed4569a11f8dcf79 (diff) |
[SCSI] qla4xxx: Added vendor specific sysfs attributes
Added fw_version, serial_num, iscsi version and boot loader version
sysfs attributes.
Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <jbottomley@parallels.com>
-rw-r--r-- | drivers/scsi/qla4xxx/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_attr.c | 69 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 8 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_fw.h | 23 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_glbl.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 63 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 1 |
8 files changed, 150 insertions, 21 deletions
diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile index 0339ff03a535..252523d7847e 100644 --- a/drivers/scsi/qla4xxx/Makefile +++ b/drivers/scsi/qla4xxx/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ | 1 | qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ |
2 | ql4_nx.o ql4_nvram.o ql4_dbg.o | 2 | ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o |
3 | 3 | ||
4 | obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o | 4 | obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o |
5 | 5 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c new file mode 100644 index 000000000000..864d018631c0 --- /dev/null +++ b/drivers/scsi/qla4xxx/ql4_attr.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * QLogic iSCSI HBA Driver | ||
3 | * Copyright (c) 2003-2011 QLogic Corporation | ||
4 | * | ||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | ||
6 | */ | ||
7 | |||
8 | #include "ql4_def.h" | ||
9 | #include "ql4_glbl.h" | ||
10 | #include "ql4_dbg.h" | ||
11 | |||
12 | /* Scsi_Host attributes. */ | ||
13 | static ssize_t | ||
14 | qla4xxx_fw_version_show(struct device *dev, | ||
15 | struct device_attribute *attr, char *buf) | ||
16 | { | ||
17 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
18 | |||
19 | if (is_qla8022(ha)) | ||
20 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", | ||
21 | ha->firmware_version[0], | ||
22 | ha->firmware_version[1], | ||
23 | ha->patch_number, ha->build_number); | ||
24 | else | ||
25 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d.%02d\n", | ||
26 | ha->firmware_version[0], | ||
27 | ha->firmware_version[1], | ||
28 | ha->patch_number, ha->build_number); | ||
29 | } | ||
30 | |||
31 | static ssize_t | ||
32 | qla4xxx_serial_num_show(struct device *dev, struct device_attribute *attr, | ||
33 | char *buf) | ||
34 | { | ||
35 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
36 | return snprintf(buf, PAGE_SIZE, "%s\n", ha->serial_number); | ||
37 | } | ||
38 | |||
39 | static ssize_t | ||
40 | qla4xxx_iscsi_version_show(struct device *dev, struct device_attribute *attr, | ||
41 | char *buf) | ||
42 | { | ||
43 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
44 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->iscsi_major, | ||
45 | ha->iscsi_minor); | ||
46 | } | ||
47 | |||
48 | static ssize_t | ||
49 | qla4xxx_optrom_version_show(struct device *dev, struct device_attribute *attr, | ||
50 | char *buf) | ||
51 | { | ||
52 | struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev)); | ||
53 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d.%02d\n", | ||
54 | ha->bootload_major, ha->bootload_minor, | ||
55 | ha->bootload_patch, ha->bootload_build); | ||
56 | } | ||
57 | |||
58 | static DEVICE_ATTR(fw_version, S_IRUGO, qla4xxx_fw_version_show, NULL); | ||
59 | static DEVICE_ATTR(serial_num, S_IRUGO, qla4xxx_serial_num_show, NULL); | ||
60 | static DEVICE_ATTR(iscsi_version, S_IRUGO, qla4xxx_iscsi_version_show, NULL); | ||
61 | static DEVICE_ATTR(optrom_version, S_IRUGO, qla4xxx_optrom_version_show, NULL); | ||
62 | |||
63 | struct device_attribute *qla4xxx_host_attrs[] = { | ||
64 | &dev_attr_fw_version, | ||
65 | &dev_attr_serial_num, | ||
66 | &dev_attr_iscsi_version, | ||
67 | &dev_attr_optrom_version, | ||
68 | NULL, | ||
69 | }; | ||
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 8e3a28e300a4..473c5c872b39 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -583,6 +583,14 @@ struct scsi_qla_host { | |||
583 | uint32_t nx_reset_timeout; | 583 | uint32_t nx_reset_timeout; |
584 | 584 | ||
585 | struct completion mbx_intr_comp; | 585 | struct completion mbx_intr_comp; |
586 | |||
587 | /* --- From About Firmware --- */ | ||
588 | uint16_t iscsi_major; | ||
589 | uint16_t iscsi_minor; | ||
590 | uint16_t bootload_major; | ||
591 | uint16_t bootload_minor; | ||
592 | uint16_t bootload_patch; | ||
593 | uint16_t bootload_build; | ||
586 | }; | 594 | }; |
587 | 595 | ||
588 | static inline int is_ipv4_enabled(struct scsi_qla_host *ha) | 596 | static inline int is_ipv4_enabled(struct scsi_qla_host *ha) |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 31e2bf97198c..01082aa77098 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -690,6 +690,29 @@ struct mbx_sys_info { | |||
690 | uint8_t reserved[12]; /* 34-3f */ | 690 | uint8_t reserved[12]; /* 34-3f */ |
691 | }; | 691 | }; |
692 | 692 | ||
693 | struct about_fw_info { | ||
694 | uint16_t fw_major; /* 00 - 01 */ | ||
695 | uint16_t fw_minor; /* 02 - 03 */ | ||
696 | uint16_t fw_patch; /* 04 - 05 */ | ||
697 | uint16_t fw_build; /* 06 - 07 */ | ||
698 | uint8_t fw_build_date[16]; /* 08 - 17 ASCII String */ | ||
699 | uint8_t fw_build_time[16]; /* 18 - 27 ASCII String */ | ||
700 | uint8_t fw_build_user[16]; /* 28 - 37 ASCII String */ | ||
701 | uint16_t fw_load_source; /* 38 - 39 */ | ||
702 | /* 1 = Flash Primary, | ||
703 | 2 = Flash Secondary, | ||
704 | 3 = Host Download | ||
705 | */ | ||
706 | uint8_t reserved1[6]; /* 3A - 3F */ | ||
707 | uint16_t iscsi_major; /* 40 - 41 */ | ||
708 | uint16_t iscsi_minor; /* 42 - 43 */ | ||
709 | uint16_t bootload_major; /* 44 - 45 */ | ||
710 | uint16_t bootload_minor; /* 46 - 47 */ | ||
711 | uint16_t bootload_patch; /* 48 - 49 */ | ||
712 | uint16_t bootload_build; /* 4A - 4B */ | ||
713 | uint8_t reserved2[180]; /* 4C - FF */ | ||
714 | }; | ||
715 | |||
693 | struct crash_record { | 716 | struct crash_record { |
694 | uint16_t fw_major_version; /* 00 - 01 */ | 717 | uint16_t fw_major_version; /* 00 - 01 */ |
695 | uint16_t fw_minor_version; /* 02 - 03 */ | 718 | uint16_t fw_minor_version; /* 02 - 03 */ |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index cc53e3fbd78c..a53a256c1f8d 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -61,7 +61,7 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha); | |||
61 | int qla4xxx_add_sess(struct ddb_entry *); | 61 | int qla4xxx_add_sess(struct ddb_entry *); |
62 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); | 62 | void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); |
63 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); | 63 | int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); |
64 | int qla4xxx_get_fw_version(struct scsi_qla_host * ha); | 64 | int qla4xxx_about_firmware(struct scsi_qla_host *ha); |
65 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, | 65 | void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, |
66 | uint32_t intr_status); | 66 | uint32_t intr_status); |
67 | int qla4xxx_init_rings(struct scsi_qla_host *ha); | 67 | int qla4xxx_init_rings(struct scsi_qla_host *ha); |
@@ -139,4 +139,5 @@ extern int ql4xextended_error_logging; | |||
139 | extern int ql4xdontresethba; | 139 | extern int ql4xdontresethba; |
140 | extern int ql4xenablemsix; | 140 | extern int ql4xenablemsix; |
141 | 141 | ||
142 | extern struct device_attribute *qla4xxx_host_attrs[]; | ||
142 | #endif /* _QLA4x_GBL_H */ | 143 | #endif /* _QLA4x_GBL_H */ |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 48e2241ddaf4..42ed5db2d530 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -1275,7 +1275,7 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, | |||
1275 | if (ha->isp_ops->start_firmware(ha) == QLA_ERROR) | 1275 | if (ha->isp_ops->start_firmware(ha) == QLA_ERROR) |
1276 | goto exit_init_hba; | 1276 | goto exit_init_hba; |
1277 | 1277 | ||
1278 | if (qla4xxx_get_fw_version(ha) == QLA_ERROR) | 1278 | if (qla4xxx_about_firmware(ha) == QLA_ERROR) |
1279 | goto exit_init_hba; | 1279 | goto exit_init_hba; |
1280 | 1280 | ||
1281 | if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR) | 1281 | if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR) |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index b768a0366f7b..fce8289e9752 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -1043,38 +1043,65 @@ int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | |||
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | /** | 1045 | /** |
1046 | * qla4xxx_get_fw_version - gets firmware version | 1046 | * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version |
1047 | * @ha: Pointer to host adapter structure. | 1047 | * @ha: Pointer to host adapter structure. |
1048 | * | 1048 | * |
1049 | * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may | 1049 | * Retrieves the FW version, iSCSI draft version & bootloader version of HBA. |
1050 | * hold an address for data. Make sure that we write 0 to those mailboxes, | 1050 | * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to |
1051 | * if unused. | 1051 | * those mailboxes, if unused. |
1052 | **/ | 1052 | **/ |
1053 | int qla4xxx_get_fw_version(struct scsi_qla_host * ha) | 1053 | int qla4xxx_about_firmware(struct scsi_qla_host *ha) |
1054 | { | 1054 | { |
1055 | struct about_fw_info *about_fw = NULL; | ||
1056 | dma_addr_t about_fw_dma; | ||
1055 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | 1057 | uint32_t mbox_cmd[MBOX_REG_COUNT]; |
1056 | uint32_t mbox_sts[MBOX_REG_COUNT]; | 1058 | uint32_t mbox_sts[MBOX_REG_COUNT]; |
1059 | int status = QLA_ERROR; | ||
1060 | |||
1061 | about_fw = dma_alloc_coherent(&ha->pdev->dev, | ||
1062 | sizeof(struct about_fw_info), | ||
1063 | &about_fw_dma, GFP_KERNEL); | ||
1064 | if (!about_fw) { | ||
1065 | DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory " | ||
1066 | "for about_fw\n", __func__)); | ||
1067 | return status; | ||
1068 | } | ||
1057 | 1069 | ||
1058 | /* Get firmware version. */ | 1070 | memset(about_fw, 0, sizeof(struct about_fw_info)); |
1059 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | 1071 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); |
1060 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | 1072 | memset(&mbox_sts, 0, sizeof(mbox_sts)); |
1061 | 1073 | ||
1062 | mbox_cmd[0] = MBOX_CMD_ABOUT_FW; | 1074 | mbox_cmd[0] = MBOX_CMD_ABOUT_FW; |
1063 | 1075 | mbox_cmd[2] = LSDW(about_fw_dma); | |
1064 | if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) != | 1076 | mbox_cmd[3] = MSDW(about_fw_dma); |
1065 | QLA_SUCCESS) { | 1077 | mbox_cmd[4] = sizeof(struct about_fw_info); |
1066 | DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ " | 1078 | |
1067 | "status %04X\n", ha->host_no, __func__, mbox_sts[0])); | 1079 | status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT, |
1068 | return QLA_ERROR; | 1080 | &mbox_cmd[0], &mbox_sts[0]); |
1081 | if (status != QLA_SUCCESS) { | ||
1082 | DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW " | ||
1083 | "failed w/ status %04X\n", __func__, | ||
1084 | mbox_sts[0])); | ||
1085 | goto exit_about_fw; | ||
1069 | } | 1086 | } |
1070 | 1087 | ||
1071 | /* Save firmware version information. */ | 1088 | /* Save version information. */ |
1072 | ha->firmware_version[0] = mbox_sts[1]; | 1089 | ha->firmware_version[0] = le16_to_cpu(about_fw->fw_major); |
1073 | ha->firmware_version[1] = mbox_sts[2]; | 1090 | ha->firmware_version[1] = le16_to_cpu(about_fw->fw_minor); |
1074 | ha->patch_number = mbox_sts[3]; | 1091 | ha->patch_number = le16_to_cpu(about_fw->fw_patch); |
1075 | ha->build_number = mbox_sts[4]; | 1092 | ha->build_number = le16_to_cpu(about_fw->fw_build); |
1093 | ha->iscsi_major = le16_to_cpu(about_fw->iscsi_major); | ||
1094 | ha->iscsi_minor = le16_to_cpu(about_fw->iscsi_minor); | ||
1095 | ha->bootload_major = le16_to_cpu(about_fw->bootload_major); | ||
1096 | ha->bootload_minor = le16_to_cpu(about_fw->bootload_minor); | ||
1097 | ha->bootload_patch = le16_to_cpu(about_fw->bootload_patch); | ||
1098 | ha->bootload_build = le16_to_cpu(about_fw->bootload_build); | ||
1099 | status = QLA_SUCCESS; | ||
1076 | 1100 | ||
1077 | return QLA_SUCCESS; | 1101 | exit_about_fw: |
1102 | dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info), | ||
1103 | about_fw, about_fw_dma); | ||
1104 | return status; | ||
1078 | } | 1105 | } |
1079 | 1106 | ||
1080 | static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, | 1107 | static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 9bfe9ce28740..f2364ec59f03 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -124,6 +124,7 @@ static struct scsi_host_template qla4xxx_driver_template = { | |||
124 | .sg_tablesize = SG_ALL, | 124 | .sg_tablesize = SG_ALL, |
125 | 125 | ||
126 | .max_sectors = 0xFFFF, | 126 | .max_sectors = 0xFFFF, |
127 | .shost_attrs = qla4xxx_host_attrs, | ||
127 | }; | 128 | }; |
128 | 129 | ||
129 | static struct iscsi_transport qla4xxx_iscsi_transport = { | 130 | static struct iscsi_transport qla4xxx_iscsi_transport = { |