[Linux1394-cvslog] rev 765 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <ben...@li...> - 2003-02-02 07:06:44
|
Author: bencollins Date: 2003-02-02 02:06:11 -0500 (Sun, 02 Feb 2003) New Revision: 765 Modified: trunk/video1394.c Log: 2nd and final phase of video1394 conversion to dma routines. Unfortunately, the ioctl usage makes it impossible to use video1394 on sparc64 with 32bit programs. Video1394 uses generic cmd numbers so they aren't unique. I can't test this yet. Some one test this please, especially on 1gig+ machines and non-i386 machines. Modified: trunk/video1394.c ============================================================================== --- trunk/video1394.c (original) +++ trunk/video1394.c 2003-02-02 02:06:12.000000000 -0500 @@ -98,8 +98,11 @@ struct dma_region dma; + struct dma_prog_region *prg_reg; + struct dma_cmd **ir_prg; struct it_dma_prg **it_prg; + unsigned int *buffer_status; struct timeval *buffer_time; /* time when the buffer was received */ unsigned int *last_used_cmd; /* For ISO Transmit with @@ -175,19 +178,17 @@ dma_region_free(&d->dma); - if (d->ir_prg) { - for (i = 0; i < d->num_desc; i++) - if (d->ir_prg[i]) - kfree(d->ir_prg[i]); - kfree(d->ir_prg); + if (d->prg_reg) { + for (i = 0; i < d->num_desc; i++) + dma_prog_region_free(&d->prg_reg[i]); + kfree(d->prg_reg); } - if (d->it_prg) { - for (i = 0; i < d->num_desc; i++) - if (d->it_prg[i]) - kfree(d->it_prg[i]); + if (d->ir_prg) + kfree(d->ir_prg); + + if (d->it_prg) kfree(d->it_prg); - } if (d->buffer_status) kfree(d->buffer_status); @@ -227,9 +228,11 @@ d->frame_size = buf_size; d->buf_size = PAGE_ALIGN(buf_size); d->last_buffer = -1; - dma_region_init(&d->dma); init_waitqueue_head(&d->waitq); + /* Init the regions for easy cleanup */ + dma_region_init(&d->dma); + if (dma_region_alloc(&d->dma, d->buf_size, ohci->dev, PCI_DMA_BIDIRECTIONAL)) { PRINT(KERN_ERR, ohci->id, "Failed to allocate dma buffer"); free_dma_iso_ctx(d); @@ -253,6 +256,17 @@ } d->ctx = d->iso_tasklet.context; + d->prg_reg = kmalloc(d->num_desc * sizeof(struct dma_prog_region), + GFP_KERNEL); + if (d->ir_prg == NULL) { + PRINT(KERN_ERR, ohci->id, "Failed to allocate ir prg regs"); + free_dma_iso_ctx(d); + return NULL; + } + /* Makes for easier cleanup */ + for (i = 0; i < d->num_desc; i++) + dma_prog_region_init(&d->prg_reg[i]); + if (type == OHCI_ISO_RECEIVE) { d->ctrlSet = OHCI1394_IsoRcvContextControlSet+32*d->ctx; d->ctrlClear = OHCI1394_IsoRcvContextControlClear+32*d->ctx; @@ -263,27 +277,24 @@ GFP_KERNEL); if (d->ir_prg == NULL) { - PRINT(KERN_ERR, ohci->id, - "Failed to allocate dma ir prg"); + PRINT(KERN_ERR, ohci->id, "Failed to allocate dma ir prg"); free_dma_iso_ctx(d); return NULL; } memset(d->ir_prg, 0, d->num_desc * sizeof(struct dma_cmd *)); - + d->nb_cmd = d->buf_size / PAGE_SIZE + 1; d->left_size = (d->frame_size % PAGE_SIZE) ? d->frame_size % PAGE_SIZE : PAGE_SIZE; - for (i=0;i<d->num_desc;i++) { - d->ir_prg[i] = kmalloc(d->nb_cmd * - sizeof(struct dma_cmd), - GFP_KERNEL); - if (d->ir_prg[i] == NULL) { - PRINT(KERN_ERR, ohci->id, - "Failed to allocate dma ir prg"); + for (i = 0;i < d->num_desc; i++) { + if (dma_prog_region_alloc(&d->prg_reg[i], d->nb_cmd * + sizeof(struct dma_cmd), ohci->dev)) { + PRINT(KERN_ERR, ohci->id, "Failed to allocate dma ir prg"); free_dma_iso_ctx(d); return NULL; } + d->ir_prg[i] = (struct dma_cmd *)d->prg_reg[i].kvirt; } } else { /* OHCI_ISO_TRANSMIT */ @@ -317,20 +328,17 @@ if (d->frame_size % d->packet_size) { d->nb_cmd++; d->left_size = d->frame_size % d->packet_size; - } - else + } else d->left_size = d->packet_size; - for (i=0;i<d->num_desc;i++) { - d->it_prg[i] = kmalloc(d->nb_cmd * - sizeof(struct it_dma_prg), - GFP_KERNEL); - if (d->it_prg[i] == NULL) { - PRINT(KERN_ERR, ohci->id, - "Failed to allocate dma it prg"); + for (i = 0; i < d->num_desc; i++) { + if (dma_prog_region_alloc(&d->prg_reg[i], d->nb_cmd * + sizeof(struct it_dma_prg), ohci->dev)) { + PRINT(KERN_ERR, ohci->id, "Failed to allocate dma it prg"); free_dma_iso_ctx(d); return NULL; } + d->it_prg[i] = (struct it_dma_prg *)d->prg_reg[i].kvirt; } } @@ -383,7 +391,7 @@ int i; d->ir_prg[n][0].status = cpu_to_le32(4); d->ir_prg[n][1].status = cpu_to_le32(PAGE_SIZE-4); - for (i=2;i<d->nb_cmd-1;i++) + for (i = 2; i < d->nb_cmd - 1; i++) d->ir_prg[n][i].status = cpu_to_le32(PAGE_SIZE); d->ir_prg[n][i].status = cpu_to_le32(d->left_size); } @@ -391,6 +399,7 @@ static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) { struct dma_cmd *ir_prg = d->ir_prg[n]; + struct dma_prog_region *ir_reg = &d->prg_reg[n]; unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; int i; @@ -404,16 +413,16 @@ ir_prg[0].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, buf - (unsigned long)d->dma.kvirt)); - ir_prg[0].branchAddress = cpu_to_le32((virt_to_bus(&(ir_prg[1].control)) - & 0xfffffff0) | 0x1); + ir_prg[0].branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg, + 1 * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1); /* the second descriptor will read PAGE_SIZE-4 bytes */ ir_prg[1].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_BRANCH | (PAGE_SIZE-4)); ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, (buf + 4) - (unsigned long)d->dma.kvirt)); - ir_prg[1].branchAddress = cpu_to_le32((virt_to_bus(&(ir_prg[2].control)) - & 0xfffffff0) | 0x1); + ir_prg[1].branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg, + 2 * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1); for (i=2;i<d->nb_cmd-1;i++) { ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | @@ -422,9 +431,9 @@ (buf+(i-1)*PAGE_SIZE) - (unsigned long)d->dma.kvirt)); - ir_prg[i].branchAddress = - cpu_to_le32((virt_to_bus(&(ir_prg[i+1].control)) - & 0xfffffff0) | 0x1); + ir_prg[i].branchAddress = + cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg, + (i + 1) * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1); } /* the last descriptor will generate an interrupt */ @@ -587,6 +596,7 @@ static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) { struct it_dma_prg *it_prg = d->it_prg[n]; + struct dma_prog_region *it_reg = &d->prg_reg[n]; unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; int i; d->last_used_cmd[n] = d->nb_cmd - 1; @@ -617,13 +627,12 @@ if (i<d->nb_cmd-1) { it_prg[i].end.control |= cpu_to_le32(d->packet_size); it_prg[i].begin.branchAddress = - cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) - & 0xfffffff0) | 0x3); + cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) * + sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); it_prg[i].end.branchAddress = - cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) - & 0xfffffff0) | 0x3); - } - else { + cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) * + sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); + } else { /* the last prg generates an interrupt */ it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | DMA_CTL_IRQ | d->left_size); @@ -640,6 +649,7 @@ struct ti_ohci *ohci) { struct it_dma_prg *it_prg = d->it_prg[n]; + struct dma_prog_region *it_reg = &d->prg_reg[n]; int i; #if 0 @@ -661,12 +671,12 @@ if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) { it_prg[i].end.control |= cpu_to_le32(size); - it_prg[i].begin.branchAddress = - cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) - & 0xfffffff0) | 0x3); - it_prg[i].end.branchAddress = - cpu_to_le32((virt_to_bus(&(it_prg[i+1].begin.control)) - & 0xfffffff0) | 0x3); + it_prg[i].begin.branchAddress = + cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) * + sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); + it_prg[i].end.branchAddress = + cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) * + sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); } else { /* the last prg generates an interrupt */ it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | @@ -882,10 +892,10 @@ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; - if (d->last_buffer>=0) - d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = - cpu_to_le32((virt_to_bus(&(d->ir_prg[v.buffer][0].control)) - & 0xfffffff0) | 0x1); + if (d->last_buffer>=0) + d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = + cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) + & 0xfffffff0) | 0x1); d->last_buffer = v.buffer; @@ -898,9 +908,9 @@ DBGMSG(ohci->id, "Starting iso DMA ctx=%d",d->ctx); /* Tell the controller where the first program is */ - reg_write(ohci, d->cmdPtr, - virt_to_bus(&(d->ir_prg[v.buffer][0]))|0x1); - + reg_write(ohci, d->cmdPtr, + dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x1); + /* Run IR context */ reg_write(ohci, d->ctrlSet, 0x8000); } @@ -1040,18 +1050,16 @@ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; - if (d->last_buffer>=0) { + if (d->last_buffer >= 0) { d->it_prg[d->last_buffer] - [ d->last_used_cmd[d->last_buffer] - ].end.branchAddress = - cpu_to_le32((virt_to_bus(&(d->it_prg[v.buffer][0].begin.control)) - & 0xfffffff0) | 0x3); + [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = + cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], + 0) & 0xfffffff0) | 0x3); d->it_prg[d->last_buffer] - [d->last_used_cmd[d->last_buffer] - ].begin.branchAddress = - cpu_to_le32((virt_to_bus(&(d->it_prg[v.buffer][0].begin.control)) - & 0xfffffff0) | 0x3); + [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress = + cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], + 0) & 0xfffffff0) | 0x3); d->next_buffer[d->last_buffer] = v.buffer; } d->last_buffer = v.buffer; @@ -1068,9 +1076,9 @@ put_timestamp(ohci, d, d->last_buffer); /* Tell the controller where the first program is */ - reg_write(ohci, d->cmdPtr, - virt_to_bus(&(d->it_prg[v.buffer][0]))|0x3); - + reg_write(ohci, d->cmdPtr, + dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x3); + /* Run IT context */ reg_write(ohci, d->ctrlSet, 0x8000); } |