[Linux1394-cvslog] rev 539 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <dm...@li...> - 2002-08-06 22:48:48
|
Author: dmaas Date: 2002-08-07 03:38:21 -0400 (Wed, 07 Aug 2002) New Revision: 539 Modified: trunk/dv1394-private.h trunk/dv1394.c Log: dv1394 updates: - make DMA programs little-endian, regardless of CPU endianness - use plain vmalloc_32() to avoid a memory leak with mem_map_reserve() - add a missing spin_unlock to dv1394_devfs_find (thanks to Baum Peter Georg for spotting this) Modified: trunk/dv1394-private.h ============================================================================== --- trunk/dv1394-private.h (original) +++ trunk/dv1394-private.h 2002-08-07 03:38:22.000000000 -0400 @@ -91,20 +91,20 @@ unsigned char sync_tag, unsigned int payload_size) { - omi->q[0] = 0x02000000 | 8 ; /* OUTPUT_MORE_IMMEDIATE; 8 is the size of the IT header */ + omi->q[0] = cpu_to_le32(0x02000000 | 8); /* OUTPUT_MORE_IMMEDIATE; 8 is the size of the IT header */ omi->q[1] = 0; omi->q[2] = 0; omi->q[3] = 0; /* IT packet header */ - omi->q[4] = (0x0 << 16) /* DMA_SPEED_100 */ - | (tag << 14) - | (channel << 8) - | (TCODE_ISO_DATA << 4) - | (sync_tag); + omi->q[4] = cpu_to_le32( (0x0 << 16) /* DMA_SPEED_100 */ + | (tag << 14) + | (channel << 8) + | (TCODE_ISO_DATA << 4) + | (sync_tag) ); - omi->q[5] = payload_size << 16; - omi->q[5] |= (0x7F << 8) | 0xA0; /* reserved field; mimic behavior of my Sony DSR-40 */ + /* reserved field; mimic behavior of my Sony DSR-40 */ + omi->q[5] = cpu_to_le32((payload_size << 16) | (0x7F << 8) | 0xA0); omi->q[6] = 0; omi->q[7] = 0; @@ -114,10 +114,8 @@ unsigned int data_size, unsigned long data_phys_addr) { - om->q[0] = 0; /* OUTPUT_MORE */ - om->q[0] |= data_size; - - om->q[1] = data_phys_addr; + om->q[0] = cpu_to_le32(data_size); + om->q[1] = cpu_to_le32(data_phys_addr); om->q[2] = 0; om->q[3] = 0; } @@ -128,19 +126,20 @@ unsigned int data_size, unsigned long data_phys_addr) { - ol->q[0] = 0; - ol->q[0] |= 1 << 28; /* OUTPUT_LAST */ + u32 temp = 0; + temp |= 1 << 28; /* OUTPUT_LAST */ if(want_timestamp) /* controller will update timestamp at DMA time */ - ol->q[0] |= 1 << 27; + temp |= 1 << 27; if(want_interrupt) - ol->q[0] |= 3 << 20; + temp |= 3 << 20; - ol->q[0] |= 3 << 18; /* must take branch */ - ol->q[0] |= data_size; - - ol->q[1] = data_phys_addr; + temp |= 3 << 18; /* must take branch */ + temp |= data_size; + + ol->q[0] = cpu_to_le32(temp); + ol->q[1] = cpu_to_le32(data_phys_addr); ol->q[2] = 0; ol->q[3] = 0; } @@ -152,15 +151,16 @@ unsigned int data_size, unsigned long data_phys_addr) { - im->q[0] = 2 << 28; /* INPUT_MORE */ - im->q[0] |= 8 << 24; /* s = 1, update xferStatus and resCount */ + u32 temp = 2 << 28; /* INPUT_MORE */ + temp |= 8 << 24; /* s = 1, update xferStatus and resCount */ if (want_interrupt) - im->q[0] |= 0 << 20; /* interrupts, i=0 in packet-per-buffer mode */ - im->q[0] |= 0x0 << 16; /* disable branch to address for packet-per-buffer mode */ + temp |= 0 << 20; /* interrupts, i=0 in packet-per-buffer mode */ + temp |= 0x0 << 16; /* disable branch to address for packet-per-buffer mode */ /* disable wait on sync field, not used in DV :-( */ - im->q[0] |= data_size; + temp |= data_size; - im->q[1] = data_phys_addr; + im->q[0] = cpu_to_le32(temp); + im->q[1] = cpu_to_le32(data_phys_addr); im->q[2] = 0; /* branchAddress and Z not use in packet-per-buffer mode */ im->q[3] = 0; /* xferStatus & resCount, resCount must be initialize to data_size */ } @@ -169,16 +169,17 @@ unsigned int data_size, unsigned long data_phys_addr) { - il->q[0] = 3 << 28; /* INPUT_LAST */ - il->q[0] |= 8 << 24; /* s = 1, update xferStatus and resCount */ - il->q[0] |= 3 << 20; /* enable interrupts */ - il->q[0] |= 0xC << 16; /* enable branch to address */ + u32 temp = 3 << 28; /* INPUT_LAST */ + temp |= 8 << 24; /* s = 1, update xferStatus and resCount */ + temp |= 3 << 20; /* enable interrupts */ + temp |= 0xC << 16; /* enable branch to address */ /* disable wait on sync field, not used in DV :-( */ - il->q[0] |= data_size; + temp |= data_size; - il->q[1] = data_phys_addr; - il->q[2] = 1; /* branchAddress (filled in later) and Z = 1 descriptor in next block */ - il->q[3] = data_size; /* xferStatus & resCount, resCount must be initialize to data_size */ + il->q[0] = cpu_to_le32(temp); + il->q[1] = cpu_to_le32(data_phys_addr); + il->q[2] = cpu_to_le32(1); /* branchAddress (filled in later) and Z = 1 descriptor in next block */ + il->q[3] = cpu_to_le32(data_size); /* xferStatus & resCount, resCount must be initialize to data_size */ } Modified: trunk/dv1394.c ============================================================================== --- trunk/dv1394.c (original) +++ trunk/dv1394.c 2002-08-07 03:38:22.000000000 -0400 @@ -188,42 +188,29 @@ } -/* Taken from bttv.c */ /*******************************/ /* Memory management functions */ /*******************************/ +/* note: we no longer use mem_map_reserve, because it causes a memory + leak, and setting vma->vm_flags to VM_RESERVED should be sufficient + to pin the pages in memory anyway. */ + static void * rvmalloc(unsigned long size) { void * mem; - unsigned long adr; - size = PAGE_ALIGN(size); - mem=vmalloc_32(size); - if (mem) { + mem = vmalloc_32(size); + + if(mem) memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr=(unsigned long) mem; - while (size > 0) { - mem_map_reserve(vmalloc_to_page((void *)adr)); - adr+=PAGE_SIZE; - size-=PAGE_SIZE; - } - } return mem; } static void rvfree(void * mem, unsigned long size) { - unsigned long adr; - if (mem) { - adr=(unsigned long) mem; - while (size > 0) { - mem_map_unreserve(vmalloc_to_page((void *)adr)); - adr+=PAGE_SIZE; - size-=PAGE_SIZE; - } vfree(mem); } } @@ -594,7 +581,7 @@ /* note: we are not linked into the active DMA chain yet */ if(last_branch_address) { - *(last_branch_address) = block_dma | n_descriptors; + *(last_branch_address) = cpu_to_le32(block_dma | n_descriptors); } last_branch_address = branch_address; @@ -606,7 +593,7 @@ /* when we first assemble a new frame, set the final branch to loop back up to the top */ - *(f->frame_end_branch) = f->descriptor_pool_dma | f->first_n_descriptors; + *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors); /* make the latest version of the frame buffer visible to the PCI card */ @@ -643,15 +630,18 @@ /* if DMA is already active, we are almost done */ /* just link us onto the active DMA chain */ if(video->frames[last_frame]->frame_end_branch) { + u32 temp; /* point the previous frame's tail to this frame's head */ - *(video->frames[last_frame]->frame_end_branch) = f->descriptor_pool_dma | f->first_n_descriptors; + *(video->frames[last_frame]->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors); /* this write MUST precede the next one, or we could silently drop frames */ wmb(); /* disable the want_status semaphore on the last packet */ - *(video->frames[last_frame]->frame_end_branch - 2) &= 0xF7CFFFFF; + temp = le32_to_cpu(*(video->frames[last_frame]->frame_end_branch - 2)); + temp &= 0xF7CFFFFF; + *(video->frames[last_frame]->frame_end_branch - 2) = cpu_to_le32(temp); /* flush these writes to memory ASAP */ flush_pci_write(video->ohci); @@ -914,14 +904,14 @@ last_branch_address = f->frame_end_branch; if (last_branch_address) - *(last_branch_address) = block_dma | 1; /* set Z=1 */ + *(last_branch_address) = cpu_to_le32(block_dma | 1); /* set Z=1 */ f->frame_end_branch = &(block->u.in.il.q[2]); } /* loop tail to head */ if (f->frame_end_branch) - *(f->frame_end_branch) = f->descriptor_pool_dma | 1; /* set Z=1 */ + *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | 1); /* set Z=1 */ spin_unlock_irqrestore(&video->spinlock, irq_flags); @@ -2392,13 +2382,15 @@ /* see if we need to set the timestamp for the next frame */ if( *(f->mid_frame_timestamp) ) { struct frame *next_frame; - u32 ts_cyc, ts_off; + u32 begin_ts, ts_cyc, ts_off; *(f->mid_frame_timestamp) = 0; + begin_ts = le32_to_cpu(*(f->frame_begin_timestamp)); + irq_printk(" MIDDLE - first packet was sent at cycle %4u (%2u), assigned timestamp was (%2u) %4u\n", - *(f->frame_begin_timestamp) & 0x1FFF, *(f->frame_begin_timestamp) & 0xF, - f->assigned_timestamp >> 12, f->assigned_timestamp & 0xFFF); + begin_ts & 0x1FFF, begin_ts & 0xF, + f->assigned_timestamp >> 12, f->assigned_timestamp & 0xFFF); /* prepare next frame and assign timestamp */ next_frame = video->frames[ (frame+1) % video->n_frames ]; @@ -2412,7 +2404,7 @@ /* set the timestamp to the timestamp of the last frame sent, plus the length of the last frame sent, plus the syt latency */ - ts_cyc = *(f->frame_begin_timestamp) & 0xF; + ts_cyc = begin_ts & 0xF; /* advance one frame, plus syt latency (typically 2-3) */ ts_cyc += f->n_packets + video->syt_offset ; @@ -2459,17 +2451,21 @@ int sof=0; /* start-of-frame flag */ struct frame *f; - + u16 packet_length, packet_time; + spin_lock(&video->spinlock); + packet_length = le16_to_cpu(video->packet_buffer[video->current_packet].data_length); + packet_time = le16_to_cpu(video->packet_buffer[video->current_packet].timestamp); + irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet, - video->packet_buffer[video->current_packet].timestamp, video->packet_buffer[video->current_packet].data_length, + packet_time, packet_length, video->packet_buffer[video->current_packet].data[0], video->packet_buffer[video->current_packet].data[1]); f = video->frames[video->active_frame]; /* exclude empty packet */ - if (video->packet_buffer[video->current_packet].data_length > 8) { + if (packet_length > 8) { /* check for start of frame */ sof = (video->packet_buffer[video->current_packet].data[0] == 0x1f && @@ -2572,12 +2568,15 @@ list_for_each(lh, &dv1394_devfs) { p = list_entry(lh, struct dv1394_devfs_entry, list); if(!strncmp(p->name, name, sizeof(p->name))) { - spin_unlock( &dv1394_devfs_lock); - return p; + goto found; } } } - return NULL; + p = NULL; + +found: + spin_unlock( &dv1394_devfs_lock); + return p; } static int dv1394_devfs_add_entry(struct video_card *video) @@ -2763,7 +2762,7 @@ if (format == DV1394_NTSC) video->id |= mode; else video->id |= 2 + mode; - + #ifdef CONFIG_DEVFS_FS if (dv1394_devfs_add_entry(video) < 0) goto err_free; |