Commit bd09363a authored by James Bottomley's avatar James Bottomley

Merge mulgrave.(none):/home/jejb/BK/linux-2.5

into mulgrave.(none):/home/jejb/BK/scsi-misc-2.6
parents 1e632d02 c9793ca3
Linux I2O Support (c) Copyright 1999 Red Hat Software
and others.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version
2 of the License, or (at your option) any later version.
AUTHORS (so far)
Alan Cox, Building Number Three Ltd.
Core code, SCSI and Block OSMs
Steve Ralston, LSI Logic Corp.
Debugging SCSI and Block OSM
Deepak Saxena, Intel Corp.
Various core/block extensions
/proc interface, bug fixes
Ioctl interfaces for control
Debugging LAN OSM
Philip Rumpf
Fixed assorted dumb SMP locking bugs
Juha Sievanen, University of Helsinki Finland
LAN OSM code
/proc interface to LAN class
Bug fixes
Core code extensions
Auvo Häkkinen, University of Helsinki Finland
LAN OSM code
/Proc interface to LAN class
Bug fixes
Core code extensions
Taneli Vähäkangas, University of Helsinki Finland
Fixes to i2o_config
CREDITS
This work was made possible by
Red Hat Software
Funding for the Building #3 part of the project
Symbios Logic (Now LSI)
Host adapters, hints, known to work platforms when I hit
compatibility problems
BoxHill Corporation
Loan of initial FibreChannel disk array used for development work.
European Comission
Funding the work done by the University of Helsinki
SysKonnect
Loan of FDDI and Gigabit Ethernet cards
ASUSTeK
Loan of I2O motherboard
This diff is collapsed.
### Version 2.00.3 Release Date : Tue Aug 24 09:43:35 EDT 2004 - Atul Mukker <atulm@lsil.com>
Wed Jan 29 09:13:44 EST 200 - Atul Mukker <atulm@lsil.com> Current Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module)
i. Change the handshake in ISR while acknowledging interrupts. Write the Older Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module)
valid interrupt pattern 0x10001234 as soon as it is read from the
outdoor register. In existing driver and on certain platform, invalid
command ids were being returned.
Also, do not wait on status be become 0xFF, since FW can return this i. Function reordering so that inline functions are defined before they
status in certain circumstances. are actually used. It is now mandatory for GCC 3.4.1 (current stable)
Initialize the numstatus field of mailbox to 0xFF so that we can wait Declare some heavy-weight functions to be non-inlined,
on this wait in next interrupt. Firmware does not change its value megaraid_mbox_build_cmd, megaraid_mbox_runpendq,
unless there are some status to be posted megaraid_mbox_prepare_pthru, megaraid_mbox_prepare_epthru,
megaraid_busywait_mbox
ii. Specify the logical drive number while issuing the RESERVATION_STATUS - Andrew Morton <akpm@osdl.org>, 08.19.2004
linux-scsi mailing list
iii. Reduce the default mailbox busy wait time from 300us to 10us. This is "Something else to clean up after inclusion: every instance of an
done to avaoid a possible deadlock in FW because of longer bust waits. inline function is actually rendered as a full function call, because
the function is always used before it is defined. Atul, please
re-arrange the code to eliminate the need for most (all) of the
function prototypes at the top of each file, and define (not just
declare with a prototype) each inline function before its first use"
iv. The max outstanding commands are reduced to 126 because that't the - Matt Domsch <Matt_Domsch@dell.com>, 07.27.2004
safest value on all FW. linux-scsi mailing list
v. Number of sectors per IO are reduced to 128 (64kb), becuase FW needs
resources in special circumstances like check consistency, rebuilds
etc.
vi. max_commands is no longer a module parameter because of iv. ii. Display elapsed time (countdown) while waiting for FW to boot.
### Version: 2.00.2 iii. Module compilation reorder in Makefile so that unresolved symbols do
i. Intermediate release with kernel specific code not occur when driver is compiled non-modular.
Patrick J. LoPresti <patl@users.sourceforge.net>, 8.22.2004
linux-scsi mailing list
### Version: 2.00.1i
Wed Dec 4 14:34:51 EST 2002 - Atul Mukker <atulm@lsil.com>
i. Making the older IO based controllers to work with this driver
Release Date : Thu Aug 19 09:58:33 EDT 2004 - Atul Mukker <atulm@lsil.com>
Current Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module)
Older Version : 2.20.2.0 (scsi module), 2.20.1.0 (cmm module)
### Version 2.00.1 i. When copying the mailbox packets, copy only first 14 bytes (for 32-bit
Fri Nov 15 10:59:44 EST 2002 - Atul Mukker <atulm@lsil.com> mailboxes) and only first 22 bytes (for 64-bit mailboxes). This is to
i. Release host lock before issuing internal command to reset avoid getting the stale values for busy bit. We want to set the busy
reservations in megaraid_reset() and reacquire after internal command bit just before issuing command to the FW.
is completed.
ii. In the reset handling, if the reseted command is not owned by the
driver, do not (wrongly) print information for the "attached" driver
packet.
iii. Have extended wait when issuing command in synchronous mode. This is
required for the cases where the option ROM is disabled and there is
no BIOS to start the controller. The FW starts to boot after receiving
the first command from the driver. The current driver has 1 second
timeout for the synchronous commands, which is far less than what is
actually required. We now wait up to MBOX_RESET_TIME (180 seconds) for
FW boot process.
iv. In megaraid_mbox_product_info, clear the mailbox contents completely
before preparing the command for inquiry3. This is to ensure that the
FW does not get junk values in the command.
v. Do away with the redundant LSI_CONFIG_COMPAT redefinition for
CONFIG_COMPAT. Replace <asm/ioctl32.h> with <linux/ioctl32.h>
- James Bottomley <James.Bottomley@SteelEye.com>, 08.17.2004
linux-scsi mailing list
vi. Add support for 64-bit applications. Current drivers assume only
32-bit applications, even on 64-bit platforms. Use the "data" and
"buffer" fields of the mimd_t structure, instead of embedded 32-bit
addresses in application mailbox and passthru structures.
vii. Move the function declarations for the management module from
megaraid_mm.h to megaraid_mm.c
- Andrew Morton <akpm@osdl.org>, 08.19.2004
linux-scsi mailing list
viii. Change default values for MEGARAID_NEWGEN, MEGARAID_MM, and
MEGARAID_MAILBOX to 'n' in Kconfig.megaraid
- Andrew Morton <akpm@osdl.org>, 08.19.2004
linux-scsi mailing list
ix. replace udelay with msleep
x. Typos corrected in comments and whitespace adjustments, explicit
grouping of expressions.
Release Date : Fri Jul 23 15:22:07 EDT 2004 - Atul Mukker <atulm@lsil.com>
Current Version : 2.20.2.0 (scsi module), 2.20.1.0 (cmm module)
Older Version : 2.20.1.0 (scsi module), 2.20.0.0 (cmm module)
i. Add PCI ids for Acer ROMB 2E solution
ii. Add PCI ids for I4
iii. Typo corrected for subsys id for megaraid sata 300-4x
iv. Remove yield() while mailbox handshake in synchronous commands
"My other main gripe is things like this:
+ // wait for maximum 1 second for status to post
+ for (i = 0; i < 40000; i++) {
+ if (mbox->numstatus != 0xFF) break;
+ udelay(25); yield();
+ }
which litter the driver. Use of yield() in drivers is deprecated."
- James Bottomley <James.Bottomley@SteelEye.com>, 07.14.2004
linux-scsi mailing list
v. Remove redundant __megaraid_busywait_mbox routine
vi. Fix bug in the managment module, which causes a system lockup when the
IO module is loaded and then unloaded, followed by executing any
management utility. The current version of management module does not
handle the adapter unregister properly.
Specifically, it still keeps a reference to the unregistered
controllers. To avoid this, the static array adapters has been
replaced by a dynamic list, which gets updated every time an adapter
is added or removed.
Also, during unregistration of the IO module, the resources are
now released in the exact reverse order of the allocation time
sequence.
Release Date : Fri Jun 25 18:58:43 EDT 2004 - Atul Mukker <atulm@lsil.com>
Current Version : 2.20.1.0
Older Version : megaraid 2.20.0.1
i. Stale list pointer in adapter causes kernel panic when module
megaraid_mbox is unloaded
Release Date : Thu Jun 24 20:37:11 EDT 2004 - Atul Mukker <atulm@lsil.com>
Current Version : 2.20.0.1
Older Version : megaraid 2.20.0.00
i. Modules are not 'y' by default, but depend on current definition of
SCSI & PCI.
ii. Redundant structure mraid_driver_t removed.
iii. Miscellaneous indentation and goto/label fixes.
- Christoph Hellwig <hch@infradead.org>, 06.24.2004 linux-scsi
iv. scsi_host_put(), do just before completing HBA shutdown.
Release Date : Mon Jun 21 19:53:54 EDT 2004 - Atul Mukker <atulm@lsil.com>
Current Version : 2.20.0.0
Older Version : megaraid 2.20.0.rc2 and 2.00.3
i. Independent module to interact with userland applications and
multiplex command to low level RAID module(s).
"Shared code in a third module, a "library module", is an acceptable
solution. modprobe automatically loads dependent modules, so users
running "modprobe driver1" or "modprobe driver2" would automatically
load the shared library module."
- Jeff Garzik <jgarzik@pobox.com> 02.25.2004 LKML
"As Jeff hinted, if your userspace<->driver API is consistent between
your new MPT-based RAID controllers and your existing megaraid driver,
then perhaps you need a single small helper module (lsiioctl or some
better name), loaded by both mptraid and megaraid automatically, which
handles registering the /dev/megaraid node dynamically. In this case,
both mptraid and megaraid would register with lsiioctl for each
adapter discovered, and lsiioctl would essentially be a switch,
redirecting userspace tool ioctls to the appropriate driver."
- Matt Domsch <Matt_Domsch@dell.com> 02.25.2004 LKML
ii. Remove C99 initializations from pci_device id.
"pci_id_table_g would be much more readable when not using C99
initializers.
PCI table doesn't change, there's lots of users that prefer the more
readable variant. And it's really far less and much easier to grok
lines without C99 initializers."
- Christoph Hellwig <hch@infradead.org>, 05.28.2004 linux-scsi
iii. Many fixes as suggested by Christoph Hellwig <hch@infradead.org> on
linux-scsi, 05.28.2004
iv. We now support up to 32 parallel ioctl commands instead of current 1.
There is a conscious effort to let memory allocation not fail for ioctl
commands.
v. Do away with internal memory management. Use pci_pool_(create|alloc)
instead.
vi. Kill tasklet when unloading the driver.
vii. Do not use "host_lock', driver has fine-grain locks now to protect all
data structures.
viii. Optimize the build scatter-gather list routine. The callers already
know the data transfer address and length.
ix. Better implementation of error handling and recovery. Driver now
performs extended errors recovery for instances like scsi cable pull.
x. Disassociate the management commands with an overlaid scsi command.
Driver now treats the management packets as special packets and has a
dedicated callback routine.
Notes on Management Module
~~~~~~~~~~~~~~~~~~~~~~~~~~
Overview:
--------
Different classes of controllers from LSI Logic, accept and respond to the
user applications in a similar way. They understand the same firmware control
commands. Furthermore, the applications also can treat different classes of
the controllers uniformly. Hence it is logical to have a single module that
interefaces with the applications on one side and all the low level drivers
on the other.
The advantages, though obvious, are listed for completeness:
i. Avoid duplicate code from the low level drivers.
ii. Unburden the low level drivers from having to export the
character node device and related handling.
iii. Implement any policy mechanisms in one place.
iv. Applications have to interface with only module instead of
multiple low level drivers.
Currently this module (called Common Management Module) is used only to issue
ioctl commands. But this module is envisioned to handle all user space level
interactions. So any 'proc', 'sysfs' implementations will be localized in this
common module.
Credits:
-------
"Shared code in a third module, a "library module", is an acceptable
solution. modprobe automatically loads dependent modules, so users
running "modprobe driver1" or "modprobe driver2" would automatically
load the shared library module."
- Jeff Garzik (jgarzik@pobox.com), 02.25.2004 LKML
"As Jeff hinted, if your userspace<->driver API is consistent between
your new MPT-based RAID controllers and your existing megaraid driver,
then perhaps you need a single small helper module (lsiioctl or some
better name), loaded by both mptraid and megaraid automatically, which
handles registering the /dev/megaraid node dynamically. In this case,
both mptraid and megaraid would register with lsiioctl for each
adapter discovered, and lsiioctl would essentially be a switch,
redirecting userspace tool ioctls to the appropriate driver."
- Matt Domsch, (Matt_Domsch@dell.com), 02.25.2004 LKML
Design:
------
The Common Management Module is implemented in megaraid_mm.[ch] files. This
module acts as a registry for low level hba drivers. The low level drivers
(currently only megaraid) register each controller with the common module.
The applications interface with the common module via the character device
node exported by the module.
The lower level drivers now understand only a new improved ioctl packet called
uioc_t. The management module converts the older ioctl packets from the older
applications into uioc_t. After driver handles the uioc_t, the common module
will convert that back into the old format before returning to applications.
As new applications evolve and replace the old ones, the old packet format
will be retired.
Common module dedicates one uioc_t packet to each controller registered. This
can easily be more than one. But since megaraid is the only low level driver
today, and it can handle only one ioctl, there is no reason to have more. But
as new controller classes get added, this will be tuned appropriately.
This diff is collapsed.
...@@ -627,6 +627,8 @@ DC390/AM53C974 SCSI driver ...@@ -627,6 +627,8 @@ DC390/AM53C974 SCSI driver
P: Kurt Garloff P: Kurt Garloff
M: garloff@suse.de M: garloff@suse.de
W: http://www.garloff.de/kurt/linux/dc390/ W: http://www.garloff.de/kurt/linux/dc390/
P: Guennadi Liakhovetski
M: g.liakhovetski@gmx.de
S: Maintained S: Maintained
DECnet NETWORK LAYER DECnet NETWORK LAYER
...@@ -956,6 +958,12 @@ L: sensors@stimpy.netroedge.com ...@@ -956,6 +958,12 @@ L: sensors@stimpy.netroedge.com
W: http://www.lm-sensors.nu/ W: http://www.lm-sensors.nu/
S: Maintained S: Maintained
I2O
P: Markus Lidel
M: markus.lidel@shadowconnect.com
W: http://i2o.shadowconnect.com/
S: Maintained
i386 BOOT CODE i386 BOOT CODE
P: Riley H. Williams P: Riley H. Williams
M: Riley@Williams.Name M: Riley@Williams.Name
......
...@@ -538,6 +538,7 @@ int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, ...@@ -538,6 +538,7 @@ int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd,
* old junk scsi send command ioctl * old junk scsi send command ioctl
*/ */
case SCSI_IOCTL_SEND_COMMAND: case SCSI_IOCTL_SEND_COMMAND:
printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
err = -EINVAL; err = -EINVAL;
if (!arg) if (!arg)
break; break;
......
...@@ -27,39 +27,6 @@ config FUSION_MAX_SGE ...@@ -27,39 +27,6 @@ config FUSION_MAX_SGE
necessary (or recommended) unless the user will be running necessary (or recommended) unless the user will be running
large I/O's via the raw interface. large I/O's via the raw interface.
config FUSION_ISENSE
tristate "Enhanced SCSI error reporting"
depends on MODULES && FUSION && m
---help---
The isense module (roughly stands for Interpret SENSE data) is
completely optional. It simply provides extra English readable
strings in SCSI Error Report(s) that might be generated from the
Fusion MPT SCSI Host driver, for example when a target device
returns a SCSI check condition on a I/O. Without this module
loaded you might see:
SCSI Error Report =-=-= (ioc0,scsi5:0)
SCSI_Status=02h (CHECK_CONDITION)
Original_CDB[]: 2A 00 00 00 00 41 00 00 02 00
SenseData[12h]: 70 00 02 00 00 00 00 0A 00 00 00 00 04 02 02 00 00 00
SenseKey=2h (NOT READY); FRU=02h
ASC/ASCQ=29h/00h
Where otherwise, if this module had been loaded, you would see:
SCSI Error Report =-=-= (ioc0,scsi5:0)
SCSI_Status=02h (CHECK_CONDITION)
Original_CDB[]: 2A 00 00 00 00 41 00 00 02 00 - "WRITE(10)"
SenseData[12h]: 70 00 02 00 00 00 00 0A 00 00 00 00 04 02 02 00 00 00
SenseKey=2h (NOT READY); FRU=02h
ASC/ASCQ=29h/00h "LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED"
Say M for "Enhanced SCSI error reporting" to compile this optional module,
creating a driver named: isense.
NOTE: Support for building this feature into the kernel is not
available, due to kernel size considerations.
config FUSION_CTL config FUSION_CTL
tristate "Fusion MPT misc device (ioctl) driver" tristate "Fusion MPT misc device (ioctl) driver"
depends on MODULES && FUSION && m depends on MODULES && FUSION && m
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the LSI Logic Fusion MPT (Message Passing Technology) drivers. # Makefile for the LSI Logic Fusion MPT (Message Passing Technology) drivers.
# #
# Note! If you want to turn on various debug defines for an extended period of # Note! If you want to turn on various debug defines for an extended period of
# time but don't want them lingering around in the Makefile when you pass it on # time but don't want them lingering around in the Makefile when you pass it on
# to someone else, use the MPT_CFLAGS env variable (thanks Steve). -nromer # to someone else, use the MPT_CFLAGS env variable (thanks Steve). -nromer
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-{ LSI_LOGIC #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-{ LSI_LOGIC
...@@ -48,6 +48,5 @@ EXTRA_CFLAGS += ${MPT_CFLAGS} ...@@ -48,6 +48,5 @@ EXTRA_CFLAGS += ${MPT_CFLAGS}
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
obj-$(CONFIG_FUSION) += mptbase.o mptscsih.o obj-$(CONFIG_FUSION) += mptbase.o mptscsih.o
obj-$(CONFIG_FUSION_ISENSE) += isense.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o obj-$(CONFIG_FUSION_LAN) += mptlan.o
This diff is collapsed.
#!/bin/sh
#
# ascq_tbl.sh - Translate SCSI t10.org's "asc-num.txt" file of
# SCSI Additional Sense Code & Qualifiers (ASC/ASCQ's)
# into something useful in C, creating "ascq_tbl.c" file.
#
#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
PREF_INFILE="t10.org/asc-num.txt" # From SCSI t10.org
PREF_OUTFILE="ascq_tbl.c"
#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
xlate_ascq() {
cat | awk '
BEGIN {
DQ = "\042";
OUTFILE = "'"${PREF_OUTFILE}"'";
TRUE = 1;
FALSE = 0;
#debug = TRUE;
# read and discard all lines up to and including the one that begins
# with the "magic token" of "------- -------------- ---"...
headers_gone = FALSE;
while (!headers_gone) {
if (getline <= 0)
exit 1;
header_line[++hdrs] = $0;
if (debug)
printf("header_line[%d] = :%s:\n", ++hdrs, $0);
if ($0 ~ /^------- -------------- ---/) {
headers_gone = TRUE;
}
}
outcount = 0;
}
(NF > 1) {
++outcount;
if (debug)
printf( "DBG: %s\n", $0 );
ASC[outcount] = substr($0,1,2);
ASCQ[outcount] = substr($0,5,2);
devtypes = substr($0,10,14);
gsub(/ /, ".", devtypes);
DESCRIP[outcount] = substr($0,26);
if (!(devtypes in DevTypesVoodoo)) {
DevTypesVoodoo[devtypes] = ++voodoo;
DevTypesIdx[voodoo] = devtypes;
}
DEVTYPES[outcount] = DevTypesVoodoo[devtypes];
# Handle 0xNN exception stuff...
if (ASCQ[outcount] == "NN" || ASCQ[outcount] == "nn")
ASCQ[outcount] = "FF";
}
END {
printf("#ifndef SCSI_ASCQ_TBL_C_INCLUDED\n") > OUTFILE;
printf("#define SCSI_ASCQ_TBL_C_INCLUDED\n") >> OUTFILE;
printf("\n/* AuToMaGiCaLlY generated from: %s'"${FIN}"'%s\n", DQ, DQ) >> OUTFILE;
printf(" *******************************************************************************\n") >> OUTFILE;
for (i=1; i<=hdrs; i++) {
printf(" * %s\n", header_line[i]) >> OUTFILE;
}
printf(" */\n") >> OUTFILE;
printf("\n") >> OUTFILE;
for (i=1; i<=voodoo; i++) {
printf("static char SenseDevTypes%03d[] = %s%s%s;\n", i, DQ, DevTypesIdx[i], DQ) >> OUTFILE;
}
printf("\nstatic ASCQ_Table_t ASCQ_Table[] = {\n") >> OUTFILE;
for (i=1; i<=outcount; i++) {
printf(" {\n") >> OUTFILE;
printf(" 0x%s, 0x%s,\n", ASC[i], ASCQ[i]) >> OUTFILE;
printf(" SenseDevTypes%03d,\n", DEVTYPES[i]) >> OUTFILE;
printf(" %s%s%s\n", DQ, DESCRIP[i], DQ) >> OUTFILE;
printf(" },\n") >> OUTFILE;
}
printf( "};\n\n" ) >> OUTFILE;
printf( "static int ASCQ_TableSize = %d;\n\n", outcount ) >> OUTFILE;
printf( "Total of %d ASC/ASCQ records generated\n", outcount );
printf("\n#endif\n") >> OUTFILE;
close(OUTFILE);
}'
return
}
#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
# main()
if [ $# -lt 1 ]; then
echo "INFO: No input filename supplied - using: $PREF_INFILE" >&2
FIN=$PREF_INFILE
else
FIN="$1"
if [ "$FIN" != "$PREF_INFILE" ]; then
echo "INFO: Ok, I'll try chewing on '$FIN' for SCSI ASC/ASCQ combos..." >&2
fi
shift
fi
cat $FIN | xlate_ascq
exit 0
/*
* linux/drivers/message/fusion/isense.c
* Little linux driver / shim that interfaces with the Fusion MPT
* Linux base driver to provide english readable strings in SCSI
* Error Report logging output. This module implements SCSI-3
* Opcode lookup and a sorted table of SCSI-3 ASC/ASCQ strings.
*
* Copyright (c) 1991-2004 Steven J. Ralston
* Written By: Steven J. Ralston
* (yes I wrote some of the orig. code back in 1991!)
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com)
*
* $Id: isense.c,v 1.33 2002/02/27 18:44:19 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
NO WARRANTY
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
solely responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement, including but not limited to
the risks and costs of program errors, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
DISCLAIMER OF LIABILITY
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <asm/io.h>
#define MODULEAUTHOR "Steven J. Ralston"
#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
#include "mptbase.h"
#include "isense.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Private data...
*/
/*
* YIKES! I don't usually #include C source files, but..
* The following #include's pulls in our needed ASCQ_Table[] array,
* ASCQ_TableSz integer, and ScsiOpcodeString[] array!
*/
#include "ascq_tbl.c"
#include "scsiops.c"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define my_NAME "SCSI-3 Opcodes & ASC/ASCQ Strings"
#define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "isense"
MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int __init isense_init(void)
{
show_mptmod_ver(my_NAME, my_VERSION);
/*
* Install our handler
*/
if (mpt_register_ascqops_strings(&ASCQ_Table[0], ASCQ_TableSize, ScsiOpcodeString) != 1)
{
printk(KERN_ERR MYNAM ": ERROR: Can't register with Fusion MPT base driver!\n");
return -EBUSY;
}
printk(KERN_INFO MYNAM ": Registered SCSI-3 Opcodes & ASC/ASCQ Strings\n");
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void isense_exit(void)
{
#ifdef MODULE
mpt_deregister_ascqops_strings();
#endif
printk(KERN_INFO MYNAM ": Deregistered SCSI-3 Opcodes & ASC/ASCQ Strings\n");
}
module_init(isense_init);
module_exit(isense_exit);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#ifndef ISENSE_H_INCLUDED
#define ISENSE_H_INCLUDED
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#ifdef __KERNEL__
#include <linux/types.h> /* needed for u8, etc. */
#include <linux/string.h> /* needed for strcat */
#include <linux/kernel.h> /* needed for sprintf */
#else
#ifndef U_STUFF_DEFINED
#define U_STUFF_DEFINED
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
#endif
#include "scsi3.h" /* needed for all things SCSI */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Defines and typedefs...
*/
#ifdef __KERNEL__
#define PrintF(x) printk x
#else
#define PrintF(x) printf x
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define RETRY_STATUS ((int) 1)
#define PUT_STATUS ((int) 0)
/*
* A generic structure to hold info about IO request that caused
* a Request Sense to be performed, and the resulting Sense Data.
*/
typedef struct IO_Info
{
char *DevIDStr; /* String of chars which identifies the device. */
u8 *cdbPtr; /* Pointer (Virtual/Logical addr) to CDB bytes of
IO request that caused ContAllegianceCond. */
u8 *sensePtr; /* Pointer (Virtual/Logical addr) to Sense Data
returned by Request Sense operation. */
u8 *dataPtr; /* Pointer (Virtual/Logical addr) to Data buffer
of IO request caused ContAllegianceCondition. */
u8 *inqPtr; /* Pointer (Virtual/Logical addr) to Inquiry Data for
IO *Device* that caused ContAllegianceCondition. */
u8 SCSIStatus; /* SCSI status byte of IO request that caused
Contingent Allegiance Condition. */
u8 DoDisplay; /* Shall we display any messages? */
u16 rsvd_align1;
u32 ComplCode; /* Four-byte OS-dependent completion code. */
u32 NotifyL; /* Four-byte OS-dependent notification field. */
} IO_Info_t;
/*
* SCSI Additional Sense Code and Additional Sense Code Qualifier table.
*/
typedef struct ASCQ_Table
{
u8 ASC;
u8 ASCQ;
char *DevTypes;
char *Description;
} ASCQ_Table_t;
#if 0
/*
* SCSI Opcodes table.
*/
typedef struct SCSI_OPS_Table
{
u8 OpCode;
char *DevTypes;
char *ScsiCmndStr;
} SCSI_OPS_Table_t;
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Public entry point prototypes
*/
/* in scsiherr.c, needed by mptscsih.c */
extern int mpt_ScsiHost_ErrorReport(IO_Info_t *ioop);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif
This diff is collapsed.
This diff is collapsed.
...@@ -111,7 +111,6 @@ MODULE_LICENSE("GPL"); ...@@ -111,7 +111,6 @@ MODULE_LICENSE("GPL");
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int mptctl_id = -1; static int mptctl_id = -1;
static struct semaphore mptctl_syscall_sem_ioc[MPT_MAX_ADAPTERS];
static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait ); static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
...@@ -140,6 +139,9 @@ static int mptctl_do_reset(unsigned long arg); ...@@ -140,6 +139,9 @@ static int mptctl_do_reset(unsigned long arg);
static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd); static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
static int mptctl_hp_targetinfo(unsigned long arg); static int mptctl_hp_targetinfo(unsigned long arg);
static int mptctl_probe(struct pci_dev *, const struct pci_device_id *);
static void mptctl_remove(struct pci_dev *);
/* /*
* Private function calls. * Private function calls.
*/ */
...@@ -208,10 +210,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) ...@@ -208,10 +210,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
} }
if (nonblock) { if (nonblock) {
if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id])) if (down_trylock(&ioc->ioctl->sem_ioc))
rc = -EAGAIN; rc = -EAGAIN;
} else { } else {
if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id])) if (down_interruptible(&ioc->ioctl->sem_ioc))
rc = -ERESTARTSYS; rc = -ERESTARTSYS;
} }
dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc)); dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
...@@ -445,7 +447,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -445,7 +447,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
mptctl_free_tm_flags(ioctl->ioc); mptctl_free_tm_flags(ioctl->ioc);
del_timer(&ioctl->TMtimer); del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioctl->ioc, mf); mpt_free_msg_frame(ioctl->ioc, mf);
ioctl->tmPtr = NULL; ioctl->tmPtr = NULL;
} }
...@@ -482,7 +484,7 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc) ...@@ -482,7 +484,7 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc)
spin_lock_irqsave(&ioc->FreeQlock, flags); spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmState = TM_STATE_ERROR; hd->tmState = TM_STATE_NONE;
hd->tmPending = 0; hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
...@@ -520,7 +522,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -520,7 +522,7 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){ if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE; ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
del_timer(&ioctl->TMtimer); del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(mptctl_id, ioc, ioctl->tmPtr); mpt_free_msg_frame(ioc, ioctl->tmPtr);
} }
} else { } else {
...@@ -630,8 +632,7 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned ...@@ -630,8 +632,7 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
else else
ret = -EINVAL; ret = -EINVAL;
up(&iocp->ioctl->sem_ioc);
up(&mptctl_syscall_sem_ioc[iocp->id]);
return ret; return ret;
} }
...@@ -1807,7 +1808,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -1807,7 +1808,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
struct buflist bufOut; /* data Out buffer */ struct buflist bufOut; /* data Out buffer */
dma_addr_t dma_addr_in; dma_addr_t dma_addr_in;
dma_addr_t dma_addr_out; dma_addr_t dma_addr_out;
int dir; /* PCI data direction */
int sgSize = 0; /* Num SG elements */ int sgSize = 0; /* Num SG elements */
int iocnum, flagsLength; int iocnum, flagsLength;
int sz, rc = 0; int sz, rc = 0;
...@@ -2117,9 +2117,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2117,9 +2117,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
/* Set up the dataOut memory allocation */ /* Set up the dataOut memory allocation */
if (karg.dataOutSize > 0) { if (karg.dataOutSize > 0) {
dir = PCI_DMA_TODEVICE;
if (karg.dataInSize > 0) { if (karg.dataInSize > 0) {
flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT | flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_DIRECTION | MPI_SGE_FLAGS_DIRECTION |
mpt_addr_size() ) mpt_addr_size() )
<< MPI_SGE_FLAGS_SHIFT; << MPI_SGE_FLAGS_SHIFT;
...@@ -2158,7 +2158,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2158,7 +2158,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
} }
if (karg.dataInSize > 0) { if (karg.dataInSize > 0) {
dir = PCI_DMA_FROMDEVICE;
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
flagsLength |= karg.dataInSize; flagsLength |= karg.dataInSize;
...@@ -2196,6 +2195,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2196,6 +2195,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
add_timer(&ioc->ioctl->timer); add_timer(&ioc->ioctl->timer);
if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) { if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);
rc = mpt_send_handshake_request(mptctl_id, ioc, rc = mpt_send_handshake_request(mptctl_id, ioc,
sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP); sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
if (rc == 0) { if (rc == 0) {
...@@ -2206,7 +2206,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2206,7 +2206,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
del_timer(&ioc->ioctl->timer); del_timer(&ioc->ioctl->timer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE; ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED; ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
mpt_free_msg_frame(mptctl_id, ioc, mf); mpt_free_msg_frame(ioc, mf);
} }
} else { } else {
mpt_put_msg_frame(mptctl_id, ioc, mf); mpt_put_msg_frame(mptctl_id, ioc, mf);
...@@ -2324,7 +2324,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2324,7 +2324,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
* otherwise, failure occured after mf acquired. * otherwise, failure occured after mf acquired.
*/ */
if (mf) if (mf)
mpt_free_msg_frame(mptctl_id, ioc, mf); mpt_free_msg_frame(ioc, mf);
return rc; return rc;
} }
...@@ -2738,7 +2738,7 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, ...@@ -2738,7 +2738,7 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen); ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
up(&mptctl_syscall_sem_ioc[iocp->id]); up(&iocp->ioctl->sem_ioc);
return ret; return ret;
} }
...@@ -2792,55 +2792,91 @@ compat_mpt_command(unsigned int fd, unsigned int cmd, ...@@ -2792,55 +2792,91 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
*/ */
ret = mptctl_do_mpt_command (karg, &uarg->MF); ret = mptctl_do_mpt_command (karg, &uarg->MF);
up(&mptctl_syscall_sem_ioc[iocp->id]); up(&iocp->ioctl->sem_ioc);
return ret; return ret;
} }
#endif #endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int __init mptctl_init(void) /*
* mptctl_probe - Installs ioctl devices per bus.
* @pdev: Pointer to pci_dev structure
*
* Returns 0 for success, non-zero for failure.
*
*/
static int
mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
int err; int err;
int i;
int where = 1;
int sz; int sz;
u8 *mem; u8 *mem;
MPT_ADAPTER *ioc = NULL; MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
int iocnum;
show_mptmod_ver(my_NAME, my_VERSION); /*
* Allocate and inite a MPT_IOCTL structure
*/
sz = sizeof (MPT_IOCTL);
mem = kmalloc(sz, GFP_KERNEL);
if (mem == NULL) {
err = -ENOMEM;
goto out_fail;
}
for (i=0; i<MPT_MAX_ADAPTERS; i++) { memset(mem, 0, sz);
sema_init(&mptctl_syscall_sem_ioc[i], 1); ioc->ioctl = (MPT_IOCTL *) mem;
ioc->ioctl->ioc = ioc;
init_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->timer.function = mptctl_timer_expired;
init_timer (&ioc->ioctl->TMtimer);
ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->TMtimer.function = mptctl_timer_expired;
sema_init(&ioc->ioctl->sem_ioc, 1);
return 0;
ioc = NULL; out_fail:
if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
(ioc == NULL)) {
continue;
}
else {
/* This adapter instance is found.
* Allocate and inite a MPT_IOCTL structure
*/
sz = sizeof (MPT_IOCTL);
mem = kmalloc(sz, GFP_KERNEL);
if (mem == NULL) {
err = -ENOMEM;
goto out_fail;
}
memset(mem, 0, sz); mptctl_remove(pdev);
ioc->ioctl = (MPT_IOCTL *) mem; return err;
ioc->ioctl->ioc = ioc; }
init_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.data = (unsigned long) ioc->ioctl; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
ioc->ioctl->timer.function = mptctl_timer_expired; /*
init_timer (&ioc->ioctl->TMtimer); * mptctl_remove - Removed ioctl devices
ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl; * @pdev: Pointer to pci_dev structure
ioc->ioctl->TMtimer.function = mptctl_timer_expired; *
} *
*/
static void
mptctl_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
kfree ( ioc->ioctl );
}
static struct mpt_pci_driver mptctl_driver = {
.probe = mptctl_probe,
.remove = mptctl_remove,
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int __init mptctl_init(void)
{
int err;
int where = 1;
show_mptmod_ver(my_NAME, my_VERSION);
if(mpt_device_driver_register(&mptctl_driver,
MPTCTL_DRIVER) != 0 ) {
dprintk((KERN_INFO MYNAM
": failed to register dd callbacks\n"));
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
...@@ -2922,29 +2958,14 @@ int __init mptctl_init(void) ...@@ -2922,29 +2958,14 @@ int __init mptctl_init(void)
unregister_ioctl32_conversion(HP_GETTARGETINFO); unregister_ioctl32_conversion(HP_GETTARGETINFO);
#endif #endif
for (i=0; i<MPT_MAX_ADAPTERS; i++) { mpt_device_driver_deregister(MPTCTL_DRIVER);
ioc = NULL;
if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
(ioc == NULL)) {
continue;
}
else {
if (ioc->ioctl) {
kfree ( ioc->ioctl );
ioc->ioctl = NULL;
}
}
}
return err; return err;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
void mptctl_exit(void) static void mptctl_exit(void)
{ {
int i;
MPT_ADAPTER *ioc;
int iocnum;
misc_deregister(&mptctl_miscdev); misc_deregister(&mptctl_miscdev);
printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n", printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor); mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
...@@ -2957,6 +2978,8 @@ void mptctl_exit(void) ...@@ -2957,6 +2978,8 @@ void mptctl_exit(void)
mpt_deregister(mptctl_id); mpt_deregister(mptctl_id);
printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n"); printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
mpt_device_driver_deregister(MPTCTL_DRIVER);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
unregister_ioctl32_conversion(MPTIOCINFO); unregister_ioctl32_conversion(MPTIOCINFO);
unregister_ioctl32_conversion(MPTIOCINFO1); unregister_ioctl32_conversion(MPTIOCINFO1);
...@@ -2973,20 +2996,6 @@ void mptctl_exit(void) ...@@ -2973,20 +2996,6 @@ void mptctl_exit(void)
unregister_ioctl32_conversion(HP_GETTARGETINFO); unregister_ioctl32_conversion(HP_GETTARGETINFO);
#endif #endif
/* Free allocated memory */
for (i=0; i<MPT_MAX_ADAPTERS; i++) {
ioc = NULL;
if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
(ioc == NULL)) {
continue;
}
else {
if (ioc->ioctl) {
kfree ( ioc->ioctl );
ioc->ioctl = NULL;
}
}
}
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......
...@@ -177,11 +177,9 @@ static int LanCtx = -1; ...@@ -177,11 +177,9 @@ static int LanCtx = -1;
static u32 max_buckets_out = 127; static u32 max_buckets_out = 127;
static u32 tx_max_out_p = 127 - 16; static u32 tx_max_out_p = 127 - 16;
static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
#ifdef QLOGIC_NAA_WORKAROUND #ifdef QLOGIC_NAA_WORKAROUND
static struct NAA_Hosed *mpt_bad_naa = NULL; static struct NAA_Hosed *mpt_bad_naa = NULL;
rwlock_t bad_naa_lock; rwlock_t bad_naa_lock = RW_LOCK_UNLOCKED;
#endif #endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -203,7 +201,7 @@ extern int mpt_lan_index; ...@@ -203,7 +201,7 @@ extern int mpt_lan_index;
static int static int
lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
{ {
struct net_device *dev = mpt_landev[ioc->id]; struct net_device *dev = ioc->netdev;
int FreeReqFrame = 0; int FreeReqFrame = 0;
dioprintk((KERN_INFO MYNAM ": %s/%s: Got reply.\n", dioprintk((KERN_INFO MYNAM ": %s/%s: Got reply.\n",
...@@ -336,7 +334,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) ...@@ -336,7 +334,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
static int static int
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{ {
struct net_device *dev = mpt_landev[ioc->id]; struct net_device *dev = ioc->netdev;
struct mpt_lan_priv *priv = netdev_priv(dev); struct mpt_lan_priv *priv = netdev_priv(dev);
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n", dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
...@@ -1334,7 +1332,7 @@ mpt_lan_post_receive_buckets(void *dev_id) ...@@ -1334,7 +1332,7 @@ mpt_lan_post_receive_buckets(void *dev_id)
if (pSimple == NULL) { if (pSimple == NULL) {
/**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n",
/**/ __FUNCTION__); /**/ __FUNCTION__);
mpt_free_msg_frame(LanCtx, mpt_dev, mf); mpt_free_msg_frame(mpt_dev, mf);
goto out; goto out;
} }
...@@ -1451,20 +1449,74 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) ...@@ -1451,20 +1449,74 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
return dev; return dev;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int
static int __init mpt_lan_init (void) mptlan_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct net_device *dev; MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
MPT_ADAPTER *p; struct net_device *dev;
int i, j; int i;
for (i = 0; i < ioc->facts.NumberOfPorts; i++) {
printk(KERN_INFO MYNAM ": %s: PortNum=%x, "
"ProtocolFlags=%02Xh (%c%c%c%c)\n",
ioc->name, ioc->pfacts[i].PortNumber,
ioc->pfacts[i].ProtocolFlags,
MPT_PROTOCOL_FLAGS_c_c_c_c(
ioc->pfacts[i].ProtocolFlags));
if (!(ioc->pfacts[i].ProtocolFlags &
MPI_PORTFACTS_PROTOCOL_LAN)) {
printk(KERN_INFO MYNAM ": %s: Hmmm... LAN protocol "
"seems to be disabled on this adapter port!\n",
ioc->name);
continue;
}
show_mptmod_ver(LANAME, LANVER); dev = mpt_register_lan_device(ioc, i);
if (!dev) {
printk(KERN_ERR MYNAM ": %s: Unable to register "
"port%d as a LAN device\n", ioc->name,
ioc->pfacts[i].PortNumber);
continue;
}
printk(KERN_INFO MYNAM ": %s: Fusion MPT LAN device "
"registered as '%s'\n", ioc->name, dev->name);
printk(KERN_INFO MYNAM ": %s/%s: "
"LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
IOC_AND_NETDEV_NAMES_s_s(dev),
dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],
dev->dev_addr[4], dev->dev_addr[5]);
ioc->netdev = dev;
#ifdef QLOGIC_NAA_WORKAROUND return 0;
/* Init the global r/w lock for the bad_naa list. We want to do this }
before any boards are initialized and may be used. */
rwlock_init(&bad_naa_lock); return -ENODEV;
#endif }
static void
mptlan_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct net_device *dev = ioc->netdev;
if(dev != NULL) {
unregister_netdev(dev);
free_netdev(dev);
}
}
static struct mpt_pci_driver mptlan_driver = {
.probe = mptlan_probe,
.remove = mptlan_remove,
};
static int __init mpt_lan_init (void)
{
show_mptmod_ver(LANAME, LANVER);
if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) { if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n"); printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
...@@ -1476,88 +1528,32 @@ static int __init mpt_lan_init (void) ...@@ -1476,88 +1528,32 @@ static int __init mpt_lan_init (void)
dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx)); dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) { if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset)) {
dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
} else {
printk(KERN_ERR MYNAM ": Eieee! unable to register a reset " printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
"handler with mptbase! The world is at an end! " "handler with mptbase! The world is at an end! "
"Everything is fading to black! Goodbye.\n"); "Everything is fading to black! Goodbye.\n");
return -EBUSY; return -EBUSY;
} }
for (j = 0; j < MPT_MAX_ADAPTERS; j++) { dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
mpt_landev[j] = NULL;
} if (mpt_device_driver_register(&mptlan_driver, MPTLAN_DRIVER))
dprintk((KERN_INFO MYNAM ": failed to register dd callbacks\n"));
list_for_each_entry(p, &ioc_list, list) {
for (i = 0; i < p->facts.NumberOfPorts; i++) {
printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
p->name,
p->pfacts[i].PortNumber,
p->pfacts[i].ProtocolFlags,
MPT_PROTOCOL_FLAGS_c_c_c_c(p->pfacts[i].ProtocolFlags));
if (!(p->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
p->name);
continue;
}
dev = mpt_register_lan_device (p, i);
if (!dev) {
printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
p->name,
p->pfacts[i].PortNumber);
}
printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
p->name, dev->name);
printk (KERN_INFO MYNAM ": %s/%s: LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
IOC_AND_NETDEV_NAMES_s_s(dev),
dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],
dev->dev_addr[4], dev->dev_addr[5]);
// printk (KERN_INFO MYNAM ": %s/%s: Max_TX_outstanding = %d\n",
// IOC_AND_NETDEV_NAMES_s_s(dev),
// NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out);
j = p->id;
mpt_landev[j] = dev;
dlprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
dev, j, mpt_landev[j]));
}
}
return 0; return 0;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void __exit mpt_lan_exit(void) static void __exit mpt_lan_exit(void)
{ {
int i; mpt_device_driver_deregister(MPTLAN_DRIVER);
mpt_reset_deregister(LanCtx); mpt_reset_deregister(LanCtx);
for (i = 0; mpt_landev[i] != NULL; i++) {
struct net_device *dev = mpt_landev[i];
printk (KERN_INFO ": %s/%s: Fusion MPT LAN device unregistered\n",
IOC_AND_NETDEV_NAMES_s_s(dev));
unregister_netdev(dev);
free_netdev(dev);
mpt_landev[i] = NULL;
}
if (LanCtx >= 0) { if (LanCtx >= 0) {
mpt_deregister(LanCtx); mpt_deregister(LanCtx);
LanCtx = -1; LanCtx = -1;
mpt_lan_index = 0; mpt_lan_index = 0;
} }
/* deregister any send/receive handler structs. I2Oism? */
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
module_init(mpt_lan_init); module_init(mpt_lan_init);
module_exit(mpt_lan_exit); module_exit(mpt_lan_exit);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# In the future, some of these should be built conditionally. # In the future, some of these should be built conditionally.
# #
i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o
obj-$(CONFIG_I2O) += i2o_core.o obj-$(CONFIG_I2O) += i2o_core.o
obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o
obj-$(CONFIG_I2O_BLOCK) += i2o_block.o obj-$(CONFIG_I2O_BLOCK) += i2o_block.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Block OSM structures/API
*
* Copyright (C) 1999-2002 Red Hat Software
*
* Written by Alan Cox, Building Number Three Ltd
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* For the purpose of avoiding doubt the preferred form of the work
* for making modifications shall be a standards compliant form such
* gzipped tar and not one requiring a proprietary or patent encumbered
* tool to unpack.
*
* Fixes/additions:
* Steve Ralston:
* Multiple device handling error fixes,
* Added a queue depth.
* Alan Cox:
* FC920 has an rmw bug. Dont or in the end marker.
* Removed queue walk, fixed for 64bitness.
* Rewrote much of the code over time
* Added indirect block lists
* Handle 64K limits on many controllers
* Don't use indirects on the Promise (breaks)
* Heavily chop down the queue depths
* Deepak Saxena:
* Independent queues per IOP
* Support for dynamic device creation/deletion
* Code cleanup
* Support for larger I/Os through merge* functions
* (taken from DAC960 driver)
* Boji T Kannanthanam:
* Set the I2O Block devices to be detected in increasing
* order of TIDs during boot.
* Search and set the I2O block device that we boot off
* from as the first device to be claimed (as /dev/i2o/hda)
* Properly attach/detach I2O gendisk structure from the
* system gendisk list. The I2O block devices now appear in
* /proc/partitions.
* Markus Lidel <Markus.Lidel@shadowconnect.com>:
* Minor bugfixes for 2.6.
*/
#ifndef I2O_BLOCK_OSM_H
#define I2O_BLOCK_OSM_H
#define I2O_BLOCK_RETRY_TIME HZ/4
#define I2O_BLOCK_MAX_OPEN_REQUESTS 50
/* I2O Block OSM mempool struct */
struct i2o_block_mempool {
kmem_cache_t *slab;
mempool_t *pool;
};
/* I2O Block device descriptor */
struct i2o_block_device {
struct i2o_device *i2o_dev; /* pointer to I2O device */
struct gendisk *gd;
spinlock_t lock; /* queue lock */
struct list_head open_queue; /* list of transfered, but unfinished
requests */
unsigned int open_queue_depth; /* number of requests in the queue */
int rcache; /* read cache flags */
int wcache; /* write cache flags */
int flags;
int power; /* power state */
int media_change_flag; /* media changed flag */
};
/* I2O Block device request */
struct i2o_block_request
{
struct list_head queue;
struct request *req; /* corresponding request */
struct i2o_block_device *i2o_blk_dev; /* I2O block device */
int sg_dma_direction; /* direction of DMA buffer read/write */
int sg_nents; /* number of SG elements */
struct scatterlist sg_table[I2O_MAX_SEGMENTS]; /* SG table */
};
/* I2O Block device delayed request */
struct i2o_block_delayed_request
{
struct work_struct work;
struct request_queue *queue;
};
#endif
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.
...@@ -95,7 +95,8 @@ obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o ...@@ -95,7 +95,8 @@ obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o
obj-$(CONFIG_SCSI_EATA) += eata.o obj-$(CONFIG_SCSI_EATA) += eata.o
obj-$(CONFIG_SCSI_DC395x) += dc395x.o obj-$(CONFIG_SCSI_DC395x) += dc395x.o
obj-$(CONFIG_SCSI_DC390T) += tmscsim.o obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
obj-$(CONFIG_SCSI_MEGARAID) += megaraid.o obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_SCSI_ACARD) += atp870u.o obj-$(CONFIG_SCSI_ACARD) += atp870u.o
obj-$(CONFIG_SCSI_SUNESP) += esp.o obj-$(CONFIG_SCSI_SUNESP) += esp.o
obj-$(CONFIG_SCSI_GDTH) += gdth.o obj-$(CONFIG_SCSI_GDTH) += gdth.o
...@@ -119,6 +120,7 @@ obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o ...@@ -119,6 +120,7 @@ obj-$(CONFIG_SCSI_CPQFCTS) += cpqfc.o
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o
obj-$(CONFIG_SCSI_IPR) += ipr.o obj-$(CONFIG_SCSI_IPR) += ipr.o
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o
obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
......
This diff is collapsed.
...@@ -251,7 +251,6 @@ ...@@ -251,7 +251,6 @@
struct NCR5380_hostdata { struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */ NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */ struct Scsi_Host *host; /* Host backpointer */
struct NCR5380_hostdata *next; /* Next in our hot chain */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */ unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected unsigned char targets_present; /* targets we have connected
to, so we can call a select to, so we can call a select
...@@ -270,7 +269,6 @@ struct NCR5380_hostdata { ...@@ -270,7 +269,6 @@ struct NCR5380_hostdata {
volatile unsigned aborted:1; /* flag, says aborted */ volatile unsigned aborted:1; /* flag, says aborted */
int flags; int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */ unsigned long time_expires; /* in jiffies, set prior to sleeping */
struct Scsi_Host *next_timer;
int select_time; /* timer in select for target response */ int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting; volatile Scsi_Cmnd *selecting;
struct work_struct coroutine; /* our co-routine */ struct work_struct coroutine; /* our co-routine */
...@@ -295,6 +293,7 @@ struct NCR5380_hostdata { ...@@ -295,6 +293,7 @@ struct NCR5380_hostdata {
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif #endif
static int NCR5380_init(struct Scsi_Host *instance, int flags); static int NCR5380_init(struct Scsi_Host *instance, int flags);
static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(struct Scsi_Host *instance); static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR #ifndef DONT_USE_INTR
static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -480,7 +480,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -480,7 +480,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
default: default:
data_dir = DMA_NONE; data_dir = DMA_NONE;
} }
if (dev->pae_support == 1) { if (dev->dac_support == 1) {
struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
byte_count = 0; byte_count = 0;
......
...@@ -761,7 +761,7 @@ void aac_printf(struct aac_dev *dev, u32 val) ...@@ -761,7 +761,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
length = 255; length = 255;
if (cp[length] != 0) if (cp[length] != 0)
cp[length] = 0; cp[length] = 0;
if (level == LOG_HIGH_ERROR) if (level == LOG_AAC_HIGH_ERROR)
printk(KERN_WARNING "aacraid:%s", cp); printk(KERN_WARNING "aacraid:%s", cp);
else else
printk(KERN_INFO "aacraid:%s", cp); printk(KERN_INFO "aacraid:%s", cp);
......
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.
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.
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