else /* this will update header digest */ iscsi_buf_init_hdr(conn, &mtask->headbuf, (char*)&mtask->hdr, (u8 *)mtask->hdrext); 
iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,			char *data, uint32_t data_size){	struct iscsi_session *session = conn->session;	struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;	struct iscsi_mgmt_task *mtask;	spin_lock_bh(&session->lock);	if (session->state == ISCSI_STATE_TERMINATE) {		spin_unlock_bh(&session->lock);		return -EPERM;	}	if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||	    hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))		/*		 * Login and Text are sent serially, in		 * request-followed-by-response sequence.		 * Same mtask can be used. Same ITT must be used.		 * Note that login_mtask is preallocated at conn_create().		 */		mtask = conn->login_mtask;	else {	        BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);	        BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);		if (!__kfifo_get(session->mgmtpool.queue,				 (void*)&mtask, sizeof(void*))) {			spin_unlock_bh(&session->lock);			return -ENOSPC;		}	}	/*	 * pre-format CmdSN and ExpStatSN for outgoing PDU.	 */	if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {		hdr->itt = mtask->itt | (conn->id << CID_SHIFT) |			   (session->age << AGE_SHIFT);		nop->cmdsn = cpu_to_be32(session->cmdsn);		if (conn->c_stage == ISCSI_CONN_STARTED &&		    !(hdr->opcode & ISCSI_OP_IMMEDIATE))			session->cmdsn++;	} else		/* do not advance CmdSN */		nop->cmdsn = cpu_to_be32(session->cmdsn);	nop->exp_statsn = cpu_to_be32(conn->exp_statsn);	memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr));	if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE ||	    conn->stop_stage == STOP_CONN_RECOVER)		iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr,				    sizeof(struct iscsi_hdr));	else		/* this will update header digest */		iscsi_buf_init_hdr(conn, &mtask->headbuf, (char*)&mtask->hdr,				    (u8 *)mtask->hdrext);	spin_unlock_bh(&session->lock);	if (data_size) {		memcpy(mtask->data, data, data_size);		mtask->data_count = data_size;	} else		mtask->data_count = 0;	mtask->xmstate = XMSTATE_IMM_HDR;	if (mtask->data_count) {		iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data,				    mtask->data_count);	}	debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",		   hdr->opcode, hdr->itt, data_size);	/*	 * since send_pdu() could be called at least from two contexts,	 * we need to serialize __kfifo_put, so we don't have to take	 * additional lock on fast data-path	 */        if (hdr->opcode & ISCSI_OP_IMMEDIATE)	        __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*));	else	        __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));	schedule_work(&conn->xmitwork);	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/af973481f4a0902ad35726636c290f4794704948/iscsi_tcp.c/clean/drivers/scsi/iscsi_tcp.c