aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c53
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c36
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c23
5 files changed, 121 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 78eec6799343..1a766b284cfc 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -338,6 +338,53 @@ static struct bin_attribute sysfs_vpd_attr = {
338 .write = qla2x00_sysfs_write_vpd, 338 .write = qla2x00_sysfs_write_vpd,
339}; 339};
340 340
341static ssize_t
342qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off,
343 size_t count)
344{
345 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
346 struct device, kobj)));
347 uint16_t iter, addr, offset;
348 int rval;
349
350 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2)
351 return 0;
352
353 addr = 0xa0;
354 for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE;
355 iter++, offset += SFP_BLOCK_SIZE) {
356 if (iter == 4) {
357 /* Skip to next device address. */
358 addr = 0xa2;
359 offset = 0;
360 }
361
362 rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset,
363 SFP_BLOCK_SIZE);
364 if (rval != QLA_SUCCESS) {
365 qla_printk(KERN_WARNING, ha,
366 "Unable to read SFP data (%x/%x/%x).\n", rval,
367 addr, offset);
368 count = 0;
369 break;
370 }
371 memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE);
372 buf += SFP_BLOCK_SIZE;
373 }
374
375 return count;
376}
377
378static struct bin_attribute sysfs_sfp_attr = {
379 .attr = {
380 .name = "sfp",
381 .mode = S_IRUSR | S_IWUSR,
382 .owner = THIS_MODULE,
383 },
384 .size = SFP_DEV_SIZE * 2,
385 .read = qla2x00_sysfs_read_sfp,
386};
387
341void 388void
342qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) 389qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
343{ 390{
@@ -349,6 +396,9 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
349 sysfs_create_bin_file(&host->shost_gendev.kobj, 396 sysfs_create_bin_file(&host->shost_gendev.kobj,
350 &sysfs_optrom_ctl_attr); 397 &sysfs_optrom_ctl_attr);
351 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); 398 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr);
399 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
400 sysfs_create_bin_file(&host->shost_gendev.kobj,
401 &sysfs_sfp_attr);
352} 402}
353 403
354void 404void
@@ -362,6 +412,9 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
362 sysfs_remove_bin_file(&host->shost_gendev.kobj, 412 sysfs_remove_bin_file(&host->shost_gendev.kobj,
363 &sysfs_optrom_ctl_attr); 413 &sysfs_optrom_ctl_attr);
364 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); 414 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr);
415 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
416 sysfs_remove_bin_file(&host->shost_gendev.kobj,
417 &sysfs_sfp_attr);
365 418
366 if (ha->beacon_blink_led == 1) 419 if (ha->beacon_blink_led == 1)
367 ha->isp_ops.beacon_off(ha); 420 ha->isp_ops.beacon_off(ha);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index dfcd3a2dd7c1..bb0b5f5e31a5 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -610,6 +610,7 @@ typedef struct {
610#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ 610#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
611#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ 611#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
612#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ 612#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
613#define MBC_READ_SFP 0x31 /* Read SFP Data. */
613#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ 614#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */
614#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ 615#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */
615#define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ 616#define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */
@@ -2242,6 +2243,11 @@ typedef struct scsi_qla_host {
2242 struct sns_cmd_pkt *sns_cmd; 2243 struct sns_cmd_pkt *sns_cmd;
2243 dma_addr_t sns_cmd_dma; 2244 dma_addr_t sns_cmd_dma;
2244 2245
2246#define SFP_DEV_SIZE 256
2247#define SFP_BLOCK_SIZE 64
2248 void *sfp_data;
2249 dma_addr_t sfp_data_dma;
2250
2245 struct task_struct *dpc_thread; 2251 struct task_struct *dpc_thread;
2246 uint8_t dpc_active; /* DPC routine is active */ 2252 uint8_t dpc_active; /* DPC routine is active */
2247 2253
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fec1e1c9381f..4edb5d11b775 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -210,6 +210,9 @@ qla2x00_stop_firmware(scsi_qla_host_t *);
210extern int 210extern int
211qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); 211qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t);
212 212
213extern int
214qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
215
213/* 216/*
214 * Global Function Prototypes in qla_isr.c source file. 217 * Global Function Prototypes in qla_isr.c source file.
215 */ 218 */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 3b16d6f2ee90..f5e226fc9e35 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2503,4 +2503,40 @@ qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma,
2503 return rval; 2503 return rval;
2504} 2504}
2505 2505
2506int
2507qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
2508 uint16_t off, uint16_t count)
2509{
2510 int rval;
2511 mbx_cmd_t mc;
2512 mbx_cmd_t *mcp = &mc;
2506 2513
2514 if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
2515 return QLA_FUNCTION_FAILED;
2516
2517 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
2518
2519 mcp->mb[0] = MBC_READ_SFP;
2520 mcp->mb[1] = addr;
2521 mcp->mb[2] = MSW(sfp_dma);
2522 mcp->mb[3] = LSW(sfp_dma);
2523 mcp->mb[6] = MSW(MSD(sfp_dma));
2524 mcp->mb[7] = LSW(MSD(sfp_dma));
2525 mcp->mb[8] = count;
2526 mcp->mb[9] = off;
2527 mcp->mb[10] = 0;
2528 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2529 mcp->in_mb = MBX_0;
2530 mcp->tov = 30;
2531 mcp->flags = 0;
2532 rval = qla2x00_mailbox_command(ha, mcp);
2533
2534 if (rval != QLA_SUCCESS) {
2535 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
2536 ha->host_no, rval, mcp->mb[0]));
2537 } else {
2538 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
2539 }
2540
2541 return rval;
2542}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c16154c51298..da84ee2d090b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1979,6 +1979,26 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
1979 continue; 1979 continue;
1980 } 1980 }
1981 memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); 1981 memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
1982
1983 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
1984 /*
1985 * Get consistent memory allocated for SFP
1986 * block.
1987 */
1988 ha->sfp_data = dma_pool_alloc(ha->s_dma_pool,
1989 GFP_KERNEL, &ha->sfp_data_dma);
1990 if (ha->sfp_data == NULL) {
1991 qla_printk(KERN_WARNING, ha,
1992 "Memory Allocation failed - "
1993 "sfp_data\n");
1994
1995 qla2x00_mem_free(ha);
1996 msleep(100);
1997
1998 continue;
1999 }
2000 memset(ha->sfp_data, 0, SFP_BLOCK_SIZE);
2001 }
1982 } 2002 }
1983 2003
1984 /* Done all allocations without any error. */ 2004 /* Done all allocations without any error. */
@@ -2034,6 +2054,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2034 dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), 2054 dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
2035 ha->ct_sns, ha->ct_sns_dma); 2055 ha->ct_sns, ha->ct_sns_dma);
2036 2056
2057 if (ha->sfp_data)
2058 dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
2059
2037 if (ha->ms_iocb) 2060 if (ha->ms_iocb)
2038 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); 2061 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
2039 2062