diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 53 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 36 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 23 |
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 | ||
341 | static ssize_t | ||
342 | qla2x00_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 | |||
378 | static 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 | |||
341 | void | 388 | void |
342 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 389 | qla2x00_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 | ||
354 | void | 404 | void |
@@ -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 *); | |||
210 | extern int | 210 | extern int |
211 | qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | 211 | qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); |
212 | 212 | ||
213 | extern int | ||
214 | qla2x00_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 | ||
2506 | int | ||
2507 | qla2x00_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 | ||