Commit 30ede89a authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/stuff/paulus/kernel/linux-2.5

into samba.org:/stuff/paulus/kernel/for-linus-ppc
parents 011109ec fbf47415
...@@ -2,7 +2,18 @@ The kobject Infrastructure ...@@ -2,7 +2,18 @@ The kobject Infrastructure
Patrick Mochel <mochel@osdl.org> Patrick Mochel <mochel@osdl.org>
7 January 2003 Updated: 3 June 2003
Copyright (c) Patrick Mochel
Copyright (c) Open Source Development Labs
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
0. Introduction 0. Introduction
...@@ -102,6 +113,28 @@ kobj_type::release() (which the kobject's kset points to) is called. ...@@ -102,6 +113,28 @@ kobj_type::release() (which the kobject's kset points to) is called.
This allows any memory allocated for the object to be freed. This allows any memory allocated for the object to be freed.
NOTE!!!
It is _imperative_ that you supply a desctructor for dynamically
allocated kobjects to free them if you are using kobject reference
counts. The reference count controls the duration of the lifetime of
the object. If it goes to 0, then it is assumed that the object will
be freed and cannot be used.
More importantly, you must free the object there, and not immediately
after an unregister call. If someone else is referencing the object
(e.g. through a sysfs file), they will obtain a reference to the
object, assume it's valid and operate on it. If the object is
unregistered and freed in the meantime, the operation will then
reference freed memory and go boom.
This can be prevented, in the simplest case, by defining a release
method and freeing the object from there only. Note that this will not
secure reference count/object management models that use a dual
reference count or do other wacky things with the reference count
(like the networking layer).
1.4 sysfs 1.4 sysfs
Each kobject receives a directory in sysfs. This directory is created Each kobject receives a directory in sysfs. This directory is created
......
...@@ -31,6 +31,11 @@ ipfrag_low_thresh - INTEGER ...@@ -31,6 +31,11 @@ ipfrag_low_thresh - INTEGER
ipfrag_time - INTEGER ipfrag_time - INTEGER
Time in seconds to keep an IP fragment in memory. Time in seconds to keep an IP fragment in memory.
ipfrag_secret_interval - INTEGER
Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IP fragments.
Default: 600
INET peer storage: INET peer storage:
inet_peer_threshold - INTEGER inet_peer_threshold - INTEGER
...@@ -515,6 +520,25 @@ bindv6only - BOOLEAN ...@@ -515,6 +520,25 @@ bindv6only - BOOLEAN
Default: FALSE (as specified in RFC2553bis) Default: FALSE (as specified in RFC2553bis)
IPv6 Fragmentation:
ip6frag_high_thresh - INTEGER
Maximum memory used to reassemble IPv6 fragments. When
ip6frag_high_thresh bytes of memory is allocated for this purpose,
the fragment handler will toss packets until ip6frag_low_thresh
is reached.
ip6frag_low_thresh - INTEGER
See ip6frag_high_thresh
ip6frag_time - INTEGER
Time in seconds to keep an IPv6 fragment in memory.
ip6frag_secret_interval - INTEGER
Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IPv6 fragments.
Default: 600
conf/default/*: conf/default/*:
Change the interface-specific default settings. Change the interface-specific default settings.
......
...@@ -36,13 +36,36 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) ...@@ -36,13 +36,36 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \ -e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ ) -e s/s390x/s390/ )
ARCH := $(SUBARCH)
# Remove hyphens since they have special meaning in RPM filenames # Remove hyphens since they have special meaning in RPM filenames
KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE)) KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
#
# When performing cross compilation for other architectures ARCH shall be set
# to the target architecture. (See arch/* for the possibilities).
# ARCH can be set during invocation of make:
# make ARCH=ia64
# Another way is to have ARCH set in the environment.
# The default ARCH is the host where make is executed.
# CROSS_COMPILE specify the prefix used for all executables used
# during compilation. Only gcc and related bin-utils executables
# are prefixed with $(CROSS_COMPILE).
# CROSS_COMPILE can be set on the command line
# make CROSS_COMPILE=ia64-linux-
# Alternatively CROSS_COMPILE can be set in the environment.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
# Architecture as present in compile.h
UTS_MACHINE := $(ARCH) UTS_MACHINE := $(ARCH)
# SHELL used by kbuild
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \ else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi) else echo sh; fi ; fi)
...@@ -53,7 +76,6 @@ HOSTCXX = g++ ...@@ -53,7 +76,6 @@ HOSTCXX = g++
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCXXFLAGS = -O2 HOSTCXXFLAGS = -O2
CROSS_COMPILE =
# That's our default target when none is given on the command line # That's our default target when none is given on the command line
# Note that 'modules' will be added as a prerequisite as well, # Note that 'modules' will be added as a prerequisite as well,
...@@ -783,25 +805,27 @@ rpm: clean spec ...@@ -783,25 +805,27 @@ rpm: clean spec
help: help:
@echo 'Cleaning targets:' @echo 'Cleaning targets:'
@echo ' clean - remove most generated files but keep the config' @echo ' clean - remove most generated files but keep the config'
@echo ' mrproper - remove all generated files + config + various backup files' @echo ' mrproper - remove all generated files + config + various backup files'
@echo '' @echo ''
@echo 'Configuration targets:' @echo 'Configuration targets:'
@echo ' oldconfig - Update current config utilising a line-oriented program' @echo ' oldconfig - Update current config utilising a line-oriented program'
@echo ' menuconfig - Update current config utilising a menu based program' @echo ' menuconfig - Update current config utilising a menu based program'
@echo ' xconfig - Update current config utilising a X-based program' @echo ' xconfig - Update current config utilising a QT based front-end'
@echo ' defconfig - New config with default answer to all options' @echo ' gconfig - Update current config utilising a GTK based front-end'
@echo ' allmodconfig - New config selecting modules when possible' @echo ' defconfig - New config with default answer to all options'
@echo ' allyesconfig - New config where all options are accepted with yes' @echo ' allmodconfig - New config selecting modules when possible'
@echo ' allnoconfig - New minimal config' @echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New minimal config'
@echo '' @echo ''
@echo 'Other generic targets:' @echo 'Other generic targets:'
@echo ' all - Build all targets marked with [*]' @echo ' all - Build all targets marked with [*]'
@echo '* vmlinux - Build the bare kernel' @echo '* vmlinux - Build the bare kernel'
@echo '* modules - Build all modules' @echo '* modules - Build all modules'
@echo ' dir/file.[ois]- Build specified target only' @echo ' modules_install - Install all modules'
@echo ' rpm - Build a kernel as an RPM package' @echo ' dir/file.[ois] - Build specified target only'
@echo ' tags/TAGS - Generate tags file for editors' @echo ' rpm - Build a kernel as an RPM package'
@echo ' tags/TAGS - Generate tags file for editors'
@echo '' @echo ''
@echo 'Documentation targets:' @echo 'Documentation targets:'
@$(MAKE) --no-print-directory -f Documentation/DocBook/Makefile dochelp @$(MAKE) --no-print-directory -f Documentation/DocBook/Makefile dochelp
...@@ -810,6 +834,9 @@ help: ...@@ -810,6 +834,9 @@ help:
@$(if $(archhelp),$(archhelp),\ @$(if $(archhelp),$(archhelp),\
echo ' No architecture specific help defined for $(ARCH)') echo ' No architecture specific help defined for $(ARCH)')
@echo '' @echo ''
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
@echo ' make C=1 [targets] Check all c source with checker tool'
@echo ''
@echo 'Execute "make" or "make all" to build all targets marked with [*] ' @echo 'Execute "make" or "make all" to build all targets marked with [*] '
@echo 'For further info browse Documentation/kbuild/*' @echo 'For further info browse Documentation/kbuild/*'
......
...@@ -460,17 +460,6 @@ void smp_send_reschedule(int cpu) ...@@ -460,17 +460,6 @@ void smp_send_reschedule(int cpu)
send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR);
} }
/*
* this function sends a reschedule IPI to all (other) CPUs.
* This should only be used if some 'global' task became runnable,
* such as a RT task, that must be handled now. The first CPU
* that manages to grab the task will run it.
*/
void smp_send_reschedule_all(void)
{
send_IPI_allbutself(RESCHEDULE_VECTOR);
}
/* /*
* Structure and data for smp_call_function(). This is designed to minimise * Structure and data for smp_call_function(). This is designed to minimise
* static memory requirements. It also looks cleaner. * static memory requirements. It also looks cleaner.
......
...@@ -205,24 +205,6 @@ smp_send_reschedule (int cpu) ...@@ -205,24 +205,6 @@ smp_send_reschedule (int cpu)
platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
} }
/*
* This function sends a reschedule IPI to all (other) CPUs. This should only be used if
* some 'global' task became runnable, such as a RT task, that must be handled now. The
* first CPU that manages to grab the task will run it.
*/
void
smp_send_reschedule_all (void)
{
int i;
int cpu = get_cpu(); /* disable preemption */
for (i = 0; i < NR_CPUS; i++)
if (cpu_online(i) && i != cpu)
smp_send_reschedule(i);
put_cpu();
}
void void
smp_flush_tlb_all (void) smp_flush_tlb_all (void)
{ {
......
...@@ -392,17 +392,6 @@ void smp_send_reschedule(int cpu) ...@@ -392,17 +392,6 @@ void smp_send_reschedule(int cpu)
smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0); smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
} }
/*
* this function sends a reschedule IPI to all (other) CPUs.
* This should only be used if some 'global' task became runnable,
* such as a RT task, that must be handled now. The first CPU
* that manages to grab the task will run it.
*/
void smp_send_reschedule_all(void)
{
smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_RESCHEDULE, 0, 0);
}
#ifdef CONFIG_XMON #ifdef CONFIG_XMON
void smp_send_xmon_break(int cpu) void smp_send_xmon_break(int cpu)
{ {
......
...@@ -304,7 +304,7 @@ static int eth_configure(int n, void *init, char *mac, ...@@ -304,7 +304,7 @@ static int eth_configure(int n, void *init, char *mac,
} }
memset(device, 0, sizeof(*device)); memset(device, 0, sizeof(*device));
device->list = INIT_LIST_HEAD(device->list); INIT_LIST_HEAD(&device->list);
device->index = n; device->index = n;
spin_lock(&devices_lock); spin_lock(&devices_lock);
...@@ -362,7 +362,7 @@ static int eth_configure(int n, void *init, char *mac, ...@@ -362,7 +362,7 @@ static int eth_configure(int n, void *init, char *mac,
return 1; return 1;
lp = dev->priv; lp = dev->priv;
lp->list = INIT_LIST_HEAD(lp->list); INIT_LIST_HEAD(&lp->list);
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
lp->dev = dev; lp->dev = dev;
lp->fd = -1; lp->fd = -1;
...@@ -537,7 +537,7 @@ static int eth_setup(char *str) ...@@ -537,7 +537,7 @@ static int eth_setup(char *str)
return(1); return(1);
} }
new->list = INIT_LIST_HEAD(new->list); INIT_LIST_HEAD(&new->list);
new->index = n; new->index = n;
new->init = str; new->init = str;
......
...@@ -6,16 +6,12 @@ menu "Cryptographic options" ...@@ -6,16 +6,12 @@ menu "Cryptographic options"
config CRYPTO config CRYPTO
bool "Cryptographic API" bool "Cryptographic API"
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m || INET6_IPCOMP=y || INET6_IPCOMP=m || IPV6_PRIVACY=y
help help
This option provides the core Cryptographic API. This option provides the core Cryptographic API.
config CRYPTO_HMAC config CRYPTO_HMAC
bool "HMAC support" bool "HMAC support"
depends on CRYPTO depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m
help help
HMAC: Keyed-Hashing for Message Authentication (RFC2104). HMAC: Keyed-Hashing for Message Authentication (RFC2104).
This is required for IPSec. This is required for IPSec.
...@@ -35,16 +31,12 @@ config CRYPTO_MD4 ...@@ -35,16 +31,12 @@ config CRYPTO_MD4
config CRYPTO_MD5 config CRYPTO_MD5
tristate "MD5 digest algorithm" tristate "MD5 digest algorithm"
depends on CRYPTO depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m || IPV6_PRIVACY=y
help help
MD5 message digest algorithm (RFC1321). MD5 message digest algorithm (RFC1321).
config CRYPTO_SHA1 config CRYPTO_SHA1
tristate "SHA1 digest algorithm" tristate "SHA1 digest algorithm"
depends on CRYPTO depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
INET6_ESP=y || INET6_ESP=m
help help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
...@@ -72,7 +64,6 @@ config CRYPTO_SHA512 ...@@ -72,7 +64,6 @@ config CRYPTO_SHA512
config CRYPTO_DES config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms" tristate "DES and Triple DES EDE cipher algorithms"
depends on CRYPTO depends on CRYPTO
default y if INET_ESP=y || INET_ESP=m || INET6_ESP=y || INET6_ESP=m
help help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
...@@ -138,7 +129,6 @@ config CRYPTO_AES ...@@ -138,7 +129,6 @@ config CRYPTO_AES
config CRYPTO_DEFLATE config CRYPTO_DEFLATE
tristate "Deflate compression algorithm" tristate "Deflate compression algorithm"
depends on CRYPTO depends on CRYPTO
default y if INET_IPCOMP=y || INET_IPCOMP=m || INET6_IPCOMP=y || INET6_IPCOMP=m
help help
This is the Deflate algorithm (RFC1951), specified for use in This is the Deflate algorithm (RFC1951), specified for use in
IPSec with the IPCOMP protocol (RFC3173, RFC2394). IPSec with the IPCOMP protocol (RFC3173, RFC2394).
......
This diff is collapsed.
...@@ -4,3 +4,12 @@ extern void bus_remove_device(struct device * dev); ...@@ -4,3 +4,12 @@ extern void bus_remove_device(struct device * dev);
extern int bus_add_driver(struct device_driver *); extern int bus_add_driver(struct device_driver *);
extern void bus_remove_driver(struct device_driver *); extern void bus_remove_driver(struct device_driver *);
static inline struct class_device *to_class_dev(struct kobject *obj)
{
return container_of(obj,struct class_device,kobj);
}
static inline
struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
{
return container_of(_attr,struct class_device_attribute,attr);
}
/* /*
* bus.c - bus driver management * bus.c - bus driver management
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
* *
* Copyright (c) 2002 Patrick Mochel * This file is released under the GPLv2
* 2002 Open Source Development Lab *
*
*
*/ */
#undef DEBUG #undef DEBUG
......
/* /*
* class.c - basic device class management * class.c - basic device class management
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
* *
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org> * This file is released under the GPLv2
*
*/ */
#undef DEBUG #undef DEBUG
...@@ -148,9 +152,6 @@ static void class_device_driver_unlink(struct class_device * class_dev) ...@@ -148,9 +152,6 @@ static void class_device_driver_unlink(struct class_device * class_dev)
} }
#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
#define to_class_dev_attr(_attr) container_of(_attr,struct class_device_attribute,attr)
static ssize_t static ssize_t
class_device_attr_show(struct kobject * kobj, struct attribute * attr, class_device_attr_show(struct kobject * kobj, struct attribute * attr,
char * buf) char * buf)
...@@ -182,8 +183,20 @@ static struct sysfs_ops class_dev_sysfs_ops = { ...@@ -182,8 +183,20 @@ static struct sysfs_ops class_dev_sysfs_ops = {
.store = class_device_attr_store, .store = class_device_attr_store,
}; };
static void class_dev_release(struct kobject * kobj)
{
struct class_device *cd = to_class_dev(kobj);
struct class * cls = cd->class;
pr_debug("device class '%s': release.\n",cd->class_id);
if (cls->release)
cd->release(cd);
}
static struct kobj_type ktype_class_device = { static struct kobj_type ktype_class_device = {
.sysfs_ops = &class_dev_sysfs_ops, .sysfs_ops = &class_dev_sysfs_ops,
.release = class_dev_release,
}; };
static int class_hotplug_filter(struct kset *kset, struct kobject *kobj) static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
...@@ -311,11 +324,8 @@ void class_device_del(struct class_device *class_dev) ...@@ -311,11 +324,8 @@ void class_device_del(struct class_device *class_dev)
up_write(&parent->subsys.rwsem); up_write(&parent->subsys.rwsem);
} }
if (class_dev->dev) { class_device_dev_unlink(class_dev);
class_device_dev_unlink(class_dev); class_device_driver_unlink(class_dev);
class_device_driver_unlink(class_dev);
put_device(class_dev->dev);
}
kobject_del(&class_dev->kobj); kobject_del(&class_dev->kobj);
......
/* /*
* drivers/base/core.c - core driver model code (device registration, etc) * drivers/base/core.c - core driver model code (device registration, etc)
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
* *
* Copyright (c) 2002 Patrick Mochel * This file is released under the GPLv2
* 2002 Open Source Development Lab *
*/ */
#undef DEBUG #undef DEBUG
......
...@@ -46,7 +46,7 @@ int __init register_cpu(struct cpu *cpu, int num, struct node *root) ...@@ -46,7 +46,7 @@ int __init register_cpu(struct cpu *cpu, int num, struct node *root)
snprintf(cpu->sysdev.class_dev.class_id, BUS_ID_SIZE, "cpu%d", num); snprintf(cpu->sysdev.class_dev.class_id, BUS_ID_SIZE, "cpu%d", num);
retval = class_device_register(&cpu->sysdev.class_dev); retval = class_device_register(&cpu->sysdev.class_dev);
if (retval) { if (retval) {
// FIXME cleanup sys_device_register sys_device_unregister(&cpu->sysdev);
return retval; return retval;
} }
return 0; return 0;
...@@ -58,10 +58,12 @@ int __init cpu_dev_init(void) ...@@ -58,10 +58,12 @@ int __init cpu_dev_init(void)
int error; int error;
error = class_register(&cpu_class); error = class_register(&cpu_class);
if (!error) { if (error)
error = driver_register(&cpu_driver); goto out;
if (error)
class_unregister(&cpu_class); error = driver_register(&cpu_driver);
} if (error)
class_unregister(&cpu_class);
out:
return error; return error;
} }
/* /*
* driver.c - centralized device driver management * driver.c - centralized device driver management
* *
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* This file is released under the GPLv2
*
*/ */
#undef DEBUG #undef DEBUG
......
/* /*
* firmware.c - firmware subsystem hoohaw. * firmware.c - firmware subsystem hoohaw.
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* This file is released under the GPLv2
*
*/ */
#include <linux/kobject.h> #include <linux/kobject.h>
......
/*
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* This file is released under the GPLv2
*
*/
#include <linux/device.h> #include <linux/device.h>
#include <linux/init.h> #include <linux/init.h>
......
/* /*
* drivers/base/interface.c - common driverfs interface that's exported to * drivers/base/interface.c - common driverfs interface that's exported to
* the world for all devices. * the world for all devices.
* Copyright (c) 2002 Patrick Mochel *
* 2002 Open Source Development Lab * Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* This file is released under the GPLv2
*
*/ */
#include <linux/device.h> #include <linux/device.h>
......
/* /*
* platform.c - platform 'psuedo' bus for legacy devices * platform.c - platform 'psuedo' bus for legacy devices
* *
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* This file is released under the GPLv2
*
* Please see Documentation/driver-model/platform.txt for more * Please see Documentation/driver-model/platform.txt for more
* information. * information.
*/ */
......
/* /*
* power.c - power management functions for the device tree. * power.c - power management functions for the device tree.
* *
* Copyright (c) 2002 Patrick Mochel * Copyright (c) 2002-3 Patrick Mochel
* 2002 Open Source Development Lab * 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
* *
* Kai Germaschewski contributed to the list walking routines. * Kai Germaschewski contributed to the list walking routines.
* *
*/ */
#undef DEBUG #define DEBUG
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -88,10 +90,12 @@ void device_shutdown(void) ...@@ -88,10 +90,12 @@ void device_shutdown(void)
down_write(&devices_subsys.rwsem); down_write(&devices_subsys.rwsem);
list_for_each(entry,&devices_subsys.kset.list) { list_for_each(entry,&devices_subsys.kset.list) {
struct device * dev = to_dev(entry); struct device * dev = to_dev(entry);
pr_debug("shutting down %s: ",dev->name);
if (dev->driver && dev->driver->shutdown) { if (dev->driver && dev->driver->shutdown) {
pr_debug("shutting down %s\n",dev->name); pr_debug("Ok\n");
dev->driver->shutdown(dev); dev->driver->shutdown(dev);
} } else
pr_debug("Ignored.\n");
} }
up_write(&devices_subsys.rwsem); up_write(&devices_subsys.rwsem);
} }
......
/* /*
* sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc) * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
* *
* Copyright (c) 2002 Patrick Mochel * Copyright (c) 2002-3 Patrick Mochel
* 2002 Open Source Development Lab * 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
* *
* This exports a 'system' bus type. * This exports a 'system' bus type.
* By default, a 'sys' bus gets added to the root of the system. There will * By default, a 'sys' bus gets added to the root of the system. There will
......
This diff is collapsed.
...@@ -712,7 +712,6 @@ void create_proc_ide_drives(ide_hwif_t *hwif) ...@@ -712,7 +712,6 @@ void create_proc_ide_drives(ide_hwif_t *hwif)
for (d = 0; d < MAX_DRIVES; d++) { for (d = 0; d < MAX_DRIVES; d++) {
ide_drive_t *drive = &hwif->drives[d]; ide_drive_t *drive = &hwif->drives[d];
ide_driver_t *driver = drive->driver;
if (!drive->present) if (!drive->present)
continue; continue;
...@@ -720,13 +719,8 @@ void create_proc_ide_drives(ide_hwif_t *hwif) ...@@ -720,13 +719,8 @@ void create_proc_ide_drives(ide_hwif_t *hwif)
continue; continue;
drive->proc = proc_mkdir(drive->name, parent); drive->proc = proc_mkdir(drive->name, parent);
if (drive->proc) { if (drive->proc)
ide_add_proc_entries(drive->proc, generic_drive_entries, drive); ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
if (driver) {
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
ide_add_proc_entries(drive->proc, driver->proc, drive);
}
}
sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name); sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
ent = proc_symlink(drive->name, proc_ide_root, name); ent = proc_symlink(drive->name, proc_ide_root, name);
if (!ent) return; if (!ent) return;
...@@ -735,34 +729,6 @@ void create_proc_ide_drives(ide_hwif_t *hwif) ...@@ -735,34 +729,6 @@ void create_proc_ide_drives(ide_hwif_t *hwif)
EXPORT_SYMBOL(create_proc_ide_drives); EXPORT_SYMBOL(create_proc_ide_drives);
void recreate_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct proc_dir_entry *ent;
struct proc_dir_entry *parent = hwif->proc;
char name[64];
if (drive->present && !drive->proc) {
drive->proc = proc_mkdir(drive->name, parent);
if (drive->proc)
ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
/*
* assume that we have these already, however, should test FIXME!
* if (driver) {
* ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
* ide_add_proc_entries(drive->proc, driver->proc, drive);
* }
*
*/
sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
ent = proc_symlink(drive->name, proc_ide_root, name);
if (!ent)
return;
}
}
EXPORT_SYMBOL(recreate_proc_ide_device);
void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
{ {
ide_driver_t *driver = drive->driver; ide_driver_t *driver = drive->driver;
......
...@@ -2349,8 +2349,10 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio ...@@ -2349,8 +2349,10 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
} }
drive->suspend_reset = 0; drive->suspend_reset = 0;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); if (drive->driver != &idedefault_driver) {
ide_add_proc_entries(drive->proc, driver->proc, drive); ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
ide_add_proc_entries(drive->proc, driver->proc, drive);
}
#endif #endif
return 0; return 0;
} }
......
...@@ -300,17 +300,11 @@ static int nopnp; ...@@ -300,17 +300,11 @@ static int nopnp;
* *
* Both call el3_common_init/el3_common_remove. */ * Both call el3_common_init/el3_common_remove. */
static int __init el3_common_init (struct net_device *dev) static void __init el3_common_init(struct net_device *dev)
{ {
struct el3_private *lp = dev->priv; struct el3_private *lp = dev->priv;
short i; short i;
el3_cards++;
if (!lp->dev) /* probed devices are not chained */
{
lp->next_dev = el3_root_dev;
el3_root_dev = dev;
}
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */ if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
...@@ -343,8 +337,6 @@ static int __init el3_common_init (struct net_device *dev) ...@@ -343,8 +337,6 @@ static int __init el3_common_init (struct net_device *dev)
dev->tx_timeout = el3_tx_timeout; dev->tx_timeout = el3_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl; dev->do_ioctl = netdev_ioctl;
return 0;
} }
static void el3_common_remove (struct net_device *dev) static void el3_common_remove (struct net_device *dev)
...@@ -374,6 +366,7 @@ static int __init el3_probe(int card_idx) ...@@ -374,6 +366,7 @@ static int __init el3_probe(int card_idx)
int ioaddr, irq, if_port; int ioaddr, irq, if_port;
u16 phys_addr[3]; u16 phys_addr[3];
static int current_tag; static int current_tag;
int err = -ENODEV;
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
static int pnp_cards; static int pnp_cards;
struct pnp_dev *idev = NULL; struct pnp_dev *idev = NULL;
...@@ -413,7 +406,8 @@ static int __init el3_probe(int card_idx) ...@@ -413,7 +406,8 @@ static int __init el3_probe(int card_idx)
phys_addr[j] = phys_addr[j] =
htons(read_eeprom(ioaddr, j)); htons(read_eeprom(ioaddr, j));
if_port = read_eeprom(ioaddr, 8) >> 14; if_port = read_eeprom(ioaddr, 8) >> 14;
if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) { dev = alloc_etherdev(sizeof (struct el3_private));
if (!dev) {
release_region(ioaddr, EL3_IO_EXTENT); release_region(ioaddr, EL3_IO_EXTENT);
pnp_device_detach(idev); pnp_device_detach(idev);
return -ENOMEM; return -ENOMEM;
...@@ -421,6 +415,8 @@ static int __init el3_probe(int card_idx) ...@@ -421,6 +415,8 @@ static int __init el3_probe(int card_idx)
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
pnp_cards++; pnp_cards++;
netdev_boot_setup_check(dev);
goto found; goto found;
} }
} }
...@@ -514,28 +510,29 @@ static int __init el3_probe(int card_idx) ...@@ -514,28 +510,29 @@ static int __init el3_probe(int card_idx)
irq = 13; irq = 13;
#endif #endif
if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) dev = alloc_etherdev(sizeof (struct el3_private));
return -ENOMEM; if (!dev)
return -ENOMEM;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
/* Set passed-in IRQ or I/O Addr. */ /* Set passed-in IRQ or I/O Addr. */
if (dev->irq > 1 && dev->irq < 16) if (dev->irq > 1 && dev->irq < 16)
irq = dev->irq; irq = dev->irq;
if (dev->base_addr) { if (dev->base_addr) {
if (dev->mem_end == 0x3c509 /* Magic key */ if (dev->mem_end == 0x3c509 /* Magic key */
&& dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0) && dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0)
ioaddr = dev->base_addr & 0x3f0; ioaddr = dev->base_addr & 0x3f0;
else if (dev->base_addr != ioaddr) { else if (dev->base_addr != ioaddr)
unregister_netdev (dev); goto out;
return -ENODEV;
}
} }
if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) { if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
unregister_netdev (dev); err = -EBUSY;
return -EBUSY; goto out;
} }
/* Set the adaptor tag so that the next card can be found. */ /* Set the adaptor tag so that the next card can be found. */
...@@ -549,11 +546,8 @@ static int __init el3_probe(int card_idx) ...@@ -549,11 +546,8 @@ static int __init el3_probe(int card_idx)
#endif #endif
EL3WINDOW(0); EL3WINDOW(0);
if (inw(ioaddr) != 0x6d50) { if (inw(ioaddr) != 0x6d50)
unregister_netdev (dev); goto out1;
release_region(ioaddr, EL3_IO_EXTENT);
return -ENODEV;
}
/* Free the interrupt so that some other card can use it. */ /* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ); outw(0x0f00, ioaddr + WN0_IRQ);
...@@ -570,6 +564,11 @@ static int __init el3_probe(int card_idx) ...@@ -570,6 +564,11 @@ static int __init el3_probe(int card_idx)
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800) #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
lp->dev = &idev->dev; lp->dev = &idev->dev;
#endif #endif
el3_common_init(dev);
err = register_netdev(dev);
if (err)
goto out1;
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* register power management */ /* register power management */
...@@ -581,7 +580,22 @@ static int __init el3_probe(int card_idx) ...@@ -581,7 +580,22 @@ static int __init el3_probe(int card_idx)
} }
#endif #endif
return el3_common_init (dev); el3_cards++;
#if !defined(__ISAPNP__) || defined(CONFIG_X86_PC9800)
lp->next_dev = el3_root_dev;
el3_root_dev = dev;
#endif
return 0;
out1:
release_region(ioaddr, EL3_IO_EXTENT);
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
if (idev)
pnp_device_detach(idev);
#endif
out:
kfree(dev);
return err;
} }
#ifdef CONFIG_MCA #ifdef CONFIG_MCA
...@@ -602,6 +616,7 @@ static int __init el3_mca_probe(struct device *device) { ...@@ -602,6 +616,7 @@ static int __init el3_mca_probe(struct device *device) {
u_char pos4, pos5; u_char pos4, pos5;
struct mca_device *mdev = to_mca_device(device); struct mca_device *mdev = to_mca_device(device);
int slot = mdev->slot; int slot = mdev->slot;
int err;
pos4 = mca_device_read_stored_pos(mdev, 4); pos4 = mca_device_read_stored_pos(mdev, 4);
pos5 = mca_device_read_stored_pos(mdev, 5); pos5 = mca_device_read_stored_pos(mdev, 5);
...@@ -630,13 +645,14 @@ static int __init el3_mca_probe(struct device *device) { ...@@ -630,13 +645,14 @@ static int __init el3_mca_probe(struct device *device) {
phys_addr[i] = htons(read_eeprom(ioaddr, i)); phys_addr[i] = htons(read_eeprom(ioaddr, i));
} }
dev = init_etherdev(NULL, sizeof(struct el3_private)); dev = alloc_etherdev(sizeof (struct el3_private));
if (dev == NULL) { if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT); release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM; return -ENOMEM;
} }
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
...@@ -646,8 +662,16 @@ static int __init el3_mca_probe(struct device *device) { ...@@ -646,8 +662,16 @@ static int __init el3_mca_probe(struct device *device) {
lp->dev = device; lp->dev = device;
lp->type = EL3_MCA; lp->type = EL3_MCA;
device->driver_data = dev; device->driver_data = dev;
el3_common_init(dev);
err = register_netdev(dev);
if (err) {
release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM;
}
return el3_common_init (dev); el3_cards++;
return 0;
} }
#endif /* CONFIG_MCA */ #endif /* CONFIG_MCA */
...@@ -661,6 +685,7 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -661,6 +685,7 @@ static int __init el3_eisa_probe (struct device *device)
u16 phys_addr[3]; u16 phys_addr[3];
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct eisa_device *edev; struct eisa_device *edev;
int err;
/* Yeepee, The driver framework is calling us ! */ /* Yeepee, The driver framework is calling us ! */
edev = to_eisa_device (device); edev = to_eisa_device (device);
...@@ -680,7 +705,7 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -680,7 +705,7 @@ static int __init el3_eisa_probe (struct device *device)
/* Restore the "Product ID" to the EEPROM read register. */ /* Restore the "Product ID" to the EEPROM read register. */
read_eeprom(ioaddr, 3); read_eeprom(ioaddr, 3);
dev = init_etherdev(NULL, sizeof(struct el3_private)); dev = alloc_etherdev(sizeof (struct el3_private));
if (dev == NULL) { if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT); release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM; return -ENOMEM;
...@@ -688,6 +713,8 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -688,6 +713,8 @@ static int __init el3_eisa_probe (struct device *device)
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
dev->irq = irq; dev->irq = irq;
...@@ -696,8 +723,16 @@ static int __init el3_eisa_probe (struct device *device) ...@@ -696,8 +723,16 @@ static int __init el3_eisa_probe (struct device *device)
lp->dev = device; lp->dev = device;
lp->type = EL3_EISA; lp->type = EL3_EISA;
eisa_set_drvdata (edev, dev); eisa_set_drvdata (edev, dev);
el3_common_init(dev);
err = register_netdev(dev);
if (err) {
release_region(ioaddr, EL3_IO_EXTENT);
return err;
}
return el3_common_init (dev); el3_cards++;
return 0;
} }
#endif #endif
......
...@@ -250,8 +250,6 @@ struct scc_info { ...@@ -250,8 +250,6 @@ struct scc_info {
/* Function declarations */ /* Function declarations */
int dmascc_init(void) __init;
static int setup_adapter(int card_base, int type, int n) __init; static int setup_adapter(int card_base, int type, int n) __init;
static void write_scc(struct scc_priv *priv, int reg, int val); static void write_scc(struct scc_priv *priv, int reg, int val);
...@@ -299,23 +297,12 @@ static struct scc_info *first; ...@@ -299,23 +297,12 @@ static struct scc_info *first;
static unsigned long rand; static unsigned long rand;
/* Module functions */
#ifdef MODULE
MODULE_AUTHOR("Klaus Kudielka"); MODULE_AUTHOR("Klaus Kudielka");
MODULE_DESCRIPTION("Driver for high-speed SCC boards"); MODULE_DESCRIPTION("Driver for high-speed SCC boards");
MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i"); MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static void __exit dmascc_exit(void) {
int init_module(void) {
return dmascc_init();
}
void cleanup_module(void) {
int i; int i;
struct scc_info *info; struct scc_info *info;
...@@ -341,24 +328,16 @@ void cleanup_module(void) { ...@@ -341,24 +328,16 @@ void cleanup_module(void) {
} }
} }
#ifndef MODULE
#else
void __init dmascc_setup(char *str, int *ints) { void __init dmascc_setup(char *str, int *ints) {
int i; int i;
for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++) for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
io[i] = ints[i+1]; io[i] = ints[i+1];
} }
#endif #endif
static int __init dmascc_init(void) {
/* Initialization functions */
int __init dmascc_init(void) {
int h, i, j, n; int h, i, j, n;
int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS], int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
t1[MAX_NUM_DEVS]; t1[MAX_NUM_DEVS];
...@@ -461,6 +440,9 @@ int __init dmascc_init(void) { ...@@ -461,6 +440,9 @@ int __init dmascc_init(void) {
return -EIO; return -EIO;
} }
module_init(dmascc_init);
module_exit(dmascc_exit);
int __init setup_adapter(int card_base, int type, int n) { int __init setup_adapter(int card_base, int type, int n) {
int i, irq, chip; int i, irq, chip;
...@@ -580,6 +562,7 @@ int __init setup_adapter(int card_base, int type, int n) { ...@@ -580,6 +562,7 @@ int __init setup_adapter(int card_base, int type, int n) {
if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name; if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name;
#endif #endif
sprintf(dev->name, "dmascc%i", 2*n+i); sprintf(dev->name, "dmascc%i", 2*n+i);
SET_MODULE_OWNER(dev);
dev->base_addr = card_base; dev->base_addr = card_base;
dev->irq = irq; dev->irq = irq;
dev->open = scc_open; dev->open = scc_open;
...@@ -707,12 +690,9 @@ static int scc_open(struct net_device *dev) { ...@@ -707,12 +690,9 @@ static int scc_open(struct net_device *dev) {
struct scc_info *info = priv->info; struct scc_info *info = priv->info;
int card_base = priv->card_base; int card_base = priv->card_base;
MOD_INC_USE_COUNT;
/* Request IRQ if not already used by other channel */ /* Request IRQ if not already used by other channel */
if (!info->irq_used) { if (!info->irq_used) {
if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) { if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) {
MOD_DEC_USE_COUNT;
return -EAGAIN; return -EAGAIN;
} }
} }
...@@ -722,7 +702,6 @@ static int scc_open(struct net_device *dev) { ...@@ -722,7 +702,6 @@ static int scc_open(struct net_device *dev) {
if (priv->param.dma >= 0) { if (priv->param.dma >= 0) {
if (request_dma(priv->param.dma, "dmascc")) { if (request_dma(priv->param.dma, "dmascc")) {
if (--info->irq_used == 0) free_irq(dev->irq, info); if (--info->irq_used == 0) free_irq(dev->irq, info);
MOD_DEC_USE_COUNT;
return -EAGAIN; return -EAGAIN;
} else { } else {
unsigned long flags = claim_dma_lock(); unsigned long flags = claim_dma_lock();
...@@ -866,7 +845,6 @@ static int scc_close(struct net_device *dev) { ...@@ -866,7 +845,6 @@ static int scc_close(struct net_device *dev) {
} }
if (--info->irq_used == 0) free_irq(dev->irq, info); if (--info->irq_used == 0) free_irq(dev->irq, info);
MOD_DEC_USE_COUNT;
return 0; return 0;
} }
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/netlink.h> #include <linux/netlink.h>
extern int dmascc_init(void);
extern int scc_enet_init(void); extern int scc_enet_init(void);
extern int fec_enet_init(void); extern int fec_enet_init(void);
...@@ -29,10 +27,6 @@ static struct net_probe pci_probes[] __initdata = { ...@@ -29,10 +27,6 @@ static struct net_probe pci_probes[] __initdata = {
/* /*
* Early setup devices * Early setup devices
*/ */
#if defined(CONFIG_DMASCC)
{dmascc_init, 0},
#endif
#if defined(CONFIG_SCC_ENET) #if defined(CONFIG_SCC_ENET)
{scc_enet_init, 0}, {scc_enet_init, 0},
#endif #endif
......
...@@ -383,6 +383,7 @@ struct s_DevNet { ...@@ -383,6 +383,7 @@ struct s_DevNet {
int Mtu; int Mtu;
int Up; int Up;
SK_AC *pAC; SK_AC *pAC;
struct proc_dir_entry *proc;
}; };
typedef struct s_TxPort TX_PORT; typedef struct s_TxPort TX_PORT;
......
...@@ -351,11 +351,7 @@ static int SkGeIocMib(DEV_NET*, unsigned int, int); ...@@ -351,11 +351,7 @@ static int SkGeIocMib(DEV_NET*, unsigned int, int);
static const char SK_Root_Dir_entry[] = "sk98lin"; static const char SK_Root_Dir_entry[] = "sk98lin";
static struct proc_dir_entry *pSkRootDir; static struct proc_dir_entry *pSkRootDir;
extern struct file_operations sk_proc_fops;
//extern struct proc_dir_entry Our_Proc_Dir;
extern int sk_proc_read(char *buffer, char **buffer_location,
off_t offset, int buffer_length, int *eof, void *data);
#ifdef DEBUG #ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*); static void DumpMsg(struct sk_buff*, char*);
...@@ -399,7 +395,6 @@ static int __init skge_probe (void) ...@@ -399,7 +395,6 @@ static int __init skge_probe (void)
struct pci_dev *pdev = NULL; struct pci_dev *pdev = NULL;
unsigned long base_address; unsigned long base_address;
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct proc_dir_entry *pProcFile;
if (probed) if (probed)
return -ENODEV; return -ENODEV;
...@@ -420,7 +415,6 @@ static int __init skge_probe (void) ...@@ -420,7 +415,6 @@ static int __init skge_probe (void)
while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT, while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) { PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
dev = NULL;
pNet = NULL; pNet = NULL;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
...@@ -431,7 +425,8 @@ static int __init skge_probe (void) ...@@ -431,7 +425,8 @@ static int __init skge_probe (void)
pci_set_dma_mask(pdev, (u64) 0xffffffff)) pci_set_dma_mask(pdev, (u64) 0xffffffff))
continue; continue;
if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) { dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev " printk(KERN_ERR "Unable to allocate etherdev "
"structure!\n"); "structure!\n");
break; break;
...@@ -440,7 +435,7 @@ static int __init skge_probe (void) ...@@ -440,7 +435,7 @@ static int __init skge_probe (void)
pNet = dev->priv; pNet = dev->priv;
pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
if (pNet->pAC == NULL){ if (pNet->pAC == NULL){
kfree(dev->priv); kfree(dev);
printk(KERN_ERR "Unable to allocate adapter " printk(KERN_ERR "Unable to allocate adapter "
"structure!\n"); "structure!\n");
break; break;
...@@ -477,15 +472,6 @@ static int __init skge_probe (void) ...@@ -477,15 +472,6 @@ static int __init skge_probe (void)
proc_root_initialized = 1; proc_root_initialized = 1;
} }
pProcFile = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
pProcFile->read_proc = sk_proc_read;
pProcFile->write_proc = NULL;
pProcFile->nlink = 1;
pProcFile->size = sizeof(dev->name+1);
pProcFile->data = (void*)pProcFile;
pProcFile->owner = THIS_MODULE;
/* /*
* Dummy value. * Dummy value.
*/ */
...@@ -532,11 +518,29 @@ static int __init skge_probe (void) ...@@ -532,11 +518,29 @@ static int __init skge_probe (void)
pNet->PortNr = 0; pNet->PortNr = 0;
pNet->NetNr = 0; pNet->NetNr = 0;
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
sk98lin_root_dev = pAC->Next;
remove_proc_entry(dev->name, pSkRootDir);
FreeResources(dev);
kfree(dev);
continue;
}
pNet->proc = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
if (pNet->proc) {
pNet->proc->data = dev;
pNet->proc->owner = THIS_MODULE;
pNet->proc->proc_fops = &sk_proc_fops;
}
boards_found++; boards_found++;
/* More then one port found */ /* More then one port found */
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) { dev = alloc_etherdev(sizeof(DEV_NET));
if (!dev) {
printk(KERN_ERR "Unable to allocate etherdev " printk(KERN_ERR "Unable to allocate etherdev "
"structure!\n"); "structure!\n");
break; break;
...@@ -559,20 +563,25 @@ static int __init skge_probe (void) ...@@ -559,20 +563,25 @@ static int __init skge_probe (void)
dev->do_ioctl = &SkGeIoctl; dev->do_ioctl = &SkGeIoctl;
dev->change_mtu = &SkGeChangeMtu; dev->change_mtu = &SkGeChangeMtu;
pProcFile = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
pProcFile->read_proc = sk_proc_read;
pProcFile->write_proc = NULL;
pProcFile->nlink = 1;
pProcFile->size = sizeof(dev->name+1);
pProcFile->data = (void*)pProcFile;
pProcFile->owner = THIS_MODULE;
memcpy((caddr_t) &dev->dev_addr, memcpy((caddr_t) &dev->dev_addr,
(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
printk("%s: %s\n", dev->name, pAC->DeviceStr); printk("%s: %s\n", dev->name, pAC->DeviceStr);
printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
if (register_netdev(dev) != 0) {
printk(KERN_ERR "Unable to register etherdev\n");
kfree(dev);
break;
}
pNet->proc = create_proc_entry(dev->name,
S_IFREG | 0444, pSkRootDir);
if (pNet->proc) {
pNet->proc->data = dev;
pNet->proc->owner = THIS_MODULE;
pNet->proc->proc_fops = &sk_proc_fops;
}
} }
...@@ -740,6 +749,7 @@ static int __init skge_init_module(void) ...@@ -740,6 +749,7 @@ static int __init skge_init_module(void)
return cards ? 0 : -ENODEV; return cards ? 0 : -ENODEV;
} /* skge_init_module */ } /* skge_init_module */
spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
/***************************************************************************** /*****************************************************************************
* *
...@@ -766,6 +776,11 @@ SK_EVPARA EvPara; ...@@ -766,6 +776,11 @@ SK_EVPARA EvPara;
netif_stop_queue(sk98lin_root_dev); netif_stop_queue(sk98lin_root_dev);
SkGeYellowLED(pAC, pAC->IoBase, 0); SkGeYellowLED(pAC, pAC->IoBase, 0);
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
}
if(pAC->BoardLevel == 2) { if(pAC->BoardLevel == 2) {
/* board is still alive */ /* board is still alive */
...@@ -792,6 +807,12 @@ SK_EVPARA EvPara; ...@@ -792,6 +807,12 @@ SK_EVPARA EvPara;
} }
if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
pNet = (DEV_NET*) pAC->dev[1]->priv;
if (pNet->proc) {
spin_lock(&sk_devs_lock);
pNet->proc->data = NULL;
spin_unlock(&sk_devs_lock);
}
unregister_netdev(pAC->dev[1]); unregister_netdev(pAC->dev[1]);
kfree(pAC->dev[1]); kfree(pAC->dev[1]);
} }
......
This diff is collapsed.
...@@ -1682,11 +1682,13 @@ static int __init init_sdla(void) ...@@ -1682,11 +1682,13 @@ static int __init init_sdla(void)
static void __exit exit_sdla(void) static void __exit exit_sdla(void)
{ {
#ifdef MODULE
unregister_netdev(&sdla0); unregister_netdev(&sdla0);
if (sdla0.priv) if (sdla0.priv)
kfree(sdla0.priv); kfree(sdla0.priv);
if (sdla0.irq) if (sdla0.irq)
free_irq(sdla0.irq, &sdla0); free_irq(sdla0.irq, &sdla0);
#endif
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -385,7 +385,7 @@ static int __init NCR_D700_init(void) ...@@ -385,7 +385,7 @@ static int __init NCR_D700_init(void)
static void __exit NCR_D700_exit(void) static void __exit NCR_D700_exit(void)
{ {
mca_unregister_driver(&NCR_D700_driver); mca_unregister_driver(&NCR_D700_driver);
scsi_sysfs_release_attributes(); scsi_sysfs_release_attributes(&NCR_D700_driver_template);
} }
module_init(NCR_D700_init); module_init(NCR_D700_init);
......
...@@ -21,26 +21,6 @@ ...@@ -21,26 +21,6 @@
* 1+ (800) 334-5454 * 1+ (800) 334-5454
*/ */
/*
* Options :
*
* PARITY - enable parity checking. Not supported.
*
* SCSI2 - enable support for SCSI-II tagged queueing. Untested.
*
* USLEEP - enable support for devices that don't disconnect. Untested.
*/
/*
* $Log: ecoscsi.c,v $
* Revision 1.2 1998/03/08 05:49:47 davem
* Merge to 2.1.89
*
* Revision 1.1 1998/02/23 02:45:24 davem
* Merge to 2.1.88
*
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -94,71 +74,8 @@ static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value) ...@@ -94,71 +74,8 @@ static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value)
* *
*/ */
void ecoscsi_setup(char *str, int *ints) { void ecoscsi_setup(char *str, int *ints)
}
/*
* Function : int ecoscsi_detect(Scsi_Host_Template * tpnt)
*
* Purpose : initializes ecoscsi NCR5380 driver based on the
* command line / compile time port and irq definitions.
*
* Inputs : tpnt - template for this SCSI adapter.
*
* Returns : 1 if a host adapter was found, 0 if not.
*
*/
int ecoscsi_detect(Scsi_Host_Template * tpnt)
{
struct Scsi_Host *host;
tpnt->proc_name = "ecoscsi";
host = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
if (!host)
return 0;
host->io_port = 0x80ce8000;
host->n_io_port = 144;
host->irq = IRQ_NONE;
if ( !(request_region(host->io_port, host->n_io_port, "ecoscsi")) )
goto unregister_scsi;
ecoscsi_write (host, MODE_REG, 0x20); /* Is it really SCSI? */
if (ecoscsi_read (host, MODE_REG) != 0x20) /* Write to a reg. */
goto release_reg;
ecoscsi_write( host, MODE_REG, 0x00 ); /* it back. */
if (ecoscsi_read (host, MODE_REG) != 0x00)
goto release_reg;
NCR5380_init(host, 0);
printk("scsi%d: at port 0x%08lx irqs disabled", host->host_no, host->io_port);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
host->can_queue, host->cmd_per_lun, ECOSCSI_PUBLIC_RELEASE);
printk("\nscsi%d:", host->host_no);
NCR5380_print_options(host);
printk("\n");
return 1;
release_reg:
release_region(host->io_port, host->n_io_port);
unregister_scsi:
scsi_unregister(host);
return 0;
}
int ecoscsi_release (struct Scsi_Host *shpnt)
{ {
if (shpnt->irq != IRQ_NONE)
free_irq (shpnt->irq, NULL);
if (shpnt->io_port)
release_region (shpnt->io_port, shpnt->n_io_port);
return 0;
} }
const char * ecoscsi_info (struct Scsi_Host *spnt) const char * ecoscsi_info (struct Scsi_Host *spnt)
...@@ -241,8 +158,7 @@ printk("reading %p len %d\n",addr, len); ...@@ -241,8 +158,7 @@ printk("reading %p len %d\n",addr, len);
static Scsi_Host_Template ecoscsi_template = { static Scsi_Host_Template ecoscsi_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "Serial Port EcoSCSI NCR5380", .name = "Serial Port EcoSCSI NCR5380",
.detect = ecoscsi_detect, .proc_name = "ecoscsi",
.release = ecoscsi_release,
.info = ecoscsi_info, .info = ecoscsi_info,
.queuecommand = ecoscsi_queue_command, .queuecommand = ecoscsi_queue_command,
.eh_abort_handler = NCR5380_abort, .eh_abort_handler = NCR5380_abort,
...@@ -256,19 +172,60 @@ static Scsi_Host_Template ecoscsi_template = { ...@@ -256,19 +172,60 @@ static Scsi_Host_Template ecoscsi_template = {
.use_clustering = DISABLE_CLUSTERING .use_clustering = DISABLE_CLUSTERING
}; };
static struct Scsi_Host *host;
static int __init ecoscsi_init(void) static int __init ecoscsi_init(void)
{ {
scsi_register_host(&ecoscsi_template);
if (ecoscsi_template.present) host = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
if (!host)
return 0; return 0;
scsi_unregister_host(&ecoscsi_template); host->io_port = 0x80ce8000;
host->n_io_port = 144;
host->irq = IRQ_NONE;
if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) )
goto unregister_scsi;
ecoscsi_write(host, MODE_REG, 0x20); /* Is it really SCSI? */
if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg. */
goto release_reg;
ecoscsi_write(host, MODE_REG, 0x00 ); /* it back. */
if (ecoscsi_read(host, MODE_REG) != 0x00)
goto release_reg;
NCR5380_init(host, 0);
printk("scsi%d: at port 0x%08lx irqs disabled", host->host_no, host->io_port);
printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
host->can_queue, host->cmd_per_lun, ECOSCSI_PUBLIC_RELEASE);
printk("\nscsi%d:", host->host_no);
NCR5380_print_options(host);
printk("\n");
scsi_add_host(host, NULL);
return 0;
release_reg:
release_region(host->io_port, host->n_io_port);
unregister_scsi:
scsi_unregister(host);
return -ENODEV; return -ENODEV;
} }
static void __exit ecoscsi_exit(void) static void __exit ecoscsi_exit(void)
{ {
scsi_unregister_host(&ecoscsi_template); scsi_remove_host(host);
if (shpnt->irq != IRQ_NONE)
free_irq(shpnt->irq, NULL);
if (shpnt->io_port)
release_region(shpnt->io_port, shpnt->n_io_port);
scsi_unregister(host);
return 0;
} }
module_init(ecoscsi_init); module_init(ecoscsi_init);
......
This diff is collapsed.
...@@ -234,27 +234,18 @@ int scsi_remove_host(struct Scsi_Host *shost) ...@@ -234,27 +234,18 @@ int scsi_remove_host(struct Scsi_Host *shost)
int scsi_add_host(struct Scsi_Host *shost, struct device *dev) int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
{ {
Scsi_Host_Template *sht = shost->hostt; Scsi_Host_Template *sht = shost->hostt;
struct scsi_device *sdev; int error;
int error = 0, saved_error = 0;
printk(KERN_INFO "scsi%d : %s\n", shost->host_no, printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
sht->info ? sht->info(shost) : sht->name); sht->info ? sht->info(shost) : sht->name);
error = scsi_sysfs_add_host(shost, dev); error = scsi_sysfs_add_host(shost, dev);
if (error) if (!error) {
return error; scsi_proc_host_add(shost);
scsi_scan_host(shost);
scsi_proc_host_add(shost); };
scsi_scan_host(shost);
list_for_each_entry (sdev, &shost->my_devices, siblings) { return error;
error = scsi_attach_device(sdev);
if (error)
saved_error = error;
}
return saved_error;
} }
/** /**
...@@ -500,60 +491,43 @@ int scsi_unregister_host(Scsi_Host_Template *shost_tp) ...@@ -500,60 +491,43 @@ int scsi_unregister_host(Scsi_Host_Template *shost_tp)
} }
/** /**
* *scsi_host_get_next - get scsi host and inc ref count * scsi_host_lookup - get a reference to a Scsi_Host by host no
* @shost: pointer to a Scsi_Host or NULL to start. *
* @hostnum: host number to locate
* *
* Return value: * Return value:
* A pointer to next Scsi_Host in list or NULL. * A pointer to located Scsi_Host or NULL.
**/ **/
struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *shost) struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
{ {
struct list_head *lh = NULL; struct class *class = class_get(&shost_class);
struct class_device *cdev;
spin_lock(&scsi_host_list_lock); struct Scsi_Host *shost = NULL, *p;
if (shost) {
/* XXX Dec ref on cur shost */ if (class) {
lh = shost->sh_list.next; down_read(&class->subsys.rwsem);
} else { list_for_each_entry(cdev, &class->children, node) {
lh = scsi_host_list.next; p = class_to_shost(cdev);
} if (p->host_no == hostnum) {
scsi_host_get(p);
if (lh == &scsi_host_list) { shost = p;
shost = (struct Scsi_Host *)NULL; break;
goto done; }
}
up_read(&class->subsys.rwsem);
} }
shost = list_entry(lh, struct Scsi_Host, sh_list);
/* XXX Inc ref count */
done:
spin_unlock(&scsi_host_list_lock);
return shost; return shost;
} }
/**
* scsi_host_hn_get - get a Scsi_Host by host no and inc ref count
* @host_no: host number to locate
*
* Return value:
* A pointer to located Scsi_Host or NULL.
**/
struct Scsi_Host *scsi_host_hn_get(unsigned short host_no)
{
/* XXX Inc ref count */
return scsi_find_host_by_num(host_no);
}
/** /**
* *scsi_host_get - inc a Scsi_Host ref count * *scsi_host_get - inc a Scsi_Host ref count
* @shost: Pointer to Scsi_Host to inc. * @shost: Pointer to Scsi_Host to inc.
**/ **/
void scsi_host_get(struct Scsi_Host *shost) void scsi_host_get(struct Scsi_Host *shost)
{ {
get_device(&shost->host_gendev); get_device(&shost->host_gendev);
class_device_get(&shost->class_dev); class_device_get(&shost->class_dev);
return;
} }
/** /**
...@@ -565,7 +539,6 @@ void scsi_host_put(struct Scsi_Host *shost) ...@@ -565,7 +539,6 @@ void scsi_host_put(struct Scsi_Host *shost)
class_device_put(&shost->class_dev); class_device_put(&shost->class_dev);
put_device(&shost->host_gendev); put_device(&shost->host_gendev);
return;
} }
/** /**
......
...@@ -542,25 +542,23 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost) ...@@ -542,25 +542,23 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
return shost->host_gendev.parent; return shost->host_gendev.parent;
} }
struct Scsi_Device_Template struct scsi_driver {
{ struct module *owner;
struct list_head list; struct device_driver gendrv;
const char * name;
struct module * module; /* Used for loadable modules */ int (*init_command)(struct scsi_cmnd *);
unsigned char scsi_type; void (*rescan)(struct device *);
int (*attach)(Scsi_Device *); /* Attach devices to arrays */
void (*detach)(Scsi_Device *);
int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
Selects command for blkdevs */
void (*rescan)(Scsi_Device *);
struct device_driver scsi_driverfs_driver;
}; };
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
/* extern int scsi_register_driver(struct device_driver *);
* Highlevel driver registration/unregistration. #define scsi_unregister_driver(drv) \
*/ driver_unregister(drv);
extern int scsi_register_device(struct Scsi_Device_Template *);
extern int scsi_unregister_device(struct Scsi_Device_Template *); extern int scsi_register_interface(struct class_interface *);
#define scsi_unregister_interface(intf) \
class_interface_unregister(intf)
/* /*
* HBA allocation/freeing. * HBA allocation/freeing.
......
...@@ -771,6 +771,10 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -771,6 +771,10 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd) static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
{ {
idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_scsi_t *scsi = drive_to_idescsi(drive);
/* this was a layering violation and we can't support it
anymore, sorry. */
#if 0
struct gendisk *disk = cmd->request->rq_disk; struct gendisk *disk = cmd->request->rq_disk;
if (disk) { if (disk) {
...@@ -778,6 +782,7 @@ static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd) ...@@ -778,6 +782,7 @@ static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0) if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
} }
#endif
return test_bit(IDESCSI_TRANSFORM, &scsi->transform); return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
} }
......
...@@ -254,7 +254,7 @@ static inline int imm_proc_write(int hostno, char *buffer, int length) ...@@ -254,7 +254,7 @@ static inline int imm_proc_write(int hostno, char *buffer, int length)
} }
int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
int length, int hostno, int inout) int length, int inout)
{ {
int i; int i;
int len = 0; int len = 0;
......
...@@ -159,6 +159,7 @@ int imm_command(Scsi_Cmnd *); ...@@ -159,6 +159,7 @@ int imm_command(Scsi_Cmnd *);
int imm_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); int imm_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
int imm_abort(Scsi_Cmnd *); int imm_abort(Scsi_Cmnd *);
int imm_reset(Scsi_Cmnd *); int imm_reset(Scsi_Cmnd *);
int imm_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
int imm_biosparam(struct scsi_device *, struct block_device *, int imm_biosparam(struct scsi_device *, struct block_device *,
sector_t, int *); sector_t, int *);
......
...@@ -278,14 +278,12 @@ static const int nsp32_table_pci_num = ...@@ -278,14 +278,12 @@ static const int nsp32_table_pci_num =
/* /*
* function declaration * function declaration
*/ */
static int nsp32_detect(Scsi_Host_Template *);
static int nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static const char *nsp32_info(struct Scsi_Host *); static const char *nsp32_info(struct Scsi_Host *);
static int nsp32_eh_abort(Scsi_Cmnd *); static int nsp32_eh_abort(Scsi_Cmnd *);
static int nsp32_eh_bus_reset(Scsi_Cmnd *); static int nsp32_eh_bus_reset(Scsi_Cmnd *);
static int nsp32_eh_host_reset(Scsi_Cmnd *); static int nsp32_eh_host_reset(Scsi_Cmnd *);
static int nsp32_reset(Scsi_Cmnd *, unsigned int); static int nsp32_reset(Scsi_Cmnd *, unsigned int);
static int nsp32_release(struct Scsi_Host *);
static int nsp32_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int nsp32_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *); static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit nsp32_remove(struct pci_dev *); static void __devexit nsp32_remove(struct pci_dev *);
...@@ -335,11 +333,10 @@ static inline int nsp32_prom_get(nsp32_hw_data *, int); ...@@ -335,11 +333,10 @@ static inline int nsp32_prom_get(nsp32_hw_data *, int);
/* /*
* max_sectors is currently limited up to 128. * max_sectors is currently limited up to 128.
*/ */
static Scsi_Host_Template driver_template = { static Scsi_Host_Template nsp32_template = {
.proc_name = "nsp32",
.name = "Workbit NinjaSCSI-32Bi/UDE", .name = "Workbit NinjaSCSI-32Bi/UDE",
.proc_name = "nsp32",
.proc_info = nsp32_proc_info, .proc_info = nsp32_proc_info,
.detect = nsp32_detect,
.info = nsp32_info, .info = nsp32_info,
.queuecommand = nsp32_queuecommand, .queuecommand = nsp32_queuecommand,
.can_queue = 1, .can_queue = 1,
...@@ -352,12 +349,6 @@ static Scsi_Host_Template driver_template = { ...@@ -352,12 +349,6 @@ static Scsi_Host_Template driver_template = {
.eh_device_reset_handler = NULL, .eh_device_reset_handler = NULL,
.eh_bus_reset_handler = nsp32_eh_bus_reset, .eh_bus_reset_handler = nsp32_eh_bus_reset,
.eh_host_reset_handler = nsp32_eh_host_reset, .eh_host_reset_handler = nsp32_eh_host_reset,
.release = nsp32_release,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
.use_new_eh_code = 1,
#else
/* .highmem_io = 1, */
#endif
}; };
#include "nsp32_io.h" #include "nsp32_io.h"
...@@ -1618,7 +1609,7 @@ static int nsp32_proc_info(struct Scsi_Host *host, char *buffer, ...@@ -1618,7 +1609,7 @@ static int nsp32_proc_info(struct Scsi_Host *host, char *buffer,
* 0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly) * 0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly)
* 0xc00-0xfff: CardBus status registers * 0xc00-0xfff: CardBus status registers
*/ */
static int nsp32_detect(Scsi_Host_Template *sht) static int nsp32_detect(struct pci_dev *pdev)
{ {
struct Scsi_Host *host; /* registered host structure */ struct Scsi_Host *host; /* registered host structure */
int ret; int ret;
...@@ -1630,7 +1621,7 @@ static int nsp32_detect(Scsi_Host_Template *sht) ...@@ -1630,7 +1621,7 @@ static int nsp32_detect(Scsi_Host_Template *sht)
/* /*
* register this HBA as SCSI device * register this HBA as SCSI device
*/ */
host = scsi_register(sht, sizeof(nsp32_hw_data)); host = scsi_register(&nsp32_template, sizeof(nsp32_hw_data));
if (host == NULL) { if (host == NULL) {
nsp32_msg (KERN_ERR, "failed to scsi register"); nsp32_msg (KERN_ERR, "failed to scsi register");
goto err; goto err;
...@@ -1793,8 +1784,6 @@ static int nsp32_detect(Scsi_Host_Template *sht) ...@@ -1793,8 +1784,6 @@ static int nsp32_detect(Scsi_Host_Template *sht)
"NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x", "NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x",
host->irq, host->io_port, host->n_io_port); host->irq, host->io_port, host->n_io_port);
sht->name = data->info_str;
/* /*
* SCSI bus reset * SCSI bus reset
* *
...@@ -1832,7 +1821,9 @@ static int nsp32_detect(Scsi_Host_Template *sht) ...@@ -1832,7 +1821,9 @@ static int nsp32_detect(Scsi_Host_Template *sht)
goto free_irq; goto free_irq;
} }
return 1; scsi_add_host(host, &pdev->dev);
pci_set_drvdata(pdev, host);
return 0;
free_irq: free_irq:
free_irq(host->irq, data); free_irq(host->irq, data);
...@@ -1852,43 +1843,7 @@ static int nsp32_detect(Scsi_Host_Template *sht) ...@@ -1852,43 +1843,7 @@ static int nsp32_detect(Scsi_Host_Template *sht)
scsi_unregister(host); scsi_unregister(host);
err: err:
return 0; return 1;
}
static int nsp32_release(struct Scsi_Host *shpnt)
{
nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata;
if (data->lunt_list) {
kfree(data->lunt_list);
}
if (data->autoparam) {
pci_free_consistent(data->Pci, AUTOPARAM_SIZE,
data->autoparam, data->apaddr);
}
if (data->sg_list) {
pci_free_consistent(data->Pci,
(sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN),
data->sg_list, data->sgaddr);
}
DEBUG(0, "free irq\n");
if (shpnt->irq) {
free_irq(shpnt->irq, data);
}
DEBUG(0, "free io\n");
if (shpnt->io_port && shpnt->n_io_port) {
release_region(shpnt->io_port, shpnt->n_io_port);
}
if (data->MmioAddress != 0) {
iounmap((void *)(data->MmioAddress));
}
return 0;
} }
static const char *nsp32_info(struct Scsi_Host *shpnt) static const char *nsp32_info(struct Scsi_Host *shpnt)
...@@ -2031,11 +1986,7 @@ static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_i ...@@ -2031,11 +1986,7 @@ static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_i
pci_set_master(pdev); pci_set_master(pdev);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)) ret = nsp32_detect(pdev);
scsi_register_host(&driver_template);
#else
scsi_register_module(MODULE_SCSI_HA, &driver_template);
#endif
nsp32_msg(KERN_INFO, "nsp32 irq: %i mmio: 0x%lx slot: %s model: %s", nsp32_msg(KERN_INFO, "nsp32 irq: %i mmio: 0x%lx slot: %s model: %s",
pdev->irq, data->MmioAddress, pdev->slot_name, pdev->irq, data->MmioAddress, pdev->slot_name,
...@@ -2043,18 +1994,23 @@ static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_i ...@@ -2043,18 +1994,23 @@ static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_i
nsp32_dbg(NSP32_DEBUG_REGISTER, "exit"); nsp32_dbg(NSP32_DEBUG_REGISTER, "exit");
return 0; return ret;
} }
static void __devexit nsp32_remove(struct pci_dev *pdev) static void __devexit nsp32_remove(struct pci_dev *pdev)
{ {
nsp32_dbg(NSP32_DEBUG_REGISTER, "enter"); struct Scsi_Host *shpnt = pci_get_drvdata(pdev);
nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_unregister_host(&driver_template); kfree(data->lunt_list);
#else pci_free_consistent(data->Pci, AUTOPARAM_SIZE,
scsi_unregister_module(MODULE_SCSI_HA, &driver_template); data->autoparam, data->apaddr);
#endif pci_free_consistent(data->Pci,
(sizeof(struct nsp32_sgtable) * NSP_SG_SIZE*MAX_TARGET*MAX_LUN),
data->sg_list, data->sgaddr);
free_irq(shpnt->irq, data);
release_region(shpnt->io_port, shpnt->n_io_port);
iounmap((void *)(data->MmioAddress));
} }
static struct pci_device_id nsp32_pci_table[] __devinitdata = { static struct pci_device_id nsp32_pci_table[] __devinitdata = {
......
...@@ -160,19 +160,15 @@ static int osst_zero_buffer_tail(OSST_buffer *); ...@@ -160,19 +160,15 @@ static int osst_zero_buffer_tail(OSST_buffer *);
static int osst_copy_to_buffer(OSST_buffer *, unsigned char *); static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
static int osst_copy_from_buffer(OSST_buffer *, unsigned char *); static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
static int osst_attach(Scsi_Device *); static int osst_probe(struct device *);
static void osst_detach(Scsi_Device *); static int osst_remove(struct device *);
struct Scsi_Device_Template osst_template = struct scsi_driver osst_template = {
{ .owner = THIS_MODULE,
.module = THIS_MODULE, .gendrv = {
.list = LIST_HEAD_INIT(osst_template.list), .name = "osst",
.name = "OnStream Tape", .probe = osst_probe,
.scsi_type = TYPE_TAPE, .remove = osst_remove,
.attach = osst_attach,
.detach = osst_detach,
.scsi_driverfs_driver = {
.name = "osst",
} }
}; };
...@@ -5326,22 +5322,6 @@ __setup("osst=", osst_setup); ...@@ -5326,22 +5322,6 @@ __setup("osst=", osst_setup);
#endif #endif
/* Driverfs file support */
static ssize_t osst_device_kdev_read(struct device *driverfs_dev, char *page)
{
kdev_t kdev;
kdev.value=(int)(long)driverfs_dev->driver_data;
return sprintf(page, "%x\n",kdev.value);
}
static DEVICE_ATTR(kdev,S_IRUGO,osst_device_kdev_read,NULL);
static ssize_t osst_device_type_read(struct device *driverfs_dev, char *page)
{
return sprintf (page, "CHR\n");
}
static DEVICE_ATTR(type,S_IRUGO,osst_device_type_read,NULL);
static struct file_operations osst_fops = { static struct file_operations osst_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.read = osst_read, .read = osst_read,
...@@ -5384,8 +5364,9 @@ static struct osst_support_data support_list[] = { ...@@ -5384,8 +5364,9 @@ static struct osst_support_data support_list[] = {
* osst startup / cleanup code * osst startup / cleanup code
*/ */
static int osst_attach(Scsi_Device * SDp) static int osst_probe(struct device *dev)
{ {
Scsi_Device * SDp = to_scsi_device(dev);
OS_Scsi_Tape * tpnt; OS_Scsi_Tape * tpnt;
ST_mode * STm; ST_mode * STm;
ST_partstat * STps; ST_partstat * STps;
...@@ -5394,12 +5375,12 @@ static int osst_attach(Scsi_Device * SDp) ...@@ -5394,12 +5375,12 @@ static int osst_attach(Scsi_Device * SDp)
int i, mode, dev_num; int i, mode, dev_num;
if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
return 1; return -ENODEV;
drive = alloc_disk(1); drive = alloc_disk(1);
if (!drive) { if (!drive) {
printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n"); printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
return 1; return -ENODEV;
} }
/* if this is the first attach, build the infrastructure */ /* if this is the first attach, build the infrastructure */
...@@ -5521,45 +5502,12 @@ static int osst_attach(Scsi_Device * SDp) ...@@ -5521,45 +5502,12 @@ static int osst_attach(Scsi_Device * SDp)
write_unlock(&os_scsi_tapes_lock); write_unlock(&os_scsi_tapes_lock);
for (mode = 0; mode < ST_NBR_MODES; ++mode) { for (mode = 0; mode < ST_NBR_MODES; ++mode) {
char name[8];
/* Rewind entry */ /* Rewind entry */
sprintf(name, "ot%s", osst_formats[mode]);
sprintf(tpnt->driverfs_dev_r[mode].bus_id, "%s:%s",
SDp->sdev_driverfs_dev.bus_id, name);
sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s",
SDp->sdev_driverfs_dev.name, name);
tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev;
tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus;
tpnt->driverfs_dev_r[mode].driver_data =
(void *)(long)__mkdev(OSST_MAJOR, dev_num + (mode << 5));
device_register(&tpnt->driverfs_dev_r[mode]);
device_create_file(&tpnt->driverfs_dev_r[mode],
&dev_attr_type);
device_create_file(&tpnt->driverfs_dev_r[mode], &dev_attr_kdev);
devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)), devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
S_IFCHR | S_IRUGO | S_IWUGO, S_IFCHR | S_IRUGO | S_IWUGO,
"%s/ot%s", SDp->devfs_name, osst_formats[mode]); "%s/ot%s", SDp->devfs_name, osst_formats[mode]);
/* No-rewind entry */ /* No-rewind entry */
sprintf (name, "ot%sn", osst_formats[mode]);
sprintf(tpnt->driverfs_dev_n[mode].bus_id, "%s:%s",
SDp->sdev_driverfs_dev.bus_id, name);
sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s",
SDp->sdev_driverfs_dev.name, name);
tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev;
tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus;
tpnt->driverfs_dev_n[mode].driver_data =
(void *)(long)__mkdev(OSST_MAJOR, dev_num + (mode << 5) + 128);
device_register(&tpnt->driverfs_dev_n[mode]);
device_create_file(&tpnt->driverfs_dev_n[mode],
&dev_attr_type);
device_create_file(&tpnt->driverfs_dev_n[mode],
&dev_attr_kdev);
devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128), devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128),
S_IFCHR | S_IRUGO | S_IWUGO, S_IFCHR | S_IRUGO | S_IWUGO,
"%s/ot%sn", SDp->devfs_name, osst_formats[mode]); "%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
...@@ -5574,16 +5522,17 @@ static int osst_attach(Scsi_Device * SDp) ...@@ -5574,16 +5522,17 @@ static int osst_attach(Scsi_Device * SDp)
out_put_disk: out_put_disk:
put_disk(drive); put_disk(drive);
return 1; return -ENODEV;
}; };
static void osst_detach(Scsi_Device * SDp) static int osst_remove(struct device *dev)
{ {
Scsi_Device * SDp = to_scsi_device(dev);
OS_Scsi_Tape * tpnt; OS_Scsi_Tape * tpnt;
int i, mode; int i, mode;
if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
return; return 0;
write_lock(&os_scsi_tapes_lock); write_lock(&os_scsi_tapes_lock);
for(i=0; i < osst_max_dev; i++) { for(i=0; i < osst_max_dev; i++) {
...@@ -5598,29 +5547,17 @@ static void osst_detach(Scsi_Device * SDp) ...@@ -5598,29 +5547,17 @@ static void osst_detach(Scsi_Device * SDp)
os_scsi_tapes[i] = NULL; os_scsi_tapes[i] = NULL;
osst_nr_dev--; osst_nr_dev--;
write_unlock(&os_scsi_tapes_lock); write_unlock(&os_scsi_tapes_lock);
for (mode = 0; mode < ST_NBR_MODES; ++mode) {
device_remove_file(&tpnt->driverfs_dev_r[mode],
&dev_attr_type);
device_remove_file(&tpnt->driverfs_dev_r[mode],
&dev_attr_kdev);
device_unregister(&tpnt->driverfs_dev_r[mode]);
device_remove_file(&tpnt->driverfs_dev_n[mode],
&dev_attr_type);
device_remove_file(&tpnt->driverfs_dev_n[mode],
&dev_attr_kdev);
device_unregister(&tpnt->driverfs_dev_n[mode]);
}
if (tpnt->header_cache != NULL) vfree(tpnt->header_cache); if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
if (tpnt->buffer) { if (tpnt->buffer) {
normalize_buffer(tpnt->buffer); normalize_buffer(tpnt->buffer);
kfree(tpnt->buffer); kfree(tpnt->buffer);
} }
kfree(tpnt); kfree(tpnt);
return; return 0;
} }
} }
write_unlock(&os_scsi_tapes_lock); write_unlock(&os_scsi_tapes_lock);
return; return 0;
} }
static int __init init_osst(void) static int __init init_osst(void)
...@@ -5629,7 +5566,7 @@ static int __init init_osst(void) ...@@ -5629,7 +5566,7 @@ static int __init init_osst(void)
validate_options(); validate_options();
if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_device(&osst_template)) { if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
return 1; return 1;
} }
...@@ -5642,7 +5579,7 @@ static void __exit exit_osst (void) ...@@ -5642,7 +5579,7 @@ static void __exit exit_osst (void)
int i; int i;
OS_Scsi_Tape * STp; OS_Scsi_Tape * STp;
scsi_unregister_device(&osst_template); scsi_unregister_driver(&osst_template.gendrv);
unregister_chrdev(OSST_MAJOR, "osst"); unregister_chrdev(OSST_MAJOR, "osst");
if (os_scsi_tapes) { if (os_scsi_tapes) {
......
...@@ -530,7 +530,7 @@ typedef struct { ...@@ -530,7 +530,7 @@ typedef struct {
/* The OnStream tape drive descriptor */ /* The OnStream tape drive descriptor */
typedef struct { typedef struct {
struct Scsi_Device_Template *driver; struct scsi_driver *driver;
unsigned capacity; unsigned capacity;
Scsi_Device* device; Scsi_Device* device;
struct semaphore lock; /* for serialization */ struct semaphore lock; /* for serialization */
...@@ -555,8 +555,6 @@ typedef struct { ...@@ -555,8 +555,6 @@ typedef struct {
/* Mode characteristics */ /* Mode characteristics */
ST_mode modes[ST_NBR_MODES]; ST_mode modes[ST_NBR_MODES];
int current_mode; int current_mode;
struct device driverfs_dev_r[ST_NBR_MODES];
struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */ /* Status variables */
int partition; int partition;
......
...@@ -277,7 +277,7 @@ int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs ...@@ -277,7 +277,7 @@ int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
int len = 0; int len = 0;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (ppa_hosts[i] == host) if (ppa_hosts[i].host == host->host_no)
break; break;
if (inout) if (inout)
......
...@@ -85,12 +85,6 @@ unsigned long scsi_pid; ...@@ -85,12 +85,6 @@ unsigned long scsi_pid;
struct scsi_cmnd *last_cmnd; struct scsi_cmnd *last_cmnd;
static unsigned long serial_number; static unsigned long serial_number;
/*
* List of all highlevel drivers.
*/
LIST_HEAD(scsi_devicelist);
static DECLARE_RWSEM(scsi_devicelist_mutex);
/* /*
* Note - the initial logging level can be set here to log events at boot time. * Note - the initial logging level can be set here to log events at boot time.
* After the system is up, you may enable logging via the /proc interface. * After the system is up, you may enable logging via the /proc interface.
...@@ -931,50 +925,6 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth) ...@@ -931,50 +925,6 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
return depth; return depth;
} }
int scsi_attach_device(struct scsi_device *sdev)
{
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
list_for_each_entry(sdt, &scsi_devicelist, list) {
if (!try_module_get(sdt->module))
continue;
(*sdt->attach)(sdev);
module_put(sdt->module);
}
up_read(&scsi_devicelist_mutex);
return 0;
}
void scsi_detach_device(struct scsi_device *sdev)
{
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
list_for_each_entry(sdt, &scsi_devicelist, list) {
if (!try_module_get(sdt->module))
continue;
(*sdt->detach)(sdev);
module_put(sdt->module);
}
up_read(&scsi_devicelist_mutex);
}
void scsi_rescan_device(struct scsi_device *sdev)
{
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
list_for_each_entry(sdt, &scsi_devicelist, list) {
if (!try_module_get(sdt->module))
continue;
if (*sdt->rescan)
(*sdt->rescan)(sdev);
module_put(sdt->module);
}
up_read(&scsi_devicelist_mutex);
}
int scsi_device_get(struct scsi_device *sdev) int scsi_device_get(struct scsi_device *sdev)
{ {
if (!try_module_get(sdev->host->hostt->module)) if (!try_module_get(sdev->host->hostt->module))
...@@ -1030,71 +980,6 @@ void scsi_set_device_offline(struct scsi_device *sdev) ...@@ -1030,71 +980,6 @@ void scsi_set_device_offline(struct scsi_device *sdev)
} }
} }
/*
* This entry point is called from the upper level module's module_init()
* routine. That implies that when this function is called, the
* scsi_mod module is locked down because of upper module layering and
* that the high level driver module is locked down by being in it's
* init routine. So, the *only* thing we have to do to protect adds
* we perform in this function is to make sure that all call's
* to the high level driver's attach() and detach() call in points, other
* than via scsi_register_device and scsi_unregister_device which are in
* the module_init and module_exit code respectively and therefore already
* locked down by the kernel module loader, are wrapped by try_module_get()
* and module_put() to avoid races on device adds and removes.
*/
int scsi_register_device(struct Scsi_Device_Template *tpnt)
{
struct scsi_device *sdev;
struct Scsi_Host *shpnt;
#ifdef CONFIG_KMOD
if (scsi_host_get_next(NULL) == NULL)
request_module("scsi_hostadapter");
#endif
if (!list_empty(&tpnt->list))
return 1;
down_write(&scsi_devicelist_mutex);
list_add_tail(&tpnt->list, &scsi_devicelist);
up_write(&scsi_devicelist_mutex);
scsi_upper_driver_register(tpnt);
for (shpnt = scsi_host_get_next(NULL); shpnt;
shpnt = scsi_host_get_next(shpnt))
list_for_each_entry(sdev, &shpnt->my_devices, siblings)
(*tpnt->attach)(sdev);
return 0;
}
int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
{
struct scsi_device *sdev;
struct Scsi_Host *shpnt;
/*
* Next, detach the devices from the driver.
*/
for (shpnt = scsi_host_get_next(NULL); shpnt;
shpnt = scsi_host_get_next(shpnt)) {
list_for_each_entry(sdev, &shpnt->my_devices, siblings)
(*tpnt->detach)(sdev);
}
/*
* Extract the template from the linked list.
*/
down_write(&scsi_devicelist_mutex);
list_del(&tpnt->list);
up_write(&scsi_devicelist_mutex);
scsi_upper_driver_unregister(tpnt);
return 0;
}
MODULE_DESCRIPTION("SCSI core"); MODULE_DESCRIPTION("SCSI core");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -316,6 +316,7 @@ extern const char *scsi_extd_sense_format(unsigned char, unsigned char); ...@@ -316,6 +316,7 @@ extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
*/ */
struct scsi_device { struct scsi_device {
struct class_device sdev_classdev;
/* /*
* This information is private to the scsi mid-layer. * This information is private to the scsi mid-layer.
*/ */
......
...@@ -612,29 +612,6 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) ...@@ -612,29 +612,6 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
cmd->request_bufflen = 0; cmd->request_bufflen = 0;
} }
/*
* Function: scsi_get_request_dev()
*
* Purpose: Find the upper-level driver that is responsible for this
* request
*
* Arguments: request - I/O request we are preparing to queue.
*
* Lock status: No locks assumed to be held, but as it happens the
* q->queue_lock is held when this is called.
*
* Returns: Nothing
*
* Notes: The requests in the request queue may have originated
* from any block device driver. We need to find out which
* one so that we can later form the appropriate command.
*/
static struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
{
struct gendisk *p = req->rq_disk;
return p ? *(struct Scsi_Device_Template **)p->private_data : NULL;
}
/* /*
* Function: scsi_io_completion() * Function: scsi_io_completion()
* *
...@@ -849,11 +826,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, int good_sectors, ...@@ -849,11 +826,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, int good_sectors,
return; return;
} }
if (result) { if (result) {
struct Scsi_Device_Template *sdt; printk("SCSI error : <%d %d %d %d> return code = 0x%x\n",
sdt = scsi_get_request_dev(cmd->request);
printk("SCSI %s error : <%d %d %d %d> return code = 0x%x\n",
(sdt ? sdt->name : "device"),
cmd->device->host->host_no, cmd->device->host->host_no,
cmd->device->channel, cmd->device->channel,
cmd->device->id, cmd->device->id,
...@@ -947,7 +920,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd) ...@@ -947,7 +920,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
static int scsi_prep_fn(struct request_queue *q, struct request *req) static int scsi_prep_fn(struct request_queue *q, struct request *req)
{ {
struct Scsi_Device_Template *sdt;
struct scsi_device *sdev = q->queuedata; struct scsi_device *sdev = q->queuedata;
struct scsi_cmnd *cmd; struct scsi_cmnd *cmd;
...@@ -1003,6 +975,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -1003,6 +975,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* happening now. * happening now.
*/ */
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
struct scsi_driver *drv;
int ret; int ret;
/* /*
...@@ -1017,8 +990,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -1017,8 +990,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* some kinds of consistency checking may cause the * some kinds of consistency checking may cause the
* request to be rejected immediately. * request to be rejected immediately.
*/ */
sdt = scsi_get_request_dev(req);
BUG_ON(!sdt);
/* /*
* This sets up the scatter-gather table (allocating if * This sets up the scatter-gather table (allocating if
...@@ -1031,7 +1002,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) ...@@ -1031,7 +1002,8 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
/* /*
* Initialize the actual SCSI command for this request. * Initialize the actual SCSI command for this request.
*/ */
if (unlikely(!sdt->init_command(cmd))) { drv = *(struct scsi_driver **)req->rq_disk->private_data;
if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd); scsi_release_buffers(cmd);
scsi_put_command(cmd); scsi_put_command(cmd);
return BLKPREP_KILL; return BLKPREP_KILL;
......
...@@ -15,21 +15,6 @@ ...@@ -15,21 +15,6 @@
#include "hosts.h" #include "hosts.h"
/* XXX - For now, we assume the first (i.e. having the least host_no)
real (i.e. non-emulated) host adapter shall be BIOS-controlled one.
We *SHOULD* invent another way. */
static inline struct Scsi_Host *first_real_host(void)
{
struct Scsi_Host *shost = NULL;
while ((shost = scsi_host_get_next(shost))) {
if (!shost->hostt->emulated)
break;
}
return shost;
}
static int pc98_first_bios_param(struct scsi_device *sdev, int *ip) static int pc98_first_bios_param(struct scsi_device *sdev, int *ip)
{ {
const u8 *p = (&__PC9800SCA(u8, PC9800SCA_SCSI_PARAMS) + sdev->id * 4); const u8 *p = (&__PC9800SCA(u8, PC9800SCA_SCSI_PARAMS) + sdev->id * 4);
...@@ -50,7 +35,16 @@ int pc98_bios_param(struct scsi_device *sdev, struct block_device *bdev, ...@@ -50,7 +35,16 @@ int pc98_bios_param(struct scsi_device *sdev, struct block_device *bdev,
{ {
struct Scsi_Host *first_real = first_real_host(); struct Scsi_Host *first_real = first_real_host();
if (sdev->host == first_real && sdev->id < 7 && /*
* XXX
* XXX This needs to become a sysfs attribute that's set
* XXX by code that knows which host is the first one.
* XXX
* XXX Currently we support only one host on with a
* XXX PC98ish HBA.
* XXX
*/
if (1 || sdev->host == first_real && sdev->id < 7 &&
__PC9800SCA_TEST_BIT(PC9800SCA_DISK_EQUIPS, sdev->id)) __PC9800SCA_TEST_BIT(PC9800SCA_DISK_EQUIPS, sdev->id))
return pc98_first_bios_param(sdev, ip); return pc98_first_bios_param(sdev, ip);
......
...@@ -41,9 +41,6 @@ ...@@ -41,9 +41,6 @@
#define SCSI_SENSE_VALID(scmd) \ #define SCSI_SENSE_VALID(scmd) \
(((scmd)->sense_buffer[0] & 0x70) == 0x70) (((scmd)->sense_buffer[0] & 0x70) == 0x70)
struct Scsi_Device_Template;
/* /*
* scsi_target: representation of a scsi target, for now, this is only * scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target, * used for single_lun devices. If no one has active IO to the target,
...@@ -58,8 +55,7 @@ struct scsi_target { ...@@ -58,8 +55,7 @@ struct scsi_target {
/* hosts.c */ /* hosts.c */
extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *); extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *); extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
extern struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *); extern struct Scsi_Host *scsi_host_lookup(unsigned short);
extern struct Scsi_Host *scsi_host_hn_get(unsigned short);
extern void scsi_host_put(struct Scsi_Host *); extern void scsi_host_put(struct Scsi_Host *);
extern void scsi_host_init(void); extern void scsi_host_init(void);
...@@ -70,9 +66,6 @@ extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); ...@@ -70,9 +66,6 @@ extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
extern void scsi_done(struct scsi_cmnd *cmd); extern void scsi_done(struct scsi_cmnd *cmd);
extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern int scsi_retry_command(struct scsi_cmnd *cmd); extern int scsi_retry_command(struct scsi_cmnd *cmd);
extern int scsi_attach_device(struct scsi_device *sdev);
extern void scsi_detach_device(struct scsi_device *sdev);
extern void scsi_rescan_device(struct scsi_device *sdev);
extern int scsi_insert_special_req(struct scsi_request *sreq, int); extern int scsi_insert_special_req(struct scsi_request *sreq, int);
extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq); struct scsi_request *sreq);
...@@ -119,12 +112,11 @@ extern void scsi_forget_host(struct Scsi_Host *shost); ...@@ -119,12 +112,11 @@ extern void scsi_forget_host(struct Scsi_Host *shost);
extern void scsi_free_sdev(struct scsi_device *); extern void scsi_free_sdev(struct scsi_device *);
extern void scsi_free_shost(struct Scsi_Host *); extern void scsi_free_shost(struct Scsi_Host *);
extern void scsi_host_get(struct Scsi_Host *); extern void scsi_host_get(struct Scsi_Host *);
extern void scsi_rescan_device(struct device *dev);
/* scsi_sysfs.c */ /* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *); extern int scsi_device_register(struct scsi_device *);
extern void scsi_device_unregister(struct scsi_device *); extern void scsi_device_unregister(struct scsi_device *);
extern int scsi_upper_driver_register(struct Scsi_Device_Template *);
extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *);
extern void scsi_sysfs_init_host(struct Scsi_Host *); extern void scsi_sysfs_init_host(struct Scsi_Host *);
extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *); extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
extern void scsi_sysfs_remove_host(struct Scsi_Host *); extern void scsi_sysfs_remove_host(struct Scsi_Host *);
...@@ -136,4 +128,7 @@ extern void scsi_sysfs_unregister(void); ...@@ -136,4 +128,7 @@ extern void scsi_sysfs_unregister(void);
extern struct class_device_attribute *scsi_sysfs_shost_attrs[]; extern struct class_device_attribute *scsi_sysfs_shost_attrs[];
extern struct device_attribute *scsi_sysfs_sdev_attrs[]; extern struct device_attribute *scsi_sysfs_sdev_attrs[];
extern struct class shost_class;
extern struct bus_type scsi_bus_type;
#endif /* _SCSI_PRIV_H */ #endif /* _SCSI_PRIV_H */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "scsi.h" #include "scsi.h"
...@@ -86,7 +87,7 @@ static int proc_scsi_read(char *buffer, char **start, off_t offset, ...@@ -86,7 +87,7 @@ static int proc_scsi_read(char *buffer, char **start, off_t offset,
return n; return n;
} }
static int proc_scsi_write(struct file *file, const char *buf, static int proc_scsi_write_proc(struct file *file, const char *buf,
unsigned long count, void *data) unsigned long count, void *data)
{ {
struct Scsi_Host *shost = data; struct Scsi_Host *shost = data;
...@@ -137,7 +138,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost) ...@@ -137,7 +138,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
return; return;
} }
p->write_proc = proc_scsi_write; p->write_proc = proc_scsi_write_proc;
p->owner = shost->hostt->module; p->owner = shost->hostt->module;
} }
...@@ -152,96 +153,52 @@ void scsi_proc_host_rm(struct Scsi_Host *shost) ...@@ -152,96 +153,52 @@ void scsi_proc_host_rm(struct Scsi_Host *shost)
remove_proc_entry(shost->hostt->proc_name, proc_scsi); remove_proc_entry(shost->hostt->proc_name, proc_scsi);
} }
static void proc_print_scsidevice(struct scsi_device* sdev, char *buffer, static int proc_print_scsidevice(struct device *dev, void *data)
int *size, int len)
{ {
struct scsi_device *sdev = to_scsi_device(dev);
int x, y = *size; struct seq_file *s = data;
extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE]; int i;
y = sprintf(buffer + len, seq_printf(s,
"Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ", "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
for (x = 0; x < 8; x++) { for (i = 0; i < 8; i++) {
if (sdev->vendor[x] >= 0x20) if (sdev->vendor[i] >= 0x20)
y += sprintf(buffer + len + y, "%c", sdev->vendor[x]); seq_printf(s, "%c", sdev->vendor[i]);
else else
y += sprintf(buffer + len + y, " "); seq_printf(s, " ");
} }
y += sprintf(buffer + len + y, " Model: ");
for (x = 0; x < 16; x++) { seq_printf(s, " Model: ");
if (sdev->model[x] >= 0x20) for (i = 0; i < 16; i++) {
y += sprintf(buffer + len + y, "%c", sdev->model[x]); if (sdev->model[i] >= 0x20)
seq_printf(s, "%c", sdev->model[i]);
else else
y += sprintf(buffer + len + y, " "); seq_printf(s, " ");
} }
y += sprintf(buffer + len + y, " Rev: ");
for (x = 0; x < 4; x++) { seq_printf(s, " Rev: ");
if (sdev->rev[x] >= 0x20) for (i = 0; i < 4; i++) {
y += sprintf(buffer + len + y, "%c", sdev->rev[x]); if (sdev->rev[i] >= 0x20)
seq_printf(s, "%c", sdev->rev[i]);
else else
y += sprintf(buffer + len + y, " "); seq_printf(s, " ");
} }
y += sprintf(buffer + len + y, "\n");
y += sprintf(buffer + len + y, " Type: %s ", seq_printf(s, "\n");
seq_printf(s, " Type: %s ",
sdev->type < MAX_SCSI_DEVICE_CODE ? sdev->type < MAX_SCSI_DEVICE_CODE ?
scsi_device_types[(int) sdev->type] : "Unknown "); scsi_device_types[(int) sdev->type] : "Unknown ");
y += sprintf(buffer + len + y, " ANSI" seq_printf(s, " ANSI"
" SCSI revision: %02x", (sdev->scsi_level - 1) ? " SCSI revision: %02x", (sdev->scsi_level - 1) ?
sdev->scsi_level - 1 : 1); sdev->scsi_level - 1 : 1);
if (sdev->scsi_level == 2) if (sdev->scsi_level == 2)
y += sprintf(buffer + len + y, " CCS\n"); seq_printf(s, " CCS\n");
else else
y += sprintf(buffer + len + y, "\n"); seq_printf(s, "\n");
*size = y;
return;
}
static int scsi_proc_info(char *buffer, char **start, off_t offset, int length) return 0;
{
struct Scsi_Host *shost;
Scsi_Device *sdev;
int size, len = 0;
off_t begin = 0;
off_t pos = 0;
/*
* First, see if there are any attached devices or not.
*/
for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) {
if (!list_empty(&shost->my_devices)) {
break;
}
}
size = sprintf(buffer + len, "Attached devices: %s\n",
(shost) ? "" : "none");
len += size;
pos = begin + len;
for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) {
list_for_each_entry(sdev, &shost->my_devices, siblings) {
proc_print_scsidevice(sdev, buffer, &size, len);
len += size;
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
if (pos > offset + length)
goto stop_output;
}
}
stop_output:
*start = buffer + (offset - begin); /* Start of wanted data */
len -= (offset - begin); /* Start slop */
if (len > length)
len = length; /* Ending slop */
return (len);
} }
static int scsi_add_single_device(uint host, uint channel, uint id, uint lun) static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
...@@ -250,7 +207,7 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun) ...@@ -250,7 +207,7 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
struct scsi_device *sdev; struct scsi_device *sdev;
int error = -ENODEV; int error = -ENODEV;
shost = scsi_host_hn_get(host); shost = scsi_host_lookup(host);
if (!shost) if (!shost)
return -ENODEV; return -ENODEV;
...@@ -272,7 +229,7 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -272,7 +229,7 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
struct Scsi_Host *shost; struct Scsi_Host *shost;
int error = -ENODEV; int error = -ENODEV;
shost = scsi_host_hn_get(host); shost = scsi_host_lookup(host);
if (!shost) if (!shost)
return -ENODEV; return -ENODEV;
sdev = scsi_find_device(shost, channel, id, lun); sdev = scsi_find_device(shost, channel, id, lun);
...@@ -287,8 +244,8 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -287,8 +244,8 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
return error; return error;
} }
static int proc_scsi_gen_write(struct file * file, const char * buf, static int proc_scsi_write(struct file *file, const char* buf,
unsigned long length, void *data) size_t length, loff_t *ppos)
{ {
int host, channel, id, lun; int host, channel, id, lun;
char *buffer, *p; char *buffer, *p;
...@@ -431,6 +388,30 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, ...@@ -431,6 +388,30 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
return err; return err;
} }
static int proc_scsi_show(struct seq_file *s, void *p)
{
seq_printf(s, "Attached devices:\n");
bus_for_each_dev(&scsi_bus_type, NULL, s, proc_print_scsidevice);
return 0;
}
static int proc_scsi_open(struct inode *inode, struct file *file)
{
/*
* We don't really needs this for the write case but it doesn't
* harm either.
*/
return single_open(file, proc_scsi_show, NULL);
}
static struct file_operations proc_scsi_operations = {
.open = proc_scsi_open,
.read = seq_read,
.write = proc_scsi_write,
.llseek = seq_lseek,
.release = single_release,
};
int __init scsi_init_procfs(void) int __init scsi_init_procfs(void)
{ {
struct proc_dir_entry *pde; struct proc_dir_entry *pde;
...@@ -439,10 +420,10 @@ int __init scsi_init_procfs(void) ...@@ -439,10 +420,10 @@ int __init scsi_init_procfs(void)
if (!proc_scsi) if (!proc_scsi)
goto err1; goto err1;
pde = create_proc_info_entry("scsi/scsi", 0, 0, scsi_proc_info); pde = create_proc_entry("scsi/scsi", 0, NULL);
if (!pde) if (!pde)
goto err2; goto err2;
pde->write_proc = proc_scsi_gen_write; pde->proc_fops = &proc_scsi_operations;
return 0; return 0;
......
...@@ -1098,24 +1098,31 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost, ...@@ -1098,24 +1098,31 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
uint channel, uint id, uint lun) uint channel, uint id, uint lun)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
int error = -ENODEV, res; int res;
res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev); res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
if (res == SCSI_SCAN_LUN_PRESENT) if (res != SCSI_SCAN_LUN_PRESENT)
error = scsi_attach_device(sdev); sdev = ERR_PTR(-ENODEV);
if (error)
sdev = ERR_PTR(error);
return sdev; return sdev;
} }
int scsi_remove_device(struct scsi_device *sdev) int scsi_remove_device(struct scsi_device *sdev)
{ {
scsi_detach_device(sdev);
scsi_device_unregister(sdev); scsi_device_unregister(sdev);
return 0; return 0;
} }
void scsi_rescan_device(struct device *dev)
{
struct scsi_driver *drv = to_scsi_driver(dev->driver);
if (try_module_get(drv->owner)) {
if (drv->rescan)
drv->rescan(dev);
module_put(drv->owner);
}
}
/** /**
* scsi_scan_target - scan a target id, possibly including all LUNs on the * scsi_scan_target - scan a target id, possibly including all LUNs on the
* target. * target.
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
* This source file contains the symbol table used by scsi loadable * This source file contains the symbol table used by scsi loadable
* modules. * modules.
*/ */
EXPORT_SYMBOL(scsi_register_device); EXPORT_SYMBOL(scsi_register_driver);
EXPORT_SYMBOL(scsi_unregister_device); EXPORT_SYMBOL(scsi_register_interface);
EXPORT_SYMBOL(scsi_register_host); EXPORT_SYMBOL(scsi_register_host);
EXPORT_SYMBOL(scsi_unregister_host); EXPORT_SYMBOL(scsi_unregister_host);
EXPORT_SYMBOL(scsi_add_host); EXPORT_SYMBOL(scsi_add_host);
......
...@@ -54,37 +54,21 @@ struct class_device_attribute *scsi_sysfs_shost_attrs[] = { ...@@ -54,37 +54,21 @@ struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
NULL NULL
}; };
static struct class shost_class = { struct class shost_class = {
.name = "scsi_host", .name = "scsi_host",
}; };
/** static struct class sdev_class = {
* scsi_bus_match: .name = "scsi_device",
* @dev: };
* @dev_driver:
* /* all probing is done in the individual ->probe routines */
* Return value: static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
**/
static int scsi_bus_match(struct device *dev,
struct device_driver *dev_driver)
{ {
if (!strcmp("sg", dev_driver->name)) { return 1;
if (strstr(dev->bus_id, ":gen"))
return 1;
} else if (!strcmp("st",dev_driver->name)) {
if (strstr(dev->bus_id,":mt"))
return 1;
} else if (!strcmp("sd", dev_driver->name)) {
if ((!strstr(dev->bus_id, ":gen")) &&
(!strstr(dev->bus_id, ":mt"))) {
return 1;
}
}
return 0;
} }
struct bus_type scsi_bus_type = {
static struct bus_type scsi_bus_type = {
.name = "scsi", .name = "scsi",
.match = scsi_bus_match, .match = scsi_bus_match,
}; };
...@@ -99,45 +83,26 @@ int scsi_sysfs_register(void) ...@@ -99,45 +83,26 @@ int scsi_sysfs_register(void)
return error; return error;
error = class_register(&shost_class); error = class_register(&shost_class);
if (error) if (error)
return error; goto bus_unregister;
error = class_register(&sdev_class);
if (error)
goto class_unregister;
return 0;
class_unregister:
class_unregister(&shost_class);
bus_unregister:
bus_unregister(&scsi_bus_type);
return error; return error;
} }
void scsi_sysfs_unregister(void) void scsi_sysfs_unregister(void)
{ {
class_unregister(&sdev_class);
class_unregister(&shost_class); class_unregister(&shost_class);
bus_unregister(&scsi_bus_type); bus_unregister(&scsi_bus_type);
} }
/**
* scsi_upper_driver_register - register upper level driver.
* @sdev_tp: Upper level driver to register with the scsi bus.
*
* Return value:
* 0 on Success / non-zero on Failure
**/
int scsi_upper_driver_register(struct Scsi_Device_Template *sdev_tp)
{
int error = 0;
sdev_tp->scsi_driverfs_driver.bus = &scsi_bus_type;
error = driver_register(&sdev_tp->scsi_driverfs_driver);
return error;
}
/**
* scsi_upper_driver_unregister - unregister upper level driver
* @sdev_tp: Upper level driver to unregister with the scsi bus.
*
**/
void scsi_upper_driver_unregister(struct Scsi_Device_Template *sdev_tp)
{
driver_unregister(&sdev_tp->scsi_driverfs_driver);
}
/* /*
* sdev_show_function: macro to create an attr function that can be used to * sdev_show_function: macro to create an attr function that can be used to
* show a non-bit field. * show a non-bit field.
...@@ -238,7 +203,7 @@ show_rescan_field (struct device *dev, char *buf) ...@@ -238,7 +203,7 @@ show_rescan_field (struct device *dev, char *buf)
static ssize_t static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count) store_rescan_field (struct device *dev, const char *buf, size_t count)
{ {
scsi_rescan_device(to_scsi_device(dev)); scsi_rescan_device(dev);
return 0; return 0;
} }
...@@ -280,15 +245,30 @@ int scsi_device_register(struct scsi_device *sdev) ...@@ -280,15 +245,30 @@ int scsi_device_register(struct scsi_device *sdev)
{ {
int error = 0, i; int error = 0, i;
device_initialize(&sdev->sdev_driverfs_dev);
sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d", sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev; sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev;
sdev->sdev_driverfs_dev.bus = &scsi_bus_type; sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
sdev->sdev_driverfs_dev.release = scsi_device_release; sdev->sdev_driverfs_dev.release = scsi_device_release;
error = device_register(&sdev->sdev_driverfs_dev); class_device_initialize(&sdev->sdev_classdev);
if (error) sdev->sdev_classdev.dev = &sdev->sdev_driverfs_dev;
sdev->sdev_classdev.class = &sdev_class;
snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, "%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
error = device_add(&sdev->sdev_driverfs_dev);
if (error) {
printk(KERN_INFO "error 1\n");
return error; return error;
}
error = class_device_add(&sdev->sdev_classdev);
if (error) {
printk(KERN_INFO "error 2\n");
device_unregister(&sdev->sdev_driverfs_dev);
return error;
}
for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++) for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++)
error = device_create_file(&sdev->sdev_driverfs_dev, error = device_create_file(&sdev->sdev_driverfs_dev,
...@@ -310,9 +290,24 @@ void scsi_device_unregister(struct scsi_device *sdev) ...@@ -310,9 +290,24 @@ void scsi_device_unregister(struct scsi_device *sdev)
for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++) for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++)
device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]); device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]);
class_device_unregister(&sdev->sdev_classdev);
device_unregister(&sdev->sdev_driverfs_dev); device_unregister(&sdev->sdev_driverfs_dev);
} }
int scsi_register_driver(struct device_driver *drv)
{
drv->bus = &scsi_bus_type;
return driver_register(drv);
}
int scsi_register_interface(struct class_interface *intf)
{
intf->class = &sdev_class;
return class_interface_register(intf);
}
static void scsi_host_release(struct device *dev) static void scsi_host_release(struct device *dev)
{ {
struct Scsi_Host *shost; struct Scsi_Host *shost;
...@@ -350,7 +345,7 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev) ...@@ -350,7 +345,7 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
int i, error; int i, error;
if (!shost->host_gendev.parent) if (!shost->host_gendev.parent)
shost->host_gendev.parent = (dev) ? dev : &legacy_bus; shost->host_gendev.parent = dev ? dev : &legacy_bus;
error = device_add(&shost->host_gendev); error = device_add(&shost->host_gendev);
if (error) if (error)
......
This diff is collapsed.
This diff is collapsed.
...@@ -67,26 +67,20 @@ MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */ ...@@ -67,26 +67,20 @@ MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */
CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \ CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_GENERIC_PACKET) CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_GENERIC_PACKET)
static int sr_attach(struct scsi_device *); static int sr_probe(struct device *);
static void sr_detach(struct scsi_device *); static int sr_remove(struct device *);
static int sr_init_command(struct scsi_cmnd *); static int sr_init_command(struct scsi_cmnd *);
static struct Scsi_Device_Template sr_template = { static struct scsi_driver sr_template = {
.module = THIS_MODULE, .owner = THIS_MODULE,
.list = LIST_HEAD_INIT(sr_template.list), .gendrv = {
.name = "cdrom", .name = "sr",
.scsi_type = TYPE_ROM, .probe = sr_probe,
.attach = sr_attach, .remove = sr_remove,
.detach = sr_detach,
.init_command = sr_init_command,
.scsi_driverfs_driver = {
.name = "sr",
}, },
.init_command = sr_init_command,
}; };
static LIST_HEAD(sr_devlist);
static spinlock_t sr_devlist_lock = SPIN_LOCK_UNLOCKED;
static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED; static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED;
...@@ -99,37 +93,6 @@ static void get_capabilities(struct scsi_cd *); ...@@ -99,37 +93,6 @@ static void get_capabilities(struct scsi_cd *);
static int sr_media_change(struct cdrom_device_info *, int); static int sr_media_change(struct cdrom_device_info *, int);
static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *); static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
static Scsi_CD *sr_find_by_sdev(Scsi_Device *sd)
{
struct list_head *p;
Scsi_CD *cd;
spin_lock(&sr_devlist_lock);
list_for_each(p, &sr_devlist) {
cd = list_entry(p, Scsi_CD, list);
if (cd->device == sd) {
spin_unlock(&sr_devlist_lock);
return cd;
}
}
spin_unlock(&sr_devlist_lock);
return NULL;
}
static inline void sr_devlist_insert(Scsi_CD *cd)
{
spin_lock(&sr_devlist_lock);
list_add(&cd->list, &sr_devlist);
spin_unlock(&sr_devlist_lock);
}
static inline void sr_devlist_remove(Scsi_CD *cd)
{
spin_lock(&sr_devlist_lock);
list_del(&cd->list);
spin_unlock(&sr_devlist_lock);
}
static struct cdrom_device_ops sr_dops = { static struct cdrom_device_ops sr_dops = {
.open = sr_open, .open = sr_open,
.release = sr_release, .release = sr_release,
...@@ -506,14 +469,16 @@ static void sr_release(struct cdrom_device_info *cdi) ...@@ -506,14 +469,16 @@ static void sr_release(struct cdrom_device_info *cdi)
scsi_device_put(cd->device); scsi_device_put(cd->device);
} }
static int sr_attach(struct scsi_device *sdev) static int sr_probe(struct device *dev)
{ {
struct scsi_device *sdev = to_scsi_device(dev);
struct gendisk *disk; struct gendisk *disk;
struct scsi_cd *cd; struct scsi_cd *cd;
int minor, error; int minor, error;
error = -ENODEV;
if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM) if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
return 1; goto fail;
error = -ENOMEM; error = -ENOMEM;
cd = kmalloc(sizeof(*cd), GFP_KERNEL); cd = kmalloc(sizeof(*cd), GFP_KERNEL);
...@@ -575,8 +540,8 @@ static int sr_attach(struct scsi_device *sdev) ...@@ -575,8 +540,8 @@ static int sr_attach(struct scsi_device *sdev)
disk->private_data = &cd->driver; disk->private_data = &cd->driver;
disk->queue = sdev->request_queue; disk->queue = sdev->request_queue;
dev_set_drvdata(dev, cd);
add_disk(disk); add_disk(disk);
sr_devlist_insert(cd);
printk(KERN_DEBUG printk(KERN_DEBUG
"Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n", "Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n",
...@@ -807,15 +772,10 @@ static int sr_packet(struct cdrom_device_info *cdi, ...@@ -807,15 +772,10 @@ static int sr_packet(struct cdrom_device_info *cdi,
return cgc->stat; return cgc->stat;
} }
static void sr_detach(struct scsi_device * SDp) static int sr_remove(struct device *dev)
{ {
struct scsi_cd *cd; struct scsi_cd *cd = dev_get_drvdata(dev);
cd = sr_find_by_sdev(SDp);
if (!cd)
return;
sr_devlist_remove(cd);
del_gendisk(cd->disk); del_gendisk(cd->disk);
spin_lock(&sr_index_lock); spin_lock(&sr_index_lock);
...@@ -825,6 +785,8 @@ static void sr_detach(struct scsi_device * SDp) ...@@ -825,6 +785,8 @@ static void sr_detach(struct scsi_device * SDp)
put_disk(cd->disk); put_disk(cd->disk);
unregister_cdrom(&cd->cdi); unregister_cdrom(&cd->cdi);
kfree(cd); kfree(cd);
return 0;
} }
static int __init init_sr(void) static int __init init_sr(void)
...@@ -834,12 +796,12 @@ static int __init init_sr(void) ...@@ -834,12 +796,12 @@ static int __init init_sr(void)
rc = register_blkdev(SCSI_CDROM_MAJOR, "sr"); rc = register_blkdev(SCSI_CDROM_MAJOR, "sr");
if (rc) if (rc)
return rc; return rc;
return scsi_register_device(&sr_template); return scsi_register_driver(&sr_template.gendrv);
} }
static void __exit exit_sr(void) static void __exit exit_sr(void)
{ {
scsi_unregister_device(&sr_template); scsi_unregister_driver(&sr_template.gendrv);
unregister_blkdev(SCSI_CDROM_MAJOR, "sr"); unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
} }
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#define IOCTL_TIMEOUT 30*HZ #define IOCTL_TIMEOUT 30*HZ
typedef struct scsi_cd { typedef struct scsi_cd {
struct Scsi_Device_Template *driver; struct scsi_driver *driver;
struct list_head list;
unsigned capacity; /* size in blocks */ unsigned capacity; /* size in blocks */
Scsi_Device *device; Scsi_Device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */ unsigned int vendor; /* vendor code, see sr_vendor.c */
......
This diff is collapsed.
This diff is collapsed.
...@@ -53,7 +53,7 @@ struct biovec_pool { ...@@ -53,7 +53,7 @@ struct biovec_pool {
* unsigned short * unsigned short
*/ */
#define BV(x) { x, "biovec-" #x } #define BV(x) { .nr_vecs = x, .name = "biovec-" #x }
static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = { static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = {
BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
}; };
......
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.
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.
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