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

Import 2.3.13pre6

parent e3be5730
Joystick API Documentation -*-Text-*-
Ragnar Hojland Espinosa
<ragnar@lightside.ddns.org>
<ragnar@lightside.dhis.org>
7 Aug 1998
......@@ -74,9 +74,10 @@ is, you have both an axis 0 and a button 0). Generally,
2nd Axis Y 3
...and so on
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
independent axis, even if the hardware doesn't allow independent movement.
Hats vary from one joystick type to another. Some can be moved in 8
directions, some only in 4. The driver, however, always reports a hat
as two independent axis, even if the hardware doesn't allow independent
movement.
2.3 js_event.value
......@@ -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
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
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
button event is 0.
......@@ -93,16 +94,16 @@ button event is 0.
Though this
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,
if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) {
if (js_event.value)
buttons_state |= (1 << js_event.number);
else
buttons_state &= ~(1 << js_event.number);
if (js_event.value)
buttons_state |= (1 << js_event.number);
else
buttons_state &= ~(1 << js_event.number);
}
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.
2.4 js_event.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
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).
For example,
while (1) {
while (read (fd, &e, sizeof(struct js_event)) > 0) {
process_event (e);
}
/* EAGAIN is returned when the queue is empty */
if (errno != EAGAIN) {
/* error */
}
/* do something interesting with processed events */
while (read (fd, &e, sizeof(struct js_event)) > 0) {
process_event (e);
}
/* EAGAIN is returned when the queue is empty */
if (errno != EAGAIN) {
/* error */
}
/* do something interesting with processed events */
}
One reason for emptying the queue is that if it gets full you'll start
......@@ -219,6 +221,7 @@ JS_VERSION symbol
#ifdef JS_VERSION
#if JS_VERSION > 0xsomething
4.2 JSIOCGNAME
~~~~~~~~~~~~~~
......@@ -232,6 +235,7 @@ possible overrun should the name be too long.
strncpy(name, "Unknown", sizeof(name));
printf("Name: %s\n", name);
4.3 JSIOC[SG]CORR
~~~~~~~~~~~~~~~~~
......@@ -266,10 +270,10 @@ The driver offers backward compatibility, though. Here's a quick summary:
struct JS_DATA_TYPE js;
while (1) {
if (read (fd, &js, JS_RETURN) != JS_RETURN) {
/* error */
}
usleep (1000);
if (read (fd, &js, JS_RETURN) != JS_RETURN) {
/* error */
}
usleep (1000);
}
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
called Multisystem joystick in this driver), under /dev/djsX. This driver
doesn't try to be compatible with that interface.
6. Final Notes
~~~~~~~~~~~~~~
......
......@@ -28,6 +28,8 @@
#include <asm/dma.h>
#include <asm/fixmap.h>
static unsigned long totalram = 0;
extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
......@@ -419,6 +421,7 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
continue;
}
set_page_count(mem_map+MAP_NR(tmp), 1);
totalram += PAGE_SIZE;
#ifdef CONFIG_BLK_DEV_INITRD
if (!initrd_start || (tmp < initrd_start || tmp >=
initrd_end))
......@@ -446,28 +449,16 @@ void free_initmem(void)
mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
set_page_count(mem_map+MAP_NR(addr), 1);
free_page(addr);
totalram += PAGE_SIZE;
}
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
void si_meminfo(struct sysinfo *val)
{
int i;
i = max_mapnr;
val->totalram = 0;
val->totalram = totalram;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
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;
}
......@@ -1763,11 +1763,10 @@ static int __init parport_pc_init_pci (int irq, int dma)
for (n = 0; n < cards[i].numports; n++) {
unsigned long lo = cards[i].addr[n].lo;
unsigned long hi = cards[i].addr[n].hi;
unsigned long io_lo = pcidev->base_address[lo];
unsigned long io_hi = ((hi < 0) ? 0 :
pcidev->base_address[hi]);
io_lo &= PCI_BASE_ADDRESS_IO_MASK;
io_hi &= PCI_BASE_ADDRESS_IO_MASK;
unsigned long io_lo, io_hi;
io_lo = pcidev->resource[lo].start;
io_hi = ((hi < 0) ? 0 :
pcidev->resource[hi].start);
if (irq == PARPORT_IRQ_AUTO) {
if (parport_pc_probe_port (io_lo,
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)
do {
size <<= 1;
} while (!(size & newval));
res->end = res->start + size - 1;
/* 64-bit memory? */
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)
#endif
}
}
res->end = res->start + size - 1;
request_resource((l & PCI_BASE_ADDRESS_SPACE_IO) ? &ioport_resource : &iomem_resource, res);
}
}
......
......@@ -9536,10 +9536,8 @@ aic7xxx_detect(Scsi_Host_Template *template)
temp_p->pdev = pdev;
temp_p->pci_bus = pdev->bus->number;
temp_p->pci_device_fn = pdev->devfn;
temp_p->base = pdev->base_address[0];
temp_p->mbase = pdev->base_address[1];
temp_p->base &= PCI_BASE_ADDRESS_IO_MASK;
temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
temp_p->base = pdev->resource[0].start;
temp_p->mbase = pdev->resource[1].start;
current_p = list_p;
while(current_p)
{
......
......@@ -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
* no-buffer-head deadlock. Return NULL on failure; waiting for
......
......@@ -652,7 +652,7 @@ static struct proc_dir_entry proc_root_ioports = {
0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_iomem = {
PROC_MEMORY, 6, "iomem",
PROC_MEMORY, 5, "iomem",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations
};
......
......@@ -57,8 +57,7 @@ typedef int (*initcall_t)(void);
extern initcall_t __initcall_start, __initcall_end;
#define __initcall(fn) \
static __attribute__ ((unused,__section__ (".initcall.init"))) \
initcall_t __initcall_##fn = fn
static initcall_t __initcall_##fn __init_call = fn
/*
* Used for kernel command line parameter setup
......@@ -70,20 +69,20 @@ struct kernel_param {
extern struct kernel_param __setup_start, __setup_end;
#define __setup(str, fn) \
static __attribute__ ((__section__ (".data.init"))) \
char __setup_str_##fn[] = str; \
static __attribute__ ((unused,__section__ (".setup.init"))) \
struct kernel_param __setup_##fn = { __setup_str_##fn, fn }
#define __setup(str, fn) \
static char __setup_str_##fn[] __initdata = str; \
static struct kernel_param __setup_##fn __initsetup = { __setup_str_##fn, fn }
/*
* Mark functions and data as being only used at initialization
* or exit time.
*/
#define __init __attribute__ ((__section__ (".text.init")))
#define __exit __attribute__ ((unused, __section__(".text.init")))
#define __initdata __attribute__ ((__section__ (".data.init")))
#define __exitdata __attribute__ ((unused, __section__ (".data.init")))
#define __init __attribute__ ((__section__ (".text.init")))
#define __exit __attribute__ ((unused, __section__(".text.init")))
#define __initdata __attribute__ ((__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) \
__arginit __init; \
......
......@@ -19,6 +19,16 @@ struct resource {
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 */
extern struct resource ioport_resource;
extern struct resource iomem_resource;
......
......@@ -948,6 +948,7 @@
#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002
#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005
#define PCI_VENDOR_ID_SIGMADES 0x1236
#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
......@@ -1210,7 +1211,8 @@ struct pci_dev {
unsigned int hdr_type; /* PCI header type */
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
* space and all would be fine. However, old PCI chips don't
......
......@@ -12,9 +12,13 @@
#include <linux/init.h>
#include <linux/malloc.h>
#include <asm/spinlock.h>
struct resource ioport_resource = { "PCI IO", 0x0000, 0xFFFF };
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
*/
......@@ -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)
{
char *fmt;
int retval;
fmt = " %08lx-%08lx : %s\n";
if (root == &ioport_resource)
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 end = new->end;
struct resource *tmp, **p;
if (end < start)
return -EINVAL;
return root;
if (start < root->start)
return -EINVAL;
return root;
if (end > root->end)
return -EINVAL;
return root;
p = &root->child;
for (;;) {
tmp = *p;
......@@ -73,15 +82,25 @@ int request_resource(struct resource *root, struct resource *new)
new->sibling = tmp;
*p = new;
new->parent = root;
return 0;
return NULL;
}
p = &tmp->sibling;
if (tmp->end < start)
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)
{
struct resource *tmp, **p;
......@@ -101,6 +120,18 @@ int release_resource(struct resource *old)
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 *res = kmalloc(sizeof(*res), GFP_KERNEL);
......@@ -110,21 +141,32 @@ struct resource * __request_region(struct resource *parent, unsigned long start,
res->name = name;
res->start = start;
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);
res = NULL;
break;
}
write_unlock(&resource_lock);
}
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)
{
......@@ -152,13 +194,20 @@ void __release_region(struct resource *parent, unsigned long start, unsigned lon
if (!res)
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;
kfree(res);
break;
return;
}
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