[Linux1394-cvslog] rev 660 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <dm...@li...> - 2002-11-06 04:10:44
|
Author: dmaas Date: 2002-11-05 23:10:39 -0500 (Tue, 05 Nov 2002) New Revision: 660 Modified: trunk/iso.c trunk/ohci1394.c Log: rawiso - keep iso headers on receive so we can record the tag/sy/channel/cycle info Modified: trunk/ohci1394.c ============================================================================== --- trunk/ohci1394.c (original) +++ trunk/ohci1394.c 2002-11-05 23:10:40.000000000 -0500 @@ -1100,6 +1100,8 @@ int i; for(i = 0; i < iso->buf_packets; i++) { + int want_interrupt; + unsigned int data_size; /* pointer to the DMA descriptor */ struct dma_cmd *il = ((struct dma_cmd*) recv->prog.kvirt) + pkt; @@ -1109,9 +1111,10 @@ /* offset of this bus_cycle within the DMA buffer */ unsigned long buf_offset = hpsb_iso_packet_data(iso, pkt) - iso->buf.kvirt; - - int want_interrupt; - unsigned int data_size = iso->max_packet_size; + + /* back up 8 bytes for the iso header */ + buf_offset -= 8; + data_size = iso->max_packet_size + 8; /* ask for an interrupt every now and then, and always interrupt on the final descriptor */ @@ -1158,14 +1161,14 @@ reg_write(recv->ohci, recv->ContextControlClear, 0xFFFFFFFF); wmb(); - /* use packet-per-buffer mode, and do not keep ISO headers */ - reg_write(recv->ohci, recv->ContextControlSet, 0x00000000); + /* use packet-per-buffer mode, and keep ISO headers */ + reg_write(recv->ohci, recv->ContextControlSet, (1 << 30)); /* match on all tags, listen on channel */ reg_write(recv->ohci, recv->ContextMatch, 0xF0000000 | iso->channel); if(cycle != -1) { - /* XXX use cycleMatch */ + /* XXX DJM use cycleMatch */ } /* address of first descriptor block */ @@ -1185,7 +1188,7 @@ /* check RUN */ if(!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) { - PRINT(KERN_ERR, recv->ohci->id, "Error starting ISO DMA reception (ContextControl 0x%08x)\n", + PRINT(KERN_ERR, recv->ohci->id, "Error starting IR DMA (ContextControl 0x%08x)\n", reg_read(recv->ohci, recv->ContextControlSet)); return -1; } @@ -1246,7 +1249,6 @@ /* loop over the entire buffer */ for(count = 0; count < iso->buf_packets; count++) { u32 packet_len = 0; - struct hpsb_iso_packet_info *info; /* pointer to the DMA descriptor */ struct dma_cmd *il = ((struct dma_cmd*) recv->prog.kvirt) + recv->pkt_dma; @@ -1268,7 +1270,7 @@ /* rescount is the number of bytes *remaining* in the packet buffer, after the packet was written */ packet_len = iso->max_packet_size - rescount; - + } else if(event == 0x02) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - packet too long for buffer\n"); } else if(event) { @@ -1279,10 +1281,18 @@ dma_region_sync(&iso->buf, recv->pkt_dma * iso->buf_stride, iso->buf_stride); /* record the per-packet info */ - info = hpsb_iso_packet_info(iso, recv->pkt_dma); - info->len = packet_len; - - /* XXX record channel, sy, tag, cycle */ + { + /* iso header is 8 bytes ahead of the data payload */ + unsigned char *hdr = hpsb_iso_packet_data(iso, recv->pkt_dma) - 8; + + struct hpsb_iso_packet_info *info = hpsb_iso_packet_info(iso, recv->pkt_dma); + + info->len = packet_len; + info->cycle = (hdr[0] | (hdr[1] << 8)) & 0x1FFF; + info->channel = hdr[5] & 0x3F; + info->tag = hdr[5] >> 6; + info->sy = hdr[4] & 0xF; + } /* at least one packet came in, so wake up the reader */ wake = 1; Modified: trunk/iso.c ============================================================================== --- trunk/iso.c (original) +++ trunk/iso.c 2002-11-05 23:10:40.000000000 -0500 @@ -42,11 +42,21 @@ struct hpsb_iso *iso; unsigned int packet_plus_info; int dma_direction; + int iso_header_bytes; + const int info_bytes = sizeof(struct hpsb_iso_packet_info); /* make sure driver supports the ISO API */ if(!host->driver->isoctl) return NULL; + if(type == HPSB_ISO_RECV) { + /* when receiving, leave 8 extra bytes in front + of the data payload for the iso header */ + iso_header_bytes = 8; + } else { + iso_header_bytes = 0; + } + /* sanitize parameters */ if(buf_packets < 2) @@ -55,14 +65,14 @@ if(irq_interval < 1 || irq_interval > buf_packets / 2) irq_interval = buf_packets / 2; - if(max_packet_size + sizeof(struct hpsb_iso_packet_info) > PAGE_SIZE) + if(max_packet_size + info_bytes + iso_header_bytes > PAGE_SIZE) return NULL; /* size of packet payload plus the per-packet info must be a power of 2 and at most equal to the page size */ for(packet_plus_info = 256; packet_plus_info < PAGE_SIZE; packet_plus_info *= 2) { - if(packet_plus_info >= (max_packet_size + sizeof(struct hpsb_iso_packet_info))) { + if(packet_plus_info >= (max_packet_size + info_bytes + iso_header_bytes)) { break; } } @@ -83,8 +93,8 @@ iso->buf_packets = buf_packets; iso->buf_stride = packet_plus_info; iso->max_packet_size = max_packet_size; - iso->packet_data_offset = 0; - iso->packet_info_offset = max_packet_size; + iso->packet_data_offset = iso_header_bytes; + iso->packet_info_offset = iso_header_bytes + max_packet_size; iso->first_packet = 0; if(iso->type == HPSB_ISO_XMIT) { |