lpfc_init.c
来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,888 行 · 第 1/4 页
C
1,888 行
struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; struct lpfc_dmabuf *mp, *next_mp; int i; /* Cleanup preposted buffers on the ELS ring */ pring = &psli->ring[LPFC_ELS_RING]; list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { list_del(&mp->list); pring->postbufq_cnt--; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; lpfc_sli_abort_iocb_ring(phba, pring); } return 0;}/************************************************************************//* *//* lpfc_handle_eratt *//* This routine will handle processing a Host Attention *//* Error Status event. This will be initialized *//* as a SLI layer callback routine. *//* *//************************************************************************/voidlpfc_handle_eratt(struct lpfc_hba * phba){ struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; if (phba->work_hs & HS_FFER6) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, "%d:1301 Re-establishing Link " "Data: x%x x%x x%x\n", phba->brd_no, phba->work_hs, phba->work_status[0], phba->work_status[1]); spin_lock_irq(phba->host->host_lock); phba->fc_flag |= FC_ESTABLISH_LINK; psli->sli_flag &= ~LPFC_SLI2_ACTIVE; spin_unlock_irq(phba->host->host_lock); /* * Firmware stops when it triggled erratt with HS_FFER6. * That could cause the I/Os dropped by the firmware. * Error iocb (I/O) on txcmplq and let the SCSI layer * retry it after re-establishing link. */ pring = &psli->ring[psli->fcp_ring]; lpfc_sli_abort_iocb_ring(phba, pring); /* * There was a firmware error. Take the hba offline and then * attempt to restart it. */ lpfc_offline(phba); lpfc_sli_brdrestart(phba); if (lpfc_online(phba) == 0) { /* Initialize the HBA */ mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); return; } } else { /* The if clause above forces this code path when the status * failure is a value other than FFER6. Do not call the offline * twice. This is the adapter hardware error path. */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "%d:0457 Adapter Hardware Error " "Data: x%x x%x x%x\n", phba->brd_no, phba->work_hs, phba->work_status[0], phba->work_status[1]); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; lpfc_offline(phba); phba->hba_state = LPFC_HBA_ERROR; lpfc_hba_down_post(phba); }}/************************************************************************//* *//* lpfc_handle_latt *//* This routine will handle processing a Host Attention *//* Link Status event. This will be initialized *//* as a SLI layer callback routine. *//* *//************************************************************************/voidlpfc_handle_latt(struct lpfc_hba * phba){ struct lpfc_sli *psli = &phba->sli; LPFC_MBOXQ_t *pmb; volatile uint32_t control; struct lpfc_dmabuf *mp; int rc = -ENOMEM; pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmb) goto lpfc_handle_latt_err_exit; mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!mp) goto lpfc_handle_latt_free_pmb; mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); if (!mp->virt) goto lpfc_handle_latt_free_mp; rc = -EIO; /* Cleanup any outstanding ELS commands */ lpfc_els_flush_cmd(phba); psli->slistat.link_event++; lpfc_read_la(phba, pmb, mp); pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); if (rc == MBX_NOT_FINISHED) goto lpfc_handle_latt_free_mp; /* Clear Link Attention in HA REG */ spin_lock_irq(phba->host->host_lock); writel(HA_LATT, phba->HAregaddr); readl(phba->HAregaddr); /* flush */ spin_unlock_irq(phba->host->host_lock); return;lpfc_handle_latt_free_mp: kfree(mp);lpfc_handle_latt_free_pmb: kfree(pmb);lpfc_handle_latt_err_exit: /* Enable Link attention interrupts */ spin_lock_irq(phba->host->host_lock); psli->sli_flag |= LPFC_PROCESS_LA; control = readl(phba->HCregaddr); control |= HC_LAINT_ENA; writel(control, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ /* Clear Link Attention in HA REG */ writel(HA_LATT, phba->HAregaddr); readl(phba->HAregaddr); /* flush */ spin_unlock_irq(phba->host->host_lock); lpfc_linkdown(phba); phba->hba_state = LPFC_HBA_ERROR; /* The other case is an error from issue_mbox */ if (rc == -ENOMEM) lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, "%d:0300 READ_LA: no buffers\n", phba->brd_no); return;}/************************************************************************//* *//* lpfc_parse_vpd *//* This routine will parse the VPD data *//* *//************************************************************************/static intlpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len){ uint8_t lenlo, lenhi; uint32_t Length; int i, j; int finished = 0; int index = 0; if (!vpd) return 0; /* Vital Product */ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "%d:0455 Vital Product Data: x%x x%x x%x x%x\n", phba->brd_no, (uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2], (uint32_t) vpd[3]); while (!finished && (index < (len - 4))) { switch (vpd[index]) { case 0x82: case 0x91: index += 1; lenlo = vpd[index]; index += 1; lenhi = vpd[index]; index += 1; i = ((((unsigned short)lenhi) << 8) + lenlo); index += i; break; case 0x90: index += 1; lenlo = vpd[index]; index += 1; lenhi = vpd[index]; index += 1; Length = ((((unsigned short)lenhi) << 8) + lenlo); if (Length > len - index) Length = len - index; while (Length > 0) { /* Look for Serial Number */ if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { index += 2; i = vpd[index]; index += 1; j = 0; Length -= (3+i); while(i--) { phba->SerialNumber[j++] = vpd[index++]; if (j == 31) break; } phba->SerialNumber[j] = 0; continue; } else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) { phba->vpd_flag |= VPD_MODEL_DESC; index += 2; i = vpd[index]; index += 1; j = 0; Length -= (3+i); while(i--) { phba->ModelDesc[j++] = vpd[index++]; if (j == 255) break; } phba->ModelDesc[j] = 0; continue; } else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) { phba->vpd_flag |= VPD_MODEL_NAME; index += 2; i = vpd[index]; index += 1; j = 0; Length -= (3+i); while(i--) { phba->ModelName[j++] = vpd[index++]; if (j == 79) break; } phba->ModelName[j] = 0; continue; } else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) { phba->vpd_flag |= VPD_PROGRAM_TYPE; index += 2; i = vpd[index]; index += 1; j = 0; Length -= (3+i); while(i--) { phba->ProgramType[j++] = vpd[index++]; if (j == 255) break; } phba->ProgramType[j] = 0; continue; } else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) { phba->vpd_flag |= VPD_PORT; index += 2; i = vpd[index]; index += 1; j = 0; Length -= (3+i); while(i--) { phba->Port[j++] = vpd[index++]; if (j == 19) break; } phba->Port[j] = 0; continue; } else { index += 2; i = vpd[index]; index += 1; index += i; Length -= (3 + i); } } finished = 0; break; case 0x78: finished = 1; break; default: index ++; break; } } return(1);}static voidlpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp){ lpfc_vpd_t *vp; uint16_t dev_id = phba->pcidev->device; uint16_t dev_subid = phba->pcidev->subsystem_device; uint8_t hdrtype; int max_speed; char * ports; struct { char * name; int max_speed; char * ports; char * bus; } m = {"<Unknown>", 0, "", ""}; pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); ports = (hdrtype == 0x80) ? "2-port " : ""; if (mdp && mdp[0] != '\0' && descp && descp[0] != '\0') return; if (phba->lmt & LMT_10Gb) max_speed = 10; else if (phba->lmt & LMT_8Gb) max_speed = 8; else if (phba->lmt & LMT_4Gb) max_speed = 4; else if (phba->lmt & LMT_2Gb) max_speed = 2; else max_speed = 1; vp = &phba->vpd; switch (dev_id) { case PCI_DEVICE_ID_FIREFLY: m = (typeof(m)){"LP6000", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_SUPERFLY: if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) m = (typeof(m)){"LP7000", max_speed, "", "PCI"}; else m = (typeof(m)){"LP7000E", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_DRAGONFLY: m = (typeof(m)){"LP8000", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_CENTAUR: if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) m = (typeof(m)){"LP9002", max_speed, "", "PCI"}; else m = (typeof(m)){"LP9000", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_RFLY: m = (typeof(m)){"LP952", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_PEGASUS: m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"}; break; case PCI_DEVICE_ID_THOR: if (hdrtype == 0x80) m = (typeof(m)){"LP10000DC", max_speed, ports, "PCI-X"}; else m = (typeof(m)){"LP10000", max_speed, ports, "PCI-X"}; break; case PCI_DEVICE_ID_VIPER: m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"}; break; case PCI_DEVICE_ID_PFLY: m = (typeof(m)){"LP982", max_speed, "", "PCI-X"}; break; case PCI_DEVICE_ID_TFLY: if (hdrtype == 0x80) m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"}; else m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"}; break; case PCI_DEVICE_ID_HELIOS: if (hdrtype == 0x80) m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"}; else m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_HELIOS_SCSP: m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_HELIOS_DCSP: m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_NEPTUNE: if (hdrtype == 0x80) m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"}; else m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_NEPTUNE_SCSP: m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_NEPTUNE_DCSP: m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_BMID: m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_BSMB: m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_ZEPHYR: if (hdrtype == 0x80) m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"}; else m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZEPHYR_SCSP: m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZEPHYR_DCSP: m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZMID: m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZSMB: m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_LP101: m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"}; break; case PCI_DEVICE_ID_LP10000S: m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"}; break; case PCI_DEVICE_ID_LP11000S: case PCI_DEVICE_ID_LPE11000S: switch (dev_subid) { case PCI_SUBSYSTEM_ID_LP11000S: m = (typeof(m)){"LP11000-S", max_speed, ports, "PCI-X2"}; break; case PCI_SUBSYSTEM_ID_LP11002S: m = (typeof(m)){"LP11002-S", max_speed, ports, "PCI-X2"}; break; case PCI_SUBSYSTEM_ID_LPE11000S: m = (typeof(m)){"LPe11000-S", max_speed, ports, "PCIe"}; break; case PCI_SUBSYSTEM_ID_LPE11002S: m = (typeof(m)){"LPe11002-S", max_speed, ports, "PCIe"}; break; case PCI_SUBSYSTEM_ID_LPE11010S: m = (typeof(m)){"LPe11010-S", max_speed, "10-port ", "PCIe"}; break; default: m = (typeof(m)){ 0 }; break; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?