[SCSI] qla2xxx: Add host attributes.
authorAndrew Vasquez <andrew.vasquez@qlogic.com>
Sat, 27 Aug 2005 02:09:40 +0000 (19:09 -0700)
committerJames Bottomley <jejb@mulgrave.(none)>
Mon, 5 Sep 2005 00:53:42 +0000 (19:53 -0500)
Export additional host information via the shost_attrs member in
the scsi_host template.  Attributes include: driver version,
firmware version, ISP serial number, ISP type, ISP product ID,
HBA model name, HBA model description, PCI interconnect
information, and HBA port state.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_os.c

index d05280eecc605703a0493a8e5307402799aba350..fe0fce71adc70153d17abaa0851b15b3a102b862 100644 (file)
@@ -211,6 +211,138 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
        sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
 }
 
+/* Scsi_Host attributes. */
+
+static ssize_t
+qla2x00_drvr_version_show(struct class_device *cdev, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
+}
+
+static ssize_t
+qla2x00_fw_version_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       char fw_str[30];
+
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+           ha->isp_ops.fw_version_str(ha, fw_str));
+}
+
+static ssize_t
+qla2x00_serial_num_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       uint32_t sn;
+
+       sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
+       return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
+           sn % 100000);
+}
+
+static ssize_t
+qla2x00_isp_name_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name);
+}
+
+static ssize_t
+qla2x00_isp_id_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
+           ha->product_id[0], ha->product_id[1], ha->product_id[2],
+           ha->product_id[3]);
+}
+
+static ssize_t
+qla2x00_model_name_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number);
+}
+
+static ssize_t
+qla2x00_model_desc_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+           ha->model_desc ? ha->model_desc: "");
+}
+
+static ssize_t
+qla2x00_pci_info_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       char pci_info[30];
+
+       return snprintf(buf, PAGE_SIZE, "%s\n",
+           ha->isp_ops.pci_info_str(ha, pci_info));
+}
+
+static ssize_t
+qla2x00_state_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       int len = 0;
+
+       if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
+           atomic_read(&ha->loop_state) == LOOP_DEAD)
+               len = snprintf(buf, PAGE_SIZE, "Link Down\n");
+       else if (atomic_read(&ha->loop_state) != LOOP_READY ||
+           test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
+           test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags))
+               len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
+       else {
+               len = snprintf(buf, PAGE_SIZE, "Link Up - ");
+
+               switch (ha->current_topology) {
+               case ISP_CFG_NL:
+                       len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
+                       break;
+               case ISP_CFG_FL:
+                       len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");
+                       break;
+               case ISP_CFG_N:
+                       len += snprintf(buf + len, PAGE_SIZE-len,
+                           "N_Port to N_Port\n");
+                       break;
+               case ISP_CFG_F:
+                       len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n");
+                       break;
+               default:
+                       len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
+                       break;
+               }
+       }
+       return len;
+}
+
+static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
+       NULL);
+static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
+static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
+static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
+static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL);
+static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);
+static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);
+static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);
+static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);
+
+struct class_device_attribute *qla2x00_host_attrs[] = {
+       &class_device_attr_driver_version,
+       &class_device_attr_fw_version,
+       &class_device_attr_serial_num,
+       &class_device_attr_isp_name,
+       &class_device_attr_isp_id,
+       &class_device_attr_model_name,
+       &class_device_attr_model_desc,
+       &class_device_attr_pci_info,
+       &class_device_attr_state,
+       NULL,
+};
+
 /* Host attributes. */
 
 static void
index 5deaa7e6ee6092dc1c91dd75112feafbfa1147c7..95fb0c4941aa712ef04383ca734dec92f4909f53 100644 (file)
@@ -290,6 +290,8 @@ extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *);
 /*
  * Global Function Prototypes in qla_attr.c source file.
  */
+struct class_device_attribute;
+extern struct class_device_attribute *qla2x00_host_attrs[];
 struct fc_function_template;
 extern struct fc_function_template qla2xxx_transport_functions;
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
index 413ccc152de5d3f3e8b595e0b5081db936379f44..14f2f9077c81c4e27707490001f5c5e9d124bbf5 100644 (file)
@@ -140,6 +140,7 @@ static struct scsi_host_template qla2x00_driver_template = {
         * which equates to 0x800000 sectors.
         */
        .max_sectors            = 0xFFFF,
+       .shost_attrs            = qla2x00_host_attrs,
 };
 
 static struct scsi_host_template qla24xx_driver_template = {
@@ -164,6 +165,7 @@ static struct scsi_host_template qla24xx_driver_template = {
        .sg_tablesize           = SG_ALL,
 
        .max_sectors            = 0xFFFF,
+       .shost_attrs            = qla2x00_host_attrs,
 };
 
 static struct scsi_transport_template *qla2xxx_transport_template = NULL;