aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r--drivers/scsi/qla4xxx/Makefile2
-rw-r--r--drivers/scsi/qla4xxx/ql4_attr.c69
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h8
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h23
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h3
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c63
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c1
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 @@
1qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ 1qla4xxx-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
4obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o 4obj-$(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. */
13static ssize_t
14qla4xxx_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
31static ssize_t
32qla4xxx_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
39static ssize_t
40qla4xxx_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
48static ssize_t
49qla4xxx_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
58static DEVICE_ATTR(fw_version, S_IRUGO, qla4xxx_fw_version_show, NULL);
59static DEVICE_ATTR(serial_num, S_IRUGO, qla4xxx_serial_num_show, NULL);
60static DEVICE_ATTR(iscsi_version, S_IRUGO, qla4xxx_iscsi_version_show, NULL);
61static DEVICE_ATTR(optrom_version, S_IRUGO, qla4xxx_optrom_version_show, NULL);
62
63struct 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
588static inline int is_ipv4_enabled(struct scsi_qla_host *ha) 596static 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
693struct 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
693struct crash_record { 716struct 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);
61int qla4xxx_add_sess(struct ddb_entry *); 61int qla4xxx_add_sess(struct ddb_entry *);
62void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); 62void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry);
63int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha); 63int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha);
64int qla4xxx_get_fw_version(struct scsi_qla_host * ha); 64int qla4xxx_about_firmware(struct scsi_qla_host *ha);
65void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha, 65void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha,
66 uint32_t intr_status); 66 uint32_t intr_status);
67int qla4xxx_init_rings(struct scsi_qla_host *ha); 67int qla4xxx_init_rings(struct scsi_qla_host *ha);
@@ -139,4 +139,5 @@ extern int ql4xextended_error_logging;
139extern int ql4xdontresethba; 139extern int ql4xdontresethba;
140extern int ql4xenablemsix; 140extern int ql4xenablemsix;
141 141
142extern 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 **/
1053int qla4xxx_get_fw_version(struct scsi_qla_host * ha) 1053int 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; 1101exit_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
1080static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, 1107static 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
129static struct iscsi_transport qla4xxx_iscsi_transport = { 130static struct iscsi_transport qla4xxx_iscsi_transport = {