int start = skb_headlen(skb); 
iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,		unsigned int offset, size_t len){	int rc;	struct iscsi_conn *conn = rd_desc->arg.data;	int start = skb_headlen(skb);	int processed;	char pad[ISCSI_PAD_LEN];	struct scatterlist sg;	/*	 * Save current SKB and its offset in the corresponding	 * connection context.	 */	conn->in.copy = start - offset;	conn->in.offset = offset;	conn->in.skb = skb;	conn->in.len = conn->in.copy;	BUG_ON(conn->in.copy <= 0);	debug_tcp("in %d bytes\n", conn->in.copy);more:	conn->in.copied = 0;	rc = 0;	if (unlikely(conn->suspend_rx)) {		debug_tcp("conn %d Rx suspended!\n", conn->id);		return 0;	}	if (conn->in_progress == IN_PROGRESS_WAIT_HEADER ||	    conn->in_progress == IN_PROGRESS_HEADER_GATHER) {		rc = iscsi_hdr_extract(conn);		if (rc) {		       if (rc == -EAGAIN)				goto nomore;		       else {				iscsi_conn_failure(conn, rc);				return 0;		       }		}		/*		 * Verify and process incoming PDU header.		 */		rc = iscsi_hdr_recv(conn);		if (!rc && conn->in.datalen) {			if (conn->datadgst_en &&			    conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {				BUG_ON(!conn->data_rx_tfm);				crypto_digest_init(conn->data_rx_tfm);			}			conn->in_progress = IN_PROGRESS_DATA_RECV;		} else if (rc) {			iscsi_conn_failure(conn, rc);			return 0;		}	}	if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {		debug_tcp("extra data_recv offset %d copy %d\n",			  conn->in.offset, conn->in.copy);		if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {			uint32_t recv_digest;			skb_copy_bits(conn->in.skb, conn->in.offset,				      &recv_digest, 4);			conn->in.offset += 4;			conn->in.copy -= 4;			if (recv_digest != conn->in.datadgst) {				debug_tcp("iscsi_tcp: data digest error!"					  "0x%x != 0x%x\n", recv_digest,					  conn->in.datadgst);				iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);				return 0;			} else {				debug_tcp("iscsi_tcp: data digest match!"					  "0x%x == 0x%x\n", recv_digest,					  conn->in.datadgst);				conn->in_progress = IN_PROGRESS_WAIT_HEADER;			}		}	}	if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) {		debug_tcp("data_recv offset %d copy %d\n",		       conn->in.offset, conn->in.copy);		rc = iscsi_data_recv(conn);		if (rc) {			if (rc == -EAGAIN) {				rd_desc->count = conn->in.datalen -						conn->in.ctask->data_count;				goto again;			}			iscsi_conn_failure(conn, rc);			return 0;		}		conn->in.copy -= conn->in.padding;		conn->in.offset += conn->in.padding;		if (conn->datadgst_en &&		    conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {			if (conn->in.padding) {				debug_tcp("padding -> %d\n", conn->in.padding);				memset(pad, 0, conn->in.padding);				sg_init_one(&sg, pad, conn->in.padding);				crypto_digest_update(conn->data_rx_tfm, &sg, 1);			}			crypto_digest_final(conn->data_rx_tfm,					    (u8 *) & conn->in.datadgst);			debug_tcp("rx digest 0x%x\n", conn->in.datadgst);			conn->in_progress = IN_PROGRESS_DDIGEST_RECV;		} else			conn->in_progress = IN_PROGRESS_WAIT_HEADER;	}	debug_tcp("f, processed %d from out of %d padding %d\n",	       conn->in.offset - offset, (int)len, conn->in.padding);	BUG_ON(conn->in.offset - offset > len);	if (conn->in.offset - offset != len) {		debug_tcp("continue to process %d bytes\n",		       (int)len - (conn->in.offset - offset));		goto more;	}nomore:	processed = conn->in.offset - offset;	BUG_ON(processed == 0);	return processed;again:	processed = conn->in.offset - offset;	debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n",	          processed, (int)len, (int)rd_desc->count);	BUG_ON(processed == 0);	BUG_ON(processed > len);	conn->rxdata_octets += processed;	return processed;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/bb052349798f775d4d7ed20ffcf1510287d8abe6/iscsi_tcp.c/clean/drivers/scsi/iscsi_tcp.c