kernels/linux-2.4.0/drivers/ieee1394/ohci1394.c
/* Bottom half that processes dma receive buffers */
Bottom half that processes dma receive buffers
Bottom half that processes dma receive buffers
static void dma_rcv_bh(void *data)
{
	struct dma_rcv_ctx *d = (struct dma_rcv_ctx*)data;
	struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
	unsigned int split_left, idx, offset, rescount;
	unsigned char tcode;
	int length, bytes_left, ack;
	quadlet_t *buf_ptr;
	char *split_ptr;
	char msg[256];
	spin_lock(&d->lock);
	idx = d->buf_ind;
	offset = d->buf_offset;
	buf_ptr = d->buf_cpu[idx] + offset/4;
	rescount = d->prg_cpu[idx]->status&0xffff;
	bytes_left = d->buf_size - rescount - offset;
	while (bytes_left>0) {
		tcode = (buf_ptr[0]>>4)&0xf;
		length = packet_length(d, idx, buf_ptr, offset);
		if (length<4) { 
			sprintf(msg,"unexpected tcode 0x%X in AR ctx=%d",
				tcode, d->ctx);
			ohci1394_stop_context(ohci, d->ctrlClear, msg);
			spin_unlock(&d->lock);
			return;
		}
		if ((offset+length)>d->buf_size) { 
			if (length>d->split_buf_size) {
				ohci1394_stop_context(ohci, d->ctrlClear,
					     "split packet size exceeded");
				d->buf_ind = idx;
				d->buf_offset = offset;
				spin_unlock(&d->lock);
				return;
			}
			if (d->prg_cpu[(idx+1)%d->num_desc]->status
			    ==d->buf_size) {
				PRINT(KERN_INFO, ohci->id,
				      "Got only half a packet !!!");
				d->buf_ind = idx;
				d->buf_offset = offset;
				spin_unlock(&d->lock);
				return;
			}
			split_left = length;
			split_ptr = (char *)d->spb;
			memcpy(split_ptr,buf_ptr,d->buf_size-offset);
			split_left -= d->buf_size-offset;
			split_ptr += d->buf_size-offset;
			insert_dma_buffer(d, idx);
			idx = (idx+1) % d->num_desc;
			buf_ptr = d->buf_cpu[idx];
			offset=0;
			while (split_left >= d->buf_size) {
				memcpy(split_ptr,buf_ptr,d->buf_size);
				split_ptr += d->buf_size;
				split_left -= d->buf_size;
				insert_dma_buffer(d, idx);
				idx = (idx+1) % d->num_desc;
				buf_ptr = d->buf_cpu[idx];
			}
			if (split_left>0) {
				memcpy(split_ptr, buf_ptr, split_left);
				offset = split_left;
				buf_ptr += offset/4;
			}
			if (tcode != 0xE) {
				DBGMSG(ohci->id, "Split packet received from"
				       " node %d ack=0x%02X spd=%d tcode=0x%X"
				       " length=%d data=0x%08x ctx=%d",
				       (d->spb[1]>>16)&0x3f,
				       (d->spb[length/4-1]>>16)&0x1f,
				       (d->spb[length/4-1]>>21)&0x3,
				       tcode, length, d->spb[3], d->ctx);
				ack = (((d->spb[length/4-1]>>16)&0x1f) 
				       == 0x11) ? 1 : 0;
				hpsb_packet_received(ohci->host, d->spb, 
						     length, ack);
			}
			else 
				PRINT(KERN_INFO, ohci->id, 
				      "Got phy packet ctx=%d ... discarded",
				      d->ctx);
		}
		else {
			if (tcode != 0xE) {
				DBGMSG(ohci->id, "Packet received from node"
				       " %d ack=0x%02X spd=%d tcode=0x%X"
				       " length=%d data=0x%08x ctx=%d",
				       (buf_ptr[1]>>16)&0x3f,
				       (buf_ptr[length/4-1]>>16)&0x1f,
				       (buf_ptr[length/4-1]>>21)&0x3,
				       tcode, length, buf_ptr[3], d->ctx);
				ack = (((buf_ptr[length/4-1]>>16)&0x1f)
				       == 0x11) ? 1 : 0;
				hpsb_packet_received(ohci->host, buf_ptr, 
						     length, ack);
			}
			else 
				PRINT(KERN_INFO, ohci->id, 
				      "Got phy packet ctx=%d ... discarded",
				      d->ctx);
			offset += length;
			buf_ptr += length/4;
			if (offset==d->buf_size) {
				insert_dma_buffer(d, idx);
				idx = (idx+1) % d->num_desc;
				buf_ptr = d->buf_cpu[idx];
				offset=0;
			}
		}
		rescount = d->prg_cpu[idx]->status & 0xffff;
		bytes_left = d->buf_size - rescount - offset;
	}
	d->buf_ind = idx;
	d->buf_offset = offset;
	spin_unlock(&d->lock);
}
static void dma_rcv_bh ( void * data ) { struct dma_rcv_ctx * d = ( struct dma_rcv_ctx * ) data ; struct ti_ohci * ohci = ( struct ti_ohci * ) ( d -> ohci ) ; unsigned int split_left , idx , offset , rescount ; unsigned char tcode ; int length , bytes_left , ack ; quadlet_t * buf_ptr ; char * split_ptr ; char msg [ 256 ] ; spin_lock ( & d -> lock ) ; idx = d -> buf_ind ; offset = d -> buf_offset ; buf_ptr = d -> buf_cpu [ idx ] + offset / 4 ; rescount = d -> prg_cpu [ idx ] -> status & 0xffff ; bytes_left = d -> buf_size - rescount - offset ; while ( bytes_left > 0 ) { tcode = ( buf_ptr [ 0 ] >> 4 ) & 0xf ; length = packet_length ( d , idx , buf_ptr , offset ) ; if ( length < 4 ) { sprintf ( msg , " " , tcode , d -> ctx ) ; ohci1394_stop_context ( ohci , d -> ctrlClear , msg ) ; spin_unlock ( & d -> lock ) ; return ; } if ( ( offset + length ) > d -> buf_size ) { if ( length > d -> split_buf_size ) { ohci1394_stop_context ( ohci , d -> ctrlClear , " " ) ; d -> buf_ind = idx ; d -> buf_offset = offset ; spin_unlock ( & d -> lock ) ; return ; } if ( d -> prg_cpu [ ( idx + 1 ) % d -> num_desc ] -> status == d -> buf_size ) { PRINT ( KERN_INFO , ohci -> id , " " ) ; d -> buf_ind = idx ; d -> buf_offset = offset ; spin_unlock ( & d -> lock ) ; return ; } split_left = length ; split_ptr = ( char * ) d -> spb ; memcpy ( split_ptr , buf_ptr , d -> buf_size - offset ) ; split_left -= d -> buf_size - offset ; split_ptr += d -> buf_size - offset ; insert_dma_buffer ( d , idx ) ; idx = ( idx + 1 ) % d -> num_desc ; buf_ptr = d -> buf_cpu [ idx ] ; offset = 0 ; while ( split_left >= d -> buf_size ) { memcpy ( split_ptr , buf_ptr , d -> buf_size ) ; split_ptr += d -> buf_size ; split_left -= d -> buf_size ; insert_dma_buffer ( d , idx ) ; idx = ( idx + 1 ) % d -> num_desc ; buf_ptr = d -> buf_cpu [ idx ] ; } if ( split_left > 0 ) { memcpy ( split_ptr , buf_ptr , split_left ) ; offset = split_left ; buf_ptr += offset / 4 ; } if ( tcode != 0xE ) { DBGMSG ( ohci -> id , " " " " " " , ( d -> spb [ 1 ] >> 16 ) & 0x3f , ( d -> spb [ length / 4 - 1 ] >> 16 ) & 0x1f , ( d -> spb [ length / 4 - 1 ] >> 21 ) & 0x3 , tcode , length , d -> spb [ 3 ] , d -> ctx ) ; ack = ( ( ( d -> spb [ length / 4 - 1 ] >> 16 ) & 0x1f ) == 0x11 ) ? 1 : 0 ; hpsb_packet_received ( ohci -> host , d -> spb , length , ack ) ; } else PRINT ( KERN_INFO , ohci -> id , " " , d -> ctx ) ; } else { if ( tcode != 0xE ) { DBGMSG ( ohci -> id , " " " " " " , ( buf_ptr [ 1 ] >> 16 ) & 0x3f , ( buf_ptr [ length / 4 - 1 ] >> 16 ) & 0x1f , ( buf_ptr [ length / 4 - 1 ] >> 21 ) & 0x3 , tcode , length , buf_ptr [ 3 ] , d -> ctx ) ; ack = ( ( ( buf_ptr [ length / 4 - 1 ] >> 16 ) & 0x1f ) == 0x11 ) ? 1 : 0 ; hpsb_packet_received ( ohci -> host , buf_ptr , length , ack ) ; } else PRINT ( KERN_INFO , ohci -> id , " " , d -> ctx ) ; offset += length ; buf_ptr += length / 4 ; if ( offset == d -> buf_size ) { insert_dma_buffer ( d , idx ) ; idx = ( idx + 1 ) % d -> num_desc ; buf_ptr = d -> buf_cpu [ idx ] ; offset = 0 ; } } rescount = d -> prg_cpu [ idx ] -> status & 0xffff ; bytes_left = d -> buf_size - rescount - offset ; } d -> buf_ind = idx ; d -> buf_offset = offset ; spin_unlock ( & d -> lock ) ; }
Bottom half that processes dma receive buffers
Bottom half that processes dma receive buffers
/* something is wrong */ /* Split packet */ /* other part of packet not written yet */ /* this should never happen I think */ /* anyway we'll get it on the next call */ /* 
			 * We get one phy packet for each bus reset. 
			 * we know that from now on the bus topology may
			 * have changed. Just ignore it for the moment
			 */ /* 
			 * We get one phy packet for each bus reset. 
			 * we know that from now on the bus topology may
			 * have changed. Just ignore it for the moment
			 */