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
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
......@@ -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.
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
Each kobject receives a directory in sysfs. This directory is created
......
......@@ -31,6 +31,11 @@ ipfrag_low_thresh - INTEGER
ipfrag_time - INTEGER
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_threshold - INTEGER
......@@ -515,6 +520,25 @@ bindv6only - BOOLEAN
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/*:
Change the interface-specific default settings.
......
......@@ -36,13 +36,36 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ )
ARCH := $(SUBARCH)
# Remove hyphens since they have special meaning in RPM filenames
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)
# SHELL used by kbuild
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi)
......@@ -53,7 +76,6 @@ HOSTCXX = g++
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCXXFLAGS = -O2
CROSS_COMPILE =
# That's our default target when none is given on the command line
# Note that 'modules' will be added as a prerequisite as well,
......@@ -783,25 +805,27 @@ rpm: clean spec
help:
@echo 'Cleaning targets:'
@echo ' clean - remove most generated files but keep the config'
@echo ' mrproper - remove all generated files + config + various backup files'
@echo ' clean - remove most generated files but keep the config'
@echo ' mrproper - remove all generated files + config + various backup files'
@echo ''
@echo 'Configuration targets:'
@echo ' oldconfig - Update current config utilising a line-oriented program'
@echo ' menuconfig - Update current config utilising a menu based program'
@echo ' xconfig - Update current config utilising a X-based program'
@echo ' defconfig - New config with default answer to all options'
@echo ' allmodconfig - New config selecting modules when possible'
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New minimal config'
@echo ' oldconfig - Update current config utilising a line-oriented program'
@echo ' menuconfig - Update current config utilising a menu based program'
@echo ' xconfig - Update current config utilising a QT based front-end'
@echo ' gconfig - Update current config utilising a GTK based front-end'
@echo ' defconfig - New config with default answer to all options'
@echo ' allmodconfig - New config selecting modules when possible'
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New minimal config'
@echo ''
@echo 'Other generic targets:'
@echo ' all - Build all targets marked with [*]'
@echo '* vmlinux - Build the bare kernel'
@echo '* modules - Build all modules'
@echo ' dir/file.[ois]- Build specified target only'
@echo ' rpm - Build a kernel as an RPM package'
@echo ' tags/TAGS - Generate tags file for editors'
@echo ' all - Build all targets marked with [*]'
@echo '* vmlinux - Build the bare kernel'
@echo '* modules - Build all modules'
@echo ' modules_install - Install all modules'
@echo ' dir/file.[ois] - Build specified target only'
@echo ' rpm - Build a kernel as an RPM package'
@echo ' tags/TAGS - Generate tags file for editors'
@echo ''
@echo 'Documentation targets:'
@$(MAKE) --no-print-directory -f Documentation/DocBook/Makefile dochelp
......@@ -810,6 +834,9 @@ help:
@$(if $(archhelp),$(archhelp),\
echo ' No architecture specific help defined for $(ARCH)')
@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 'For further info browse Documentation/kbuild/*'
......
......@@ -460,17 +460,6 @@ void smp_send_reschedule(int cpu)
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
* static memory requirements. It also looks cleaner.
......
......@@ -205,24 +205,6 @@ smp_send_reschedule (int cpu)
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
smp_flush_tlb_all (void)
{
......
......@@ -392,17 +392,6 @@ void smp_send_reschedule(int cpu)
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
void smp_send_xmon_break(int cpu)
{
......
......@@ -304,7 +304,7 @@ static int eth_configure(int n, void *init, char *mac,
}
memset(device, 0, sizeof(*device));
device->list = INIT_LIST_HEAD(device->list);
INIT_LIST_HEAD(&device->list);
device->index = n;
spin_lock(&devices_lock);
......@@ -362,7 +362,7 @@ static int eth_configure(int n, void *init, char *mac,
return 1;
lp = dev->priv;
lp->list = INIT_LIST_HEAD(lp->list);
INIT_LIST_HEAD(&lp->list);
spin_lock_init(&lp->lock);
lp->dev = dev;
lp->fd = -1;
......@@ -537,7 +537,7 @@ static int eth_setup(char *str)
return(1);
}
new->list = INIT_LIST_HEAD(new->list);
INIT_LIST_HEAD(&new->list);
new->index = n;
new->init = str;
......
......@@ -6,16 +6,12 @@ menu "Cryptographic options"
config CRYPTO
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
This option provides the core Cryptographic API.
config CRYPTO_HMAC
bool "HMAC support"
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
HMAC: Keyed-Hashing for Message Authentication (RFC2104).
This is required for IPSec.
......@@ -35,16 +31,12 @@ config CRYPTO_MD4
config CRYPTO_MD5
tristate "MD5 digest algorithm"
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
MD5 message digest algorithm (RFC1321).
config CRYPTO_SHA1
tristate "SHA1 digest algorithm"
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
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
......@@ -72,7 +64,6 @@ config CRYPTO_SHA512
config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms"
depends on CRYPTO
default y if INET_ESP=y || INET_ESP=m || INET6_ESP=y || INET6_ESP=m
help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
......@@ -138,7 +129,6 @@ config CRYPTO_AES
config CRYPTO_DEFLATE
tristate "Deflate compression algorithm"
depends on CRYPTO
default y if INET_IPCOMP=y || INET_IPCOMP=m || INET6_IPCOMP=y || INET6_IPCOMP=m
help
This is the Deflate algorithm (RFC1951), specified for use in
IPSec with the IPCOMP protocol (RFC3173, RFC2394).
......
This diff is collapsed.
......@@ -4,3 +4,12 @@ extern void bus_remove_device(struct device * dev);
extern int bus_add_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
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
*
* Copyright (c) 2002 Patrick Mochel
* 2002 Open Source Development Lab
*
*
* This file is released under the GPLv2
*
*/
#undef DEBUG
......
/*
* 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
......@@ -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
class_device_attr_show(struct kobject * kobj, struct attribute * attr,
char * buf)
......@@ -182,8 +183,20 @@ static struct sysfs_ops class_dev_sysfs_ops = {
.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 = {
.sysfs_ops = &class_dev_sysfs_ops,
.release = class_dev_release,
};
static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
......@@ -311,11 +324,8 @@ void class_device_del(struct class_device *class_dev)
up_write(&parent->subsys.rwsem);
}
if (class_dev->dev) {
class_device_dev_unlink(class_dev);
class_device_driver_unlink(class_dev);
put_device(class_dev->dev);
}
class_device_dev_unlink(class_dev);
class_device_driver_unlink(class_dev);
kobject_del(&class_dev->kobj);
......
/*
* 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
* 2002 Open Source Development Lab
* This file is released under the GPLv2
*
*/
#undef DEBUG
......
......@@ -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);
retval = class_device_register(&cpu->sysdev.class_dev);
if (retval) {
// FIXME cleanup sys_device_register
sys_device_unregister(&cpu->sysdev);
return retval;
}
return 0;
......@@ -58,10 +58,12 @@ int __init cpu_dev_init(void)
int error;
error = class_register(&cpu_class);
if (!error) {
error = driver_register(&cpu_driver);
if (error)
class_unregister(&cpu_class);
}
if (error)
goto out;
error = driver_register(&cpu_driver);
if (error)
class_unregister(&cpu_class);
out:
return error;
}
/*
* 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
......
/*
* 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>
......
/*
*
* 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/init.h>
......
/*
* drivers/base/interface.c - common driverfs interface that's exported to
* 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>
......
/*
* 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
* information.
*/
......
/*
* power.c - power management functions for the device tree.
*
* Copyright (c) 2002 Patrick Mochel
* 2002 Open Source Development Lab
* Copyright (c) 2002-3 Patrick Mochel
* 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
*
* Kai Germaschewski contributed to the list walking routines.
*
*/
#undef DEBUG
#define DEBUG
#include <linux/device.h>
#include <linux/module.h>
......@@ -88,10 +90,12 @@ void device_shutdown(void)
down_write(&devices_subsys.rwsem);
list_for_each(entry,&devices_subsys.kset.list) {
struct device * dev = to_dev(entry);
pr_debug("shutting down %s: ",dev->name);
if (dev->driver && dev->driver->shutdown) {
pr_debug("shutting down %s\n",dev->name);
pr_debug("Ok\n");
dev->driver->shutdown(dev);
}
} else
pr_debug("Ignored.\n");
}
up_write(&devices_subsys.rwsem);
}
......
/*
* sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
*
* Copyright (c) 2002 Patrick Mochel
* 2002 Open Source Development Lab
* Copyright (c) 2002-3 Patrick Mochel
* 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
*
* This exports a 'system' bus type.
* 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)
for (d = 0; d < MAX_DRIVES; d++) {
ide_drive_t *drive = &hwif->drives[d];
ide_driver_t *driver = drive->driver;
if (!drive->present)
continue;
......@@ -720,13 +719,8 @@ void create_proc_ide_drives(ide_hwif_t *hwif)
continue;
drive->proc = proc_mkdir(drive->name, parent);
if (drive->proc) {
if (drive->proc)
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);
ent = proc_symlink(drive->name, proc_ide_root, name);
if (!ent) return;
......@@ -735,34 +729,6 @@ void create_proc_ide_drives(ide_hwif_t *hwif)
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)
{
ide_driver_t *driver = drive->driver;
......
......@@ -2349,8 +2349,10 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
}
drive->suspend_reset = 0;
#ifdef CONFIG_PROC_FS
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
ide_add_proc_entries(drive->proc, driver->proc, drive);
if (drive->driver != &idedefault_driver) {
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
ide_add_proc_entries(drive->proc, driver->proc, drive);
}
#endif
return 0;
}
......
......@@ -300,17 +300,11 @@ static int nopnp;
*
* 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;
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);
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)
dev->tx_timeout = el3_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl;
return 0;
}
static void el3_common_remove (struct net_device *dev)
......@@ -374,6 +366,7 @@ static int __init el3_probe(int card_idx)
int ioaddr, irq, if_port;
u16 phys_addr[3];
static int current_tag;
int err = -ENODEV;
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
static int pnp_cards;
struct pnp_dev *idev = NULL;
......@@ -413,7 +406,8 @@ static int __init el3_probe(int card_idx)
phys_addr[j] =
htons(read_eeprom(ioaddr, j));
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);
pnp_device_detach(idev);
return -ENOMEM;
......@@ -421,6 +415,8 @@ static int __init el3_probe(int card_idx)
SET_MODULE_OWNER(dev);
pnp_cards++;
netdev_boot_setup_check(dev);
goto found;
}
}
......@@ -514,28 +510,29 @@ static int __init el3_probe(int card_idx)
irq = 13;
#endif
if (!(dev = init_etherdev(NULL, sizeof(struct el3_private))))
return -ENOMEM;
dev = alloc_etherdev(sizeof (struct el3_private));
if (!dev)
return -ENOMEM;
SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
/* Set passed-in IRQ or I/O Addr. */
if (dev->irq > 1 && dev->irq < 16)
irq = dev->irq;
if (dev->base_addr) {
if (dev->mem_end == 0x3c509 /* Magic key */
&& dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0)
ioaddr = dev->base_addr & 0x3f0;
else if (dev->base_addr != ioaddr) {
unregister_netdev (dev);
return -ENODEV;
}
if (dev->mem_end == 0x3c509 /* Magic key */
&& dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0)
ioaddr = dev->base_addr & 0x3f0;
else if (dev->base_addr != ioaddr)
goto out;
}
if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
unregister_netdev (dev);
return -EBUSY;
err = -EBUSY;
goto out;
}
/* Set the adaptor tag so that the next card can be found. */
......@@ -549,11 +546,8 @@ static int __init el3_probe(int card_idx)
#endif
EL3WINDOW(0);
if (inw(ioaddr) != 0x6d50) {
unregister_netdev (dev);
release_region(ioaddr, EL3_IO_EXTENT);
return -ENODEV;
}
if (inw(ioaddr) != 0x6d50)
goto out1;
/* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ);
......@@ -570,6 +564,11 @@ static int __init el3_probe(int card_idx)
#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
lp->dev = &idev->dev;
#endif
el3_common_init(dev);
err = register_netdev(dev);
if (err)
goto out1;
#ifdef CONFIG_PM
/* register power management */
......@@ -581,7 +580,22 @@ static int __init el3_probe(int card_idx)
}
#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
......@@ -602,6 +616,7 @@ static int __init el3_mca_probe(struct device *device) {
u_char pos4, pos5;
struct mca_device *mdev = to_mca_device(device);
int slot = mdev->slot;
int err;
pos4 = mca_device_read_stored_pos(mdev, 4);
pos5 = mca_device_read_stored_pos(mdev, 5);
......@@ -630,13 +645,14 @@ static int __init el3_mca_probe(struct device *device) {
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) {
release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM;
}
SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr;
......@@ -646,8 +662,16 @@ static int __init el3_mca_probe(struct device *device) {
lp->dev = device;
lp->type = EL3_MCA;
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 */
......@@ -661,6 +685,7 @@ static int __init el3_eisa_probe (struct device *device)
u16 phys_addr[3];
struct net_device *dev = NULL;
struct eisa_device *edev;
int err;
/* Yeepee, The driver framework is calling us ! */
edev = to_eisa_device (device);
......@@ -680,7 +705,7 @@ static int __init el3_eisa_probe (struct device *device)
/* Restore the "Product ID" to the EEPROM read register. */
read_eeprom(ioaddr, 3);
dev = init_etherdev(NULL, sizeof(struct el3_private));
dev = alloc_etherdev(sizeof (struct el3_private));
if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT);
return -ENOMEM;
......@@ -688,6 +713,8 @@ static int __init el3_eisa_probe (struct device *device)
SET_MODULE_OWNER(dev);
netdev_boot_setup_check(dev);
memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
dev->base_addr = ioaddr;
dev->irq = irq;
......@@ -696,8 +723,16 @@ static int __init el3_eisa_probe (struct device *device)
lp->dev = device;
lp->type = EL3_EISA;
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
......
......@@ -250,8 +250,6 @@ struct scc_info {
/* Function declarations */
int dmascc_init(void) __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);
......@@ -299,23 +297,12 @@ static struct scc_info *first;
static unsigned long rand;
/* Module functions */
#ifdef MODULE
MODULE_AUTHOR("Klaus Kudielka");
MODULE_DESCRIPTION("Driver for high-speed SCC boards");
MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i");
MODULE_LICENSE("GPL");
int init_module(void) {
return dmascc_init();
}
void cleanup_module(void) {
static void __exit dmascc_exit(void) {
int i;
struct scc_info *info;
......@@ -341,24 +328,16 @@ void cleanup_module(void) {
}
}
#else
#ifndef MODULE
void __init dmascc_setup(char *str, int *ints) {
int i;
for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
io[i] = ints[i+1];
}
#endif
/* Initialization functions */
int __init dmascc_init(void) {
static int __init dmascc_init(void) {
int h, i, j, n;
int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
t1[MAX_NUM_DEVS];
......@@ -461,6 +440,9 @@ int __init dmascc_init(void) {
return -EIO;
}
module_init(dmascc_init);
module_exit(dmascc_exit);
int __init setup_adapter(int card_base, int type, int n) {
int i, irq, chip;
......@@ -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;
#endif
sprintf(dev->name, "dmascc%i", 2*n+i);
SET_MODULE_OWNER(dev);
dev->base_addr = card_base;
dev->irq = irq;
dev->open = scc_open;
......@@ -707,12 +690,9 @@ static int scc_open(struct net_device *dev) {
struct scc_info *info = priv->info;
int card_base = priv->card_base;
MOD_INC_USE_COUNT;
/* Request IRQ if not already used by other channel */
if (!info->irq_used) {
if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) {
MOD_DEC_USE_COUNT;
return -EAGAIN;
}
}
......@@ -722,7 +702,6 @@ static int scc_open(struct net_device *dev) {
if (priv->param.dma >= 0) {
if (request_dma(priv->param.dma, "dmascc")) {
if (--info->irq_used == 0) free_irq(dev->irq, info);
MOD_DEC_USE_COUNT;
return -EAGAIN;
} else {
unsigned long flags = claim_dma_lock();
......@@ -866,7 +845,6 @@ static int scc_close(struct net_device *dev) {
}
if (--info->irq_used == 0) free_irq(dev->irq, info);
MOD_DEC_USE_COUNT;
return 0;
}
......
......@@ -9,8 +9,6 @@
#include <linux/init.h>
#include <linux/netlink.h>
extern int dmascc_init(void);
extern int scc_enet_init(void);
extern int fec_enet_init(void);
......@@ -29,10 +27,6 @@ static struct net_probe pci_probes[] __initdata = {
/*
* Early setup devices
*/
#if defined(CONFIG_DMASCC)
{dmascc_init, 0},
#endif
#if defined(CONFIG_SCC_ENET)
{scc_enet_init, 0},
#endif
......
......@@ -383,6 +383,7 @@ struct s_DevNet {
int Mtu;
int Up;
SK_AC *pAC;
struct proc_dir_entry *proc;
};
typedef struct s_TxPort TX_PORT;
......
......@@ -351,11 +351,7 @@ static int SkGeIocMib(DEV_NET*, unsigned int, int);
static const char SK_Root_Dir_entry[] = "sk98lin";
static struct proc_dir_entry *pSkRootDir;
//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);
extern struct file_operations sk_proc_fops;
#ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*);
......@@ -399,7 +395,6 @@ static int __init skge_probe (void)
struct pci_dev *pdev = NULL;
unsigned long base_address;
struct net_device *dev = NULL;
struct proc_dir_entry *pProcFile;
if (probed)
return -ENODEV;
......@@ -420,7 +415,6 @@ static int __init skge_probe (void)
while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
dev = NULL;
pNet = NULL;
if (pci_enable_device(pdev))
......@@ -431,7 +425,8 @@ static int __init skge_probe (void)
pci_set_dma_mask(pdev, (u64) 0xffffffff))
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 "
"structure!\n");
break;
......@@ -440,7 +435,7 @@ static int __init skge_probe (void)
pNet = dev->priv;
pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
if (pNet->pAC == NULL){
kfree(dev->priv);
kfree(dev);
printk(KERN_ERR "Unable to allocate adapter "
"structure!\n");
break;
......@@ -477,15 +472,6 @@ static int __init skge_probe (void)
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.
*/
......@@ -532,11 +518,29 @@ static int __init skge_probe (void)
pNet->PortNr = 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++;
/* More then one port found */
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 "
"structure!\n");
break;
......@@ -559,20 +563,25 @@ static int __init skge_probe (void)
dev->do_ioctl = &SkGeIoctl;
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,
(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
printk("%s: %s\n", dev->name, pAC->DeviceStr);
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)
return cards ? 0 : -ENODEV;
} /* skge_init_module */
spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
/*****************************************************************************
*
......@@ -766,6 +776,11 @@ SK_EVPARA EvPara;
netif_stop_queue(sk98lin_root_dev);
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) {
/* board is still alive */
......@@ -792,6 +807,12 @@ SK_EVPARA EvPara;
}
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]);
kfree(pAC->dev[1]);
}
......
This diff is collapsed.
......@@ -1682,11 +1682,13 @@ static int __init init_sdla(void)
static void __exit exit_sdla(void)
{
#ifdef MODULE
unregister_netdev(&sdla0);
if (sdla0.priv)
kfree(sdla0.priv);
if (sdla0.irq)
free_irq(sdla0.irq, &sdla0);
#endif
}
MODULE_LICENSE("GPL");
......
......@@ -385,7 +385,7 @@ static int __init NCR_D700_init(void)
static void __exit NCR_D700_exit(void)
{
mca_unregister_driver(&NCR_D700_driver);
scsi_sysfs_release_attributes();
scsi_sysfs_release_attributes(&NCR_D700_driver_template);
}
module_init(NCR_D700_init);
......
......@@ -21,26 +21,6 @@
* 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/signal.h>
#include <linux/sched.h>
......@@ -94,71 +74,8 @@ static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value)
*
*/
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)
void ecoscsi_setup(char *str, int *ints)
{
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)
......@@ -241,8 +158,7 @@ printk("reading %p len %d\n",addr, len);
static Scsi_Host_Template ecoscsi_template = {
.module = THIS_MODULE,
.name = "Serial Port EcoSCSI NCR5380",
.detect = ecoscsi_detect,
.release = ecoscsi_release,
.proc_name = "ecoscsi",
.info = ecoscsi_info,
.queuecommand = ecoscsi_queue_command,
.eh_abort_handler = NCR5380_abort,
......@@ -256,19 +172,60 @@ static Scsi_Host_Template ecoscsi_template = {
.use_clustering = DISABLE_CLUSTERING
};
static struct Scsi_Host *host;
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;
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;
}
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);
......
This diff is collapsed.
......@@ -234,27 +234,18 @@ int scsi_remove_host(struct Scsi_Host *shost)
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
{
Scsi_Host_Template *sht = shost->hostt;
struct scsi_device *sdev;
int error = 0, saved_error = 0;
int error;
printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
sht->info ? sht->info(shost) : sht->name);
error = scsi_sysfs_add_host(shost, dev);
if (error)
return error;
scsi_proc_host_add(shost);
scsi_scan_host(shost);
if (!error) {
scsi_proc_host_add(shost);
scsi_scan_host(shost);
};
list_for_each_entry (sdev, &shost->my_devices, siblings) {
error = scsi_attach_device(sdev);
if (error)
saved_error = error;
}
return saved_error;
return error;
}
/**
......@@ -500,60 +491,43 @@ int scsi_unregister_host(Scsi_Host_Template *shost_tp)
}
/**
* *scsi_host_get_next - get scsi host and inc ref count
* @shost: pointer to a Scsi_Host or NULL to start.
* scsi_host_lookup - get a reference to a Scsi_Host by host no
*
* @hostnum: host number to locate
*
* 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;
spin_lock(&scsi_host_list_lock);
if (shost) {
/* XXX Dec ref on cur shost */
lh = shost->sh_list.next;
} else {
lh = scsi_host_list.next;
}
if (lh == &scsi_host_list) {
shost = (struct Scsi_Host *)NULL;
goto done;
struct class *class = class_get(&shost_class);
struct class_device *cdev;
struct Scsi_Host *shost = NULL, *p;
if (class) {
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
p = class_to_shost(cdev);
if (p->host_no == hostnum) {
scsi_host_get(p);
shost = p;
break;
}
}
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;
}
/**
* 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
* @shost: Pointer to Scsi_Host to inc.
**/
void scsi_host_get(struct Scsi_Host *shost)
{
get_device(&shost->host_gendev);
class_device_get(&shost->class_dev);
return;
}
/**
......@@ -565,7 +539,6 @@ void scsi_host_put(struct Scsi_Host *shost)
class_device_put(&shost->class_dev);
put_device(&shost->host_gendev);
return;
}
/**
......
......@@ -542,25 +542,23 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
return shost->host_gendev.parent;
}
struct Scsi_Device_Template
{
struct list_head list;
const char * name;
struct module * module; /* Used for loadable modules */
unsigned char scsi_type;
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;
struct scsi_driver {
struct module *owner;
struct device_driver gendrv;
int (*init_command)(struct scsi_cmnd *);
void (*rescan)(struct device *);
};
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
/*
* Highlevel driver registration/unregistration.
*/
extern int scsi_register_device(struct Scsi_Device_Template *);
extern int scsi_unregister_device(struct Scsi_Device_Template *);
extern int scsi_register_driver(struct device_driver *);
#define scsi_unregister_driver(drv) \
driver_unregister(drv);
extern int scsi_register_interface(struct class_interface *);
#define scsi_unregister_interface(intf) \
class_interface_unregister(intf)
/*
* HBA allocation/freeing.
......
......@@ -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)
{
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;
if (disk) {
......@@ -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)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
}
#endif
return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
}
......
......@@ -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 length, int hostno, int inout)
int length, int inout)
{
int i;
int len = 0;
......
......@@ -159,6 +159,7 @@ int imm_command(Scsi_Cmnd *);
int imm_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
int imm_abort(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 *,
sector_t, int *);
......
......@@ -278,14 +278,12 @@ static const int nsp32_table_pci_num =
/*
* function declaration
*/
static int nsp32_detect(Scsi_Host_Template *);
static int nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static const char *nsp32_info(struct Scsi_Host *);
static int nsp32_eh_abort(Scsi_Cmnd *);
static int nsp32_eh_bus_reset(Scsi_Cmnd *);
static int nsp32_eh_host_reset(Scsi_Cmnd *);
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 __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit nsp32_remove(struct pci_dev *);
......@@ -335,11 +333,10 @@ static inline int nsp32_prom_get(nsp32_hw_data *, int);
/*
* max_sectors is currently limited up to 128.
*/
static Scsi_Host_Template driver_template = {
.proc_name = "nsp32",
static Scsi_Host_Template nsp32_template = {
.name = "Workbit NinjaSCSI-32Bi/UDE",
.proc_name = "nsp32",
.proc_info = nsp32_proc_info,
.detect = nsp32_detect,
.info = nsp32_info,
.queuecommand = nsp32_queuecommand,
.can_queue = 1,
......@@ -352,12 +349,6 @@ static Scsi_Host_Template driver_template = {
.eh_device_reset_handler = NULL,
.eh_bus_reset_handler = nsp32_eh_bus_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"
......@@ -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)
* 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 */
int ret;
......@@ -1630,7 +1621,7 @@ static int nsp32_detect(Scsi_Host_Template *sht)
/*
* 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) {
nsp32_msg (KERN_ERR, "failed to scsi register");
goto err;
......@@ -1793,8 +1784,6 @@ static int nsp32_detect(Scsi_Host_Template *sht)
"NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x",
host->irq, host->io_port, host->n_io_port);
sht->name = data->info_str;
/*
* SCSI bus reset
*
......@@ -1832,7 +1821,9 @@ static int nsp32_detect(Scsi_Host_Template *sht)
goto free_irq;
}
return 1;
scsi_add_host(host, &pdev->dev);
pci_set_drvdata(pdev, host);
return 0;
free_irq:
free_irq(host->irq, data);
......@@ -1852,43 +1843,7 @@ static int nsp32_detect(Scsi_Host_Template *sht)
scsi_unregister(host);
err:
return 0;
}
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;
return 1;
}
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
pci_set_master(pdev);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_register_host(&driver_template);
#else
scsi_register_module(MODULE_SCSI_HA, &driver_template);
#endif
ret = nsp32_detect(pdev);
nsp32_msg(KERN_INFO, "nsp32 irq: %i mmio: 0x%lx slot: %s model: %s",
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
nsp32_dbg(NSP32_DEBUG_REGISTER, "exit");
return 0;
return ret;
}
static void __devexit nsp32_remove(struct pci_dev *pdev)
{
nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_unregister_host(&driver_template);
#else
scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
#endif
struct Scsi_Host *shpnt = pci_get_drvdata(pdev);
nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata;
kfree(data->lunt_list);
pci_free_consistent(data->Pci, AUTOPARAM_SIZE,
data->autoparam, data->apaddr);
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 = {
......
......@@ -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_from_buffer(OSST_buffer *, unsigned char *);
static int osst_attach(Scsi_Device *);
static void osst_detach(Scsi_Device *);
static int osst_probe(struct device *);
static int osst_remove(struct device *);
struct Scsi_Device_Template osst_template =
{
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(osst_template.list),
.name = "OnStream Tape",
.scsi_type = TYPE_TAPE,
.attach = osst_attach,
.detach = osst_detach,
.scsi_driverfs_driver = {
.name = "osst",
struct scsi_driver osst_template = {
.owner = THIS_MODULE,
.gendrv = {
.name = "osst",
.probe = osst_probe,
.remove = osst_remove,
}
};
......@@ -5326,22 +5322,6 @@ __setup("osst=", osst_setup);
#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 = {
.owner = THIS_MODULE,
.read = osst_read,
......@@ -5384,8 +5364,9 @@ static struct osst_support_data support_list[] = {
* 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;
ST_mode * STm;
ST_partstat * STps;
......@@ -5394,12 +5375,12 @@ static int osst_attach(Scsi_Device * SDp)
int i, mode, dev_num;
if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
return 1;
return -ENODEV;
drive = alloc_disk(1);
if (!drive) {
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 */
......@@ -5521,45 +5502,12 @@ static int osst_attach(Scsi_Device * SDp)
write_unlock(&os_scsi_tapes_lock);
for (mode = 0; mode < ST_NBR_MODES; ++mode) {
char name[8];
/* 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)),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/ot%s", SDp->devfs_name, osst_formats[mode]);
/* 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),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
......@@ -5574,16 +5522,17 @@ static int osst_attach(Scsi_Device * SDp)
out_put_disk:
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;
int i, mode;
if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
return;
return 0;
write_lock(&os_scsi_tapes_lock);
for(i=0; i < osst_max_dev; i++) {
......@@ -5598,29 +5547,17 @@ static void osst_detach(Scsi_Device * SDp)
os_scsi_tapes[i] = NULL;
osst_nr_dev--;
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->buffer) {
normalize_buffer(tpnt->buffer);
kfree(tpnt->buffer);
}
kfree(tpnt);
return;
return 0;
}
}
write_unlock(&os_scsi_tapes_lock);
return;
return 0;
}
static int __init init_osst(void)
......@@ -5629,7 +5566,7 @@ static int __init init_osst(void)
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);
return 1;
}
......@@ -5642,7 +5579,7 @@ static void __exit exit_osst (void)
int i;
OS_Scsi_Tape * STp;
scsi_unregister_device(&osst_template);
scsi_unregister_driver(&osst_template.gendrv);
unregister_chrdev(OSST_MAJOR, "osst");
if (os_scsi_tapes) {
......
......@@ -530,7 +530,7 @@ typedef struct {
/* The OnStream tape drive descriptor */
typedef struct {
struct Scsi_Device_Template *driver;
struct scsi_driver *driver;
unsigned capacity;
Scsi_Device* device;
struct semaphore lock; /* for serialization */
......@@ -555,8 +555,6 @@ typedef struct {
/* Mode characteristics */
ST_mode modes[ST_NBR_MODES];
int current_mode;
struct device driverfs_dev_r[ST_NBR_MODES];
struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */
int partition;
......
......@@ -277,7 +277,7 @@ int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offs
int len = 0;
for (i = 0; i < 4; i++)
if (ppa_hosts[i] == host)
if (ppa_hosts[i].host == host->host_no)
break;
if (inout)
......
......@@ -85,12 +85,6 @@ unsigned long scsi_pid;
struct scsi_cmnd *last_cmnd;
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.
* 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)
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)
{
if (!try_module_get(sdev->host->hostt->module))
......@@ -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_LICENSE("GPL");
......
......@@ -316,6 +316,7 @@ extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
*/
struct scsi_device {
struct class_device sdev_classdev;
/*
* This information is private to the scsi mid-layer.
*/
......
......@@ -612,29 +612,6 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
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()
*
......@@ -849,11 +826,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, int good_sectors,
return;
}
if (result) {
struct Scsi_Device_Template *sdt;
sdt = scsi_get_request_dev(cmd->request);
printk("SCSI %s error : <%d %d %d %d> return code = 0x%x\n",
(sdt ? sdt->name : "device"),
printk("SCSI error : <%d %d %d %d> return code = 0x%x\n",
cmd->device->host->host_no,
cmd->device->channel,
cmd->device->id,
......@@ -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)
{
struct Scsi_Device_Template *sdt;
struct scsi_device *sdev = q->queuedata;
struct scsi_cmnd *cmd;
......@@ -1003,6 +975,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* happening now.
*/
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
struct scsi_driver *drv;
int ret;
/*
......@@ -1017,8 +990,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
* some kinds of consistency checking may cause the
* request to be rejected immediately.
*/
sdt = scsi_get_request_dev(req);
BUG_ON(!sdt);
/*
* 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)
/*
* 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_put_command(cmd);
return BLKPREP_KILL;
......
......@@ -15,21 +15,6 @@
#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)
{
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,
{
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))
return pc98_first_bios_param(sdev, ip);
......
......@@ -41,9 +41,6 @@
#define SCSI_SENSE_VALID(scmd) \
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
struct Scsi_Device_Template;
/*
* 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,
......@@ -58,8 +55,7 @@ struct scsi_target {
/* hosts.c */
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 struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *);
extern struct Scsi_Host *scsi_host_hn_get(unsigned short);
extern struct Scsi_Host *scsi_host_lookup(unsigned short);
extern void scsi_host_put(struct Scsi_Host *);
extern void scsi_host_init(void);
......@@ -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_finish_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 void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq);
......@@ -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_shost(struct Scsi_Host *);
extern void scsi_host_get(struct Scsi_Host *);
extern void scsi_rescan_device(struct device *dev);
/* scsi_sysfs.c */
extern int scsi_device_register(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 int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
extern void scsi_sysfs_remove_host(struct Scsi_Host *);
......@@ -136,4 +128,7 @@ extern void scsi_sysfs_unregister(void);
extern struct class_device_attribute *scsi_sysfs_shost_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 */
......@@ -24,6 +24,7 @@
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <linux/blk.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include "scsi.h"
......@@ -86,7 +87,7 @@ static int proc_scsi_read(char *buffer, char **start, off_t offset,
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)
{
struct Scsi_Host *shost = data;
......@@ -137,7 +138,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
return;
}
p->write_proc = proc_scsi_write;
p->write_proc = proc_scsi_write_proc;
p->owner = shost->hostt->module;
}
......@@ -152,96 +153,52 @@ void scsi_proc_host_rm(struct Scsi_Host *shost)
remove_proc_entry(shost->hostt->proc_name, proc_scsi);
}
static void proc_print_scsidevice(struct scsi_device* sdev, char *buffer,
int *size, int len)
static int proc_print_scsidevice(struct device *dev, void *data)
{
int x, y = *size;
extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
y = sprintf(buffer + len,
"Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
for (x = 0; x < 8; x++) {
if (sdev->vendor[x] >= 0x20)
y += sprintf(buffer + len + y, "%c", sdev->vendor[x]);
struct scsi_device *sdev = to_scsi_device(dev);
struct seq_file *s = data;
int i;
seq_printf(s,
"Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
for (i = 0; i < 8; i++) {
if (sdev->vendor[i] >= 0x20)
seq_printf(s, "%c", sdev->vendor[i]);
else
y += sprintf(buffer + len + y, " ");
seq_printf(s, " ");
}
y += sprintf(buffer + len + y, " Model: ");
for (x = 0; x < 16; x++) {
if (sdev->model[x] >= 0x20)
y += sprintf(buffer + len + y, "%c", sdev->model[x]);
seq_printf(s, " Model: ");
for (i = 0; i < 16; i++) {
if (sdev->model[i] >= 0x20)
seq_printf(s, "%c", sdev->model[i]);
else
y += sprintf(buffer + len + y, " ");
seq_printf(s, " ");
}
y += sprintf(buffer + len + y, " Rev: ");
for (x = 0; x < 4; x++) {
if (sdev->rev[x] >= 0x20)
y += sprintf(buffer + len + y, "%c", sdev->rev[x]);
seq_printf(s, " Rev: ");
for (i = 0; i < 4; i++) {
if (sdev->rev[i] >= 0x20)
seq_printf(s, "%c", sdev->rev[i]);
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 ?
scsi_device_types[(int) sdev->type] : "Unknown ");
y += sprintf(buffer + len + y, " ANSI"
seq_printf(s, " ANSI"
" SCSI revision: %02x", (sdev->scsi_level - 1) ?
sdev->scsi_level - 1 : 1);
if (sdev->scsi_level == 2)
y += sprintf(buffer + len + y, " CCS\n");
seq_printf(s, " CCS\n");
else
y += sprintf(buffer + len + y, "\n");
*size = y;
return;
}
seq_printf(s, "\n");
static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
{
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);
return 0;
}
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;
int error = -ENODEV;
shost = scsi_host_hn_get(host);
shost = scsi_host_lookup(host);
if (!shost)
return -ENODEV;
......@@ -272,7 +229,7 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
struct Scsi_Host *shost;
int error = -ENODEV;
shost = scsi_host_hn_get(host);
shost = scsi_host_lookup(host);
if (!shost)
return -ENODEV;
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)
return error;
}
static int proc_scsi_gen_write(struct file * file, const char * buf,
unsigned long length, void *data)
static int proc_scsi_write(struct file *file, const char* buf,
size_t length, loff_t *ppos)
{
int host, channel, id, lun;
char *buffer, *p;
......@@ -431,6 +388,30 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
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)
{
struct proc_dir_entry *pde;
......@@ -439,10 +420,10 @@ int __init scsi_init_procfs(void)
if (!proc_scsi)
goto err1;
pde = create_proc_info_entry("scsi/scsi", 0, 0, scsi_proc_info);
pde = create_proc_entry("scsi/scsi", 0, NULL);
if (!pde)
goto err2;
pde->write_proc = proc_scsi_gen_write;
pde->proc_fops = &proc_scsi_operations;
return 0;
......
......@@ -1098,24 +1098,31 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
uint channel, uint id, uint lun)
{
struct scsi_device *sdev;
int error = -ENODEV, res;
int res;
res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
if (res == SCSI_SCAN_LUN_PRESENT)
error = scsi_attach_device(sdev);
if (error)
sdev = ERR_PTR(error);
if (res != SCSI_SCAN_LUN_PRESENT)
sdev = ERR_PTR(-ENODEV);
return sdev;
}
int scsi_remove_device(struct scsi_device *sdev)
{
scsi_detach_device(sdev);
scsi_device_unregister(sdev);
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
* target.
......
......@@ -29,8 +29,8 @@
* This source file contains the symbol table used by scsi loadable
* modules.
*/
EXPORT_SYMBOL(scsi_register_device);
EXPORT_SYMBOL(scsi_unregister_device);
EXPORT_SYMBOL(scsi_register_driver);
EXPORT_SYMBOL(scsi_register_interface);
EXPORT_SYMBOL(scsi_register_host);
EXPORT_SYMBOL(scsi_unregister_host);
EXPORT_SYMBOL(scsi_add_host);
......
......@@ -54,37 +54,21 @@ struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
NULL
};
static struct class shost_class = {
struct class shost_class = {
.name = "scsi_host",
};
/**
* scsi_bus_match:
* @dev:
* @dev_driver:
*
* Return value:
**/
static int scsi_bus_match(struct device *dev,
struct device_driver *dev_driver)
static struct class sdev_class = {
.name = "scsi_device",
};
/* all probing is done in the individual ->probe routines */
static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
{
if (!strcmp("sg", dev_driver->name)) {
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;
return 1;
}
static struct bus_type scsi_bus_type = {
struct bus_type scsi_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
};
......@@ -99,45 +83,26 @@ int scsi_sysfs_register(void)
return error;
error = class_register(&shost_class);
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;
}
void scsi_sysfs_unregister(void)
{
class_unregister(&sdev_class);
class_unregister(&shost_class);
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
* show a non-bit field.
......@@ -238,7 +203,7 @@ show_rescan_field (struct device *dev, char *buf)
static ssize_t
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;
}
......@@ -280,15 +245,30 @@ int scsi_device_register(struct scsi_device *sdev)
{
int error = 0, i;
device_initialize(&sdev->sdev_driverfs_dev);
sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev;
sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
sdev->sdev_driverfs_dev.release = scsi_device_release;
error = device_register(&sdev->sdev_driverfs_dev);
if (error)
class_device_initialize(&sdev->sdev_classdev);
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;
}
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++)
error = device_create_file(&sdev->sdev_driverfs_dev,
......@@ -310,9 +290,24 @@ void scsi_device_unregister(struct scsi_device *sdev)
for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; 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);
}
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)
{
struct Scsi_Host *shost;
......@@ -350,7 +345,7 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
int i, error;
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);
if (error)
......
This diff is collapsed.
This diff is collapsed.
......@@ -67,26 +67,20 @@ MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */
CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_GENERIC_PACKET)
static int sr_attach(struct scsi_device *);
static void sr_detach(struct scsi_device *);
static int sr_probe(struct device *);
static int sr_remove(struct device *);
static int sr_init_command(struct scsi_cmnd *);
static struct Scsi_Device_Template sr_template = {
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(sr_template.list),
.name = "cdrom",
.scsi_type = TYPE_ROM,
.attach = sr_attach,
.detach = sr_detach,
.init_command = sr_init_command,
.scsi_driverfs_driver = {
.name = "sr",
static struct scsi_driver sr_template = {
.owner = THIS_MODULE,
.gendrv = {
.name = "sr",
.probe = sr_probe,
.remove = sr_remove,
},
.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 spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED;
......@@ -99,37 +93,6 @@ static void get_capabilities(struct scsi_cd *);
static int sr_media_change(struct cdrom_device_info *, int);
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 = {
.open = sr_open,
.release = sr_release,
......@@ -506,14 +469,16 @@ static void sr_release(struct cdrom_device_info *cdi)
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 scsi_cd *cd;
int minor, error;
error = -ENODEV;
if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
return 1;
goto fail;
error = -ENOMEM;
cd = kmalloc(sizeof(*cd), GFP_KERNEL);
......@@ -575,8 +540,8 @@ static int sr_attach(struct scsi_device *sdev)
disk->private_data = &cd->driver;
disk->queue = sdev->request_queue;
dev_set_drvdata(dev, cd);
add_disk(disk);
sr_devlist_insert(cd);
printk(KERN_DEBUG
"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,
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);
spin_lock(&sr_index_lock);
......@@ -825,6 +785,8 @@ static void sr_detach(struct scsi_device * SDp)
put_disk(cd->disk);
unregister_cdrom(&cd->cdi);
kfree(cd);
return 0;
}
static int __init init_sr(void)
......@@ -834,12 +796,12 @@ static int __init init_sr(void)
rc = register_blkdev(SCSI_CDROM_MAJOR, "sr");
if (rc)
return rc;
return scsi_register_device(&sr_template);
return scsi_register_driver(&sr_template.gendrv);
}
static void __exit exit_sr(void)
{
scsi_unregister_device(&sr_template);
scsi_unregister_driver(&sr_template.gendrv);
unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
}
......
......@@ -25,8 +25,7 @@
#define IOCTL_TIMEOUT 30*HZ
typedef struct scsi_cd {
struct Scsi_Device_Template *driver;
struct list_head list;
struct scsi_driver *driver;
unsigned capacity; /* size in blocks */
Scsi_Device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
......
This diff is collapsed.
This diff is collapsed.
......@@ -53,7 +53,7 @@ struct biovec_pool {
* 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] = {
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