From Bugzilla Helper: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Description of problem: 1)I can't read out the status register(base+1) of a new-installed parallel port device at base 0x378, 0x278, and 0x3bc using a test program that has been tested on redhat 7.0/7.1 told by the author of book <<practical linux programming>>@2002. Note:1) the parallel port DB25 connector is free, has no wire connection; 2) my printer works well when connected. 2)The more strange is : using the simple test program I can open the uninstalled parallel port device "pport", even any named device, say "xyz09". And from that I have got the same result as the ones from the installed pport. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1.copy into your machine (a6)pport.c,(a5)test.c,(a4)makefilep,(a3) makefilet,(a2)pp_load, and (a1)pp_unload attached at the end of this steps; Note: you may need change INCLUDEDIR of makefilep for pport.c for your redhat version; 2.run make the pport.c and get pport.o; 3.as root, run pp_load; 4.run make the test.c and get t; 5.and in another window, run t and type in 0x55, 0xAA, 0x00, 67, ... one each time. 6.run pp_unload goto step 5 or goto step 2 with changing pport-base, or replace line 13 fh= open("dev/pport",O_RDWR) with fh = open ("/dev/xyz09",O_RDWR), goto step 4. ===================Attached files below here========================= (a1)pp_unload: #!/bin/sh module="pport.o" device="pport" # invoke rmmod with all arguments we got /sbin/rmmod $device || exit 1 # Remove stale nodes rm -f /dev/${device} (a2)pp_load: #!/bin/sh module="pport.o" device="pport" group="root" mode="664" #remove any existing node /sbin/rmmod pport # invoke insmod with all arguments we got /sbin/insmod -f $module $device || exit 1 major=`cat /proc/devices | awk "\\$2==\"$device\" {print \\$1}"` echo "Major number = $major" rm -f /dev/${device} mknod /dev/${device} c $major 0 chgrp $group /dev/${device} chmod $mode /dev/${device} (a3)makefilet: all: t CC = gcc INCLUDEDIR = /usr/include CFLAGS = -g -O2 -Wall -I$(INCLUDEDIR) t: test.o $(CC) -o t test.o test.o: test.c $(CC) -c test.c $(CFLAGS) clean: rm -f *.o t (a4)makefilep: #INCLUDEDIR = /usr/include INCLUDEDIR = /usr/src/linux-2.4.18-3/include DEBFLAGS = -O2 CFLAGS = -D__KERNEL__ -DMODULE -Wall $(DEBFLAGS) CFLAGS += -I$(INCLUDEDIR) OBJS = pport.o all: $(OBJS) clean: rm -f *.o (a5)test.c: #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> /*****************************/ void LoopBackTest(int pattern) { int fh, cnt; char bfr[2]; bfr[0] = (char) pattern; printf("LoopBack test begin %2.2x\n",bfr[0]); fh = open("/dev/pport",O_RDWR); // fh = open("/dev/xyz09",O_RDWR); if (fh) { write(fh,bfr,1); cnt = read(fh,bfr,1); printf("Status Port bits %2.2x\n",bfr[0] & 0xff); close(fh); } else printf("Fail open device\n"); } /*****************************/ int main(int argc , char *argv[]) { int pattern; printf("Loop Back test for the parallel port device driver \n"); printf("Press Ctrl C to exit\n"); while(1) { printf ("Data register\n"); printf ("bit 0 ------> DB25 pin 2\n"); printf ("bit 1 ------> DB25 pin 3\n"); printf ("bit 2 ------> DB25 pin 4\n"); printf ("bit 3 ------> DB25 pin 5\n"); printf ("bit 4 ------> DB25 pin 6\n"); printf ("bit 5 ------> DB25 pin 7\n"); printf ("bit 6 ------> DB25 pin 8\n"); printf ("bit 7 ------> DB25 pin 9\n"); printf ("Status register (Notice bit 0,1,2 are not available)\n"); printf ("bit 3 <------ DB25 pin 15\n"); printf ("bit 4 <------ DB25 pin 13\n"); printf ("bit 5 <------ DB25 pin 12\n"); printf ("bit 6 <--Inverted---- DB25 pin 10\n"); printf ("bit 7 <------ DB25 pin 11\n"); printf("Enter bit pattern in hex for data register "); scanf ("%x",&pattern); LoopBackTest(pattern); } } (a6)pport.c: /* * pp.c -- Simple Hardware Operations and Raw Tests * pp.c -- also a brief example of interrupt handling ("pp int") * * untested (by now) the hardware r/w * * Tested with 2.0.18 (intel & alpha -- but no irq available for me) * This module won't work on the sparc, where there's no concept of I/O space * *********/ #include <linux/module.h> #include <linux/sched.h> #include <linux/kernel.h> /* printk() */ #include <linux/fs.h> /* everything... */ #include <linux/errno.h> /* error codes */ #include <linux/malloc.h> #include <linux/mm.h> #include <linux/ioport.h> #include <linux/interrupt.h> #include <linux/tqueue.h> #include <asm/io.h> #include <asm/segment.h> /* #include "sysdep-2.1.h" */ #include <linux/poll.h> #define READ_IRQ 1 int pp_major = 0; //int pp_base = 0x378; /* intel: default to lp0 */ //int pp_base = 0x278; /* */ int pp_base = 0x3bc; /* */ int pp_irq = 7; unsigned long pp_buffer = 0; int minor = 0; int IrqCount = 0; unsigned long volatile pp_head; volatile unsigned long pp_tail; struct wait_queue *pp_queue; int pp_open (struct inode *inode, struct file *filp) { MOD_INC_USE_COUNT; minor =(MINOR(inode->i_rdev)&0x0f); printk(KERN_INFO "pp:U OPEN %d\n", minor); return 0; } int pp_close (struct file *filp) { MOD_DEC_USE_COUNT; return(0); } int pp_read (struct file * filp, char *buf, size_t count, loff_t * t) { unsigned char *kbuf=kmalloc(16, GFP_KERNEL); kbuf[1]='\0'; kbuf[0] = inb(pp_base+1); printk(KERN_INFO " READ VALUE pp: %2x\n",*kbuf); copy_to_user(buf, kbuf, 1); kfree(kbuf); return (0); } int pp_write (struct file * filp, const char *buf, size_t count, loff_t * t) { int retval = count; unsigned char *kbuf=kmalloc(16, GFP_KERNEL); if (!kbuf) return -ENOMEM; copy_from_user(kbuf, buf, 1); printk(KERN_INFO "pp: WRITE %2x\n",kbuf[0]); outb(kbuf[0], pp_base); kfree(kbuf); return retval; } struct file_operations pp_fops = { NULL, NULL, /* pp_lseek */ pp_read, pp_write, NULL, /* pp_readdir */ NULL, NULL, NULL, /* mmap */ pp_open, pp_close, NULL, /* pp_fsync */ NULL, /* pp_fasync */ /* nothing more, fill with NULLs */ }; int init_module(void) { int result = check_region(pp_base,4); printk(KERN_INFO "pp: INIT_MOD\n"); if (result) { printk(KERN_INFO "pp: can't get I/O address 0x%x\n",pp_base); return result; } request_region(pp_base,4,"pport"); result = register_chrdev(pp_major, "pport", &pp_fops); if (result < 0) { printk(KERN_INFO "pp: can't get major number\n"); release_region(pp_base,4); return result; } if (pp_major == 0) pp_major = result; /* dynamic */ pp_buffer = __get_free_page(GFP_KERNEL); /* never fails */ pp_head = pp_tail = pp_buffer; return 0; } void cleanup_module(void) { free_irq(pp_irq, NULL); unregister_chrdev(pp_major, "pport"); release_region(pp_base,4); if (pp_buffer) free_page(pp_buffer); } ======================End attached files========================== Actual Results: 1) Using pport.o with base address 0x378, yuo can't pass pp_load due to device or resources busy, see result below; 2) with installed pport.o, you will get what you type in: that's, in 0x55, out 55; in 0xAA, out aa; in 0x00, out 00; in 67,out 67; ... see the attached results at the end of this section; 3) with pp_unload pport.o or without installed pport.o at all(from restart system after pp_unload), you will get the same result as 1) even you can change the opened device name of the test progam into "dev/xyz09". ======================Attached results below here=================== 1) using pport.o with base_address 0x378: [root simple:684]# pp_load rmmod: module pport is not loaded Warning: loading pport.o will taint the kernel: no license Warning: loading pport.o will taint the kernel: forced load pport.o: init_module: Device or resource busy Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters [root simple:685]# 2) with or without pport.o installed with base address 0x278 or 0x3bc: [test:1002]$ t Loop Back test for the parallel port device driver Press Ctrl C to exit Data register bit 0 ------> DB25 pin 2 bit 1 ------> DB25 pin 3 bit 2 ------> DB25 pin 4 bit 3 ------> DB25 pin 5 bit 4 ------> DB25 pin 6 bit 5 ------> DB25 pin 7 bit 6 ------> DB25 pin 8 bit 7 ------> DB25 pin 9 Status register (Notice bit 0,1,2 are not available) bit 3 <------ DB25 pin 15 bit 4 <------ DB25 pin 13 bit 5 <------ DB25 pin 12 bit 6 <--Inverted---- DB25 pin 10 bit 7 <------ DB25 pin 11 Enter bit pattern in hex for data register 0x55 LoopBack test begin 55 Status Port bits 55 Data register bit 0 ------> DB25 pin 2 bit 1 ------> DB25 pin 3 bit 2 ------> DB25 pin 4 bit 3 ------> DB25 pin 5 bit 4 ------> DB25 pin 6 bit 5 ------> DB25 pin 7 bit 6 ------> DB25 pin 8 bit 7 ------> DB25 pin 9 Status register (Notice bit 0,1,2 are not available) bit 3 <------ DB25 pin 15 bit 4 <------ DB25 pin 13 bit 5 <------ DB25 pin 12 bit 6 <--Inverted---- DB25 pin 10 bit 7 <------ DB25 pin 11 Enter bit pattern in hex for data register 00 LoopBack test begin 00 Status Port bits 00 Data register bit 0 ------> DB25 pin 2 bit 1 ------> DB25 pin 3 bit 2 ------> DB25 pin 4 bit 3 ------> DB25 pin 5 bit 4 ------> DB25 pin 6 bit 5 ------> DB25 pin 7 bit 6 ------> DB25 pin 8 bit 7 ------> DB25 pin 9 Status register (Notice bit 0,1,2 are not available) bit 3 <------ DB25 pin 15 bit 4 <------ DB25 pin 13 bit 5 <------ DB25 pin 12 bit 6 <--Inverted---- DB25 pin 10 bit 7 <------ DB25 pin 11 Enter bit pattern in hex for data register 0xAA LoopBack test begin ffffffaa Status Port bits aa Data register bit 0 ------> DB25 pin 2 bit 1 ------> DB25 pin 3 bit 2 ------> DB25 pin 4 bit 3 ------> DB25 pin 5 bit 4 ------> DB25 pin 6 bit 5 ------> DB25 pin 7 bit 6 ------> DB25 pin 8 bit 7 ------> DB25 pin 9 Status register (Notice bit 0,1,2 are not available) bit 3 <------ DB25 pin 15 bit 4 <------ DB25 pin 13 bit 5 <------ DB25 pin 12 bit 6 <--Inverted---- DB25 pin 10 bit 7 <------ DB25 pin 11 Enter bit pattern in hex for data register [test:1003]$ 3) check if there is a port related name "pport" or "xyz09":no at all; [root simple:681]# /sbin/lsmod Module Size Used by Not tainted nls_iso8859-1 3488 1 (autoclean) sr_mod 16920 2 (autoclean) emu10k1 64096 0 (autoclean) ac97_codec 11904 0 (autoclean) [emu10k1] sound 72012 0 (autoclean) [emu10k1] soundcore 6692 7 (autoclean) [emu10k1 sound] r128 94680 1 agpgart 39488 3 binfmt_misc 7556 1 parport_pc 18724 1 (autoclean) lp 8864 0 (autoclean) parport 34208 1 (autoclean) [parport_pc lp] autofs 12164 0 (autoclean) (unused) 8139too 16448 1 mii 2408 0 [8139too] ipchains 43560 12 ide-scsi 9664 1 scsi_mod 108608 2 [sr_mod ide-scsi] ide-cd 30272 0 cdrom 32192 0 [sr_mod ide-cd] usb-uhci 24484 0 (unused) usbcore 73152 1 [usb-uhci] ext3 67136 3 jbd 49400 3 [ext3] [root simple:682]# cat /proc/devices Character devices: 1 mem 2 pty 3 ttyp 4 ttyS 5 cua 6 lp 7 vcs 10 misc 14 sound 29 fb 36 netlink 128 ptm 129 ptm 130 ptm 131 ptm 132 ptm 133 ptm 134 ptm 135 ptm 136 pts 137 pts 138 pts 139 pts 140 pts 141 pts 142 pts 143 pts 162 raw 180 usb 226 drm Block devices: 1 ramdisk 2 fd 3 ide0 9 md 11 sr 12 unnamed 14 unnamed 22 ide1 38 unnamed 39 unnamed [root simple:683]# ls /dev/pp* /dev/ppp /dev/pppox0 /dev/pppox1 /dev/pppox2 /dev/pppox3 ======================End attached results========================== Expected Results: I should get the initialize value of the status register of pc whatever I type in : for an example, I should have 00 if the register is initialized as 0x00, or have ff if initialized as 0xff, and so on; Additional info: No any wire connection on DB25 connector for all testing.
expected results added: for uninstalled parallel port driver, I should get -1 return from open function for unsuccesful device openning instead the current successful openning.
This is a driver that we do not ship, and so can't support. Why not use the 'ppdev' driver, which we *do* ship? It provides backing for /dev/parport0. To read how to use it look at http://cyberelk.net/tim/parport/html/. For even better results, use the libieee1284 library from http://cyberelk.net/tim/libieee1284.
I got what you mean from cyberelk.net/tim/parport/html: k2.4 and k2.0 have different locations and methods for their parallel ports. I will try libieee1284. Thank you very much. Martin