lkml.org 
[lkml]   [1997]   [Apr]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectpatches for 2.1.34
Here are some patches against 2.1.34 to fix the remaining problems with
parport and merge Jose's /proc code. If all seems well I'll send them to
Linus for 2.1.35.

Enjoy.
p.

Index: linux/Makefile
diff -u linux/Makefile:1.6 linux/Makefile:1.6.2.1
--- linux/Makefile:1.6 Tue Apr 15 00:28:38 1997
+++ linux/Makefile Tue Apr 15 11:54:33 1997
@@ -118,7 +118,8 @@
FILESYSTEMS =fs/filesystems.a
NETWORKS =net/network.a
DRIVERS =drivers/block/block.a \
- drivers/char/char.a
+ drivers/char/char.a \
+ drivers/pnp/pnp.a
LIBS =$(TOPDIR)/lib/lib.a
SUBDIRS =kernel drivers mm fs net ipc lib

@@ -142,10 +143,6 @@

ifdef CONFIG_PCI
DRIVERS := $(DRIVERS) drivers/pci/pci.a
-endif
-
-ifdef CONFIG_PNP
-DRIVERS := $(DRIVERS) drivers/pnp/pnp.a
endif

ifdef CONFIG_SBUS
Index: linux/drivers/Makefile
diff -u linux/drivers/Makefile:1.2 linux/drivers/Makefile:1.2.6.1
--- linux/drivers/Makefile:1.2 Fri Apr 11 16:12:46 1997
+++ linux/drivers/Makefile Tue Apr 15 11:56:03 1997
@@ -7,17 +7,12 @@
#
# Note 2! The CFLAGS definitions are now in the main makefile...

-SUB_DIRS := block char net #streams
+SUB_DIRS := block char net pnp #streams
MOD_SUB_DIRS := $(SUB_DIRS) sbus
ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus sound cdrom isdn pnp

ifdef CONFIG_PCI
SUB_DIRS += pci
-endif
-
-ifdef CONFIG_PNP
-SUB_DIRS += pnp
-MOD_SUB_DIRS += pnp
endif

ifdef CONFIG_SBUS
Index: linux/drivers/pnp/BUGS-parport
diff -u linux/drivers/pnp/BUGS-parport:1.2 linux/drivers/pnp/BUGS-parport:1.2.6.1
--- linux/drivers/pnp/BUGS-parport:1.2 Fri Apr 11 16:12:57 1997
+++ linux/drivers/pnp/BUGS-parport Tue Apr 15 11:56:13 1997
@@ -1,8 +1,6 @@
Currently known (or at least suspected) bugs in parport:

-o /proc/parport is buggy under 2.0.29 (ls /proc/parport/0 gives no such
- file or directory). David has suggested a fix for this. [/proc/parport
- has been temporarily taken out]
+o /proc/parport is untested under 2.0.XX

o SCSI aborts for PPA under 2.0.29 [reported by jmr]. Under investigation.

Index: linux/drivers/pnp/TODO-parport
diff -u linux/drivers/pnp/TODO-parport:1.2 linux/drivers/pnp/TODO-parport:1.2.6.1
--- linux/drivers/pnp/TODO-parport:1.2 Fri Apr 11 16:12:58 1997
+++ linux/drivers/pnp/TODO-parport Tue Apr 15 11:56:13 1997
@@ -2,31 +2,9 @@

0. Fix the bugs (see BUGS-parport).

-1. Write a /proc interface for parport. As a starting point, we could
- probably have something like this:
+1. Proper documentation.

- /proc/parport/N/hardware
-
- Details of the port hardware - chipset, capabilities and so on.
- Read-only.
-
- /proc/parport/N/irq
-
- IRQ number of the port. Read-write.
-
- /proc/parport/N/devices
-
- List of devices connected to this bus, with the currently active
- one marked in some way. Probably you'd have the device in the
- first column, and '*' (for the current device) or '-' (for a
- lurker) in the second column.
-
- NOTE: The directory structure has been coded -- but the files are
- missing ...
-
-2. Proper documentation.
-
-3. Overhaul lp.c:
+2. Overhaul lp.c:

a) It's a mess, and there is a lot of code duplication.

@@ -40,4 +18,4 @@
bits when they have something to say. We should read out and deal
with (maybe just log) whatever the printer wants to tell the world.

-4. Assimilate more drivers.
+3. Assimilate more drivers.
Index: linux/drivers/pnp/parport_init.c
diff -u linux/drivers/pnp/parport_init.c:1.3 linux/drivers/pnp/parport_init.c:1.3.2.1
--- linux/drivers/pnp/parport_init.c:1.3 Tue Apr 15 00:29:15 1997
+++ linux/drivers/pnp/parport_init.c Tue Apr 15 11:56:13 1997
@@ -1,4 +1,4 @@
-/* $Id: parport_init.c,v 1.3 1997/04/14 23:29:15 phil Exp $
+/* $Id: parport_init.c,v 1.3.2.1 1997/04/15 10:56:13 phil Exp $
* Parallel-port initialisation code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
@@ -76,7 +76,7 @@
return dma;
}

-static int parport_detect_dma_transfer(int dma,int size)
+static int parport_detect_dma_transfer(int dma,int size,int *resid)
{
int i,n,retv;
int count=0;
@@ -88,6 +88,7 @@
clear_dma_ff(i);
n = get_dma_residue(i);
if (n != size) {
+ *resid = n;
retv = i;
if (count > 0) {
retv = -1; /* Multiple DMA's */
@@ -149,7 +150,7 @@
if( retv != -1 )
return retv;

- buff = kmalloc(16, GFP_KERNEL | GFP_DMA);
+ buff = kmalloc(2048, GFP_KERNEL | GFP_DMA);
if( !buff ){
printk("parport: memory squezze\n");
return -1;
@@ -160,11 +161,12 @@

w_ecr(pb, 0xc0); /* ECP MODE */
w_ctr(pb, dsr_read );
- dma=parport_prepare_dma(buff,8);
+ dma=parport_prepare_dma(buff,1000);
w_ecr(pb, 0xd8); /* ECP FIFO + enable DMA */
parport_enable_dma(dma);
- udelay(30); /* Give some for DMA tranfer */
- retv = parport_detect_dma_transfer(dma,8);
+ udelay(500); /* Give some for DMA tranfer */
+ retv = parport_detect_dma_transfer(dma,1000,&pb->speed);
+ pb->speed = pb->speed * 2000; /* 500uSec * 2000 = 1sec */

/*
* National Semiconductors only supports DMA tranfers
@@ -173,11 +175,12 @@
if( retv == -1 ){
w_ecr(pb, 0x60); /* ECP MODE */
w_ctr(pb, dsr_read );
- dma=parport_prepare_dma(buff,8);
+ dma=parport_prepare_dma(buff,1000);
w_ecr(pb, 0x68); /* ECP FIFO + enable DMA */
parport_enable_dma(dma);
- udelay(30); /* Give some for DMA tranfer */
- retv = parport_detect_dma_transfer(dma,8);
+ udelay(500); /* Give some for DMA tranfer */
+ retv = parport_detect_dma_transfer(dma,1000,&pb->speed);
+ pb->speed = pb->speed * 2000; /* 500uSec * 2000 = 1sec */
}

kfree(buff);
@@ -506,7 +509,7 @@
}

/*
- * It's called only if supports EPP on National Semiconductors
+ * This detection seems that only works in National Semiconductors
* This doesn't work in SMC, LGS, and Winbond
*/
static int irq_probe_EPP(struct parport *pb)
@@ -738,17 +741,20 @@
struct parport *pb;

printk(KERN_INFO "Parallel port sharing: %s\n",
- "$Revision: 1.3 $");
+ "$Revision: 1.3.2.1 $");

if (io[0] == -2) return 1;

- /* Register /proc/parport */
- parport_proc_register(NULL);
+#ifdef CONFIG_PROC_FS
+ parport_proc_init();
+#endif

/* Run probes to ensure parport does exist */
#define PORT(a,b,c) \
if ((pb = parport_register_port((a), (b), (c)))) \
parport_destroy(pb);
+
+
if (io[0]) {
/* If the user specified any ports, use them */
int i;
@@ -764,8 +770,12 @@
}

#ifdef CONFIG_PNP_PARPORT_AUTOPROBE
- for (pb = parport_enumerate(); pb; pb = pb->next)
+ for (pb = parport_enumerate(); pb; pb = pb->next) {
parport_probe_one(pb);
+#ifdef CONFIG_PROC_FS
+ parport_proc_register(pb);
+#endif
+ }
#endif

return 0;
@@ -784,7 +794,7 @@
kfree(port);
}

- parport_proc_unregister(NULL);
+ parport_proc_cleanup();
}
#endif

Index: linux/drivers/pnp/parport_procfs.c
diff -u linux/drivers/pnp/parport_procfs.c:1.3 linux/drivers/pnp/parport_procfs.c:1.3.2.1
--- linux/drivers/pnp/parport_procfs.c:1.3 Tue Apr 15 00:29:16 1997
+++ linux/drivers/pnp/parport_procfs.c Tue Apr 15 11:56:14 1997
@@ -1,4 +1,4 @@
-/* $Id: parport_procfs.c,v 1.3 1997/04/14 23:29:16 phil Exp $
+/* $Id: parport_procfs.c,v 1.3.2.1 1997/04/15 10:56:14 phil Exp $
* Parallel port /proc interface code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
@@ -26,103 +26,305 @@
#endif

#include <linux/parport.h>
+#include "parport_ll_io.h"

-#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED)
+struct proc_dir_entry *base=NULL;

-/************************************************/
-static long proc_readparport(struct inode * inode, struct file * file,
- char * buf, unsigned long count)
+void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs);
+
+static int irq_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
{
- printk("proc_readparport\n");
- return 0;
+ int newirq;
+ struct parport *pp=(struct parport *)data;
+ struct ppd *pd;
+
+ if(count > 4 ) { /* more than 4 digits for a irq 0x?? 0?? ?? */
+ return(-EOVERFLOW);
+ }
+
+ if( buffer[0] == '0' ){
+ if( buffer[1] == 'x' ){
+ newirq = simple_strtoul(&buffer[2],0,16);
+ }else{
+ newirq = simple_strtoul(&buffer[1],0,8);
+ }
+ }else{
+ newirq = simple_strtoul(buffer,0,10);
+ }
+
+ if (pp->irq >= 0 ) {
+ free_irq(pp->irq, pp);
+ }
+ pp->irq = newirq;
+ pd = pp->cad;
+ if( pd == NULL ){
+ pd = pp->devices;
+ if( pd != NULL )
+ request_irq(pp->irq, pd->irq_func ? pd->irq_func : parport_null_intr_func,
+ SA_INTERRUPT, pd->name, pd->port);
+ }else{
+ request_irq(pp->irq, pd->irq_func ? pd->irq_func : parport_null_intr_func,
+ SA_INTERRUPT, pp->name, pd->port);
+ }
+
+ return count;
}

-static long proc_writeparport(struct inode * inode, struct file * file,
- const char * buf, unsigned long count)
+static int irq_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
{
- printk("proc_writeparport\n");
+ struct parport *pp = (struct parport *)data;
+ int len;

- return 0;
+ len = sprintf(page, "%d\n",pp->irq);
+
+ *start = 0;
+ *eof = 1;
+ return len;
+}
+
+static int devices_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct parport *pp = (struct parport *)data;
+ struct ppd *pd1;
+ int len=0;
+
+ for (pd1 = pp->devices; pd1 ; pd1 = pd1->next) {
+ if( pd1 == pp->cad )
+ len += sprintf(page+len, "+");
+ else
+ len += sprintf(page+len, " ");
+
+ len += sprintf(page+len, "%s",pd1->name);
+
+ if( pd1 == pp->lurker )
+ len += sprintf(page+len, " LURK");
+
+ len += sprintf(page+len,"\n");
+ }
+
+ *start = 0;
+ *eof = 1;
+ return len;
}

-static long long proc_parportlseek(struct inode * inode, struct file * file,
- long long offset, int orig)
+static int hardware_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
{
- switch (orig) {
+ struct parport *pp = (struct parport *)data;
+ int len=0;
+
+ len += sprintf(page+len, "base\t:\t0x%x\n",pp->base);
+ len += sprintf(page+len, "irq\t:\t%d\n",pp->irq);
+ len += sprintf(page+len, "dma\t:\t%d\n",pp->dma);
+
+ len += sprintf(page+len, "modes\t:\t");
+ {
+#define printmode(x) {if(pp->modes&PARPORT_MODE_##x){len+=sprintf(page+len,"%s%s",f?",":"",#x);f++;}}
+ int f = 0;
+ printmode(SPP);
+ printmode(PS2);
+ printmode(EPP);
+ printmode(ECP);
+ printmode(ECPEPP);
+ printmode(ECPPS2);
+#undef printmode
+ }
+ len += sprintf(page+len, "\n");
+
+ len += sprintf(page+len, "mode\t:\t");
+ if( pp->modes & PARPORT_MODE_ECR ){
+ switch( r_ecr(pp) >> 5 ){
case 0:
- file->f_pos = offset;
- return(file->f_pos);
+ len += sprintf(page+len, "SPP");
+ if( pp->modes & PARPORT_MODE_PS2 )
+ len += sprintf(page+len, ",PS2");
+ if( pp->modes & PARPORT_MODE_EPP )
+ len += sprintf(page+len, ",EPP");
+ break;
case 1:
- file->f_pos += offset;
- return(file->f_pos);
+ len += sprintf(page+len, "ECPPS2");
+ break;
case 2:
- return(-EINVAL);
- default:
- return(-EINVAL);
+ len += sprintf(page+len, "DATAFIFO");
+ break;
+ case 3:
+ len += sprintf(page+len, "ECP");
+ break;
+ case 4:
+ len += sprintf(page+len, "ECPEPP");
+ break;
+ case 5:
+ len += sprintf(page+len, "Reserved?");
+ break;
+ case 6:
+ len += sprintf(page+len, "TEST");
+ break;
+ case 7:
+ len += sprintf(page+len, "Configuration");
+ break;
+ }
+ }else{
+ len += sprintf(page+len, "SPP");
+ if( pp->modes & PARPORT_MODE_PS2 )
+ len += sprintf(page+len, ",PS2");
+ if( pp->modes & PARPORT_MODE_EPP )
+ len += sprintf(page+len, ",EPP");
}
+ len += sprintf(page+len, "\n");
+
+ /* Now no detection, please fix with an external function */
+ len += sprintf(page+len, "chipset\t:\tunknown\n");
+ if( pp->speed )
+ len += sprintf(page+len, "bench\t:\t%d Bytes/s\n",pp->speed);
+ else
+ len += sprintf(page+len, "bench\t:\tunknown\n");
+
+ *start = 0;
+ *eof = 1;
+ return len;
}

-static struct file_operations proc_dir_operations = {
- proc_parportlseek, /* lseek */
- proc_readparport, /* read */
- proc_writeparport, /* write */
- proc_readdir, /* readdir */
- NULL, /* poll */
- NULL, /* ioctl */
- NULL, /* mmap */
- NULL, /* no special open code */
- NULL, /* no special release code */
- NULL /* can't fsync */
-};
-
-/************************************************/
-static struct inode_operations parport_proc_dir_inode_operations = {
- &proc_dir_operations, /* default net directory file-ops */
- NULL, /* create */
- proc_lookup, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* bmap */
- NULL, /* truncate */
- NULL /* permission */
-};
-
-static struct proc_dir_entry proc_root_parport = {
- PROC_PARPORT, 7, "parport",
- S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
- 0, &parport_proc_dir_inode_operations,
- NULL, NULL,
- NULL, &proc_root, NULL,
- NULL, NULL
-};
-#endif
+static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode,
+ struct proc_dir_entry *parent,
+ unsigned short ino)
+{
+ struct proc_dir_entry *ent;
+
+ ent = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
+ if (!ent)
+ return NULL;
+ memset(ent, 0, sizeof(struct proc_dir_entry));
+
+ if (mode == S_IFDIR)
+ mode |= S_IRUGO | S_IXUGO;
+ else if (mode == 0)
+ mode = S_IFREG | S_IRUGO;
+
+
+ ent->low_ino = ino;
+ ent->name = name;
+ ent->namelen = strlen(name);
+ ent->mode = mode;
+ if (S_ISDIR(mode))
+ ent->nlink = 2;
+ else
+ ent->nlink = 1;
+
+ proc_register(parent, ent);
+
+ return ent;
+}
+
+
+int parport_proc_init()
+{
+ base = new_proc_entry("parport", S_IFDIR, &proc_root,PROC_PARPORT);
+
+ if( base )
+ return 1;
+ else{
+ printk("parport: Error creating proc entry /proc/parport\n");
+ return 0;
+ }
+}
+
+int parport_proc_cleanup()
+{
+ if( base )
+ proc_unregister(&proc_root,base->low_ino);
+
+ base = NULL;
+
+ return 0;
+}

int parport_proc_register(struct parport *pp)
{
-#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED)
- return proc_register(&proc_root, &proc_root_parport);
+#if defined(CONFIG_PROC_FS)
+ struct proc_dir_entry *ent;
+ static int conta=0;
+ char *name;
+
+ memset(&pp->pdir,0,sizeof(struct parport_dir));
+
+ if( !base ){
+ printk("parport: Error entry /proc/parport, not generated?\n");
+ return 1;
+ }
+
+ name = pp->pdir.name;
+ sprintf(name,"%d",conta++);
+
+ ent = new_proc_entry(name, S_IFDIR, base,0);
+ if( !ent ){
+ printk("parport: Error registering proc_entry /proc/%s\n",name);
+ return 1;
+ }
+ pp->pdir.entry = ent;
+
+ ent = new_proc_entry("irq", S_IFREG | S_IRUGO | S_IWUSR, pp->pdir.entry,0);
+ if( !ent ){
+ printk("parport: Error registering proc_entry /proc/%s/irq\n",name);
+ return 1;
+ }
+ ent->read_proc = irq_read_proc;
+ ent->write_proc= irq_write_proc;
+ ent->data = pp;
+ pp->pdir.irq = ent;
+
+ ent = new_proc_entry("devices", 0, pp->pdir.entry,0);
+ if( !ent ){
+ printk("parport: Error registering proc_entry /proc/%s/devices\n",name);
+ return 1;
+ }
+ ent->read_proc = devices_read_proc;
+ ent->data = pp;
+ pp->pdir.devices = ent;
+
+ ent = new_proc_entry("hardware", 0, pp->pdir.entry,0);
+ if( !ent ){
+ printk("parport: Error registering proc_entry /proc/%s/hardware\n",name);
+ return 1;
+ }
+ ent->read_proc = hardware_read_proc;
+ ent->data = pp;
+ pp->pdir.hardware = ent;
+
+ return 0;
#else
return 0;
#endif
}

-void parport_proc_unregister(struct parport *pp)
+int parport_proc_unregister(struct parport *pp)
{
-#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED)
- if( pp ){
- proc_unregister(&proc_root_parport, pp->proc_dir->low_ino);
- kfree(pp->proc_dir);
- }else{
- proc_unregister(&proc_root, proc_root_parport.low_ino);
+#if defined(CONFIG_PROC_FS)
+ if( pp->pdir.entry ){
+ if( pp->pdir.irq ){
+ proc_unregister(pp->pdir.entry, pp->pdir.irq->low_ino);
+ kfree(pp->pdir.irq);
+ }
+
+ if( pp->pdir.devices ){
+ proc_unregister(pp->pdir.entry, pp->pdir.devices->low_ino);
+ kfree(pp->pdir.devices);
+ }
+
+ if( pp->pdir.hardware ){
+ proc_unregister(pp->pdir.entry, pp->pdir.hardware->low_ino);
+ kfree(pp->pdir.hardware);
+ }
+
+ proc_unregister(base, pp->pdir.entry->low_ino);
+ kfree(pp->pdir.entry);
}
+
#endif
+
+ return 0;
}
+
+
Index: linux/drivers/pnp/parport_share.c
diff -u linux/drivers/pnp/parport_share.c:1.3 linux/drivers/pnp/parport_share.c:1.3.2.1
--- linux/drivers/pnp/parport_share.c:1.3 Tue Apr 15 00:29:16 1997
+++ linux/drivers/pnp/parport_share.c Tue Apr 15 11:56:14 1997
@@ -1,4 +1,4 @@
-/* $Id: parport_share.c,v 1.3 1997/04/14 23:29:16 phil Exp $
+/* $Id: parport_share.c,v 1.3.2.1 1997/04/15 10:56:14 phil Exp $
* Parallel-port resource manager code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
@@ -36,7 +36,7 @@
return portlist;
}

-static void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
+void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
{
/* NULL function - Does nothing */
return;
Index: linux/include/linux/parport.h
diff -u linux/include/linux/parport.h:1.2 linux/include/linux/parport.h:1.2.6.1
--- linux/include/linux/parport.h:1.2 Fri Apr 11 16:13:17 1997
+++ linux/include/linux/parport.h Tue Apr 15 12:01:07 1997
@@ -1,10 +1,11 @@
-/* $Id: parport.h,v 1.2 1997/04/11 15:13:17 phil Exp $ */
+/* $Id: parport.h,v 1.2.6.1 1997/04/15 11:01:07 phil Exp $ */

#ifndef _PARPORT_H_
#define _PARPORT_H_

#include <asm/system.h>
#include <asm/ptrace.h>
+#include <linux/proc_fs.h>

/* Maximum of 8 ports per machine */
#define PARPORT_MAX 8
@@ -78,6 +79,14 @@
struct ppd *prev;
};

+struct parport_dir{
+ struct proc_dir_entry *entry; /* Directory /proc/parport/X */
+ struct proc_dir_entry *irq; /* IRQ entry /proc/parport/X/irq */
+ struct proc_dir_entry *devices; /* /proc/parport/X/devices */
+ struct proc_dir_entry *hardware; /* /proc/parport/X/hardware */
+ char name[4]; /* /proc/parport/"XXXX" */
+};
+
/* A parallel port */
struct parport {
unsigned int base; /* base address */
@@ -93,8 +102,9 @@
unsigned int ecr; /* ECP ECR register */
struct parport *next;
unsigned int flags;
- struct proc_dir_entry *proc_dir;
+ struct parport_dir pdir;
struct parport_device_info probe_info;
+ int speed; /* Max Write in Bytes/s */
};

/* parport_register_port registers a new parallel port at the given address (if
@@ -174,8 +184,10 @@
char);

/* Prototypes from parport_procfs */
+extern int parport_proc_init(void);
+extern int parport_proc_cleanup(void);
extern int parport_proc_register(struct parport *pp);
-extern void parport_proc_unregister(struct parport *pp);
+extern int parport_proc_unregister(struct parport *pp);

/* Prototypes from parport_ksyms.c */
extern void dec_parport_count(void);


\
 
 \ /
  Last update: 2005-03-22 13:39    [W:0.044 / U:0.272 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site