提交 df517985 编写于 作者: D David Woodhouse

Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml scsidrivers.xml \ procfs-guide.xml writing_usb_driver.xml \
sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \ sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml gadget.xml libata.xml mtdnand.xml librs.xml
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="scsidrivers">
<bookinfo>
<title>SCSI Subsystem Interfaces</title>
<authorgroup>
<author>
<firstname>Douglas</firstname>
<surname>Gilbert</surname>
<affiliation>
<address>
<email>dgilbert@interlog.com</email>
</address>
</affiliation>
</author>
</authorgroup>
<pubdate>2003-08-11</pubdate>
<copyright>
<year>2002</year>
<year>2003</year>
<holder>Douglas Gilbert</holder>
</copyright>
<legalnotice>
<para>
This documentation 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.
</para>
<para>
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.
</para>
<para>
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
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
</bookinfo>
<toc></toc>
<chapter id="intro">
<title>Introduction</title>
<para>
This document outlines the interface between the Linux scsi mid level
and lower level drivers. Lower level drivers are variously called HBA
(host bus adapter) drivers, host drivers (HD) or pseudo adapter drivers.
The latter alludes to the fact that a lower level driver may be a
bridge to another IO subsystem (and the "ide-scsi" driver is an example
of this). There can be many lower level drivers active in a running
system, but only one per hardware type. For example, the aic7xxx driver
controls adaptec controllers based on the 7xxx chip series. Most lower
level drivers can control one or more scsi hosts (a.k.a. scsi initiators).
</para>
<para>
This document can been found in an ASCII text file in the linux kernel
source: <filename>Documentation/scsi/scsi_mid_low_api.txt</filename> .
It currently hold a little more information than this document. The
<filename>drivers/scsi/hosts.h</filename> and <filename>
drivers/scsi/scsi.h</filename> headers contain descriptions of members
of important structures for the scsi subsystem.
</para>
</chapter>
<chapter id="driver-struct">
<title>Driver structure</title>
<para>
Traditionally a lower level driver for the scsi subsystem has been
at least two files in the drivers/scsi directory. For example, a
driver called "xyz" has a header file "xyz.h" and a source file
"xyz.c". [Actually there is no good reason why this couldn't all
be in one file.] Some drivers that have been ported to several operating
systems (e.g. aic7xxx which has separate files for generic and
OS-specific code) have more than two files. Such drivers tend to have
their own directory under the drivers/scsi directory.
</para>
<para>
scsi_module.c is normally included at the end of a lower
level driver. For it to work a declaration like this is needed before
it is included:
<programlisting>
static Scsi_Host_Template driver_template = DRIVER_TEMPLATE;
/* DRIVER_TEMPLATE should contain pointers to supported interface
functions. Scsi_Host_Template is defined hosts.h */
#include "scsi_module.c"
</programlisting>
</para>
<para>
The scsi_module.c assumes the name "driver_template" is appropriately
defined. It contains 2 functions:
<orderedlist>
<listitem><para>
init_this_scsi_driver() called during builtin and module driver
initialization: invokes mid level's scsi_register_host()
</para></listitem>
<listitem><para>
exit_this_scsi_driver() called during closedown: invokes
mid level's scsi_unregister_host()
</para></listitem>
</orderedlist>
</para>
<para>
When a new, lower level driver is being added to Linux, the following
files (all found in the drivers/scsi directory) will need some attention:
Makefile, Config.help and Config.in . It is probably best to look at what
an existing lower level driver does in this regard.
</para>
</chapter>
<chapter id="intfunctions">
<title>Interface Functions</title>
!EDocumentation/scsi/scsi_mid_low_api.txt
</chapter>
<chapter id="locks">
<title>Locks</title>
<para>
Each Scsi_Host instance has a spin_lock called Scsi_Host::default_lock
which is initialized in scsi_register() [found in hosts.c]. Within the
same function the Scsi_Host::host_lock pointer is initialized to point
at default_lock with the scsi_assign_lock() function. Thereafter
lock and unlock operations performed by the mid level use the
Scsi_Host::host_lock pointer.
</para>
<para>
Lower level drivers can override the use of Scsi_Host::default_lock by
using scsi_assign_lock(). The earliest opportunity to do this would
be in the detect() function after it has invoked scsi_register(). It
could be replaced by a coarser grain lock (e.g. per driver) or a
lock of equal granularity (i.e. per host). Using finer grain locks
(e.g. per scsi device) may be possible by juggling locks in
queuecommand().
</para>
</chapter>
<chapter id="changes">
<title>Changes since lk 2.4 series</title>
<para>
io_request_lock has been replaced by several finer grained locks. The lock
relevant to lower level drivers is Scsi_Host::host_lock and there is one
per scsi host.
</para>
<para>
The older error handling mechanism has been removed. This means the
lower level interface functions abort() and reset() have been removed.
</para>
<para>
In the 2.4 series the scsi subsystem configuration descriptions were
aggregated with the configuration descriptions from all other Linux
subsystems in the Documentation/Configure.help file. In the 2.5 series,
the scsi subsystem now has its own (much smaller) drivers/scsi/Config.help
file.
</para>
</chapter>
<chapter id="credits">
<title>Credits</title>
<para>
The following people have contributed to this document:
<orderedlist>
<listitem><para>
Mike Anderson <email>andmike@us.ibm.com</email>
</para></listitem>
<listitem><para>
James Bottomley <email>James.Bottomley@steeleye.com</email>
</para></listitem>
<listitem><para>
Patrick Mansfield <email>patmans@us.ibm.com</email>
</para></listitem>
</orderedlist>
</para>
</chapter>
</book>
Generic HDLC layer Generic HDLC layer
Krzysztof Halasa <khc@pm.waw.pl> Krzysztof Halasa <khc@pm.waw.pl>
January, 2003
Generic HDLC layer currently supports: Generic HDLC layer currently supports:
- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP). 1. Frame Relay (ANSI, CCITT, Cisco and no LMI).
Normal (routed) and Ethernet-bridged (Ethernet device emulation) - Normal (routed) and Ethernet-bridged (Ethernet device emulation)
interfaces can share a single PVC. interfaces can share a single PVC.
- raw HDLC - either IP (IPv4) interface or Ethernet device emulation. - ARP support (no InARP support in the kernel - there is an
- Cisco HDLC, experimental InARP user-space daemon available on:
- PPP (uses syncppp.c), http://www.kernel.org/pub/linux/utils/net/hdlc/).
- X.25 (uses X.25 routines). 2. raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
3. Cisco HDLC.
There are hardware drivers for the following cards: 4. PPP (uses syncppp.c).
- C101 by Moxa Technologies Co., Ltd. 5. X.25 (uses X.25 routines).
- RISCom/N2 by SDL Communications Inc.
- and others, some not in the official kernel. Generic HDLC is a protocol driver only - it needs a low-level driver
for your particular hardware.
Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
...@@ -24,7 +24,7 @@ with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging). ...@@ -24,7 +24,7 @@ with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
Make sure the hdlc.o and the hardware driver are loaded. It should Make sure the hdlc.o and the hardware driver are loaded. It should
create a number of "hdlc" (hdlc0 etc) network devices, one for each create a number of "hdlc" (hdlc0 etc) network devices, one for each
WAN port. You'll need the "sethdlc" utility, get it from: WAN port. You'll need the "sethdlc" utility, get it from:
http://hq.pm.waw.pl/hdlc/ http://www.kernel.org/pub/linux/utils/net/hdlc/
Compile sethdlc.c utility: Compile sethdlc.c utility:
gcc -O2 -Wall -o sethdlc sethdlc.c gcc -O2 -Wall -o sethdlc sethdlc.c
...@@ -52,12 +52,12 @@ Setting interface: ...@@ -52,12 +52,12 @@ Setting interface:
* v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port * v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port
if the card has software-selectable interfaces if the card has software-selectable interfaces
loopback - activate hardware loopback (for testing only) loopback - activate hardware loopback (for testing only)
* clock ext - external clock (uses DTE RX and TX clock) * clock ext - both RX clock and TX clock external
* clock int - internal clock (provides clock signal on DCE clock output) * clock int - both RX clock and TX clock internal
* clock txint - TX internal, RX external (provides TX clock on DCE output) * clock txint - RX clock external, TX clock internal
* clock txfromrx - TX clock derived from RX clock (TX clock on DCE output) * clock txfromrx - RX clock external, TX clock derived from RX clock
* rate - sets clock rate in bps (not required for external clock or * rate - sets clock rate in bps (for "int" or "txint" clock only)
for txfromrx)
Setting protocol: Setting protocol:
...@@ -79,7 +79,7 @@ Setting protocol: ...@@ -79,7 +79,7 @@ Setting protocol:
* x25 - sets X.25 mode * x25 - sets X.25 mode
* fr - Frame Relay mode * fr - Frame Relay mode
lmi ansi / ccitt / none - LMI (link management) type lmi ansi / ccitt / cisco / none - LMI (link management) type
dce - Frame Relay DCE (network) side LMI instead of default DTE (user). dce - Frame Relay DCE (network) side LMI instead of default DTE (user).
It has nothing to do with clocks! It has nothing to do with clocks!
t391 - link integrity verification polling timer (in seconds) - user t391 - link integrity verification polling timer (in seconds) - user
...@@ -119,13 +119,14 @@ or ...@@ -119,13 +119,14 @@ or
If you have a problem with N2 or C101 card, you can issue the "private" If you have a problem with N2, C101 or PLX200SYN card, you can issue the
command to see port's packet descriptor rings (in kernel logs): "private" command to see port's packet descriptor rings (in kernel logs):
sethdlc hdlc0 private sethdlc hdlc0 private
The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS. The hardware driver has to be build with #define DEBUG_RINGS.
Attaching this info to bug reports would be helpful. Anyway, let me know Attaching this info to bug reports would be helpful. Anyway, let me know
if you have problems using this. if you have problems using this.
For patches and other info look at http://hq.pm.waw.pl/hdlc/ For patches and other info look at:
<http://www.kernel.org/pub/linux/utils/net/hdlc/>.
...@@ -47,7 +47,6 @@ ni52 <------------------ Buggy ------------------> ...@@ -47,7 +47,6 @@ ni52 <------------------ Buggy ------------------>
ni65 YES YES YES Software(#) ni65 YES YES YES Software(#)
seeq NO NO NO N/A seeq NO NO NO N/A
sgiseek <------------------ Buggy ------------------> sgiseek <------------------ Buggy ------------------>
sk_g16 NO NO YES N/A
smc-ultra YES YES YES Hardware smc-ultra YES YES YES Hardware
sunlance YES YES YES Hardware sunlance YES YES YES Hardware
tulip YES YES YES Hardware tulip YES YES YES Hardware
......
...@@ -284,9 +284,6 @@ ppp.c: ...@@ -284,9 +284,6 @@ ppp.c:
seeq8005.c: *Not modularized* seeq8005.c: *Not modularized*
(Probes ports: 0x300, 0x320, 0x340, 0x360) (Probes ports: 0x300, 0x320, 0x340, 0x360)
sk_g16.c: *Not modularized*
(Probes ports: 0x100, 0x180, 0x208, 0x220m 0x288, 0x320, 0x328, 0x390)
skeleton.c: *Skeleton* skeleton.c: *Skeleton*
slhc.c: slhc.c:
......
Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
1. Added IOCTL backward compatibility.
Convert megaraid_mm driver to new compat_ioctl entry points.
I don't have easy access to hardware, so only compile tested.
- Signed-off-by:Andi Kleen <ak@muc.de>
2. megaraid_mbox fix: wrong order of arguments in memset()
That, BTW, shows why cross-builds are useful-the only indication of
problem had been a new warning showing up in sparse output on alpha
build (number of exceeding 256 got truncated).
- Signed-off-by: Al Viro
<viro@parcelfarce.linux.theplanet.co.uk>
3. Convert pci_module_init to pci_register_driver
Convert from pci_module_init to pci_register_driver
(from:http://kerneljanitors.org/TODO)
- Signed-off-by: Domen Puncer <domen@coderock.org>
4. Use the pre defined DMA mask constants from dma-mapping.h
Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling
pci_set_dma_mask() or pci_set_consistend_dma_mask(). See
http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for more
details.
Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch>
Signed-off-by: Domen Puncer <domen@coderock.org>
5. Remove SSID checking for Dobson, Lindsay, and Verde based products.
Checking the SSVID/SSID for controllers which have Dobson, Lindsay,
and Verde is unnecessary because device ID has been assigned by LSI
and it is unique value. So, all controllers with these IOPs have to be
supported by the driver regardless SSVID/SSID.
6. Date Thu, 27 Jan 2005 04:31:09 +0100
From Herbert Poetzl <>
Subject RFC: assert_spin_locked() for 2.6
Greetings!
overcautious programming will kill your kernel ;)
ever thought about checking a spin_lock or even
asserting that it must be held (maybe just for
spinlock debugging?) ...
there are several checks present in the kernel
where somebody does a variation on the following:
BUG_ON(!spin_is_locked(&some_lock));
so what's wrong about that? nothing, unless you
compile the code with CONFIG_DEBUG_SPINLOCK but
without CONFIG_SMP ... in which case the BUG()
will kill your kernel ...
maybe it's not advised to make such assertions,
but here is a solution which works for me ...
(compile tested for sh, x86_64 and x86, boot/run
tested for x86 only)
best,
Herbert
- Herbert Poetzl <herbert@13thfloor.at>, Thu, 27 Jan 2005
Release Date : Thu Feb 03 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com> Release Date : Thu Feb 03 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module) Current Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
Older Version : 2.20.4.4 (scsi module), 2.20.2.4 (cmm module) Older Version : 2.20.4.4 (scsi module), 2.20.2.4 (cmm module)
......
README for the SCSI media changer driver
========================================
This is a driver for SCSI Medium Changer devices, which are listed
with "Type: Medium Changer" in /proc/scsi/scsi.
This is for *real* Jukeboxes. It is *not* supported to work with
common small CD-ROM changers, neither one-lun-per-slot SCSI changers
nor IDE drives.
Userland tools available from here:
http://linux.bytesex.org/misc/changer.html
General Information
-------------------
First some words about how changers work: A changer has 2 (possibly
more) SCSI ID's. One for the changer device which controls the robot,
and one for the device which actually reads and writes the data. The
later may be anything, a MOD, a CD-ROM, a tape or whatever. For the
changer device this is a "don't care", he *only* shuffles around the
media, nothing else.
The SCSI changer model is complex, compared to - for example - IDE-CD
changers. But it allows to handle nearly all possible cases. It knows
4 different types of changer elements:
media transport - this one shuffles around the media, i.e. the
transport arm. Also known as "picker".
storage - a slot which can hold a media.
import/export - the same as above, but is accessable from outside,
i.e. there the operator (you !) can use this to
fill in and remove media from the changer.
Sometimes named "mailslot".
data transfer - this is the device which reads/writes, i.e. the
CD-ROM / Tape / whatever drive.
None of these is limited to one: A huge Jukebox could have slots for
123 CD-ROM's, 5 CD-ROM readers (and therefore 6 SCSI ID's: the changer
and each CD-ROM) and 2 transport arms. No problem to handle.
How it is implemented
---------------------
I implemented the driver as character device driver with a NetBSD-like
ioctl interface. Just grabbed NetBSD's header file and one of the
other linux SCSI device drivers as starting point. The interface
should be source code compatible with NetBSD. So if there is any
software (anybody knows ???) which supports a BSDish changer driver,
it should work with this driver too.
Over time a few more ioctls where added, volume tag support for example
wasn't covered by the NetBSD ioctl API.
Current State
-------------
Support for more than one transport arm is not implemented yet (and
nobody asked for it so far...).
I test and use the driver myself with a 35 slot cdrom jukebox from
Grundig. I got some reports telling it works ok with tape autoloaders
(Exabyte, HP and DEC). Some People use this driver with amanda. It
works fine with small (11 slots) and a huge (4 MOs, 88 slots)
magneto-optical Jukebox. Probably with lots of other changers too, most
(but not all :-) people mail me only if it does *not* work...
I don't have any device lists, neither black-list nor white-list. Thus
it is quite useless to ask me whenever a specific device is supported or
not. In theory every changer device which supports the SCSI-2 media
changer command set should work out-of-the-box with this driver. If it
doesn't, it is a bug. Either within the driver or within the firmware
of the changer device.
Using it
--------
This is a character device with major number is 86, so use
"mknod /dev/sch0 c 86 0" to create the special file for the driver.
If the module finds the changer, it prints some messages about the
device [ try "dmesg" if you don't see anything ] and should show up in
/proc/devices. If not.... some changers use ID ? / LUN 0 for the
device and ID ? / LUN 1 for the robot mechanism. But Linux does *not*
look for LUN's other than 0 as default, becauce there are to many
broken devices. So you can try:
1) echo "scsi add-single-device 0 0 ID 1" > /proc/scsi/scsi
(replace ID with the SCSI-ID of the device)
2) boot the kernel with "max_scsi_luns=1" on the command line
(append="max_scsi_luns=1" in lilo.conf should do the trick)
Trouble?
--------
If you insmod the driver with "insmod debug=1", it will be verbose and
prints a lot of stuff to the syslog. Compiling the kernel with
CONFIG_SCSI_CONSTANTS=y improves the quality of the error messages alot
because the kernel will translate the error codes into human-readable
strings then.
You can display these messages with the dmesg command (or check the
logfiles). If you email me some question becauce of a problem with the
driver, please include these messages.
Insmod options
--------------
debug=0/1
Enable debug messages (see above, default: 0).
verbose=0/1
Be verbose (default: 1).
init=0/1
Send INITIALIZE ELEMENT STATUS command to the changer
at insmod time (default: 1).
timeout_init=<seconds>
timeout for the INITIALIZE ELEMENT STATUS command
(default: 3600).
timeout_move=<seconds>
timeout for all other commands (default: 120).
dt_id=<id1>,<id2>,...
dt_lun=<lun1>,<lun2>,...
These two allow to specify the SCSI ID and LUN for the data
transfer elements. You likely don't need this as the jukebox
should provide this information. But some devices don't ...
vendor_firsts=
vendor_counts=
vendor_labels=
These insmod options can be used to tell the driver that there
are some vendor-specific element types. Grundig for example
does this. Some jukeboxes have a printer to label fresh burned
CDs, which is addressed as element 0xc000 (type 5). To tell the
driver about this vendor-specific element, use this:
$ insmod ch \
vendor_firsts=0xc000 \
vendor_counts=1 \
vendor_labels=printer
All three insmod options accept up to four comma-separated
values, this way you can configure the element types 5-8.
You likely need the SCSI specs for the device in question to
find the correct values as they are not covered by the SCSI-2
standard.
Credits
-------
I wrote this driver using the famous mailing-patches-around-the-world
method. With (more or less) help from:
Daniel Moehwald <moehwald@hdg.de>
Dane Jasper <dane@sonic.net>
R. Scott Bailey <sbailey@dsddi.eds.com>
Jonathan Corbet <corbet@lwn.net>
Special thanks go to
Martin Kuehne <martin.kuehne@bnbt.de>
for a old, second-hand (but full functional) cdrom jukebox which I use
to develop/test driver and tools now.
Have fun,
Gerd
--
Gerd Knorr <kraxel@bytesex.org>
...@@ -936,8 +936,7 @@ Details: ...@@ -936,8 +936,7 @@ Details:
* *
* Returns SUCCESS if command aborted else FAILED * Returns SUCCESS if command aborted else FAILED
* *
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry * Locks: None held
* and assumed to be held on return.
* *
* Calling context: kernel thread * Calling context: kernel thread
* *
...@@ -955,8 +954,7 @@ Details: ...@@ -955,8 +954,7 @@ Details:
* *
* Returns SUCCESS if command aborted else FAILED * Returns SUCCESS if command aborted else FAILED
* *
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry * Locks: None held
* and assumed to be held on return.
* *
* Calling context: kernel thread * Calling context: kernel thread
* *
...@@ -974,8 +972,7 @@ Details: ...@@ -974,8 +972,7 @@ Details:
* *
* Returns SUCCESS if command aborted else FAILED * Returns SUCCESS if command aborted else FAILED
* *
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry * Locks: None held
* and assumed to be held on return.
* *
* Calling context: kernel thread * Calling context: kernel thread
* *
...@@ -993,8 +990,7 @@ Details: ...@@ -993,8 +990,7 @@ Details:
* *
* Returns SUCCESS if command aborted else FAILED * Returns SUCCESS if command aborted else FAILED
* *
* Locks: struct Scsi_Host::host_lock held (with irqsave) on entry * Locks: None held
* and assumed to be held on return.
* *
* Calling context: kernel thread * Calling context: kernel thread
* *
......
...@@ -736,6 +736,11 @@ M: tori@unhappy.mine.nu ...@@ -736,6 +736,11 @@ M: tori@unhappy.mine.nu
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
DOCBOOK FOR DOCUMENTATION
P: Martin Waitz
M: tali@admingilde.org
S: Maintained
DOUBLETALK DRIVER DOUBLETALK DRIVER
P: James R. Van Zandt P: James R. Van Zandt
M: jrv@vanzandt.mv.com M: jrv@vanzandt.mv.com
......
...@@ -23,49 +23,92 @@ ...@@ -23,49 +23,92 @@
#include "entry-header.S" #include "entry-header.S"
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro irq_handler
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrne lr, 1b
bne asm_do_IRQ
#ifdef CONFIG_SMP
/*
* XXX
*
* this macro assumes that irqstat (r6) and base (r5) are
* preserved from get_irqnr_and_base above
*/
test_for_ipi r0, r6, r5, lr
movne r0, sp
adrne lr, 1b
bne do_IPI
#endif
.endm
/* /*
* Invalid mode handlers * Invalid mode handlers
*/ */
.macro inv_entry, sym, reason .macro inv_entry, reason
sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - lr} @ Save XXX r0 - lr stmib sp, {r1 - lr}
ldr r4, .LC\sym
mov r1, #\reason mov r1, #\reason
.endm .endm
__pabt_invalid: __pabt_invalid:
inv_entry abt, BAD_PREFETCH inv_entry BAD_PREFETCH
b 1f b common_invalid
__dabt_invalid: __dabt_invalid:
inv_entry abt, BAD_DATA inv_entry BAD_DATA
b 1f b common_invalid
__irq_invalid: __irq_invalid:
inv_entry irq, BAD_IRQ inv_entry BAD_IRQ
b 1f b common_invalid
__und_invalid: __und_invalid:
inv_entry und, BAD_UNDEFINSTR inv_entry BAD_UNDEFINSTR
@
@ XXX fall through to common_invalid
@
@
@ common_invalid - generic code for failed exception (re-entrant version of handlers)
@
common_invalid:
zero_fp
ldmia r0, {r4 - r6}
add r0, sp, #S_PC @ here for interlock avoidance
mov r7, #-1 @ "" "" "" ""
str r4, [sp] @ save preserved r0
stmia r0, {r5 - r7} @ lr_<exception>,
@ cpsr_<exception>, "old_r0"
1: zero_fp
ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0
add r4, sp, #S_PC
stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0
mov r0, sp mov r0, sp
and r2, r6, #31 @ int mode and r2, r6, #0x1f
b bad_mode b bad_mode
/* /*
* SVC mode handlers * SVC mode handlers
*/ */
.macro svc_entry, sym .macro svc_entry
sub sp, sp, #S_FRAME_SIZE sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12 stmib sp, {r1 - r12}
ldr r2, .LC\sym
add r0, sp, #S_FRAME_SIZE ldmia r0, {r1 - r3}
ldmia r2, {r2 - r4} @ get pc, cpsr add r5, sp, #S_SP @ here for interlock avoidance
add r5, sp, #S_SP mov r4, #-1 @ "" "" "" ""
add r0, sp, #S_FRAME_SIZE @ "" "" "" ""
str r1, [sp] @ save the "real" r0 copied
@ from the exception stack
mov r1, lr mov r1, lr
@ @
...@@ -82,7 +125,7 @@ __und_invalid: ...@@ -82,7 +125,7 @@ __und_invalid:
.align 5 .align 5
__dabt_svc: __dabt_svc:
svc_entry abt svc_entry
@ @
@ get ready to re-enable interrupts if appropriate @ get ready to re-enable interrupts if appropriate
...@@ -129,28 +172,24 @@ __dabt_svc: ...@@ -129,28 +172,24 @@ __dabt_svc:
.align 5 .align 5
__irq_svc: __irq_svc:
svc_entry irq svc_entry
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
get_thread_info r8 get_thread_info tsk
ldr r9, [r8, #TI_PREEMPT] @ get preempt count ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
add r7, r9, #1 @ increment it add r7, r8, #1 @ increment it
str r7, [r8, #TI_PREEMPT] str r7, [tsk, #TI_PREEMPT]
#endif #endif
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp irq_handler
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrne lr, 1b
bne asm_do_IRQ
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
ldr r0, [r8, #TI_FLAGS] @ get flags ldr r0, [tsk, #TI_FLAGS] @ get flags
tst r0, #_TIF_NEED_RESCHED tst r0, #_TIF_NEED_RESCHED
blne svc_preempt blne svc_preempt
preempt_return: preempt_return:
ldr r0, [r8, #TI_PREEMPT] @ read preempt value ldr r0, [tsk, #TI_PREEMPT] @ read preempt value
str r8, [tsk, #TI_PREEMPT] @ restore preempt count
teq r0, r7 teq r0, r7
str r9, [r8, #TI_PREEMPT] @ restore preempt count
strne r0, [r0, -r0] @ bug() strne r0, [r0, -r0] @ bug()
#endif #endif
ldr r0, [sp, #S_PSR] @ irqs are already disabled ldr r0, [sp, #S_PSR] @ irqs are already disabled
...@@ -161,7 +200,7 @@ preempt_return: ...@@ -161,7 +200,7 @@ preempt_return:
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
svc_preempt: svc_preempt:
teq r9, #0 @ was preempt count = 0 teq r8, #0 @ was preempt count = 0
ldreq r6, .LCirq_stat ldreq r6, .LCirq_stat
movne pc, lr @ no movne pc, lr @ no
ldr r0, [r6, #4] @ local_irq_count ldr r0, [r6, #4] @ local_irq_count
...@@ -169,9 +208,9 @@ svc_preempt: ...@@ -169,9 +208,9 @@ svc_preempt:
adds r0, r0, r1 adds r0, r0, r1
movne pc, lr movne pc, lr
mov r7, #0 @ preempt_schedule_irq mov r7, #0 @ preempt_schedule_irq
str r7, [r8, #TI_PREEMPT] @ expects preempt_count == 0 str r7, [tsk, #TI_PREEMPT] @ expects preempt_count == 0
1: bl preempt_schedule_irq @ irq en/disable is done inside 1: bl preempt_schedule_irq @ irq en/disable is done inside
ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS
tst r0, #_TIF_NEED_RESCHED tst r0, #_TIF_NEED_RESCHED
beq preempt_return @ go again beq preempt_return @ go again
b 1b b 1b
...@@ -179,7 +218,7 @@ svc_preempt: ...@@ -179,7 +218,7 @@ svc_preempt:
.align 5 .align 5
__und_svc: __und_svc:
svc_entry und svc_entry
@ @
@ call emulation code, which returns using r9 if it has emulated @ call emulation code, which returns using r9 if it has emulated
...@@ -209,7 +248,7 @@ __und_svc: ...@@ -209,7 +248,7 @@ __und_svc:
.align 5 .align 5
__pabt_svc: __pabt_svc:
svc_entry abt svc_entry
@ @
@ re-enable interrupts if appropriate @ re-enable interrupts if appropriate
...@@ -242,12 +281,8 @@ __pabt_svc: ...@@ -242,12 +281,8 @@ __pabt_svc:
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
.align 5 .align 5
.LCirq: .LCcralign:
.word __temp_irq .word cr_alignment
.LCund:
.word __temp_und
.LCabt:
.word __temp_abt
#ifdef MULTI_ABORT #ifdef MULTI_ABORT
.LCprocfns: .LCprocfns:
.word processor .word processor
...@@ -262,12 +297,16 @@ __pabt_svc: ...@@ -262,12 +297,16 @@ __pabt_svc:
/* /*
* User mode handlers * User mode handlers
*/ */
.macro usr_entry, sym .macro usr_entry
sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12 stmib sp, {r1 - r12}
ldr r7, .LC\sym
add r5, sp, #S_PC ldmia r0, {r1 - r3}
ldmia r7, {r2 - r4} @ Get USR pc, cpsr add r0, sp, #S_PC @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
str r1, [sp] @ save the "real" r0 copied
@ from the exception stack
#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
@ make sure our user space atomic helper is aborted @ make sure our user space atomic helper is aborted
...@@ -284,13 +323,13 @@ __pabt_svc: ...@@ -284,13 +323,13 @@ __pabt_svc:
@ @
@ Also, separately save sp_usr and lr_usr @ Also, separately save sp_usr and lr_usr
@ @
stmia r5, {r2 - r4} stmia r0, {r2 - r4}
stmdb r5, {sp, lr}^ stmdb r0, {sp, lr}^
@ @
@ Enable the alignment trap while in kernel mode @ Enable the alignment trap while in kernel mode
@ @
alignment_trap r7, r0, __temp_\sym alignment_trap r0
@ @
@ Clear FP to mark the first stack frame @ Clear FP to mark the first stack frame
...@@ -300,7 +339,7 @@ __pabt_svc: ...@@ -300,7 +339,7 @@ __pabt_svc:
.align 5 .align 5
__dabt_usr: __dabt_usr:
usr_entry abt usr_entry
@ @
@ Call the processor-specific abort handler: @ Call the processor-specific abort handler:
...@@ -329,30 +368,23 @@ __dabt_usr: ...@@ -329,30 +368,23 @@ __dabt_usr:
.align 5 .align 5
__irq_usr: __irq_usr:
usr_entry irq usr_entry
get_thread_info tsk
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
get_thread_info r8 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
ldr r9, [r8, #TI_PREEMPT] @ get preempt count add r7, r8, #1 @ increment it
add r7, r9, #1 @ increment it str r7, [tsk, #TI_PREEMPT]
str r7, [r8, #TI_PREEMPT]
#endif #endif
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp irq_handler
adrne lr, 1b
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
bne asm_do_IRQ
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
ldr r0, [r8, #TI_PREEMPT] ldr r0, [tsk, #TI_PREEMPT]
str r8, [tsk, #TI_PREEMPT]
teq r0, r7 teq r0, r7
str r9, [r8, #TI_PREEMPT]
strne r0, [r0, -r0] strne r0, [r0, -r0]
mov tsk, r8
#else
get_thread_info tsk
#endif #endif
mov why, #0 mov why, #0
b ret_to_user b ret_to_user
...@@ -360,7 +392,7 @@ __irq_usr: ...@@ -360,7 +392,7 @@ __irq_usr:
.align 5 .align 5
__und_usr: __und_usr:
usr_entry und usr_entry
tst r3, #PSR_T_BIT @ Thumb mode? tst r3, #PSR_T_BIT @ Thumb mode?
bne fpundefinstr @ ignore FP bne fpundefinstr @ ignore FP
...@@ -476,7 +508,7 @@ fpundefinstr: ...@@ -476,7 +508,7 @@ fpundefinstr:
.align 5 .align 5
__pabt_usr: __pabt_usr:
usr_entry abt usr_entry
enable_irq @ Enable interrupts enable_irq @ Enable interrupts
mov r0, r2 @ address (pc) mov r0, r2 @ address (pc)
...@@ -741,29 +773,41 @@ __kuser_helper_end: ...@@ -741,29 +773,41 @@ __kuser_helper_end:
* *
* Common stub entry macro: * Common stub entry macro:
* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*
* SP points to a minimal amount of processor-private memory, the address
* of which is copied into r0 for the mode specific abort handler.
*/ */
.macro vector_stub, name, sym, correction=0 .macro vector_stub, name, correction=0
.align 5 .align 5
vector_\name: vector_\name:
ldr r13, .LCs\sym
.if \correction .if \correction
sub lr, lr, #\correction sub lr, lr, #\correction
.endif .endif
str lr, [r13] @ save lr_IRQ
@
@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
@ (parent CPSR)
@
stmia sp, {r0, lr} @ save r0, lr
mrs lr, spsr mrs lr, spsr
str lr, [r13, #4] @ save spsr_IRQ str lr, [sp, #8] @ save spsr
@ @
@ now branch to the relevant MODE handling routine @ Prepare for SVC32 mode. IRQs remain disabled.
@ @
mrs r13, cpsr mrs r0, cpsr
bic r13, r13, #MODE_MASK bic r0, r0, #MODE_MASK
orr r13, r13, #SVC_MODE orr r0, r0, #SVC_MODE
msr spsr_cxsf, r13 @ switch to SVC_32 mode msr spsr_cxsf, r0
and lr, lr, #15 @
@ the branch table must immediately follow this code
@
mov r0, sp
and lr, lr, #0x0f
ldr lr, [pc, lr, lsl #2] ldr lr, [pc, lr, lsl #2]
movs pc, lr @ Changes mode and branches movs pc, lr @ branch to handler in SVC mode
.endm .endm
.globl __stubs_start .globl __stubs_start
...@@ -771,7 +815,7 @@ __stubs_start: ...@@ -771,7 +815,7 @@ __stubs_start:
/* /*
* Interrupt dispatcher * Interrupt dispatcher
*/ */
vector_stub irq, irq, 4 vector_stub irq, 4
.long __irq_usr @ 0 (USR_26 / USR_32) .long __irq_usr @ 0 (USR_26 / USR_32)
.long __irq_invalid @ 1 (FIQ_26 / FIQ_32) .long __irq_invalid @ 1 (FIQ_26 / FIQ_32)
...@@ -794,7 +838,7 @@ __stubs_start: ...@@ -794,7 +838,7 @@ __stubs_start:
* Data abort dispatcher * Data abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/ */
vector_stub dabt, abt, 8 vector_stub dabt, 8
.long __dabt_usr @ 0 (USR_26 / USR_32) .long __dabt_usr @ 0 (USR_26 / USR_32)
.long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
...@@ -817,7 +861,7 @@ __stubs_start: ...@@ -817,7 +861,7 @@ __stubs_start:
* Prefetch abort dispatcher * Prefetch abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/ */
vector_stub pabt, abt, 4 vector_stub pabt, 4
.long __pabt_usr @ 0 (USR_26 / USR_32) .long __pabt_usr @ 0 (USR_26 / USR_32)
.long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
...@@ -840,7 +884,7 @@ __stubs_start: ...@@ -840,7 +884,7 @@ __stubs_start:
* Undef instr entry dispatcher * Undef instr entry dispatcher
* Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/ */
vector_stub und, und vector_stub und
.long __und_usr @ 0 (USR_26 / USR_32) .long __und_usr @ 0 (USR_26 / USR_32)
.long __und_invalid @ 1 (FIQ_26 / FIQ_32) .long __und_invalid @ 1 (FIQ_26 / FIQ_32)
...@@ -894,13 +938,6 @@ vector_addrexcptn: ...@@ -894,13 +938,6 @@ vector_addrexcptn:
.LCvswi: .LCvswi:
.word vector_swi .word vector_swi
.LCsirq:
.word __temp_irq
.LCsund:
.word __temp_und
.LCsabt:
.word __temp_abt
.globl __stubs_end .globl __stubs_end
__stubs_end: __stubs_end:
...@@ -922,23 +959,6 @@ __vectors_end: ...@@ -922,23 +959,6 @@ __vectors_end:
.data .data
/*
* Do not reorder these, and do not insert extra data between...
*/
__temp_irq:
.word 0 @ saved lr_irq
.word 0 @ saved spsr_irq
.word -1 @ old_r0
__temp_und:
.word 0 @ Saved lr_und
.word 0 @ Saved spsr_und
.word -1 @ old_r0
__temp_abt:
.word 0 @ Saved lr_abt
.word 0 @ Saved spsr_abt
.word -1 @ old_r0
.globl cr_alignment .globl cr_alignment
.globl cr_no_alignment .globl cr_no_alignment
cr_alignment: cr_alignment:
......
...@@ -59,11 +59,10 @@ ...@@ -59,11 +59,10 @@
mov \rd, \rd, lsl #13 mov \rd, \rd, lsl #13
.endm .endm
.macro alignment_trap, rbase, rtemp, sym .macro alignment_trap, rtemp
#ifdef CONFIG_ALIGNMENT_TRAP #ifdef CONFIG_ALIGNMENT_TRAP
#define OFF_CR_ALIGNMENT(x) cr_alignment - x ldr \rtemp, .LCcralign
ldr \rtemp, [\rtemp]
ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
mcr p15, 0, \rtemp, c1, c0 mcr p15, 0, \rtemp, c1, c0
#endif #endif
.endm .endm
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* linux/arch/arm/kernel/head.S * linux/arch/arm/kernel/head.S
* *
* Copyright (C) 1994-2002 Russell King * Copyright (C) 1994-2002 Russell King
* Copyright (c) 2003 ARM Limited
* All Rights Reserved
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -165,6 +167,48 @@ __mmap_switched: ...@@ -165,6 +167,48 @@ __mmap_switched:
stmia r6, {r0, r4} @ Save control register values stmia r6, {r0, r4} @ Save control register values
b start_kernel b start_kernel
#if defined(CONFIG_SMP)
.type secondary_startup, #function
ENTRY(secondary_startup)
/*
* Common entry point for secondary CPUs.
*
* Ensure that we're in SVC mode, and IRQs are disabled. Lookup
* the processor type - there is no need to check the machine type
* as it has already been validated by the primary processor.
*/
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC
bl __lookup_processor_type
movs r10, r5 @ invalid processor?
moveq r0, #'p' @ yes, error 'p'
beq __error
/*
* Use the page tables supplied from __cpu_up.
*/
adr r4, __secondary_data
ldmia r4, {r5, r6, r13} @ address to jump to after
sub r4, r4, r5 @ mmu has been enabled
ldr r4, [r6, r4] @ get secondary_data.pgdir
adr lr, __enable_mmu @ return address
add pc, r10, #12 @ initialise processor
@ (return control reg)
/*
* r6 = &secondary_data
*/
ENTRY(__secondary_switched)
ldr sp, [r6, #4] @ get secondary_data.stack
mov fp, #0
b secondary_start_kernel
.type __secondary_data, %object
__secondary_data:
.long .
.long secondary_data
.long __secondary_switched
#endif /* defined(CONFIG_SMP) */
/* /*
......
...@@ -92,6 +92,14 @@ struct cpu_user_fns cpu_user; ...@@ -92,6 +92,14 @@ struct cpu_user_fns cpu_user;
struct cpu_cache_fns cpu_cache; struct cpu_cache_fns cpu_cache;
#endif #endif
struct stack {
u32 irq[3];
u32 abt[3];
u32 und[3];
} ____cacheline_aligned;
static struct stack stacks[NR_CPUS];
char elf_platform[ELF_PLATFORM_SIZE]; char elf_platform[ELF_PLATFORM_SIZE];
EXPORT_SYMBOL(elf_platform); EXPORT_SYMBOL(elf_platform);
...@@ -307,8 +315,6 @@ static void __init setup_processor(void) ...@@ -307,8 +315,6 @@ static void __init setup_processor(void)
cpu_name, processor_id, (int)processor_id & 15, cpu_name, processor_id, (int)processor_id & 15,
proc_arch[cpu_architecture()]); proc_arch[cpu_architecture()]);
dump_cpu_info(smp_processor_id());
sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
elf_hwcap = list->elf_hwcap; elf_hwcap = list->elf_hwcap;
...@@ -316,6 +322,46 @@ static void __init setup_processor(void) ...@@ -316,6 +322,46 @@ static void __init setup_processor(void)
cpu_proc_init(); cpu_proc_init();
} }
/*
* cpu_init - initialise one CPU.
*
* cpu_init dumps the cache information, initialises SMP specific
* information, and sets up the per-CPU stacks.
*/
void cpu_init(void)
{
unsigned int cpu = smp_processor_id();
struct stack *stk = &stacks[cpu];
if (cpu >= NR_CPUS) {
printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
BUG();
}
dump_cpu_info(cpu);
/*
* setup stacks for re-entrant exception handlers
*/
__asm__ (
"msr cpsr_c, %1\n\t"
"add sp, %0, %2\n\t"
"msr cpsr_c, %3\n\t"
"add sp, %0, %4\n\t"
"msr cpsr_c, %5\n\t"
"add sp, %0, %6\n\t"
"msr cpsr_c, %7"
:
: "r" (stk),
"I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
"I" (offsetof(struct stack, irq[0])),
"I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
"I" (offsetof(struct stack, abt[0])),
"I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
"I" (offsetof(struct stack, und[0])),
"I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE));
}
static struct machine_desc * __init setup_machine(unsigned int nr) static struct machine_desc * __init setup_machine(unsigned int nr)
{ {
struct machine_desc *list; struct machine_desc *list;
...@@ -715,6 +761,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -715,6 +761,8 @@ void __init setup_arch(char **cmdline_p)
paging_init(&meminfo, mdesc); paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc); request_standard_resources(&meminfo, mdesc);
cpu_init();
/* /*
* Set up various architecture-specific pointers * Set up various architecture-specific pointers
*/ */
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
...@@ -36,6 +39,13 @@ ...@@ -36,6 +39,13 @@
cpumask_t cpu_present_mask; cpumask_t cpu_present_mask;
cpumask_t cpu_online_map; cpumask_t cpu_online_map;
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
* where to place its SVC stack
*/
struct secondary_data secondary_data;
/* /*
* structures for inter-processor calls * structures for inter-processor calls
* - A collection of single bit ipi messages. * - A collection of single bit ipi messages.
...@@ -71,6 +81,8 @@ static DEFINE_SPINLOCK(smp_call_function_lock); ...@@ -71,6 +81,8 @@ static DEFINE_SPINLOCK(smp_call_function_lock);
int __init __cpu_up(unsigned int cpu) int __init __cpu_up(unsigned int cpu)
{ {
struct task_struct *idle; struct task_struct *idle;
pgd_t *pgd;
pmd_t *pmd;
int ret; int ret;
/* /*
...@@ -83,10 +95,55 @@ int __init __cpu_up(unsigned int cpu) ...@@ -83,10 +95,55 @@ int __init __cpu_up(unsigned int cpu)
return PTR_ERR(idle); return PTR_ERR(idle);
} }
/*
* Allocate initial page tables to allow the new CPU to
* enable the MMU safely. This essentially means a set
* of our "standard" page tables, with the addition of
* a 1:1 mapping for the physical address of the kernel.
*/
pgd = pgd_alloc(&init_mm);
pmd = pmd_offset(pgd, PHYS_OFFSET);
*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
/*
* We need to tell the secondary core where to find
* its stack and the page tables.
*/
secondary_data.stack = (void *)idle->thread_info + THREAD_SIZE - 8;
secondary_data.pgdir = virt_to_phys(pgd);
wmb();
/* /*
* Now bring the CPU into our world. * Now bring the CPU into our world.
*/ */
ret = boot_secondary(cpu, idle); ret = boot_secondary(cpu, idle);
if (ret == 0) {
unsigned long timeout;
/*
* CPU was successfully started, wait for it
* to come online or time out.
*/
timeout = jiffies + HZ;
while (time_before(jiffies, timeout)) {
if (cpu_online(cpu))
break;
udelay(10);
barrier();
}
if (!cpu_online(cpu))
ret = -EIO;
}
secondary_data.stack = 0;
secondary_data.pgdir = 0;
*pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
pgd_free(pgd);
if (ret) { if (ret) {
printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu); printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu);
/* /*
...@@ -97,6 +154,56 @@ int __init __cpu_up(unsigned int cpu) ...@@ -97,6 +154,56 @@ int __init __cpu_up(unsigned int cpu)
return ret; return ret;
} }
/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
asmlinkage void __init secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();
printk("CPU%u: Booted secondary processor\n", cpu);
/*
* All kernel threads share the same mm context; grab a
* reference and switch to it.
*/
atomic_inc(&mm->mm_users);
atomic_inc(&mm->mm_count);
current->active_mm = mm;
cpu_set(cpu, mm->cpu_vm_mask);
cpu_switch_mm(mm->pgd, mm);
enter_lazy_tlb(mm, current);
cpu_init();
/*
* Give the platform a chance to do its own initialisation.
*/
platform_secondary_init(cpu);
/*
* Enable local interrupts.
*/
local_irq_enable();
local_fiq_enable();
calibrate_delay();
smp_store_cpu_info(cpu);
/*
* OK, now it's safe to let the boot CPU continue
*/
cpu_set(cpu, cpu_online_map);
/*
* OK, it's off to the idle thread for us
*/
cpu_idle();
}
/* /*
* Called by both boot and secondaries to move global data into * Called by both boot and secondaries to move global data into
* per-processor storage. * per-processor storage.
......
...@@ -12,3 +12,4 @@ obj-$(CONFIG_LEDS) += leds.o ...@@ -12,3 +12,4 @@ obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_PCI) += pci_v3.o pci.o obj-$(CONFIG_PCI) += pci_v3.o pci.o
obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o
obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -221,7 +222,24 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -221,7 +222,24 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/ */
timer1->TimerClear = 1; timer1->TimerClear = 1;
timer_tick(regs); /*
* the clock tick routines are only processed on the
* primary CPU
*/
if (hard_smp_processor_id() == 0) {
nmi_tick();
timer_tick(regs);
#ifdef CONFIG_SMP
smp_send_timer();
#endif
}
#ifdef CONFIG_SMP
/*
* this is the ARM equivalent of the APIC timer interrupt
*/
update_process_times(user_mode(regs));
#endif /* CONFIG_SMP */
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
......
/*
* linux/arch/arm/mach-integrator/headsmp.S
*
* Copyright (c) 2003 ARM Limited
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <linux/init.h>
__INIT
/*
* Integrator specific entry point for secondary CPUs. This provides
* a "holding pen" into which all secondary cores are held until we're
* ready for them to initialise.
*/
ENTRY(integrator_secondary_startup)
adr r4, 1f
ldmia r4, {r5, r6}
sub r4, r4, r5
ldr r6, [r6, r4]
pen: ldr r7, [r6]
cmp r7, r0
bne pen
/*
* we've been released from the holding pen: secondary_stack
* should now contain the SVC stack for this core
*/
b secondary_startup
1: .long .
.long phys_pen_release
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -85,4 +87,4 @@ static int __init leds_init(void) ...@@ -85,4 +87,4 @@ static int __init leds_init(void)
return 0; return 0;
} }
__initcall(leds_init); core_initcall(leds_init);
/*
* linux/arch/arm/mach-cintegrator/platsmp.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <asm/atomic.h>
#include <asm/delay.h>
#include <asm/mmu_context.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
#include <asm/smp.h>
extern void integrator_secondary_startup(void);
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __initdata pen_release = -1;
unsigned long __initdata phys_pen_release = 0;
static DEFINE_SPINLOCK(boot_lock);
void __init platform_secondary_init(unsigned int cpu)
{
/*
* the primary core may have used a "cross call" soft interrupt
* to get this processor out of WFI in the BootMonitor - make
* sure that we are no longer being sent this soft interrupt
*/
smp_cross_call_done(cpumask_of_cpu(cpu));
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
secondary_scan_irqs();
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
pen_release = -1;
/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
int __init boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
/*
* set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);
/*
* The secondary processor is waiting to be released from
* the holding pen - release it, then wait for it to flag
* that it has been released by resetting pen_release.
*
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
pen_release = cpu;
/*
* XXX
*
* This is a later addition to the booting protocol: the
* bootMonitor now puts secondary cores into WFI, so
* poke_milo() no longer gets the cores moving; we need
* to send a soft interrupt to wake the secondary core.
* Use smp_cross_call() for this, since there's little
* point duplicating the code here
*/
smp_cross_call(cpumask_of_cpu(cpu));
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
if (pen_release == -1)
break;
udelay(10);
}
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);
return pen_release != -1 ? -ENOSYS : 0;
}
static void __init poke_milo(void)
{
extern void secondary_startup(void);
/* nobody is to be released from the pen yet */
pen_release = -1;
phys_pen_release = virt_to_phys(&pen_release);
/*
* write the address of secondary startup into the system-wide
* flags register, then clear the bottom two bits, which is what
* BootMonitor is waiting for
*/
#if 1
#define CINTEGRATOR_HDR_FLAGSS_OFFSET 0x30
__raw_writel(virt_to_phys(integrator_secondary_startup),
(IO_ADDRESS(INTEGRATOR_HDR_BASE) +
CINTEGRATOR_HDR_FLAGSS_OFFSET));
#define CINTEGRATOR_HDR_FLAGSC_OFFSET 0x34
__raw_writel(3,
(IO_ADDRESS(INTEGRATOR_HDR_BASE) +
CINTEGRATOR_HDR_FLAGSC_OFFSET));
#endif
mb();
}
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int ncores = get_core_count();
unsigned int cpu = smp_processor_id();
int i;
/* sanity check */
if (ncores == 0) {
printk(KERN_ERR
"Integrator/CP: strange CM count of 0? Default to 1\n");
ncores = 1;
}
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"Integrator/CP: no. of cores (%d) greater than configured "
"maximum of %d - clipping\n",
ncores, NR_CPUS);
ncores = NR_CPUS;
}
/*
* start with some more config for the Boot CPU, now that
* the world is a bit more alive (which was not the case
* when smp_prepare_boot_cpu() was called)
*/
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/*
* Initialise the present mask - this tells us which CPUs should
* be present.
*/
for (i = 0; i < max_cpus; i++) {
cpu_set(i, cpu_present_mask);
}
/*
* Do we need any more CPUs? If so, then let them know where
* to start. Note that, on modern versions of MILO, the "poke"
* doesn't actually do anything until each individual core is
* sent a soft interrupt to get it out of WFI
*/
if (max_cpus > 1)
poke_milo();
}
...@@ -133,6 +133,8 @@ static int pxa_pm_enter(suspend_state_t state) ...@@ -133,6 +133,8 @@ static int pxa_pm_enter(suspend_state_t state)
/* *** go zzz *** */ /* *** go zzz *** */
pxa_cpu_pm_enter(state); pxa_cpu_pm_enter(state);
cpu_init();
/* after sleeping, validate the checksum */ /* after sleeping, validate the checksum */
checksum = 0; checksum = 0;
for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
......
...@@ -88,6 +88,8 @@ static int sa11x0_pm_enter(suspend_state_t state) ...@@ -88,6 +88,8 @@ static int sa11x0_pm_enter(suspend_state_t state)
/* go zzz */ /* go zzz */
sa1100_cpu_suspend(); sa1100_cpu_suspend();
cpu_init();
/* /*
* Ensure not to come back here if it wasn't intended * Ensure not to come back here if it wasn't intended
*/ */
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/dma-mapping.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/genhd.h> #include <linux/genhd.h>
#include <linux/completion.h> #include <linux/completion.h>
...@@ -126,8 +127,6 @@ static struct board_type products[] = { ...@@ -126,8 +127,6 @@ static struct board_type products[] = {
#define MAX_CTLR_ORIG 8 #define MAX_CTLR_ORIG 8
#define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */
static ctlr_info_t *hba[MAX_CTLR]; static ctlr_info_t *hba[MAX_CTLR];
static void do_cciss_request(request_queue_t *q); static void do_cciss_request(request_queue_t *q);
...@@ -2393,11 +2392,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) ...@@ -2393,11 +2392,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
return( -1); return( -1);
} }
if (pci_set_dma_mask(pdev, CCISS_DMA_MASK ) != 0)
{
printk(KERN_ERR "cciss: Unable to set DMA mask\n");
return(-1);
}
subsystem_vendor_id = pdev->subsystem_vendor; subsystem_vendor_id = pdev->subsystem_vendor;
subsystem_device_id = pdev->subsystem_device; subsystem_device_id = pdev->subsystem_device;
...@@ -2747,9 +2741,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, ...@@ -2747,9 +2741,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->pdev = pdev; hba[i]->pdev = pdev;
/* configure PCI DMA stuff */ /* configure PCI DMA stuff */
if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
printk("cciss: using DAC cycles\n"); printk("cciss: using DAC cycles\n");
else if (!pci_set_dma_mask(pdev, 0xffffffff)) else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
printk("cciss: not using DAC cycles\n"); printk("cciss: not using DAC cycles\n");
else { else {
printk("cciss: no suitable DMA available\n"); printk("cciss: no suitable DMA available\n");
......
...@@ -285,6 +285,13 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) ...@@ -285,6 +285,13 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
rq = rq->end_io_data; rq = rq->end_io_data;
} }
/*
* the request is prepped and may have some resources allocated.
* allowing unprepped requests to pass this one may cause resource
* deadlock. turn on softbarrier.
*/
rq->flags |= REQ_SOFTBARRIER;
/* /*
* if iosched has an explicit requeue hook, then use that. otherwise * if iosched has an explicit requeue hook, then use that. otherwise
* just put the request at the front of the queue * just put the request at the front of the queue
...@@ -381,6 +388,12 @@ struct request *elv_next_request(request_queue_t *q) ...@@ -381,6 +388,12 @@ struct request *elv_next_request(request_queue_t *q)
if (ret == BLKPREP_OK) { if (ret == BLKPREP_OK) {
break; break;
} else if (ret == BLKPREP_DEFER) { } else if (ret == BLKPREP_DEFER) {
/*
* the request may have been (partially) prepped.
* we need to keep this request in the front to
* avoid resource deadlock. turn on softbarrier.
*/
rq->flags |= REQ_SOFTBARRIER;
rq = NULL; rq = NULL;
break; break;
} else if (ret == BLKPREP_KILL) { } else if (ret == BLKPREP_KILL) {
......
...@@ -2038,7 +2038,6 @@ EXPORT_SYMBOL(blk_requeue_request); ...@@ -2038,7 +2038,6 @@ EXPORT_SYMBOL(blk_requeue_request);
* @rq: request to be inserted * @rq: request to be inserted
* @at_head: insert request at head or tail of queue * @at_head: insert request at head or tail of queue
* @data: private data * @data: private data
* @reinsert: true if request it a reinsertion of previously processed one
* *
* Description: * Description:
* Many block devices need to execute commands asynchronously, so they don't * Many block devices need to execute commands asynchronously, so they don't
...@@ -2053,8 +2052,9 @@ EXPORT_SYMBOL(blk_requeue_request); ...@@ -2053,8 +2052,9 @@ EXPORT_SYMBOL(blk_requeue_request);
* host that is unable to accept a particular command. * host that is unable to accept a particular command.
*/ */
void blk_insert_request(request_queue_t *q, struct request *rq, void blk_insert_request(request_queue_t *q, struct request *rq,
int at_head, void *data, int reinsert) int at_head, void *data)
{ {
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
unsigned long flags; unsigned long flags;
/* /*
...@@ -2071,20 +2071,12 @@ void blk_insert_request(request_queue_t *q, struct request *rq, ...@@ -2071,20 +2071,12 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
/* /*
* If command is tagged, release the tag * If command is tagged, release the tag
*/ */
if (reinsert) if (blk_rq_tagged(rq))
blk_requeue_request(q, rq); blk_queue_end_tag(q, rq);
else {
int where = ELEVATOR_INSERT_BACK;
if (at_head)
where = ELEVATOR_INSERT_FRONT;
if (blk_rq_tagged(rq)) drive_stat_acct(rq, rq->nr_sectors, 1);
blk_queue_end_tag(q, rq); __elv_add_request(q, rq, where, 0);
drive_stat_acct(rq, rq->nr_sectors, 1);
__elv_add_request(q, rq, where, 0);
}
if (blk_queue_plugged(q)) if (blk_queue_plugged(q))
__generic_unplug_device(q); __generic_unplug_device(q);
else else
......
...@@ -723,7 +723,7 @@ static int pd_special_command(struct pd_unit *disk, ...@@ -723,7 +723,7 @@ static int pd_special_command(struct pd_unit *disk,
rq.ref_count = 1; rq.ref_count = 1;
rq.waiting = &wait; rq.waiting = &wait;
rq.end_io = blk_end_sync_rq; rq.end_io = blk_end_sync_rq;
blk_insert_request(disk->gd->queue, &rq, 0, func, 0); blk_insert_request(disk->gd->queue, &rq, 0, func);
wait_for_completion(&wait); wait_for_completion(&wait);
rq.waiting = NULL; rq.waiting = NULL;
if (rq.errors) if (rq.errors)
......
...@@ -614,7 +614,7 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx) ...@@ -614,7 +614,7 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx)
spin_unlock_irq(&host->lock); spin_unlock_irq(&host->lock);
DPRINTK("blk_insert_request, tag == %u\n", idx); DPRINTK("blk_insert_request, tag == %u\n", idx);
blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); blk_insert_request(host->oob_q, crq->rq, 1, crq);
return 0; return 0;
...@@ -653,7 +653,7 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func) ...@@ -653,7 +653,7 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func)
crq->msg_bucket = (u32) rc; crq->msg_bucket = (u32) rc;
DPRINTK("blk_insert_request, tag == %u\n", idx); DPRINTK("blk_insert_request, tag == %u\n", idx);
blk_insert_request(host->oob_q, crq->rq, 1, crq, 0); blk_insert_request(host->oob_q, crq->rq, 1, crq);
return 0; return 0;
} }
......
...@@ -2867,6 +2867,10 @@ void unblank_screen(void) ...@@ -2867,6 +2867,10 @@ void unblank_screen(void)
*/ */
static void blank_screen_t(unsigned long dummy) static void blank_screen_t(unsigned long dummy)
{ {
if (unlikely(!keventd_up())) {
mod_timer(&console_timer, jiffies + blankinterval);
return;
}
blank_timer_expired = 1; blank_timer_expired = 1;
schedule_work(&console_work); schedule_work(&console_work);
} }
......
...@@ -767,10 +767,8 @@ static void fcp_scsi_done (Scsi_Cmnd *SCpnt) ...@@ -767,10 +767,8 @@ static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
if (FCP_CMND(SCpnt)->done) if (FCP_CMND(SCpnt)->done)
FCP_CMND(SCpnt)->done(SCpnt); FCP_CMND(SCpnt)->done(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
} }
static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
...@@ -912,9 +910,7 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt) ...@@ -912,9 +910,7 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
unsigned long flags; unsigned long flags;
SCpnt->result = DID_ABORT; SCpnt->result = DID_ABORT;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
fcmd->done(SCpnt); fcmd->done(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
printk("FC: soft abort\n"); printk("FC: soft abort\n");
return SUCCESS; return SUCCESS;
} else { } else {
...@@ -987,7 +983,10 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) ...@@ -987,7 +983,10 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY; fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
fc->rst_pkt->done = fcp_scsi_reset_done; fc->rst_pkt->done = fcp_scsi_reset_done;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0); fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
down(&sem); down(&sem);
...@@ -1006,13 +1005,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) ...@@ -1006,13 +1005,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
return SUCCESS; return SUCCESS;
} }
int fcp_scsi_bus_reset(Scsi_Cmnd *SCpnt) static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
{
printk ("FC: bus reset!\n");
return FAILED;
}
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
{ {
fc_channel *fc = FC_SCMND(SCpnt); fc_channel *fc = FC_SCMND(SCpnt);
fcp_cmnd *fcmd = FCP_CMND(SCpnt); fcp_cmnd *fcmd = FCP_CMND(SCpnt);
...@@ -1033,6 +1026,17 @@ int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) ...@@ -1033,6 +1026,17 @@ int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
else return FAILED; else return FAILED;
} }
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
{
int rc;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
rc = __fcp_scsi_host_reset(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
return rc;
}
static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd) static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd)
{ {
long i; long i;
......
...@@ -27,7 +27,6 @@ EXPORT_SYMBOL(fc_do_prli); ...@@ -27,7 +27,6 @@ EXPORT_SYMBOL(fc_do_prli);
EXPORT_SYMBOL(fcp_scsi_queuecommand); EXPORT_SYMBOL(fcp_scsi_queuecommand);
EXPORT_SYMBOL(fcp_scsi_abort); EXPORT_SYMBOL(fcp_scsi_abort);
EXPORT_SYMBOL(fcp_scsi_dev_reset); EXPORT_SYMBOL(fcp_scsi_dev_reset);
EXPORT_SYMBOL(fcp_scsi_bus_reset);
EXPORT_SYMBOL(fcp_scsi_host_reset); EXPORT_SYMBOL(fcp_scsi_host_reset);
#endif /* CONFIG_MODULES */ #endif /* CONFIG_MODULES */
...@@ -158,7 +158,6 @@ int fc_do_prli(fc_channel *, unsigned char); ...@@ -158,7 +158,6 @@ int fc_do_prli(fc_channel *, unsigned char);
int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int fcp_scsi_abort(Scsi_Cmnd *); int fcp_scsi_abort(Scsi_Cmnd *);
int fcp_scsi_dev_reset(Scsi_Cmnd *); int fcp_scsi_dev_reset(Scsi_Cmnd *);
int fcp_scsi_bus_reset(Scsi_Cmnd *);
int fcp_scsi_host_reset(Scsi_Cmnd *); int fcp_scsi_host_reset(Scsi_Cmnd *);
#endif /* !(_FCP_SCSI_H) */ #endif /* !(_FCP_SCSI_H) */
...@@ -1071,7 +1071,7 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_ ...@@ -1071,7 +1071,7 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_
static __inline__ int sbp2_command_conversion_device_type(u8 device_type) static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
{ {
return (((device_type == TYPE_DISK) || return (((device_type == TYPE_DISK) ||
(device_type == TYPE_SDAD) || (device_type == TYPE_RBC) ||
(device_type == TYPE_ROM)) ? 1:0); (device_type == TYPE_ROM)) ? 1:0);
} }
...@@ -2112,102 +2112,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, ...@@ -2112,102 +2112,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
*/ */
static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd) static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
{ {
unchar new_cmd[16];
u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_command");
switch (*cmd) {
case READ_6:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert READ_6 to READ_10");
/*
* Need to turn read_6 into read_10
*/
new_cmd[0] = 0x28;
new_cmd[1] = (cmd[1] & 0xe0);
new_cmd[2] = 0x0;
new_cmd[3] = (cmd[1] & 0x1f);
new_cmd[4] = cmd[2];
new_cmd[5] = cmd[3];
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case WRITE_6:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
/*
* Need to turn write_6 into write_10
*/
new_cmd[0] = 0x2a;
new_cmd[1] = (cmd[1] & 0xe0);
new_cmd[2] = 0x0;
new_cmd[3] = (cmd[1] & 0x1f);
new_cmd[4] = cmd[2];
new_cmd[5] = cmd[3];
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case MODE_SENSE:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
/*
* Need to turn mode_sense_6 into mode_sense_10
*/
new_cmd[0] = 0x5a;
new_cmd[1] = cmd[1];
new_cmd[2] = cmd[2];
new_cmd[3] = 0x0;
new_cmd[4] = 0x0;
new_cmd[5] = 0x0;
new_cmd[6] = 0x0;
new_cmd[7] = 0x0;
new_cmd[8] = cmd[4];
new_cmd[9] = cmd[5];
memcpy(cmd, new_cmd, 10);
}
break;
case MODE_SELECT:
/*
* TODO. Probably need to change mode select to 10 byte version
*/
default:
break;
}
return;
} }
/* /*
...@@ -2248,7 +2152,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, ...@@ -2248,7 +2152,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt) struct scsi_cmnd *SCpnt)
{ {
u8 *scsi_buf = SCpnt->request_buffer; u8 *scsi_buf = SCpnt->request_buffer;
u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_response"); SBP2_DEBUG("sbp2_check_sbp2_response");
...@@ -2272,14 +2175,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, ...@@ -2272,14 +2175,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
scsi_buf[4] = 36 - 5; scsi_buf[4] = 36 - 5;
} }
/*
* Check for Simple Direct Access Device and change it to TYPE_DISK
*/
if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) {
SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK");
scsi_buf[0] &= 0xe0;
}
/* /*
* Fix ansi revision and response data format * Fix ansi revision and response data format
*/ */
...@@ -2288,27 +2183,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, ...@@ -2288,27 +2183,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
break; break;
case MODE_SENSE:
if (sbp2_command_conversion_device_type(device_type)) {
SBP2_DEBUG("Modify mode sense response (10 byte version)");
scsi_buf[0] = scsi_buf[1]; /* Mode data length */
scsi_buf[1] = scsi_buf[2]; /* Medium type */
scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */
scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */
memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
}
break;
case MODE_SELECT:
/*
* TODO. Probably need to change mode select to 10 byte version
*/
default: default:
break; break;
} }
...@@ -2580,8 +2454,6 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -2580,8 +2454,6 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
u32 scsi_status, struct scsi_cmnd *SCpnt, u32 scsi_status, struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *)) void (*done)(struct scsi_cmnd *))
{ {
unsigned long flags;
SBP2_DEBUG("sbp2scsi_complete_command"); SBP2_DEBUG("sbp2scsi_complete_command");
/* /*
...@@ -2680,18 +2552,15 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -2680,18 +2552,15 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
/* /*
* Tell scsi stack that we're done with this command * Tell scsi stack that we're done with this command
*/ */
spin_lock_irqsave(scsi_id->scsi_host->host_lock,flags);
done (SCpnt); done (SCpnt);
spin_unlock_irqrestore(scsi_id->scsi_host->host_lock,flags);
return;
} }
static int sbp2scsi_slave_configure (struct scsi_device *sdev) static int sbp2scsi_slave_configure (struct scsi_device *sdev)
{ {
blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
return 0; return 0;
} }
...@@ -2747,7 +2616,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) ...@@ -2747,7 +2616,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
/* /*
* Called by scsi stack when something has really gone wrong. * Called by scsi stack when something has really gone wrong.
*/ */
static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) static int __sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{ {
struct scsi_id_instance_data *scsi_id = struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
...@@ -2762,6 +2631,18 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) ...@@ -2762,6 +2631,18 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
return(SUCCESS); return(SUCCESS);
} }
static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{
unsigned long flags;
int rc;
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
rc = __sbp2scsi_reset(SCpnt);
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
return rc;
}
static const char *sbp2scsi_info (struct Scsi_Host *host) static const char *sbp2scsi_info (struct Scsi_Host *host)
{ {
return "SCSI emulation for IEEE-1394 SBP-2 Devices"; return "SCSI emulation for IEEE-1394 SBP-2 Devices";
......
...@@ -266,10 +266,6 @@ struct sbp2_status_block { ...@@ -266,10 +266,6 @@ struct sbp2_status_block {
#define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */ #define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */ #define SBP2_MAX_SECTORS 255 /* Max sectors supported */
#ifndef TYPE_SDAD
#define TYPE_SDAD 0x0e /* simplified direct access device */
#endif
/* /*
* SCSI direction table... * SCSI direction table...
* (now used as a back-up in case the direction passed down from above is "unknown") * (now used as a back-up in case the direction passed down from above is "unknown")
......
...@@ -2,34 +2,54 @@ ...@@ -2,34 +2,54 @@
menu "Fusion MPT device support" menu "Fusion MPT device support"
config FUSION config FUSION
tristate "Fusion MPT (base + ScsiHost) drivers" bool
default n
config FUSION_SPI
tristate "Fusion MPT ScsiHost drivers for SPI"
depends on PCI && SCSI
select FUSION
---help---
SCSI HOST support for a parallel SCSI host adapters.
List of supported controllers:
LSI53C1020
LSI53C1020A
LSI53C1030
LSI53C1035
config FUSION_FC
tristate "Fusion MPT ScsiHost drivers for FC"
depends on PCI && SCSI depends on PCI && SCSI
select FUSION
---help--- ---help---
LSI Logic Fusion(TM) Message Passing Technology (MPT) device support SCSI HOST support for a Fiber Channel host adapters.
provides high performance SCSI host initiator, and LAN [1] interface
services to a host system. The Fusion architecture is capable of
duplexing these protocols on high-speed Fibre Channel
(up to 2 GHz x 2 ports = 4 GHz) and parallel SCSI (up to Ultra-320)
physical medium.
[1] LAN is not supported on parallel SCSI medium. List of supported controllers:
LSIFC909
LSIFC919
LSIFC919X
LSIFC929
LSIFC929X
LSIFC929XL
config FUSION_MAX_SGE config FUSION_MAX_SGE
int "Maximum number of scatter gather entries" int "Maximum number of scatter gather entries (16 - 128)"
depends on FUSION depends on FUSION
default "40" default "128"
range 16 128
help help
This option allows you to specify the maximum number of scatter- This option allows you to specify the maximum number of scatter-
gather entries per I/O. The driver defaults to 40, a reasonable number gather entries per I/O. The driver default is 128, which matches
for most systems. However, the user may increase this up to 128. SCSI_MAX_PHYS_SEGMENTS. However, it may decreased down to 16.
Increasing this parameter will require significantly more memory Decreasing this parameter will reduce memory requirements
on a per controller instance. Increasing the parameter is not on a per controller instance.
necessary (or recommended) unless the user will be running
large I/O's via the raw interface.
config FUSION_CTL config FUSION_CTL
tristate "Fusion MPT misc device (ioctl) driver" tristate "Fusion MPT misc device (ioctl) driver"
depends on FUSION depends on FUSION_SPI || FUSION_FC
---help--- ---help---
The Fusion MPT misc device driver provides specialized control The Fusion MPT misc device driver provides specialized control
of MPT adapters via system ioctl calls. Use of ioctl calls to of MPT adapters via system ioctl calls. Use of ioctl calls to
...@@ -48,7 +68,7 @@ config FUSION_CTL ...@@ -48,7 +68,7 @@ config FUSION_CTL
config FUSION_LAN config FUSION_LAN
tristate "Fusion MPT LAN driver" tristate "Fusion MPT LAN driver"
depends on FUSION && NET_FC depends on FUSION_FC && NET_FC
---help--- ---help---
This module supports LAN IP traffic over Fibre Channel port(s) This module supports LAN IP traffic over Fibre Channel port(s)
on Fusion MPT compatible hardware (LSIFC9xx chips). on Fusion MPT compatible hardware (LSIFC9xx chips).
......
#
# 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
# 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
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-{ LSI_LOGIC
# Architecture-specific...
# # intel
#EXTRA_CFLAGS += -g
# # sparc64
#EXTRA_CFLAGS += -gstabs+
EXTRA_CFLAGS += ${MPT_CFLAGS}
# Fusion MPT drivers; recognized debug defines... # Fusion MPT drivers; recognized debug defines...
# MPT general: # MPT general:
#EXTRA_CFLAGS += -DMPT_DEBUG_SCSI
#EXTRA_CFLAGS += -DMPT_DEBUG #EXTRA_CFLAGS += -DMPT_DEBUG
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
#EXTRA_CFLAGS += -DMPT_DEBUG_SG #EXTRA_CFLAGS += -DMPT_DEBUG_SG
#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS
#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
# #
# driver/module specifics... # driver/module specifics...
# #
# For mptbase: # For mptbase:
#CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE #CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE
#CFLAGS_mptbase.o += -DMPT_DEBUG_CONFIG
#CFLAGS_mptbase.o += -DMPT_DEBUG_DL
#CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ #CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ
#CFLAGS_mptbase.o += -DMPT_DEBUG_RESET
# #
# For mptscsih: # For mptscsih:
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV #CFLAGS_mptscsih.o += -DMPT_DEBUG_DV
#CFLAGS_mptscsih.o += -DMPT_DEBUG_RESET #CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO
#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEH #CFLAGS_mptscsih.o += -DMPT_DEBUG_TM
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI
#CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY
# #
# For mptctl: # For mptctl:
#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
# #
# For mptlan:
#CFLAGS_mptlan.o += -DMPT_LAN_IO_DEBUG
#
# For isense:
# EXP...
##mptscsih-objs := scsihost.o scsiherr.o
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
obj-$(CONFIG_FUSION) += mptbase.o mptscsih.o obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
obj-$(CONFIG_FUSION_FC) += mptbase.o mptscsih.o mptfc.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
/* /*
* Copyright (c) 2000-2003 LSI Logic Corporation. * Copyright (c) 2000-2005 LSI Logic Corporation.
* *
* *
* Name: mpi.h * Name: mpi.h
* Title: MPI Message independent structures and definitions * Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000 * Creation Date: July 27, 2000
* *
* mpi.h Version: 01.05.xx * mpi.h Version: 01.05.07
* *
* Version History * Version History
* --------------- * ---------------
...@@ -52,6 +52,25 @@ ...@@ -52,6 +52,25 @@
* obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX. * obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
* 04-01-03 01.02.09 New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED * 04-01-03 01.02.09 New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
* 06-26-03 01.02.10 Bumped MPI_HEADER_VERSION_UNIT value. * 06-26-03 01.02.10 Bumped MPI_HEADER_VERSION_UNIT value.
* 01-16-04 01.02.11 Added define for MPI_IOCLOGINFO_TYPE_SHIFT.
* 04-29-04 01.02.12 Added function codes for MPI_FUNCTION_DIAG_BUFFER_POST
* and MPI_FUNCTION_DIAG_RELEASE.
* Added MPI_IOCSTATUS_DIAGNOSTIC_RELEASED define.
* Bumped MPI_HEADER_VERSION_UNIT value.
* 05-11-04 01.03.01 Bumped MPI_VERSION_MINOR for MPI v1.3.
* Added codes for Inband.
* 08-19-04 01.05.01 Added defines for Host Buffer Access Control doorbell.
* Added define for offset of High Priority Request Queue.
* Added new function codes and new IOCStatus codes.
* Added a IOCLogInfo type of SAS.
* 12-07-04 01.05.02 Bumped MPI_HEADER_VERSION_UNIT.
* 12-09-04 01.05.03 Bumped MPI_HEADER_VERSION_UNIT.
* 01-15-05 01.05.04 Bumped MPI_HEADER_VERSION_UNIT.
* 02-09-05 01.05.05 Bumped MPI_HEADER_VERSION_UNIT.
* 02-22-05 01.05.06 Bumped MPI_HEADER_VERSION_UNIT.
* 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Removed EEDP IOCStatus codes.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -82,7 +101,7 @@ ...@@ -82,7 +101,7 @@
/* Note: The major versions of 0xe0 through 0xff are reserved */ /* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */ /* versioning for this MPI header set */
#define MPI_HEADER_VERSION_UNIT (0x00) #define MPI_HEADER_VERSION_UNIT (0x09)
#define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8) #define MPI_HEADER_VERSION_UNIT_SHIFT (8)
...@@ -122,7 +141,11 @@ ...@@ -122,7 +141,11 @@
* *
*****************************************************************************/ *****************************************************************************/
/* S y s t e m D o o r b e l l */ /*
* Defines for working with the System Doorbell register.
* Values for doorbell function codes are included in the section that defines
* all the function codes (further on in this file).
*/
#define MPI_DOORBELL_OFFSET (0x00000000) #define MPI_DOORBELL_OFFSET (0x00000000)
#define MPI_DOORBELL_ACTIVE (0x08000000) /* DoorbellUsed */ #define MPI_DOORBELL_ACTIVE (0x08000000) /* DoorbellUsed */
#define MPI_DOORBELL_USED (MPI_DOORBELL_ACTIVE) #define MPI_DOORBELL_USED (MPI_DOORBELL_ACTIVE)
...@@ -134,6 +157,13 @@ ...@@ -134,6 +157,13 @@
#define MPI_DOORBELL_ADD_DWORDS_MASK (0x00FF0000) #define MPI_DOORBELL_ADD_DWORDS_MASK (0x00FF0000)
#define MPI_DOORBELL_ADD_DWORDS_SHIFT (16) #define MPI_DOORBELL_ADD_DWORDS_SHIFT (16)
#define MPI_DOORBELL_DATA_MASK (0x0000FFFF) #define MPI_DOORBELL_DATA_MASK (0x0000FFFF)
#define MPI_DOORBELL_FUNCTION_SPECIFIC_MASK (0x0000FFFF)
/* values for Host Buffer Access Control doorbell function */
#define MPI_DB_HPBAC_VALUE_MASK (0x0000F000)
#define MPI_DB_HPBAC_ENABLE_ACCESS (0x01)
#define MPI_DB_HPBAC_DISABLE_ACCESS (0x02)
#define MPI_DB_HPBAC_FREE_BUFFER (0x03)
#define MPI_WRITE_SEQUENCE_OFFSET (0x00000004) #define MPI_WRITE_SEQUENCE_OFFSET (0x00000004)
...@@ -257,16 +287,18 @@ ...@@ -257,16 +287,18 @@
#define MPI_FUNCTION_SMP_PASSTHROUGH (0x1A) #define MPI_FUNCTION_SMP_PASSTHROUGH (0x1A)
#define MPI_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) #define MPI_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B)
#define MPI_FUNCTION_SATA_PASSTHROUGH (0x1C)
#define MPI_DIAG_BUFFER_POST (0x1D) #define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D)
#define MPI_DIAG_RELEASE (0x1E) #define MPI_FUNCTION_DIAG_RELEASE (0x1E)
#define MPI_FUNCTION_SCSI_IO_32 (0x1F)
#define MPI_FUNCTION_LAN_SEND (0x20) #define MPI_FUNCTION_LAN_SEND (0x20)
#define MPI_FUNCTION_LAN_RECEIVE (0x21) #define MPI_FUNCTION_LAN_RECEIVE (0x21)
#define MPI_FUNCTION_LAN_RESET (0x22) #define MPI_FUNCTION_LAN_RESET (0x22)
#define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24)
#define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25)
#define MPI_FUNCTION_INBAND_BUFFER_POST (0x28) #define MPI_FUNCTION_INBAND_BUFFER_POST (0x28)
#define MPI_FUNCTION_INBAND_SEND (0x29) #define MPI_FUNCTION_INBAND_SEND (0x29)
#define MPI_FUNCTION_INBAND_RSP (0x2A) #define MPI_FUNCTION_INBAND_RSP (0x2A)
...@@ -276,6 +308,7 @@ ...@@ -276,6 +308,7 @@
#define MPI_FUNCTION_IO_UNIT_RESET (0x41) #define MPI_FUNCTION_IO_UNIT_RESET (0x41)
#define MPI_FUNCTION_HANDSHAKE (0x42) #define MPI_FUNCTION_HANDSHAKE (0x42)
#define MPI_FUNCTION_REPLY_FRAME_REMOVAL (0x43) #define MPI_FUNCTION_REPLY_FRAME_REMOVAL (0x43)
#define MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL (0x44)
/* standard version format */ /* standard version format */
...@@ -328,8 +361,8 @@ typedef struct _SGE_SIMPLE_UNION ...@@ -328,8 +361,8 @@ typedef struct _SGE_SIMPLE_UNION
U32 Address32; U32 Address32;
U64 Address64; U64 Address64;
}u; }u;
} SGESimpleUnion_t, MPI_POINTER pSGESimpleUnion_t, } SGE_SIMPLE_UNION, MPI_POINTER PTR_SGE_SIMPLE_UNION,
SGE_SIMPLE_UNION, MPI_POINTER PTR_SGE_SIMPLE_UNION; SGESimpleUnion_t, MPI_POINTER pSGESimpleUnion_t;
/****************************************************************************/ /****************************************************************************/
/* Chain element structures */ /* Chain element structures */
...@@ -648,27 +681,21 @@ typedef struct _MSG_DEFAULT_REPLY ...@@ -648,27 +681,21 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) #define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
/****************************************************************************/ /****************************************************************************/
/* For use by SCSI Initiator and SCSI Target end-to-end data protection */ /* SCSI Target values */
/****************************************************************************/
#define MPI_IOCSTATUS_EEDP_CRC_ERROR (0x004D)
#define MPI_IOCSTATUS_EEDP_LBA_TAG_ERROR (0x004E)
#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F)
/****************************************************************************/
/* SCSI (SPI & FCP) target values */
/****************************************************************************/ /****************************************************************************/
#define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060) #define MPI_IOCSTATUS_TARGET_PRIORITY_IO (0x0060)
#define MPI_IOCSTATUS_TARGET_INVALID_PORT (0x0061) #define MPI_IOCSTATUS_TARGET_INVALID_PORT (0x0061)
#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) /* obsolete */ #define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX (0x0062) /* obsolete name */
#define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) #define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062)
#define MPI_IOCSTATUS_TARGET_ABORTED (0x0063) #define MPI_IOCSTATUS_TARGET_ABORTED (0x0063)
#define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) #define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064)
#define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) #define MPI_IOCSTATUS_TARGET_NO_CONNECTION (0x0065)
#define MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A) #define MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A)
#define MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT (0x006B) #define MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT (0x006B)
#define MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D)
#define MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E)
#define MPI_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F)
/****************************************************************************/ /****************************************************************************/
/* Additional FCP target values (obsolete) */ /* Additional FCP target values (obsolete) */
...@@ -707,6 +734,7 @@ typedef struct _MSG_DEFAULT_REPLY ...@@ -707,6 +734,7 @@ typedef struct _MSG_DEFAULT_REPLY
/****************************************************************************/ /****************************************************************************/
#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) #define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
#define MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN (0x0091)
/****************************************************************************/ /****************************************************************************/
/* Inband values */ /* Inband values */
......
/* /*
* Copyright (c) 2000-2003 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Logic Corporation.
* *
* *
* Name: mpi_fc.h * Name: mpi_fc.h
* Title: MPI Fibre Channel messages and structures * Title: MPI Fibre Channel messages and structures
* Creation Date: June 12, 2000 * Creation Date: June 12, 2000
* *
* mpi_fc.h Version: 01.05.xx * mpi_fc.h Version: 01.05.01
* *
* Version History * Version History
* --------------- * ---------------
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
* 09-28-01 01.02.02 Change name of reserved field in * 09-28-01 01.02.02 Change name of reserved field in
* MSG_LINK_SERVICE_RSP_REPLY. * MSG_LINK_SERVICE_RSP_REPLY.
* 05-31-02 01.02.03 Adding AliasIndex to FC Direct Access requests. * 05-31-02 01.02.03 Adding AliasIndex to FC Direct Access requests.
* 01-16-04 01.02.04 Added define for MPI_FC_PRIM_SEND_FLAGS_ML_RESET_LINK.
* 05-11-04 01.03.01 Original release for MPI v1.3.
* 08-19-04 01.05.01 Original release for MPI v1.5.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
......
/* /*
* Copyright (c) 2003 LSI Logic Corporation. * Copyright (c) 2003-2004 LSI Logic Corporation.
* *
* *
* Name: mpi_inb.h * Name: mpi_inb.h
* Title: MPI Inband structures and definitions * Title: MPI Inband structures and definitions
* Creation Date: September 30, 2003 * Creation Date: September 30, 2003
* *
* mpi_inb.h Version: 01.03.xx * mpi_inb.h Version: 01.05.01
* *
* Version History * Version History
* --------------- * ---------------
* *
* Date Version Description * Date Version Description
* -------- -------- ------------------------------------------------------ * -------- -------- ------------------------------------------------------
* ??-??-?? 01.03.01 Original release. * 05-11-04 01.03.01 Original release.
* 08-19-04 01.05.01 Original release for MPI v1.5.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
......
/* /*
* Copyright (c) 2000-2003 LSI Logic Corporation. * Copyright (c) 2000-2005 LSI Logic Corporation.
* *
* *
* Name: mpi_init.h * Name: mpi_init.h
* Title: MPI initiator mode messages and structures * Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000 * Creation Date: June 8, 2000
* *
* mpi_init.h Version: 01.05.xx * mpi_init.h Version: 01.05.04
* *
* Version History * Version History
* --------------- * ---------------
...@@ -33,6 +33,21 @@ ...@@ -33,6 +33,21 @@
* for SCSI IO requests. * for SCSI IO requests.
* 11-15-02 01.02.06 Added special extended SCSI Status defines for FCP. * 11-15-02 01.02.06 Added special extended SCSI Status defines for FCP.
* 06-26-03 01.02.07 Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define. * 06-26-03 01.02.07 Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define.
* 05-11-04 01.03.01 Original release for MPI v1.3.
* 08-19-04 01.05.01 Added MsgFlags defines for EEDP to SCSI IO request.
* Added new word to MSG_SCSI_IO_REPLY to add TaskTag field
* and a reserved U16.
* Added new MSG_SCSI_IO32_REQUEST structure.
* Added a TaskType of Clear Task Set to SCSI
* Task Management request.
* 12-07-04 01.05.02 Added support for Task Management Query Task.
* 01-15-05 01.05.03 Modified SCSI Enclosure Processor Request to support
* WWID addressing.
* 03-11-05 01.05.04 Removed EEDP flags from SCSI IO Request.
* Removed SCSI IO 32 Request.
* Modified SCSI Enclosure Processor Request and Reply to
* support Enclosure/Slot addressing rather than WWID
* addressing.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -76,20 +91,12 @@ typedef struct _MSG_SCSI_IO_REQUEST ...@@ -76,20 +91,12 @@ typedef struct _MSG_SCSI_IO_REQUEST
#define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH (0x01) #define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH (0x01)
#define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32 (0x00) #define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32 (0x00)
#define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 (0x01) #define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64 (0x01)
#define MPI_SCSIIO_MSGFLGS_SENSE_LOCATION (0x02) #define MPI_SCSIIO_MSGFLGS_SENSE_LOCATION (0x02)
#define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST (0x00) #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST (0x00)
#define MPI_SCSIIO_MSGFLGS_SENSE_LOC_IOC (0x02) #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_IOC (0x02)
#define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04)
#define MPI_SCSIIO_MSGFLGS_EEDP_TYPE_MASK (0xE0)
#define MPI_SCSIIO_MSGFLGS_EEDP_NONE (0x00)
#define MPI_SCSIIO_MSGFLGS_EEDP_RDPROTECT_T10 (0x20)
#define MPI_SCSIIO_MSGFLGS_EEDP_VRPROTECT_T10 (0x40)
#define MPI_SCSIIO_MSGFLGS_EEDP_WRPROTECT_T10 (0x60)
#define MPI_SCSIIO_MSGFLGS_EEDP_520_READ_MODE1 (0x20)
#define MPI_SCSIIO_MSGFLGS_EEDP_520_WRITE_MODE1 (0x40)
#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_READ_MODE1 (0x60)
#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_WRITE_MODE1 (0x80)
#define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04)
/* SCSI IO LUN fields */ /* SCSI IO LUN fields */
...@@ -148,6 +155,8 @@ typedef struct _MSG_SCSI_IO_REPLY ...@@ -148,6 +155,8 @@ typedef struct _MSG_SCSI_IO_REPLY
U32 TransferCount; /* 14h */ U32 TransferCount; /* 14h */
U32 SenseCount; /* 18h */ U32 SenseCount; /* 18h */
U32 ResponseInfo; /* 1Ch */ U32 ResponseInfo; /* 1Ch */
U16 TaskTag; /* 20h */
U16 Reserved1; /* 22h */
} MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY, } MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY,
SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t; SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t;
...@@ -190,32 +199,7 @@ typedef struct _MSG_SCSI_IO_REPLY ...@@ -190,32 +199,7 @@ typedef struct _MSG_SCSI_IO_REPLY
#define MPI_SCSI_RSP_INFO_TASK_MGMT_FAILED (0x05000000) #define MPI_SCSI_RSP_INFO_TASK_MGMT_FAILED (0x05000000)
#define MPI_SCSI_RSP_INFO_SPI_LQ_INVALID_TYPE (0x06000000) #define MPI_SCSI_RSP_INFO_SPI_LQ_INVALID_TYPE (0x06000000)
#define MPI_SCSI_TASKTAG_UNKNOWN (0xFFFF)
/****************************************************************************/
/* SCSI IO 32 Request message structure */
/****************************************************************************/
typedef struct _MSG_SCSI_IO32_REQUEST
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 CDBLength; /* 04h */
U8 SenseBufferLength; /* 05h */
U8 Reserved; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 LUN[8]; /* 0Ch */
U32 Control; /* 14h */
U8 CDB[32]; /* 18h */
U32 DataLength; /* 38h */
U32 SenseBufferLowAddr; /* 3Ch */
SGE_IO_UNION SGL; /* 40h */
} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
/* SCSI IO 32 uses the same defines as above for SCSI IO */
/****************************************************************************/ /****************************************************************************/
...@@ -247,6 +231,7 @@ typedef struct _MSG_SCSI_TASK_MGMT ...@@ -247,6 +231,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04) #define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04)
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
/* MsgFlags bits */ /* MsgFlags bits */
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
...@@ -260,7 +245,7 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY ...@@ -260,7 +245,7 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
U8 Bus; /* 01h */ U8 Bus; /* 01h */
U8 MsgLength; /* 02h */ U8 MsgLength; /* 02h */
U8 Function; /* 03h */ U8 Function; /* 03h */
U8 Reserved; /* 04h */ U8 ResponseCode; /* 04h */
U8 TaskType; /* 05h */ U8 TaskType; /* 05h */
U8 Reserved1; /* 06h */ U8 Reserved1; /* 06h */
U8 MsgFlags; /* 07h */ U8 MsgFlags; /* 07h */
...@@ -272,6 +257,15 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY ...@@ -272,6 +257,15 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
} MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY, } MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t; SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
/* ResponseCode values */
#define MPI_SCSITASKMGMT_RSP_TM_COMPLETE (0x00)
#define MPI_SCSITASKMGMT_RSP_INVALID_FRAME (0x02)
#define MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04)
#define MPI_SCSITASKMGMT_RSP_TM_FAILED (0x05)
#define MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08)
#define MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09)
#define MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80)
/****************************************************************************/ /****************************************************************************/
/* SCSI Enclosure Processor messages */ /* SCSI Enclosure Processor messages */
...@@ -284,11 +278,16 @@ typedef struct _MSG_SEP_REQUEST ...@@ -284,11 +278,16 @@ typedef struct _MSG_SEP_REQUEST
U8 ChainOffset; /* 02h */ U8 ChainOffset; /* 02h */
U8 Function; /* 03h */ U8 Function; /* 03h */
U8 Action; /* 04h */ U8 Action; /* 04h */
U8 Reserved1; /* 05h */ U8 Flags; /* 05h */
U8 Reserved2; /* 06h */ U8 Reserved1; /* 06h */
U8 MsgFlags; /* 07h */ U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */ U32 MsgContext; /* 08h */
U32 SlotStatus; /* 0Ch */ U32 SlotStatus; /* 0Ch */
U32 Reserved2; /* 10h */
U32 Reserved3; /* 14h */
U32 Reserved4; /* 18h */
U16 Slot; /* 1Ch */
U16 EnclosureHandle; /* 1Eh */
} MSG_SEP_REQUEST, MPI_POINTER PTR_MSG_SEP_REQUEST, } MSG_SEP_REQUEST, MPI_POINTER PTR_MSG_SEP_REQUEST,
SEPRequest_t, MPI_POINTER pSEPRequest_t; SEPRequest_t, MPI_POINTER pSEPRequest_t;
...@@ -296,6 +295,10 @@ typedef struct _MSG_SEP_REQUEST ...@@ -296,6 +295,10 @@ typedef struct _MSG_SEP_REQUEST
#define MPI_SEP_REQ_ACTION_WRITE_STATUS (0x00) #define MPI_SEP_REQ_ACTION_WRITE_STATUS (0x00)
#define MPI_SEP_REQ_ACTION_READ_STATUS (0x01) #define MPI_SEP_REQ_ACTION_READ_STATUS (0x01)
/* Flags defines */
#define MPI_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01)
#define MPI_SEP_REQ_FLAGS_BUS_TARGETID_ADDRESS (0x00)
/* SlotStatus bits for MSG_SEP_REQUEST */ /* SlotStatus bits for MSG_SEP_REQUEST */
#define MPI_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001) #define MPI_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001)
#define MPI_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002) #define MPI_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002)
...@@ -332,6 +335,9 @@ typedef struct _MSG_SEP_REPLY ...@@ -332,6 +335,9 @@ typedef struct _MSG_SEP_REPLY
U16 IOCStatus; /* 0Eh */ U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */ U32 IOCLogInfo; /* 10h */
U32 SlotStatus; /* 14h */ U32 SlotStatus; /* 14h */
U32 Reserved4; /* 18h */
U16 Slot; /* 1Ch */
U16 EnclosureHandle; /* 1Eh */
} MSG_SEP_REPLY, MPI_POINTER PTR_MSG_SEP_REPLY, } MSG_SEP_REPLY, MPI_POINTER PTR_MSG_SEP_REPLY,
SEPReply_t, MPI_POINTER pSEPReply_t; SEPReply_t, MPI_POINTER pSEPReply_t;
......
/* /*
* Copyright (c) 2000-2003 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Logic Corporation.
* *
* *
* Name: mpi_lan.h * Name: mpi_lan.h
* Title: MPI LAN messages and structures * Title: MPI LAN messages and structures
* Creation Date: June 30, 2000 * Creation Date: June 30, 2000
* *
* mpi_lan.h Version: 01.05.xx * mpi_lan.h Version: 01.05.01
* *
* Version History * Version History
* --------------- * ---------------
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
* 02-20-01 01.01.02 Started using MPI_POINTER. * 02-20-01 01.01.02 Started using MPI_POINTER.
* 03-27-01 01.01.03 Added structure offset comments. * 03-27-01 01.01.03 Added structure offset comments.
* 08-08-01 01.02.01 Original release for v1.2 work. * 08-08-01 01.02.01 Original release for v1.2 work.
* 05-11-04 01.03.01 Original release for MPI v1.3.
* 08-19-04 01.05.01 Original release for MPI v1.5.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
......
/* /*
* Copyright (c) 2001-2003 LSI Logic Corporation. * Copyright (c) 2001-2005 LSI Logic Corporation.
* *
* *
* Name: mpi_raid.h * Name: mpi_raid.h
* Title: MPI RAID message and structures * Title: MPI RAID message and structures
* Creation Date: February 27, 2001 * Creation Date: February 27, 2001
* *
* mpi_raid.h Version: 01.05.xx * mpi_raid.h Version: 01.05.02
* *
* Version History * Version History
* --------------- * ---------------
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
* 11-15-02 01.02.08 Added missing MsgContext field to MSG_MAILBOX_REQUEST. * 11-15-02 01.02.08 Added missing MsgContext field to MSG_MAILBOX_REQUEST.
* 04-01-03 01.02.09 New action data option flag for * 04-01-03 01.02.09 New action data option flag for
* MPI_RAID_ACTION_DELETE_VOLUME. * MPI_RAID_ACTION_DELETE_VOLUME.
* 05-11-04 01.03.01 Original release for MPI v1.3.
* 08-19-04 01.05.01 Original release for MPI v1.5.
* 01-15-05 01.05.02 Added defines for the two new RAID Actions for
* _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -84,6 +88,8 @@ typedef struct _MSG_RAID_ACTION ...@@ -84,6 +88,8 @@ typedef struct _MSG_RAID_ACTION
#define MPI_RAID_ACTION_REPLACE_PHYSDISK (0x10) #define MPI_RAID_ACTION_REPLACE_PHYSDISK (0x10)
#define MPI_RAID_ACTION_ACTIVATE_VOLUME (0x11) #define MPI_RAID_ACTION_ACTIVATE_VOLUME (0x11)
#define MPI_RAID_ACTION_INACTIVATE_VOLUME (0x12) #define MPI_RAID_ACTION_INACTIVATE_VOLUME (0x12)
#define MPI_RAID_ACTION_SET_RESYNC_RATE (0x13)
#define MPI_RAID_ACTION_SET_DATA_SCRUB_RATE (0x14)
/* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */ /* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC (0x00000001) #define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC (0x00000001)
...@@ -99,6 +105,13 @@ typedef struct _MSG_RAID_ACTION ...@@ -99,6 +105,13 @@ typedef struct _MSG_RAID_ACTION
/* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */ /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */
#define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001) #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001)
/* ActionDataWord defines for use with MPI_RAID_ACTION_SET_RESYNC_RATE action */
#define MPI_RAID_ACTION_ADATA_RESYNC_RATE_MASK (0x000000FF)
/* ActionDataWord defines for use with MPI_RAID_ACTION_SET_DATA_SCRUB_RATE action */
#define MPI_RAID_ACTION_ADATA_DATA_SCRUB_RATE_MASK (0x000000FF)
/* RAID Action reply message */ /* RAID Action reply message */
......
/* /*
* Copyright (c) 2000-2003 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Logic Corporation.
* *
* *
* Name: mpi_type.h * Name: mpi_type.h
* Title: MPI Basic type definitions * Title: MPI Basic type definitions
* Creation Date: June 6, 2000 * Creation Date: June 6, 2000
* *
* mpi_type.h Version: 01.05.xx * mpi_type.h Version: 01.05.01
* *
* Version History * Version History
* --------------- * ---------------
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 11-02-00 01.01.01 Original release for post 1.0 work * 11-02-00 01.01.01 Original release for post 1.0 work
* 02-20-01 01.01.02 Added define and ifdef for MPI_POINTER. * 02-20-01 01.01.02 Added define and ifdef for MPI_POINTER.
* 08-08-01 01.02.01 Original release for v1.2 work. * 08-08-01 01.02.01 Original release for v1.2 work.
* 05-11-04 01.03.01 Original release for MPI v1.3.
* 08-19-04 01.05.01 Original release for MPI v1.5.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -50,11 +52,6 @@ typedef unsigned short U16; ...@@ -50,11 +52,6 @@ typedef unsigned short U16;
typedef int32_t S32; typedef int32_t S32;
typedef u_int32_t U32; typedef u_int32_t U32;
/*
* The only way crap below could work on big-endian boxen would be if it
* wasn't used at all.
*/
typedef struct _S64 typedef struct _S64
{ {
U32 Low; U32 Low;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -5,22 +5,9 @@ ...@@ -5,22 +5,9 @@
* LSIFC9xx/LSI409xx Fibre Channel * LSIFC9xx/LSI409xx Fibre Channel
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
* *
* Credits: * Copyright (c) 1999-2005 LSI Logic Corporation
* This driver would not exist if not for Alan Cox's development
* of the linux i2o driver.
*
* A huge debt of gratitude is owed to David S. Miller (DaveM)
* for fixing much of the stupid and broken stuff in the early
* driver while porting to sparc64 platform. THANK YOU!
*
* (see also mptbase.c)
*
* Copyright (c) 1999-2004 LSI Logic Corporation
* Originally By: Steven J. Ralston
* (mailto:sjralston1@netscape.net)
* (mailto:mpt_linux_developer@lsil.com) * (mailto:mpt_linux_developer@lsil.com)
* *
* $Id: mptctl.h,v 1.13 2002/12/03 21:26:33 pdelaney Exp $
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -53,6 +53,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o ...@@ -53,6 +53,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_TIGON3) += tg3.o obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BNX2) += bnx2.o obj-$(CONFIG_BNX2) += bnx2.o
obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SK98LIN) += sk98lin/ obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/ obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_RHINE) += via-rhine.o
...@@ -74,7 +75,6 @@ obj-$(CONFIG_MAC8390) += mac8390.o 8390.o ...@@ -74,7 +75,6 @@ obj-$(CONFIG_MAC8390) += mac8390.o 8390.o
obj-$(CONFIG_APNE) += apne.o 8390.o obj-$(CONFIG_APNE) += apne.o 8390.o
obj-$(CONFIG_PCMCIA_PCNET) += 8390.o obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
obj-$(CONFIG_SHAPER) += shaper.o obj-$(CONFIG_SHAPER) += shaper.o
obj-$(CONFIG_SK_G16) += sk_g16.o
obj-$(CONFIG_HP100) += hp100.o obj-$(CONFIG_HP100) += hp100.o
obj-$(CONFIG_SMC9194) += smc9194.o obj-$(CONFIG_SMC9194) += smc9194.o
obj-$(CONFIG_FEC) += fec.o obj-$(CONFIG_FEC) += fec.o
...@@ -122,7 +122,6 @@ obj-$(CONFIG_DEFXX) += defxx.o ...@@ -122,7 +122,6 @@ obj-$(CONFIG_DEFXX) += defxx.o
obj-$(CONFIG_SGISEEQ) += sgiseeq.o obj-$(CONFIG_SGISEEQ) += sgiseeq.o
obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
obj-$(CONFIG_AT1700) += at1700.o obj-$(CONFIG_AT1700) += at1700.o
obj-$(CONFIG_FMV18X) += fmv18x.o
obj-$(CONFIG_EL1) += 3c501.o obj-$(CONFIG_EL1) += 3c501.o
obj-$(CONFIG_EL16) += 3c507.o obj-$(CONFIG_EL16) += 3c507.o
obj-$(CONFIG_ELMC) += 3c523.o obj-$(CONFIG_ELMC) += 3c523.o
...@@ -180,6 +179,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o ...@@ -180,6 +179,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
obj-$(CONFIG_IBMVETH) += ibmveth.o obj-$(CONFIG_IBMVETH) += ibmveth.o
obj-$(CONFIG_S2IO) += s2io.o obj-$(CONFIG_S2IO) += s2io.o
obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_SMC91X) += smc91x.o
obj-$(CONFIG_DM9000) += dm9000.o
obj-$(CONFIG_FEC_8XX) += fec_8xx/ obj-$(CONFIG_FEC_8XX) += fec_8xx/
obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_ARM) += arm/
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -1412,7 +1412,6 @@ static int bmac_open(struct net_device *dev) ...@@ -1412,7 +1412,6 @@ static int bmac_open(struct net_device *dev)
bp->opened = 1; bp->opened = 1;
bmac_reset_and_enable(dev); bmac_reset_and_enable(dev);
enable_irq(dev->irq); enable_irq(dev->irq);
dev->flags |= IFF_RUNNING;
return 0; return 0;
} }
...@@ -1425,7 +1424,6 @@ static int bmac_close(struct net_device *dev) ...@@ -1425,7 +1424,6 @@ static int bmac_close(struct net_device *dev)
int i; int i;
bp->sleeping = 1; bp->sleeping = 1;
dev->flags &= ~(IFF_UP | IFF_RUNNING);
/* disable rx and tx */ /* disable rx and tx */
config = bmread(dev, RXCFG); config = bmread(dev, RXCFG);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册