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]
P: Networking Team
M: netdev@oss.sgi.com
L: linux-net@vger.kernel.org
W: http://www.uk.linux.org/NetNews.html (2.0 only)
S: Maintained
NETWORKING [IPv4/IPv6]
......
VERSION = 2
PATCHLEVEL = 5
SUBLEVEL = 38
SUBLEVEL = 39
EXTRAVERSION =
# *DOCUMENTATION*
......@@ -173,6 +173,9 @@ noconfig_targets := xconfig menuconfig config oldconfig randconfig \
help tags TAGS sgmldocs psdocs pdfdocs htmldocs \
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/
# ---------------------------------------------------------------------------
......@@ -581,13 +584,13 @@ spec:
# will become invalid
rpm: clean spec
find . -name SCCS -prune -o -name BitKeeper -prune -o \
find . $(RCS_FIND_IGNORE) \
\( -size 0 -o -name .depend -o -name .hdepend \) \
-type f -print | xargs rm -f
set -e; \
cd $(TOPDIR)/.. ; \
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) ; \
cd $(TOPDIR) ; \
. scripts/mkversion > .version ; \
......@@ -717,7 +720,7 @@ include arch/$(ARCH)/Makefile
clean: archclean
@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 .\*.tmp -o -name .\*.d \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
......@@ -726,7 +729,7 @@ clean: archclean
mrproper: clean archmrproper
@echo 'Making mrproper'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
@find . $(RCS_FIND_IGNORE) \
\( -name .depend -o -name .\*.cmd \) \
-type f -print | xargs rm -f
@rm -f $(MRPROPER_FILES)
......@@ -736,7 +739,7 @@ mrproper: clean archmrproper
distclean: mrproper
@echo 'Making distclean'
@find . -name SCCS -prune -o -name BitKeeper -prune -o \
@find . $(RCS_FIND_IGNORE) \
\( -not -type d \) -and \
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
......@@ -747,18 +750,18 @@ distclean: mrproper
# ---------------------------------------------------------------------------
define all-sources
( find . \( -name SCCS -o -name BitKeeper -o -name include -o \
-name arch \) -prune \
-o -name '*.[chS]' -print; \
find arch/$(ARCH) \( -name SCCS -o -name BitKeeper \) -prune \
-o -name '*.[chS]' -print; \
find include \( -name SCCS -o -name BitKeeper -o -name config -o \
-name 'asm-*' \) -prune \
-o -name '*.[chS]' -print; \
find include/asm-$(ARCH) \( -name SCCS -o -name BitKeeper \) -prune \
( find . $(RCS_FIND_IGNORE) \
\( -name include -o -name arch \) -prune -o \
-name '*.[chS]' -print; \
find arch/$(ARCH) $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print; \
find include $(RCS_FIND_IGNORE) \
\( -name config -o -name 'asm-*' \) -prune -o \
-o -name '*.[chS]' -print; \
find include/asm-generic \( -name SCCS -o -name BitKeeper \) -prune \
-o -name '*.[chS]' -print )
find include/asm-$(ARCH) $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print; \
find include/asm-generic $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print )
endef
quiet_cmd_TAGS = MAKE $@
......@@ -825,17 +828,17 @@ sgmldocs psdocs pdfdocs htmldocs: scripts
# ---------------------------------------------------------------------------
checkconfig:
find * -name SCCS -prune -o -name BitKeeper -prune -o \
find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkconfig.pl
checkhelp:
find * -name SCCS -prune -o -name BitKeeper -prune -o \
find * $(RCS_FIND_IGNORE) \
-name [cC]onfig.in -print | sort \
| xargs $(PERL) -w scripts/checkhelp.pl
checkincludes:
find * -name SCCS -prune -o -name BitKeeper -prune -o \
find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkincludes.pl
......
......@@ -34,6 +34,7 @@ if [ "$CONFIG_X86" = "y" ]; then
define_bool CONFIG_ACPI_EC y
define_bool CONFIG_ACPI_POWER y
define_bool CONFIG_ACPI_PCI $CONFIG_PCI
define_bool CONFIG_ACPI_SLEEP $CONFIG_SOFTWARE_SUSPEND
define_bool CONFIG_ACPI_SYSTEM y
fi
fi
......
......@@ -55,7 +55,8 @@ static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
[ACPI_SPCR] = "SPCR",
[ACPI_SRAT] = "SRAT",
[ACPI_SSDT] = "SSDT",
[ACPI_SPMI] = "SPMI"
[ACPI_SPMI] = "SPMI",
[ACPI_HPET] = "HPET"
};
/* System Description Table (RSDT/XSDT) */
......@@ -320,7 +321,7 @@ acpi_table_parse_madt_family (
handler(entry);
}
entry = (acpi_table_entry_header *)
((unsigned long) entry += entry->length);
((unsigned long) entry + entry->length);
}
return count;
......
......@@ -6,6 +6,8 @@ obj-y := core.o sys.o interface.o power.o bus.o \
obj-y += fs/
obj-$(CONFIG_HOTPLUG) += hotplug.o
export-objs := core.o power.o sys.o bus.o driver.o \
class.o intf.o platform.o cpu.o
......
......@@ -50,3 +50,13 @@ extern void interface_remove(struct device_class *, struct device *);
extern int driver_attach(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)
if (platform_notify)
platform_notify(dev);
/* notify userspace of device entry */
dev_hotplug(dev, "add");
register_done:
if (error) {
spin_lock(&device_lock);
......@@ -255,6 +258,9 @@ void put_device(struct device * dev)
if (platform_notify_remove)
platform_notify_remove(dev);
/* notify userspace that this device is about to disappear */
dev_hotplug (dev, "remove");
device_detach(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)
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
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;
const int data_dir = bio_data_dir(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
*/
ret = elv_try_last_merge(q, req, bio);
if (ret != ELEVATOR_NO_MERGE)
ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) {
*insert = q->last_merge;
goto out;
}
/*
* 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)
BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
if (elv_rq_merge_ok(__rq, bio)) {
*req = __rq;
*insert = &__rq->queuelist;
ret = ELEVATOR_BACK_MERGE;
goto out;
}
}
/*
* scan list from back to find insertion point.
*/
entry = sort_list = &dd->sort_list[data_dir];
while ((entry = entry->prev) != sort_list) {
__rq = list_entry_rq(entry);
......@@ -177,8 +198,8 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
if (!(__rq->flags & REQ_CMD))
continue;
if (!*req && bio_rq_in_between(bio, __rq, sort_list))
*req = __rq;
if (!*insert && bio_rq_in_between(bio, __rq, sort_list))
*insert = &__rq->queuelist;
if (__rq->flags & REQ_BARRIER)
break;
......@@ -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) {
ret = elv_try_merge(__rq, bio);
if (ret != ELEVATOR_NO_MERGE) {
*req = __rq;
*insert = &__rq->queuelist;
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:
return ret;
}
......@@ -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)
{
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;
/*
* 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 {
struct list_head *nxt = rq->queuelist.next;
int this_rq_cost;
......
......@@ -136,8 +136,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
return ret;
}
inline int elv_try_last_merge(request_queue_t *q, struct request **req,
struct bio *bio)
inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
{
int ret = ELEVATOR_NO_MERGE;
......@@ -150,8 +149,8 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req,
if (!rq_mergeable(__rq))
q->last_merge = NULL;
else if ((ret = elv_try_merge(__rq, bio)))
*req = __rq;
else
ret = elv_try_merge(__rq, bio);
}
return ret;
......@@ -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.
*/
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 list_head *entry = &q->queue_head;
struct request *__rq;
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;
}
while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry);
......@@ -182,7 +183,7 @@ int elevator_noop_merge(request_queue_t *q, struct request **req,
continue;
if ((ret = elv_try_merge(__rq, bio))) {
*req = __rq;
*insert = &__rq->queuelist;
q->last_merge = &__rq->queuelist;
return ret;
}
......@@ -240,12 +241,12 @@ int elevator_global_init(void)
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;
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;
}
......
......@@ -1583,7 +1583,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
spin_lock_irq(q->queue_lock);
again:
req = NULL;
insert_here = NULL;
if (blk_queue_empty(q)) {
......@@ -1593,10 +1592,13 @@ static int __make_request(request_queue_t *q, struct bio *bio)
if (barrier)
goto get_rq;
el_ret = elv_merge(q, &req, bio);
el_ret = elv_merge(q, &insert_here, bio);
switch (el_ret) {
case ELEVATOR_BACK_MERGE:
req = list_entry_rq(insert_here);
BUG_ON(!rq_mergeable(req));
if (!q->back_merge_fn(q, req, bio)) {
insert_here = &req->queuelist;
break;
......@@ -1611,7 +1613,10 @@ static int __make_request(request_queue_t *q, struct bio *bio)
goto out;
case ELEVATOR_FRONT_MERGE:
req = list_entry_rq(insert_here);
BUG_ON(!rq_mergeable(req));
if (!q->front_merge_fn(q, req, bio)) {
insert_here = req->queuelist.prev;
break;
......@@ -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
*/
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;
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
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
......@@ -7,6 +12,9 @@ if [ "$CONFIG_AGP" != "n" ]; then
bool ' Generic SiS support' CONFIG_AGP_SIS
bool ' ALI chipset support' CONFIG_AGP_ALI
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
bool ' Intel 460GX support' CONFIG_AGP_I460
bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
......
......@@ -16,6 +16,7 @@ agpgart-$(CONFIG_AGP_ALI) += ali-agp.o
agpgart-$(CONFIG_AGP_SWORKS) += sworks-agp.o
agpgart-$(CONFIG_AGP_I460) += i460-agp.o
agpgart-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
agpgart-$(CONFIG_AGP_AMD_8151) += k8-agp.o
agpgart-objs := $(agpgart-y)
obj-$(CONFIG_AGP) += agpgart.o
......
......@@ -50,6 +50,9 @@ EXPORT_SYMBOL(agp_backend_release);
struct agp_bridge_data agp_bridge = { type: NOT_SUPPORTED };
static int agp_try_unsupported __initdata = 0;
int agp_memory_reserved;
__u32 *agp_gatt_table;
int agp_backend_acquire(void)
{
if (agp_bridge.type == NOT_SUPPORTED)
......@@ -243,7 +246,7 @@ static int agp_return_size(void)
/* 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;
int i;
......@@ -251,7 +254,7 @@ void agp_copy_info(agp_kern_info * info)
memset(info, 0, sizeof(agp_kern_info));
if (agp_bridge.type == NOT_SUPPORTED) {
info->chipset = agp_bridge.type;
return;
return -EIO;
}
info->version.major = agp_bridge.version->major;
info->version.minor = agp_bridge.version->minor;
......@@ -268,6 +271,7 @@ void agp_copy_info(agp_kern_info * info)
page_mask |= agp_bridge.mask_memory(page_mask, i);
info->page_mask = ~page_mask;
return 0;
}
/* End - Routine to copy over information structure */
......@@ -518,6 +522,7 @@ int agp_generic_create_gatt_table(void)
SetPageReserved(page);
agp_bridge.gatt_table_real = (unsigned long *) table;
agp_gatt_table = (void *)table;
CACHE_FLUSH();
agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
(PAGE_SIZE * (1 << page_order)));
......@@ -625,6 +630,9 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
break;
}
num_entries -= agp_memory_reserved/PAGE_SIZE;
if (num_entries < 0) num_entries = 0;
if (type != 0 || mem->type != 0) {
/* The generic routines know nothing of memory types */
return -EINVAL;
......@@ -824,6 +832,17 @@ static struct {
},
#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
{
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006,
......@@ -858,7 +877,6 @@ static struct {
.chipset_setup = amd_irongate_setup,
},
#endif /* CONFIG_AGP_AMD */
#ifdef CONFIG_AGP_INTEL
{
.device_id = PCI_DEVICE_ID_INTEL_82443LX_0,
......@@ -1632,7 +1650,7 @@ static struct pci_driver agp_pci_driver = {
.probe = agp_probe,
};
static int __init agp_init(void)
int __init agp_init(void)
{
int ret_val;
......@@ -1658,5 +1676,7 @@ static void __exit agp_cleanup(void)
}
}
#ifndef CONFIG_GART_IOMMU
module_init(agp_init);
module_exit(agp_cleanup);
#endif
......@@ -49,6 +49,7 @@ void agp_free_key(int key);
/* chipset specific init routines. */
int __init ali_generic_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 intel_i460_setup (struct pci_dev *pdev);
int __init intel_generic_setup (struct pci_dev *pdev);
......@@ -319,6 +320,22 @@ struct agp_bridge_data {
#define AMD_TLBFLUSH 0x0c /* 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 */
#define ALI_APBASE 0x10
#define ALI_AGPCTRL 0xb8
......
This diff is collapsed.
......@@ -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 */
#endif
extern void disable_early_printk(void);
/*
* redirect is the pseudo-tty that console output
* is redirected to if asked by TIOCCONS.
......@@ -2185,6 +2187,9 @@ void __init console_init(void)
* set up the console device so that later boot sequences can
* inform about problems etc..
*/
#ifdef CONFIG_EARLY_PRINTK
disable_early_printk();
#endif
#ifdef CONFIG_VT
con_init();
#endif
......
......@@ -36,14 +36,11 @@
* This driver has been tested SUCCESSFULLY with the following drivers :
* o usb-uhci-hcd (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 :
* 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,
* so we don't have to worry about that anymore.
* One common problem is the failure to set the address on the dongle,
......@@ -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 void irda_usb_disconnect(struct usb_device *dev, void *ptr);
static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
static void irda_usb_disconnect(struct usb_interface *intf);
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_open(struct irda_usb_cb *self);
......@@ -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
*
......@@ -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
* 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;
int ret;
......@@ -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),
IU_REQ_GET_CLASS_DESC,
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);
if (ret < sizeof(*desc)) {
......@@ -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
* spinlock... Or not, because maybe USB already deal with that...
*/
static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id)
static int irda_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct irda_usb_cb *self = NULL;
struct usb_interface_descriptor *interface;
struct irda_class_desc *irda_desc;
......@@ -1430,7 +1430,7 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
(irda->present == 0) &&
(irda->netopen == 0)) {
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,
if(self == NULL) {
WARNING("Too many USB IrDA devices !!! (max = %d)\n",
NIRUSB);
return NULL;
return -ENFILE;
}
/* Reset the instance */
......@@ -1459,35 +1459,35 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
int j;
for (j = 0; j < i; j++)
usb_free_urb(self->rx_urb[j]);
return NULL;
return -ENOMEM;
}
}
self->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!self->tx_urb) {
for (i = 0; i < IU_MAX_RX_URBS; i++)
usb_free_urb(self->rx_urb[i]);
return NULL;
return -ENOMEM;
}
self->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!self->speed_urb) {
for (i = 0; i < IU_MAX_RX_URBS; i++)
usb_free_urb(self->rx_urb[i]);
usb_free_urb(self->tx_urb);
return NULL;
return -ENOMEM;
}
/* Is this really necessary? */
if (usb_set_configuration (dev, dev->config[0].bConfigurationValue) < 0) {
err("set_configuration failed");
return NULL;
return -EIO;
}
/* Is this really necessary? */
/* Note : some driver do hardcode the interface number, some others
* specify an alternate, but very few driver do like this.
* Jean II */
ret = usb_set_interface(dev, ifnum, 0);
IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret);
ret = usb_set_interface(dev, intf->altsetting->bInterfaceNumber, 0);
IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->bInterfaceNumber, ret);
switch (ret) {
case 0:
break;
......@@ -1497,33 +1497,35 @@ static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
break;
default:
IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret);
return NULL;
return -EIO;
break;
}
/* Find our endpoints */
interface = &dev->actconfig->interface[ifnum].altsetting[0];
interface = &intf->altsetting[0];
if(!irda_usb_parse_endpoints(self, interface->endpoint,
interface->bNumEndpoints)) {
ERROR("%s(), Bogus endpoints...\n", __FUNCTION__);
return NULL;
return -EIO;
}
/* 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)
return NULL;
return -ENODEV;
self->irda_desc = irda_desc;
self->present = 1;
self->netopen = 0;
self->capability = id->driver_info;
self->usbdev = dev;
self->usbintf = intf;
ret = irda_usb_open(self);
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,
* So, we must make bloody sure that everything gets deactivated.
* 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;
struct irda_usb_cb *self = (struct irda_usb_cb *) ptr;
struct irda_usb_cb *self = dev_get_drvdata (&intf->dev);
int i;
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 */
spin_lock_irqsave(&self->lock, flags);
......@@ -1577,6 +1583,7 @@ static void irda_usb_disconnect(struct usb_device *dev, void *ptr)
irda_usb_close(self);
/* No longer attached to USB bus */
self->usbdev = NULL;
self->usbintf = NULL;
/* Clean up our urbs */
for (i = 0; i < IU_MAX_RX_URBS; i++)
......@@ -1635,7 +1642,7 @@ void __exit usb_irda_cleanup(void)
/* If the Device is zombie */
if((irda->usbdev != NULL) && (irda->present == 0)) {
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
* card.
......@@ -30,7 +30,6 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <linux/list.h>
#include <linux/adb.h>
#include <linux/pmu.h>
......@@ -39,22 +38,15 @@
#include <asm/pmac_feature.h>
#include <asm/irq.h>
#include "hermes.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 */
struct airport {
struct device_node* node;
struct device_node *node;
void *vaddr;
int irq_requested;
int ndev_registered;
int open;
};
#ifdef CONFIG_PMAC_PBOOK
......@@ -70,101 +62,77 @@ static struct pmu_sleep_notifier airport_sleep_notifier = {
static struct net_device *airport_attach(struct device_node *of_node);
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 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
static int
airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
struct net_device *dev = airport_dev;
struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
struct hermes *hw = &priv->hw;
struct airport* card = (struct airport *)priv->card;
int rc;
struct orinoco_private *priv = dev->priv;
struct airport *card = priv->card;
unsigned long flags;
int err;
if (! airport_dev)
return PBOOK_SLEEP_OK;
switch (when) {
case PBOOK_SLEEP_REQUEST:
break;
case PBOOK_SLEEP_REJECT:
break;
case PBOOK_SLEEP_NOW:
printk(KERN_INFO "%s: Airport entering sleep mode\n", dev->name);
if (card->open) {
netif_stop_queue(dev);
orinoco_shutdown(priv);
netif_device_detach(dev);
printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name);
err = orinoco_lock(priv, &flags);
if (err) {
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);
pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
break;
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);
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);
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;
}
return PBOOK_SLEEP_OK;
......@@ -172,7 +140,7 @@ airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
#endif /* CONFIG_PMAC_PBOOK */
static struct net_device *
airport_attach(struct device_node* of_node)
airport_attach(struct device_node *of_node)
{
struct orinoco_private *priv;
struct net_device *dev;
......@@ -180,15 +148,13 @@ airport_attach(struct device_node* of_node)
unsigned long phys_addr;
hermes_t *hw;
TRACE_ENTER("orinoco");
if (of_node->n_addrs < 1 || of_node->n_intrs < 1) {
printk(KERN_ERR "airport: wrong interrupt/addresses in OF tree\n");
return NULL;
}
/* Allocate space for private device-specific data */
dev = alloc_orinocodev(sizeof(*card));
dev = alloc_orinocodev(sizeof(*card), NULL);
if (! dev) {
printk(KERN_ERR "airport: can't allocate device datas\n");
return NULL;
......@@ -204,17 +170,14 @@ airport_attach(struct device_node* of_node)
kfree(dev);
return NULL;
}
dev->name[0] = '\0'; /* register_netdev will give us an ethX name */
SET_MODULE_OWNER(dev);
/* Overrides */
dev->open = airport_open;
dev->stop = airport_stop;
/* Setup interrupts & base address */
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;
card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
if (! card->vaddr) {
......@@ -231,14 +194,14 @@ airport_attach(struct device_node* of_node)
schedule_timeout(HZ);
/* Reset it before we get the interrupt */
hermes_reset(hw);
hermes_init(hw);
if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
goto failed;
}
card->irq_requested = 1;
/* Tell the stack we exist */
if (register_netdev(dev) != 0) {
printk(KERN_ERR "airport: register_netdev() failed\n");
......@@ -248,7 +211,7 @@ airport_attach(struct device_node* of_node)
card->ndev_registered = 1;
/* 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",
dev->name);
......@@ -257,7 +220,7 @@ airport_attach(struct device_node* of_node)
#endif
return dev;
failed:
failed:
airport_detach(dev);
return NULL;
} /* airport_attach */
......@@ -273,7 +236,7 @@ airport_detach(struct net_device *dev)
struct airport *card = priv->card;
/* Unregister proc entry */
orinoco_proc_dev_cleanup(priv);
orinoco_proc_dev_cleanup(dev);
#ifdef CONFIG_PMAC_PBOOK
pmu_unregister_sleep_notifier(&airport_sleep_notifier);
......@@ -281,7 +244,7 @@ airport_detach(struct net_device *dev)
if (card->ndev_registered)
unregister_netdev(dev);
card->ndev_registered = 0;
if (card->irq_requested)
free_irq(dev->irq, priv);
card->irq_requested = 0;
......@@ -289,22 +252,28 @@ airport_detach(struct net_device *dev)
if (card->vaddr)
iounmap(card->vaddr);
card->vaddr = 0;
dev->base_addr = 0;
release_OF_resource(card->node, 0);
pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 0);
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(HZ);
kfree(dev);
} /* 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
init_airport(void)
{
struct device_node* airport_node;
struct device_node *airport_node;
printk(KERN_DEBUG "%s\n", version);
......
......@@ -45,7 +45,6 @@
#include <linux/threads.h>
#include <linux/smp.h>
#include <asm/io.h>
#include <linux/ptrace.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
......@@ -53,7 +52,7 @@
#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_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
#ifdef MODULE_LICENSE
......@@ -70,14 +69,14 @@ MODULE_LICENSE("Dual MPL/GPL");
* 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
#ifdef HERMES_DEBUG
#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)
#else /* ! HERMES_DEBUG */
......@@ -86,7 +85,6 @@ MODULE_LICENSE("Dual MPL/GPL");
#endif /* ! HERMES_DEBUG */
#define IO_TYPE(hw) ((hw)->io_space ? "IO " : "MEM ")
/*
* Internal functions
......@@ -111,7 +109,6 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
udelay(1);
reg = hermes_read_regn(hw, CMD);
}
DEBUG(3, "hermes_issue_cmd: did %d retries.\n", CMD_BUSY_TIMEOUT-k);
if (reg & HERMES_CMD_BUSY) {
return -EBUSY;
}
......@@ -143,7 +140,7 @@ void hermes_struct_init(hermes_t *hw, ulong address,
#endif
}
int hermes_reset(hermes_t *hw)
int hermes_init(hermes_t *hw)
{
u16 status, reg;
int err = 0;
......@@ -195,8 +192,6 @@ int hermes_reset(hermes_t *hw)
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);
if (! hermes_present(hw)) {
......@@ -303,9 +298,6 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
if (err) {
printk(KERN_WARNING "hermes @ %s0x%lx: "
"Frame allocation command failed (0x%X).\n",
IO_TYPE(hw), hw->iobase, err);
return err;
}
......@@ -393,12 +385,10 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
}
if (reg & HERMES_OFFSET_BUSY) {
DEBUG(1,"hermes_bap_seek: timeout\n");
return -ETIMEDOUT;
}
if (reg & HERMES_OFFSET_ERR) {
DEBUG(1,"hermes_bap_seek: BAP error\n");
return -EIO;
}
......@@ -472,6 +462,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
int err = 0;
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
u16 rlength, rtype;
int nwords;
if ( (bufsize < 0) || (bufsize % 2) )
return -EINVAL;
......@@ -500,10 +491,9 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
"(rid=0x%04x, len=0x%04x)\n",
IO_TYPE(hw), hw->iobase,
HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
/* FIXME: we should read the min of the requested length and
the actual record length */
hermes_read_words(hw, dreg, buf, bufsize / 2);
nwords = min_t(int, rlength - 1, bufsize / 2);
hermes_read_words(hw, dreg, buf, nwords);
out:
return err;
......@@ -516,9 +506,6 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
int err = 0;
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);
if (err)
goto out;
......@@ -538,7 +525,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
}
EXPORT_SYMBOL(hermes_struct_init);
EXPORT_SYMBOL(hermes_reset);
EXPORT_SYMBOL(hermes_init);
EXPORT_SYMBOL(hermes_docmd_wait);
EXPORT_SYMBOL(hermes_allocate);
......
......@@ -171,6 +171,7 @@ struct hermes_rx_descriptor {
#define HERMES_RXSTAT_BADCRC (0x0001)
#define HERMES_RXSTAT_UNDECRYPTABLE (0x0002)
#define HERMES_RXSTAT_MACPORT (0x0700)
#define HERMES_RXSTAT_PCF (0x1000) /* Frame was received in CF period */
#define HERMES_RXSTAT_MSGTYPE (0xE000)
#define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */
#define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel encoded frame */
......@@ -299,7 +300,7 @@ typedef struct hermes_response {
/* Function prototypes */
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_allocate(hermes_t *hw, u16 size, u16 *fid);
......@@ -319,12 +320,6 @@ static inline int hermes_present(hermes_t *hw)
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)
{
hw->inten = events;
......@@ -350,7 +345,7 @@ static inline int hermes_inquire(hermes_t *hw, u16 rid)
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 )
/* Note that for the next two, the count is in 16-bit words, not bytes */
......
......@@ -3,8 +3,8 @@
#define IEEE802_11_DATA_LEN 2304
/* 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
figure in section 7.1.2 says 2312 octects. */
maximum frame size really is. Section 6.2.1.1.2 says 2304 octets,
but the figure in Section 7.1.2 says 2312 octects. */
#define IEEE802_11_HLEN 30
#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
......
This diff is collapsed.
......@@ -7,6 +7,8 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H
#include "hermes.h"
/* To enable debug messages */
//#define ORINOCO_DEBUG 3
......@@ -18,24 +20,26 @@
#define ORINOCO_MAX_KEY_SIZE 14
#define ORINOCO_MAX_KEYS 4
typedef struct orinoco_key {
u16 len; /* always store little-endian */
struct orinoco_key {
u16 len; /* always stored as little-endian */
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 {
void *card; /* Pointer to card dependant structure */
/* card dependant extra reset code (i.e. bus/interface specific */
int (*hard_reset)(struct orinoco_private *);
/* Synchronisation stuff */
spinlock_t lock;
long state;
#define ORINOCO_STATE_INIRQ 0
#define ORINOCO_STATE_DOIRQ 1
int hw_unavailable;
struct tq_struct timeout_task;
int open;
/* Net device stuff */
struct net_device *ndev;
......@@ -58,14 +62,13 @@ struct orinoco_private {
int has_preamble;
int has_sensitivity;
int nicbuf_size;
int broken_cor_reset;
u16 channel_mask;
/* Configuration paramaters */
u32 iw_mode;
int prefer_port3;
u16 wep_on, wep_restrict, tx_key;
orinoco_keys_t keys;
struct orinoco_key keys[ORINOCO_MAX_KEYS];
int bitratemode;
char nick[IW_ESSID_MAX_SIZE+1];
char desired_essid[IW_ESSID_MAX_SIZE+1];
......@@ -81,38 +84,58 @@ struct orinoco_private {
#endif
/* Configuration dependent variables */
int port_type, allow_ibss;
int port_type, createibss;
int promiscuous, mc_count;
/* /proc based debugging stuff */
struct proc_dir_entry *dir_dev;
};
/*====================================================================*/
extern struct list_head orinoco_instances;
#ifdef ORINOCO_DEBUG
extern int orinoco_debug;
#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
#define DEBUG(n, args...) do { } while (0)
#define DEBUGMORE(n, args...) do { } while (0)
#endif /* ORINOCO_DEBUG */
#define TRACE_ENTER(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 */
struct net_device *alloc_orinocodev(int sizeof_card);
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 int orinoco_proc_dev_init(struct net_device *dev);
extern void orinoco_proc_dev_cleanup(struct net_device *dev);
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 */
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,
* but are connected to the PCI bus by a PLX9052.
......@@ -134,13 +134,6 @@ not have time for a while..
#include "hermes.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";
#define COR_OFFSET (0x3e0 / 2) /* COR attribute offset of Prism2 PC card */
......@@ -149,37 +142,6 @@ static char dev_info[] = "orinoco_plx";
#define PLX_INTCSR 0x4c /* Interrupt Control and Status Register */
#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[] = {
0x0001, 0x0003, 0x0000, 0x0000, 0x00ff, 0x0017, 0x0004, 0x0067
};
......@@ -197,8 +159,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
int netdev_registered = 0;
int i;
TRACE_ENTER("orinoco_plx");
err = pci_enable_device(pdev);
if (err)
return -EIO;
......@@ -266,7 +226,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
goto fail;
}
dev = alloc_orinocodev(0);
dev = alloc_orinocodev(0, NULL);
if (! dev) {
err = -ENOMEM;
goto fail;
......@@ -274,8 +234,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
priv = dev->priv;
dev->base_addr = pccard_ioaddr;
dev->open = orinoco_plx_open;
dev->stop = orinoco_plx_stop;
SET_MODULE_OWNER(dev);
printk(KERN_DEBUG
......@@ -286,7 +244,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
HERMES_IO, HERMES_16BIT_REGSPACING);
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) {
printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq);
err = -EBUSY;
......@@ -299,19 +257,17 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
goto fail;
netdev_registered = 1;
err = orinoco_proc_dev_init(priv);
err = orinoco_proc_dev_init(dev);
if (err)
goto fail;
TRACE_EXIT("orinoco_plx");
return 0; /* succeeded */
fail:
printk(KERN_DEBUG "orinoco_plx: init_one(), FAIL!\n");
if (priv) {
orinoco_proc_dev_cleanup(priv);
orinoco_proc_dev_cleanup(dev);
if (netdev_registered)
unregister_netdev(dev);
......@@ -330,8 +286,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
pci_disable_device(pdev);
TRACE_EXIT("orinoco_plx");
return err;
}
......@@ -340,12 +294,10 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = dev->priv;
TRACE_ENTER("orinoco_plx");
if (! dev)
BUG();
orinoco_proc_dev_cleanup(priv);
orinoco_proc_dev_cleanup(dev);
unregister_netdev(dev);
......@@ -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));
pci_disable_device(pdev);
TRACE_EXIT("orinoco_plx");
}
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 */
{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */
{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 = {
{0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,}, /* USR 2415 */
{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, /* Belkin F5D6000 tested by
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,},
};
......@@ -387,8 +337,17 @@ static struct pci_driver orinoco_plx_driver = {
.id_table = orinoco_plx_pci_id_table,
.probe = orinoco_plx_init_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)
{
printk(KERN_DEBUG "%s\n", version);
......
#include <linux/pci.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
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;
char *argv[3], *envp[8];
char id[20], sub_id[24], bus_id[24], class_id[20];
if (!hotplug_path[0])
return;
sprintf(class_id, "PCI_CLASS=%04X", pdev->class);
sprintf(id, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device);
sprintf(sub_id, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor, pdev->subsystem_device);
sprintf(bus_id, "PCI_SLOT_NAME=%s", pdev->slot_name);
i = 0;
argv[i++] = hotplug_path;
argv[i++] = "pci";
argv[i] = 0;
i = 0;
/* minimal command environment */
envp[i++] = "HOME=/";
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
/* other stuff we want to pass to /sbin/hotplug */
envp[i++] = class_id;
envp[i++] = id;
envp[i++] = sub_id;
envp[i++] = bus_id;
if (insert)
envp[i++] = "ACTION=add";
else
envp[i++] = "ACTION=remove";
struct pci_dev *pdev;
char *scratch;
int i = 0;
int length = 0;
if (!dev)
return -ENODEV;
pdev = to_pci_dev(dev);
if (!pdev)
return -ENODEV;
scratch = buffer;
/* stuff we want to pass to /sbin/hotplug */
envp[i++] = scratch;
length += snprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
pdev->class);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
envp[i++] = scratch;
length += snprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
pdev->vendor, pdev->device);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
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;
call_usermodehelper (argv [0], argv, envp);
return 0;
}
#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
/**
......@@ -66,8 +82,6 @@ pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
#ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev);
#endif
/* notify userspace of new hotplug device */
run_sbin_hotplug(dev, TRUE);
}
static void
......@@ -99,8 +113,6 @@ pci_remove_device(struct pci_dev *dev)
#ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev);
#endif
/* notify userspace of hotplug device removal */
run_sbin_hotplug(dev, FALSE);
}
#ifdef CONFIG_HOTPLUG
......
......@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/init.h>
#include "pci.h"
/*
* 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)
}
struct bus_type pci_bus_type = {
name: "pci",
match: pci_bus_match,
name: "pci",
match: pci_bus_match,
hotplug: pci_hotplug,
};
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 @@
#include "i82092aa.h"
#include "i82365.h"
MODULE_LICENSE("GPL");
/* PCI core routines */
static struct pci_device_id i82092aa_pci_ids[] = {
{
......
......@@ -1048,11 +1048,19 @@ int isapnp_cfg_begin(int csn, int logdev)
isapnp_wait();
isapnp_key();
isapnp_wake(csn);
#if 1 /* to avoid malfunction when the isapnptools package is used */
isapnp_set_rdp();
udelay(1000); /* delay 1000us */
write_address(0x01);
udelay(1000); /* delay 1000us */
#if 1
/* to avoid malfunction when the isapnptools package is used */
/* we must set RDP to our value again */
/* it is possible to set RDP only in the isolation phase */
/* 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
if (logdev >= 0)
isapnp_device(logdev);
......
......@@ -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
* 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;
int i = 0, value;
struct usb_interface *intf;
struct usb_device *usb_dev;
char *scratch;
int i = 0;
int length = 0;
if (!hotplug_path [0])
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;
}
dbg ("%s", __FUNCTION__);
/* only one standardized param to hotplug command: type */
argv [0] = hotplug_path;
argv [1] = "usb";
argv [2] = 0;
if (!dev)
return -ENODEV;
/* minimal command environment */
envp [i++] = "HOME=/";
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
/* check for generic driver, we do not call do hotplug calls for it */
if (dev->driver == &usb_generic_driver)
return -ENODEV;
#ifdef DEBUG
/* hint that policy agent should enter no-stdout debug mode */
envp [i++] = "DEBUG=kernel";
#endif
/* extensible set of named bus-specific parameters,
* supporting multiple driver selection algorithms.
*/
scratch = buf;
intf = to_usb_interface(dev);
if (!intf)
return -ENODEV;
/* action: add, remove */
envp [i++] = scratch;
scratch += sprintf (scratch, "ACTION=%s", verb) + 1;
usb_dev = interface_to_usbdev (intf);
if (!usb_dev)
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
/* If this is available, userspace programs can directly read
......@@ -569,27 +554,48 @@ static void call_policy (char *verb, struct usb_device *dev)
*
* FIXME reduce hardwired intelligence here
*/
envp [i++] = "DEVFS=/proc/bus/usb";
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVICE=/proc/bus/usb/%03d/%03d",
dev->bus->busnum, dev->devnum) + 1;
length += snprintf (scratch, buffer_size - length,
"%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
/* per-device configuration hacks are common */
envp [i++] = scratch;
scratch += sprintf (scratch, "PRODUCT=%x/%x/%x",
dev->descriptor.idVendor,
dev->descriptor.idProduct,
dev->descriptor.bcdDevice) + 1;
length += snprintf (scratch, buffer_size - length, "PRODUCT=%x/%x/%x",
usb_dev->descriptor.idVendor,
usb_dev->descriptor.idProduct,
usb_dev->descriptor.bcdDevice);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
/* class-based driver binding models */
envp [i++] = scratch;
scratch += sprintf (scratch, "TYPE=%d/%d/%d",
dev->descriptor.bDeviceClass,
dev->descriptor.bDeviceSubClass,
dev->descriptor.bDeviceProtocol) + 1;
if (dev->descriptor.bDeviceClass == 0) {
int alt = dev->actconfig->interface [0].act_altsetting;
length += snprintf (scratch, buffer_size - length, "TYPE=%d/%d/%d",
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol);
if ((buffer_size - length <= 0) || (i >= num_envp))
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
* with current altsetting being a reasonable setting.
......@@ -597,31 +603,29 @@ static void call_policy (char *verb, struct usb_device *dev)
* device-specific binding policies.
*/
envp [i++] = scratch;
scratch += sprintf (scratch, "INTERFACE=%d/%d/%d",
dev->actconfig->interface [0].altsetting [alt].bInterfaceClass,
dev->actconfig->interface [0].altsetting [alt].bInterfaceSubClass,
dev->actconfig->interface [0].altsetting [alt].bInterfaceProtocol)
+ 1;
/* INTERFACE-0, INTERFACE-1, ... ? */
length += snprintf (scratch, buffer_size - length,
"INTERFACE=%d/%d/%d",
intf->altsetting[alt].bInterfaceClass,
intf->altsetting[alt].bInterfaceSubClass,
intf->altsetting[alt].bInterfaceProtocol);
if ((buffer_size - length <= 0) || (i >= num_envp))
return -ENOMEM;
++length;
scratch += length;
}
envp [i++] = 0;
/* assert: (scratch - buf) < sizeof buf */
/* NOTE: user mode daemons can call the agents too */
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);
return 0;
}
#else
static inline void
call_policy (char *verb, struct usb_device *dev)
{ }
static int usb_hotplug (struct device *dev, char **envp,
char *buffer, int buffer_size)
{
return -ENODEV;
}
#endif /* CONFIG_HOTPLUG */
......@@ -894,9 +898,6 @@ void usb_disconnect(struct usb_device **pdev)
put_device(&dev->dev);
}
/* Let policy agent unload modules etc */
call_policy ("remove", dev);
/* Decrement the reference count, it'll auto free everything when */
/* it hits 0 which could very well be now */
usb_put_dev(dev);
......@@ -1174,9 +1175,6 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
/* add a /proc/bus/usb entry */
usbfs_add_device(dev);
/* userspace may load modules and/or configure further */
call_policy ("add", dev);
return 0;
}
......@@ -1439,6 +1437,7 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.hotplug = usb_hotplug,
};
/*
......
......@@ -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
* 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 */
result = sddr55_status (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 */
void usb_stor_abort_transport(struct us_data *us)
{
struct Scsi_Host *host;
int state = atomic_read(&us->sm_state);
US_DEBUGP("usb_stor_abort_transport called\n");
......@@ -870,7 +871,8 @@ void usb_stor_abort_transport(struct us_data *us)
/* set state to abort and release the lock */
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,
* let's wake it up */
......@@ -892,8 +894,8 @@ void usb_stor_abort_transport(struct us_data *us)
/* Wait for the aborted command to finish */
wait_for_completion(&us->notify);
/* Reacquire the lock */
scsi_lock(us->srb->host);
/* Reacquire the lock: note that us->srb is now NULL */
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)
}
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