Commit 2c1c2abf authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/network-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents b2751e50 b2fd37fa
...@@ -1132,7 +1132,6 @@ NETWORKING [GENERAL] ...@@ -1132,7 +1132,6 @@ NETWORKING [GENERAL]
P: Networking Team P: Networking Team
M: netdev@oss.sgi.com M: netdev@oss.sgi.com
L: linux-net@vger.kernel.org L: linux-net@vger.kernel.org
W: http://www.uk.linux.org/NetNews.html (2.0 only)
S: Maintained S: Maintained
NETWORKING [IPv4/IPv6] NETWORKING [IPv4/IPv6]
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 5 PATCHLEVEL = 5
SUBLEVEL = 38 SUBLEVEL = 39
EXTRAVERSION = EXTRAVERSION =
# *DOCUMENTATION* # *DOCUMENTATION*
...@@ -173,6 +173,9 @@ noconfig_targets := xconfig menuconfig config oldconfig randconfig \ ...@@ -173,6 +173,9 @@ noconfig_targets := xconfig menuconfig config oldconfig randconfig \
help tags TAGS sgmldocs psdocs pdfdocs htmldocs \ help tags TAGS sgmldocs psdocs pdfdocs htmldocs \
checkconfig checkhelp checkincludes checkconfig checkhelp checkincludes
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o
RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS
# Helpers built in scripts/ # Helpers built in scripts/
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
...@@ -581,13 +584,13 @@ spec: ...@@ -581,13 +584,13 @@ spec:
# will become invalid # will become invalid
rpm: clean spec rpm: clean spec
find . -name SCCS -prune -o -name BitKeeper -prune -o \ find . $(RCS_FIND_IGNORE) \
\( -size 0 -o -name .depend -o -name .hdepend \) \ \( -size 0 -o -name .depend -o -name .hdepend \) \
-type f -print | xargs rm -f -type f -print | xargs rm -f
set -e; \ set -e; \
cd $(TOPDIR)/.. ; \ cd $(TOPDIR)/.. ; \
ln -sf $(TOPDIR) $(KERNELPATH) ; \ ln -sf $(TOPDIR) $(KERNELPATH) ; \
tar -cvz --exclude CVS -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \ tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
rm $(KERNELPATH) ; \ rm $(KERNELPATH) ; \
cd $(TOPDIR) ; \ cd $(TOPDIR) ; \
. scripts/mkversion > .version ; \ . scripts/mkversion > .version ; \
...@@ -717,7 +720,7 @@ include arch/$(ARCH)/Makefile ...@@ -717,7 +720,7 @@ include arch/$(ARCH)/Makefile
clean: archclean clean: archclean
@echo 'Cleaning up' @echo 'Cleaning up'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \ @find . $(RCS_FIND_IGNORE) \
\( -name \*.[oas] -o -name core -o -name .\*.cmd -o \ \( -name \*.[oas] -o -name core -o -name .\*.cmd -o \
-name .\*.tmp -o -name .\*.d \) -type f -print \ -name .\*.tmp -o -name .\*.d \) -type f -print \
| grep -v lxdialog/ | xargs rm -f | grep -v lxdialog/ | xargs rm -f
...@@ -726,7 +729,7 @@ clean: archclean ...@@ -726,7 +729,7 @@ clean: archclean
mrproper: clean archmrproper mrproper: clean archmrproper
@echo 'Making mrproper' @echo 'Making mrproper'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \ @find . $(RCS_FIND_IGNORE) \
\( -name .depend -o -name .\*.cmd \) \ \( -name .depend -o -name .\*.cmd \) \
-type f -print | xargs rm -f -type f -print | xargs rm -f
@rm -f $(MRPROPER_FILES) @rm -f $(MRPROPER_FILES)
...@@ -736,7 +739,7 @@ mrproper: clean archmrproper ...@@ -736,7 +739,7 @@ mrproper: clean archmrproper
distclean: mrproper distclean: mrproper
@echo 'Making distclean' @echo 'Making distclean'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \ @find . $(RCS_FIND_IGNORE) \
\( -not -type d \) -and \ \( -not -type d \) -and \
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \ \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
...@@ -747,18 +750,18 @@ distclean: mrproper ...@@ -747,18 +750,18 @@ distclean: mrproper
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
define all-sources define all-sources
( find . \( -name SCCS -o -name BitKeeper -o -name include -o \ ( find . $(RCS_FIND_IGNORE) \
-name arch \) -prune \ \( -name include -o -name arch \) -prune -o \
-o -name '*.[chS]' -print; \ -name '*.[chS]' -print; \
find arch/$(ARCH) \( -name SCCS -o -name BitKeeper \) -prune \ find arch/$(ARCH) $(RCS_FIND_IGNORE) \
-o -name '*.[chS]' -print; \ -name '*.[chS]' -print; \
find include \( -name SCCS -o -name BitKeeper -o -name config -o \ find include $(RCS_FIND_IGNORE) \
-name 'asm-*' \) -prune \ \( -name config -o -name 'asm-*' \) -prune -o \
-o -name '*.[chS]' -print; \
find include/asm-$(ARCH) \( -name SCCS -o -name BitKeeper \) -prune \
-o -name '*.[chS]' -print; \ -o -name '*.[chS]' -print; \
find include/asm-generic \( -name SCCS -o -name BitKeeper \) -prune \ find include/asm-$(ARCH) $(RCS_FIND_IGNORE) \
-o -name '*.[chS]' -print ) -name '*.[chS]' -print; \
find include/asm-generic $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print )
endef endef
quiet_cmd_TAGS = MAKE $@ quiet_cmd_TAGS = MAKE $@
...@@ -825,17 +828,17 @@ sgmldocs psdocs pdfdocs htmldocs: scripts ...@@ -825,17 +828,17 @@ sgmldocs psdocs pdfdocs htmldocs: scripts
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
checkconfig: checkconfig:
find * -name SCCS -prune -o -name BitKeeper -prune -o \ find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \ -name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkconfig.pl | xargs $(PERL) -w scripts/checkconfig.pl
checkhelp: checkhelp:
find * -name SCCS -prune -o -name BitKeeper -prune -o \ find * $(RCS_FIND_IGNORE) \
-name [cC]onfig.in -print | sort \ -name [cC]onfig.in -print | sort \
| xargs $(PERL) -w scripts/checkhelp.pl | xargs $(PERL) -w scripts/checkhelp.pl
checkincludes: checkincludes:
find * -name SCCS -prune -o -name BitKeeper -prune -o \ find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \ -name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkincludes.pl | xargs $(PERL) -w scripts/checkincludes.pl
......
...@@ -34,6 +34,7 @@ if [ "$CONFIG_X86" = "y" ]; then ...@@ -34,6 +34,7 @@ if [ "$CONFIG_X86" = "y" ]; then
define_bool CONFIG_ACPI_EC y define_bool CONFIG_ACPI_EC y
define_bool CONFIG_ACPI_POWER y define_bool CONFIG_ACPI_POWER y
define_bool CONFIG_ACPI_PCI $CONFIG_PCI define_bool CONFIG_ACPI_PCI $CONFIG_PCI
define_bool CONFIG_ACPI_SLEEP $CONFIG_SOFTWARE_SUSPEND
define_bool CONFIG_ACPI_SYSTEM y define_bool CONFIG_ACPI_SYSTEM y
fi fi
fi fi
......
...@@ -55,7 +55,8 @@ static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { ...@@ -55,7 +55,8 @@ static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
[ACPI_SPCR] = "SPCR", [ACPI_SPCR] = "SPCR",
[ACPI_SRAT] = "SRAT", [ACPI_SRAT] = "SRAT",
[ACPI_SSDT] = "SSDT", [ACPI_SSDT] = "SSDT",
[ACPI_SPMI] = "SPMI" [ACPI_SPMI] = "SPMI",
[ACPI_HPET] = "HPET"
}; };
/* System Description Table (RSDT/XSDT) */ /* System Description Table (RSDT/XSDT) */
...@@ -320,7 +321,7 @@ acpi_table_parse_madt_family ( ...@@ -320,7 +321,7 @@ acpi_table_parse_madt_family (
handler(entry); handler(entry);
} }
entry = (acpi_table_entry_header *) entry = (acpi_table_entry_header *)
((unsigned long) entry += entry->length); ((unsigned long) entry + entry->length);
} }
return count; return count;
......
...@@ -6,6 +6,8 @@ obj-y := core.o sys.o interface.o power.o bus.o \ ...@@ -6,6 +6,8 @@ obj-y := core.o sys.o interface.o power.o bus.o \
obj-y += fs/ obj-y += fs/
obj-$(CONFIG_HOTPLUG) += hotplug.o
export-objs := core.o power.o sys.o bus.o driver.o \ export-objs := core.o power.o sys.o bus.o driver.o \
class.o intf.o platform.o cpu.o class.o intf.o platform.o cpu.o
......
...@@ -50,3 +50,13 @@ extern void interface_remove(struct device_class *, struct device *); ...@@ -50,3 +50,13 @@ extern void interface_remove(struct device_class *, struct device *);
extern int driver_attach(struct device_driver * drv); extern int driver_attach(struct device_driver * drv);
extern void driver_detach(struct device_driver * drv); extern void driver_detach(struct device_driver * drv);
#ifdef CONFIG_HOTPLUG
extern int dev_hotplug(struct device *dev, const char *action);
#else
static inline int dev_hotplug(struct device *dev, const char *action)
{
return 0;
}
#endif
...@@ -200,6 +200,9 @@ int device_register(struct device *dev) ...@@ -200,6 +200,9 @@ int device_register(struct device *dev)
if (platform_notify) if (platform_notify)
platform_notify(dev); platform_notify(dev);
/* notify userspace of device entry */
dev_hotplug(dev, "add");
register_done: register_done:
if (error) { if (error) {
spin_lock(&device_lock); spin_lock(&device_lock);
...@@ -255,6 +258,9 @@ void put_device(struct device * dev) ...@@ -255,6 +258,9 @@ void put_device(struct device * dev)
if (platform_notify_remove) if (platform_notify_remove)
platform_notify_remove(dev); platform_notify_remove(dev);
/* notify userspace that this device is about to disappear */
dev_hotplug (dev, "remove");
device_detach(dev); device_detach(dev);
bus_remove_device(dev); bus_remove_device(dev);
......
/*
* drivers/base/hotplug.c - hotplug call code
*
* Copyright (c) 2000-2001 David Brownell
* Copyright (c) 2002 Greg Kroah-Hartman
* Copyright (c) 2002 IBM Corp.
*
* Based off of drivers/usb/core/usb.c:call_agent(), which was
* written by David Brownell.
*
*/
#define DEBUG 0
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include "base.h"
/*
* hotplugging invokes what /proc/sys/kernel/hotplug says (normally
* /sbin/hotplug) when devices get added or removed.
*
* This invokes a user mode policy agent, typically helping to load driver
* or other modules, configure the device, and more. Drivers can provide
* a MODULE_DEVICE_TABLE to help with module loading subtasks.
*/
#define BUFFER_SIZE 1024 /* should be enough memory for the env */
#define NUM_ENVP 32 /* number of env pointers */
int dev_hotplug (struct device *dev, const char *action)
{
char *argv [3], **envp, *buffer, *scratch;
int retval;
int i = 0;
pr_debug ("%s\n", __FUNCTION__);
if (!dev)
return -ENODEV;
if (!dev->bus || !dev->bus->hotplug)
return -ENODEV;
if (!hotplug_path [0])
return -ENODEV;
if (in_interrupt ()) {
pr_debug ("%s - in_interrupt, not allowed!", __FUNCTION__);
return -EIO;
}
if (!current->fs->root) {
/* don't try to do anything unless we have a root partition */
pr_debug ("%s - %s -- no FS yet\n", __FUNCTION__, action);
return -EIO;
}
envp = (char **) kmalloc (NUM_ENVP * sizeof (char *), GFP_KERNEL);
if (!envp)
return -ENOMEM;
buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
if (!buffer) {
kfree (envp);
return -ENOMEM;
}
/* only one standardized param to hotplug command: the bus name */
argv [0] = hotplug_path;
argv [1] = dev->bus->name;
argv [2] = 0;
/* minimal command environment */
envp [i++] = "HOME=/";
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
scratch = buffer;
/* action: add, remove */
envp [i++] = scratch;
scratch += sprintf (scratch, "ACTION=%s", action) + 1;
/* have the bus specific function set up the rest of the environment */
retval = dev->bus->hotplug (dev, &envp[i], NUM_ENVP - i,
scratch, BUFFER_SIZE - (scratch - buffer));
if (retval) {
pr_debug ("%s - hotplug() returned %d\n", __FUNCTION__, retval);
goto exit;
}
pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv [0], argv[1],
action, envp[0], envp[1], envp[2]);
retval = call_usermodehelper (argv [0], argv, envp);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
__FUNCTION__, retval);
exit:
kfree (buffer);
kfree (envp);
return retval;
}
...@@ -137,8 +137,24 @@ deadline_find_hash(struct deadline_data *dd, sector_t offset) ...@@ -137,8 +137,24 @@ deadline_find_hash(struct deadline_data *dd, sector_t offset)
return rq; return rq;
} }
static sector_t deadline_get_last_sector(struct deadline_data *dd)
{
sector_t last_sec = dd->last_sector;
/*
* if dispatch is non-empty, disregard last_sector and check last one
*/
if (!list_empty(dd->dispatch)) {
struct request *__rq = list_entry_rq(dd->dispatch->prev);
last_sec = __rq->sector + __rq->nr_sectors;
}
return last_sec;
}
static int static int
deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
{ {
struct deadline_data *dd = q->elevator.elevator_data; struct deadline_data *dd = q->elevator.elevator_data;
const int data_dir = bio_data_dir(bio); const int data_dir = bio_data_dir(bio);
...@@ -150,9 +166,11 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -150,9 +166,11 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
/* /*
* try last_merge to avoid going to hash * try last_merge to avoid going to hash
*/ */
ret = elv_try_last_merge(q, req, bio); ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) if (ret != ELEVATOR_NO_MERGE) {
*insert = q->last_merge;
goto out; goto out;
}
/* /*
* see if the merge hash can satisfy a back merge * see if the merge hash can satisfy a back merge
...@@ -161,12 +179,15 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -161,12 +179,15 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector); BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
if (elv_rq_merge_ok(__rq, bio)) { if (elv_rq_merge_ok(__rq, bio)) {
*req = __rq; *insert = &__rq->queuelist;
ret = ELEVATOR_BACK_MERGE; ret = ELEVATOR_BACK_MERGE;
goto out; goto out;
} }
} }
/*
* scan list from back to find insertion point.
*/
entry = sort_list = &dd->sort_list[data_dir]; entry = sort_list = &dd->sort_list[data_dir];
while ((entry = entry->prev) != sort_list) { while ((entry = entry->prev) != sort_list) {
__rq = list_entry_rq(entry); __rq = list_entry_rq(entry);
...@@ -177,8 +198,8 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -177,8 +198,8 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
if (!(__rq->flags & REQ_CMD)) if (!(__rq->flags & REQ_CMD))
continue; continue;
if (!*req && bio_rq_in_between(bio, __rq, sort_list)) if (!*insert && bio_rq_in_between(bio, __rq, sort_list))
*req = __rq; *insert = &__rq->queuelist;
if (__rq->flags & REQ_BARRIER) if (__rq->flags & REQ_BARRIER)
break; break;
...@@ -189,12 +210,23 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -189,12 +210,23 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
if (__rq->sector - bio_sectors(bio) == bio->bi_sector) { if (__rq->sector - bio_sectors(bio) == bio->bi_sector) {
ret = elv_try_merge(__rq, bio); ret = elv_try_merge(__rq, bio);
if (ret != ELEVATOR_NO_MERGE) { if (ret != ELEVATOR_NO_MERGE) {
*req = __rq; *insert = &__rq->queuelist;
break; break;
} }
} }
} }
/*
* no insertion point found, check the very front
*/
if (!*insert && !list_empty(sort_list)) {
__rq = list_entry_rq(sort_list->next);
if (bio->bi_sector + bio_sectors(bio) < __rq->sector &&
bio->bi_sector > deadline_get_last_sector(dd))
*insert = sort_list;
}
out: out:
return ret; return ret;
} }
...@@ -254,18 +286,9 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq) ...@@ -254,18 +286,9 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq)
static void deadline_move_requests(struct deadline_data *dd, struct request *rq) static void deadline_move_requests(struct deadline_data *dd, struct request *rq)
{ {
struct list_head *sort_head = &dd->sort_list[rq_data_dir(rq)]; struct list_head *sort_head = &dd->sort_list[rq_data_dir(rq)];
sector_t last_sec = dd->last_sector; sector_t last_sec = deadline_get_last_sector(dd);
int batch_count = dd->fifo_batch; int batch_count = dd->fifo_batch;
/*
* if dispatch is non-empty, disregard last_sector and check last one
*/
if (!list_empty(dd->dispatch)) {
struct request *__rq = list_entry_rq(dd->dispatch->prev);
last_sec = __rq->sector + __rq->nr_sectors;
}
do { do {
struct list_head *nxt = rq->queuelist.next; struct list_head *nxt = rq->queuelist.next;
int this_rq_cost; int this_rq_cost;
......
...@@ -136,8 +136,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio) ...@@ -136,8 +136,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
return ret; return ret;
} }
inline int elv_try_last_merge(request_queue_t *q, struct request **req, inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
struct bio *bio)
{ {
int ret = ELEVATOR_NO_MERGE; int ret = ELEVATOR_NO_MERGE;
...@@ -150,8 +149,8 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req, ...@@ -150,8 +149,8 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req,
if (!rq_mergeable(__rq)) if (!rq_mergeable(__rq))
q->last_merge = NULL; q->last_merge = NULL;
else if ((ret = elv_try_merge(__rq, bio))) else
*req = __rq; ret = elv_try_merge(__rq, bio);
} }
return ret; return ret;
...@@ -162,15 +161,17 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req, ...@@ -162,15 +161,17 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req,
* *
* See if we can find a request that this buffer can be coalesced with. * See if we can find a request that this buffer can be coalesced with.
*/ */
int elevator_noop_merge(request_queue_t *q, struct request **req, int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
struct bio *bio) struct bio *bio)
{ {
struct list_head *entry = &q->queue_head; struct list_head *entry = &q->queue_head;
struct request *__rq; struct request *__rq;
int ret; int ret;
if ((ret = elv_try_last_merge(q, req, bio))) if ((ret = elv_try_last_merge(q, bio))) {
*insert = q->last_merge;
return ret; return ret;
}
while ((entry = entry->prev) != &q->queue_head) { while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry); __rq = list_entry_rq(entry);
...@@ -182,7 +183,7 @@ int elevator_noop_merge(request_queue_t *q, struct request **req, ...@@ -182,7 +183,7 @@ int elevator_noop_merge(request_queue_t *q, struct request **req,
continue; continue;
if ((ret = elv_try_merge(__rq, bio))) { if ((ret = elv_try_merge(__rq, bio))) {
*req = __rq; *insert = &__rq->queuelist;
q->last_merge = &__rq->queuelist; q->last_merge = &__rq->queuelist;
return ret; return ret;
} }
...@@ -240,12 +241,12 @@ int elevator_global_init(void) ...@@ -240,12 +241,12 @@ int elevator_global_init(void)
return 0; return 0;
} }
int elv_merge(request_queue_t *q, struct request **rq, struct bio *bio) int elv_merge(request_queue_t *q, struct list_head **entry, struct bio *bio)
{ {
elevator_t *e = &q->elevator; elevator_t *e = &q->elevator;
if (e->elevator_merge_fn) if (e->elevator_merge_fn)
return e->elevator_merge_fn(q, rq, bio); return e->elevator_merge_fn(q, entry, bio);
return ELEVATOR_NO_MERGE; return ELEVATOR_NO_MERGE;
} }
......
...@@ -1583,7 +1583,6 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1583,7 +1583,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
again: again:
req = NULL;
insert_here = NULL; insert_here = NULL;
if (blk_queue_empty(q)) { if (blk_queue_empty(q)) {
...@@ -1593,10 +1592,13 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1593,10 +1592,13 @@ static int __make_request(request_queue_t *q, struct bio *bio)
if (barrier) if (barrier)
goto get_rq; goto get_rq;
el_ret = elv_merge(q, &req, bio); el_ret = elv_merge(q, &insert_here, bio);
switch (el_ret) { switch (el_ret) {
case ELEVATOR_BACK_MERGE: case ELEVATOR_BACK_MERGE:
req = list_entry_rq(insert_here);
BUG_ON(!rq_mergeable(req)); BUG_ON(!rq_mergeable(req));
if (!q->back_merge_fn(q, req, bio)) { if (!q->back_merge_fn(q, req, bio)) {
insert_here = &req->queuelist; insert_here = &req->queuelist;
break; break;
...@@ -1611,7 +1613,10 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1611,7 +1613,10 @@ static int __make_request(request_queue_t *q, struct bio *bio)
goto out; goto out;
case ELEVATOR_FRONT_MERGE: case ELEVATOR_FRONT_MERGE:
req = list_entry_rq(insert_here);
BUG_ON(!rq_mergeable(req)); BUG_ON(!rq_mergeable(req));
if (!q->front_merge_fn(q, req, bio)) { if (!q->front_merge_fn(q, req, bio)) {
insert_here = req->queuelist.prev; insert_here = req->queuelist.prev;
break; break;
...@@ -1638,13 +1643,6 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1638,13 +1643,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
* elevator says don't/can't merge. get new request * elevator says don't/can't merge. get new request
*/ */
case ELEVATOR_NO_MERGE: case ELEVATOR_NO_MERGE:
/*
* use elevator hints as to where to insert the
* request. if no hints, just add it to the back
* of the queue
*/
if (req)
insert_here = &req->queuelist;
break; break;
default: default:
......
dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
if [ "$CONFIG_GART_IOMMU" = "y" ]; then
dep_bool '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
else
dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
fi
if [ "$CONFIG_AGP" != "n" ]; then if [ "$CONFIG_AGP" != "n" ]; then
bool ' Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL bool ' Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL
bool ' Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810 bool ' Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
...@@ -7,6 +12,9 @@ if [ "$CONFIG_AGP" != "n" ]; then ...@@ -7,6 +12,9 @@ if [ "$CONFIG_AGP" != "n" ]; then
bool ' Generic SiS support' CONFIG_AGP_SIS bool ' Generic SiS support' CONFIG_AGP_SIS
bool ' ALI chipset support' CONFIG_AGP_ALI bool ' ALI chipset support' CONFIG_AGP_ALI
bool ' Serverworks LE/HE support' CONFIG_AGP_SWORKS bool ' Serverworks LE/HE support' CONFIG_AGP_SWORKS
if [ "$CONFIG_GART_IOMMU" != "y" ]; then
bool ' AMD 8151 support' CONFIG_AGP_AMD_8151
fi
if [ "$CONFIG_IA64" = "y" ]; then if [ "$CONFIG_IA64" = "y" ]; then
bool ' Intel 460GX support' CONFIG_AGP_I460 bool ' Intel 460GX support' CONFIG_AGP_I460
bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1 bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
......
...@@ -16,6 +16,7 @@ agpgart-$(CONFIG_AGP_ALI) += ali-agp.o ...@@ -16,6 +16,7 @@ agpgart-$(CONFIG_AGP_ALI) += ali-agp.o
agpgart-$(CONFIG_AGP_SWORKS) += sworks-agp.o agpgart-$(CONFIG_AGP_SWORKS) += sworks-agp.o
agpgart-$(CONFIG_AGP_I460) += i460-agp.o agpgart-$(CONFIG_AGP_I460) += i460-agp.o
agpgart-$(CONFIG_AGP_HP_ZX1) += hp-agp.o agpgart-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
agpgart-$(CONFIG_AGP_AMD_8151) += k8-agp.o
agpgart-objs := $(agpgart-y) agpgart-objs := $(agpgart-y)
obj-$(CONFIG_AGP) += agpgart.o obj-$(CONFIG_AGP) += agpgart.o
......
...@@ -50,6 +50,9 @@ EXPORT_SYMBOL(agp_backend_release); ...@@ -50,6 +50,9 @@ EXPORT_SYMBOL(agp_backend_release);
struct agp_bridge_data agp_bridge = { type: NOT_SUPPORTED }; struct agp_bridge_data agp_bridge = { type: NOT_SUPPORTED };
static int agp_try_unsupported __initdata = 0; static int agp_try_unsupported __initdata = 0;
int agp_memory_reserved;
__u32 *agp_gatt_table;
int agp_backend_acquire(void) int agp_backend_acquire(void)
{ {
if (agp_bridge.type == NOT_SUPPORTED) if (agp_bridge.type == NOT_SUPPORTED)
...@@ -243,7 +246,7 @@ static int agp_return_size(void) ...@@ -243,7 +246,7 @@ static int agp_return_size(void)
/* Routine to copy over information structure */ /* Routine to copy over information structure */
void agp_copy_info(agp_kern_info * info) int agp_copy_info(agp_kern_info * info)
{ {
unsigned long page_mask = 0; unsigned long page_mask = 0;
int i; int i;
...@@ -251,7 +254,7 @@ void agp_copy_info(agp_kern_info * info) ...@@ -251,7 +254,7 @@ void agp_copy_info(agp_kern_info * info)
memset(info, 0, sizeof(agp_kern_info)); memset(info, 0, sizeof(agp_kern_info));
if (agp_bridge.type == NOT_SUPPORTED) { if (agp_bridge.type == NOT_SUPPORTED) {
info->chipset = agp_bridge.type; info->chipset = agp_bridge.type;
return; return -EIO;
} }
info->version.major = agp_bridge.version->major; info->version.major = agp_bridge.version->major;
info->version.minor = agp_bridge.version->minor; info->version.minor = agp_bridge.version->minor;
...@@ -268,6 +271,7 @@ void agp_copy_info(agp_kern_info * info) ...@@ -268,6 +271,7 @@ void agp_copy_info(agp_kern_info * info)
page_mask |= agp_bridge.mask_memory(page_mask, i); page_mask |= agp_bridge.mask_memory(page_mask, i);
info->page_mask = ~page_mask; info->page_mask = ~page_mask;
return 0;
} }
/* End - Routine to copy over information structure */ /* End - Routine to copy over information structure */
...@@ -518,6 +522,7 @@ int agp_generic_create_gatt_table(void) ...@@ -518,6 +522,7 @@ int agp_generic_create_gatt_table(void)
SetPageReserved(page); SetPageReserved(page);
agp_bridge.gatt_table_real = (unsigned long *) table; agp_bridge.gatt_table_real = (unsigned long *) table;
agp_gatt_table = (void *)table;
CACHE_FLUSH(); CACHE_FLUSH();
agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table), agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
(PAGE_SIZE * (1 << page_order))); (PAGE_SIZE * (1 << page_order)));
...@@ -625,6 +630,9 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -625,6 +630,9 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
break; break;
} }
num_entries -= agp_memory_reserved/PAGE_SIZE;
if (num_entries < 0) num_entries = 0;
if (type != 0 || mem->type != 0) { if (type != 0 || mem->type != 0) {
/* The generic routines know nothing of memory types */ /* The generic routines know nothing of memory types */
return -EINVAL; return -EINVAL;
...@@ -824,6 +832,17 @@ static struct { ...@@ -824,6 +832,17 @@ static struct {
}, },
#endif /* CONFIG_AGP_ALI */ #endif /* CONFIG_AGP_ALI */
#ifdef CONFIG_AGP_AMD_8151
{
.device_id = PCI_DEVICE_ID_AMD_8151_0,
.vendor_id = PCI_VENDOR_ID_AMD,
.chipset = AMD_8151,
.vendor_name = "AMD",
.chipset_name = "8151",
.chipset_setup = amd_8151_setup
},
#endif /* CONFIG_AGP_AMD */
#ifdef CONFIG_AGP_AMD #ifdef CONFIG_AGP_AMD
{ {
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006, .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006,
...@@ -858,7 +877,6 @@ static struct { ...@@ -858,7 +877,6 @@ static struct {
.chipset_setup = amd_irongate_setup, .chipset_setup = amd_irongate_setup,
}, },
#endif /* CONFIG_AGP_AMD */ #endif /* CONFIG_AGP_AMD */
#ifdef CONFIG_AGP_INTEL #ifdef CONFIG_AGP_INTEL
{ {
.device_id = PCI_DEVICE_ID_INTEL_82443LX_0, .device_id = PCI_DEVICE_ID_INTEL_82443LX_0,
...@@ -1632,7 +1650,7 @@ static struct pci_driver agp_pci_driver = { ...@@ -1632,7 +1650,7 @@ static struct pci_driver agp_pci_driver = {
.probe = agp_probe, .probe = agp_probe,
}; };
static int __init agp_init(void) int __init agp_init(void)
{ {
int ret_val; int ret_val;
...@@ -1658,5 +1676,7 @@ static void __exit agp_cleanup(void) ...@@ -1658,5 +1676,7 @@ static void __exit agp_cleanup(void)
} }
} }
#ifndef CONFIG_GART_IOMMU
module_init(agp_init); module_init(agp_init);
module_exit(agp_cleanup); module_exit(agp_cleanup);
#endif
...@@ -49,6 +49,7 @@ void agp_free_key(int key); ...@@ -49,6 +49,7 @@ void agp_free_key(int key);
/* chipset specific init routines. */ /* chipset specific init routines. */
int __init ali_generic_setup (struct pci_dev *pdev); int __init ali_generic_setup (struct pci_dev *pdev);
int __init amd_irongate_setup (struct pci_dev *pdev); int __init amd_irongate_setup (struct pci_dev *pdev);
int __init amd_8151_setup (struct pci_dev *pdev);
int __init hp_zx1_setup (struct pci_dev *pdev); int __init hp_zx1_setup (struct pci_dev *pdev);
int __init intel_i460_setup (struct pci_dev *pdev); int __init intel_i460_setup (struct pci_dev *pdev);
int __init intel_generic_setup (struct pci_dev *pdev); int __init intel_generic_setup (struct pci_dev *pdev);
...@@ -319,6 +320,22 @@ struct agp_bridge_data { ...@@ -319,6 +320,22 @@ struct agp_bridge_data {
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */ #define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */ #define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
#define AMD_8151_APSIZE 0xb4
#define AMD_8151_GARTBLOCK 0xb8
#define AMD_X86_64_GARTAPERTURECTL 0x90
#define AMD_X86_64_GARTAPERTUREBASE 0x94
#define AMD_X86_64_GARTTABLEBASE 0x98
#define AMD_X86_64_GARTCACHECTL 0x9c
#define AMD_X86_64_GARTEN 1<<0
#define AMD_8151_VMAPERTURE 0x10
#define AMD_8151_AGP_CTL 0xb0
#define AMD_8151_APERTURESIZE 0xb4
#define AMD_8151_GARTPTR 0xb8
#define AMD_8151_GTLBEN 1<<7
#define AMD_8151_APEREN 1<<8
/* ALi registers */ /* ALi registers */
#define ALI_APBASE 0x10 #define ALI_APBASE 0x10
#define ALI_AGPCTRL 0xb8 #define ALI_AGPCTRL 0xb8
......
This diff is collapsed.
...@@ -121,6 +121,8 @@ extern struct tty_driver ptm_driver[]; /* Unix98 pty masters; for /dev/ptmx */ ...@@ -121,6 +121,8 @@ extern struct tty_driver ptm_driver[]; /* Unix98 pty masters; for /dev/ptmx */
extern struct tty_driver pts_driver[]; /* Unix98 pty slaves; for /dev/ptmx */ extern struct tty_driver pts_driver[]; /* Unix98 pty slaves; for /dev/ptmx */
#endif #endif
extern void disable_early_printk(void);
/* /*
* redirect is the pseudo-tty that console output * redirect is the pseudo-tty that console output
* is redirected to if asked by TIOCCONS. * is redirected to if asked by TIOCCONS.
...@@ -2185,6 +2187,9 @@ void __init console_init(void) ...@@ -2185,6 +2187,9 @@ void __init console_init(void)
* set up the console device so that later boot sequences can * set up the console device so that later boot sequences can
* inform about problems etc.. * inform about problems etc..
*/ */
#ifdef CONFIG_EARLY_PRINTK
disable_early_printk();
#endif
#ifdef CONFIG_VT #ifdef CONFIG_VT
con_init(); con_init();
#endif #endif
......
...@@ -36,14 +36,11 @@ ...@@ -36,14 +36,11 @@
* This driver has been tested SUCCESSFULLY with the following drivers : * This driver has been tested SUCCESSFULLY with the following drivers :
* o usb-uhci-hcd (For Intel/Via USB controllers) * o usb-uhci-hcd (For Intel/Via USB controllers)
* o uhci-hcd (Alternate/JE driver for Intel/Via USB controllers) * o uhci-hcd (Alternate/JE driver for Intel/Via USB controllers)
* o ohci-hcd (For other USB controllers)
* *
* This driver has NOT been tested with the following drivers : * This driver has NOT been tested with the following drivers :
* o ehci-hcd (USB 2.0 controllers) * o ehci-hcd (USB 2.0 controllers)
* *
* This driver DOESN'T SEEM TO WORK with the following drivers :
* o ohci-hcd (For other USB controllers)
* The first outgoing URB never calls its completion/failure callback.
*
* Note that all HCD drivers do USB_ZERO_PACKET and timeout properly, * Note that all HCD drivers do USB_ZERO_PACKET and timeout properly,
* so we don't have to worry about that anymore. * so we don't have to worry about that anymore.
* One common problem is the failure to set the address on the dongle, * One common problem is the failure to set the address on the dongle,
...@@ -104,8 +101,8 @@ MODULE_DEVICE_TABLE(usb, dongles); ...@@ -104,8 +101,8 @@ MODULE_DEVICE_TABLE(usb, dongles);
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum); static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
static void irda_usb_disconnect(struct usb_device *dev, void *ptr); static void irda_usb_disconnect(struct usb_interface *intf);
static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self); static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
static int irda_usb_open(struct irda_usb_cb *self); static int irda_usb_open(struct irda_usb_cb *self);
...@@ -1340,7 +1337,7 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc) ...@@ -1340,7 +1337,7 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* /*
* Function irda_usb_find_class_desc(dev, ifnum) * Function irda_usb_find_class_desc(intf)
* *
* Returns instance of IrDA class descriptor, or NULL if not found * Returns instance of IrDA class descriptor, or NULL if not found
* *
...@@ -1348,8 +1345,9 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc) ...@@ -1348,8 +1345,9 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
* offer to us, describing their IrDA characteristics. We will use that in * offer to us, describing their IrDA characteristics. We will use that in
* irda_usb_init_qos() * irda_usb_init_qos()
*/ */
static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum) static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf)
{ {
struct usb_device *dev = interface_to_usbdev (intf);
struct irda_class_desc *desc; struct irda_class_desc *desc;
int ret; int ret;
...@@ -1368,7 +1366,8 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device ...@@ -1368,7 +1366,8 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0), ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
IU_REQ_GET_CLASS_DESC, IU_REQ_GET_CLASS_DESC,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, ifnum, desc, sizeof(*desc), MSECS_TO_JIFFIES(500)); 0, intf->altsetting->bInterfaceNumber, desc,
sizeof(*desc), MSECS_TO_JIFFIES(500));
IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret); IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret);
if (ret < sizeof(*desc)) { if (ret < sizeof(*desc)) {
...@@ -1403,9 +1402,10 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device ...@@ -1403,9 +1402,10 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device
* Note : it might be worth protecting this function by a global * Note : it might be worth protecting this function by a global
* spinlock... Or not, because maybe USB already deal with that... * spinlock... Or not, because maybe USB already deal with that...
*/ */
static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum, static int irda_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device *dev = interface_to_usbdev(intf);
struct irda_usb_cb *self = NULL; struct irda_usb_cb *self = NULL;
struct usb_interface_descriptor *interface; struct usb_interface_descriptor *interface;
struct irda_class_desc *irda_desc; struct irda_class_desc *irda_desc;
...@@ -1430,7 +1430,7 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1430,7 +1430,7 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
(irda->present == 0) && (irda->present == 0) &&
(irda->netopen == 0)) { (irda->netopen == 0)) {
IRDA_DEBUG(0, "%s(), found a zombie instance !!!\n", __FUNCTION__); IRDA_DEBUG(0, "%s(), found a zombie instance !!!\n", __FUNCTION__);
irda_usb_disconnect(irda->usbdev, (void *) irda); irda_usb_disconnect(irda->usbintf);
} }
} }
...@@ -1445,7 +1445,7 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1445,7 +1445,7 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
if(self == NULL) { if(self == NULL) {
WARNING("Too many USB IrDA devices !!! (max = %d)\n", WARNING("Too many USB IrDA devices !!! (max = %d)\n",
NIRUSB); NIRUSB);
return NULL; return -ENFILE;
} }
/* Reset the instance */ /* Reset the instance */
...@@ -1459,35 +1459,35 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1459,35 +1459,35 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
int j; int j;
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
usb_free_urb(self->rx_urb[j]); usb_free_urb(self->rx_urb[j]);
return NULL; return -ENOMEM;
} }
} }
self->tx_urb = usb_alloc_urb(0, GFP_KERNEL); self->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!self->tx_urb) { if (!self->tx_urb) {
for (i = 0; i < IU_MAX_RX_URBS; i++) for (i = 0; i < IU_MAX_RX_URBS; i++)
usb_free_urb(self->rx_urb[i]); usb_free_urb(self->rx_urb[i]);
return NULL; return -ENOMEM;
} }
self->speed_urb = usb_alloc_urb(0, GFP_KERNEL); self->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!self->speed_urb) { if (!self->speed_urb) {
for (i = 0; i < IU_MAX_RX_URBS; i++) for (i = 0; i < IU_MAX_RX_URBS; i++)
usb_free_urb(self->rx_urb[i]); usb_free_urb(self->rx_urb[i]);
usb_free_urb(self->tx_urb); usb_free_urb(self->tx_urb);
return NULL; return -ENOMEM;
} }
/* Is this really necessary? */ /* Is this really necessary? */
if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) { if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
err("set_configuration failed"); err("set_configuration failed");
return NULL; return -EIO;
} }
/* Is this really necessary? */ /* Is this really necessary? */
/* Note : some driver do hardcode the interface number, some others /* Note : some driver do hardcode the interface number, some others
* specify an alternate, but very few driver do like this. * specify an alternate, but very few driver do like this.
* Jean II */ * Jean II */
ret = usb_set_interface(dev, ifnum, 0); ret = usb_set_interface(dev, intf->altsetting->bInterfaceNumber, 0);
IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret); IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->bInterfaceNumber, ret);
switch (ret) { switch (ret) {
case 0: case 0:
break; break;
...@@ -1497,33 +1497,35 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1497,33 +1497,35 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
break; break;
default: default:
IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret); IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret);
return NULL; return -EIO;
break; break;
} }
/* Find our endpoints */ /* Find our endpoints */
interface = &dev->actconfig->interface[ifnum].altsetting[0]; interface = &intf->altsetting[0];
if(!irda_usb_parse_endpoints(self, interface->endpoint, if(!irda_usb_parse_endpoints(self, interface->endpoint,
interface->bNumEndpoints)) { interface->bNumEndpoints)) {
ERROR("%s(), Bogus endpoints...\n", __FUNCTION__); ERROR("%s(), Bogus endpoints...\n", __FUNCTION__);
return NULL; return -EIO;
} }
/* Find IrDA class descriptor */ /* Find IrDA class descriptor */
irda_desc = irda_usb_find_class_desc(dev, ifnum); irda_desc = irda_usb_find_class_desc(intf);
if (irda_desc == NULL) if (irda_desc == NULL)
return NULL; return -ENODEV;
self->irda_desc = irda_desc; self->irda_desc = irda_desc;
self->present = 1; self->present = 1;
self->netopen = 0; self->netopen = 0;
self->capability = id->driver_info; self->capability = id->driver_info;
self->usbdev = dev; self->usbdev = dev;
self->usbintf = intf;
ret = irda_usb_open(self); ret = irda_usb_open(self);
if (ret) if (ret)
return NULL; return -ENOMEM;
return self; dev_set_drvdata(&intf->dev, self);
return 0;
} }
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
...@@ -1538,14 +1540,18 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -1538,14 +1540,18 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
* So, we must make bloody sure that everything gets deactivated. * So, we must make bloody sure that everything gets deactivated.
* Jean II * Jean II
*/ */
static void irda_usb_disconnect(struct usb_device *dev, void *ptr) static void irda_usb_disconnect(struct usb_interface *intf)
{ {
unsigned long flags; unsigned long flags;
struct irda_usb_cb *self = (struct irda_usb_cb *) ptr; struct irda_usb_cb *self = dev_get_drvdata (&intf->dev);
int i; int i;
IRDA_DEBUG(1, "%s()\n", __FUNCTION__); IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
dev_set_drvdata(&intf->dev, NULL);
if (!self)
return;
/* Make sure that the Tx path is not executing. - Jean II */ /* Make sure that the Tx path is not executing. - Jean II */
spin_lock_irqsave(&self->lock, flags); spin_lock_irqsave(&self->lock, flags);
...@@ -1577,6 +1583,7 @@ static void irda_usb_disconnect(struct usb_device *dev, void *ptr) ...@@ -1577,6 +1583,7 @@ static void irda_usb_disconnect(struct usb_device *dev, void *ptr)
irda_usb_close(self); irda_usb_close(self);
/* No longer attached to USB bus */ /* No longer attached to USB bus */
self->usbdev = NULL; self->usbdev = NULL;
self->usbintf = NULL;
/* Clean up our urbs */ /* Clean up our urbs */
for (i = 0; i < IU_MAX_RX_URBS; i++) for (i = 0; i < IU_MAX_RX_URBS; i++)
...@@ -1635,7 +1642,7 @@ void __exit usb_irda_cleanup(void) ...@@ -1635,7 +1642,7 @@ void __exit usb_irda_cleanup(void)
/* If the Device is zombie */ /* If the Device is zombie */
if((irda->usbdev != NULL) && (irda->present == 0)) { if((irda->usbdev != NULL) && (irda->present == 0)) {
IRDA_DEBUG(0, "%s(), disconnect zombie now !\n", __FUNCTION__); IRDA_DEBUG(0, "%s(), disconnect zombie now !\n", __FUNCTION__);
irda_usb_disconnect(irda->usbdev, (void *) irda); irda_usb_disconnect(irda->usbintf);
} }
} }
......
/* airport.c 0.11b /* airport.c 0.13
* *
* A driver for "Hermes" chipset based Apple Airport wireless * A driver for "Hermes" chipset based Apple Airport wireless
* card. * card.
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <linux/list.h>
#include <linux/adb.h> #include <linux/adb.h>
#include <linux/pmu.h> #include <linux/pmu.h>
...@@ -39,22 +38,15 @@ ...@@ -39,22 +38,15 @@
#include <asm/pmac_feature.h> #include <asm/pmac_feature.h>
#include <asm/irq.h> #include <asm/irq.h>
#include "hermes.h"
#include "orinoco.h" #include "orinoco.h"
static char version[] __initdata = "airport.c 0.11b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
MODULE_LICENSE("Dual MPL/GPL");
#define AIRPORT_IO_LEN (0x1000) /* one page */ #define AIRPORT_IO_LEN (0x1000) /* one page */
struct airport { struct airport {
struct device_node* node; struct device_node *node;
void *vaddr; void *vaddr;
int irq_requested; int irq_requested;
int ndev_registered; int ndev_registered;
int open;
}; };
#ifdef CONFIG_PMAC_PBOOK #ifdef CONFIG_PMAC_PBOOK
...@@ -70,101 +62,77 @@ static struct pmu_sleep_notifier airport_sleep_notifier = { ...@@ -70,101 +62,77 @@ static struct pmu_sleep_notifier airport_sleep_notifier = {
static struct net_device *airport_attach(struct device_node *of_node); static struct net_device *airport_attach(struct device_node *of_node);
static void airport_detach(struct net_device *dev); static void airport_detach(struct net_device *dev);
static int airport_open(struct net_device *dev);
static int airport_stop(struct net_device *dev);
/*
A linked list of "instances" of the dummy device. Each actual
PCMCIA card corresponds to one device instance, and is described
by one dev_link_t structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
memory card driver uses an array of dev_link_t pointers, where minor
device numbers are used to derive the corresponding array index.
*/
static struct net_device *airport_dev; static struct net_device *airport_dev;
static int
airport_open(struct net_device *dev)
{
struct orinoco_private *priv = dev->priv;
struct airport* card = (struct airport *)priv->card;
int rc;
TRACE_ENTER(dev->name);
netif_device_attach(dev);
rc = orinoco_reset(priv);
if (rc)
airport_stop(dev);
else {
card->open = 1;
netif_start_queue(dev);
}
TRACE_EXIT(dev->name);
return rc;
}
static int
airport_stop(struct net_device *dev)
{
struct orinoco_private *priv = dev->priv;
struct airport* card = (struct airport *)priv->card;
TRACE_ENTER(dev->name);
netif_stop_queue(dev);
orinoco_shutdown(priv);
card->open = 0;
TRACE_EXIT(dev->name);
return 0;
}
#ifdef CONFIG_PMAC_PBOOK #ifdef CONFIG_PMAC_PBOOK
static int static int
airport_sleep_notify(struct pmu_sleep_notifier *self, int when) airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
{ {
struct net_device *dev = airport_dev; struct net_device *dev = airport_dev;
struct orinoco_private *priv = (struct orinoco_private *)dev->priv; struct orinoco_private *priv = dev->priv;
struct hermes *hw = &priv->hw; struct airport *card = priv->card;
struct airport* card = (struct airport *)priv->card; unsigned long flags;
int rc; int err;
if (! airport_dev) if (! airport_dev)
return PBOOK_SLEEP_OK; return PBOOK_SLEEP_OK;
switch (when) { switch (when) {
case PBOOK_SLEEP_REQUEST:
break;
case PBOOK_SLEEP_REJECT:
break;
case PBOOK_SLEEP_NOW: case PBOOK_SLEEP_NOW:
printk(KERN_INFO "%s: Airport entering sleep mode\n", dev->name); printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name);
if (card->open) {
netif_stop_queue(dev); err = orinoco_lock(priv, &flags);
orinoco_shutdown(priv); if (err) {
netif_device_detach(dev); printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n",
dev->name);
break;
} }
err = __orinoco_down(dev);
if (err)
printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
dev->name, err);
netif_device_detach(dev);
priv->hw_unavailable = 1;
orinoco_unlock(priv, &flags);
disable_irq(dev->irq); disable_irq(dev->irq);
pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
break; break;
case PBOOK_WAKE: case PBOOK_WAKE:
printk(KERN_INFO "%s: Airport waking up\n", dev->name); printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1);
mdelay(200); mdelay(200);
hermes_reset(hw);
rc = orinoco_reset(priv);
if (rc)
printk(KERN_ERR "airport: Error %d re-initing card !\n", rc);
else if (card->open)
netif_device_attach(dev);
enable_irq(dev->irq); enable_irq(dev->irq);
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
dev->name, err);
break;
}
spin_lock_irqsave(&priv->lock, flags);
netif_device_attach(dev);
if (priv->open) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
dev->name, err);
}
priv->hw_unavailable = 0;
spin_unlock_irqrestore(&priv->lock, flags);
break; break;
} }
return PBOOK_SLEEP_OK; return PBOOK_SLEEP_OK;
...@@ -172,7 +140,7 @@ airport_sleep_notify(struct pmu_sleep_notifier *self, int when) ...@@ -172,7 +140,7 @@ airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
#endif /* CONFIG_PMAC_PBOOK */ #endif /* CONFIG_PMAC_PBOOK */
static struct net_device * static struct net_device *
airport_attach(struct device_node* of_node) airport_attach(struct device_node *of_node)
{ {
struct orinoco_private *priv; struct orinoco_private *priv;
struct net_device *dev; struct net_device *dev;
...@@ -180,15 +148,13 @@ airport_attach(struct device_node* of_node) ...@@ -180,15 +148,13 @@ airport_attach(struct device_node* of_node)
unsigned long phys_addr; unsigned long phys_addr;
hermes_t *hw; hermes_t *hw;
TRACE_ENTER("orinoco");
if (of_node->n_addrs < 1 || of_node->n_intrs < 1) { if (of_node->n_addrs < 1 || of_node->n_intrs < 1) {
printk(KERN_ERR "airport: wrong interrupt/addresses in OF tree\n"); printk(KERN_ERR "airport: wrong interrupt/addresses in OF tree\n");
return NULL; return NULL;
} }
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
dev = alloc_orinocodev(sizeof(*card)); dev = alloc_orinocodev(sizeof(*card), NULL);
if (! dev) { if (! dev) {
printk(KERN_ERR "airport: can't allocate device datas\n"); printk(KERN_ERR "airport: can't allocate device datas\n");
return NULL; return NULL;
...@@ -204,17 +170,14 @@ airport_attach(struct device_node* of_node) ...@@ -204,17 +170,14 @@ airport_attach(struct device_node* of_node)
kfree(dev); kfree(dev);
return NULL; return NULL;
} }
dev->name[0] = '\0'; /* register_netdev will give us an ethX name */ dev->name[0] = '\0'; /* register_netdev will give us an ethX name */
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
/* Overrides */
dev->open = airport_open;
dev->stop = airport_stop;
/* Setup interrupts & base address */ /* Setup interrupts & base address */
dev->irq = of_node->intrs[0].line; dev->irq = of_node->intrs[0].line;
phys_addr = of_node->addrs[0].address; /* Physical address */ phys_addr = of_node->addrs[0].address; /* Physical address */
printk(KERN_DEBUG "Airport at physical address %lx\n", phys_addr);
dev->base_addr = phys_addr; dev->base_addr = phys_addr;
card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN); card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
if (! card->vaddr) { if (! card->vaddr) {
...@@ -231,14 +194,14 @@ airport_attach(struct device_node* of_node) ...@@ -231,14 +194,14 @@ airport_attach(struct device_node* of_node)
schedule_timeout(HZ); schedule_timeout(HZ);
/* Reset it before we get the interrupt */ /* Reset it before we get the interrupt */
hermes_reset(hw); hermes_init(hw);
if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) { if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq); printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
goto failed; goto failed;
} }
card->irq_requested = 1; card->irq_requested = 1;
/* Tell the stack we exist */ /* Tell the stack we exist */
if (register_netdev(dev) != 0) { if (register_netdev(dev) != 0) {
printk(KERN_ERR "airport: register_netdev() failed\n"); printk(KERN_ERR "airport: register_netdev() failed\n");
...@@ -248,7 +211,7 @@ airport_attach(struct device_node* of_node) ...@@ -248,7 +211,7 @@ airport_attach(struct device_node* of_node)
card->ndev_registered = 1; card->ndev_registered = 1;
/* And give us the proc nodes for debugging */ /* And give us the proc nodes for debugging */
if (orinoco_proc_dev_init(priv) != 0) if (orinoco_proc_dev_init(dev) != 0)
printk(KERN_ERR "airport: Failed to create /proc node for %s\n", printk(KERN_ERR "airport: Failed to create /proc node for %s\n",
dev->name); dev->name);
...@@ -257,7 +220,7 @@ airport_attach(struct device_node* of_node) ...@@ -257,7 +220,7 @@ airport_attach(struct device_node* of_node)
#endif #endif
return dev; return dev;
failed: failed:
airport_detach(dev); airport_detach(dev);
return NULL; return NULL;
} /* airport_attach */ } /* airport_attach */
...@@ -273,7 +236,7 @@ airport_detach(struct net_device *dev) ...@@ -273,7 +236,7 @@ airport_detach(struct net_device *dev)
struct airport *card = priv->card; struct airport *card = priv->card;
/* Unregister proc entry */ /* Unregister proc entry */
orinoco_proc_dev_cleanup(priv); orinoco_proc_dev_cleanup(dev);
#ifdef CONFIG_PMAC_PBOOK #ifdef CONFIG_PMAC_PBOOK
pmu_unregister_sleep_notifier(&airport_sleep_notifier); pmu_unregister_sleep_notifier(&airport_sleep_notifier);
...@@ -281,7 +244,7 @@ airport_detach(struct net_device *dev) ...@@ -281,7 +244,7 @@ airport_detach(struct net_device *dev)
if (card->ndev_registered) if (card->ndev_registered)
unregister_netdev(dev); unregister_netdev(dev);
card->ndev_registered = 0; card->ndev_registered = 0;
if (card->irq_requested) if (card->irq_requested)
free_irq(dev->irq, priv); free_irq(dev->irq, priv);
card->irq_requested = 0; card->irq_requested = 0;
...@@ -289,22 +252,28 @@ airport_detach(struct net_device *dev) ...@@ -289,22 +252,28 @@ airport_detach(struct net_device *dev)
if (card->vaddr) if (card->vaddr)
iounmap(card->vaddr); iounmap(card->vaddr);
card->vaddr = 0; card->vaddr = 0;
dev->base_addr = 0; dev->base_addr = 0;
release_OF_resource(card->node, 0); release_OF_resource(card->node, 0);
pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0); pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
current->state = TASK_UNINTERRUPTIBLE; current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(HZ); schedule_timeout(HZ);
kfree(dev); kfree(dev);
} /* airport_detach */ } /* airport_detach */
static char version[] __initdata = "airport.c 0.13 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
MODULE_LICENSE("Dual MPL/GPL");
EXPORT_NO_SYMBOLS;
static int __init static int __init
init_airport(void) init_airport(void)
{ {
struct device_node* airport_node; struct device_node *airport_node;
printk(KERN_DEBUG "%s\n", version); printk(KERN_DEBUG "%s\n", version);
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/ptrace.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -53,7 +52,7 @@ ...@@ -53,7 +52,7 @@
#include "hermes.h" #include "hermes.h"
static char version[] __initdata = "hermes.c: 5 Apr 2002 David Gibson <hermes@gibson.dropbear.id.au>"; static char version[] __initdata = "hermes.c: 4 Jul 2002 David Gibson <hermes@gibson.dropbear.id.au>";
MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller"); MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>"); MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
#ifdef MODULE_LICENSE #ifdef MODULE_LICENSE
...@@ -70,14 +69,14 @@ MODULE_LICENSE("Dual MPL/GPL"); ...@@ -70,14 +69,14 @@ MODULE_LICENSE("Dual MPL/GPL");
* Debugging helpers * Debugging helpers
*/ */
#define IO_TYPE(hw) ((hw)->io_space ? "IO " : "MEM ")
#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %s0x%x: " , IO_TYPE(hw), hw->iobase); \
printk(stuff);} while (0)
#undef HERMES_DEBUG #undef HERMES_DEBUG
#ifdef HERMES_DEBUG #ifdef HERMES_DEBUG
#include <stdarg.h> #include <stdarg.h>
#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ 0x%x: " , hw->iobase); \
printk(stuff);} while (0)
#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff) #define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
#else /* ! HERMES_DEBUG */ #else /* ! HERMES_DEBUG */
...@@ -86,7 +85,6 @@ MODULE_LICENSE("Dual MPL/GPL"); ...@@ -86,7 +85,6 @@ MODULE_LICENSE("Dual MPL/GPL");
#endif /* ! HERMES_DEBUG */ #endif /* ! HERMES_DEBUG */
#define IO_TYPE(hw) ((hw)->io_space ? "IO " : "MEM ")
/* /*
* Internal functions * Internal functions
...@@ -111,7 +109,6 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0) ...@@ -111,7 +109,6 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
udelay(1); udelay(1);
reg = hermes_read_regn(hw, CMD); reg = hermes_read_regn(hw, CMD);
} }
DEBUG(3, "hermes_issue_cmd: did %d retries.\n", CMD_BUSY_TIMEOUT-k);
if (reg & HERMES_CMD_BUSY) { if (reg & HERMES_CMD_BUSY) {
return -EBUSY; return -EBUSY;
} }
...@@ -143,7 +140,7 @@ void hermes_struct_init(hermes_t *hw, ulong address, ...@@ -143,7 +140,7 @@ void hermes_struct_init(hermes_t *hw, ulong address,
#endif #endif
} }
int hermes_reset(hermes_t *hw) int hermes_init(hermes_t *hw)
{ {
u16 status, reg; u16 status, reg;
int err = 0; int err = 0;
...@@ -195,8 +192,6 @@ int hermes_reset(hermes_t *hw) ...@@ -195,8 +192,6 @@ int hermes_reset(hermes_t *hw)
reg = hermes_read_regn(hw, EVSTAT); reg = hermes_read_regn(hw, EVSTAT);
} }
DEBUG(0, "Reset completed in %d iterations\n", CMD_INIT_TIMEOUT - k);
hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC); hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
if (! hermes_present(hw)) { if (! hermes_present(hw)) {
...@@ -303,9 +298,6 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) ...@@ -303,9 +298,6 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL); err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
if (err) { if (err) {
printk(KERN_WARNING "hermes @ %s0x%lx: "
"Frame allocation command failed (0x%X).\n",
IO_TYPE(hw), hw->iobase, err);
return err; return err;
} }
...@@ -393,12 +385,10 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset) ...@@ -393,12 +385,10 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
} }
if (reg & HERMES_OFFSET_BUSY) { if (reg & HERMES_OFFSET_BUSY) {
DEBUG(1,"hermes_bap_seek: timeout\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (reg & HERMES_OFFSET_ERR) { if (reg & HERMES_OFFSET_ERR) {
DEBUG(1,"hermes_bap_seek: BAP error\n");
return -EIO; return -EIO;
} }
...@@ -472,6 +462,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize, ...@@ -472,6 +462,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
int err = 0; int err = 0;
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
u16 rlength, rtype; u16 rlength, rtype;
int nwords;
if ( (bufsize < 0) || (bufsize % 2) ) if ( (bufsize < 0) || (bufsize % 2) )
return -EINVAL; return -EINVAL;
...@@ -500,10 +491,9 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize, ...@@ -500,10 +491,9 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
"(rid=0x%04x, len=0x%04x)\n", "(rid=0x%04x, len=0x%04x)\n",
IO_TYPE(hw), hw->iobase, IO_TYPE(hw), hw->iobase,
HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength); HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
/* FIXME: we should read the min of the requested length and nwords = min_t(int, rlength - 1, bufsize / 2);
the actual record length */ hermes_read_words(hw, dreg, buf, nwords);
hermes_read_words(hw, dreg, buf, bufsize / 2);
out: out:
return err; return err;
...@@ -516,9 +506,6 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, ...@@ -516,9 +506,6 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
int err = 0; int err = 0;
int count; int count;
DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
bap, rid, length, * ((u16 *)value));
err = hermes_bap_seek(hw, bap, rid, 0); err = hermes_bap_seek(hw, bap, rid, 0);
if (err) if (err)
goto out; goto out;
...@@ -538,7 +525,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, ...@@ -538,7 +525,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
} }
EXPORT_SYMBOL(hermes_struct_init); EXPORT_SYMBOL(hermes_struct_init);
EXPORT_SYMBOL(hermes_reset); EXPORT_SYMBOL(hermes_init);
EXPORT_SYMBOL(hermes_docmd_wait); EXPORT_SYMBOL(hermes_docmd_wait);
EXPORT_SYMBOL(hermes_allocate); EXPORT_SYMBOL(hermes_allocate);
......
...@@ -171,6 +171,7 @@ struct hermes_rx_descriptor { ...@@ -171,6 +171,7 @@ struct hermes_rx_descriptor {
#define HERMES_RXSTAT_BADCRC (0x0001) #define HERMES_RXSTAT_BADCRC (0x0001)
#define HERMES_RXSTAT_UNDECRYPTABLE (0x0002) #define HERMES_RXSTAT_UNDECRYPTABLE (0x0002)
#define HERMES_RXSTAT_MACPORT (0x0700) #define HERMES_RXSTAT_MACPORT (0x0700)
#define HERMES_RXSTAT_PCF (0x1000) /* Frame was received in CF period */
#define HERMES_RXSTAT_MSGTYPE (0xE000) #define HERMES_RXSTAT_MSGTYPE (0xE000)
#define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */ #define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */
#define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel encoded frame */ #define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel encoded frame */
...@@ -299,7 +300,7 @@ typedef struct hermes_response { ...@@ -299,7 +300,7 @@ typedef struct hermes_response {
/* Function prototypes */ /* Function prototypes */
void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing); void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing);
int hermes_reset(hermes_t *hw); int hermes_init(hermes_t *hw);
int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp); int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp);
int hermes_allocate(hermes_t *hw, u16 size, u16 *fid); int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
...@@ -319,12 +320,6 @@ static inline int hermes_present(hermes_t *hw) ...@@ -319,12 +320,6 @@ static inline int hermes_present(hermes_t *hw)
return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC; return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
} }
static inline void hermes_enable_interrupt(hermes_t *hw, u16 events)
{
hw->inten |= events;
hermes_write_regn(hw, INTEN, hw->inten);
}
static inline void hermes_set_irqmask(hermes_t *hw, u16 events) static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
{ {
hw->inten = events; hw->inten = events;
...@@ -350,7 +345,7 @@ static inline int hermes_inquire(hermes_t *hw, u16 rid) ...@@ -350,7 +345,7 @@ static inline int hermes_inquire(hermes_t *hw, u16 rid)
return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
} }
#define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 ) #define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 ) #define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
/* Note that for the next two, the count is in 16-bit words, not bytes */ /* Note that for the next two, the count is in 16-bit words, not bytes */
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
#define IEEE802_11_DATA_LEN 2304 #define IEEE802_11_DATA_LEN 2304
/* Actually, the standard seems to be inconsistent about what the /* Actually, the standard seems to be inconsistent about what the
maximum frame size really is. S6.2.1.1.2 says 2304 octets, but the maximum frame size really is. Section 6.2.1.1.2 says 2304 octets,
figure in section 7.1.2 says 2312 octects. */ but the figure in Section 7.1.2 says 2312 octects. */
#define IEEE802_11_HLEN 30 #define IEEE802_11_HLEN 30
#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN) #define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
......
This diff is collapsed.
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#ifndef _ORINOCO_H #ifndef _ORINOCO_H
#define _ORINOCO_H #define _ORINOCO_H
#include "hermes.h"
/* To enable debug messages */ /* To enable debug messages */
//#define ORINOCO_DEBUG 3 //#define ORINOCO_DEBUG 3
...@@ -18,24 +20,26 @@ ...@@ -18,24 +20,26 @@
#define ORINOCO_MAX_KEY_SIZE 14 #define ORINOCO_MAX_KEY_SIZE 14
#define ORINOCO_MAX_KEYS 4 #define ORINOCO_MAX_KEYS 4
typedef struct orinoco_key { struct orinoco_key {
u16 len; /* always store little-endian */ u16 len; /* always stored as little-endian */
char data[ORINOCO_MAX_KEY_SIZE]; char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed)) orinoco_key_t; } __attribute__ ((packed));
typedef orinoco_key_t orinoco_keys_t[ORINOCO_MAX_KEYS]; #define ORINOCO_INTEN ( HERMES_EV_RX | HERMES_EV_ALLOC | HERMES_EV_TX | \
HERMES_EV_TXEXC | HERMES_EV_WTERR | HERMES_EV_INFO | \
HERMES_EV_INFDROP )
/*====================================================================*/
struct orinoco_private { struct orinoco_private {
void *card; /* Pointer to card dependant structure */ void *card; /* Pointer to card dependant structure */
/* card dependant extra reset code (i.e. bus/interface specific */
int (*hard_reset)(struct orinoco_private *); int (*hard_reset)(struct orinoco_private *);
/* Synchronisation stuff */
spinlock_t lock; spinlock_t lock;
long state; int hw_unavailable;
#define ORINOCO_STATE_INIRQ 0 struct tq_struct timeout_task;
#define ORINOCO_STATE_DOIRQ 1
int open;
/* Net device stuff */ /* Net device stuff */
struct net_device *ndev; struct net_device *ndev;
...@@ -58,14 +62,13 @@ struct orinoco_private { ...@@ -58,14 +62,13 @@ struct orinoco_private {
int has_preamble; int has_preamble;
int has_sensitivity; int has_sensitivity;
int nicbuf_size; int nicbuf_size;
int broken_cor_reset;
u16 channel_mask; u16 channel_mask;
/* Configuration paramaters */ /* Configuration paramaters */
u32 iw_mode; u32 iw_mode;
int prefer_port3; int prefer_port3;
u16 wep_on, wep_restrict, tx_key; u16 wep_on, wep_restrict, tx_key;
orinoco_keys_t keys; struct orinoco_key keys[ORINOCO_MAX_KEYS];
int bitratemode; int bitratemode;
char nick[IW_ESSID_MAX_SIZE+1]; char nick[IW_ESSID_MAX_SIZE+1];
char desired_essid[IW_ESSID_MAX_SIZE+1]; char desired_essid[IW_ESSID_MAX_SIZE+1];
...@@ -81,38 +84,58 @@ struct orinoco_private { ...@@ -81,38 +84,58 @@ struct orinoco_private {
#endif #endif
/* Configuration dependent variables */ /* Configuration dependent variables */
int port_type, allow_ibss; int port_type, createibss;
int promiscuous, mc_count; int promiscuous, mc_count;
/* /proc based debugging stuff */ /* /proc based debugging stuff */
struct proc_dir_entry *dir_dev; struct proc_dir_entry *dir_dev;
}; };
/*====================================================================*/
extern struct list_head orinoco_instances;
#ifdef ORINOCO_DEBUG #ifdef ORINOCO_DEBUG
extern int orinoco_debug; extern int orinoco_debug;
#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0) #define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
#define DEBUGMORE(n, args...) do { if (orinoco_debug>(n)) printk(args); } while (0)
#else #else
#define DEBUG(n, args...) do { } while (0) #define DEBUG(n, args...) do { } while (0)
#define DEBUGMORE(n, args...) do { } while (0)
#endif /* ORINOCO_DEBUG */ #endif /* ORINOCO_DEBUG */
#define TRACE_ENTER(devname) DEBUG(2, "%s: -> " __FUNCTION__ "()\n", devname); #define TRACE_ENTER(devname) DEBUG(2, "%s: -> " __FUNCTION__ "()\n", devname);
#define TRACE_EXIT(devname) DEBUG(2, "%s: <- " __FUNCTION__ "()\n", devname); #define TRACE_EXIT(devname) DEBUG(2, "%s: <- " __FUNCTION__ "()\n", devname);
#define RUP_EVEN(a) ( (a) % 2 ? (a) + 1 : (a) ) extern struct net_device *alloc_orinocodev(int sizeof_card,
int (*hard_reset)(struct orinoco_private *));
extern int __orinoco_up(struct net_device *dev);
extern int __orinoco_down(struct net_device *dev);
int orinoco_reinit_firmware(struct net_device *dev);
/* utility routines */ extern int orinoco_proc_dev_init(struct net_device *dev);
struct net_device *alloc_orinocodev(int sizeof_card); extern void orinoco_proc_dev_cleanup(struct net_device *dev);
extern void orinoco_shutdown(struct orinoco_private *dev);
extern int orinoco_reset(struct orinoco_private *dev);
extern int orinoco_proc_dev_init(struct orinoco_private *dev);
extern void orinoco_proc_dev_cleanup(struct orinoco_private *priv);
extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs); extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
/********************************************************************/
/* Locking and synchronization functions */
/********************************************************************/
/* These functions *must* be inline or they will break horribly on
* SPARC, due to its weird semantics for save/restore flags. extern
* inline should prevent the kernel from linking or module from
* loading if they are not inlined. */
extern inline int orinoco_lock(struct orinoco_private *priv,
unsigned long *flags)
{
spin_lock_irqsave(&priv->lock, *flags);
if (priv->hw_unavailable) {
printk(KERN_DEBUG "orinoco_lock() called with hw_unavailable (dev=%p)\n",
priv->ndev);
spin_unlock_irqrestore(&priv->lock, *flags);
return -EBUSY;
}
return 0;
}
extern inline void orinoco_unlock(struct orinoco_private *priv,
unsigned long *flags)
{
spin_unlock_irqrestore(&priv->lock, *flags);
}
#endif /* _ORINOCO_H */ #endif /* _ORINOCO_H */
This diff is collapsed.
/* orinoco_plx.c 0.11b /* orinoco_plx.c 0.13
* *
* Driver for Prism II devices which would usually be driven by orinoco_cs, * Driver for Prism II devices which would usually be driven by orinoco_cs,
* but are connected to the PCI bus by a PLX9052. * but are connected to the PCI bus by a PLX9052.
...@@ -134,13 +134,6 @@ not have time for a while.. ...@@ -134,13 +134,6 @@ not have time for a while..
#include "hermes.h" #include "hermes.h"
#include "orinoco.h" #include "orinoco.h"
static char version[] __initdata = "orinoco_plx.c 0.11b (Daniel Barlow <dan@telent.net>)";
MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual MPL/GPL");
#endif
static char dev_info[] = "orinoco_plx"; static char dev_info[] = "orinoco_plx";
#define COR_OFFSET (0x3e0 / 2) /* COR attribute offset of Prism2 PC card */ #define COR_OFFSET (0x3e0 / 2) /* COR attribute offset of Prism2 PC card */
...@@ -149,37 +142,6 @@ static char dev_info[] = "orinoco_plx"; ...@@ -149,37 +142,6 @@ static char dev_info[] = "orinoco_plx";
#define PLX_INTCSR 0x4c /* Interrupt Control and Status Register */ #define PLX_INTCSR 0x4c /* Interrupt Control and Status Register */
#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */ #define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
static int orinoco_plx_open(struct net_device *dev)
{
struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
int err;
netif_device_attach(dev);
err = orinoco_reset(priv);
if (err)
printk(KERN_ERR "%s: orinoco_reset failed in orinoco_plx_open()",
dev->name);
else
netif_start_queue(dev);
return err;
}
static int orinoco_plx_stop(struct net_device *dev)
{
struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
netif_stop_queue(dev);
orinoco_shutdown(priv);
return 0;
}
static void
orinoco_plx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
orinoco_interrupt(irq, (struct orinoco_private *)dev_id, regs);
}
static const u16 cis_magic[] = { static const u16 cis_magic[] = {
0x0001, 0x0003, 0x0000, 0x0000, 0x00ff, 0x0017, 0x0004, 0x0067 0x0001, 0x0003, 0x0000, 0x0000, 0x00ff, 0x0017, 0x0004, 0x0067
}; };
...@@ -197,8 +159,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, ...@@ -197,8 +159,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
int netdev_registered = 0; int netdev_registered = 0;
int i; int i;
TRACE_ENTER("orinoco_plx");
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
if (err) if (err)
return -EIO; return -EIO;
...@@ -266,7 +226,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, ...@@ -266,7 +226,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
goto fail; goto fail;
} }
dev = alloc_orinocodev(0); dev = alloc_orinocodev(0, NULL);
if (! dev) { if (! dev) {
err = -ENOMEM; err = -ENOMEM;
goto fail; goto fail;
...@@ -274,8 +234,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, ...@@ -274,8 +234,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
priv = dev->priv; priv = dev->priv;
dev->base_addr = pccard_ioaddr; dev->base_addr = pccard_ioaddr;
dev->open = orinoco_plx_open;
dev->stop = orinoco_plx_stop;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
printk(KERN_DEBUG printk(KERN_DEBUG
...@@ -286,7 +244,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, ...@@ -286,7 +244,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
HERMES_IO, HERMES_16BIT_REGSPACING); HERMES_IO, HERMES_16BIT_REGSPACING);
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
err = request_irq(pdev->irq, orinoco_plx_interrupt, SA_SHIRQ, dev->name, priv); err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv);
if (err) { if (err) {
printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq); printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq);
err = -EBUSY; err = -EBUSY;
...@@ -299,19 +257,17 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, ...@@ -299,19 +257,17 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
goto fail; goto fail;
netdev_registered = 1; netdev_registered = 1;
err = orinoco_proc_dev_init(priv); err = orinoco_proc_dev_init(dev);
if (err) if (err)
goto fail; goto fail;
TRACE_EXIT("orinoco_plx");
return 0; /* succeeded */ return 0; /* succeeded */
fail: fail:
printk(KERN_DEBUG "orinoco_plx: init_one(), FAIL!\n"); printk(KERN_DEBUG "orinoco_plx: init_one(), FAIL!\n");
if (priv) { if (priv) {
orinoco_proc_dev_cleanup(priv); orinoco_proc_dev_cleanup(dev);
if (netdev_registered) if (netdev_registered)
unregister_netdev(dev); unregister_netdev(dev);
...@@ -330,8 +286,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, ...@@ -330,8 +286,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
pci_disable_device(pdev); pci_disable_device(pdev);
TRACE_EXIT("orinoco_plx");
return err; return err;
} }
...@@ -340,12 +294,10 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) ...@@ -340,12 +294,10 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = dev->priv; struct orinoco_private *priv = dev->priv;
TRACE_ENTER("orinoco_plx");
if (! dev) if (! dev)
BUG(); BUG();
orinoco_proc_dev_cleanup(priv); orinoco_proc_dev_cleanup(dev);
unregister_netdev(dev); unregister_netdev(dev);
...@@ -357,13 +309,10 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) ...@@ -357,13 +309,10 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3)); release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
pci_disable_device(pdev); pci_disable_device(pdev);
TRACE_EXIT("orinoco_plx");
} }
static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = { static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
{0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,}, /* 3ComAirConnect */
{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */ {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */
{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */ {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */
{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */ {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */
...@@ -376,7 +325,8 @@ static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = { ...@@ -376,7 +325,8 @@ static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
{0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,}, /* USR 2415 */ {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,}, /* USR 2415 */
{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, /* Belkin F5D6000 tested by {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, /* Belkin F5D6000 tested by
Brendan W. McAdams <rit@jacked-in.org> */ Brendan W. McAdams <rit@jacked-in.org> */
{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,}, /* Nortel emobility */ {0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,}, /* 3Com AirConnect PCI tested by
Damien Persohn <damien@persohn.net> */
{0,}, {0,},
}; };
...@@ -387,8 +337,17 @@ static struct pci_driver orinoco_plx_driver = { ...@@ -387,8 +337,17 @@ static struct pci_driver orinoco_plx_driver = {
.id_table = orinoco_plx_pci_id_table, .id_table = orinoco_plx_pci_id_table,
.probe = orinoco_plx_init_one, .probe = orinoco_plx_init_one,
.remove = __devexit_p(orinoco_plx_remove_one), .remove = __devexit_p(orinoco_plx_remove_one),
.suspend = 0,
.resume = 0,
}; };
static char version[] __initdata = "orinoco_plx.c 0.13 (Daniel Barlow <dan@telent.net>, David Gibson <hermes@gibson.dropbear.id.au>)";
MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
#ifdef MODULE_LICENSE
MODULE_LICENSE("Dual MPL/GPL");
#endif
static int __init orinoco_plx_init(void) static int __init orinoco_plx_init(void)
{ {
printk(KERN_DEBUG "%s\n", version); printk(KERN_DEBUG "%s\n", version);
......
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kmod.h> /* for hotplug_path */ #include "pci.h"
#ifndef FALSE
#define FALSE (0)
#define TRUE (!FALSE)
#endif
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
static void run_sbin_hotplug(struct pci_dev *pdev, int insert) int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{ {
int i; struct pci_dev *pdev;
char *argv[3], *envp[8]; char *scratch;
char id[20], sub_id[24], bus_id[24], class_id[20]; int i = 0;
int length = 0;
if (!hotplug_path[0])
return; if (!dev)
return -ENODEV;
sprintf(class_id, "PCI_CLASS=%04X", pdev->class);
sprintf(id, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device); pdev = to_pci_dev(dev);
sprintf(sub_id, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, pdev->subsystem_device); if (!pdev)
sprintf(bus_id, "PCI_SLOT_NAME=%s", pdev->slot_name); return -ENODEV;
i = 0; scratch = buffer;
argv[i++] = hotplug_path;
argv[i++] = "pci"; /* stuff we want to pass to /sbin/hotplug */
argv[i] = 0; envp[i++] = scratch;
length += snprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
i = 0; pdev->class);
/* minimal command environment */ if ((buffer_size - length <= 0) || (i >= num_envp))
envp[i++] = "HOME=/"; return -ENOMEM;
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; ++length;
scratch += length;
/* other stuff we want to pass to /sbin/hotplug */
envp[i++] = class_id; envp[i++] = scratch;
envp[i++] = id; length += snprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
envp[i++] = sub_id; pdev->vendor, pdev->device);
envp[i++] = bus_id; if ((buffer_size - length <= 0) || (i >= num_envp))
if (insert) return -ENOMEM;
envp[i++] = "ACTION=add"; ++length;
else scratch += length;
envp[i++] = "ACTION=remove";
envp[i++] = scratch;
length += snprintf (scratch, buffer_size - length,
"PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
pdev->subsystem_device);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
envp[i++] = scratch;
length += snprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
pdev->slot_name);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
envp[i] = 0; envp[i] = 0;
call_usermodehelper (argv [0], argv, envp); return 0;
} }
#else #else
static void run_sbin_hotplug(struct pci_dev *pdev, int insert) { } int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
return -ENODEV;
}
#endif #endif
/** /**
...@@ -66,8 +82,6 @@ pci_insert_device(struct pci_dev *dev, struct pci_bus *bus) ...@@ -66,8 +82,6 @@ pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev); pci_proc_attach_device(dev);
#endif #endif
/* notify userspace of new hotplug device */
run_sbin_hotplug(dev, TRUE);
} }
static void static void
...@@ -99,8 +113,6 @@ pci_remove_device(struct pci_dev *dev) ...@@ -99,8 +113,6 @@ pci_remove_device(struct pci_dev *dev)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev); pci_proc_detach_device(dev);
#endif #endif
/* notify userspace of hotplug device removal */
run_sbin_hotplug(dev, FALSE);
} }
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include "pci.h"
/* /*
* Registration of PCI drivers and handling of hot-pluggable devices. * Registration of PCI drivers and handling of hot-pluggable devices.
...@@ -199,8 +200,9 @@ static int pci_bus_match(struct device * dev, struct device_driver * drv) ...@@ -199,8 +200,9 @@ static int pci_bus_match(struct device * dev, struct device_driver * drv)
} }
struct bus_type pci_bus_type = { struct bus_type pci_bus_type = {
name: "pci", name: "pci",
match: pci_bus_match, match: pci_bus_match,
hotplug: pci_hotplug,
}; };
static int __init pci_driver_init(void) static int __init pci_driver_init(void)
......
/* Functions internal to the PCI core code */
extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size);
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "i82092aa.h" #include "i82092aa.h"
#include "i82365.h" #include "i82365.h"
MODULE_LICENSE("GPL");
/* PCI core routines */ /* PCI core routines */
static struct pci_device_id i82092aa_pci_ids[] = { static struct pci_device_id i82092aa_pci_ids[] = {
{ {
......
...@@ -1048,11 +1048,19 @@ int isapnp_cfg_begin(int csn, int logdev) ...@@ -1048,11 +1048,19 @@ int isapnp_cfg_begin(int csn, int logdev)
isapnp_wait(); isapnp_wait();
isapnp_key(); isapnp_key();
isapnp_wake(csn); isapnp_wake(csn);
#if 1 /* to avoid malfunction when the isapnptools package is used */ #if 1
isapnp_set_rdp(); /* to avoid malfunction when the isapnptools package is used */
udelay(1000); /* delay 1000us */ /* we must set RDP to our value again */
write_address(0x01); /* it is possible to set RDP only in the isolation phase */
udelay(1000); /* delay 1000us */ /* Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
isapnp_write_byte(0x02, 0x04); /* clear CSN of card */
mdelay(2); /* is this necessary? */
isapnp_wake(csn); /* bring card into sleep state */
isapnp_wake(0); /* bring card into isolation state */
isapnp_set_rdp(); /* reset the RDP port */
udelay(1000); /* delay 1000us */
isapnp_write_byte(0x06, csn); /* reset CSN to previous value */
udelay(250); /* is this necessary? */
#endif #endif
if (logdev >= 0) if (logdev >= 0)
isapnp_device(logdev); isapnp_device(logdev);
......
...@@ -510,57 +510,42 @@ static int usb_device_match (struct device *dev, struct device_driver *drv) ...@@ -510,57 +510,42 @@ static int usb_device_match (struct device *dev, struct device_driver *drv)
* cases, we know no other thread can recycle our address, since we must * cases, we know no other thread can recycle our address, since we must
* already have been serialized enough to prevent that. * already have been serialized enough to prevent that.
*/ */
static void call_policy (char *verb, struct usb_device *dev) static int usb_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{ {
char *argv [3], **envp, *buf, *scratch; struct usb_interface *intf;
int i = 0, value; struct usb_device *usb_dev;
char *scratch;
int i = 0;
int length = 0;
if (!hotplug_path [0]) dbg ("%s", __FUNCTION__);
return;
if (in_interrupt ()) {
dbg ("In_interrupt");
return;
}
if (!current->fs->root) {
/* statically linked USB is initted rather early */
dbg ("call_policy %s, num %d -- no FS yet", verb, dev->devnum);
return;
}
if (dev->devnum < 0) {
dbg ("device already deleted ??");
return;
}
if (!(envp = (char **) kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
dbg ("enomem");
return;
}
if (!(buf = kmalloc (256, GFP_KERNEL))) {
kfree (envp);
dbg ("enomem2");
return;
}
/* only one standardized param to hotplug command: type */ if (!dev)
argv [0] = hotplug_path; return -ENODEV;
argv [1] = "usb";
argv [2] = 0;
/* minimal command environment */ /* check for generic driver, we do not call do hotplug calls for it */
envp [i++] = "HOME=/"; if (dev->driver == &usb_generic_driver)
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; return -ENODEV;
#ifdef DEBUG intf = to_usb_interface(dev);
/* hint that policy agent should enter no-stdout debug mode */ if (!intf)
envp [i++] = "DEBUG=kernel"; return -ENODEV;
#endif
/* extensible set of named bus-specific parameters,
* supporting multiple driver selection algorithms.
*/
scratch = buf;
/* action: add, remove */ usb_dev = interface_to_usbdev (intf);
envp [i++] = scratch; if (!usb_dev)
scratch += sprintf (scratch, "ACTION=%s", verb) + 1; return -ENODEV;
if (usb_dev->devnum < 0) {
dbg ("device already deleted ??");
return -ENODEV;
}
if (!usb_dev->bus) {
dbg ("bus already removed?");
return -ENODEV;
}
scratch = buffer;
#ifdef CONFIG_USB_DEVICEFS #ifdef CONFIG_USB_DEVICEFS
/* If this is available, userspace programs can directly read /* If this is available, userspace programs can directly read
...@@ -569,27 +554,48 @@ static void call_policy (char *verb, struct usb_device *dev) ...@@ -569,27 +554,48 @@ static void call_policy (char *verb, struct usb_device *dev)
* *
* FIXME reduce hardwired intelligence here * FIXME reduce hardwired intelligence here
*/ */
envp [i++] = "DEVFS=/proc/bus/usb";
envp [i++] = scratch; envp [i++] = scratch;
scratch += sprintf (scratch, "DEVICE=/proc/bus/usb/%03d/%03d", length += snprintf (scratch, buffer_size - length,
dev->bus->busnum, dev->devnum) + 1; "%s", "DEVFS=/proc/bus/usb");
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
envp [i++] = scratch;
length += snprintf (scratch, buffer_size - length,
"DEVICE=/proc/bus/usb/%03d/%03d",
usb_dev->bus->busnum, usb_dev->devnum);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
#endif #endif
/* per-device configuration hacks are common */ /* per-device configuration hacks are common */
envp [i++] = scratch; envp [i++] = scratch;
scratch += sprintf (scratch, "PRODUCT=%x/%x/%x", length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x",
dev->descriptor.idVendor, usb_dev->descriptor.idVendor,
dev->descriptor.idProduct, usb_dev->descriptor.idProduct,
dev->descriptor.bcdDevice) + 1; usb_dev->descriptor.bcdDevice);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
/* class-based driver binding models */ /* class-based driver binding models */
envp [i++] = scratch; envp [i++] = scratch;
scratch += sprintf (scratch, "TYPE=%d/%d/%d", length += snprintf (scratch, buffer_size - length, "TYPE=%d/%d/%d",
dev->descriptor.bDeviceClass, usb_dev->descriptor.bDeviceClass,
dev->descriptor.bDeviceSubClass, usb_dev->descriptor.bDeviceSubClass,
dev->descriptor.bDeviceProtocol) + 1; usb_dev->descriptor.bDeviceProtocol);
if (dev->descriptor.bDeviceClass == 0) { if ((buffer_size - length <= 0) || (i >= num_envp))
int alt = dev->actconfig->interface [0].act_altsetting; return -ENOMEM;
++length;
scratch += length;
if (usb_dev->descriptor.bDeviceClass == 0) {
int alt = intf->act_altsetting;
/* a simple/common case: one config, one interface, one driver /* a simple/common case: one config, one interface, one driver
* with current altsetting being a reasonable setting. * with current altsetting being a reasonable setting.
...@@ -597,31 +603,29 @@ static void call_policy (char *verb, struct usb_device *dev) ...@@ -597,31 +603,29 @@ static void call_policy (char *verb, struct usb_device *dev)
* device-specific binding policies. * device-specific binding policies.
*/ */
envp [i++] = scratch; envp [i++] = scratch;
scratch += sprintf (scratch, "INTERFACE=%d/%d/%d", length += snprintf (scratch, buffer_size - length,
dev->actconfig->interface [0].altsetting [alt].bInterfaceClass, "INTERFACE=%d/%d/%d",
dev->actconfig->interface [0].altsetting [alt].bInterfaceSubClass, intf->altsetting[alt].bInterfaceClass,
dev->actconfig->interface [0].altsetting [alt].bInterfaceProtocol) intf->altsetting[alt].bInterfaceSubClass,
+ 1; intf->altsetting[alt].bInterfaceProtocol);
/* INTERFACE-0, INTERFACE-1, ... ? */ if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
} }
envp [i++] = 0; envp [i++] = 0;
/* assert: (scratch - buf) < sizeof buf */
/* NOTE: user mode daemons can call the agents too */ return 0;
dbg ("kusbd: %s %s %d", argv [0], verb, dev->devnum);
value = call_usermodehelper (argv [0], argv, envp);
kfree (buf);
kfree (envp);
if (value != 0)
dbg ("kusbd policy returned 0x%x", value);
} }
#else #else
static inline void static int usb_hotplug (struct device *dev, char **envp,
call_policy (char *verb, struct usb_device *dev) char *buffer, int buffer_size)
{ } {
return -ENODEV;
}
#endif /* CONFIG_HOTPLUG */ #endif /* CONFIG_HOTPLUG */
...@@ -894,9 +898,6 @@ void usb_disconnect(struct usb_device **pdev) ...@@ -894,9 +898,6 @@ void usb_disconnect(struct usb_device **pdev)
put_device(&dev->dev); put_device(&dev->dev);
} }
/* Let policy agent unload modules etc */
call_policy ("remove", dev);
/* Decrement the reference count, it'll auto free everything when */ /* Decrement the reference count, it'll auto free everything when */
/* it hits 0 which could very well be now */ /* it hits 0 which could very well be now */
usb_put_dev(dev); usb_put_dev(dev);
...@@ -1174,9 +1175,6 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1174,9 +1175,6 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
/* add a /proc/bus/usb entry */ /* add a /proc/bus/usb entry */
usbfs_add_device(dev); usbfs_add_device(dev);
/* userspace may load modules and/or configure further */
call_policy ("add", dev);
return 0; return 0;
} }
...@@ -1439,6 +1437,7 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, ...@@ -1439,6 +1437,7 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
struct bus_type usb_bus_type = { struct bus_type usb_bus_type = {
.name = "usb", .name = "usb",
.match = usb_device_match, .match = usb_device_match,
.hotplug = usb_hotplug,
}; };
/* /*
......
...@@ -788,7 +788,7 @@ int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -788,7 +788,7 @@ int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us)
/* only check card status if the map isn't allocated, ie no card seen yet /* only check card status if the map isn't allocated, ie no card seen yet
* or if it's been over half a second since we last accessed it * or if it's been over half a second since we last accessed it
*/ */
if (info->lba_to_pba == NULL || jiffies > (info->last_access + HZ/2)) { if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {
/* check to see if a card is fitted */ /* check to see if a card is fitted */
result = sddr55_status (us); result = sddr55_status (us);
......
...@@ -859,6 +859,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -859,6 +859,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* This must be called with scsi_lock(us->srb->host) held */ * This must be called with scsi_lock(us->srb->host) held */
void usb_stor_abort_transport(struct us_data *us) void usb_stor_abort_transport(struct us_data *us)
{ {
struct Scsi_Host *host;
int state = atomic_read(&us->sm_state); int state = atomic_read(&us->sm_state);
US_DEBUGP("usb_stor_abort_transport called\n"); US_DEBUGP("usb_stor_abort_transport called\n");
...@@ -870,7 +871,8 @@ void usb_stor_abort_transport(struct us_data *us) ...@@ -870,7 +871,8 @@ void usb_stor_abort_transport(struct us_data *us)
/* set state to abort and release the lock */ /* set state to abort and release the lock */
atomic_set(&us->sm_state, US_STATE_ABORTING); atomic_set(&us->sm_state, US_STATE_ABORTING);
scsi_unlock(us->srb->host); host = us->srb->host;
scsi_unlock(host);
/* If the state machine is blocked waiting for an URB or an IRQ, /* If the state machine is blocked waiting for an URB or an IRQ,
* let's wake it up */ * let's wake it up */
...@@ -892,8 +894,8 @@ void usb_stor_abort_transport(struct us_data *us) ...@@ -892,8 +894,8 @@ void usb_stor_abort_transport(struct us_data *us)
/* Wait for the aborted command to finish */ /* Wait for the aborted command to finish */
wait_for_completion(&us->notify); wait_for_completion(&us->notify);
/* Reacquire the lock */ /* Reacquire the lock: note that us->srb is now NULL */
scsi_lock(us->srb->host); scsi_lock(host);
} }
/* /*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -601,3 +601,4 @@ int test_clear_page_dirty(struct page *page) ...@@ -601,3 +601,4 @@ int test_clear_page_dirty(struct page *page)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(test_clear_page_dirty);
This diff is collapsed.
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