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

📄 qla_rscn.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));	mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);	wmb();	qla2x00_add_iodesc_timer(iodesc);	/* Issue command to ISP. */	qla2x00_isp_cmd(ha);	if (!ha_locked)		spin_unlock_irqrestore(&ha->hardware_lock, flags);	DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",	    ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));	return (QLA_SUCCESS);}/** * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback. * @ha: HA context * @iodesc: io descriptor * @mbxstat: mailbox status IOCB * * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc * will be used for a retry. */static intqla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,    struct mbx_entry *mbxstat){	fc_port_t *remote_fcport;	remote_fcport = iodesc->remote_fcport;	/* Ensure the port IDs are consistent. */	if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {		DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "		    "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",		    ha->host_no, remote_fcport->d_id.b.domain,		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,		    iodesc->d_id.b.domain, iodesc->d_id.b.area,		    iodesc->d_id.b.al_pa));		return (QLA_SUCCESS);	}	/* Only process the last command. */	if (remote_fcport->iodesc_idx_sent != iodesc->idx) {		DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "		    "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,		    iodesc->d_id.b.domain, iodesc->d_id.b.area,		    iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,		    iodesc->idx));		return (QLA_SUCCESS);	}	if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {		DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "		    "[%x/%02x%02x%02x] online.\n", ha->host_no,		    remote_fcport->loop_id, remote_fcport->d_id.b.domain,		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));		atomic_set(&remote_fcport->state, FCS_ONLINE);	} else {		DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "		    "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,		    remote_fcport->loop_id, remote_fcport->d_id.b.domain,		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,		    le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));		if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)			atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);	}	remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;	return (QLA_SUCCESS);}/** * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware. * @ha: HA context * @iodesc: io descriptor * @ha_locked: is function called with the hardware lock * * Returns QLA_SUCCESS if the IOCB was issued. */static intqla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,    int ha_locked){	unsigned long flags = 0;	struct mbx_entry *mbxentry;	/* Send marker if required. */	if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)		return (QLA_FUNCTION_FAILED);	if (!ha_locked)		spin_lock_irqsave(&ha->hardware_lock, flags);	/* Build fabric port logout mailbox IOCB. */	mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);	if (mbxentry == NULL) {		if (!ha_locked)			spin_unlock_irqrestore(&ha->hardware_lock, flags);		return (QLA_FUNCTION_FAILED);	}	mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);	mbxentry->mb1 = mbxentry->loop_id.extended =	    cpu_to_le16(iodesc->remote_fcport->loop_id);	wmb();	qla2x00_add_iodesc_timer(iodesc);	/* Issue command to ISP. */	qla2x00_isp_cmd(ha);	if (!ha_locked)		spin_unlock_irqrestore(&ha->hardware_lock, flags);	DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",	    ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));	return (QLA_SUCCESS);}/** * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback. * @ha: HA context * @iodesc: io descriptor * @mbxstat: mailbox status IOCB * * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc * will be used for a retry. */static intqla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,    struct mbx_entry *mbxstat){	DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "	    "status=%x mb0=%x mb1=%x.\n", ha->host_no,	    iodesc->remote_fcport->loop_id,	    iodesc->remote_fcport->d_id.b.domain,	    iodesc->remote_fcport->d_id.b.area,	    iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status),	    le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1)));	return (QLA_SUCCESS);}/** * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware. * @ha: HA context * @iodesc: io descriptor * @d_id: port id for device * @ha_locked: is function called with the hardware lock * * Returns QLA_SUCCESS if the IOCB was issued. */static intqla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,    port_id_t *d_id, int ha_locked){	unsigned long flags = 0;	struct mbx_entry *mbxentry;	/* Send marker if required. */	if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)		return (QLA_FUNCTION_FAILED);	if (!ha_locked)		spin_lock_irqsave(&ha->hardware_lock, flags);	/* Build fabric port login mailbox IOCB. */	mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);	if (mbxentry == NULL) {		if (!ha_locked)			spin_unlock_irqrestore(&ha->hardware_lock, flags);		return (QLA_FUNCTION_FAILED);	}	mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT);	mbxentry->mb1 = mbxentry->loop_id.extended =	    cpu_to_le16(iodesc->remote_fcport->loop_id);	mbxentry->mb2 = cpu_to_le16(d_id->b.domain);	mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa);	mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);	wmb();	qla2x00_add_iodesc_timer(iodesc);	/* Issue command to ISP. */	qla2x00_isp_cmd(ha);	if (!ha_locked)		spin_unlock_irqrestore(&ha->hardware_lock, flags);	DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "	    "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,	    iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,	    d_id->b.al_pa));	return (QLA_SUCCESS);}/** * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback. * @ha: HA context * @iodesc: io descriptor * @mbxstat: mailbox status IOCB * * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc * will be used for a retry. */static intqla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,    struct mbx_entry *mbxstat){	int rval;	fc_port_t *fcport, *remote_fcport, *exist_fcport;	struct io_descriptor *abort_iodesc, *login_iodesc;	uint16_t status, mb[8];	uint16_t reuse;	uint16_t remote_loopid;	port_id_t remote_did, inuse_did;	remote_fcport = iodesc->remote_fcport;	/* Only process the last command. */	if (remote_fcport->iodesc_idx_sent != iodesc->idx) {		DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "		    "[%02x%02x%02x], expected %x, received %x.\n",		    ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,		    iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,		    iodesc->idx));		/* Free RSCN fcport resources. */		if (remote_fcport->port_type == FCT_RSCN) {			DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "			    "fcport %p [%x/%02x%02x%02x] given ignored Login "			    "IOCB.\n", ha->host_no, remote_fcport,			    remote_fcport->loop_id,			    remote_fcport->d_id.b.domain,			    remote_fcport->d_id.b.area,			    remote_fcport->d_id.b.al_pa));			list_del(&remote_fcport->list);			kfree(remote_fcport);		}		return (QLA_SUCCESS);	}	status = le16_to_cpu(mbxstat->status);	mb[0] = le16_to_cpu(mbxstat->mb0);	mb[1] = le16_to_cpu(mbxstat->mb1);	mb[2] = le16_to_cpu(mbxstat->mb2);	mb[6] = le16_to_cpu(mbxstat->mb6);	mb[7] = le16_to_cpu(mbxstat->mb7);	/* Good status? */	if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&	    mb[0] == MBS_COMMAND_COMPLETE) {		DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="		    "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,		    mb[1], mbxstat->port_name[0], mbxstat->port_name[1],		    mbxstat->port_name[2], mbxstat->port_name[3],		    mbxstat->port_name[4], mbxstat->port_name[5],		    mbxstat->port_name[6], mbxstat->port_name[7]));		memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);		memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);		/* Is the device already in our fcports list? */		if (remote_fcport->port_type != FCT_RSCN) {			DEBUG14(printk("scsi(%ld): Login IOCB -- marking "			    "[%x/%02x%02x%02x] online.\n", ha->host_no,			    remote_fcport->loop_id,			    remote_fcport->d_id.b.domain,			    remote_fcport->d_id.b.area,			    remote_fcport->d_id.b.al_pa));			qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);			return (QLA_SUCCESS);		}		/* Does the RSCN portname already exist in our fcports list? */		exist_fcport = NULL;		list_for_each_entry(fcport, &ha->fcports, list) {			if (memcmp(remote_fcport->port_name, fcport->port_name,			    WWN_SIZE) == 0) {				exist_fcport = fcport;				break;			}		}		if (exist_fcport != NULL) {			DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "			    "fcport in fcports list [%p].\n", ha->host_no,			    exist_fcport));			/* Abort any ADISC that could have been sent. */			if (exist_fcport->iodesc_idx_sent != iodesc->idx &&			    exist_fcport->iodesc_idx_sent <			    MAX_IO_DESCRIPTORS &&			    ha->io_descriptors[exist_fcport->iodesc_idx_sent].			    cb_idx == ADISC_PORT_IOCB_CB) {				abort_iodesc = qla2x00_alloc_iodesc(ha);				if (abort_iodesc) {					DEBUG14(printk("scsi(%ld): Login IOCB "					    "-- issuing abort to outstanding "					    "Adisc [%x/%02x%02x%02x].\n",					    ha->host_no, remote_fcport->loop_id,					    exist_fcport->d_id.b.domain,					    exist_fcport->d_id.b.area,					    exist_fcport->d_id.b.al_pa));					abort_iodesc->cb_idx = ABORT_IOCB_CB;					abort_iodesc->d_id.b24 =					    exist_fcport->d_id.b24;					abort_iodesc->remote_fcport =					    exist_fcport;					exist_fcport->iodesc_idx_sent =					    abort_iodesc->idx;					qla2x00_send_abort_iocb(ha,					    abort_iodesc, ha->io_descriptors[					     exist_fcport->iodesc_idx_sent].					      signature, 1);				} else {					DEBUG14(printk("scsi(%ld): Login IOCB "					    "-- unable to abort outstanding "					    "Adisc [%x/%02x%02x%02x].\n",					    ha->host_no, remote_fcport->loop_id,					    exist_fcport->d_id.b.domain,					    exist_fcport->d_id.b.area,					    exist_fcport->d_id.b.al_pa));				}			}			/*			 * If the existing fcport is waiting to send an ADISC			 * or LOGIN, then reuse remote fcport (RSCN) to			 * continue waiting.			 */			reuse = 0;			remote_loopid = remote_fcport->loop_id;			remote_did.b24 = remote_fcport->d_id.b24;			if (exist_fcport->iodesc_idx_sent ==			    IODESC_ADISC_NEEDED ||			    exist_fcport->iodesc_idx_sent ==			    IODESC_LOGIN_NEEDED) {				DEBUG14(printk("scsi(%ld): Login IOCB -- "				    "existing fcport [%x/%02x%02x%02x] "				    "waiting for IO descriptor, reuse RSCN "				    "fcport.\n", ha->host_no,				    exist_fcport->loop_id,				    exist_fcport->d_id.b.domain,				    exist_fcport->d_id.b.area,				    exist_fcport->d_id.b.al_pa));				reuse++;				remote_fcport->iodesc_idx_sent =				    exist_fcport->iodesc_idx_sent;				exist_fcport->iodesc_idx_sent =				    IODESC_INVALID_INDEX;				remote_fcport->loop_id = exist_fcport->loop_id;				remote_fcport->d_id.b24 =				    exist_fcport->d_id.b24;			}			/* Logout the old loopid. */			if (!reuse &&			    exist_fcport->loop_id != remote_fcport->loop_id &&			    exist_fcport->loop_id != FC_NO_LOOP_ID) {				login_iodesc = qla2x00_alloc_iodesc(ha);				if (login_iodesc) {					DEBUG14(printk("scsi(%ld): Login IOCB "					    "-- issuing logout to free old "					    "loop id [%x/%02x%02x%02x].\n",					    ha->host_no, exist_fcport->loop_id,					    exist_fcport->d_id.b.domain,					    exist_fcport->d_id.b.area,					    exist_fcport->d_id.b.al_pa));					login_iodesc->cb_idx =					    LOGOUT_PORT_IOCB_CB;					login_iodesc->d_id.b24 =					    exist_fcport->d_id.b24;					login_iodesc->remote_fcport =					    exist_fcport;					exist_fcport->iodesc_idx_sent =					    login_iodesc->idx;					qla2x00_send_logout_iocb(ha,					    login_iodesc, 1);				} else {					/* Ran out of IO descriptiors. */					DEBUG14(printk("scsi(%ld): Login IOCB "					    "-- unable to logout to free old "					    "loop id [%x/%02x%02x%02x].\n",					    ha->host_no, exist_fcport->loop_id,					    exist_fcport->d_id.b.domain,					    exist_fcport->d_id.b.area,					    exist_fcport->d_id.b.al_pa));					exist_fcport->iodesc_idx_sent =					    IODESC_INVALID_INDEX;				}			}			/* Update existing fcport with remote fcport info. */			DEBUG14(printk("scsi(%ld): Login IOCB -- marking "			    "existing fcport [%x/%02x%02x%02x] online.\n",			    ha->host_no, remote_loopid, remote_did.b.domain,			    remote_did.b.area, remote_did.b.al_pa));			memcpy(exist_fcport->node_name,			    remote_fcport->node_name, WWN_SIZE);			exist_fcport->loop_id = remote_loopid;			exist_fcport->d_id.b24 = remote_did.b24;			qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);			/* Finally, free the remote (RSCN) fcport. */			if (!reuse) {				DEBUG14(printk("scsi(%ld): Login IOCB -- "				    "Freeing RSCN fcport %p "				    "[%x/%02x%02x%02x].\n", ha->host_no,				    remote_fcport, remote_fcport->loop_id,				    remote_fcport->d_id.b.domain,				    remote_fcport->d_id.b.area,				    remote_fcport->d_id.b.al_pa));				list_del(&remote_fcport->list);				kfree(remote_fcport);			}			return (QLA_SUCCESS);		}		/*		 * A new device has been added, move the RSCN fcport to our		 * fcports list.		 */		DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "		    "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,		    remote_fcport->loop_id, remote_fcport->d_id.b.domain,		    remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));		list_del(&remote_fcport->list);		remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);		qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);		list_add_tail(&remote_fcport->list, &ha->fcports);		set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);	} else {		/* Handle login failure. */		if (remote_fcport->login_retry != 0) {			if (mb[0] == MBS_LOOP_ID_USED) {				inuse_did.b.domain = LSB(mb[1]);				inuse_did.b.area = MSB(mb[2]);				inuse_did.b.al_pa = LSB(mb[2]);				DEBUG14(printk("scsi(%ld): Login IOCB -- loop "				    "id [%x] used by port id [%02x%02x%02x].\n",				    ha->host_no, remote_fcport->loop_id,				    inuse_did.b.domain, inuse_did.b.area,				    inuse_did.b.al_pa));				if (remote_fcport->d_id.b24 ==				    INVALID_PORT_ID) {					/*					 * Invalid port id means we are trying

⌨️ 快捷键说明

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