diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 52 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 37 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 4 |
6 files changed, 101 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index e8c1c9e01a7b..9aa00f25aa6a 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -744,6 +744,57 @@ static struct bin_attribute sysfs_xgmac_stats_attr = { | |||
744 | .read = qla2x00_sysfs_read_xgmac_stats, | 744 | .read = qla2x00_sysfs_read_xgmac_stats, |
745 | }; | 745 | }; |
746 | 746 | ||
747 | static ssize_t | ||
748 | qla2x00_sysfs_read_dcbx_tlv(struct kobject *kobj, | ||
749 | struct bin_attribute *bin_attr, | ||
750 | char *buf, loff_t off, size_t count) | ||
751 | { | ||
752 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | ||
753 | struct device, kobj))); | ||
754 | struct qla_hw_data *ha = vha->hw; | ||
755 | int rval; | ||
756 | uint16_t actual_size; | ||
757 | |||
758 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count > DCBX_TLV_DATA_SIZE) | ||
759 | return 0; | ||
760 | |||
761 | if (ha->dcbx_tlv) | ||
762 | goto do_read; | ||
763 | |||
764 | ha->dcbx_tlv = dma_alloc_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, | ||
765 | &ha->dcbx_tlv_dma, GFP_KERNEL); | ||
766 | if (!ha->dcbx_tlv) { | ||
767 | qla_printk(KERN_WARNING, ha, | ||
768 | "Unable to allocate memory for DCBX TLV read-data.\n"); | ||
769 | return 0; | ||
770 | } | ||
771 | |||
772 | do_read: | ||
773 | actual_size = 0; | ||
774 | memset(ha->dcbx_tlv, 0, DCBX_TLV_DATA_SIZE); | ||
775 | |||
776 | rval = qla2x00_get_dcbx_params(vha, ha->dcbx_tlv_dma, | ||
777 | DCBX_TLV_DATA_SIZE); | ||
778 | if (rval != QLA_SUCCESS) { | ||
779 | qla_printk(KERN_WARNING, ha, | ||
780 | "Unable to read DCBX TLV data (%x).\n", rval); | ||
781 | count = 0; | ||
782 | } | ||
783 | |||
784 | memcpy(buf, ha->dcbx_tlv, count); | ||
785 | |||
786 | return count; | ||
787 | } | ||
788 | |||
789 | static struct bin_attribute sysfs_dcbx_tlv_attr = { | ||
790 | .attr = { | ||
791 | .name = "dcbx_tlv", | ||
792 | .mode = S_IRUSR, | ||
793 | }, | ||
794 | .size = 0, | ||
795 | .read = qla2x00_sysfs_read_dcbx_tlv, | ||
796 | }; | ||
797 | |||
747 | static struct sysfs_entry { | 798 | static struct sysfs_entry { |
748 | char *name; | 799 | char *name; |
749 | struct bin_attribute *attr; | 800 | struct bin_attribute *attr; |
@@ -759,6 +810,7 @@ static struct sysfs_entry { | |||
759 | { "edc", &sysfs_edc_attr, 2 }, | 810 | { "edc", &sysfs_edc_attr, 2 }, |
760 | { "edc_status", &sysfs_edc_status_attr, 2 }, | 811 | { "edc_status", &sysfs_edc_status_attr, 2 }, |
761 | { "xgmac_stats", &sysfs_xgmac_stats_attr, 3 }, | 812 | { "xgmac_stats", &sysfs_xgmac_stats_attr, 3 }, |
813 | { "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 }, | ||
762 | { NULL }, | 814 | { NULL }, |
763 | }; | 815 | }; |
764 | 816 | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index da941be9b182..bb6bfd7b35f3 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2401,6 +2401,10 @@ struct qla_hw_data { | |||
2401 | void *xgmac_data; | 2401 | void *xgmac_data; |
2402 | dma_addr_t xgmac_data_dma; | 2402 | dma_addr_t xgmac_data_dma; |
2403 | 2403 | ||
2404 | #define DCBX_TLV_DATA_SIZE PAGE_SIZE | ||
2405 | void *dcbx_tlv; | ||
2406 | dma_addr_t dcbx_tlv_dma; | ||
2407 | |||
2404 | struct task_struct *dpc_thread; | 2408 | struct task_struct *dpc_thread; |
2405 | uint8_t dpc_active; /* DPC routine is active */ | 2409 | uint8_t dpc_active; /* DPC routine is active */ |
2406 | 2410 | ||
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 80ab46cfaca6..152d16c77f3e 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1406,6 +1406,7 @@ struct access_chip_rsp_84xx { | |||
1406 | #define MBC_RESTART_MPI_FW 0x3d | 1406 | #define MBC_RESTART_MPI_FW 0x3d |
1407 | #define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */ | 1407 | #define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */ |
1408 | #define MBC_GET_XGMAC_STATS 0x7a | 1408 | #define MBC_GET_XGMAC_STATS 0x7a |
1409 | #define MBC_GET_DCBX_PARAMS 0x51 | ||
1409 | 1410 | ||
1410 | /* Flash access control option field bit definitions */ | 1411 | /* Flash access control option field bit definitions */ |
1411 | #define FAC_OPT_FORCE_SEMAPHORE BIT_15 | 1412 | #define FAC_OPT_FORCE_SEMAPHORE BIT_15 |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 66ba3997c91c..fbf99726e551 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -296,6 +296,9 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t); | |||
296 | extern int | 296 | extern int |
297 | qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *); | 297 | qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *); |
298 | 298 | ||
299 | extern int | ||
300 | qla2x00_get_dcbx_params(scsi_qla_host_t *, dma_addr_t, uint16_t); | ||
301 | |||
299 | /* | 302 | /* |
300 | * Global Function Prototypes in qla_isr.c source file. | 303 | * Global Function Prototypes in qla_isr.c source file. |
301 | */ | 304 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 2497fe4ce5aa..e0fee484f79c 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -3500,3 +3500,40 @@ qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma, | |||
3500 | 3500 | ||
3501 | return rval; | 3501 | return rval; |
3502 | } | 3502 | } |
3503 | |||
3504 | int | ||
3505 | qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma, | ||
3506 | uint16_t size) | ||
3507 | { | ||
3508 | int rval; | ||
3509 | mbx_cmd_t mc; | ||
3510 | mbx_cmd_t *mcp = &mc; | ||
3511 | |||
3512 | if (!IS_QLA81XX(vha->hw)) | ||
3513 | return QLA_FUNCTION_FAILED; | ||
3514 | |||
3515 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | ||
3516 | |||
3517 | mcp->mb[0] = MBC_GET_DCBX_PARAMS; | ||
3518 | mcp->mb[1] = 0; | ||
3519 | mcp->mb[2] = MSW(tlv_dma); | ||
3520 | mcp->mb[3] = LSW(tlv_dma); | ||
3521 | mcp->mb[6] = MSW(MSD(tlv_dma)); | ||
3522 | mcp->mb[7] = LSW(MSD(tlv_dma)); | ||
3523 | mcp->mb[8] = size; | ||
3524 | mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | ||
3525 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
3526 | mcp->tov = MBX_TOV_SECONDS; | ||
3527 | mcp->flags = 0; | ||
3528 | rval = qla2x00_mailbox_command(vha, mcp); | ||
3529 | |||
3530 | if (rval != QLA_SUCCESS) { | ||
3531 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x " | ||
3532 | "mb[1]=0x%x mb[2]=0x%x.\n", __func__, vha->host_no, rval, | ||
3533 | mcp->mb[0], mcp->mb[1], mcp->mb[2])); | ||
3534 | } else { | ||
3535 | DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no)); | ||
3536 | } | ||
3537 | |||
3538 | return rval; | ||
3539 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 642e976083e8..7415ead92154 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2434,6 +2434,10 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
2434 | vfree(ha->fw_dump); | 2434 | vfree(ha->fw_dump); |
2435 | } | 2435 | } |
2436 | 2436 | ||
2437 | if (ha->dcbx_tlv) | ||
2438 | dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, | ||
2439 | ha->dcbx_tlv, ha->dcbx_tlv_dma); | ||
2440 | |||
2437 | if (ha->xgmac_data) | 2441 | if (ha->xgmac_data) |
2438 | dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, | 2442 | dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, |
2439 | ha->xgmac_data, ha->xgmac_data_dma); | 2443 | ha->xgmac_data, ha->xgmac_data_dma); |