Loadable module support for bt-ALPHA-0.0.1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To install this patch: cd to the directory where you have extracted bt-ALPHA-0.0.1 and pipe this file into "patch -p". Then cd to bt-ALPHA-0.0.1 and read README.module. Marc -- Marc Huber (huber@fzi.de) diff -u --recursive --new-file bt-ALPHA-0.0.1.original/Makefile bt-ALPHA-0.0.1/Makefile --- bt-ALPHA-0.0.1.original/Makefile Thu Oct 27 20:52:47 1994 +++ bt-ALPHA-0.0.1/Makefile Mon Sep 25 09:11:36 1995 @@ -41,6 +41,10 @@ # Initial revision # ############################################################################### +# +# Loadable module support by Marc Huber (huber@fzi.de) 1995/09/21 +# +############################################################################### # management information VERSION = $(shell sed -n '/bt_version/s/[^"]*"\([^"]*\).*/\1/p' < bt_version.h) @@ -78,7 +82,13 @@ FILES = $(INFOFILES) $(PATCHFILE) $(SRCS) $(HDRS) $(MAN) $(TSTPRGS) $(SETUPPRG) ANNOUNCE=ANNOUNCE -default: zdisk +DEFINES = -D__KERNEL__ -DMODULE + +CFLAGS = -O2 -m486 -Wall -Wstrict-prototypes -fomit-frame-pointer $(DEFINES) + +default: bt.o + +bt.o: *.c *.h $(KINCDIR)/version.h dist $(TARFILE): $(FILES) rm -f -r $(TMPDIR) @@ -98,7 +108,10 @@ ############################################################################## # Software installation by copying # (choose between soft- or hard installation) -install: install.full +install: install.module + +install.module: bt.o + install -m 644 bt.o /lib/modules/`uname -r`/misc/ install.full: install.src apply.patch install.doc @@ -142,6 +155,9 @@ ############################################################################## clean: + rm bt.o + +clean.dist: rm -f $(PATCHFILE) $(TARFILE) $(DOSTARF) rm -f -r $(TMPDIR) diff -u --recursive --new-file bt-ALPHA-0.0.1.original/README.module bt-ALPHA-0.0.1/README.module --- bt-ALPHA-0.0.1.original/README.module Thu Jan 1 01:00:00 1970 +++ bt-ALPHA-0.0.1/README.module Mon Sep 25 10:30:41 1995 @@ -0,0 +1,72 @@ +Loadable module support for Thomas Weidenfeller's BiTronics device driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Warranty & Copyright +~~~~~~~~~~~~~~~~~~~~ +Please understand that there's no warranty of any kind. The modifications +I've made to Thomas Weidenfeller`s bt driver are in the public domain. The +usual disclaimers apply. + + +Why a loadable module? +~~~~~~~~~~~~~~~~~~~~~~ +There's no need to modify anything in the /usr/src/linux hierarchy. The +"bt" driver is one of the non-standard drivers -- installing it into the +kernel could break Linus' patches. + + +Changes to the original bt distribution +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ Loadable module support with auto-creation of necessary devices. ++ Minor fix for BT_COOPERATE_WITH_LP + + +Installation +~~~~~~~~~~~~ +Have a look at bt_config.h and at the Makefile and make changes where +appropriate. Uncomment BT_COOPERATE_WITH_LP in bt_config.h if you want to +have both the bt and lp device drivers installed. This is not recommended, +but it worked for me. It's saver, however, to remove the lp driver from the +kernel. If you #define BT_COOPERATE_WITH_LP: make shure that the relevant +devices don't use conflicting parameters. + +Become root, then type + + make install.module install.man + +That's it. You may load the module with + + depmod -a; modprobe bt + +The kernel will write a few lines similar to + + bt: Experimental BiTronics device driver vALPHA-0.0.1 at major # 63 + bt: parallel port at 0x378 is minor device # 1 (bt1) + +to /var/adm/messages, hopefully indicating that everything went fine. + +The module will automatically create the necessary /dev/bt* devices, so +make shure you have "/" mounted read-write. The default ownership/permissions +for the /dev/bt* devices are: + + uid=0 gid=7 perm=0660 + +You can change these defaults in bt_config.h, or simply use the insmod +"symbol=" mechanism. Example: "insmod bt.o uid=1999 gid=0 perm=0644" + +If you have more than one parallel port and don't want to run bt on every +port, you may add "ports=", where is an integer with +only those bits set whose positions match the interface numbers which bt may +use. E.g., "ports=3" will tell the module to use the parallel ports 0 and 1, +and to leave port 2 alone. + +At the time of writing, the loadable module support was tested with the +1.3.25 kernel only. It may or may not work with other kernel releases. + +Have fun! + + Marc + +--- +Marc Huber (huber@fzi.de) + diff -u --recursive --new-file bt-ALPHA-0.0.1.original/bt.c bt-ALPHA-0.0.1/bt.c --- bt-ALPHA-0.0.1.original/bt.c Thu Oct 27 20:52:47 1994 +++ bt-ALPHA-0.0.1/bt.c Mon Sep 25 10:27:38 1995 @@ -78,6 +78,12 @@ * Initial revision *****************************************************************************/ +#ifdef MODULE +/****************************************************************************** + * Loadable module support by Marc Huber (huber@fzi.de) 1995/09/21 + *****************************************************************************/ +#endif + /* .EOC .P @@ -89,7 +95,6 @@ #include #include -#include #include #include #include @@ -98,9 +103,20 @@ #ifdef BT_COOPERATE_WITH_LP #include + extern struct lp_struct lp_table[]; #endif +#ifndef MODULE #include +#include +#else +#include +#include +#include +#include +#include +#include "bt.h" +#endif /****************************************************************************** * driver internal definitions @@ -109,15 +125,30 @@ static char bt_RCS_ID[] = "@(#)$Id: bt.c,v 1.7 1994/10/26 18:23:46 root Exp $"; #define BT_USE(x) ((void)(x)) /* null macro to hide warning */ +#ifdef MODULE +/******************************************************************************* + * Global variables needed for auto-creation of devices. You may override the + * BT_* defaults when loading the module -- insmod(1) is your friend ;-) + *******************************************************************************/ + +static int major = 0; +static int uid = BT_UID; +static int gid = BT_GID; +static int perm = BT_PERM; +static int ports = BT_PORTS; +static char name[] = BT_DEVICE_NAME; +#endif + /* .P */ + /******************************************************************************* * Create the status lookup tables *******************************************************************************/ -BT_PRN_STAT bt_prn_stat_norm[] = { +static BT_PRN_STAT bt_prn_stat_norm[] = { BT_PRN_STE(READY), BT_PRN_STE(NO_PRN), BT_PRN_STE(PE), @@ -127,7 +158,7 @@ { 0, 0, NULL } }; -BT_PRN_STAT bt_prn_stat_bt[] = { +static BT_PRN_STAT bt_prn_stat_bt[] = { BT_PRN_STE(ACK), BT_PRN_STE(ADR), BT_PRN_STE(CLK_H), @@ -226,7 +257,7 @@ ******************************************************************************/ static void bt_release(struct inode *inode, struct file *file); static int bt_open( struct inode *inode, struct file *file); -static int bt_write( struct inode* inode, struct file *file, char *buf, int count); +static int bt_write( struct inode* inode, struct file *file, const char *buf, int count); static int bt_read( struct inode* inode, struct file *file, char *buf, int count); /* @@ -594,7 +625,7 @@ -static int bt_write(struct inode* inode, struct file *file, char *buf, +static int bt_write(struct inode* inode, struct file *file, const char *buf, int count) /****************************************************************************** * Performes the writing of data to the printer @@ -664,7 +695,7 @@ * READ operation ******************************************************************************/ -int bt_read_char(int minor, char *c) +static int bt_read_char(int minor, char *c) /****************************************************************************** * Reads one byte (two nibbles) from the printer * IN: minor Minor device to use @@ -905,6 +936,7 @@ * Open/Release & Initialisation/Deinitialisation ******************************************************************************/ + static int bt_open(struct inode *inode, struct file *file) /****************************************************************************** * Probes if a minor device exists and - if yes - brings it into service @@ -951,6 +983,9 @@ bt_data[minor].last_error = BT_NO_ERROR; BTEXIT(BTTF_ALL,"OK\n"); +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif return 0; } @@ -980,6 +1015,9 @@ LP_F(minor) &= ~LP_BUSY; #endif bt_data[minor].busy = 0; +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif } @@ -1009,7 +1047,30 @@ } } +#ifdef MODULE +void cleanup_module(void); + +char kernel_version[]= UTS_RELEASE; + +/* + * Syscalls needed for creating/removing the special files + */ + +typedef int (*syscall_ptr)(const char *, ...); +extern syscall_ptr sys_call_table[]; +#define unlink sys_call_table[__NR_unlink] +#define mknod sys_call_table[__NR_mknod] +#define chown sys_call_table[__NR_chown] +#define chmod sys_call_table[__NR_chmod] + +long init_module(long kmem_start) +/****************************************************************************** + * Initialize the driver, create devices + * IN: kmem_start First kernel mem addr. which could be used + * OUT: 0: module loaded, any other for failure + *****************************************************************************/ +#else long bt_init(long kmem_start) /****************************************************************************** * Initialize the driver (really strange that this is called by mem.c, but @@ -1017,33 +1078,108 @@ * IN: kmem_start First kernel mem addr. which could be used * OUT: bt_init New first unused kernel mem addr. *****************************************************************************/ +#endif { int minor; int n_existing = 0; /* nbr of existing ports */ +#ifdef MODULE + int len, oldfs, res; +#endif BT_USE(bt_RCS_ID); /* get rid of "defined but not used" warning */ /* * use the chance to make ourselfe known */ +#ifndef MODULE if (register_chrdev(BT_MAJOR, BT_DRIVER_NAME, &bt_fops)) { - printk(BT_DRIVER_NAME ": unable to get major # %d for driver\ndriver not usable!\n", BT_MAJOR); +#else + if ((major = register_chrdev(0, BT_DRIVER_NAME, &bt_fops)) < 1) { +#endif + printk(BT_DRIVER_NAME ": no major device id available\ndriver not usable!\n"); +#ifndef MODULE return kmem_start; - /* XXX perhaps a loop to get first unused major # ???*/ - /* XXX perhaps auto creation of /dev/bt? entries??? */ } - printk(BT_DRIVER_NAME ": Experimental BiTronics device driver v%s at major # %d\n", bt_version, BT_MAJOR); +#else + return -EIO; + } + + printk(BT_DRIVER_NAME ": Experimental BiTronics device driver v%s at major # %d\n", bt_version, major); + + for(len = 0; name[len] ; len++); + len--; +#endif + for(minor = 0; minor < BT_NBR; minor++) { /* * iterate over all possible ports and note succesfull attempts */ +#ifndef MODULE n_existing += bt_probe_port(minor); +#else + if(bt_probe_port(minor) && ((ports >> minor) & 1)) { + n_existing++; + name[len] = '0' + minor; + oldfs=get_fs(); + set_fs(KERNEL_DS); + unlink(name); + res = mknod(name, S_IFCHR, MKDEV(major, minor)); + chown(name, uid, gid); + chmod(name, perm); + set_fs(oldfs); + if(res){ + /* + * Well, mknod failed, probably because "/" is + * mounted read-only. + */ + printk(BT_DRIVER_NAME ": Creating %s (%d %d) failed!\n", name, major, minor); + cleanup_module(); + return -EIO; + } + } +#endif } +#ifndef MODULE if(!n_existing) printk(BT_DRIVER_NAME ": no printer ports found!\n"); +#else + if(!n_existing) { + printk(BT_DRIVER_NAME ": no printer ports found!\n"); + cleanup_module(); + return -EIO; + } +#endif +#ifndef MODULE return kmem_start; +#else + return 0; +} + +void cleanup_module(void) +/****************************************************************************** + * Unregister the device, remove the devices created by bt_init() + *****************************************************************************/ +{ + int len, minor, oldfs; + if(MOD_IN_USE) + printk("bt: busy - remove delayed\n"); + else { + unregister_chrdev(major,"bt"); + for(len = 0; name[len]; len++); + len--; + for(minor = 0; minor < BT_NBR; minor++){ + if((ports >> minor) & 1) { + name[len] = '0' + minor; + oldfs=get_fs(); + set_fs(KERNEL_DS); + unlink(name); + set_fs(oldfs); + } + } + } } +#endif diff -u --recursive --new-file bt-ALPHA-0.0.1.original/bt_config.h bt-ALPHA-0.0.1/bt_config.h --- bt-ALPHA-0.0.1.original/bt_config.h Thu Oct 27 20:52:47 1994 +++ bt-ALPHA-0.0.1/bt_config.h Mon Sep 25 09:22:29 1995 @@ -47,10 +47,43 @@ #ifndef BT_CONFIG_H_ #define BT_CONFIG_H_ + +#ifdef MODULE +/****************************************************************************** + * Loadable module support by Marc Huber (huber@fzi.de) 1995/09/21 + *****************************************************************************/ +#endif + + /* * how the driver identifies itselfe in printouts */ #define BT_DRIVER_NAME "bt" + + +#ifdef MODULE + +/* + * Name template for auto-created devices + */ +#define BT_DEVICE_NAME "/dev/bt?" + + +/* + * Ownership and permissions of auto-created devices + */ +#define BT_UID 0 /* root */ +#define BT_GID 7 /* lp */ +#define BT_PERM 0660 + + +/* + * The module will use only the ports with the corresponding bits in + * BT_PORTS set. + */ +#define BT_PORTS 1|2|4 /* ports 0, 1 and 2 */ + +#endif /*