ARM: tegra: add sysfs support for tegra cpuquiet driver
[linux-2.6.git] / include / linux / pipe_fs_i.h
index 660e9d8..77257c9 100644 (file)
 
 #define PIPEFS_MAGIC 0x50495045
 
-#define PIPE_BUFFERS (16)
+#define PIPE_DEF_BUFFERS       16
 
-#define PIPE_BUF_FLAG_STOLEN   0x01
-#define PIPE_BUF_FLAG_LRU      0x02
+#define PIPE_BUF_FLAG_LRU      0x01    /* page is on the LRU */
+#define PIPE_BUF_FLAG_ATOMIC   0x02    /* was atomically mapped */
+#define PIPE_BUF_FLAG_GIFT     0x04    /* page is a gift */
 
+/**
+ *     struct pipe_buffer - a linux kernel pipe buffer
+ *     @page: the page containing the data for the pipe buffer
+ *     @offset: offset of data inside the @page
+ *     @len: length of data inside the @page
+ *     @ops: operations associated with this buffer. See @pipe_buf_operations.
+ *     @flags: pipe buffer flags. See above.
+ *     @private: private data owned by the ops.
+ **/
 struct pipe_buffer {
        struct page *page;
        unsigned int offset, len;
-       struct pipe_buf_operations *ops;
+       const struct pipe_buf_operations *ops;
        unsigned int flags;
+       unsigned long private;
 };
 
-struct pipe_buf_operations {
-       int can_merge;
-       void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *);
-       void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *);
-       void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
-       int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
-};
-
+/**
+ *     struct pipe_inode_info - a linux kernel pipe
+ *     @wait: reader/writer wait point in case of empty/full pipe
+ *     @nrbufs: the number of non-empty pipe buffers in this pipe
+ *     @buffers: total number of buffers (should be a power of 2)
+ *     @curbuf: the current pipe buffer entry
+ *     @tmp_page: cached released page
+ *     @readers: number of current readers of this pipe
+ *     @writers: number of current writers of this pipe
+ *     @waiting_writers: number of writers blocked waiting for room
+ *     @r_counter: reader counter
+ *     @w_counter: writer counter
+ *     @fasync_readers: reader side fasync
+ *     @fasync_writers: writer side fasync
+ *     @inode: inode this pipe is attached to
+ *     @bufs: the circular array of pipe buffers
+ **/
 struct pipe_inode_info {
        wait_queue_head_t wait;
-       unsigned int nrbufs, curbuf;
-       struct pipe_buffer bufs[PIPE_BUFFERS];
-       struct page *tmp_page;
-       unsigned int start;
+       unsigned int nrbufs, curbuf, buffers;
        unsigned int readers;
        unsigned int writers;
        unsigned int waiting_writers;
        unsigned int r_counter;
        unsigned int w_counter;
+       struct page *tmp_page;
        struct fasync_struct *fasync_readers;
        struct fasync_struct *fasync_writers;
        struct inode *inode;
+       struct pipe_buffer *bufs;
+};
+
+/*
+ * Note on the nesting of these functions:
+ *
+ * ->confirm()
+ *     ->steal()
+ *     ...
+ *     ->map()
+ *     ...
+ *     ->unmap()
+ *
+ * That is, ->map() must be called on a confirmed buffer,
+ * same goes for ->steal(). See below for the meaning of each
+ * operation. Also see kerneldoc in fs/pipe.c for the pipe
+ * and generic variants of these hooks.
+ */
+struct pipe_buf_operations {
+       /*
+        * This is set to 1, if the generic pipe read/write may coalesce
+        * data into an existing buffer. If this is set to 0, a new pipe
+        * page segment is always used for new data.
+        */
+       int can_merge;
+
+       /*
+        * ->map() returns a virtual address mapping of the pipe buffer.
+        * The last integer flag reflects whether this should be an atomic
+        * mapping or not. The atomic map is faster, however you can't take
+        * page faults before calling ->unmap() again. So if you need to eg
+        * access user data through copy_to/from_user(), then you must get
+        * a non-atomic map. ->map() uses the KM_USER0 atomic slot for
+        * atomic maps, so you can't map more than one pipe_buffer at once
+        * and you have to be careful if mapping another page as source
+        * or destination for a copy (IOW, it has to use something else
+        * than KM_USER0).
+        */
+       void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
+
+       /*
+        * Undoes ->map(), finishes the virtual mapping of the pipe buffer.
+        */
+       void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
+
+       /*
+        * ->confirm() verifies that the data in the pipe buffer is there
+        * and that the contents are good. If the pages in the pipe belong
+        * to a file system, we may need to wait for IO completion in this
+        * hook. Returns 0 for good, or a negative error value in case of
+        * error.
+        */
+       int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * When the contents of this pipe buffer has been completely
+        * consumed by a reader, ->release() is called.
+        */
+       void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * Attempt to take ownership of the pipe buffer and its contents.
+        * ->steal() returns 0 for success, in which case the contents
+        * of the pipe (the buf->page) is locked and now completely owned
+        * by the caller. The page may then be transferred to a different
+        * mapping, the most often used case is insertion into different
+        * file address space cache.
+        */
+       int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
+
+       /*
+        * Get a reference to the pipe buffer.
+        */
+       void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
 };
 
 /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
 #define PIPE_SIZE              PAGE_SIZE
 
-#define PIPE_MUTEX(inode)      (&(inode).i_mutex)
-#define PIPE_WAIT(inode)       (&(inode).i_pipe->wait)
-#define PIPE_READERS(inode)    ((inode).i_pipe->readers)
-#define PIPE_WRITERS(inode)    ((inode).i_pipe->writers)
-#define PIPE_WAITING_WRITERS(inode)    ((inode).i_pipe->waiting_writers)
-#define PIPE_RCOUNTER(inode)   ((inode).i_pipe->r_counter)
-#define PIPE_WCOUNTER(inode)   ((inode).i_pipe->w_counter)
-#define PIPE_FASYNC_READERS(inode)     (&((inode).i_pipe->fasync_readers))
-#define PIPE_FASYNC_WRITERS(inode)     (&((inode).i_pipe->fasync_writers))
+/* Pipe lock and unlock operations */
+void pipe_lock(struct pipe_inode_info *);
+void pipe_unlock(struct pipe_inode_info *);
+void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);
+
+extern unsigned int pipe_max_size, pipe_min_size;
+int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
+
 
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct pipe_inode_info *pipe);
@@ -60,14 +151,16 @@ struct pipe_inode_info * alloc_pipe_info(struct inode * inode);
 void free_pipe_info(struct inode * inode);
 void __free_pipe_info(struct pipe_inode_info *);
 
-/*
- * splice is tied to pipes as a transport (at least for now), so we'll just
- * add the splice flags here.
- */
-#define SPLICE_F_MOVE  (0x01)  /* move pages instead of copying */
-#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
-                                /* we may still block on the fd we splice */
-                                /* from/to, of course */
-#define SPLICE_F_MORE  (0x04)  /* expect more data */
+/* Generic pipe buffer ops functions */
+void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
+void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
+void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
+int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
+int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
+void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
+
+/* for F_SETPIPE_SZ and F_GETPIPE_SZ */
+long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
+struct pipe_inode_info *get_pipe_info(struct file *file);
 
 #endif