diff options
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 113 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 4 |
3 files changed, 106 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 2c3e171da8cb..80719bb3511e 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -29,7 +29,8 @@ struct lpfc_sli2_slim; | |||
29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact | 29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact |
30 | the NameServer before giving up. */ | 30 | the NameServer before giving up. */ |
31 | #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ | 31 | #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ |
32 | #define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ | 32 | #define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ |
33 | #define LPFC_MAX_SG_SEG_CNT 256 /* sg element count per scsi cmnd */ | ||
33 | #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ | 34 | #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ |
34 | #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ | 35 | #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ |
35 | 36 | ||
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index eb5a5ad4ffbf..4bae4a2ed2f1 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -45,6 +45,10 @@ | |||
45 | #define LPFC_MIN_DEVLOSS_TMO 1 | 45 | #define LPFC_MIN_DEVLOSS_TMO 1 |
46 | #define LPFC_MAX_DEVLOSS_TMO 255 | 46 | #define LPFC_MAX_DEVLOSS_TMO 255 |
47 | 47 | ||
48 | #define LPFC_MAX_LINK_SPEED 8 | ||
49 | #define LPFC_LINK_SPEED_BITMAP 0x00000117 | ||
50 | #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8" | ||
51 | |||
48 | static void | 52 | static void |
49 | lpfc_jedec_to_ascii(int incr, char hdw[]) | 53 | lpfc_jedec_to_ascii(int incr, char hdw[]) |
50 | { | 54 | { |
@@ -258,8 +262,7 @@ lpfc_issue_lip(struct Scsi_Host *shost) | |||
258 | int mbxstatus = MBXERR_ERROR; | 262 | int mbxstatus = MBXERR_ERROR; |
259 | 263 | ||
260 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 264 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
261 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) || | 265 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)) |
262 | (vport->port_state != LPFC_VPORT_READY)) | ||
263 | return -EPERM; | 266 | return -EPERM; |
264 | 267 | ||
265 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); | 268 | pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); |
@@ -1405,7 +1408,33 @@ LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1, | |||
1405 | # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. | 1408 | # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. |
1406 | # Default value is 0. | 1409 | # Default value is 0. |
1407 | */ | 1410 | */ |
1408 | LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); | 1411 | static int |
1412 | lpfc_topology_set(struct lpfc_hba *phba, int val) | ||
1413 | { | ||
1414 | int err; | ||
1415 | uint32_t prev_val; | ||
1416 | if (val >= 0 && val <= 6) { | ||
1417 | prev_val = phba->cfg_topology; | ||
1418 | phba->cfg_topology = val; | ||
1419 | err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport)); | ||
1420 | if (err) | ||
1421 | phba->cfg_topology = prev_val; | ||
1422 | return err; | ||
1423 | } | ||
1424 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1425 | "%d:0467 lpfc_topology attribute cannot be set to %d, " | ||
1426 | "allowed range is [0, 6]\n", | ||
1427 | phba->brd_no, val); | ||
1428 | return -EINVAL; | ||
1429 | } | ||
1430 | static int lpfc_topology = 0; | ||
1431 | module_param(lpfc_topology, int, 0); | ||
1432 | MODULE_PARM_DESC(lpfc_topology, "Select Fibre Channel topology"); | ||
1433 | lpfc_param_show(topology) | ||
1434 | lpfc_param_init(topology, 0, 0, 6) | ||
1435 | lpfc_param_store(topology) | ||
1436 | static CLASS_DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR, | ||
1437 | lpfc_topology_show, lpfc_topology_store); | ||
1409 | 1438 | ||
1410 | /* | 1439 | /* |
1411 | # lpfc_link_speed: Link speed selection for initializing the Fibre Channel | 1440 | # lpfc_link_speed: Link speed selection for initializing the Fibre Channel |
@@ -1417,7 +1446,59 @@ LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); | |||
1417 | # 8 = 8 Gigabaud | 1446 | # 8 = 8 Gigabaud |
1418 | # Value range is [0,8]. Default value is 0. | 1447 | # Value range is [0,8]. Default value is 0. |
1419 | */ | 1448 | */ |
1420 | LPFC_ATTR_R(link_speed, 0, 0, 8, "Select link speed"); | 1449 | static int |
1450 | lpfc_link_speed_set(struct lpfc_hba *phba, int val) | ||
1451 | { | ||
1452 | int err; | ||
1453 | uint32_t prev_val; | ||
1454 | |||
1455 | if (((val == LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) || | ||
1456 | ((val == LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) || | ||
1457 | ((val == LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) || | ||
1458 | ((val == LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) || | ||
1459 | ((val == LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb))) | ||
1460 | return -EINVAL; | ||
1461 | |||
1462 | if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED) | ||
1463 | && (LPFC_LINK_SPEED_BITMAP & (1 << val))) { | ||
1464 | prev_val = phba->cfg_link_speed; | ||
1465 | phba->cfg_link_speed = val; | ||
1466 | err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport)); | ||
1467 | if (err) | ||
1468 | phba->cfg_link_speed = prev_val; | ||
1469 | return err; | ||
1470 | } | ||
1471 | |||
1472 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1473 | "%d:0469 lpfc_link_speed attribute cannot be set to %d, " | ||
1474 | "allowed range is [0, 8]\n", | ||
1475 | phba->brd_no, val); | ||
1476 | return -EINVAL; | ||
1477 | } | ||
1478 | |||
1479 | static int lpfc_link_speed = 0; | ||
1480 | module_param(lpfc_link_speed, int, 0); | ||
1481 | MODULE_PARM_DESC(lpfc_link_speed, "Select link speed"); | ||
1482 | lpfc_param_show(link_speed) | ||
1483 | static int | ||
1484 | lpfc_link_speed_init(struct lpfc_hba *phba, int val) | ||
1485 | { | ||
1486 | if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED) | ||
1487 | && (LPFC_LINK_SPEED_BITMAP & (1 << val))) { | ||
1488 | phba->cfg_link_speed = val; | ||
1489 | return 0; | ||
1490 | } | ||
1491 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1492 | "0454 lpfc_link_speed attribute cannot " | ||
1493 | "be set to %d, allowed values are " | ||
1494 | "["LPFC_LINK_SPEED_STRING"]\n", val); | ||
1495 | phba->cfg_link_speed = 0; | ||
1496 | return -EINVAL; | ||
1497 | } | ||
1498 | |||
1499 | lpfc_param_store(link_speed) | ||
1500 | static CLASS_DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR, | ||
1501 | lpfc_link_speed_show, lpfc_link_speed_store); | ||
1421 | 1502 | ||
1422 | /* | 1503 | /* |
1423 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. | 1504 | # lpfc_fcp_class: Determines FC class to use for the FCP protocol. |
@@ -1531,6 +1612,15 @@ LPFC_ATTR_R(enable_hba_reset, 1, 0, 1, "Enable HBA resets from the driver."); | |||
1531 | */ | 1612 | */ |
1532 | LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat."); | 1613 | LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat."); |
1533 | 1614 | ||
1615 | /* | ||
1616 | * lpfc_sg_seg_cnt: Initial Maximum DMA Segment Count | ||
1617 | * This value can be set to values between 64 and 256. The default value is | ||
1618 | * 64, but may be increased to allow for larger Max I/O sizes. The scsi layer | ||
1619 | * will be allowed to request I/Os of sizes up to (MAX_SEG_COUNT * SEG_SIZE). | ||
1620 | */ | ||
1621 | LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT, | ||
1622 | LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count"); | ||
1623 | |||
1534 | struct class_device_attribute *lpfc_hba_attrs[] = { | 1624 | struct class_device_attribute *lpfc_hba_attrs[] = { |
1535 | &class_device_attr_info, | 1625 | &class_device_attr_info, |
1536 | &class_device_attr_serialnum, | 1626 | &class_device_attr_serialnum, |
@@ -1583,6 +1673,7 @@ struct class_device_attribute *lpfc_hba_attrs[] = { | |||
1583 | &class_device_attr_lpfc_soft_wwn_enable, | 1673 | &class_device_attr_lpfc_soft_wwn_enable, |
1584 | &class_device_attr_lpfc_enable_hba_reset, | 1674 | &class_device_attr_lpfc_enable_hba_reset, |
1585 | &class_device_attr_lpfc_enable_hba_heartbeat, | 1675 | &class_device_attr_lpfc_enable_hba_heartbeat, |
1676 | &class_device_attr_lpfc_sg_seg_cnt, | ||
1586 | NULL, | 1677 | NULL, |
1587 | }; | 1678 | }; |
1588 | 1679 | ||
@@ -2490,18 +2581,18 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
2490 | phba->cfg_poll = lpfc_poll; | 2581 | phba->cfg_poll = lpfc_poll; |
2491 | phba->cfg_soft_wwnn = 0L; | 2582 | phba->cfg_soft_wwnn = 0L; |
2492 | phba->cfg_soft_wwpn = 0L; | 2583 | phba->cfg_soft_wwpn = 0L; |
2493 | /* | 2584 | lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); |
2494 | * The total number of segments is the configuration value plus 2 | 2585 | /* Also reinitialize the host templates with new values. */ |
2495 | * since the IOCB need a command and response bde. | 2586 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
2496 | */ | 2587 | lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
2497 | phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2; | ||
2498 | /* | 2588 | /* |
2499 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size | 2589 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size |
2500 | * used to create the sg_dma_buf_pool must be dynamically calculated | 2590 | * used to create the sg_dma_buf_pool must be dynamically calculated. |
2591 | * 2 segments are added since the IOCB needs a command and response bde. | ||
2501 | */ | 2592 | */ |
2502 | phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + | 2593 | phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + |
2503 | sizeof(struct fcp_rsp) + | 2594 | sizeof(struct fcp_rsp) + |
2504 | (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64)); | 2595 | ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct ulp_bde64)); |
2505 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); | 2596 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); |
2506 | return; | 2597 | return; |
2507 | } | 2598 | } |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 648795806a83..6483c62730b3 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1458,7 +1458,7 @@ struct scsi_host_template lpfc_template = { | |||
1458 | .slave_destroy = lpfc_slave_destroy, | 1458 | .slave_destroy = lpfc_slave_destroy, |
1459 | .scan_finished = lpfc_scan_finished, | 1459 | .scan_finished = lpfc_scan_finished, |
1460 | .this_id = -1, | 1460 | .this_id = -1, |
1461 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1461 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, |
1462 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1462 | .use_sg_chaining = ENABLE_SG_CHAINING, |
1463 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1463 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1464 | .use_clustering = ENABLE_CLUSTERING, | 1464 | .use_clustering = ENABLE_CLUSTERING, |
@@ -1479,7 +1479,7 @@ struct scsi_host_template lpfc_vport_template = { | |||
1479 | .slave_destroy = lpfc_slave_destroy, | 1479 | .slave_destroy = lpfc_slave_destroy, |
1480 | .scan_finished = lpfc_scan_finished, | 1480 | .scan_finished = lpfc_scan_finished, |
1481 | .this_id = -1, | 1481 | .this_id = -1, |
1482 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1482 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, |
1483 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1483 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1484 | .use_clustering = ENABLE_CLUSTERING, | 1484 | .use_clustering = ENABLE_CLUSTERING, |
1485 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1485 | .use_sg_chaining = ENABLE_SG_CHAINING, |