lpfc_attr.c
来自「linux 内核源代码」· C语言 代码 · 共 2,217 行 · 第 1/5 页
C
2,217 行
static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL);static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO, lpfc_option_rom_version_show, NULL);static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO, lpfc_num_discovered_ports_show, NULL);static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL);static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, lpfc_board_mode_show, lpfc_board_mode_store);static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);static CLASS_DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL);static CLASS_DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL);static CLASS_DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL);static CLASS_DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL);static CLASS_DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL);static CLASS_DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL);static CLASS_DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL);static char *lpfc_soft_wwn_key = "C99G71SL8032A";static ssize_tlpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, size_t count){ struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; unsigned int cnt = count; /* * We're doing a simple sanity check for soft_wwpn setting. * We require that the user write a specific key to enable * the soft_wwpn attribute to be settable. Once the attribute * is written, the enable key resets. If further updates are * desired, the key must be written again to re-enable the * attribute. * * The "key" is not secret - it is a hardcoded string shown * here. The intent is to protect against the random user or * application that is just writing attributes. */ /* count may include a LF at end of string */ if (buf[cnt-1] == '\n') cnt--; if ((cnt != strlen(lpfc_soft_wwn_key)) || (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0)) return -EINVAL; phba->soft_wwn_enable = 1; return count;}static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, lpfc_soft_wwn_enable_store);static ssize_tlpfc_soft_wwpn_show(struct class_device *cdev, char *buf){ struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; return snprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)phba->cfg_soft_wwpn);}static ssize_tlpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count){ struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct completion online_compl; int stat1=0, stat2=0; unsigned int i, j, cnt=count; u8 wwpn[8]; /* count may include a LF at end of string */ if (buf[cnt-1] == '\n') cnt--; if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) || ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) return -EINVAL; phba->soft_wwn_enable = 0; memset(wwpn, 0, sizeof(wwpn)); /* Validate and store the new name */ for (i=0, j=0; i < 16; i++) { if ((*buf >= 'a') && (*buf <= 'f')) j = ((j << 4) | ((*buf++ -'a') + 10)); else if ((*buf >= 'A') && (*buf <= 'F')) j = ((j << 4) | ((*buf++ -'A') + 10)); else if ((*buf >= '0') && (*buf <= '9')) j = ((j << 4) | (*buf++ -'0')); else return -EINVAL; if (i % 2) { wwpn[i/2] = j & 0xff; j = 0; } } phba->cfg_soft_wwpn = wwn_to_u64(wwpn); fc_host_port_name(shost) = phba->cfg_soft_wwpn; if (phba->cfg_soft_wwnn) fc_host_node_name(shost) = phba->cfg_soft_wwnn; dev_printk(KERN_NOTICE, &phba->pcidev->dev, "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (stat1) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0463 lpfc_soft_wwpn attribute set failed to " "reinit adapter - %d\n", stat1); init_completion(&online_compl); lpfc_workq_post_event(phba, &stat2, &online_compl, LPFC_EVT_ONLINE); wait_for_completion(&online_compl); if (stat2) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0464 lpfc_soft_wwpn attribute set failed to " "reinit adapter - %d\n", stat2); return (stat1 || stat2) ? -EIO : count;}static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ lpfc_soft_wwpn_show, lpfc_soft_wwpn_store);static ssize_tlpfc_soft_wwnn_show(struct class_device *cdev, char *buf){ struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; return snprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)phba->cfg_soft_wwnn);}static ssize_tlpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count){ struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; unsigned int i, j, cnt=count; u8 wwnn[8]; /* count may include a LF at end of string */ if (buf[cnt-1] == '\n') cnt--; if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) || ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) return -EINVAL; /* * Allow wwnn to be set many times, as long as the enable is set. * However, once the wwpn is set, everything locks. */ memset(wwnn, 0, sizeof(wwnn)); /* Validate and store the new name */ for (i=0, j=0; i < 16; i++) { if ((*buf >= 'a') && (*buf <= 'f')) j = ((j << 4) | ((*buf++ -'a') + 10)); else if ((*buf >= 'A') && (*buf <= 'F')) j = ((j << 4) | ((*buf++ -'A') + 10)); else if ((*buf >= '0') && (*buf <= '9')) j = ((j << 4) | (*buf++ -'0')); else return -EINVAL; if (i % 2) { wwnn[i/2] = j & 0xff; j = 0; } } phba->cfg_soft_wwnn = wwn_to_u64(wwnn); dev_printk(KERN_NOTICE, &phba->pcidev->dev, "lpfc%d: soft_wwnn set. Value will take effect upon " "setting of the soft_wwpn\n", phba->brd_no); return count;}static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\ lpfc_soft_wwnn_show, lpfc_soft_wwnn_store);static int lpfc_poll = 0;module_param(lpfc_poll, int, 0);MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:" " 0 - none," " 1 - poll with interrupts enabled" " 3 - poll and disable FCP ring interrupts");static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, lpfc_poll_show, lpfc_poll_store);int lpfc_sli_mode = 0;module_param(lpfc_sli_mode, int, 0);MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:" " 0 - auto (SLI-3 if supported)," " 2 - select SLI-2 even on SLI-3 capable HBAs," " 3 - select SLI-3");LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality");/*# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear# until the timer expires. Value range is [0,255]. Default value is 30.*/static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;module_param(lpfc_nodev_tmo, int, 0);MODULE_PARM_DESC(lpfc_nodev_tmo, "Seconds driver will hold I/O waiting " "for a device to come back");static ssize_tlpfc_nodev_tmo_show(struct class_device *cdev, char *buf){ struct Scsi_Host *shost = class_to_shost(cdev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; int val = 0; val = vport->cfg_devloss_tmo; return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);}static intlpfc_nodev_tmo_init(struct lpfc_vport *vport, int val){ if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) { vport->cfg_nodev_tmo = vport->cfg_devloss_tmo; if (val != LPFC_DEF_DEVLOSS_TMO) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0402 Ignoring nodev_tmo module " "parameter because devloss_tmo is " "set.\n"); return 0; } if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { vport->cfg_nodev_tmo = val; vport->cfg_devloss_tmo = val; return 0; } lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0400 lpfc_nodev_tmo attribute cannot be set to" " %d, allowed range is [%d, %d]\n", val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO; return -EINVAL;}static voidlpfc_update_rport_devloss_tmo(struct lpfc_vport *vport){ struct Scsi_Host *shost; struct lpfc_nodelist *ndlp; shost = lpfc_shost_from_vport(vport); spin_lock_irq(shost->host_lock); list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) if (ndlp->rport) ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo; spin_unlock_irq(shost->host_lock);}static intlpfc_nodev_tmo_set(struct lpfc_vport *vport, int val){ if (vport->dev_loss_tmo_changed || (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0401 Ignoring change to nodev_tmo " "because devloss_tmo is set.\n"); return 0; } if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { vport->cfg_nodev_tmo = val; vport->cfg_devloss_tmo = val; lpfc_update_rport_devloss_tmo(vport); return 0; } lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0403 lpfc_nodev_tmo attribute cannot be set to" "%d, allowed range is [%d, %d]\n", val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); return -EINVAL;}lpfc_vport_param_store(nodev_tmo)static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR, lpfc_nodev_tmo_show, lpfc_nodev_tmo_store);/*# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that# disappear until the timer expires. Value range is [0,255]. Default# value is 30.*/module_param(lpfc_devloss_tmo, int, 0);MODULE_PARM_DESC(lpfc_devloss_tmo, "Seconds driver will hold I/O waiting " "for a device to come back");lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)lpfc_vport_param_show(devloss_tmo)static intlpfc_devloss_tmo_set(struct lpfc_vport *vport, int val){ if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { vport->cfg_nodev_tmo = val; vport->cfg_devloss_tmo = val; vport->dev_loss_tmo_changed = 1; lpfc_update_rport_devloss_tmo(vport); return 0; } lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0404 lpfc_devloss_tmo attribute cannot be set to" " %d, allowed range is [%d, %d]\n", val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO); return -EINVAL;}lpfc_vport_param_store(devloss_tmo)static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);/*# lpfc_log_verbose: Only turn this flag on if you are willing to risk being# deluged with LOTS of information.# You can set a bit mask to record specific types of verbose messages:## LOG_ELS 0x1 ELS events# LOG_DISCOVERY 0x2 Link discovery events# LOG_MBOX 0x4 Mailbox events# LOG_INIT 0x8 Initialization events# LOG_LINK_EVENT 0x10 Link events# LOG_FCP 0x40 FCP traffic history# LOG_NODE 0x80 Node table events# LOG_MISC 0x400 Miscellaneous events# LOG_SLI 0x800 SLI events# LOG_FCP_ERROR 0x1000 Only log FCP errors# LOG_LIBDFC 0x2000 LIBDFC events# LOG_ALL_MSG 0xffff LOG all messages*/LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");/*# lun_queue_depth: This parameter is used to limit the number of outstanding# commands per FCP LUN. Value range is [1,128]. Default value is 30.*/LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 128, "Max number of FCP commands we can queue to a specific LUN");/*# hba_queue_depth: This parameter is used to limit the number of outstanding# commands per lpfc HBA. Value range is [32,8192]. If this parameter# value is greater than the maximum number of exchanges supported by the HBA,# then maximum number of exchanges supported by the HBA is used to determine# the hba_queue_depth.*/LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192, "Max number of FCP commands we can queue to a lpfc HBA");/*# peer_port_login: This parameter allows/prevents logins# between peer ports hosted on the same physical port.# When this parameter is set 0 peer ports of same physical port# are not allowed to login to each other.# When this parameter is set 1 peer ports of same physical port# are allowed to login to each other.# Default value of this parameter is 0.*/LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1, "Allow peer ports on the same physical port to login to each " "other.");/*# restrict_login: This parameter allows/prevents logins# between Virtual Ports and remote initiators.# When this parameter is not set (0) Virtual Ports will accept PLOGIs from# other initiators and will attempt to PLOGI all remote ports.# When this parameter is set (1) Virtual Ports will reject PLOGIs from# remote ports and will not attempt to PLOGI to other initiators.# This parameter does not restrict to the physical port.# This parameter does not restrict logins to Fabric resident remote ports.# Default value of this parameter is 1.*/static int lpfc_restrict_login = 1;module_param(lpfc_restrict_login, int, 0);MODULE_PARM_DESC(lpfc_restrict_login, "Restrict virtual ports login to remote initiators.");lpfc_vport_param_show(restrict_login);static intlpfc_restrict_login_init(struct lpfc_vport *vport, int val){ if (val < 0 || val > 1) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0449 lpfc_restrict_login attribute cannot " "be set to %d, allowed range is [0, 1]\n", val); vport->cfg_restrict_login = 1; return -EINVAL; } if (vport->port_type == LPFC_PHYSICAL_PORT) { vport->cfg_restrict_login = 0; return 0; } vport->cfg_restrict_login = val; return 0;}static intlpfc_restrict_login_set(struct lpfc_vport *vport, int val){ if (val < 0 || val > 1) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0450 lpfc_restrict_login attribute cannot " "be set to %d, allowed range is [0, 1]\n", val); vport->cfg_restrict_login = 1; return -EINVAL; } if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0468 lpfc_restrict_login must be 0 for " "Physical ports.\n"); vport->cfg_restrict_login = 0; return 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?