Commit 152e5911 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.13pre6

parent e3be5730
Joystick API Documentation -*-Text-*- Joystick API Documentation -*-Text-*-
Ragnar Hojland Espinosa Ragnar Hojland Espinosa
<ragnar@lightside.ddns.org> <ragnar@lightside.dhis.org>
7 Aug 1998 7 Aug 1998
...@@ -74,9 +74,10 @@ is, you have both an axis 0 and a button 0). Generally, ...@@ -74,9 +74,10 @@ is, you have both an axis 0 and a button 0). Generally,
2nd Axis Y 3 2nd Axis Y 3
...and so on ...and so on
Hats vary from one joystick type to another. Some can be moved in 8 Hats vary from one joystick type to another. Some can be moved in 8
directions, some only in 4, however, the driver always reports a hat as two directions, some only in 4. The driver, however, always reports a hat
independent axis, even if the hardware doesn't allow independent movement. as two independent axis, even if the hardware doesn't allow independent
movement.
2.3 js_event.value 2.3 js_event.value
...@@ -85,7 +86,7 @@ independent axis, even if the hardware doesn't allow independent movement. ...@@ -85,7 +86,7 @@ independent axis, even if the hardware doesn't allow independent movement.
For an axis, ``value'' is a signed integer between -32767 and +32767 For an axis, ``value'' is a signed integer between -32767 and +32767
representing the position of the joystick along that axis. If you representing the position of the joystick along that axis. If you
don't read a 0 when the joystick is `dead', or if it doesn't span the don't read a 0 when the joystick is `dead', or if it doesn't span the
full range, you should recalibrate (with, for example, jscal). full range, you should recalibrate it (with, for example, jscal).
For a button, ``value'' for a press button event is 1 and for a release For a button, ``value'' for a press button event is 1 and for a release
button event is 0. button event is 0.
...@@ -93,16 +94,16 @@ button event is 0. ...@@ -93,16 +94,16 @@ button event is 0.
Though this Though this
if (js_event.type == JS_EVENT_BUTTON) { if (js_event.type == JS_EVENT_BUTTON) {
buttons_state ^= (1 << js_event.number); buttons_state ^= (1 << js_event.number);
} }
may work well if you handle JS_EVENT_INIT events separately, may work well if you handle JS_EVENT_INIT events separately,
if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) { if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) {
if (js_event.value) if (js_event.value)
buttons_state |= (1 << js_event.number); buttons_state |= (1 << js_event.number);
else else
buttons_state &= ~(1 << js_event.number); buttons_state &= ~(1 << js_event.number);
} }
is much safer since it can't lose sync with the driver. As you would is much safer since it can't lose sync with the driver. As you would
...@@ -112,6 +113,7 @@ snippet, this ends up being shorter. ...@@ -112,6 +113,7 @@ snippet, this ends up being shorter.
2.4 js_event.time 2.4 js_event.time
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
The time an event was generated is stored in ``js_event.time''. It's a time The time an event was generated is stored in ``js_event.time''. It's a time
in miliseconds since ... well, since sometime in the past. This eases the in miliseconds since ... well, since sometime in the past. This eases the
task of detecting double clicks, figuring out if movement of axis and button task of detecting double clicks, figuring out if movement of axis and button
...@@ -144,14 +146,14 @@ all events on the queue (that is, until you get a -1). ...@@ -144,14 +146,14 @@ all events on the queue (that is, until you get a -1).
For example, For example,
while (1) { while (1) {
while (read (fd, &e, sizeof(struct js_event)) > 0) { while (read (fd, &e, sizeof(struct js_event)) > 0) {
process_event (e); process_event (e);
} }
/* EAGAIN is returned when the queue is empty */ /* EAGAIN is returned when the queue is empty */
if (errno != EAGAIN) { if (errno != EAGAIN) {
/* error */ /* error */
} }
/* do something interesting with processed events */ /* do something interesting with processed events */
} }
One reason for emptying the queue is that if it gets full you'll start One reason for emptying the queue is that if it gets full you'll start
...@@ -219,6 +221,7 @@ JS_VERSION symbol ...@@ -219,6 +221,7 @@ JS_VERSION symbol
#ifdef JS_VERSION #ifdef JS_VERSION
#if JS_VERSION > 0xsomething #if JS_VERSION > 0xsomething
4.2 JSIOCGNAME 4.2 JSIOCGNAME
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
...@@ -232,6 +235,7 @@ possible overrun should the name be too long. ...@@ -232,6 +235,7 @@ possible overrun should the name be too long.
strncpy(name, "Unknown", sizeof(name)); strncpy(name, "Unknown", sizeof(name));
printf("Name: %s\n", name); printf("Name: %s\n", name);
4.3 JSIOC[SG]CORR 4.3 JSIOC[SG]CORR
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
...@@ -266,10 +270,10 @@ The driver offers backward compatibility, though. Here's a quick summary: ...@@ -266,10 +270,10 @@ The driver offers backward compatibility, though. Here's a quick summary:
struct JS_DATA_TYPE js; struct JS_DATA_TYPE js;
while (1) { while (1) {
if (read (fd, &js, JS_RETURN) != JS_RETURN) { if (read (fd, &js, JS_RETURN) != JS_RETURN) {
/* error */ /* error */
} }
usleep (1000); usleep (1000);
} }
As you can figure out from the example, the read returns immediately, As you can figure out from the example, the read returns immediately,
...@@ -299,6 +303,7 @@ The v0.8.0.2 driver also had an interface for 'digital joysticks', (now ...@@ -299,6 +303,7 @@ The v0.8.0.2 driver also had an interface for 'digital joysticks', (now
called Multisystem joystick in this driver), under /dev/djsX. This driver called Multisystem joystick in this driver), under /dev/djsX. This driver
doesn't try to be compatible with that interface. doesn't try to be compatible with that interface.
6. Final Notes 6. Final Notes
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
static unsigned long totalram = 0;
extern void show_net_buffers(void); extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long); extern unsigned long init_smp_mappings(unsigned long);
...@@ -419,6 +421,7 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) ...@@ -419,6 +421,7 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
continue; continue;
} }
set_page_count(mem_map+MAP_NR(tmp), 1); set_page_count(mem_map+MAP_NR(tmp), 1);
totalram += PAGE_SIZE;
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (!initrd_start || (tmp < initrd_start || tmp >= if (!initrd_start || (tmp < initrd_start || tmp >=
initrd_end)) initrd_end))
...@@ -446,28 +449,16 @@ void free_initmem(void) ...@@ -446,28 +449,16 @@ void free_initmem(void)
mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
set_page_count(mem_map+MAP_NR(addr), 1); set_page_count(mem_map+MAP_NR(addr), 1);
free_page(addr); free_page(addr);
totalram += PAGE_SIZE;
} }
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
} }
void si_meminfo(struct sysinfo *val) void si_meminfo(struct sysinfo *val)
{ {
int i; val->totalram = totalram;
i = max_mapnr;
val->totalram = 0;
val->sharedram = 0; val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT; val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = atomic_read(&buffermem); val->bufferram = atomic_read(&buffermem);
while (i-- > 0) {
if (PageReserved(mem_map+i))
continue;
val->totalram++;
if (!page_count(mem_map+i))
continue;
val->sharedram += page_count(mem_map+i) - 1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
return; return;
} }
...@@ -1763,11 +1763,10 @@ static int __init parport_pc_init_pci (int irq, int dma) ...@@ -1763,11 +1763,10 @@ static int __init parport_pc_init_pci (int irq, int dma)
for (n = 0; n < cards[i].numports; n++) { for (n = 0; n < cards[i].numports; n++) {
unsigned long lo = cards[i].addr[n].lo; unsigned long lo = cards[i].addr[n].lo;
unsigned long hi = cards[i].addr[n].hi; unsigned long hi = cards[i].addr[n].hi;
unsigned long io_lo = pcidev->base_address[lo]; unsigned long io_lo, io_hi;
unsigned long io_hi = ((hi < 0) ? 0 : io_lo = pcidev->resource[lo].start;
pcidev->base_address[hi]); io_hi = ((hi < 0) ? 0 :
io_lo &= PCI_BASE_ADDRESS_IO_MASK; pcidev->resource[hi].start);
io_hi &= PCI_BASE_ADDRESS_IO_MASK;
if (irq == PARPORT_IRQ_AUTO) { if (irq == PARPORT_IRQ_AUTO) {
if (parport_pc_probe_port (io_lo, if (parport_pc_probe_port (io_lo,
io_hi, io_hi,
......
This diff is collapsed.
This diff is collapsed.
...@@ -171,7 +171,6 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany) ...@@ -171,7 +171,6 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany)
do { do {
size <<= 1; size <<= 1;
} while (!(size & newval)); } while (!(size & newval));
res->end = res->start + size - 1;
/* 64-bit memory? */ /* 64-bit memory? */
if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
...@@ -192,6 +191,7 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany) ...@@ -192,6 +191,7 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany)
#endif #endif
} }
} }
res->end = res->start + size - 1;
request_resource((l & PCI_BASE_ADDRESS_SPACE_IO) ? &ioport_resource : &iomem_resource, res); request_resource((l & PCI_BASE_ADDRESS_SPACE_IO) ? &ioport_resource : &iomem_resource, res);
} }
} }
......
...@@ -9536,10 +9536,8 @@ aic7xxx_detect(Scsi_Host_Template *template) ...@@ -9536,10 +9536,8 @@ aic7xxx_detect(Scsi_Host_Template *template)
temp_p->pdev = pdev; temp_p->pdev = pdev;
temp_p->pci_bus = pdev->bus->number; temp_p->pci_bus = pdev->bus->number;
temp_p->pci_device_fn = pdev->devfn; temp_p->pci_device_fn = pdev->devfn;
temp_p->base = pdev->base_address[0]; temp_p->base = pdev->resource[0].start;
temp_p->mbase = pdev->base_address[1]; temp_p->mbase = pdev->resource[1].start;
temp_p->base &= PCI_BASE_ADDRESS_IO_MASK;
temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
current_p = list_p; current_p = list_p;
while(current_p) while(current_p)
{ {
......
...@@ -1036,13 +1036,6 @@ static __inline__ void __put_unused_buffer_head(struct buffer_head * bh) ...@@ -1036,13 +1036,6 @@ static __inline__ void __put_unused_buffer_head(struct buffer_head * bh)
} }
} }
static void put_unused_buffer_head(struct buffer_head *bh)
{
spin_lock(&unused_list_lock);
__put_unused_buffer_head(bh);
spin_unlock(&unused_list_lock);
}
/* /*
* Reserve NR_RESERVED buffer heads for async IO requests to avoid * Reserve NR_RESERVED buffer heads for async IO requests to avoid
* no-buffer-head deadlock. Return NULL on failure; waiting for * no-buffer-head deadlock. Return NULL on failure; waiting for
......
...@@ -652,7 +652,7 @@ static struct proc_dir_entry proc_root_ioports = { ...@@ -652,7 +652,7 @@ static struct proc_dir_entry proc_root_ioports = {
0, &proc_array_inode_operations 0, &proc_array_inode_operations
}; };
static struct proc_dir_entry proc_root_iomem = { static struct proc_dir_entry proc_root_iomem = {
PROC_MEMORY, 6, "iomem", PROC_MEMORY, 5, "iomem",
S_IFREG | S_IRUGO, 1, 0, 0, S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations 0, &proc_array_inode_operations
}; };
......
...@@ -57,8 +57,7 @@ typedef int (*initcall_t)(void); ...@@ -57,8 +57,7 @@ typedef int (*initcall_t)(void);
extern initcall_t __initcall_start, __initcall_end; extern initcall_t __initcall_start, __initcall_end;
#define __initcall(fn) \ #define __initcall(fn) \
static __attribute__ ((unused,__section__ (".initcall.init"))) \ static initcall_t __initcall_##fn __init_call = fn
initcall_t __initcall_##fn = fn
/* /*
* Used for kernel command line parameter setup * Used for kernel command line parameter setup
...@@ -70,20 +69,20 @@ struct kernel_param { ...@@ -70,20 +69,20 @@ struct kernel_param {
extern struct kernel_param __setup_start, __setup_end; extern struct kernel_param __setup_start, __setup_end;
#define __setup(str, fn) \ #define __setup(str, fn) \
static __attribute__ ((__section__ (".data.init"))) \ static char __setup_str_##fn[] __initdata = str; \
char __setup_str_##fn[] = str; \ static struct kernel_param __setup_##fn __initsetup = { __setup_str_##fn, fn }
static __attribute__ ((unused,__section__ (".setup.init"))) \
struct kernel_param __setup_##fn = { __setup_str_##fn, fn }
/* /*
* Mark functions and data as being only used at initialization * Mark functions and data as being only used at initialization
* or exit time. * or exit time.
*/ */
#define __init __attribute__ ((__section__ (".text.init"))) #define __init __attribute__ ((__section__ (".text.init")))
#define __exit __attribute__ ((unused, __section__(".text.init"))) #define __exit __attribute__ ((unused, __section__(".text.init")))
#define __initdata __attribute__ ((__section__ (".data.init"))) #define __initdata __attribute__ ((__section__ (".data.init")))
#define __exitdata __attribute__ ((unused, __section__ (".data.init"))) #define __exitdata __attribute__ ((unused, __section__ (".data.init")))
#define __initsetup __attribute__ ((unused,__section__ (".setup.init")))
#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
#define __initfunc(__arginit) \ #define __initfunc(__arginit) \
__arginit __init; \ __arginit __init; \
......
...@@ -19,6 +19,16 @@ struct resource { ...@@ -19,6 +19,16 @@ struct resource {
struct resource *parent, *sibling, *child; struct resource *parent, *sibling, *child;
}; };
/*
* PCI-like IO resources have these defined flags.
* The low four bits come directly from the PCI specs,
* the rest are extended sw flags..
*/
#define IORESOURCE_IOPORT 0x01 /* 0 - memory mapped, 1 - IO ports */
#define IORESOURCE_MEMTYPE_MASK 0x06 /* PCI-specific mapping info */
#define IORESOURCE_PREFETCH 0x08 /* No side effects */
#define IORESOURCE_BUSY 0x10 /* Driver uses this resource */
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */ /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource; extern struct resource ioport_resource;
extern struct resource iomem_resource; extern struct resource iomem_resource;
......
...@@ -948,6 +948,7 @@ ...@@ -948,6 +948,7 @@
#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 #define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002 #define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002
#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 #define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005
#define PCI_VENDOR_ID_SIGMADES 0x1236 #define PCI_VENDOR_ID_SIGMADES 0x1236
#define PCI_DEVICE_ID_SIGMADES_6425 0x6401 #define PCI_DEVICE_ID_SIGMADES_6425 0x6401
...@@ -1210,7 +1211,8 @@ struct pci_dev { ...@@ -1210,7 +1211,8 @@ struct pci_dev {
unsigned int hdr_type; /* PCI header type */ unsigned int hdr_type; /* PCI header type */
unsigned int master : 1; /* set if device is master capable */ unsigned int master : 1; /* set if device is master capable */
char name[32]; char name[48];
/* /*
* In theory, the irq level can be read from configuration * In theory, the irq level can be read from configuration
* space and all would be fine. However, old PCI chips don't * space and all would be fine. However, old PCI chips don't
......
...@@ -12,9 +12,13 @@ ...@@ -12,9 +12,13 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <asm/spinlock.h>
struct resource ioport_resource = { "PCI IO", 0x0000, 0xFFFF }; struct resource ioport_resource = { "PCI IO", 0x0000, 0xFFFF };
struct resource iomem_resource = { "PCI mem", 0x00000000, 0xFFFFFFFF }; struct resource iomem_resource = { "PCI mem", 0x00000000, 0xFFFFFFFF };
static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
/* /*
* This generates reports for /proc/ioports and /proc/memory * This generates reports for /proc/ioports and /proc/memory
*/ */
...@@ -47,25 +51,30 @@ static char * do_resource_list(struct resource *entry, const char *fmt, int offs ...@@ -47,25 +51,30 @@ static char * do_resource_list(struct resource *entry, const char *fmt, int offs
int get_resource_list(struct resource *root, char *buf, int size) int get_resource_list(struct resource *root, char *buf, int size)
{ {
char *fmt; char *fmt;
int retval;
fmt = " %08lx-%08lx : %s\n"; fmt = " %08lx-%08lx : %s\n";
if (root == &ioport_resource) if (root == &ioport_resource)
fmt = " %04lx-%04lx : %s\n"; fmt = " %04lx-%04lx : %s\n";
return do_resource_list(root->child, fmt, 8, buf, buf + size) - buf; read_lock(&resource_lock);
retval = do_resource_list(root->child, fmt, 8, buf, buf + size) - buf;
read_unlock(&resource_lock);
return retval;
} }
int request_resource(struct resource *root, struct resource *new) /* Return the conflict entry if you can't request it */
static struct resource * __request_resource(struct resource *root, struct resource *new)
{ {
unsigned long start = new->start; unsigned long start = new->start;
unsigned long end = new->end; unsigned long end = new->end;
struct resource *tmp, **p; struct resource *tmp, **p;
if (end < start) if (end < start)
return -EINVAL; return root;
if (start < root->start) if (start < root->start)
return -EINVAL; return root;
if (end > root->end) if (end > root->end)
return -EINVAL; return root;
p = &root->child; p = &root->child;
for (;;) { for (;;) {
tmp = *p; tmp = *p;
...@@ -73,15 +82,25 @@ int request_resource(struct resource *root, struct resource *new) ...@@ -73,15 +82,25 @@ int request_resource(struct resource *root, struct resource *new)
new->sibling = tmp; new->sibling = tmp;
*p = new; *p = new;
new->parent = root; new->parent = root;
return 0; return NULL;
} }
p = &tmp->sibling; p = &tmp->sibling;
if (tmp->end < start) if (tmp->end < start)
continue; continue;
return -EBUSY; return tmp;
} }
} }
int request_resource(struct resource *root, struct resource *new)
{
struct resource *conflict;
write_lock(&resource_lock);
conflict = __request_resource(root, new);
write_unlock(&resource_lock);
return conflict ? -EBUSY : 0;
}
int release_resource(struct resource *old) int release_resource(struct resource *old)
{ {
struct resource *tmp, **p; struct resource *tmp, **p;
...@@ -101,6 +120,18 @@ int release_resource(struct resource *old) ...@@ -101,6 +120,18 @@ int release_resource(struct resource *old)
return -EINVAL; return -EINVAL;
} }
/*
* This is compatibility stuff for IO resources.
*
* Note how this, unlike the above, knows about
* the IO flag meanings (busy etc).
*
* Request-region creates a new busy region.
*
* Check-region returns non-zero if the area is already busy
*
* Release-region releases a matching busy region.
*/
struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name) struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name)
{ {
struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL); struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
...@@ -110,21 +141,32 @@ struct resource * __request_region(struct resource *parent, unsigned long start, ...@@ -110,21 +141,32 @@ struct resource * __request_region(struct resource *parent, unsigned long start,
res->name = name; res->name = name;
res->start = start; res->start = start;
res->end = start + n - 1; res->end = start + n - 1;
if (request_resource(parent, res) != 0) { res->flags = IORESOURCE_BUSY;
write_lock(&resource_lock);
while (!(parent->flags & IORESOURCE_BUSY)) {
struct resource *conflict;
conflict = __request_resource(parent, res);
if (!conflict)
break;
if (conflict != parent) {
parent = conflict;
continue;
}
/* Uhhuh, that didn't work out.. */
kfree(res); kfree(res);
res = NULL; res = NULL;
break;
} }
write_unlock(&resource_lock);
} }
return res; return res;
} }
/* /*
* Compatibility cruft.
*
* Check-region returns non-zero if something already exists.
*
* Release-region releases an anonymous region that matches
* the IO port range.
*/ */
int __check_region(struct resource *parent, unsigned long start, unsigned long n) int __check_region(struct resource *parent, unsigned long start, unsigned long n)
{ {
...@@ -152,13 +194,20 @@ void __release_region(struct resource *parent, unsigned long start, unsigned lon ...@@ -152,13 +194,20 @@ void __release_region(struct resource *parent, unsigned long start, unsigned lon
if (!res) if (!res)
break; break;
if (res->start == start && res->end == end) { if (res->start <= start && res->end >= end) {
if (!(res->flags & IORESOURCE_BUSY)) {
p = &res->child;
continue;
}
if (res->start != start || res->end != end)
break;
*p = res->sibling; *p = res->sibling;
kfree(res); kfree(res);
break; return;
} }
p = &res->sibling; p = &res->sibling;
} }
printk("Trying to free nonexistent resource <%04lx-%04lx>\n", start, end);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment