Loading drivers/scsi/qla2xxx/qla_attr.c +144 −0 Original line number Diff line number Diff line Loading @@ -548,6 +548,144 @@ static struct bin_attribute sysfs_reset_attr = { .write = qla2x00_sysfs_write_reset, }; static ssize_t qla2x00_sysfs_write_edc(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; uint16_t dev, adr, opt, len; int rval; ha->edc_data_len = 0; if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8) return 0; if (!ha->edc_data) { ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &ha->edc_data_dma); if (!ha->edc_data) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to allocate memory for EDC write.\n")); return 0; } } dev = le16_to_cpup((void *)&buf[0]); adr = le16_to_cpup((void *)&buf[2]); opt = le16_to_cpup((void *)&buf[4]); len = le16_to_cpup((void *)&buf[6]); if (!(opt & BIT_0)) if (len == 0 || len > DMA_POOL_SIZE || len > count - 8) return -EINVAL; memcpy(ha->edc_data, &buf[8], len); rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma, ha->edc_data, len, opt); if (rval != QLA_SUCCESS) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n", rval, dev, adr, opt, len, *buf)); return 0; } return count; } static struct bin_attribute sysfs_edc_attr = { .attr = { .name = "edc", .mode = S_IWUSR, }, .size = 0, .write = qla2x00_sysfs_write_edc, }; static ssize_t qla2x00_sysfs_write_edc_status(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; uint16_t dev, adr, opt, len; int rval; ha->edc_data_len = 0; if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8) return 0; if (!ha->edc_data) { ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &ha->edc_data_dma); if (!ha->edc_data) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to allocate memory for EDC status.\n")); return 0; } } dev = le16_to_cpup((void *)&buf[0]); adr = le16_to_cpup((void *)&buf[2]); opt = le16_to_cpup((void *)&buf[4]); len = le16_to_cpup((void *)&buf[6]); if (!(opt & BIT_0)) if (len == 0 || len > DMA_POOL_SIZE) return -EINVAL; memset(ha->edc_data, 0, len); rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma, ha->edc_data, len, opt); if (rval != QLA_SUCCESS) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n", rval, dev, adr, opt, len)); return 0; } ha->edc_data_len = len; return count; } static ssize_t qla2x00_sysfs_read_edc_status(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0) return 0; if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count) return -EINVAL; memcpy(buf, ha->edc_data, ha->edc_data_len); return ha->edc_data_len; } static struct bin_attribute sysfs_edc_status_attr = { .attr = { .name = "edc_status", .mode = S_IRUSR | S_IWUSR, }, .size = 0, .write = qla2x00_sysfs_write_edc_status, .read = qla2x00_sysfs_read_edc_status, }; static struct sysfs_entry { char *name; struct bin_attribute *attr; Loading @@ -560,6 +698,8 @@ static struct sysfs_entry { { "vpd", &sysfs_vpd_attr, 1 }, { "sfp", &sysfs_sfp_attr, 1 }, { "reset", &sysfs_reset_attr, }, { "edc", &sysfs_edc_attr, 2 }, { "edc_status", &sysfs_edc_status_attr, 2 }, { NULL }, }; Loading @@ -573,6 +713,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) for (iter = bin_file_entries; iter->name; iter++) { if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw)) continue; if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) continue; ret = sysfs_create_bin_file(&host->shost_gendev.kobj, iter->attr); Loading @@ -593,6 +735,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) for (iter = bin_file_entries; iter->name; iter++) { if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) continue; if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) continue; sysfs_remove_bin_file(&host->shost_gendev.kobj, iter->attr); Loading drivers/scsi/qla2xxx/qla_def.h +5 −0 Original line number Diff line number Diff line Loading @@ -607,6 +607,7 @@ typedef struct { #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ #define MBC_WRITE_SFP 0x30 /* Write SFP Data. */ #define MBC_READ_SFP 0x31 /* Read SFP Data. */ #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ Loading Loading @@ -2387,6 +2388,10 @@ struct qla_hw_data { void *sfp_data; dma_addr_t sfp_data_dma; uint8_t *edc_data; dma_addr_t edc_data_dma; uint16_t edc_data_len; struct task_struct *dpc_thread; uint8_t dpc_active; /* DPC routine is active */ Loading drivers/scsi/qla2xxx/qla_gbl.h +8 −0 Original line number Diff line number Diff line Loading @@ -264,6 +264,14 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *); extern int qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); extern int qla2x00_read_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t, uint8_t *, uint16_t, uint16_t); extern int qla2x00_write_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t, uint8_t *, uint16_t, uint16_t); extern int qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); Loading drivers/scsi/qla2xxx/qla_mbx.c +78 −0 Original line number Diff line number Diff line Loading @@ -3347,3 +3347,81 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) return rval; } int qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr, dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt) { int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); mcp->mb[0] = MBC_READ_SFP; mcp->mb[1] = dev; mcp->mb[2] = MSW(sfp_dma); mcp->mb[3] = LSW(sfp_dma); mcp->mb[6] = MSW(MSD(sfp_dma)); mcp->mb[7] = LSW(MSD(sfp_dma)); mcp->mb[8] = len; mcp->mb[9] = adr; mcp->mb[10] = opt; mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); if (opt & BIT_0) if (sfp) *sfp = mcp->mb[8]; if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, vha->host_no, rval, mcp->mb[0])); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval; } int qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr, dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt) { int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); if (opt & BIT_0) if (sfp) len = *sfp; mcp->mb[0] = MBC_WRITE_SFP; mcp->mb[1] = dev; mcp->mb[2] = MSW(sfp_dma); mcp->mb[3] = LSW(sfp_dma); mcp->mb[6] = MSW(MSD(sfp_dma)); mcp->mb[7] = LSW(MSD(sfp_dma)); mcp->mb[8] = len; mcp->mb[9] = adr; mcp->mb[10] = opt; mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, vha->host_no, rval, mcp->mb[0])); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no)); } return rval; } drivers/scsi/qla2xxx/qla_os.c +3 −0 Original line number Diff line number Diff line Loading @@ -2337,6 +2337,9 @@ qla2x00_mem_free(struct qla_hw_data *ha) if (ha->sfp_data) dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); if (ha->edc_data) dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma); if (ha->ms_iocb) dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); Loading Loading
drivers/scsi/qla2xxx/qla_attr.c +144 −0 Original line number Diff line number Diff line Loading @@ -548,6 +548,144 @@ static struct bin_attribute sysfs_reset_attr = { .write = qla2x00_sysfs_write_reset, }; static ssize_t qla2x00_sysfs_write_edc(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; uint16_t dev, adr, opt, len; int rval; ha->edc_data_len = 0; if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8) return 0; if (!ha->edc_data) { ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &ha->edc_data_dma); if (!ha->edc_data) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to allocate memory for EDC write.\n")); return 0; } } dev = le16_to_cpup((void *)&buf[0]); adr = le16_to_cpup((void *)&buf[2]); opt = le16_to_cpup((void *)&buf[4]); len = le16_to_cpup((void *)&buf[6]); if (!(opt & BIT_0)) if (len == 0 || len > DMA_POOL_SIZE || len > count - 8) return -EINVAL; memcpy(ha->edc_data, &buf[8], len); rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma, ha->edc_data, len, opt); if (rval != QLA_SUCCESS) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n", rval, dev, adr, opt, len, *buf)); return 0; } return count; } static struct bin_attribute sysfs_edc_attr = { .attr = { .name = "edc", .mode = S_IWUSR, }, .size = 0, .write = qla2x00_sysfs_write_edc, }; static ssize_t qla2x00_sysfs_write_edc_status(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; uint16_t dev, adr, opt, len; int rval; ha->edc_data_len = 0; if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8) return 0; if (!ha->edc_data) { ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &ha->edc_data_dma); if (!ha->edc_data) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to allocate memory for EDC status.\n")); return 0; } } dev = le16_to_cpup((void *)&buf[0]); adr = le16_to_cpup((void *)&buf[2]); opt = le16_to_cpup((void *)&buf[4]); len = le16_to_cpup((void *)&buf[6]); if (!(opt & BIT_0)) if (len == 0 || len > DMA_POOL_SIZE) return -EINVAL; memset(ha->edc_data, 0, len); rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma, ha->edc_data, len, opt); if (rval != QLA_SUCCESS) { DEBUG2(qla_printk(KERN_INFO, ha, "Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n", rval, dev, adr, opt, len)); return 0; } ha->edc_data_len = len; return count; } static ssize_t qla2x00_sysfs_read_edc_status(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); struct qla_hw_data *ha = vha->hw; if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0) return 0; if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count) return -EINVAL; memcpy(buf, ha->edc_data, ha->edc_data_len); return ha->edc_data_len; } static struct bin_attribute sysfs_edc_status_attr = { .attr = { .name = "edc_status", .mode = S_IRUSR | S_IWUSR, }, .size = 0, .write = qla2x00_sysfs_write_edc_status, .read = qla2x00_sysfs_read_edc_status, }; static struct sysfs_entry { char *name; struct bin_attribute *attr; Loading @@ -560,6 +698,8 @@ static struct sysfs_entry { { "vpd", &sysfs_vpd_attr, 1 }, { "sfp", &sysfs_sfp_attr, 1 }, { "reset", &sysfs_reset_attr, }, { "edc", &sysfs_edc_attr, 2 }, { "edc_status", &sysfs_edc_status_attr, 2 }, { NULL }, }; Loading @@ -573,6 +713,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) for (iter = bin_file_entries; iter->name; iter++) { if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw)) continue; if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) continue; ret = sysfs_create_bin_file(&host->shost_gendev.kobj, iter->attr); Loading @@ -593,6 +735,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) for (iter = bin_file_entries; iter->name; iter++) { if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) continue; if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) continue; sysfs_remove_bin_file(&host->shost_gendev.kobj, iter->attr); Loading
drivers/scsi/qla2xxx/qla_def.h +5 −0 Original line number Diff line number Diff line Loading @@ -607,6 +607,7 @@ typedef struct { #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ #define MBC_WRITE_SFP 0x30 /* Write SFP Data. */ #define MBC_READ_SFP 0x31 /* Read SFP Data. */ #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ Loading Loading @@ -2387,6 +2388,10 @@ struct qla_hw_data { void *sfp_data; dma_addr_t sfp_data_dma; uint8_t *edc_data; dma_addr_t edc_data_dma; uint16_t edc_data_len; struct task_struct *dpc_thread; uint8_t dpc_active; /* DPC routine is active */ Loading
drivers/scsi/qla2xxx/qla_gbl.h +8 −0 Original line number Diff line number Diff line Loading @@ -264,6 +264,14 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *); extern int qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); extern int qla2x00_read_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t, uint8_t *, uint16_t, uint16_t); extern int qla2x00_write_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t, uint8_t *, uint16_t, uint16_t); extern int qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); Loading
drivers/scsi/qla2xxx/qla_mbx.c +78 −0 Original line number Diff line number Diff line Loading @@ -3347,3 +3347,81 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) return rval; } int qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr, dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt) { int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); mcp->mb[0] = MBC_READ_SFP; mcp->mb[1] = dev; mcp->mb[2] = MSW(sfp_dma); mcp->mb[3] = LSW(sfp_dma); mcp->mb[6] = MSW(MSD(sfp_dma)); mcp->mb[7] = LSW(MSD(sfp_dma)); mcp->mb[8] = len; mcp->mb[9] = adr; mcp->mb[10] = opt; mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); if (opt & BIT_0) if (sfp) *sfp = mcp->mb[8]; if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, vha->host_no, rval, mcp->mb[0])); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); } return rval; } int qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr, dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt) { int rval; mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); if (opt & BIT_0) if (sfp) len = *sfp; mcp->mb[0] = MBC_WRITE_SFP; mcp->mb[1] = dev; mcp->mb[2] = MSW(sfp_dma); mcp->mb[3] = LSW(sfp_dma); mcp->mb[6] = MSW(MSD(sfp_dma)); mcp->mb[7] = LSW(MSD(sfp_dma)); mcp->mb[8] = len; mcp->mb[9] = adr; mcp->mb[10] = opt; mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); if (rval != QLA_SUCCESS) { DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, vha->host_no, rval, mcp->mb[0])); } else { DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no)); } return rval; }
drivers/scsi/qla2xxx/qla_os.c +3 −0 Original line number Diff line number Diff line Loading @@ -2337,6 +2337,9 @@ qla2x00_mem_free(struct qla_hw_data *ha) if (ha->sfp_data) dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); if (ha->edc_data) dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma); if (ha->ms_iocb) dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); Loading