if (!rc) rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, NULL, 0); } else rc = ISCSI_ERR_BAD_OPCODE; 
if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) rc = iscsi_recv_pdu(iscsi_handle(conn), hdr, NULL, 0); } else rc = ISCSI_ERR_PROTO; break; case ISCSI_OP_REJECT: /* we need sth like iscsi_reject_rsp()*/ case ISCSI_OP_ASYNC_EVENT: /* we need sth like iscsi_async_event_rsp() */ rc = ISCSI_ERR_BAD_OPCODE; break; default: rc = ISCSI_ERR_BAD_OPCODE; break; } 
iscsi_hdr_recv(struct iscsi_conn *conn){	int rc = 0;	struct iscsi_hdr *hdr;	struct iscsi_cmd_task *ctask;	struct iscsi_session *session = conn->session;	uint32_t cdgst, rdgst = 0;	hdr = conn->in.hdr;	/* verify PDU length */	conn->in.datalen = ntoh24(hdr->dlength);	if (conn->in.datalen > conn->max_recv_dlength) {		printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n",		       conn->in.datalen, conn->max_recv_dlength);		return ISCSI_ERR_DATALEN;	}	conn->data_copied = 0;	/* read AHS */	conn->in.ahslen = hdr->hlength * 4;	conn->in.offset += conn->in.ahslen;	conn->in.copy -= conn->in.ahslen;	if (conn->in.copy < 0) {		printk(KERN_ERR "iscsi_tcp: can't handle AHS with length "		       "%d bytes\n", conn->in.ahslen);		return ISCSI_ERR_AHSLEN;	}	/* calculate read padding */	conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1);	if (conn->in.padding) {		conn->in.padding = ISCSI_PAD_LEN - conn->in.padding;		debug_scsi("read padding %d bytes\n", conn->in.padding);	}	if (conn->hdrdgst_en) {		struct scatterlist sg;		sg_init_one(&sg, (u8 *)hdr,			    sizeof(struct iscsi_hdr) + conn->in.ahslen);		crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);		rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +				     conn->in.ahslen);	}	/* save opcode for later */	conn->in.opcode = hdr->opcode;	/* verify itt (itt encoding: age+cid+itt) */	if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {		if ((hdr->itt & AGE_MASK) !=				(session->age << AGE_SHIFT)) {			printk(KERN_ERR "iscsi_tcp: received itt %x expected "				"session age (%x)\n", hdr->itt,				session->age & AGE_MASK);			return ISCSI_ERR_BAD_ITT;		}		if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) {			printk(KERN_ERR "iscsi_tcp: received itt %x, expected "				"CID (%x)\n", hdr->itt, conn->id);			return ISCSI_ERR_BAD_ITT;		}		conn->in.itt = hdr->itt & ITT_MASK;	} else		conn->in.itt = hdr->itt;	debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n",		  hdr->opcode, conn->in.offset, conn->in.copy,		  conn->in.ahslen, conn->in.datalen);	if (conn->in.itt < session->cmds_max) {		if (conn->hdrdgst_en && cdgst != rdgst) {			printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "			       "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,			       cdgst);			return ISCSI_ERR_HDR_DGST;		}		ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];		if (!ctask->sc) {			printk(KERN_INFO "iscsi_tcp: dropping ctask with "			       "itt 0x%x\n", ctask->itt);			conn->in.datalen = 0; /* force drop */			return 0;		}		if (ctask->sc->SCp.phase != session->age) {			printk(KERN_ERR "iscsi_tcp: ctask's session age %d, "				"expected %d\n", ctask->sc->SCp.phase,				session->age);			return ISCSI_ERR_SESSION_FAILED;		}		conn->in.ctask = ctask;		debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n",			   hdr->opcode, conn->id, (long)ctask->sc,			   ctask->itt, conn->in.datalen);		switch(conn->in.opcode) {		case ISCSI_OP_SCSI_CMD_RSP:			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);			if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE)				rc = iscsi_cmd_rsp(conn, ctask);			else if (!conn->in.datalen)				rc = iscsi_cmd_rsp(conn, ctask);			else				/*				 * got sense or response data; copying PDU				 * Header to the connection's header				 * placeholder				 */				memcpy(&conn->hdr, hdr,				       sizeof(struct iscsi_hdr));			break;		case ISCSI_OP_SCSI_DATA_IN:			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);			/* save flags for non-exceptional status */			conn->in.flags = hdr->flags;			/* save cmd_status for sense data */			conn->in.cmd_status =				((struct iscsi_data_rsp*)hdr)->cmd_status;			rc = iscsi_data_rsp(conn, ctask);			break;		case ISCSI_OP_R2T:			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);			if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE &&			    ctask->sc->sc_data_direction == DMA_TO_DEVICE)				rc = iscsi_r2t_rsp(conn, ctask);			else				rc = ISCSI_ERR_PROTO;			break;		case ISCSI_OP_NOOP_IN:		case ISCSI_OP_TEXT_RSP:		case ISCSI_OP_LOGOUT_RSP:		case ISCSI_OP_ASYNC_EVENT:		case ISCSI_OP_REJECT:			rc = iscsi_check_assign_cmdsn(session,						 (struct iscsi_nopin*)hdr);			if (rc)				break;			/* update ExpStatSN */			conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;			if (!conn->in.datalen) {				struct iscsi_mgmt_task *mtask;				rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,						    NULL, 0);				mtask = (struct iscsi_mgmt_task *)					session->mgmt_cmds[conn->in.itt -						ISCSI_MGMT_ITT_OFFSET];				if (conn->login_mtask != mtask) {					spin_lock(&session->lock);					__kfifo_put(session->mgmtpool.queue,					    (void*)&mtask, sizeof(void*));					spin_unlock(&session->lock);				}			}			break;		default:			rc = ISCSI_ERR_BAD_OPCODE;			break;		}	} else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET &&		   conn->in.itt < ISCSI_MGMT_ITT_OFFSET +					session->mgmtpool_max) {		struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *)					session->mgmt_cmds[conn->in.itt -						ISCSI_MGMT_ITT_OFFSET];		debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",			   conn->in.opcode, conn->id, mtask->itt,			   conn->in.datalen);		switch(conn->in.opcode) {		case ISCSI_OP_LOGIN_RSP:		case ISCSI_OP_TEXT_RSP:			rc = iscsi_check_assign_cmdsn(session,						 (struct iscsi_nopin*)hdr);			if (rc)				break;			if (!conn->in.datalen) {				rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,						    NULL, 0);				if (conn->login_mtask != mtask) {					spin_lock(&session->lock);					__kfifo_put(session->mgmtpool.queue,					    (void*)&mtask, sizeof(void*));					spin_unlock(&session->lock);				}			}			break;		case ISCSI_OP_SCSI_TMFUNC_RSP:			rc = iscsi_check_assign_cmdsn(session,						 (struct iscsi_nopin*)hdr);			if (rc)				break;			if (conn->in.datalen || conn->in.ahslen) {				rc = ISCSI_ERR_PROTO;				break;			}			conn->tmfrsp_pdus_cnt++;			spin_lock(&session->lock);			if (conn->tmabort_state == TMABORT_INITIAL) {				__kfifo_put(session->mgmtpool.queue,						(void*)&mtask, sizeof(void*));				conn->tmabort_state =					((struct iscsi_tm_rsp *)hdr)->					response == ISCSI_TMF_RSP_COMPLETE ?						TMABORT_SUCCESS:TMABORT_FAILED;				/* unblock eh_abort() */				wake_up(&conn->ehwait);			}			spin_unlock(&session->lock);			break;		default:			rc = ISCSI_ERR_BAD_OPCODE;			break;		}	} else if (conn->in.itt == ISCSI_RESERVED_TAG) {		if (conn->in.opcode == ISCSI_OP_NOOP_IN && !conn->in.datalen) {			rc = iscsi_check_assign_cmdsn(session,						 (struct iscsi_nopin*)hdr);			if (!rc)				rc = iscsi_recv_pdu(iscsi_handle(conn),						    hdr, NULL, 0);		}		else			rc = ISCSI_ERR_BAD_OPCODE;	} else		rc = ISCSI_ERR_BAD_ITT;	return rc;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/9974487824570e7ac388390333ef5c4ca3ebc2da/iscsi_tcp.c/clean/drivers/scsi/iscsi_tcp.c