patch-2.3.42 linux/drivers/ap1000/ringbuf.c
Next file: linux/drivers/ap1000/smt-types.h
Previous file: linux/drivers/ap1000/plc.h
Back to the patch index
Back to the overall index
- Lines: 312
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.3.41/linux/drivers/ap1000/ringbuf.c
- Orig date:
Tue Dec 7 09:32:42 1999
diff -u --recursive --new-file v2.3.41/linux/drivers/ap1000/ringbuf.c linux/drivers/ap1000/ringbuf.c
@@ -1,311 +0,0 @@
- /*
- * Copyright 1996 The Australian National University.
- * Copyright 1996 Fujitsu Laboratories Limited
- *
- * This software may be distributed under the terms of the Gnu
- * Public License version 2 or later
- */
-/*
- * linux/drivers/ap1000/ringbuf.c
- *
- * This provides the /proc/XX/ringbuf interface to the Tnet ring buffer
- */
-#define _APLIB_
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-
-#include <asm/page.h>
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-
-#include <asm/ap1000/pgtapmmu.h>
-#include <asm/ap1000/apreg.h>
-#include <asm/ap1000/apservice.h>
-
-
-/* we have a small number of reserved ring buffers to ensure that at
- least one parallel program can always run */
-#define RBUF_RESERVED 4
-#define RBUF_RESERVED_ORDER 5
-static struct {
- char *rb_ptr;
- char *shared_ptr;
- int used;
-} reserved_ringbuf[RBUF_RESERVED];
-
-
-void ap_ringbuf_init(void)
-{
- int i,j;
- char *rb_ptr, *shared_ptr;
- int rb_size = PAGE_SIZE * (1<<RBUF_RESERVED_ORDER);
-
- /* preallocate some ringbuffers */
- for (i=0;i<RBUF_RESERVED;i++) {
- if (!(rb_ptr = (char *)__get_free_pages(GFP_ATOMIC,RBUF_RESERVED_ORDER))) {
- printk("failed to preallocate ringbuf %d\n",i);
- return;
- }
- for (j = MAP_NR(rb_ptr); j <= MAP_NR(rb_ptr+rb_size-1); j++) {
- set_bit(PG_reserved,&mem_map[j].flags);
- }
-
- if (!(shared_ptr = (char *)__get_free_page(GFP_ATOMIC))) {
- printk("failed to preallocate shared ptr %d\n",i);
- return;
- }
- set_bit(PG_reserved,&mem_map[MAP_NR(shared_ptr)].flags);
-
- reserved_ringbuf[i].used = 0;
- reserved_ringbuf[i].rb_ptr = rb_ptr;
- reserved_ringbuf[i].shared_ptr = shared_ptr;
- }
-}
-
-
-
-void exit_ringbuf(struct task_struct *tsk)
-{
- int i;
-
- if (!tsk->ringbuf) return;
-
- if (tsk->ringbuf->ringbuf) {
- char *rb_ptr = tsk->ringbuf->ringbuf;
- char *shared_ptr = tsk->ringbuf->shared;
- int order = tsk->ringbuf->order;
- int rb_size = PAGE_SIZE * (1<<order);
-
- for (i=0;i<RBUF_RESERVED;i++)
- if (rb_ptr == reserved_ringbuf[i].rb_ptr) break;
-
- if (i < RBUF_RESERVED) {
- reserved_ringbuf[i].used = 0;
- } else {
- for (i = MAP_NR(rb_ptr); i <= MAP_NR(rb_ptr+rb_size-1); i++) {
- clear_bit(PG_reserved, &mem_map[i].flags);
- }
- free_pages((unsigned)rb_ptr,order);
-
- i = MAP_NR(shared_ptr);
- clear_bit(PG_reserved,&mem_map[i]);
- free_page((unsigned)shared_ptr);
- }
- }
-
- kfree_s(tsk->ringbuf,sizeof(*(tsk->ringbuf)));
- tsk->ringbuf = NULL;
-}
-
-
-/*
- * map the ring buffer into users memory
- */
-static int cap_map(int rb_size)
-{
- struct task_struct *tsk=current;
- int i;
- char *rb_ptr=NULL;
- char *shared_ptr=NULL;
- int order = 0;
- int error,old_uid;
-
- error = verify_area(VERIFY_WRITE,(char *)RBUF_VBASE,rb_size);
- if (error) return error;
-
- if (!MPP_IS_PAR_TASK(tsk->taskid)) {
- printk("ringbuf_mmap called from non-parallel task\n");
- return -EINVAL;
- }
-
-
- if (tsk->ringbuf) return -EINVAL;
-
- rb_size -= RBUF_RING_BUFFER_OFFSET;
- rb_size >>= 1;
-
- switch (rb_size/1024) {
- case 128:
- order = 5;
- break;
- case 512:
- order = 7;
- break;
- case 2048:
- order = 9;
- break;
- case 8192:
- order = 11;
- break;
- default:
- printk("ringbuf_mmap with invalid size %d\n",rb_size);
- return -EINVAL;
- }
-
- if (order == RBUF_RESERVED_ORDER) {
- for (i=0;i<RBUF_RESERVED;i++)
- if (!reserved_ringbuf[i].used) {
- rb_ptr = reserved_ringbuf[i].rb_ptr;
- shared_ptr = reserved_ringbuf[i].shared_ptr;
- reserved_ringbuf[i].used = 1;
- break;
- }
- }
-
- if (!rb_ptr) {
- rb_ptr = (char *)__get_free_pages(GFP_USER,order);
- if (!rb_ptr) return -ENOMEM;
-
- for (i = MAP_NR(rb_ptr); i <= MAP_NR(rb_ptr+rb_size-1); i++) {
- set_bit(PG_reserved,&mem_map[i].flags);
- }
-
- shared_ptr = (char *)__get_free_page(GFP_USER);
- if (!shared_ptr)
- return -ENOMEM;
- set_bit(PG_reserved,&mem_map[MAP_NR(shared_ptr)].flags);
- }
-
- if (!rb_ptr)
- return -ENOMEM;
-
- memset(rb_ptr,0,rb_size);
- memset(shared_ptr,0,PAGE_SIZE);
-
- if (remap_page_range(RBUF_VBASE + RBUF_RING_BUFFER_OFFSET,
- mmu_v2p((unsigned)rb_ptr),
- rb_size,APMMU_PAGE_SHARED))
- return -EAGAIN;
-
- if (remap_page_range(RBUF_VBASE + RBUF_RING_BUFFER_OFFSET + rb_size,
- mmu_v2p((unsigned)rb_ptr),
- rb_size,APMMU_PAGE_SHARED))
- return -EAGAIN;
-
- /* the shared area */
- if (remap_page_range(RBUF_VBASE + RBUF_SHARED_PAGE_OFF,
- mmu_v2p((unsigned)shared_ptr),
- PAGE_SIZE,APMMU_PAGE_SHARED))
- return -EAGAIN;
-
-#if 0
- /* lock the ringbuffer in memory */
- old_uid = current->euid;
- current->euid = 0;
- error = sys_mlock(RBUF_VBASE,2*rb_size+RBUF_RING_BUFFER_OFFSET);
- current->euid = old_uid;
- if (error) {
- printk("ringbuffer mlock failed\n");
- return error;
- }
-#endif
-
- /* the queue pages */
-#define MAP_QUEUE(offset,phys) \
- io_remap_page_range(RBUF_VBASE + offset, \
- phys<<PAGE_SHIFT,PAGE_SIZE,APMMU_PAGE_SHARED,0xa)
-
- MAP_QUEUE(RBUF_PUT_QUEUE, 0x00000);
- MAP_QUEUE(RBUF_GET_QUEUE, 0x00001);
- MAP_QUEUE(RBUF_SEND_QUEUE, 0x00040);
-
- MAP_QUEUE(RBUF_XY_QUEUE, 0x00640);
- MAP_QUEUE(RBUF_X_QUEUE, 0x00240);
- MAP_QUEUE(RBUF_Y_QUEUE, 0x00440);
- MAP_QUEUE(RBUF_XYG_QUEUE, 0x00600);
- MAP_QUEUE(RBUF_XG_QUEUE, 0x00200);
- MAP_QUEUE(RBUF_YG_QUEUE, 0x00400);
- MAP_QUEUE(RBUF_CSI_QUEUE, 0x02004);
- MAP_QUEUE(RBUF_FOP_QUEUE, 0x02005);
-
-#undef MAP_QUEUE
-
- if (!tsk->ringbuf) {
- tsk->ringbuf = (void *)kmalloc(sizeof(*(tsk->ringbuf)),GFP_ATOMIC);
- if (!tsk->ringbuf)
- return -ENOMEM;
- }
-
- memset(tsk->ringbuf,0,sizeof(*tsk->ringbuf));
- tsk->ringbuf->ringbuf = rb_ptr;
- tsk->ringbuf->shared = shared_ptr;
- tsk->ringbuf->order = order;
- tsk->ringbuf->write_ptr = mmu_v2p((unsigned)rb_ptr)<<1;
- tsk->ringbuf->vaddr = RBUF_VBASE;
-
- memset(tsk->ringbuf->vaddr+RBUF_SHARED_PAGE_OFF,0,PAGE_SIZE);
- {
- struct _kernel_cap_shared *_kernel =
- (struct _kernel_cap_shared *)tsk->ringbuf->vaddr;
- _kernel->rbuf_read_ptr = (rb_size>>5) - 1;
- }
-
- return 0;
-}
-
-
-static int
-ringbuf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- int numcells, *phys_cells;
- extern struct cap_init cap_init;
-
- switch (cmd) {
- case CAP_GETINIT:
- if (copy_to_user((char *)arg,(char *)&cap_init,sizeof(cap_init)))
- return -EFAULT;
- break;
-
- case CAP_SYNC:
- if (verify_area(VERIFY_READ, (void *) arg, sizeof(int)*2))
- return -EFAULT;
- if (get_user(numcells,(int *)arg)) return -EFAULT;
- if (get_user((unsigned)phys_cells,
- ((int *)arg)+1)) return -EFAULT;
- if (verify_area(VERIFY_READ,phys_cells,sizeof(int)*numcells))
- return -EFAULT;
- return ap_sync(numcells,phys_cells);
- break;
-
- case CAP_SETGANG:
- {
- int v;
- if (get_user(v,(int *)arg)) return -EFAULT;
- mpp_set_gang_factor(v);
- break;
- }
-
- case CAP_MAP:
- return cap_map(arg);
-
- default:
- printk("unknown ringbuf ioctl %d\n",cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-
-static struct file_operations proc_ringbuf_operations = {
- NULL,
- NULL,
- NULL,
- NULL, /* readdir */
- NULL, /* poll */
- ringbuf_ioctl, /* ioctl */
- NULL, /* mmap */
- NULL, /* no special open code */
- NULL, /* flush */
- NULL, /* no special release code */
- NULL /* can't fsync */
-};
-
-struct inode_operations proc_ringbuf_inode_operations = {
- &proc_ringbuf_operations, /* default base directory file-ops */
-};
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)