⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpfc_init.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * any potential PRLIs to flush thru the SLI sub-system.	 */	msleep(50);	return (0);}/************************************************************************//*                                                                      *//*    lpfc_hba_down_prep                                                *//*    This routine will do LPFC uninitialization before the             *//*    HBA is reset when bringing down the SLI Layer. This will be       *//*    initialized as a SLI layer callback routine.                      *//*    This routine returns 0 on success. Any other return value         *//*    indicates an error.                                               *//*                                                                      *//************************************************************************/intlpfc_hba_down_prep(struct lpfc_hba * phba){	/* Disable interrupts */	writel(0, phba->HCregaddr);	readl(phba->HCregaddr); /* flush */	/* Cleanup potential discovery resources */	lpfc_els_flush_rscn(phba);	lpfc_els_flush_cmd(phba);	lpfc_disc_flush_list(phba);	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 a reset is sent to the HBA restore PCI configuration registers.	 */	if ( phba->hba_state == LPFC_INIT_START ) {		mdelay(1);		readl(phba->HCregaddr); /* flush */		writel(0, phba->HCregaddr);		readl(phba->HCregaddr); /* flush */		/* Restore PCI cmd register */		pci_write_config_word(phba->pcidev,				      PCI_COMMAND, phba->pci_cfg_value);	}	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;		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);		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]);		lpfc_offline(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;	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){	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]);	do {		switch (vpd[index]) {		case 0x82:			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);			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;		}	} while (!finished && (index < 108));	return(1);}static voidlpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp){	lpfc_vpd_t *vp;	uint32_t id;	uint8_t hdrtype;	char str[16];	vp = &phba->vpd;	pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);	pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);	switch ((id >> 16) & 0xffff) {	case PCI_DEVICE_ID_FIREFLY:		strcpy(str, "LP6000 1");		break;	case PCI_DEVICE_ID_SUPERFLY:		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)			strcpy(str, "LP7000 1");		else			strcpy(str, "LP7000E 1");		break;	case PCI_DEVICE_ID_DRAGONFLY:		strcpy(str, "LP8000 1");		break;	case PCI_DEVICE_ID_CENTAUR:		if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)			strcpy(str, "LP9002 2");		else			strcpy(str, "LP9000 1");		break;	case PCI_DEVICE_ID_RFLY:		strcpy(str, "LP952 2");		break;	case PCI_DEVICE_ID_PEGASUS:		strcpy(str, "LP9802 2");		break;	case PCI_DEVICE_ID_THOR:		if (hdrtype == 0x80)			strcpy(str, "LP10000DC 2");		else			strcpy(str, "LP10000 2");		break;	case PCI_DEVICE_ID_VIPER:		strcpy(str, "LPX1000 10");		break;	case PCI_DEVICE_ID_PFLY:		strcpy(str, "LP982 2");		break;	case PCI_DEVICE_ID_TFLY:		if (hdrtype == 0x80)			strcpy(str, "LP1050DC 2");		else			strcpy(str, "LP1050 2");		break;	case PCI_DEVICE_ID_HELIOS:		if (hdrtype == 0x80)			strcpy(str, "LP11002 4");		else			strcpy(str, "LP11000 4");		break;	case PCI_DEVICE_ID_BMID:		strcpy(str, "LP1150 4");		break;	case PCI_DEVICE_ID_BSMB:		strcpy(str, "LP111 4");		break;	case PCI_DEVICE_ID_ZEPHYR:		if (hdrtype == 0x80)			strcpy(str, "LPe11002 4");		else			strcpy(str, "LPe11000 4");		break;	case PCI_DEVICE_ID_ZMID:		strcpy(str, "LPe1150 4");		break;	case PCI_DEVICE_ID_ZSMB:		strcpy(str, "LPe111 4");		break;	case PCI_DEVICE_ID_LP101:		strcpy(str, "LP101 2");		break;	case PCI_DEVICE_ID_LP10000S:		strcpy(str, "LP10000-S 2");		break;	default:		memset(str, 0, 16);		break;	}	if (mdp)		sscanf(str, "%s", mdp);	if (descp)		sprintf(descp, "Emulex LightPulse %s Gigabit PCI Fibre "			"Channel Adapter", str);}/**************************************************//*   lpfc_post_buffer                             *//*                                                *//*   This routine will post count buffers to the  *//*   ring with the QUE_RING_BUF_CN command. This  *//*   allows 3 buffers / command to be posted.     *//*   Returns the number of buffers NOT posted.    *//**************************************************/intlpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,		 int type){	IOCB_t *icmd;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -