diff --git a/CHANGES b/CHANGES index cef8c503..9461b56a 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ ask CVS about it: 2.1.2 (199801??) Modules lm80.o, w83781d.o: fan-related Segmentation fault corrected Module gl518sm.o: yet more bug fixes. It should at long last be usable now + Documentation in doc/kernel: NEW 2.1.1 (19990107) Module i2c-proc.o: Hack to make /proc/bus/ possible for kernels 2.0.35 diff --git a/doc/kernel/file_operations b/doc/kernel/file_operations new file mode 100644 index 00000000..cfd9445b --- /dev/null +++ b/doc/kernel/file_operations @@ -0,0 +1,91 @@ +This file documents the changes in struct file_operations throughout the 2.1 +kernel series. + +Kernels 2.0.x: + +struct file_operations { + int (*lseek) (struct inode *, struct file *, off_t, int); + int (*read) (struct inode *, struct file *, char *, int); + int (*write) (struct inode *, struct file *, const char *, int); + int (*readdir) (struct inode *, struct file *, void *, filldir_t); + int (*select) (struct inode *, struct file *, int, select_table *); + int (*ioctl) (struct inode *, struct file *, unsigned int, + unsigned long); + int (*mmap) (struct inode *, struct file *, struct vm_area_struct *); + int (*open) (struct inode *, struct file *); + void (*release) (struct inode *, struct file *); + int (*fsync) (struct inode *, struct file *); + int (*fasync) (struct inode *, struct file *, int); + int (*check_media_change) (kdev_t dev); + int (*revalidate) (kdev_t dev); +}; + + +Kernel 2.1.0: + +- int (*lseek) (struct inode *, struct file *, off_t, int); ++ long long (*llseek) (struct inode *, struct file *, long long, int); +- int (*read) (struct inode *, struct file *, char *, int); ++ long (*read) (struct inode *, struct file *, char *, unsigned long); +- int (*write) (struct inode *, struct file *, const char *, int); ++ long (*write) (struct inode *, struct file *, const char *, unsigned lon + + +Kernel 2.1.23: + +- int (*select) (struct inode *, struct file *, int, select_table *); ++ unsigned int (*poll) (struct file *, poll_table *); +[The lock field is added behind the revalidate field] ++ int (*lock) (struct inode *, struct file *, int, struct file_lock *); + + +Kernel 2.1.31: + +- void (*release) (struct inode *, struct file *); ++ int (*release) (struct inode *, struct file *); + + +Kernel 2.1.55: + +- int (*readdir) (struct inode *, struct file *, void *, filldir_t); ++ int (*readdir) (struct file *, void *, filldir_t); + + +Kernel 2.1.56: + +- long long (*llseek) (struct inode *, struct file *, long long, int); ++ long long (*llseek) (struct file *, long long, int); +- int (*mmap) (struct inode *, struct file *, struct vm_area_struct *); ++ int (*mmap) (struct file *, struct vm_area_struct *); +- int (*fsync) (struct inode *, struct file *); ++ int (*fsync) (struct file *, struct dentry *); +- int (*fasync) (struct inode *, struct file *, int); ++ int (*fasync) (struct file *, int); +- int (*lock) (struct inode *, struct file *, int, struct file_lock *); ++ int (*lock) (struct file *, int, struct file_lock *); + + +Kernel 2.1.70: + +- long long (*llseek) (struct file *, long long, int); ++ loff_t (*llseek) (struct file *, loff_t, int); +- long (*read) (struct inode *, struct file *, char *, unsigned long); ++ ssize_t (*read) (struct file *, char *, size_t, loff_t *); +- long (*write) (struct inode *, struct file *, const char *, + unsigned long); ++ ssize_t (*write) (struct file *, const char *, size_t, loff_t *); + + +Kernel 2.1.72: + +- unsigned int (*poll) (struct file *, poll_table *); ++ unsigned int (*poll) (struct file *, struct poll_table_struct *); + + +Kernel 2.1.118: + +[The flush field is added behind the open field -- stupid...] ++ int (*flush) (struct file *); + + +Last kernel checked: 2.2.0-pre4. diff --git a/doc/kernel/proc_dir_entry b/doc/kernel/proc_dir_entry new file mode 100644 index 00000000..9763d15e --- /dev/null +++ b/doc/kernel/proc_dir_entry @@ -0,0 +1,145 @@ +This file documents how to handle the callback function that returns the +information displayed in a (non-/proc/sys) /proc file. + +For kernels before 2.1.29, you have to declare a proc_dir_entry, with +in the get_info field the procedure handler. For kernels 2.1.29 and later, +you can use the create_proc_entry function and assign a new value (the +procedure handler address) to the read_proc field: + + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29) + static int read_bus_i2c(char *buf, char **start, off_t offset, int len, + int unused); + static struct proc_dir_entry proc_bus_i2c_dir = + { + /* low_ino */ 0, /* Set by proc_register_dynamic */ + /* namelen */ 3, /* The length of the name field */ + /* name */ "i2c", + /* mode */ S_IRUGO | S_IFREG, + /* nlink */ 1, + /* uid */ 0, + /* gid */ 0, + /* size */ 0, + /* ops */ NULL, + /* get_info */ &read_bus_i2c + }; + +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29) + static int read_bus_i2c(char *buf, char **start, off_t offset, int len, + int *eof , void *private); +#endif + + + /* This code fragment is part of the initialization code. You should do + several safety checks, like whether create_proc_entry does not return + NULL. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29) + proc_register_dynamic(&proc_root, &proc_bus_i2c_dir); +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29) + proc_bus_i2c = create_proc_entry("i2c",0,proc_root); + proc_bus_i2c->read_proc = &read_bus_i2c; +#endif + + + +Now for the function itself. + + LINUX KERNEL 2.0.x, and 2.1.x upto 2.1.28 + ========================================= + This function is known as the get_info function. + + int get_info(char *buf, char **start, off_t offset, int len, int unused); + + (INPUT) + buf: A kernel-space buffer where we can put the information. + len: The buffer length (we have a bit of slack here: if we write + 'a little' beyond this, things will still work out) + (OUTPUT) + *buf: The complete contents of the /proc file, starting at the + beginning. + return value: the number of chars written to buf. + + This is all you have to do if all information fits in the buffer (it is + about 3K in length). You can safely ignore offset and start in this case. + + If your /proc entry gets larger, you have to do a bit more work. + + (INPUT) + buf: See above + len: see above + offset: The offset from the beginning of the /proc file where the user + wants to start reading + (OUTPUT) + *buf: A part of the /proc file. The requested information does not + have to start at the beginning. + start: this is the place within buf where the information starts (ie. + you must use offset to compute this!). + return value: The number of valid characters written to buf. Begin + counting at start, not at buf! + + You do not have to worry about not the whole information being in buf. + Another call will be done (with a higher offset value) if more is + needed. + + + LINUX KERNEL 2.1.x, from 2.1.29 upwards + ======================================= + + This function is known as the read_proc function. + + int read_proc(char *buf, char **start, off_t offset, int len, int *eof, + void *private); + (INPUT) + buf: A kernel-space buffer where we can put the information. + len: The buffer length (we have a bit of slack here: if we write + 'a little' beyond this, things will still work out) + (OUTPUT) + *buf: The complete contents of the /proc file, starting at the + beginning. + eof: You can set this to true (anything but 0) to indicate we have + reached the end of the file with this read. Not strictly + necessary, but it is more efficient (else this function may be + called again). + return value: The number of valid characters written to buf. Begin + counting at start, not at buf! + + If your /proc entry gets larger, you have to do a bit more work. + + (INPUT) + buf: See above + len: See above + offset: The offset from the beginning of the /proc file where the user + wants to start reading + (OUTPUT) + *buf: A part of the /proc file. The requested information does not + have to start at the beginning. + eof: See above + start: this is the place within buf where the information starts (ie. + you must use offset to compute this!). + return value: The number of valid characters written to buf. + + You do not have to worry about not the whole information being in buf. + Another call will be done (with a higher offset value) if more is + needed. Ignore private. + + A third way to do this: + + (INPUT) + buf: See above + len: See above + offset: The offset from the beginning of the /proc file where the user + wants to start reading + (OUTPUT) + *buf: A part of the /proc file, with the requested information starting + at the beginning. + eof: See above + start: (long)start is added to the offset pointer after reading. This + allows you to play tricks with the file offset, independent of + the number of read bytes. + return value: the number of chars written to buf. + + +This document was written by Frodo Looijaard . I do not +accept any responsibility for omissions or errors, but you are free to +drop me a note if something is wrong or if you miss something.