From 2e0fef85e098f6794956b8b80b111179fbb4cbb7 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 17 Jun 2007 19:56:36 -0500 Subject: [SCSI] lpfc: NPIV: split ports The driver is reorganized to separate the handling of the adapter from the handling of the FC port. Adapter handling includes submissions of command requests, receiving responses, and managing adapter resources. The FC port includes the discovery engine, login handling, and the mapping of a Scsi_Host on the "port". Although not a large functional change, as it touches core structures and functions, resulting in a large text delta. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_attr.c | 443 +++++++++++++++++++++++------------------- 1 file changed, 239 insertions(+), 204 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_attr.c') diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 95fe77e816f..b8adff8cea6 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -76,55 +76,68 @@ static ssize_t lpfc_info_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); + return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); } static ssize_t lpfc_serialnum_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%s\n",phba->SerialNumber); } static ssize_t lpfc_modeldesc_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%s\n",phba->ModelDesc); } static ssize_t lpfc_modelname_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%s\n",phba->ModelName); } static ssize_t lpfc_programtype_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%s\n",phba->ProgramType); } static ssize_t -lpfc_portnum_show(struct class_device *cdev, char *buf) +lpfc_vportnum_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%s\n",phba->Port); } static ssize_t lpfc_fwrev_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; char fwrev[32]; + lpfc_decode_firmware_rev(phba, fwrev, 1); return snprintf(buf, PAGE_SIZE, "%s\n",fwrev); } @@ -133,59 +146,80 @@ static ssize_t lpfc_hdw_show(struct class_device *cdev, char *buf) { char hdw[9]; - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; lpfc_vpd_t *vp = &phba->vpd; + lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); return snprintf(buf, PAGE_SIZE, "%s\n", hdw); } static ssize_t lpfc_option_rom_version_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%s\n", phba->OptionROMVersion); } static ssize_t lpfc_state_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - int len = 0; - switch (phba->hba_state) { - case LPFC_STATE_UNKNOWN: + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + int len = 0; + + switch (phba->link_state) { + case LPFC_LINK_UNKNOWN: case LPFC_WARM_START: case LPFC_INIT_START: case LPFC_INIT_MBX_CMDS: case LPFC_LINK_DOWN: - len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n"); + case LPFC_HBA_ERROR: + len += snprintf(buf + len, PAGE_SIZE-len, "Link Down"); break; case LPFC_LINK_UP: - case LPFC_LOCAL_CFG_LINK: - len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n"); - break; - case LPFC_FLOGI: - case LPFC_FABRIC_CFG_LINK: - case LPFC_NS_REG: - case LPFC_NS_QRY: - case LPFC_BUILD_DISC_LIST: - case LPFC_DISC_AUTH: case LPFC_CLEAR_LA: - len += snprintf(buf + len, PAGE_SIZE-len, - "Link Up - Discovery\n"); - break; - case LPFC_HBA_READY: - len += snprintf(buf + len, PAGE_SIZE-len, - "Link Up - Ready:\n"); + len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - \n"); + + switch (vport->port_state) { + len += snprintf(buf + len, PAGE_SIZE-len, + "initializing\n"); + break; + case LPFC_LOCAL_CFG_LINK: + len += snprintf(buf + len, PAGE_SIZE-len, + "configuring\n"); + break; + case LPFC_FLOGI: + case LPFC_FABRIC_CFG_LINK: + case LPFC_NS_REG: + case LPFC_NS_QRY: + case LPFC_BUILD_DISC_LIST: + case LPFC_DISC_AUTH: + len += snprintf(buf + len, PAGE_SIZE - len, + "Discovery\n"); + break; + case LPFC_VPORT_READY: + len += snprintf(buf + len, PAGE_SIZE - len, "Ready\n"); + break; + + case LPFC_STATE_UNKNOWN: + len += snprintf(buf + len, PAGE_SIZE - len, + "Unknown\n"); + break; + } + if (phba->fc_topology == TOPOLOGY_LOOP) { - if (phba->fc_flag & FC_PUBLIC_LOOP) + if (vport->fc_flag & FC_PUBLIC_LOOP) len += snprintf(buf + len, PAGE_SIZE-len, " Public Loop\n"); else len += snprintf(buf + len, PAGE_SIZE-len, " Private Loop\n"); } else { - if (phba->fc_flag & FC_FABRIC) + if (vport->fc_flag & FC_FABRIC) len += snprintf(buf + len, PAGE_SIZE-len, " Fabric\n"); else @@ -193,29 +227,32 @@ lpfc_state_show(struct class_device *cdev, char *buf) " Point-2-Point\n"); } } + return len; } static ssize_t lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt + - phba->fc_unmap_cnt); + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + + return snprintf(buf, PAGE_SIZE, "%d\n", + vport->fc_map_cnt + vport->fc_unmap_cnt); } static int -lpfc_issue_lip(struct Scsi_Host *host) +lpfc_issue_lip(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; LPFC_MBOXQ_t *pmboxq; int mbxstatus = MBXERR_ERROR; - if ((phba->fc_flag & FC_OFFLINE_MODE) || - (phba->fc_flag & FC_BLOCK_MGMT_IO) || - (phba->hba_state != LPFC_HBA_READY)) + if ((vport->fc_flag & FC_OFFLINE_MODE) || + (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) || + (vport->port_state != LPFC_VPORT_READY)) return -EPERM; pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); @@ -320,8 +357,10 @@ lpfc_selective_reset(struct lpfc_hba *phba) static ssize_t lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + int status = -EINVAL; if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) @@ -336,23 +375,26 @@ lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) static ssize_t lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%d\n", phba->nport_event_cnt); } static ssize_t lpfc_board_mode_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; char * state; - if (phba->hba_state == LPFC_HBA_ERROR) + if (phba->link_state == LPFC_HBA_ERROR) state = "error"; - else if (phba->hba_state == LPFC_WARM_START) + else if (phba->link_state == LPFC_WARM_START) state = "warm start"; - else if (phba->hba_state == LPFC_INIT_START) + else if (phba->link_state == LPFC_INIT_START) state = "offline"; else state = "online"; @@ -363,8 +405,9 @@ lpfc_board_mode_show(struct class_device *cdev, char *buf) static ssize_t lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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 status=0; @@ -392,8 +435,9 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) static ssize_t lpfc_poll_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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, "%#x\n", phba->cfg_poll); } @@ -402,8 +446,9 @@ static ssize_t lpfc_poll_store(struct class_device *cdev, const char *buf, size_t count) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; uint32_t creg_val; uint32_t old_val; int val=0; @@ -417,7 +462,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, if ((val & 0x3) != val) return -EINVAL; - spin_lock_irq(phba->host->host_lock); + spin_lock_irq(&phba->hbalock); old_val = phba->cfg_poll; @@ -432,16 +477,16 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, lpfc_poll_start_timer(phba); } } else if (val != 0x0) { - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EINVAL; } if (!(val & DISABLE_FCP_RING_INT) && (old_val & DISABLE_FCP_RING_INT)) { - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); del_timer(&phba->fcp_poll_timer); - spin_lock_irq(phba->host->host_lock); + spin_lock_irq(&phba->hbalock); creg_val = readl(phba->HCregaddr); creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING); writel(creg_val, phba->HCregaddr); @@ -450,7 +495,7 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, phba->cfg_poll = val; - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return strlen(buf); } @@ -459,8 +504,9 @@ lpfc_poll_store(struct class_device *cdev, const char *buf, static ssize_t \ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ { \ - struct Scsi_Host *host = class_to_shost(cdev);\ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ + struct Scsi_Host *shost = class_to_shost(cdev);\ + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ + struct lpfc_hba *phba = vport->phba;\ int val = 0;\ val = phba->cfg_##attr;\ return snprintf(buf, PAGE_SIZE, "%d\n",\ @@ -471,8 +517,9 @@ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ static ssize_t \ lpfc_##attr##_show(struct class_device *cdev, char *buf) \ { \ - struct Scsi_Host *host = class_to_shost(cdev);\ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ + struct Scsi_Host *shost = class_to_shost(cdev);\ + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ + struct lpfc_hba *phba = vport->phba;\ int val = 0;\ val = phba->cfg_##attr;\ return snprintf(buf, PAGE_SIZE, "%#x\n",\ @@ -514,8 +561,9 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \ static ssize_t \ lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \ { \ - struct Scsi_Host *host = class_to_shost(cdev);\ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;\ + struct Scsi_Host *shost = class_to_shost(cdev);\ + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ + struct lpfc_hba *phba = vport->phba;\ int val=0;\ if (!isdigit(buf[0]))\ return -EINVAL;\ @@ -576,7 +624,7 @@ static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); -static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_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); @@ -600,8 +648,9 @@ static ssize_t lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, size_t count) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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; /* @@ -634,8 +683,10 @@ static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, static ssize_t lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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); } @@ -644,8 +695,9 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) static ssize_t lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + 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; @@ -680,9 +732,9 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) } } phba->cfg_soft_wwpn = wwn_to_u64(wwpn); - fc_host_port_name(host) = phba->cfg_soft_wwpn; + fc_host_port_name(shost) = phba->cfg_soft_wwpn; if (phba->cfg_soft_wwnn) - fc_host_node_name(host) = 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); @@ -790,8 +842,9 @@ MODULE_PARM_DESC(lpfc_nodev_tmo, static ssize_t lpfc_nodev_tmo_show(struct class_device *cdev, char *buf) { - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; int val = 0; val = phba->cfg_devloss_tmo; return snprintf(buf, PAGE_SIZE, "%d\n", @@ -829,18 +882,6 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val) return -EINVAL; } -static void -lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) -{ - struct lpfc_nodelist *ndlp; - - spin_lock_irq(phba->host->host_lock); - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) - if (ndlp->rport) - ndlp->rport->dev_loss_tmo = phba->cfg_devloss_tmo; - spin_unlock_irq(phba->host->host_lock); -} - static int lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) { @@ -856,7 +897,6 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { phba->cfg_nodev_tmo = val; phba->cfg_devloss_tmo = val; - lpfc_update_rport_devloss_tmo(phba); return 0; } @@ -892,7 +932,6 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val) phba->cfg_nodev_tmo = val; phba->cfg_devloss_tmo = val; phba->dev_loss_tmo_changed = 1; - lpfc_update_rport_devloss_tmo(phba); return 0; } @@ -1088,7 +1127,7 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); -struct class_device_attribute *lpfc_host_attrs[] = { +struct class_device_attribute *lpfc_hba_attrs[] = { &class_device_attr_info, &class_device_attr_serialnum, &class_device_attr_modeldesc, @@ -1136,9 +1175,11 @@ static ssize_t sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) { size_t buf_off; - struct Scsi_Host *host = class_to_shost(container_of(kobj, - struct class_device, kobj)); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct class_device *cdev = container_of(kobj, struct class_device, + kobj); + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; if ((off + count) > FF_REG_AREA_SIZE) return -ERANGE; @@ -1148,18 +1189,16 @@ sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) if (off % 4 || count % 4 || (unsigned long)buf % 4) return -EINVAL; - spin_lock_irq(phba->host->host_lock); - - if (!(phba->fc_flag & FC_OFFLINE_MODE)) { - spin_unlock_irq(phba->host->host_lock); + if (!(vport->fc_flag & FC_OFFLINE_MODE)) { return -EPERM; } + spin_lock_irq(&phba->hbalock); for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) writel(*((uint32_t *)(buf + buf_off)), phba->ctrl_regs_memmap_p + off + buf_off); - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return count; } @@ -1169,9 +1208,11 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) { size_t buf_off; uint32_t * tmp_ptr; - struct Scsi_Host *host = class_to_shost(container_of(kobj, - struct class_device, kobj)); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct class_device *cdev = container_of(kobj, struct class_device, + kobj); + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; if (off > FF_REG_AREA_SIZE) return -ERANGE; @@ -1184,14 +1225,14 @@ sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) if (off % 4 || count % 4 || (unsigned long)buf % 4) return -EINVAL; - spin_lock_irq(phba->host->host_lock); + spin_lock_irq(&phba->hbalock); for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) { tmp_ptr = (uint32_t *)(buf + buf_off); *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off); } - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return count; } @@ -1209,7 +1250,7 @@ static struct bin_attribute sysfs_ctlreg_attr = { static void -sysfs_mbox_idle (struct lpfc_hba * phba) +sysfs_mbox_idle(struct lpfc_hba *phba) { phba->sysfs_mbox.state = SMBOX_IDLE; phba->sysfs_mbox.offset = 0; @@ -1224,10 +1265,12 @@ sysfs_mbox_idle (struct lpfc_hba * phba) static ssize_t sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) { - struct Scsi_Host * host = - class_to_shost(container_of(kobj, struct class_device, kobj)); - struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata; - struct lpfcMboxq * mbox = NULL; + struct class_device *cdev = container_of(kobj, struct class_device, + kobj); + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + struct lpfcMboxq *mbox = NULL; if ((count + off) > MAILBOX_CMD_SIZE) return -ERANGE; @@ -1245,7 +1288,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) memset(mbox, 0, sizeof (LPFC_MBOXQ_t)); } - spin_lock_irq(host->host_lock); + spin_lock_irq(&phba->hbalock); if (off == 0) { if (phba->sysfs_mbox.mbox) @@ -1258,7 +1301,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) phba->sysfs_mbox.offset != off || phba->sysfs_mbox.mbox == NULL ) { sysfs_mbox_idle(phba); - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EAGAIN; } } @@ -1268,7 +1311,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) phba->sysfs_mbox.offset = off + count; - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&phba->hbalock); return count; } @@ -1276,10 +1319,11 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) static ssize_t sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) { - struct Scsi_Host *host = - class_to_shost(container_of(kobj, struct class_device, - kobj)); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + struct class_device *cdev = container_of(kobj, struct class_device, + kobj); + struct Scsi_Host *shost = class_to_shost(cdev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; int rc; if (off > MAILBOX_CMD_SIZE) @@ -1294,7 +1338,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) if (off && count == 0) return 0; - spin_lock_irq(phba->host->host_lock); + spin_lock_irq(&phba->hbalock); if (off == 0 && phba->sysfs_mbox.state == SMBOX_WRITING && @@ -1317,12 +1361,12 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) case MBX_SET_MASK: case MBX_SET_SLIM: case MBX_SET_DEBUG: - if (!(phba->fc_flag & FC_OFFLINE_MODE)) { + if (!(vport->fc_flag & FC_OFFLINE_MODE)) { printk(KERN_WARNING "mbox_read:Command 0x%x " "is illegal in on-line state\n", phba->sysfs_mbox.mbox->mb.mbxCommand); sysfs_mbox_idle(phba); - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EPERM; } case MBX_LOAD_SM: @@ -1352,38 +1396,38 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", phba->sysfs_mbox.mbox->mb.mbxCommand); sysfs_mbox_idle(phba); - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EPERM; default: printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", phba->sysfs_mbox.mbox->mb.mbxCommand); sysfs_mbox_idle(phba); - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EPERM; } - if (phba->fc_flag & FC_BLOCK_MGMT_IO) { + if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { sysfs_mbox_idle(phba); - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EAGAIN; } - if ((phba->fc_flag & FC_OFFLINE_MODE) || + if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); rc = lpfc_sli_issue_mbox (phba, phba->sysfs_mbox.mbox, MBX_POLL); - spin_lock_irq(phba->host->host_lock); + spin_lock_irq(&phba->hbalock); } else { - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); rc = lpfc_sli_issue_mbox_wait (phba, phba->sysfs_mbox.mbox, lpfc_mbox_tmo_val(phba, phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); - spin_lock_irq(phba->host->host_lock); + spin_lock_irq(&phba->hbalock); } if (rc != MBX_SUCCESS) { @@ -1393,7 +1437,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) phba->sysfs_mbox.mbox = NULL; } sysfs_mbox_idle(phba); - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&phba->hbalock); return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; } phba->sysfs_mbox.state = SMBOX_READING; @@ -1402,7 +1446,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) phba->sysfs_mbox.state != SMBOX_READING) { printk(KERN_WARNING "mbox_read: Bad State\n"); sysfs_mbox_idle(phba); - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&phba->hbalock); return -EAGAIN; } @@ -1413,7 +1457,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) sysfs_mbox_idle(phba); - spin_unlock_irq(phba->host->host_lock); + spin_unlock_irq(&phba->hbalock); return count; } @@ -1430,35 +1474,35 @@ static struct bin_attribute sysfs_mbox_attr = { }; int -lpfc_alloc_sysfs_attr(struct lpfc_hba *phba) +lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) { - struct Scsi_Host *host = phba->host; + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); int error; - error = sysfs_create_bin_file(&host->shost_classdev.kobj, + error = sysfs_create_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); if (error) goto out; - error = sysfs_create_bin_file(&host->shost_classdev.kobj, + error = sysfs_create_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr); if (error) goto out_remove_ctlreg_attr; return 0; out_remove_ctlreg_attr: - sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr); + sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); out: return error; } void -lpfc_free_sysfs_attr(struct lpfc_hba *phba) +lpfc_free_sysfs_attr(struct lpfc_vport *vport) { - struct Scsi_Host *host = phba->host; + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr); - sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr); + sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_mbox_attr); + sysfs_remove_bin_file(&shost->shost_classdev.kobj, &sysfs_ctlreg_attr); } @@ -1469,26 +1513,28 @@ lpfc_free_sysfs_attr(struct lpfc_hba *phba) static void lpfc_get_host_port_id(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + /* note: fc_myDID already in cpu endianness */ - fc_host_port_id(shost) = phba->fc_myDID; + fc_host_port_id(shost) = vport->fc_myDID; } static void lpfc_get_host_port_type(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; spin_lock_irq(shost->host_lock); - if (phba->hba_state == LPFC_HBA_READY) { + if (lpfc_is_link_up(phba)) { if (phba->fc_topology == TOPOLOGY_LOOP) { - if (phba->fc_flag & FC_PUBLIC_LOOP) + if (vport->fc_flag & FC_PUBLIC_LOOP) fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; else fc_host_port_type(shost) = FC_PORTTYPE_LPORT; } else { - if (phba->fc_flag & FC_FABRIC) + if (vport->fc_flag & FC_FABRIC) fc_host_port_type(shost) = FC_PORTTYPE_NPORT; else fc_host_port_type(shost) = FC_PORTTYPE_PTP; @@ -1502,31 +1548,21 @@ lpfc_get_host_port_type(struct Scsi_Host *shost) static void lpfc_get_host_port_state(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; spin_lock_irq(shost->host_lock); - if (phba->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; else { - switch (phba->hba_state) { - case LPFC_STATE_UNKNOWN: - case LPFC_WARM_START: - case LPFC_INIT_START: - case LPFC_INIT_MBX_CMDS: + switch (phba->link_state) { + case LPFC_LINK_UNKNOWN: case LPFC_LINK_DOWN: fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; break; case LPFC_LINK_UP: - case LPFC_LOCAL_CFG_LINK: - case LPFC_FLOGI: - case LPFC_FABRIC_CFG_LINK: - case LPFC_NS_REG: - case LPFC_NS_QRY: - case LPFC_BUILD_DISC_LIST: - case LPFC_DISC_AUTH: case LPFC_CLEAR_LA: - case LPFC_HBA_READY: /* Links up, beyond this port_type reports state */ fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; break; @@ -1545,11 +1581,12 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) static void lpfc_get_host_speed(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; spin_lock_irq(shost->host_lock); - if (phba->hba_state == LPFC_HBA_READY) { + if (lpfc_is_link_up(phba)) { switch(phba->fc_linkspeed) { case LA_1GHZ_LINK: fc_host_speed(shost) = FC_PORTSPEED_1GBIT; @@ -1575,39 +1612,31 @@ lpfc_get_host_speed(struct Scsi_Host *shost) static void lpfc_get_host_fabric_name (struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; u64 node_name; spin_lock_irq(shost->host_lock); - if ((phba->fc_flag & FC_FABRIC) || + if ((vport->fc_flag & FC_FABRIC) || ((phba->fc_topology == TOPOLOGY_LOOP) && - (phba->fc_flag & FC_PUBLIC_LOOP))) + (vport->fc_flag & FC_PUBLIC_LOOP))) node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); else /* fabric is local port if there is no F/FL_Port */ - node_name = wwn_to_u64(phba->fc_nodename.u.wwn); + node_name = wwn_to_u64(vport->fc_nodename.u.wwn); spin_unlock_irq(shost->host_lock); fc_host_fabric_name(shost) = node_name; } -static void -lpfc_get_host_symbolic_name (struct Scsi_Host *shost) -{ - struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata; - - spin_lock_irq(shost->host_lock); - lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost)); - spin_unlock_irq(shost->host_lock); -} - static struct fc_host_statistics * lpfc_get_stats(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; - struct lpfc_sli *psli = &phba->sli; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + struct lpfc_sli *psli = &phba->sli; struct fc_host_statistics *hs = &phba->link_stats; struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; LPFC_MBOXQ_t *pmboxq; @@ -1615,7 +1644,15 @@ lpfc_get_stats(struct Scsi_Host *shost) unsigned long seconds; int rc = 0; - if (phba->fc_flag & FC_BLOCK_MGMT_IO) + /* prevent udev from issuing mailbox commands + * until the port is configured. + */ + if (phba->link_state < LPFC_LINK_DOWN || + !phba->mbox_mem_pool || + (phba->sli.sli_flag & LPFC_SLI2_ACTIVE) == 0) + return NULL; + + if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) return NULL; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); @@ -1628,7 +1665,7 @@ lpfc_get_stats(struct Scsi_Host *shost) pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; - if ((phba->fc_flag & FC_OFFLINE_MODE) || + if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else @@ -1654,7 +1691,7 @@ lpfc_get_stats(struct Scsi_Host *shost) pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; - if ((phba->fc_flag & FC_OFFLINE_MODE) || + if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else @@ -1711,14 +1748,15 @@ lpfc_get_stats(struct Scsi_Host *shost) static void lpfc_reset_stats(struct Scsi_Host *shost) { - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; - struct lpfc_sli *psli = &phba->sli; - struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct lpfc_hba *phba = vport->phba; + struct lpfc_sli *psli = &phba->sli; + struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets; LPFC_MBOXQ_t *pmboxq; MAILBOX_t *pmb; int rc = 0; - if (phba->fc_flag & FC_BLOCK_MGMT_IO) + if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) return; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); @@ -1732,7 +1770,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmb->un.varWords[0] = 0x1; /* reset request */ pmboxq->context1 = NULL; - if ((phba->fc_flag & FC_OFFLINE_MODE) || + if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else @@ -1751,7 +1789,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmb->mbxOwner = OWN_HOST; pmboxq->context1 = NULL; - if ((phba->fc_flag & FC_OFFLINE_MODE) || + if ((vport->fc_flag & FC_OFFLINE_MODE) || (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); else @@ -1789,13 +1827,13 @@ lpfc_reset_stats(struct Scsi_Host *shost) static struct lpfc_nodelist * lpfc_get_node_by_target(struct scsi_target *starget) { - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_nodelist *ndlp; spin_lock_irq(shost->host_lock); /* Search for this, mapped, target ID */ - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { + list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && starget->id == ndlp->nlp_sid) { spin_unlock_irq(shost->host_lock); @@ -1885,9 +1923,6 @@ struct fc_function_template lpfc_transport_functions = { .get_host_fabric_name = lpfc_get_host_fabric_name, .show_host_fabric_name = 1, - .get_host_symbolic_name = lpfc_get_host_symbolic_name, - .show_host_symbolic_name = 1, - /* * The LPFC driver treats linkdown handling as target loss events * so there are no sysfs handlers for link_down_tmo. -- cgit v1.2.3